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
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
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}
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})
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}
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']}
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}
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})
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})
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
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)
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)
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}
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)
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}
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}
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}
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)
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}
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}
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})
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}
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})
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}
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)
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}
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})
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)
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}
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()
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)
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}
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}
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)
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}
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}
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}
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})
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}
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()))
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)
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}
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}
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)
def on_post(self, external_project_id): data = api.load_body(pecan.request) response = plugin.update_policy(data, external_project_id) return response
def on_post(self, external_project_id): data = api.load_body(pecan.request) response = plugin.do_provision_kek(data, external_project_id) return response
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}