Exemple #1
0
 def on_put(self, external_project_id, **kwargs):
     LOG.debug('=== ProjectQuotasController PUT ===')
     if not pecan.request.body:
         raise exception.NoDataToProcess()
     api.load_body(pecan.request,
                   validator=self.validator)
     self.quota_driver.set_project_quotas(self.passed_project_id,
                                          kwargs['project_quotas'])
     LOG.info(u._LI('Put Project Quotas'))
     pecan.response.status = 204
Exemple #2
0
 def on_post(self, external_project_id, **kwargs):
     LOG.debug('=== ProjectQuotasController POST ===')
     api.load_body(pecan.request,
                   validator=self.validator)
     # TODO(dave) implement
     resp = {'project_quotas': {
         'secrets': 10,
         'orders': 20,
         'containers': 10,
         'transport_keys': 10,
         'consumers': -1}
     }
     LOG.info(u._LI('Post Project Quotas'))
     return resp
Exemple #3
0
    def on_post(self, keystone_id, **kwargs):

        tenant = res.get_or_create_tenant(keystone_id, self.tenant_repo)

        body = api.load_body(pecan.request, validator=self.validator)
        LOG.debug('Start on_post...{0}'.format(body))

        if 'secret' not in body:
            _secret_not_in_order()
        secret_info = body['secret']
        name = secret_info.get('name')
        LOG.debug('Secret to create is {0}'.format(name))

        new_order = models.Order()
        new_order.secret_name = secret_info.get('name')
        new_order.secret_algorithm = secret_info.get('algorithm')
        new_order.secret_bit_length = secret_info.get('bit_length', 0)
        new_order.secret_mode = secret_info.get('mode')
        new_order.secret_payload_content_type = secret_info.get(
            'payload_content_type')

        new_order.secret_expiration = secret_info.get('expiration')
        new_order.tenant_id = tenant.id
        self.order_repo.create_from(new_order)

        # Send to workers to process.
        self.queue.process_order(order_id=new_order.id,
                                 keystone_id=keystone_id)

        pecan.response.status = 202
        pecan.response.headers['Location'] = '/{0}/orders/{1}'.format(
            keystone_id, new_order.id
        )
        url = hrefs.convert_order_to_href(keystone_id, new_order.id)
        return {'order_ref': url}
Exemple #4
0
    def on_post(self, req, resp, keystone_id):
        LOG.debug('Start on_post for tenant-ID {0}:...'.format(keystone_id))

        data = api.load_body(req, resp, self.validator)
        tenant = res.get_or_create_tenant(keystone_id, self.tenant_repo)

        try:
            new_secret = res.create_secret(data, tenant, self.crypto_manager,
                                           self.secret_repo,
                                           self.tenant_secret_repo,
                                           self.datum_repo)
        except em.CryptoMimeTypeNotSupportedException as cmtnse:
            LOG.exception('Secret creation failed - mime-type not supported')
            _secret_mime_type_not_supported(cmtnse.mime_type, req, resp)
        except exception.NoDataToProcess:
            LOG.exception('No secret data to process')
            _secret_plain_text_empty(req, resp)
        except exception.LimitExceeded:
            LOG.exception('Secret data too big to process')
            _secret_data_too_large(req, resp)
        except Exception as e:
            LOG.exception('Secret creation failed - unknown')
            _general_failure('Secret creation failed - unknown', req, resp)

        resp.status = falcon.HTTP_201
        resp.set_header('Location', '/{0}/secrets/{1}'.format(keystone_id,
                                                              new_secret.id))
        url = convert_secret_to_href(keystone_id, new_secret.id)
        LOG.debug('URI to secret is {0}'.format(url))
        resp.body = json.dumps({'secret_ref': url})
Exemple #5
0
    def on_post(self, keystone_id, **kwargs):
        LOG.debug('Start on_post for project-ID %s:...', keystone_id)

        data = api.load_body(pecan.request, validator=self.validator)
        project = res.get_or_create_project(keystone_id,
                                            self.repos.project_repo)

        transport_key_needed = data.get('transport_key_needed',
                                        'false').lower() == 'true'

        new_secret, transport_key_model = plugin.store_secret(
            data.get('payload'),
            data.get('payload_content_type',
                     'application/octet-stream'),
            data.get('payload_content_encoding'),
            data, None, project,
            self.repos,
            transport_key_needed=transport_key_needed,
            transport_key_id=data.get('transport_key_id'))

        pecan.response.status = 201
        pecan.response.headers['Location'] = '/secrets/{0}'.format(
            new_secret.id
        )
        url = hrefs.convert_secret_to_href(new_secret.id)
        LOG.debug('URI to secret is %s', url)
        if transport_key_model is not None:
            tkey_url = hrefs.convert_transport_key_to_href(
                transport_key_model.id)
            return {'secret_ref': url, 'transport_key_ref': tkey_url}
        else:
            return {'secret_ref': url}
Exemple #6
0
    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']}
Exemple #7
0
    def on_post(self, external_project_id, **kwargs):
        LOG.debug('Start on_post for project-ID %s:...', external_project_id)

        data = api.load_body(pecan.request, validator=self.validator)
        project = res.get_or_create_project(external_project_id)

        transport_key_needed = data.get('transport_key_needed',
                                        'false').lower() == 'true'
        ctxt = controllers._get_barbican_context(pecan.request)
        if ctxt:  # in authenticated pipleline case, always use auth token user
            data['creator_id'] = ctxt.user

        new_secret, transport_key_model = plugin.store_secret(
            data.get('payload'),
            data.get('payload_content_type',
                     'application/octet-stream'),
            data.get('payload_content_encoding'),
            data, None, project,
            transport_key_needed=transport_key_needed,
            transport_key_id=data.get('transport_key_id'))

        url = hrefs.convert_secret_to_href(new_secret.id)
        LOG.debug('URI to secret is %s', url)

        pecan.response.status = 201
        pecan.response.headers['Location'] = url

        LOG.info(u._LI('Created a secret for project: %s'),
                 external_project_id)
        if transport_key_model is not None:
            tkey_url = hrefs.convert_transport_key_to_href(
                transport_key_model.id)
            return {'secret_ref': url, 'transport_key_ref': tkey_url}
        else:
            return {'secret_ref': url}
