Merge "Removed per ACL operations and added support for PUT method."

This commit is contained in:
Jenkins
2015-06-03 16:47:21 +00:00
committed by Gerrit Code Review
8 changed files with 614 additions and 1237 deletions

View File

@@ -13,6 +13,7 @@
import itertools
import pecan
import six
from barbican import api
from barbican.api import controllers
@@ -26,113 +27,21 @@ from barbican.model import repositories as repo
LOG = utils.getLogger(__name__)
def _acls_not_found(acl_for=None):
"""Throw exception indicating no secret or container acls found."""
pecan.abort(404, u._('Not Found. Sorry no ACL found for given {0}.').
format(acl_for))
def _convert_acl_to_response_format(acl, acls_dict):
fields = acl.to_dict_fields()
operation = fields['operation']
acl_data = {} # dict for each acl operation data
acl_data['creator-only'] = fields['creator_only']
acl_data['users'] = fields.get('users', [])
acl_data['created'] = fields['created']
acl_data['updated'] = fields['updated']
acls_dict[operation] = acl_data
def _acl_not_found():
"""Throw exception indicating no secret or container acl found."""
pecan.abort(404, u._('Not Found. Sorry no ACL found for given id.'))
def _acls_already_exist():
"""Throw exception indicating secret or container acls already exist."""
pecan.abort(400, u._('Existing ACL cannot be updated with POST method.'))
def _acl_operation_update_not_allowed():
"""Throw exception indicating existing secret or container acl operation.
Operation cannot be changed for an existing ACL. Allowed change is list of
users and/or creator_only flag change.
"""
pecan.abort(400, u._("Existing ACL's operation cannot be updated."))
class SecretACLController(controllers.ACLMixin):
"""Handles a SecretACL entity retrieval and update requests."""
def __init__(self, acl_id, secret_project_id, secret):
self.acl_id = acl_id
self.secret_project_id = secret_project_id
self.secret = secret
self.acl_repo = repo.get_secret_acl_repository()
self.validator = validators.ACLValidator()
def get_acl_tuple(self, req, **kwargs):
d = {'project_id': self.secret_project_id}
return 'secret', d
@pecan.expose(generic=True)
def index(self):
pecan.abort(405) # HTTP 405 Method Not Allowed as default
@index.when(method='GET', template='json')
@controllers.handle_exceptions(u._('SecretACL retrieval'))
@controllers.enforce_rbac('secret_acl:get')
def on_get(self, external_project_id):
secret_acl = self.acl_repo.get(
entity_id=self.acl_id,
suppress_exception=True)
if not secret_acl:
_acl_not_found()
dict_fields = secret_acl.to_dict_fields()
return hrefs.convert_acl_to_hrefs(dict_fields)
@index.when(method='PATCH', template='json')
@controllers.handle_exceptions(u._('A SecretACL Update'))
@controllers.enforce_rbac('secret_acl:patch')
@controllers.enforce_content_types(['application/json'])
def on_patch(self, external_project_id, **kwargs):
"""Handles existing secret ACL update for given acl id."""
data = api.load_body(pecan.request, validator=self.validator)
LOG.debug('Start SecretACLController on_patch...%s', data)
secret_acl = self.acl_repo.get(
entity_id=self.acl_id,
suppress_exception=True)
if not secret_acl:
_acl_not_found()
# Make sure request acl operation matches with acl stored in db
operation = secret_acl.operation
input_acl = data.get(operation)
if not input_acl:
_acl_operation_update_not_allowed()
creator_only = input_acl.get('creator-only')
user_ids = input_acl.get('users')
if creator_only is not None:
secret_acl.creator_only = creator_only
self.acl_repo.create_or_replace_from(self.secret,
secret_acl=secret_acl,
user_ids=user_ids)
acl_ref = hrefs.convert_acl_to_hrefs(secret_acl.to_dict_fields())
return {'acl_ref': acl_ref['acl_ref']}
@index.when(method='DELETE', template='json')
@controllers.handle_exceptions(u._('SecretACL deletion'))
@controllers.enforce_rbac('secret_acl:delete')
def on_delete(self, external_project_id, **kwargs):
"""Deletes existing ACL by acl_id provided in URI."""
secret_acl = self.acl_repo.get(
entity_id=self.acl_id,
suppress_exception=True)
if not secret_acl:
_acl_not_found()
self.acl_repo.delete_entity_by_id(entity_id=self.acl_id,
external_project_id=None)
DEFAULT_ACL = {'read': {'creator-only': False}}
class SecretACLsController(controllers.ACLMixin):
@@ -146,14 +55,10 @@ class SecretACLsController(controllers.ACLMixin):
self.validator = validators.ACLValidator()
def get_acl_tuple(self, req, **kwargs):
d = {'project_id': self.secret_project_id}
d = {'project_id': self.secret_project_id,
'creator_id': self.secret.creator_id}
return 'secret', d
@pecan.expose()
def _lookup(self, acl_id, *remainder):
return SecretACLController(acl_id, self.secret_project_id,
self.secret), remainder
@pecan.expose(generic=True)
def index(self, **kwargs):
pecan.abort(405) # HTTP 405 Method Not Allowed as default
@@ -165,60 +70,11 @@ class SecretACLsController(controllers.ACLMixin):
LOG.debug('Start secret ACL on_get '
'for secret-ID %s:', self.secret.id)
return self._return_acl_hrefs(self.secret.id)
@index.when(method='POST', template='json')
@controllers.handle_exceptions(u._('SecretACL(s) creation'))
@controllers.enforce_rbac('secret_acls:post')
@controllers.enforce_content_types(['application/json'])
def on_post(self, external_project_id, **kwargs):
"""Handles secret acls creation request.
Once a set of ACLs exists for a given secret, it can only be updated
via PATCH method. In create, multiple operation ACL payload can be
specified as mentioned in sample below.
{
"read":{
"users":[
"5ecb18f341894e94baca9e8c7b6a824a"
]
},
"write":{
"users":[
"20b63d71f90848cf827ee48074f213b7",
"5ecb18f341894e94baca9e8c7b6a824a"
],
"creator-only":false
}
}
"""
count = self.acl_repo.get_count(self.secret.id)
LOG.debug('Count of existing ACL on_post is [%s] '
' for secret-ID %s:', count, self.secret.id)
if count > 0:
_acls_already_exist()
data = api.load_body(pecan.request, validator=self.validator)
LOG.debug('Start on_post...%s', data)
for operation in itertools.ifilter(lambda x: data.get(x),
validators.ACL_OPERATIONS):
input_cr_only = data[operation].get('creator-only')
creator_only = True if input_cr_only else False
new_acl = models.SecretACL(self.secret.id, operation=operation,
creator_only=creator_only)
self.acl_repo.create_or_replace_from(
self.secret, secret_acl=new_acl,
user_ids=data[operation].get('users'))
pecan.response.status = 201
return self._return_acl_hrefs(self.secret.id)
return self._return_acl_list_response(self.secret.id)
@index.when(method='PATCH', template='json')
@controllers.handle_exceptions(u._('SecretACL(s) Update'))
@controllers.enforce_rbac('secret_acls:patch')
@controllers.enforce_rbac('secret_acls:put_patch')
@controllers.enforce_content_types(['application/json'])
def on_patch(self, external_project_id, **kwargs):
"""Handles update of existing secret acl requests.
@@ -244,13 +100,6 @@ class SecretACLsController(controllers.ACLMixin):
}
}
"""
count = self.acl_repo.get_count(self.secret.id)
LOG.debug('Count of existing ACL on_secret is [%s] '
' for secret-ID %s:', count, self.secret.id)
if count == 0:
_acls_not_found("secret")
data = api.load_body(pecan.request, validator=self.validator)
LOG.debug('Start on_patch...%s', data)
@@ -271,7 +120,72 @@ class SecretACLsController(controllers.ACLMixin):
self.acl_repo.create_or_replace_from(self.secret, secret_acl=s_acl,
user_ids=user_ids)
return self._return_acl_hrefs(self.secret.id)
acl_ref = '{0}/acl'.format(
hrefs.convert_secret_to_href(self.secret.id))
return {'acl_ref': acl_ref}
@index.when(method='PUT', template='json')
@controllers.handle_exceptions(u._('SecretACL(s) Update'))
@controllers.enforce_rbac('secret_acls:put_patch')
@controllers.enforce_content_types(['application/json'])
def on_put(self, external_project_id, **kwargs):
"""Handles update of existing secret acl requests.
Replaces existing secret ACL(s) with input ACL(s) data. Existing
ACL operation not specified in input are removed as part of update.
For missing creator-only in ACL, false is used as default.
In update, multiple operation ACL payload can be specified as
mentioned in sample below. A specific ACL can be updated by its
own id via SecretACLController patch request.
{
"read":{
"users":[
"5ecb18f341894e94baca9e8c7b6a824a",
"20b63d71f90848cf827ee48074f213b7",
"c7753f8da8dc4fbea75730ab0b6e0ef4"
]
},
"write":{
"users":[
"5ecb18f341894e94baca9e8c7b6a824a"
],
"creator-only":true
}
}
Every secret, by default, has an implicit ACL in case client has not
defined an explicit ACL. That default ACL definition, DEFAULT_ACL,
signifies that a secret by default has project based access i.e. client
with necessary roles on secret project can access the secret. That's
why when ACL is added to a secret, it always returns 200 (and not 201)
indicating existence of implicit ACL on a secret.
"""
data = api.load_body(pecan.request, validator=self.validator)
LOG.debug('Start on_put...%s', data)
existing_acls_map = {acl.operation: acl for acl in
self.secret.secret_acls}
for operation in itertools.ifilter(lambda x: data.get(x),
validators.ACL_OPERATIONS):
creator_only = data[operation].get('creator-only', False)
user_ids = data[operation].get('users', [])
s_acl = None
if operation in existing_acls_map: # update if matching acl exists
s_acl = existing_acls_map.pop(operation)
s_acl.creator_only = creator_only
else:
s_acl = models.SecretACL(self.secret.id, operation=operation,
creator_only=creator_only)
self.acl_repo.create_or_replace_from(self.secret, secret_acl=s_acl,
user_ids=user_ids)
# delete remaining existing acls as they are not present in input.
for acl in six.itervalues(existing_acls_map):
self.acl_repo.delete_entity_by_id(entity_id=acl.id,
external_project_id=None)
acl_ref = '{0}/acl'.format(
hrefs.convert_secret_to_href(self.secret.id))
return {'acl_ref': acl_ref}
@index.when(method='DELETE', template='json')
@controllers.handle_exceptions(u._('SecretACL(s) deletion'))
@@ -279,125 +193,37 @@ class SecretACLsController(controllers.ACLMixin):
def on_delete(self, external_project_id, **kwargs):
count = self.acl_repo.get_count(self.secret.id)
if count == 0:
_acls_not_found("secret")
self.acl_repo.delete_acls_for_secret(self.secret)
if count > 0:
self.acl_repo.delete_acls_for_secret(self.secret)
def _return_acl_hrefs(self, secret_id):
def _return_acl_list_response(self, secret_id):
result = self.acl_repo.get_by_secret_id(secret_id)
if not result:
_acls_not_found("secret")
else:
acl_recs = [hrefs.convert_acl_to_hrefs(acl.to_dict_fields())
for acl in result]
return [{'acl_ref': acl['acl_ref']} for acl in acl_recs]
class ContainerACLController(controllers.ACLMixin):
"""Handles a ContainerACL entity retrieval and update requests."""
def __init__(self, acl_id, container_project_id, container):
self.acl_id = acl_id
self.container_project_id = container_project_id
self.container = container
self.acl_repo = repo.get_container_acl_repository()
self.validator = validators.ACLValidator()
def get_acl_tuple(self, req, **kwargs):
d = {'project_id': self.container_project_id}
return 'container', d
@pecan.expose(generic=True)
def index(self):
pecan.abort(405) # HTTP 405 Method Not Allowed as default
@index.when(method='GET', template='json')
@controllers.handle_exceptions(u._('ContainerACL retrieval'))
@controllers.enforce_rbac('container_acl:get')
def on_get(self, external_project_id):
container_acl = self.acl_repo.get(
entity_id=self.acl_id,
suppress_exception=True)
if not container_acl:
_acl_not_found()
dict_fields = container_acl.to_dict_fields()
return hrefs.convert_acl_to_hrefs(dict_fields)
@index.when(method='PATCH', template='json')
@controllers.handle_exceptions(u._('A ContainerACL Update'))
@controllers.enforce_rbac('container_acl:patch')
@controllers.enforce_content_types(['application/json'])
def on_patch(self, external_project_id, **kwargs):
"""Handles existing container ACL update for given acl id."""
data = api.load_body(pecan.request, validator=self.validator)
LOG.debug('Start ContainerACLController on_patch...%s', data)
container_acl = self.acl_repo.get(
entity_id=self.acl_id,
suppress_exception=True)
if not container_acl:
_acl_not_found()
# Make sure request acl operation matches with acl stored in db
operation = container_acl.operation
input_acl = data.get(operation)
if not input_acl:
_acl_operation_update_not_allowed()
creator_only = input_acl.get('creator-only')
user_ids = input_acl.get('users')
if creator_only is not None:
container_acl.creator_only = creator_only
self.acl_repo.create_or_replace_from(self.container,
container_acl=container_acl,
user_ids=user_ids)
acl_ref = hrefs.convert_acl_to_hrefs(container_acl.to_dict_fields())
return {'acl_ref': acl_ref['acl_ref']}
@index.when(method='DELETE', template='json')
@controllers.handle_exceptions(u._('ContainerACL deletion'))
@controllers.enforce_rbac('container_acl:delete')
def on_delete(self, external_project_id, **kwargs):
"""Deletes existing ACL by acl_id provided in URI."""
container_acl = self.acl_repo.get(
entity_id=self.acl_id,
suppress_exception=True)
if not container_acl:
_acl_not_found()
self.acl_repo.delete_entity_by_id(entity_id=self.acl_id,
external_project_id=None)
acls_data = {}
if result:
for acl in result:
_convert_acl_to_response_format(acl, acls_data)
if not acls_data:
acls_data = DEFAULT_ACL.copy()
return acls_data
class ContainerACLsController(controllers.ACLMixin):
"""Handles ContainerACL requests by a given container id."""
def __init__(self, container_id):
self.container_id = container_id
self.container = None
def __init__(self, container):
self.container = container
self.container_id = container.id
self.acl_repo = repo.get_container_acl_repository()
self.container_repo = repo.get_container_repository()
self.validator = validators.ACLValidator()
self.container_project_id = None
self.container_project_id = container.project.external_id
def get_acl_tuple(self, req, **kwargs):
self._assert_id_and_set_container(suppress_exception=True)
d = {'project_id': self.container_project_id}
d = {'project_id': self.container_project_id,
'creator_id': self.container.creator_id}
return 'container', d
@pecan.expose()
def _lookup(self, acl_id, *remainder):
self._assert_id_and_set_container()
return (ContainerACLController(acl_id, self.container_project_id,
self.container), remainder)
@pecan.expose(generic=True)
def index(self, **kwargs):
pecan.abort(405) # HTTP 405 Method Not Allowed as default
@@ -406,68 +232,14 @@ class ContainerACLsController(controllers.ACLMixin):
@controllers.handle_exceptions(u._('ContainerACL(s) retrieval'))
@controllers.enforce_rbac('container_acls:get')
def on_get(self, external_project_id, **kw):
self._assert_id_and_set_container(suppress_exception=True)
LOG.debug('Start container ACL on_get '
'for container-ID %s:', self.container_id)
if not self.container:
controllers.containers.container_not_found()
return self._return_acl_hrefs(self.container.id)
@index.when(method='POST', template='json')
@controllers.handle_exceptions(u._('ContainerACL(s) creation'))
@controllers.enforce_rbac('container_acls:post')
@controllers.enforce_content_types(['application/json'])
def on_post(self, external_project_id, **kwargs):
"""Handles container acls creation request.
Once a set of ACLs exists for a given container, it can only be updated
via PATCH method. In create, multiple operation ACL payload can be
specified as mentioned in sample below.
{
"read":{
"users":[
"5ecb18f341894e94baca9e8c7b6a824a"
]
},
"write":{
"users":[
"20b63d71f90848cf827ee48074f213b7",
"5ecb18f341894e94baca9e8c7b6a824a"
],
"creator-only":false
}
}
"""
self._assert_id_and_set_container()
count = self.acl_repo.get_count(self.container.id)
LOG.debug('Count of existing ACL on_post is [%s] '
' for container-ID %s:', count, self.container.id)
if count > 0:
_acls_already_exist()
data = api.load_body(pecan.request, validator=self.validator)
LOG.debug('Start ContainerACLsController on_post...%s', data)
for operation in itertools.ifilter(lambda x: data.get(x),
validators.ACL_OPERATIONS):
in_cr_only = data[operation].get('creator-only')
creator_only = True if in_cr_only else False
new_acl = models.ContainerACL(self.container.id,
operation=operation,
creator_only=creator_only)
self.acl_repo.create_or_replace_from(
self.container, container_acl=new_acl,
user_ids=data[operation].get('users'))
pecan.response.status = 201
return self._return_acl_hrefs(self.container.id)
return self._return_acl_list_response(self.container.id)
@index.when(method='PATCH', template='json')
@controllers.handle_exceptions(u._('ContainerACL(s) Update'))
@controllers.enforce_rbac('container_acls:patch')
@controllers.enforce_rbac('container_acls:put_patch')
@controllers.enforce_content_types(['application/json'])
def on_patch(self, external_project_id, **kwargs):
"""Handles update of existing container acl requests.
@@ -493,13 +265,6 @@ class ContainerACLsController(controllers.ACLMixin):
}
}
"""
self._assert_id_and_set_container()
count = self.acl_repo.get_count(self.container.id)
LOG.debug('Count of existing ACL on_patch is [%s] '
' for container-ID %s:', count, self.container.id)
if count == 0:
_acls_not_found("container")
data = api.load_body(pecan.request, validator=self.validator)
LOG.debug('Start ContainerACLsController on_patch...%s', data)
@@ -521,42 +286,91 @@ class ContainerACLsController(controllers.ACLMixin):
container_acl=c_acl,
user_ids=user_ids)
return self._return_acl_hrefs(self.container.id)
acl_ref = '{0}/acl'.format(
hrefs.convert_container_to_href(self.container.id))
return {'acl_ref': acl_ref}
@index.when(method='PUT', template='json')
@controllers.handle_exceptions(u._('ContainerACL(s) Update'))
@controllers.enforce_rbac('container_acls:put_patch')
@controllers.enforce_content_types(['application/json'])
def on_put(self, external_project_id, **kwargs):
"""Handles update of existing container acl requests.
Replaces existing container ACL(s) with input ACL(s) data. Existing
ACL operation not specified in input are removed as part of update.
For missing creator-only in ACL, false is used as default.
In update, multiple operation ACL payload can be specified as
mentioned in sample below. A specific ACL can be updated by its
own id via ContainerACLController patch request.
{
"read":{
"users":[
"5ecb18f341894e94baca9e8c7b6a824a",
"20b63d71f90848cf827ee48074f213b7",
"c7753f8da8dc4fbea75730ab0b6e0ef4"
]
},
"write":{
"users":[
"5ecb18f341894e94baca9e8c7b6a824a"
],
"creator-only":true
}
}
Every container, by default, has an implicit ACL in case client has not
defined an explicit ACL. That default ACL definition, DEFAULT_ACL,
signifies that a container by default has project based access i.e.
client with necessary roles on container project can access the
container. That's why when ACL is added to a container, it always
returns 200 (and not 201) indicating existence of implicit ACL on a
container.
"""
data = api.load_body(pecan.request, validator=self.validator)
LOG.debug('Start ContainerACLsController on_put...%s', data)
existing_acls_map = {acl.operation: acl for acl in
self.container.container_acls}
for operation in itertools.ifilter(lambda x: data.get(x),
validators.ACL_OPERATIONS):
creator_only = data[operation].get('creator-only', False)
user_ids = data[operation].get('users', [])
if operation in existing_acls_map: # update if matching acl exists
c_acl = existing_acls_map.pop(operation)
c_acl.creator_only = creator_only
else:
c_acl = models.ContainerACL(self.container.id,
operation=operation,
creator_only=creator_only)
self.acl_repo.create_or_replace_from(self.container,
container_acl=c_acl,
user_ids=user_ids)
# delete remaining existing acls as they are not present in input.
for acl in six.itervalues(existing_acls_map):
self.acl_repo.delete_entity_by_id(entity_id=acl.id,
external_project_id=None)
acl_ref = '{0}/acl'.format(
hrefs.convert_container_to_href(self.container.id))
return {'acl_ref': acl_ref}
@index.when(method='DELETE', template='json')
@controllers.handle_exceptions(u._('ContainerACL(s) deletion'))
@controllers.enforce_rbac('container_acls:delete')
def on_delete(self, external_project_id, **kwargs):
self._assert_id_and_set_container()
count = self.acl_repo.get_count(self.container_id)
if count == 0:
_acls_not_found("container")
if count > 0:
self.acl_repo.delete_acls_for_container(self.container)
self.acl_repo.delete_acls_for_container(self.container)
def _assert_id_and_set_container(self, suppress_exception=False):
"""Checks whether container_id is valid or not.
Whether container is associated with token's project is not needed as
that check is now made via policy rule.
"""
if self.container:
return
controllers.assert_is_valid_uuid_from_uri(self.container_id)
self.container = self.container_repo.get_container_by_id(
entity_id=self.container_id, suppress_exception=True)
if not self.container and not suppress_exception:
controllers.containers.container_not_found()
if self.container:
self.container_project_id = self.container.project.external_id
def _return_acl_hrefs(self, container_id):
def _return_acl_list_response(self, container_id):
result = self.acl_repo.get_by_container_id(container_id)
if not result:
_acls_not_found("container")
else:
acl_recs = [hrefs.convert_acl_to_hrefs(acl.to_dict_fields())
for acl in result]
return [{'acl_ref': acl['acl_ref']} for acl in acl_recs]
acls_data = {}
if result:
for acl in result:
_convert_acl_to_response_format(acl, acls_data)
if not acls_data:
acls_data = DEFAULT_ACL.copy()
return acls_data

