Other small updates

Change-Id: I94f347bdba1e11fe2b6e300ca7ba7a1f4b4632d8
This commit is contained in:
Mike Fedosin 2017-02-16 00:50:05 +03:00
parent 5e175c764e
commit 2280b332a4
3 changed files with 24 additions and 61 deletions

View File

@ -218,6 +218,9 @@ class ArtifactsController(api_versioning.VersionedResource):
:param values: dict with artifact fields
:return: definition of created artifact
"""
if req.context.tenant is None or req.context.read_only:
msg = _("It's forbidden to anonymous users to create artifacts.")
raise exc.Forbidden(msg)
return self.engine.create(req.context, type_name, values)
@supported_versions(min_ver='1.0')

View File

@ -68,52 +68,28 @@ class Engine(object):
return copy.deepcopy(cls.schemas)
@classmethod
def _get_artifact(cls, context, type_name, artifact_id,
read_only=False):
def _get_artifact(cls, ctx, type_name, artifact_id, read_only=False):
"""Return artifact requested by user.
Check access permissions and policies.
:param context: user context
:param ctx: user context
:param type_name: artifact type name
:param artifact_id: id of the artifact to be updated
:param read_only: flag, if set to True only read access is checked,
if False then engine checks if artifact can be modified by the user
"""
def _check_read_write_access(ctx, af):
"""Check if artifact can be modified by user.
:param ctx: user context
:param af: artifact definition
:raise: Forbidden if access is not allowed
"""
if not ctx.is_admin and ctx.tenant != af.owner or ctx.read_only:
raise exception.Forbidden()
def _check_read_only_access(ctx, af):
"""Check if user has read only access to artifact.
:param ctx: user context
:param af: artifact definition
:raise: Forbidden if access is not allowed
"""
private = af.visibility != 'public'
if (private and
not ctx.is_admin and ctx.tenant != af.owner):
# TODO(kairat): check artifact sharing here
raise exception.Forbidden()
artifact_type = registry.ArtifactRegistry.get_artifact_type(type_name)
# only artifact is available for class users
artifact = artifact_type.get(context, artifact_id)
if read_only:
_check_read_only_access(context, artifact)
LOG.debug("Artifact %s acquired for read-only access", artifact_id)
else:
_check_read_write_access(context, artifact)
af = artifact_type.get(ctx, artifact_id)
if not read_only:
if not ctx.is_admin and ctx.tenant != af.owner or ctx.read_only:
raise exception.Forbidden()
LOG.debug("Artifact %s acquired for read-write access",
artifact_id)
return artifact
else:
LOG.debug("Artifact %s acquired for read-only access", artifact_id)
return af
@classmethod
def list_type_schemas(cls, context):
@ -193,7 +169,7 @@ class Engine(object):
except TypeError as e:
msg = _("Incorrect type of the element. Reason: %s") % str(e)
raise exception.BadRequest(msg)
lock_key = "%s:%s:" % (type_name, artifact_id)
lock_key = "%s:%s" % (type_name, artifact_id)
with base.BaseArtifact.lock_engine.acquire(context, lock_key):
af = cls._get_artifact(context, type_name, artifact_id)
af_dict = af.to_dict()

View File

@ -256,22 +256,7 @@ class BaseArtifact(base.VersionedObject):
raise NotImplementedError()
@classmethod
def _lock_version(cls, context, values):
"""Create scope lock for artifact creation.
:param values: artifact values
:return: Lock object
"""
name = values.get('name')
version = values.get('version', cls.DEFAULT_ARTIFACT_VERSION)
scope_id = None
if name:
scope_id = "%s:%s" % (name, str(version))
return cls.lock_engine.acquire(context, scope_id)
@classmethod
def _lock_updated_version(cls, af, values):
def _get_scoped_lock(cls, af, values):
"""Create scope lock for artifact update.
:param values: artifact values
@ -283,7 +268,7 @@ class BaseArtifact(base.VersionedObject):
scope_id = None
if (name, version, visibility) != (af.name, af.version, af.visibility):
# no version change == no lock for version
scope_id = "%s:%s" % (name, str(version))
scope_id = "%s:%s:%s" % (cls.get_type_name(), name, str(version))
if visibility != 'public':
scope_id += ':%s' % str(af.obj_context.tenant)
@ -297,13 +282,12 @@ class BaseArtifact(base.VersionedObject):
:param values: dictionary with specified artifact fields
:return: created artifact object
"""
if context.tenant is None or context.read_only:
msg = _("It's forbidden to anonymous users to create artifacts.")
raise exception.Forbidden(msg)
with cls._lock_version(context, values):
ver = values.setdefault(
'version', cls.DEFAULT_ARTIFACT_VERSION)
cls._validate_versioning(context, values.get('name'), ver)
name = values.get('name')
ver = values.setdefault(
'version', cls.DEFAULT_ARTIFACT_VERSION)
scope_id = "%s:%s:%s" % (cls.get_type_name(), name, ver)
with cls.lock_engine.acquire(context, scope_id):
cls._validate_versioning(context, name, ver)
# validate other values
cls._validate_change_allowed(values)
# validate visibility
@ -386,7 +370,7 @@ class BaseArtifact(base.VersionedObject):
"""
# reset all changes of artifact to reuse them after update
af.obj_reset_changes()
with cls._lock_updated_version(af, values):
with cls._get_scoped_lock(af, values):
# validate version
if 'name' in values or 'version' in values:
new_name = values.get('name') or af.name
@ -772,7 +756,7 @@ class BaseArtifact(base.VersionedObject):
"for artifact publish.")
raise exception.BadRequest(msg)
with cls._lock_updated_version(af, values):
with cls._get_scoped_lock(af, values):
if af.status != cls.STATUS.ACTIVE:
msg = _("Cannot publish non-active artifact")
raise exception.BadRequest(msg)