Exemple #8
0
    def on_post(self, req, resp, keystone_id):

        tenant = res.get_or_create_tenant(keystone_id, self.tenant_repo)

        data = api.load_body(req, resp, self.validator)
        LOG.debug('Start on_post...{0}'.format(data))

        new_container = models.Container(data)
        new_container.tenant_id = tenant.id

        #TODO: (hgedikli) performance optimizations
        for secret_ref in new_container.container_secrets:
            secret = self.secret_repo.get(entity_id=secret_ref.secret_id,
                                          keystone_id=keystone_id,
                                          suppress_exception=True)
            if not secret:
                api.abort(falcon.HTTP_404,
                          u._("Secret provided for '%s'"
                              " doesn't exist." % secret_ref.name),
                          req, resp)

        self.container_repo.create_from(new_container)

        resp.status = falcon.HTTP_202
        resp.set_header('Location',
                        '/{0}/containers/{1}'.format(keystone_id,
                                                     new_container.id))
        url = convert_container_to_href(keystone_id, new_container.id)
        resp.body = json.dumps({'container_ref': url})
Exemple #9
0
    def on_post(self, req, resp, keystone_id):

        tenant = res.get_or_create_tenant(keystone_id, self.tenant_repo)

        body = api.load_body(req, resp, self.validator)
        LOG.debug('Start on_post...{0}'.format(body))

        if 'secret' not in body:
            _secret_not_in_order(req, resp)
        secret_info = body['secret']
        name = secret_info.get('name')
        LOG.debug('Secret to create is {0}'.format(name))

        new_order = models.Order()
        new_order.secret_name = secret_info.get('name')
        new_order.secret_algorithm = secret_info.get('algorithm')
        new_order.secret_bit_length = secret_info.get('bit_length', 0)
        new_order.secret_mode = secret_info.get('mode')
        new_order.secret_payload_content_type = secret_info.get(
            'payload_content_type')

        new_order.secret_expiration = secret_info.get('expiration')
        new_order.tenant_id = tenant.id
        self.order_repo.create_from(new_order)

        # Send to workers to process.
        self.queue.process_order(order_id=new_order.id,
                                 keystone_id=keystone_id)

        resp.status = falcon.HTTP_202
        resp.set_header('Location', '/{0}/orders/{1}'.format(keystone_id,
                                                             new_order.id))
        url = convert_order_to_href(keystone_id, new_order.id)
        resp.body = json.dumps({'order_ref': url})
Exemple #10
0
    def on_delete(self, external_project_id, **kwargs):
        data = api.load_body(pecan.request, validator=self.validator)
        LOG.debug(data)
        consumer = self.consumer_repo.get_by_values(
            self.container_id,
            data["name"],
            data["URL"],
            suppress_exception=True
        )
        if not consumer:
            _consumer_not_found()
        LOG.debug("Found consumer: %s", consumer)

        try:
            self.consumer_repo.delete_entity_by_id(consumer.id,
                                                   external_project_id)
        except exception.NotFound:
            LOG.exception(u._LE('Problem deleting consumer'))
            _consumer_not_found()

        ret_data = self._return_container_data(
            self.container_id,
            external_project_id
        )
        LOG.info(u._LI('Deleted a consumer for project: %s'),
                 external_project_id)
        return ret_data
Exemple #11
0
    def on_post(self, external_project_id, **kwargs):

        project = res.get_or_create_project(external_project_id)
        data = api.load_body(pecan.request, validator=self.validator)
        LOG.debug('Start on_post...%s', data)

        try:
            container = self.container_repo.get(self.container_id,
                                                external_project_id)
        except exception.NotFound:
            controllers.containers.container_not_found()

        self.quota_enforcer.enforce(project)

        new_consumer = models.ContainerConsumerMetadatum(self.container_id,
                                                         data)
        new_consumer.project_id = project.id
        self.consumer_repo.create_or_update_from(new_consumer, container)

        url = hrefs.convert_consumer_to_href(new_consumer.container_id)
        pecan.response.headers['Location'] = url

        LOG.info(u._LI('Created a consumer for project: %s'),
                 external_project_id)

        return self._return_container_data(self.container_id,
                                           external_project_id)
Exemple #12
0
    def on_delete(self, external_project_id, **kwargs):
        """Handles removing a secret reference from an existing container."""

        data = api.load_body(pecan.request, validator=self.validator)

        name = data.get('name')
        secret_ref = data.get('secret_ref')
        secret_id = hrefs.get_secret_id_from_ref(secret_ref)

        secret = self.secret_repo.get(
            entity_id=secret_id,
            external_project_id=external_project_id,
            suppress_exception=True)
        if not secret:
            pecan.abort(404, u._("Secret '{secret_name}' with reference "
                                 "'{secret_ref}' doesn't exist.").format(
                                     secret_name=name, secret_ref=secret_ref))

        found_container_secrets = list(
            filter(lambda cs: cs.secret_id == secret_id and cs.name == name,
                   self.container.container_secrets)
        )

        if not found_container_secrets:
            pecan.abort(404, u._('Secret provided is not in the container'))

        for container_secret in found_container_secrets:
            self.container_secret_repo.delete_entity_by_id(
                container_secret.id, external_project_id)

        pecan.response.status = 204
        LOG.info(u._LI('Deleted container secret for project: %s'),
                 external_project_id)