View File

@@ -47,7 +47,7 @@ class ContainerController(controllers.ACLMixin):
self.validator = validators.ContainerValidator()
self.consumers = consumers.ContainerConsumersController(
self.container_id)
self.acls = acls.ContainerACLsController(self.container_id)
self.acl = acls.ContainerACLsController(self.container)
def get_acl_tuple(self, req, **kwargs):
d = self.get_acl_dict_for_user(req, self.container.container_acls)

View File

@@ -70,7 +70,7 @@ class SecretController(controllers.ACLMixin):
@pecan.expose()
def _lookup(self, sub_resource, *remainder):
if sub_resource == 'acls':
if sub_resource == 'acl':
return acls.SecretACLsController(self.secret), remainder
else:
pecan.abort(405) # only 'acl' as sub-resource is supported

View File

@@ -9,7 +9,6 @@
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from barbican.common import utils
@@ -52,42 +51,6 @@ def convert_certificate_authority_to_href(ca_id):
return convert_resource_id_to_href('cas', ca_id)
def convert_secret_acl_to_href(secret_id, acl_id):
"""Convert the secret acl ID to a HATEOS-style href."""
secret_href = convert_secret_to_href(secret_id)
return secret_href + '/acls/' + acl_id
def convert_container_acl_to_href(container_id, acl_id):
"""Convert the container acl ID to a HATEOS-style href."""
container_href = convert_container_to_href(container_id)
return container_href + '/acls/' + acl_id
def convert_acl_to_hrefs(fields):
acl_id = fields['acl_id']
if 'secret_id' in fields:
fields['acl_ref'] = convert_secret_acl_to_href(fields['secret_id'],
acl_id)
del fields['acl_id']
fields['secret_ref'] = convert_secret_to_href(fields['secret_id'])
del fields['secret_id']
if 'container_id' in fields:
fields['acl_ref'] = convert_container_acl_to_href(
fields['container_id'], acl_id)
del fields['acl_id']
fields['container_ref'] = convert_container_to_href(
fields['container_id'])
del fields['container_id']
if 'creator_only' in fields:
fields['creator-only'] = fields['creator_only']
del fields['creator_only']
return fields
# TODO(hgedikli) handle list of fields in here
def convert_to_hrefs(fields):
"""Convert id's within a fields dict to HATEOS-style hrefs."""

