def authorize_quota_class_context(context, class_name): """Ensures a request has permission to access the given quota class.""" if is_user_context(context): if not context.quota_class: raise exception.NotAuthorized() elif context.quota_class != class_name: raise exception.NotAuthorized()
def authorize_user_context(context, user_id): """Ensures a request has permission to access the given user.""" if is_user_context(context): if not context.user_id: raise exception.NotAuthorized() elif context.user_id != user_id: raise exception.NotAuthorized()
def authorize_project_context(context, project_id): """Ensures a request has permission to access the given project.""" if is_user_context(context): if not context.project_id: raise exception.NotAuthorized() elif context.project_id != project_id: raise exception.NotAuthorized()
def _translate_plain_exception(exc_value): if isinstance(exc_value, (glance_exc.Forbidden, glance_exc.Unauthorized)): return exception.NotAuthorized(exc_value) if isinstance(exc_value, glance_exc.NotFound): return exception.NotFound(exc_value) if isinstance(exc_value, glance_exc.BadRequest): return exception.Invalid(exc_value) return exc_value
def test_render_http_exception(self): error_dict = { 'faultcode': '403', 'faultstring': 'Not authorized', 'debuginfo': None } try: e = exception.NotAuthorized() e.code = 403 except exception.IronicException: excinfo = sys.exc_info() self.assertEqual( json.dumps(error_dict), self.renderer.render('/', expose.format_exception(excinfo)))
def post(self, allocation): """Create a new allocation. :param allocation: an allocation within the request body. """ context = api.request.context cdict = context.to_policy_values() allocation = self._authorize_create_allocation(allocation) if (allocation.get('name') and not api_utils.is_valid_logical_name(allocation['name'])): msg = _("Cannot create allocation with invalid name " "'%(name)s'") % { 'name': allocation['name'] } raise exception.Invalid(msg) # TODO(TheJulia): We need to likely look at refactoring post # processing for allocations as pep8 says it is a complexity of 19, # although it is not actually that horrible since it is phased out # just modifying/assembling the allocation. Given that, it seems # not great to try for a full method rewrite at the same time as # RBAC work, so the complexity limit is being raised. :( if (CONF.oslo_policy.enforce_new_defaults and cdict.get('system_scope') != 'all'): # if not a system scope originated request, we need to check/apply # an owner - But we can only do this with when new defaults are # enabled. project_id = cdict.get('project_id') req_alloc_owner = allocation.get('owner') if req_alloc_owner: if not api_utils.check_policy_true( 'baremetal:allocation:create_restricted'): if req_alloc_owner != project_id: msg = _("Cannot create allocation with an owner " "Project ID value %(req_owner)s not matching " "the requestor Project ID %(project)s. " "Policy baremetal:allocation:create_restricted" " is required for this capability.") % { 'req_owner': req_alloc_owner, 'project': project_id } raise exception.NotAuthorized(msg) # NOTE(TheJulia): IF not restricted, i.e. else above, # their supplied allocation owner is okay, they are allowed # to provide an override by policy. else: # An allocation owner was not supplied, we need to save one. allocation['owner'] = project_id node = None if allocation.get('node'): if api_utils.allow_allocation_backfill(): try: node = api_utils.get_rpc_node(allocation['node']) api_utils.check_owner_policy( 'node', 'baremetal:node:get', node.owner, node.lessee, conceal_node=allocation['node']) except exception.NodeNotFound as exc: exc.code = http_client.BAD_REQUEST raise else: msg = _("Cannot set node when creating an allocation " "in this API version") raise exception.Invalid(msg) if not allocation.get('resource_class'): if node: allocation['resource_class'] = node.resource_class else: msg = _("The resource_class field is mandatory when not " "backfilling") raise exception.Invalid(msg) if allocation.get('candidate_nodes'): # Convert nodes from names to UUIDs and check their validity try: owner = None if not api_utils.check_policy_true( 'baremetal:allocation:create_restricted'): owner = cdict.get('project_id') # Filter the candidate search by the requestor project ID # if any. The result is processes authenticating with system # scope will not be impacted, where as project scoped requests # will need additional authorization. converted = api.request.dbapi.check_node_list( allocation['candidate_nodes'], project=owner) except exception.NodeNotFound as exc: exc.code = http_client.BAD_REQUEST raise else: # Make sure we keep the ordering of candidate nodes. allocation['candidate_nodes'] = [ converted[ident] for ident in allocation['candidate_nodes'] ] # NOTE(yuriyz): UUID is mandatory for notifications payload if not allocation.get('uuid'): if node and node.instance_uuid: # When backfilling without UUID requested, assume that the # target instance_uuid is the desired UUID allocation['uuid'] = node.instance_uuid else: allocation['uuid'] = uuidutils.generate_uuid() new_allocation = objects.Allocation(context, **allocation) if node: new_allocation.node_id = node.id topic = api.request.rpcapi.get_topic_for(node) else: topic = api.request.rpcapi.get_random_topic() notify.emit_start_notification(context, new_allocation, 'create') with notify.handle_error_notification(context, new_allocation, 'create'): new_allocation = api.request.rpcapi.create_allocation( context, new_allocation, topic) notify.emit_end_notification(context, new_allocation, 'create') # Set the HTTP Location Header api.response.location = link.build_url('allocations', new_allocation.uuid) return convert_with_links(new_allocation)
def require_context(ctxt): """Raise exception.NotAuthorized() if context is not a user or an admin context. """ if not ctxt.is_admin and not is_user_context(ctxt): raise exception.NotAuthorized()