Exemple #13
0
    def on_post(self, keystone_id, **kwargs):

        tenant = res.get_or_create_tenant(keystone_id, self.tenant_repo)

        data = api.load_body(pecan.request, validator=self.validator)
        LOG.debug('Start on_post...%s', data)

        new_container = models.Container(data)
        new_container.tenant_id = tenant.id

        #TODO(hgedikli): performance optimizations
        for secret_ref in new_container.container_secrets:
            secret = self.secret_repo.get(entity_id=secret_ref.secret_id,
                                          keystone_id=keystone_id,
                                          suppress_exception=True)
            if not secret:
                # This only partially localizes the error message and
                # doesn't localize secret_ref.name.
                pecan.abort(404, u._("Secret provided for '{0}' doesn't"
                                     " exist.").format(secret_ref.name))

        self.container_repo.create_from(new_container)

        pecan.response.status = 201
        pecan.response.headers['Location'] = '/{0}/containers/{1}'.format(
            keystone_id, new_container.id
        )
        url = controllers.hrefs.convert_container_to_href(new_container.id)
        return {'container_ref': url}
Exemple #14
0
    def on_put(self, external_project_id, **kwargs):
        body = api.load_body(pecan.request,
                             validator=self.type_order_validator)

        project = res.get_or_create_project(external_project_id)
        order_type = body.get('type')

        request_id = None
        ctxt = controllers._get_barbican_context(pecan.request)
        if ctxt and ctxt.request_id:
            request_id = ctxt.request_id

        if self.order.type != order_type:
            order_cannot_modify_order_type()

        if models.OrderType.CERTIFICATE != self.order.type:
            _order_update_not_supported_for_type(order_type)

        if models.States.PENDING != self.order.status:
            _order_cannot_be_updated_if_not_pending(self.order.status)

        updated_meta = body.get('meta')
        validators.validate_ca_id(project.id, updated_meta)

        # TODO(chellygel): Put 'meta' into a separate order association
        # entity.
        self.queue.update_order(order_id=self.order.id,
                                project_id=external_project_id,
                                updated_meta=updated_meta,
                                request_id=request_id)
Exemple #15
0
    def on_post(self, external_project_id, **kwargs):
        LOG.debug('Start on_post for project-ID %s:...', external_project_id)

        data = api.load_body(pecan.request, validator=self.validator)
        project = res.get_or_create_project(external_project_id)

        ctxt = controllers._get_barbican_context(pecan.request)
        if ctxt:  # in authenticated pipeline case, always use auth token user
            creator_id = ctxt.user

        self.quota_enforcer.enforce(project)

        new_ca = cert_resources.create_subordinate_ca(
            project_model=project,
            name=data.get('name'),
            description=data.get('description'),
            subject_dn=data.get('subject_dn'),
            parent_ca_ref=data.get('parent_ca_ref'),
            creator_id=creator_id
        )

        url = hrefs.convert_certificate_authority_to_href(new_ca.id)
        LOG.debug('URI to sub-CA is %s', url)

        pecan.response.status = 201
        pecan.response.headers['Location'] = url

        LOG.info(u._LI('Created a sub CA for project: %s'),
                 external_project_id)

        return {'ca_ref': url}
Exemple #16
0
    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 project-access in ACL, true 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"
            ],
            "project-access":false
          }
        }

        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 six.moves.filter(lambda x: data.get(x),
                                          validators.ACL_OPERATIONS):
            project_access = data[operation].get('project-access', True)
            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.project_access = project_access
            else:
                s_acl = models.SecretACL(self.secret.id, operation=operation,
                                         project_access=project_access)
            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 existing_acls_map.values():
            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}
Exemple #17
0
    def on_put(self, external_project_id, **kwargs):
        """Handles creation/update of secret metadata."""
        data = api.load_body(pecan.request, validator=self.metadata_validator)
        LOG.debug('Start secret metadata on_put...%s', data)

        self.user_meta_repo.create_replace_user_metadata(self.secret.id, data)

        url = hrefs.convert_user_meta_to_href(self.secret.id)
        LOG.debug('URI to secret metadata is %s', url)

        pecan.response.status = 201
        return {'metadata_ref': url}
Exemple #18
0
    def on_patch(self, external_project_id, **kwargs):
        """Handles update of existing container acl requests.

        At least one container ACL needs to exist for update to proceed.
        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
          }
        }
        """
        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)

        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')
            user_ids = data[operation].get('users')
            if operation in existing_acls_map:  # update if matching acl exists
                c_acl = existing_acls_map[operation]
                if creator_only is not None:
                    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)

        return self._return_acl_hrefs(self.container.id)
Exemple #19
0
    def on_post(self, external_project_id, **kwargs):
        project = res.get_or_create_project(external_project_id)

        body = api.load_body(pecan.request,
                             validator=self.type_order_validator)

        order_type = body.get('type')
        order_meta = body.get('meta')
        request_type = order_meta.get('request_type')

        LOG.debug('Processing order type %s, request type %s',
                  order_type, request_type)

        if order_type == models.OrderType.CERTIFICATE:
            validators.validate_ca_id(project.id, body.get('meta'))
            if request_type == 'stored-key':
                container_ref = order_meta.get('container_ref')
                validators.validate_stored_key_rsa_container(
                    external_project_id,
                    container_ref, pecan.request)

        self.quota_enforcer.enforce(project)

        new_order = models.Order()
        new_order.meta = body.get('meta')
        new_order.type = order_type
        new_order.project_id = project.id

        request_id = None
        ctxt = controllers._get_barbican_context(pecan.request)
        if ctxt:
            new_order.creator_id = ctxt.user
            request_id = ctxt.request_id

        self.order_repo.create_from(new_order)

        # Grab our id before commit due to obj expiration from sqlalchemy
        order_id = new_order.id

        # Force commit to avoid async issues with the workers
        repo.commit()

        self.queue.process_type_order(order_id=order_id,
                                      project_id=external_project_id,
                                      request_id=request_id)

        url = hrefs.convert_order_to_href(order_id)

        pecan.response.status = 202
        pecan.response.headers['Location'] = url

        return {'order_ref': url}