View File

@@ -1710,6 +1710,7 @@ class SecretACLRepo(BaseRepo):
session=None):
session = self.get_session(session)
secret.updated_at = timeutils.utcnow()
secret_acl.updated_at = timeutils.utcnow()
secret.secret_acls.append(secret_acl)
secret.save(session=session)
@@ -1804,7 +1805,7 @@ class ContainerACLRepo(BaseRepo):
user_ids=None, session=None):
session = self.get_session(session)
container.updated_at = timeutils.utcnow()
container_acl.updated_at = timeutils.utcnow()
container.container_acls.append(container_acl)
container.save(session=session)

File diff suppressed because it is too large Load Diff

View File

@@ -489,7 +489,7 @@ class WhenCreatingStoredKeyOrders(utils.BarbicanAPIBaseTestCase,
)
if add_acls:
_, _ = test_acls.manage_acls(
test_acls.manage_acls(
self.app, 'containers', container_id,
read_user_ids=['u1', 'u3', 'u4'],
read_creator_only=read_creator_only,

View File

@@ -20,6 +20,10 @@
"secret_non_private_read": "rule:all_users and rule:secret_project_match and not rule:secret_private_read",
"secret_decrypt_non_private_read": "rule:all_but_audit and rule:secret_project_match and not rule:secret_private_read",
"container_non_private_read": "rule:all_users and rule:container_project_match and not rule:container_private_read",
"secret_project_admin": "rule:admin and rule:secret_project_match",
"secret_project_creator": "rule:creator_role and rule:secret_project_match and rule:secret_creator_user",
"container_project_admin": "rule:admin and rule:container_project_match",
"container_project_creator": "rule:creator_role and rule:container_project_match and rule:container_creator_user",
"version:get": "@",
"secret:decrypt": "rule:secret_decrypt_non_private_read or rule:secret_creator_user or rule:secret_acl_read",
@@ -57,18 +61,10 @@
"certificate_authority:unset_global_preferred": "rule:admin",
"certificate_authority:get_global_preferred": "rule:all_users",
"certificate_authority:get_preferred_ca": "rule:all_users",
"secret_acls:post": "rule:admin_or_creator_role and rule:secret_project_match",
"secret_acls:patch": "rule:admin_or_creator_role and rule:secret_project_match",
"secret_acls:delete": "rule:admin_or_creator_role and rule:secret_project_match",
"secret_acls:put_patch": "rule:secret_project_admin or rule:secret_project_creator",
"secret_acls:delete": "rule:secret_project_admin or rule:secret_project_creator",
"secret_acls:get": "rule:all_but_audit and rule:secret_project_match",
"secret_acl:get": "rule:all_but_audit and rule:secret_project_match",
"secret_acl:patch": "rule:admin_or_creator_role and rule:secret_project_match",
"secret_acl:delete": "rule:admin_or_creator_role and rule:secret_project_match",
"container_acls:post": "rule:admin_or_creator_role and rule:container_project_match",
"container_acls:patch": "rule:admin_or_creator_role and rule:container_project_match",
"container_acls:delete": "rule:admin_or_creator_role and rule:container_project_match",
"container_acls:get": "rule:all_but_audit and rule:container_project_match",
"container_acl:get": "rule:all_but_audit and rule:container_project_match",
"container_acl:patch": "rule:admin_or_creator_role and rule:container_project_match",
"container_acl:delete": "rule:admin_or_creator_role and rule:container_project_match"
"container_acls:put_patch": "rule:container_project_admin or rule:container_project_creator",
"container_acls:delete": "rule:container_project_admin or rule:container_project_creator",
"container_acls:get": "rule:all_but_audit and rule:container_project_match"
}