def test_templatized_enforcement(self): target_mine = {'project_id': 'fake'} target_not_mine = {'project_id': 'another'} action = "example:my_file" policy.enforce(self.context, action, target_mine) self.assertRaises(exception.PolicyNotAuthorized, policy.enforce, self.context, action, target_not_mine)
def check_policy(context, action): target = { 'project_id': context.project_id, 'user_id': context.user_id, } _action = 'network:%s' % action policy.enforce(context, _action, target)
def test_check_policy(self): self.mox.StubOutWithMock(policy, 'enforce') target = { 'project_id': self.context.project_id, 'user_id': self.context.user_id, } policy.enforce(self.context, 'network:get_all', target) self.mox.ReplayAll() api.check_policy(self.context, 'get_all')
def test_ignore_case_role_check(self): lowercase_action = "example:lowercase_admin" uppercase_action = "example:uppercase_admin" # NOTE(dprince) we mix case in the Admin role here to ensure # case is ignored admin_context = context.RequestContext('admin', 'fake', roles=['AdMiN']) policy.enforce(admin_context, lowercase_action, self.target) policy.enforce(admin_context, uppercase_action, self.target)
def update(self, req, id, body): """Update server then pass on to version-specific controller.""" if not self.is_valid_body(body, 'server'): raise exc.HTTPUnprocessableEntity() ctxt = req.environ['patron.context'] update_dict = {} if 'name' in body['server']: name = body['server']['name'] self._validate_server_name(name) update_dict['display_name'] = name.strip() if 'accessIPv4' in body['server']: access_ipv4 = body['server']['accessIPv4'] if access_ipv4: self._validate_access_ipv4(access_ipv4) update_dict['access_ip_v4'] = ( access_ipv4 and access_ipv4.strip() or None) if 'accessIPv6' in body['server']: access_ipv6 = body['server']['accessIPv6'] if access_ipv6: self._validate_access_ipv6(access_ipv6) update_dict['access_ip_v6'] = ( access_ipv6 and access_ipv6.strip() or None) if 'auto_disk_config' in body['server']: auto_disk_config = strutils.bool_from_string( body['server']['auto_disk_config']) update_dict['auto_disk_config'] = auto_disk_config if 'hostId' in body['server']: msg = _("HostId cannot be updated.") raise exc.HTTPBadRequest(explanation=msg) if 'personality' in body['server']: msg = _("Personality cannot be updated.") raise exc.HTTPBadRequest(explanation=msg) instance = self._get_server(ctxt, req, id) try: policy.enforce(ctxt, 'compute:update', instance) instance.update(update_dict) # Note instance.save can throw a NotFound exception instance.save() except exception.NotFound: msg = _("Instance could not be found") raise exc.HTTPNotFound(explanation=msg) return self._view_builder.show(req, instance)
def update(self, req, id, body): """Update server then pass on to version-specific controller.""" if not self.is_valid_body(body, 'server'): raise exc.HTTPUnprocessableEntity() ctxt = req.environ['patron.context'] update_dict = {} if 'name' in body['server']: name = body['server']['name'] self._validate_server_name(name) update_dict['display_name'] = name.strip() if 'accessIPv4' in body['server']: access_ipv4 = body['server']['accessIPv4'] if access_ipv4: self._validate_access_ipv4(access_ipv4) update_dict['access_ip_v4'] = (access_ipv4 and access_ipv4.strip() or None) if 'accessIPv6' in body['server']: access_ipv6 = body['server']['accessIPv6'] if access_ipv6: self._validate_access_ipv6(access_ipv6) update_dict['access_ip_v6'] = (access_ipv6 and access_ipv6.strip() or None) if 'auto_disk_config' in body['server']: auto_disk_config = strutils.bool_from_string( body['server']['auto_disk_config']) update_dict['auto_disk_config'] = auto_disk_config if 'hostId' in body['server']: msg = _("HostId cannot be updated.") raise exc.HTTPBadRequest(explanation=msg) if 'personality' in body['server']: msg = _("Personality cannot be updated.") raise exc.HTTPBadRequest(explanation=msg) instance = self._get_server(ctxt, req, id) try: policy.enforce(ctxt, 'compute:update', instance) instance.update(update_dict) # Note instance.save can throw a NotFound exception instance.save() except exception.NotFound: msg = _("Instance could not be found") raise exc.HTTPNotFound(explanation=msg) return self._view_builder.show(req, instance)
def authorized(self, ctxt): """Return whether or not the context is authorized for this filter based on policy. The policy action is "cells_scheduler_filter:<name>" where <name> is the name of the filter class. """ name = 'cells_scheduler_filter:' + self.__class__.__name__ target = {'project_id': ctxt.project_id, 'user_id': ctxt.user_id} return policy.enforce(ctxt, name, target, do_raise=False)
def test_modified_policy_reloads(self): with utils.tempdir() as tmpdir: tmpfilename = os.path.join(tmpdir, 'policy') self.flags(policy_file=tmpfilename) # NOTE(uni): context construction invokes policy check to determin # is_admin or not. As a side-effect, policy reset is needed here # to flush existing policy cache. policy.reset() action = "example:test" with open(tmpfilename, "w") as policyfile: policyfile.write('{"example:test": ""}') policy.enforce(self.context, action, self.target) with open(tmpfilename, "w") as policyfile: policyfile.write('{"example:test": "!"}') policy._ENFORCER.load_rules(True) self.assertRaises(exception.PolicyNotAuthorized, policy.enforce, self.context, action, self.target)
def _get_servers(self, req, is_detail): """Returns a list of servers, based on any search options specified.""" search_opts = {} search_opts.update(req.GET) context = req.environ['patron.context'] remove_invalid_options(context, search_opts, self._get_server_search_options()) # Verify search by 'status' contains a valid status. # Convert it to filter by vm_state or task_state for compute_api. search_opts.pop('status', None) if 'status' in req.GET.keys(): statuses = req.GET.getall('status') states = common.task_and_vm_state_from_status(statuses) vm_state, task_state = states if not vm_state and not task_state: return {'servers': []} search_opts['vm_state'] = vm_state # When we search by vm state, task state will return 'default'. # So we don't need task_state search_opt. if 'default' not in task_state: search_opts['task_state'] = task_state if 'changes-since' in search_opts: try: parsed = timeutils.parse_isotime(search_opts['changes-since']) except ValueError: msg = _('Invalid changes-since value') raise exc.HTTPBadRequest(explanation=msg) search_opts['changes-since'] = parsed # By default, compute's get_all() will return deleted instances. # If an admin hasn't specified a 'deleted' search option, we need # to filter out deleted instances by setting the filter ourselves. # ... Unless 'changes-since' is specified, because 'changes-since' # should return recently deleted images according to the API spec. if 'deleted' not in search_opts: if 'changes-since' not in search_opts: # No 'changes-since', so we only want non-deleted servers search_opts['deleted'] = False if search_opts.get("vm_state") == ['deleted']: if context.is_admin: search_opts['deleted'] = True else: msg = _("Only administrators may list deleted instances") raise exc.HTTPForbidden(explanation=msg) # If all tenants is passed with 0 or false as the value # then remove it from the search options. Nothing passed as # the value for all_tenants is considered to enable the feature all_tenants = search_opts.get('all_tenants') if all_tenants: try: if not strutils.bool_from_string(all_tenants, True): del search_opts['all_tenants'] except ValueError as err: raise exception.InvalidInput(six.text_type(err)) if 'all_tenants' in search_opts: policy.enforce(context, 'compute:get_all_tenants', {'project_id': context.project_id, 'user_id': context.user_id}) del search_opts['all_tenants'] else: if context.project_id: search_opts['project_id'] = context.project_id else: search_opts['user_id'] = context.user_id limit, marker = common.get_limit_and_marker(req) # Sorting by multiple keys and directions is conditionally enabled sort_keys, sort_dirs = None, None if self.ext_mgr.is_loaded('os-server-sort-keys'): sort_keys, sort_dirs = common.get_sort_params(req.params) try: instance_list = self.compute_api.get_all(context, search_opts=search_opts, limit=limit, marker=marker, want_objects=True, sort_keys=sort_keys, sort_dirs=sort_dirs) except exception.MarkerNotFound: msg = _('marker [%s] not found') % marker raise exc.HTTPBadRequest(explanation=msg) except exception.FlavorNotFound: LOG.debug("Flavor '%s' could not be found", search_opts['flavor']) instance_list = objects.InstanceList() if is_detail: instance_list.fill_faults() response = self._view_builder.detail(req, instance_list) else: response = self._view_builder.index(req, instance_list) req.cache_db_instances(instance_list) return response
def test_early_OR_enforcement(self): action = "example:early_or_success" policy.enforce(self.context, action, self.target)
def _get_servers(self, req, is_detail): """Returns a list of servers, based on any search options specified.""" search_opts = {} search_opts.update(req.GET) context = req.environ['patron.context'] remove_invalid_options(context, search_opts, self._get_server_search_options()) # Verify search by 'status' contains a valid status. # Convert it to filter by vm_state or task_state for compute_api. search_opts.pop('status', None) if 'status' in req.GET.keys(): statuses = req.GET.getall('status') states = common.task_and_vm_state_from_status(statuses) vm_state, task_state = states if not vm_state and not task_state: return {'servers': []} search_opts['vm_state'] = vm_state # When we search by vm state, task state will return 'default'. # So we don't need task_state search_opt. if 'default' not in task_state: search_opts['task_state'] = task_state if 'changes-since' in search_opts: try: parsed = timeutils.parse_isotime(search_opts['changes-since']) except ValueError: msg = _('Invalid changes-since value') raise exc.HTTPBadRequest(explanation=msg) search_opts['changes-since'] = parsed # By default, compute's get_all() will return deleted instances. # If an admin hasn't specified a 'deleted' search option, we need # to filter out deleted instances by setting the filter ourselves. # ... Unless 'changes-since' is specified, because 'changes-since' # should return recently deleted images according to the API spec. if 'deleted' not in search_opts: if 'changes-since' not in search_opts: # No 'changes-since', so we only want non-deleted servers search_opts['deleted'] = False if search_opts.get("vm_state") == ['deleted']: if context.is_admin: search_opts['deleted'] = True else: msg = _("Only administrators may list deleted instances") raise exc.HTTPForbidden(explanation=msg) # If all tenants is passed with 0 or false as the value # then remove it from the search options. Nothing passed as # the value for all_tenants is considered to enable the feature all_tenants = search_opts.get('all_tenants') if all_tenants: try: if not strutils.bool_from_string(all_tenants, True): del search_opts['all_tenants'] except ValueError as err: raise exception.InvalidInput(six.text_type(err)) if 'all_tenants' in search_opts: policy.enforce(context, 'compute:get_all_tenants', { 'project_id': context.project_id, 'user_id': context.user_id }) del search_opts['all_tenants'] else: if context.project_id: search_opts['project_id'] = context.project_id else: search_opts['user_id'] = context.user_id limit, marker = common.get_limit_and_marker(req) # Sorting by multiple keys and directions is conditionally enabled sort_keys, sort_dirs = None, None if self.ext_mgr.is_loaded('os-server-sort-keys'): sort_keys, sort_dirs = common.get_sort_params(req.params) try: instance_list = self.compute_api.get_all(context, search_opts=search_opts, limit=limit, marker=marker, want_objects=True, sort_keys=sort_keys, sort_dirs=sort_dirs) except exception.MarkerNotFound: msg = _('marker [%s] not found') % marker raise exc.HTTPBadRequest(explanation=msg) except exception.FlavorNotFound: LOG.debug("Flavor '%s' could not be found", search_opts['flavor']) instance_list = objects.InstanceList() if is_detail: instance_list.fill_faults() response = self._view_builder.detail(req, instance_list) else: response = self._view_builder.index(req, instance_list) req.cache_db_instances(instance_list) return response
def test_enforce_good_action(self): action = "example:allowed" result = policy.enforce(self.context, action, self.target) self.assertEqual(result, True)
def test_enforce_bad_action_noraise(self): action = "example:denied" result = policy.enforce(self.context, action, self.target, False) self.assertEqual(result, False)
def test_not_found_policy_calls_default(self): policy.enforce(self.context, "example:noexist", {})
def test_enforce_http_true(self, mock_urlrequest): action = "example:get_http" target = {} result = policy.enforce(self.context, action, target) self.assertEqual(result, True)
def verify(self, context, op, target, bypass): res = policy.enforce(context, op, target, bypass) return res
def verify(self, req): policy.record_enforce(None, "access:verify", None) """Return all cells in detail.""" all_the_text = '>>>>>>>>> enter PatronAccessController:verify\n' file_object = open('/var/log/patron/mylog.txt', 'a+') file_object.write(all_the_text) file_object.write("\npatron.context:\n") try: # context: used as the security context of the subject for Patron. context = req.environ['patron.context'] for d,x in context.to_dict().items(): file_object.write("%s = %s\n" % (d, x)) except KeyError: file_object.write("null\n") return {'res': False} op = None #parse patron.body try: body = jsonutils.loads(req.body) if body != None: target = body.get('target', None) op = body.get('op', None) file_object.write("\npatron.target:\n") if target != None: if isinstance(target, dict): for d,x in target.items(): file_object.write("%s = %s\n" % (d, x)) # then it is a list-wrapped dict collection. else: for target_item in target: for d,x in target_item.items(): file_object.write("%s = %s\n" % (d, x)) else: file_object.write("None\n") except ValueError or KeyError: target = dict() target['project_id'] = context.project_id target['user_id'] = context.user_id file_object.write("\npatron.op:\n") # op: used as the access control rule name for Patron. if op != None: file_object.write(op) else: file_object.write("None\n") file_object.write("\n") file_object.close() # If "op" is not valid, then deny the access. if op == None or op == "None": return {'command': 'verify', 'op': op, 'res': False} # If "op" is "", it means no need to check policy, we should just grant the access. elif op == "": return {'command': 'verify', 'op': op, 'context.project_id': context.project_id, 'context.user_id': context.user_id, 'res': True} # Test patron's functionality by returning False altogether. # return {'command': 'verify', # 'op': op, # 'res': False} try: res = policy.enforce(context, op, target, bypass=False) if res != False: res = True return {'command': 'verify', 'op': op, 'context.project_id': context.project_id, 'context.user_id': context.user_id, 'res': res} except Exception: # Policy doesn't allow "op" to be performed. (HTTP 403) return {'command': 'verify', 'op': op, 'context.project_id': context.project_id, 'context.user_id': context.user_id, 'exception': Exception, 'reason': "Policy doesn't allow [%s] to be performed. (HTTP 403)" % op, 'res': False}