Exemple #20
0
    def on_put(self, external_project_id, **kwargs):
        """Handles creation/update of secret metadata."""
        data = api.load_body(pecan.request, validator=self.metadata_validator)
        LOG.debug('Start secret metadata on_put...%s', data)

        self.user_meta_repo.create_replace_user_metadata(self.secret.id,
                                                         data)

        url = hrefs.convert_user_meta_to_href(self.secret.id)
        LOG.debug('URI to secret metadata is %s', url)

        pecan.response.status = 201
        return {'metadata_ref': url}
Exemple #21
0
    def on_post(self, external_project_id, **kwargs):
        project = res.get_or_create_project(external_project_id)

        body = api.load_body(pecan.request,
                             validator=self.type_order_validator)

        order_type = body.get('type')
        order_meta = body.get('meta')
        request_type = order_meta.get('request_type')

        LOG.debug('Processing order type %s, request type %s', order_type,
                  request_type)

        if order_type == models.OrderType.CERTIFICATE:
            validators.validate_ca_id(project.id, body.get('meta'))
            if request_type == 'stored-key':
                container_ref = order_meta.get('container_ref')
                validators.validate_stored_key_rsa_container(
                    external_project_id, container_ref, pecan.request)

        self.quota_enforcer.enforce(project)

        new_order = models.Order()
        new_order.meta = body.get('meta')
        new_order.type = order_type
        new_order.project_id = project.id

        request_id = None
        ctxt = controllers._get_barbican_context(pecan.request)
        if ctxt:
            new_order.creator_id = ctxt.user
            request_id = ctxt.request_id

        self.order_repo.create_from(new_order)

        # Grab our id before commit due to obj expiration from sqlalchemy
        order_id = new_order.id

        # Force commit to avoid async issues with the workers
        repo.commit()

        self.queue.process_type_order(order_id=order_id,
                                      project_id=external_project_id,
                                      request_id=request_id)

        url = hrefs.convert_order_to_href(order_id)

        pecan.response.status = 202
        pecan.response.headers['Location'] = url

        return {'order_ref': url}
