def _is_authorized(test_obj, service, rule, extra_target_data): """Validates whether current RBAC role has permission to do policy action. :param test_obj: An instance or subclass of ``tempest.test.BaseTestCase``. :param service: The OpenStack service that enforces ``rule``. :param rule: The name of the policy action. Examples include "identity:create_user" or "os_compute_api:os-agents". :param extra_target_data: Dictionary, keyed with ``oslo.policy`` generic check names, whose values are string literals that reference nested ``tempest.test.BaseTestCase`` attributes. Used by ``oslo.policy`` for performing matching against attributes that are sent along with the API calls. :returns: True if the current RBAC role can perform the policy action, else False. :raises RbacResourceSetupFailed: If `project_id` or `user_id` are missing from the `auth_provider` attribute in `test_obj`. """ try: project_id = test_obj.os_primary.credentials.project_id user_id = test_obj.os_primary.credentials.user_id except AttributeError as e: msg = ("{0}: project_id or user_id not found in os_primary.credentials" .format(e)) LOG.error(msg) raise rbac_exceptions.RbacResourceSetupFailed(msg) roles = CONF.patrole.rbac_test_roles # TODO(vegasq) drop once CONF.patrole.rbac_test_role is removed if CONF.patrole.rbac_test_role: if not roles: roles.append(CONF.patrole.rbac_test_role) # Adding implied roles roles = test_obj.get_all_needed_roles(roles) # Test RBAC against custom requirements. Otherwise use oslo.policy. if CONF.patrole.test_custom_requirements: authority = requirements_authority.RequirementsAuthority( CONF.patrole.custom_requirements_file, service) else: formatted_target_data = _format_extra_target_data( test_obj, extra_target_data) authority = policy_authority.PolicyAuthority( project_id, user_id, service, extra_target_data=formatted_target_data) is_allowed = authority.allowed(rule, roles) if is_allowed: LOG.debug("[Policy action]: %s, [Role]: %s is allowed!", rule, roles) else: LOG.debug("[Policy action]: %s, [Role]: %s is NOT allowed!", rule, roles) return is_allowed
def setUp(self): super(BaseRequirementsAuthorityTest, self).setUp() self.rbac_auth = req_auth.RequirementsAuthority() self.current_directory = os.path.dirname(os.path.realpath(__file__)) self.yaml_test_file = os.path.join(self.current_directory, 'resources', 'rbac_roles.yaml') self.expected_result = { 'test:create': [['test_member'], ['_member_']], 'test:create2': [['test_member']], 'test:create3': [['test_member', '_member_']], 'test:create4': [['test_member', '!_member_']] } self.expected_rbac_map = { 'test:create': ['test_member', '_member_'], 'test:create2': ['test_member'], 'test:create3': ['test_member, _member_'], 'test:create4': ['test_member, !_member_'] }
def _is_authorized(test_obj, service, rule, extra_target_data, admin_only): """Validates whether current RBAC role has permission to do policy action. :param test_obj: An instance or subclass of ``tempest.test.BaseTestCase``. :param service: The OpenStack service that enforces ``rule``. :param rule: The name of the policy action. Examples include "identity:create_user" or "os_compute_api:os-agents". :param extra_target_data: Dictionary, keyed with ``oslo.policy`` generic check names, whose values are string literals that reference nested ``tempest.test.BaseTestCase`` attributes. Used by ``oslo.policy`` for performing matching against attributes that are sent along with the API calls. :param admin_only: Skips over ``oslo.policy`` check because the policy action defined by ``rule`` is not enforced by the service's policy enforcement engine. For example, Keystone v2 performs an admin check for most of its endpoints. If True, ``rule`` is effectively ignored. :returns: True if the current RBAC role can perform the policy action, else False. :raises RbacResourceSetupFailed: If `project_id` or `user_id` are missing from the `auth_provider` attribute in `test_obj`. :raises RbacParsingException: if ``[patrole] strict_policy_check`` is True and the ``rule`` does not exist in the system. :raises skipException: If ``[patrole] strict_policy_check`` is False and the ``rule`` does not exist in the system. """ if admin_only: LOG.info("As admin_only is True, only admin role should be " "allowed to perform the API. Skipping oslo.policy " "check for policy action {0}.".format(rule)) return rbac_utils.is_admin() try: project_id = test_obj.os_primary.credentials.project_id user_id = test_obj.os_primary.credentials.user_id except AttributeError as e: msg = ("{0}: project_id or user_id not found in os_primary.credentials" .format(e)) LOG.error(msg) raise rbac_exceptions.RbacResourceSetupFailed(msg) try: role = CONF.patrole.rbac_test_role # Test RBAC against custom requirements. Otherwise use oslo.policy. if CONF.patrole.test_custom_requirements: authority = requirements_authority.RequirementsAuthority( CONF.patrole.custom_requirements_file, service) else: formatted_target_data = _format_extra_target_data( test_obj, extra_target_data) authority = policy_authority.PolicyAuthority( project_id, user_id, service, extra_target_data=formatted_target_data) is_allowed = authority.allowed(rule, role) if is_allowed: LOG.debug("[Action]: %s, [Role]: %s is allowed!", rule, role) else: LOG.debug("[Action]: %s, [Role]: %s is NOT allowed!", rule, role) return is_allowed except rbac_exceptions.RbacParsingException as e: if CONF.patrole.strict_policy_check: raise e else: raise testtools.TestCase.skipException(str(e)) return False
def test_requirements_auth_init(self): rbac_auth = req_auth.RequirementsAuthority(self.yaml_test_file, 'Test') self.assertEqual(self.expected_result, rbac_auth.roles_dict)