Exemple #22
0
    def on_patch(self, external_project_id, **kwargs):
        """Handles update of existing secret acl requests.

        At least one secret ACL needs to exist for update to proceed.
        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"
            ],
            "project-access":true
          }
        }
        """
        data = api.load_body(pecan.request, validator=self.validator)
        LOG.debug('Start on_patch...%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):
            project_access = data[operation].get('project-access')
            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[operation]
                if project_access is not None:
                    s_acl.project_access = project_access
            else:
                s_acl = models.SecretACL(self.secret.id,
                                         operation=operation,
                                         project_access=project_access)
            self.acl_repo.create_or_replace_from(self.secret,
                                                 secret_acl=s_acl,
                                                 user_ids=user_ids)

        acl_ref = '{0}/acl'.format(hrefs.convert_secret_to_href(
            self.secret.id))
        return {'acl_ref': acl_ref}
Exemple #23
0
    def on_post(self, req, resp, tenant_id):

        # Retrieve Tenant, or else create new Tenant
        #   if this is a request from a new tenant.
        tenant = self.tenant_repo.get(tenant_id, suppress_exception=True)
        if not tenant:
            tenant = Tenant()
            tenant.keystone_id = tenant_id
            tenant.status = States.ACTIVE
            self.tenant_repo.create_from(tenant)

        body = load_body(req)
        LOG.debug('Start on_post...{0}'.format(body))

        if 'secret' not in body:
            _secret_not_in_order()
        secret_info = body['secret']
        name = secret_info['name']
        LOG.debug('Secret to create is {0}'.format(name))

        # TODO: What criteria to restrict multiple concurrent Order
        #      requests per tenant?
        # order = self.order_repo.find_by_name(name=secret_name,
        #                                  suppress_exception=True)
        # if order:
        #    abort(falcon.HTTP_400, 'Order with username {0} '
        #                           'already exists'.format(username))

        # TODO: Encrypt fields as needed

        new_order = Order()
        new_order.secret_name = secret_info['name']
        new_order.secret_algorithm = secret_info.get('algorithm', None)
        new_order.secret_bit_length = secret_info.get('bit_length', None)
        new_order.secret_cypher_type = secret_info.get('cypher_type', None)
        new_order.secret_mime_type = secret_info['mime_type']
        new_order.secret_expiration = secret_info.get('expiration', None)

        new_order.tenant_id = tenant.id
        self.order_repo.create_from(new_order)

        # Send to workers to process.
        self.queue.process_order(order_id=new_order.id)

        resp.status = falcon.HTTP_202
        resp.set_header('Location', '/{0}/orders/{1}'.format(tenant_id,
                                                             new_order.id))
        url = convert_order_to_href(tenant_id, new_order.id)
        resp.body = json.dumps({'order_ref': url})
Exemple #24
0
    def on_patch(self, external_project_id, **kwargs):
        """Handles update of existing container acl requests.

        At least one container ACL needs to exist for update to proceed.
        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"
            ],
            "project-access":false
          }
        }
        """
        data = api.load_body(pecan.request, validator=self.validator)
        LOG.debug('Start ContainerACLsController on_patch...%s', data)

        existing_acls_map = {acl.operation: acl for acl in
                             self.container.container_acls}
        for operation in six.moves.filter(lambda x: data.get(x),
                                          validators.ACL_OPERATIONS):
            project_access = data[operation].get('project-access')
            user_ids = data[operation].get('users')
            if operation in existing_acls_map:  # update if matching acl exists
                c_acl = existing_acls_map[operation]
                if project_access is not None:
                    c_acl.project_access = project_access
            else:
                c_acl = models.ContainerACL(self.container.id,
                                            operation=operation,
                                            project_access=project_access)
            self.acl_repo.create_or_replace_from(self.container,
                                                 container_acl=c_acl,
                                                 user_ids=user_ids)

        acl_ref = '{0}/acl'.format(
            hrefs.convert_container_to_href(self.container.id))
        return {'acl_ref': acl_ref}
Exemple #25
0
    def on_post(self, req, resp, tenant_id):
        LOG.debug('Start on_post for tenant-ID {0}:'.format(tenant_id))

        data = load_body(req)
        tenant = get_or_create_tenant(tenant_id, self.tenant_repo)

        new_secret = create_secret(data, tenant, self.crypto_manager,
                                   self.secret_repo, self.tenant_secret_repo,
                                   self.datum_repo)

        resp.status = falcon.HTTP_202
        resp.set_header('Location', '/{0}/secrets/{1}'.format(tenant_id,
                                                              new_secret.id))
        url = convert_secret_to_href(tenant_id, new_secret.id)
        LOG.debug('URI to secret is {0}'.format(url))
        resp.body = json.dumps({'secret_ref': url})
Exemple #26
0
    def on_post(self, external_project_id, **kwargs):
        """Handles adding an existing secret to an existing container."""

        if self.container.type != 'generic':
            pecan.abort(400, u._("Only 'generic' containers can be modified."))

        data = api.load_body(pecan.request, validator=self.validator)

        name = data.get('name')
        secret_ref = data.get('secret_ref')
        secret_id = hrefs.get_secret_id_from_ref(secret_ref)

        secret = self.secret_repo.get(
            entity_id=secret_id,
            external_project_id=external_project_id,
            suppress_exception=True)
        if not secret:
            pecan.abort(404, u._("Secret provided doesn't exist."))

        found_container_secrets = list(
            filter(lambda cs: cs.secret_id == secret_id and cs.name == name,
                   self.container.container_secrets)
        )

        if found_container_secrets:
            pecan.abort(409, u._('Conflict. A secret with that name and ID is '
                                 'already stored in this container. The same '
                                 'secret can exist in a container as long as '
                                 'the name is unique.'))

        LOG.debug('Start container secret on_post...%s', secret_ref)
        new_container_secret = models.ContainerSecret()
        new_container_secret.container_id = self.container.id
        new_container_secret.name = name
        new_container_secret.secret_id = secret_id
        self.container_secret_repo.save(new_container_secret)

        url = hrefs.convert_container_to_href(self.container.id)
        LOG.debug('URI to container is %s', url)

        pecan.response.status = 201
        pecan.response.headers['Location'] = url
        LOG.info(u._LI('Created a container secret for project: %s'),
                 external_project_id)

        return {'container_ref': url}
Exemple #27
0
    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)
Exemple #28
0
    def on_post(self, external_project_id, **kwargs):
        """Handles adding an existing secret to an existing container."""

        if self.container.type != 'generic':
            pecan.abort(400, u._("Only 'generic' containers can be modified."))

        data = api.load_body(pecan.request, validator=self.validator)

        name = data.get('name')
        secret_ref = data.get('secret_ref')
        secret_id = hrefs.get_secret_id_from_ref(secret_ref)

        secret = self.secret_repo.get(
            entity_id=secret_id,
            external_project_id=external_project_id,
            suppress_exception=True)
        if not secret:
            pecan.abort(404, u._("Secret provided doesn't exist."))

        found_container_secrets = list(
            filter(lambda cs: cs.secret_id == secret_id and cs.name == name,
                   self.container.container_secrets)
        )

        if found_container_secrets:
            pecan.abort(409, u._('Conflict. A secret with that name and ID is '
                                 'already stored in this container. The same '
                                 'secret can exist in a container as long as '
                                 'the name is unique.'))

        LOG.debug('Start container secret on_post...%s', secret_ref)
        new_container_secret = models.ContainerSecret()
        new_container_secret.container_id = self.container.id
        new_container_secret.name = name
        new_container_secret.secret_id = secret_id
        self.container_secret_repo.save(new_container_secret)

        url = hrefs.convert_container_to_href(self.container.id)
        LOG.debug(u._('URI to container is %s'), url)

        pecan.response.status = 201
        pecan.response.headers['Location'] = url
        LOG.info(u._LI('Created a container secret for project: %s'),
                 external_project_id)

        return {'container_ref': url}
Exemple #29
0
    def on_post(self, req, resp, keystone_id):
        LOG.debug('Start on_post for tenant-ID {0}:...'.format(keystone_id))

        data = api.load_body(req, resp, self.validator)
        tenant = res.get_or_create_tenant(keystone_id, self.tenant_repo)

        new_secret = res.create_secret(data, tenant, self.crypto_manager,
                                       self.secret_repo,
                                       self.tenant_secret_repo,
                                       self.datum_repo,
                                       self.kek_repo)

        resp.status = falcon.HTTP_201
        resp.set_header('Location', '/{0}/secrets/{1}'.format(keystone_id,
                                                              new_secret.id))
        url = convert_secret_to_href(keystone_id, new_secret.id)
        LOG.debug('URI to secret is {0}'.format(url))
        resp.body = json.dumps({'secret_ref': url})
Exemple #30
0
    def on_delete(self, external_project_id, **kwargs):
        data = api.load_body(pecan.request, validator=self.validator)
        LOG.debug(data)
        consumer = self.consumer_repo.get_by_values(self.container_id,
                                                    data["name"],
                                                    data["URL"],
                                                    suppress_exception=True)
        if not consumer:
            _consumer_not_found()
        LOG.debug("Found consumer: %s", consumer)

        try:
            self.consumer_repo.delete_entity_by_id(consumer.id,
                                                   external_project_id)
        except exception.NotFound:
            LOG.exception(u._LE('Problem deleting consumer'))
            _consumer_not_found()
        return self._return_container_data(self.container_id,
                                           external_project_id)
Exemple #31
0
    def on_post(self, keystone_id, **kwargs):
        LOG.debug('Start on_post for tenant-ID {0}:...'.format(keystone_id))

        data = api.load_body(pecan.request, validator=self.validator)
        tenant = res.get_or_create_tenant(keystone_id, self.tenant_repo)

        new_secret = res.create_secret(data, tenant, self.crypto_manager,
                                       self.secret_repo,
                                       self.tenant_secret_repo,
                                       self.datum_repo,
                                       self.kek_repo)

        pecan.response.status = 201
        pecan.response.headers['Location'] = '/{0}/secrets/{1}'.format(
            keystone_id, new_secret.id
        )
        url = hrefs.convert_secret_to_href(keystone_id, new_secret.id)
        LOG.debug('URI to secret is {0}'.format(url))
        return {'secret_ref': url}
Exemple #32
0
    def on_post(self, external_project_id, **kwargs):

        project = res.get_or_create_project(external_project_id)
        data = api.load_body(pecan.request, validator=self.validator)
        LOG.debug('Start on_post...%s', data)

        self.quota_enforcer.enforce(project)

        new_consumer = models.ContainerConsumerMetadatum(
            self.container_id, project.id, data)
        self.consumer_repo.create_or_update_from(new_consumer, self.container)

        url = hrefs.convert_consumer_to_href(new_consumer.container_id)
        pecan.response.headers['Location'] = url

        LOG.info('Created a container consumer for project: %s',
                 external_project_id)

        return self._return_container_data()
Exemple #33
0
    def on_delete(self, keystone_id, **kwargs):
        data = api.load_body(pecan.request, validator=self.validator)
        LOG.debug(data)
        consumer = self.consumer_repo.get_by_values(
            self.container_id,
            data["name"],
            data["URL"],
            suppress_exception=True
        )
        if not consumer:
            _consumer_not_found()
        LOG.debug("Found consumer: %s", consumer)

        try:
            self.consumer_repo.delete_entity_by_id(consumer.id, keystone_id)
        except exception.NotFound:
            LOG.exception('Problem deleting consumer')
            _consumer_not_found()
        return self._return_container_data(self.container_id, keystone_id)
Exemple #34
0
    def on_post(self, keystone_id):
        LOG.debug('Start on_post for tenant-ID {0}:...'.format(keystone_id))

        data = api.load_body(pecan.request, validator=self.validator)
        tenant = res.get_or_create_tenant(keystone_id, self.tenant_repo)

        new_secret = res.create_secret(data, tenant, self.crypto_manager,
                                       self.secret_repo,
                                       self.tenant_secret_repo,
                                       self.datum_repo,
                                       self.kek_repo)

        pecan.response.status = 201
        pecan.response.headers['Location'] = '/{0}/secrets/{1}'.format(
            keystone_id, new_secret.id
        )
        url = hrefs.convert_secret_to_href(keystone_id, new_secret.id)
        LOG.debug('URI to secret is {0}'.format(url))
        return {'secret_ref': url}
Exemple #35
0
    def on_post(self, keystone_id, **kwargs):
        LOG.debug('Start on_post for tenant-ID {0}:...'.format(keystone_id))

        data = api.load_body(pecan.request, validator=self.validator)
        tenant = res.get_or_create_tenant(keystone_id, self.repos.tenant_repo)

        new_secret = plugin.store_secret(data.get('payload'),
                                         data.get('payload_content_type',
                                                  'application/octet-stream'),
                                         data.get('payload_content_encoding'),
                                         data, None, tenant,
                                         self.repos)

        pecan.response.status = 201
        pecan.response.headers['Location'] = '/{0}/secrets/{1}'.format(
            keystone_id, new_secret.id
        )
        url = hrefs.convert_secret_to_href(keystone_id, new_secret.id)
        LOG.debug('URI to secret is {0}'.format(url))
        return {'secret_ref': url}
Exemple #36
0
    def on_post(self, keystone_id, **kwargs):

        tenant = res.get_or_create_tenant(keystone_id, self.tenant_repo)
        data = api.load_body(pecan.request, validator=self.validator)
        LOG.debug('Start on_post...%s', data)

        try:
            self.container_repo.get(self.container_id, keystone_id)
        except exception.NotFound:
            controllers.containers.container_not_found()

        new_consumer = models.ContainerConsumerMetadatum(self.container_id,
                                                         data)
        new_consumer.tenant_id = tenant.id
        self.consumer_repo.create_from(new_consumer)

        pecan.response.headers['Location'] = '/{0}/containers/{1}/consumers' \
            .format(keystone_id, new_consumer.container_id)

        return self._return_container_data(self.container_id, keystone_id)
Exemple #37
0
    def on_post(self, keystone_id):
        LOG.debug('Start transport_keys on_post')

        # TODO(alee) POST should determine the plugin name and call the
        # relevant get_transport_key() call.  We will implement this once
        # we figure out how the plugins will be enumerated.

        data = api.load_body(pecan.request, validator=self.validator)

        new_key = models.TransportKey(data.get('plugin_name'),
                                      data.get('transport_key'))

        self.repo.create_from(new_key)

        pecan.response.status = 201
        pecan.response.headers['Location'] = '/{0}/transport_keys/{1}'.format(
            keystone_id, new_key.id)
        url = hrefs.convert_transport_key_to_href(keystone_id, new_key.id)
        LOG.debug('URI to transport key is {0}'.format(url))
        return {'transport_key_ref': url}
Exemple #38
0
    def on_post(self, external_project_id, **kwargs):
        LOG.debug('Start on_post for project-ID %s:...',
                  external_project_id)

        data = api.load_body(pecan.request, validator=self.validator)
        project = res.get_or_create_project(external_project_id)

        self.quota_enforcer.enforce(project)

        transport_key_needed = data.get('transport_key_needed',
                                        'false').lower() == 'true'
        ctxt = controllers._get_barbican_context(pecan.request)
        if ctxt:  # in authenticated pipleline case, always use auth token user
            data['creator_id'] = ctxt.user

        secret_model = models.Secret(data)

        new_secret, transport_key_model = plugin.store_secret(
            unencrypted_raw=data.get('payload'),
            content_type_raw=data.get('payload_content_type',
                                      'application/octet-stream'),
            content_encoding=data.get('payload_content_encoding'),
            secret_model=secret_model,
            project_model=project,
            transport_key_needed=transport_key_needed,
            transport_key_id=data.get('transport_key_id'))

        url = hrefs.convert_secret_to_href(new_secret.id)
        LOG.debug('URI to secret is %s', url)

        pecan.response.status = 201
        pecan.response.headers['Location'] = url

        LOG.info('Created a secret for project: %s',
                 external_project_id)
        if transport_key_model is not None:
            tkey_url = hrefs.convert_transport_key_to_href(
                transport_key_model.id)
            return {'secret_ref': url, 'transport_key_ref': tkey_url}
        else:
            return {'secret_ref': url}
Exemple #39
0
    def on_post(self, external_project_id, **kwargs):

        project = res.get_or_create_project(external_project_id)

        data = api.load_body(pecan.request, validator=self.validator)
        ctxt = controllers._get_barbican_context(pecan.request)
        if ctxt:  # in authenticated pipleline case, always use auth token user
            data['creator_id'] = ctxt.user

        self.quota_enforcer.enforce(project)

        LOG.debug('Start on_post...%s', data)

        new_container = models.Container(data)
        new_container.project_id = project.id

        # TODO(hgedikli): performance optimizations
        for secret_ref in new_container.container_secrets:
            secret = self.secret_repo.get(
                entity_id=secret_ref.secret_id,
                external_project_id=external_project_id,
                suppress_exception=True)
            if not secret:
                # This only partially localizes the error message and
                # doesn't localize secret_ref.name.
                pecan.abort(
                    404,
                    u._("Secret provided for '{secret_name}' doesn't "
                        "exist.").format(secret_name=secret_ref.name)
                )

        self.container_repo.create_from(new_container)

        url = hrefs.convert_container_to_href(new_container.id)

        pecan.response.status = 201
        pecan.response.headers['Location'] = url
        LOG.info(u._LI('Created a container for project: %s'),
                 external_project_id)

        return {'container_ref': url}
Exemple #40
0
    def on_post(self, external_project_id, **kwargs):

        project = res.get_or_create_project(external_project_id)

        data = api.load_body(pecan.request, validator=self.validator)
        ctxt = controllers._get_barbican_context(pecan.request)
        if ctxt:  # in authenticated pipleline case, always use auth token user
            data['creator_id'] = ctxt.user

        self.quota_enforcer.enforce(project)

        LOG.debug('Start on_post...%s', data)

        new_container = models.Container(data)
        new_container.project_id = project.id

        # TODO(hgedikli): performance optimizations
        for secret_ref in new_container.container_secrets:
            secret = self.secret_repo.get(
                entity_id=secret_ref.secret_id,
                external_project_id=external_project_id,
                suppress_exception=True)
            if not secret:
                # This only partially localizes the error message and
                # doesn't localize secret_ref.name.
                pecan.abort(
                    404,
                    u._("Secret provided for '{secret_name}' doesn't "
                        "exist.").format(secret_name=secret_ref.name)
                )

        self.container_repo.create_from(new_container)

        url = hrefs.convert_container_to_href(new_container.id)

        pecan.response.status = 201
        pecan.response.headers['Location'] = url
        LOG.info(u._LI('Created a container for project: %s'),
                 external_project_id)

        return {'container_ref': url}
Exemple #41
0
    def on_post(self, req, resp, keystone_id):
        LOG.debug('Start on_post for tenant-ID {0}:...'.format(keystone_id))

        data = api.load_body(req, resp, self.validator)
        tenant = res.get_or_create_tenant(keystone_id, self.tenant_repo)

        new_verification = models.Verification(data)
        new_verification.tenant_id = tenant.id
        self.verification_repo.create_from(new_verification)

        # Send to workers to process.
        self.queue.process_verification(verification_id=new_verification.id,
                                        keystone_id=keystone_id)

        resp.status = falcon.HTTP_202
        resp.set_header('Location',
                        '/{0}/verifications/{1}'.format(keystone_id,
                                                        new_verification.id))
        url = convert_verification_to_href(keystone_id, new_verification.id)
        LOG.debug('URI to verification is {0}'.format(url))
        resp.body = json.dumps({'verification_ref': url})
Exemple #42
0
    def on_post(self, keystone_id, **kwargs):
        LOG.debug('Start transport_keys on_post')

        # TODO(alee) POST should determine the plugin name and call the
        # relevant get_transport_key() call.  We will implement this once
        # we figure out how the plugins will be enumerated.

        data = api.load_body(pecan.request, validator=self.validator)

        new_key = models.TransportKey(data.get('plugin_name'),
                                      data.get('transport_key'))

        self.repo.create_from(new_key)

        pecan.response.status = 201
        pecan.response.headers['Location'] = '/{0}/transport_keys/{1}'.format(
            keystone_id, new_key.id
        )
        url = hrefs.convert_transport_key_to_href(keystone_id, new_key.id)
        LOG.debug('URI to transport key is {0}'.format(url))
        return {'transport_key_ref': url}
Exemple #43
0
    def on_put(self, external_project_id, remainder, **kwargs):
        """Handles update of existing secret metadatum."""
        metadata = self.user_meta_repo.get_metadata_for_secret(self.secret.id)
        data = api.load_body(pecan.request, validator=self.metadatum_validator)

        key = data.get('key')
        value = data.get('value')

        if remainder not in metadata:
            _secret_metadata_not_found()
        elif remainder != key:
            msg = 'Key in request data does not match key in the '
            'request url.'
            pecan.abort(409, msg)
        else:
            LOG.debug('Start secret metadatum on_put...%s', metadata)

            self.user_meta_repo.create_replace_user_metadatum(self.secret.id,
                                                              key, value)

            pecan.response.status = 200
            pair = {'key': key, 'value': value}
            return collections.OrderedDict(sorted(pair.items()))
Exemple #44
0
    def on_post(self, external_project_id, **kwargs):

        project = res.get_or_create_project(external_project_id,
                                            self.project_repo)
        data = api.load_body(pecan.request, validator=self.validator)
        LOG.debug('Start on_post...%s', data)

        try:
            container = self.container_repo.get(self.container_id,
                                                external_project_id)
        except exception.NotFound:
            controllers.containers.container_not_found()

        new_consumer = models.ContainerConsumerMetadatum(
            self.container_id, data)
        new_consumer.project_id = project.id
        self.consumer_repo.create_or_update_from(new_consumer, container)

        pecan.response.headers['Location'] = (
            '/containers/{0}/consumers'.format(new_consumer.container_id))

        return self._return_container_data(self.container_id,
                                           external_project_id)
Exemple #45
0
    def on_post(self, external_project_id, **kwargs):
        """Handles creation of secret metadatum."""

        data = api.load_body(pecan.request, validator=self.metadatum_validator)

        key = data.get('key')
        value = data.get('value')

        metadata = self.user_meta_repo.get_metadata_for_secret(self.secret.id)
        if key in metadata:
            pecan.abort(409, u._('Conflict. Key in request is already in the '
                                 'secret metadata'))

        LOG.debug('Start secret metadatum on_post...%s', metadata)
        self.user_meta_repo.create_replace_user_metadatum(self.secret.id,
                                                          key, value)

        url = hrefs.convert_user_meta_to_href(self.secret.id)
        LOG.debug('URI to secret metadata is %s', url)

        pecan.response.status = 201
        pecan.response.headers['Location'] = url + '/' + key
        return {'key': key, 'value': value}
Exemple #46
0
    def on_post(self, external_project_id, **kwargs):

        project = res.get_or_create_project(external_project_id,
                                            self.project_repo)

        body = api.load_body(pecan.request,
                             validator=self.type_order_validator)
        order_type = body.get('type')
        LOG.debug('Processing order type %s', order_type)

        new_order = models.Order()
        new_order.meta = body.get('meta')
        new_order.type = order_type
        new_order.project_id = project.id

        self.order_repo.create_from(new_order)

        self.queue.process_type_order(order_id=new_order.id,
                                      project_id=external_project_id)
        pecan.response.status = 202
        pecan.response.headers['Location'] = '/{0}/orders/{1}'.format(
            external_project_id, new_order.id)
        url = hrefs.convert_order_to_href(new_order.id)
        return {'order_ref': url}
Exemple #47
0
    def on_put(self, external_project_id, **kwargs):
        body = api.load_body(pecan.request,
                             validator=self.type_order_validator)

        project = res.get_or_create_project(external_project_id)
        order_type = body.get('type')

        if self.order.type != order_type:
            order_cannot_modify_order_type()

        if models.OrderType.CERTIFICATE != self.order.type:
            _order_update_not_supported_for_type(order_type)

        if models.States.PENDING != self.order.status:
            _order_cannot_be_updated_if_not_pending(self.order.status)

        updated_meta = body.get('meta')
        validators.validate_ca_id(project.id, updated_meta)

        # TODO(chellygel): Put 'meta' into a separate order association
        # entity.
        self.queue.update_order(order_id=self.order.id,
                                project_id=external_project_id,
                                updated_meta=updated_meta)
Exemple #48
0
 def on_post(self, external_project_id):
     data = api.load_body(pecan.request)
     response = plugin.update_policy(data, external_project_id)
     return response
Exemple #49
0
 def on_post(self, external_project_id):
     data = api.load_body(pecan.request)
     response = plugin.do_provision_kek(data, external_project_id)
     return response
Exemple #50
0
    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 project-access in ACL, true 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"
            ],
            "project-access":false
          }
        }

        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):
            project_access = data[operation].get('project-access', True)
            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.project_access = project_access
            else:
                c_acl = models.ContainerACL(self.container.id,
                                            operation=operation,
                                            project_access=project_access)
            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}