def test_admin_policy_file_with_context_is_admin(self):
        test_tenant_id = mock.sentinel.tenant_id
        test_user_id = mock.sentinel.user_id
        self.mock_path.path.join.return_value = self.alt_admin_policy_file
        parser = rbac_policy_parser.RbacPolicyParser(test_tenant_id,
                                                     test_user_id, "test")

        role = 'fake_admin'
        allowed_rules = ['non_admin_rule']
        disallowed_rules = ['admin_rule']

        for rule in allowed_rules:
            allowed = parser.allowed(rule, role)
            self.assertTrue(allowed)

        for rule in disallowed_rules:
            allowed = parser.allowed(rule, role)
            self.assertFalse(allowed)

        role = 'super_admin'
        allowed_rules = ['admin_rule']
        disallowed_rules = ['non_admin_rule']

        for rule in allowed_rules:
            allowed = parser.allowed(rule, role)
            self.assertTrue(allowed)

        for rule in disallowed_rules:
            allowed = parser.allowed(rule, role)
            self.assertFalse(allowed)
Esempio n. 2
0
def _is_authorized(test_obj, service, rule_name, extra_target_data):
    try:
        project_id = test_obj.auth_provider.credentials.project_id
        user_id = test_obj.auth_provider.credentials.user_id
    except AttributeError as e:
        msg = ("{0}: project_id/user_id not found in "
               "cls.auth_provider.credentials".format(e))
        LOG.error(msg)
        raise rbac_exceptions.RbacResourceSetupFailed(msg)

    try:
        role = CONF.rbac.rbac_test_role
        formatted_target_data = _format_extra_target_data(
            test_obj, extra_target_data)
        policy_parser = rbac_policy_parser.RbacPolicyParser(
            project_id,
            user_id,
            service,
            extra_target_data=formatted_target_data)
        is_allowed = policy_parser.allowed(rule_name, role)

        if is_allowed:
            LOG.debug("[Action]: %s, [Role]: %s is allowed!", rule_name, role)
        else:
            LOG.debug("[Action]: %s, [Role]: %s is NOT allowed!", rule_name,
                      role)
        return is_allowed
    except rbac_exceptions.RbacParsingException as e:
        if CONF.rbac.strict_policy_check:
            raise e
        else:
            raise testtools.TestCase.skipException(str(e))
    return False
    def test_custom_policy(self, m_log):
        default_roles = [
            'zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven',
            'eight', 'nine'
        ]

        test_tenant_id = mock.sentinel.tenant_id
        test_user_id = mock.sentinel.user_id
        self.mock_path.path.join.return_value = self.custom_policy_file
        parser = rbac_policy_parser.RbacPolicyParser(test_tenant_id,
                                                     test_user_id, "test")

        expected = {
            'policy_action_1': ['two', 'four', 'six', 'eight'],
            'policy_action_2': ['one', 'three', 'five', 'seven', 'nine'],
            'policy_action_3': ['zero'],
            'policy_action_4': ['one', 'two', 'three', 'five', 'seven'],
            'policy_action_5': [
                'zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven',
                'eight', 'nine'
            ],
            'policy_action_6': ['eight'],
        }

        for rule, role_list in expected.items():
            for role in role_list:
                self.assertTrue(parser.allowed(rule, role))
            for role in set(default_roles) - set(role_list):
                self.assertFalse(parser.allowed(rule, role))
    def test_tenant_user_policy(self):
        """Test whether rules with format tenant_id/user_id formatting work.

        Test whether Neutron rules that contain project_id, tenant_id, and
        network:tenant_id pass. And test whether Nova rules that contain
        user_id pass.
        """
        test_tenant_id = mock.sentinel.tenant_id
        test_user_id = mock.sentinel.user_id
        self.mock_path.path.join.return_value = self.tenant_policy_file
        parser = rbac_policy_parser.RbacPolicyParser(test_tenant_id,
                                                     test_user_id, "test")

        # Check whether Member role can perform expected actions.
        allowed_rules = ['rule1', 'rule2', 'rule3', 'rule4']
        for rule in allowed_rules:
            allowed = parser.allowed(rule, 'Member')
            self.assertTrue(allowed)

        disallowed_rules = ['admin_tenant_rule', 'admin_user_rule']
        for disallowed_rule in disallowed_rules:
            self.assertFalse(parser.allowed(disallowed_rule, 'Member'))

        # Check whether admin role can perform expected actions.
        allowed_rules.extend(disallowed_rules)
        for rule in allowed_rules:
            allowed = parser.allowed(rule, 'admin')
            self.assertTrue(allowed)

        # Check whether _try_rule is called with the correct target dictionary.
        with mock.patch.object(
            parser, '_try_rule', return_value=True, autospec=True) \
            as mock_try_rule:

            expected_target = {
                "project_id": mock.sentinel.tenant_id,
                "tenant_id": mock.sentinel.tenant_id,
                "network:tenant_id": mock.sentinel.tenant_id,
                "user_id": mock.sentinel.user_id
            }

            expected_access_data = {
                "roles": ['Member'],
                "is_admin": False,
                "is_admin_project": True,
                "user_id": mock.sentinel.user_id,
                "tenant_id": mock.sentinel.tenant_id,
                "project_id": mock.sentinel.tenant_id
            }

            for rule in allowed_rules:
                allowed = parser.allowed(rule, 'Member')
                self.assertTrue(allowed)
                mock_try_rule.assert_called_once_with(rule, expected_target,
                                                      expected_access_data,
                                                      mock.ANY)
                mock_try_rule.reset_mock()
    def test_invalid_policy_rule_throws_rbac_parsing_exception(self, m_log):
        test_tenant_id = mock.sentinel.tenant_id
        test_user_id = mock.sentinel.user_id
        self.mock_path.path.join.return_value = self.custom_policy_file
        parser = rbac_policy_parser.RbacPolicyParser(test_tenant_id,
                                                     test_user_id, "test")

        fake_rule = 'fake_rule'
        expected_message = "Policy action: {0} not found in policy file: {1}."\
                           .format(fake_rule, self.custom_policy_file)

        e = self.assertRaises(rbac_exceptions.RbacParsingException,
                              parser.allowed, fake_rule, None)
        self.assertIn(expected_message, str(e))
        m_log.debug.assert_called_once_with(expected_message)
    def test_unknown_exception_throws_rbac_parsing_exception(self, m_log):
        test_tenant_id = mock.sentinel.tenant_id
        test_user_id = mock.sentinel.user_id
        self.mock_path.path.join.return_value = self.custom_policy_file
        parser = rbac_policy_parser.RbacPolicyParser(test_tenant_id,
                                                     test_user_id, "test")
        parser.rules = mock.MagicMock(**{
            '__getitem__.return_value.side_effect':
            Exception(mock.sentinel.error)
        })

        expected_message = "Policy action: {0} not found in "\
                           "policy file: {1}.".format(mock.sentinel.rule,
                                                      self.custom_policy_file)

        e = self.assertRaises(rbac_exceptions.RbacParsingException,
                              parser.allowed, mock.sentinel.rule, None)
        self.assertIn(expected_message, str(e))
        m_log.debug.assert_called_once_with(expected_message)
    def test_get_policy_data_from_file_and_from_code(self, mock_stevedore):
        fake_policy_rules = [
            self._get_fake_policy_rule('code_policy_action_1',
                                       'rule:code_rule_1'),
            self._get_fake_policy_rule('code_policy_action_2',
                                       'rule:code_rule_2'),
            self._get_fake_policy_rule('code_policy_action_3',
                                       'rule:code_rule_3'),
        ]

        mock_manager = mock.Mock(obj=fake_policy_rules)
        mock_manager.configure_mock(name='fake_service')
        mock_stevedore.named.NamedExtensionManager.return_value = [
            mock_manager
        ]

        test_tenant_id = mock.sentinel.tenant_id
        test_user_id = mock.sentinel.user_id
        self.mock_path.path.join.return_value = self.tenant_policy_file
        parser = rbac_policy_parser.RbacPolicyParser(test_tenant_id,
                                                     test_user_id, "test")

        policy_data = parser._get_policy_data('fake_service')

        self.assertIsInstance(policy_data, str)

        actual_policy_data = json.loads(policy_data)
        expected_policy_data = {
            "code_policy_action_1": "rule:code_rule_1",
            "code_policy_action_2": "rule:code_rule_2",
            "code_policy_action_3": "rule:code_rule_3",
            "rule1": "tenant_id:%(network:tenant_id)s",
            "rule2": "tenant_id:%(tenant_id)s",
            "rule3": "project_id:%(project_id)s",
            "rule4": "user_id:%(user_id)s",
            "admin_tenant_rule": "role:admin and tenant_id:%(tenant_id)s",
            "admin_user_rule": "role:admin and user_id:%(user_id)s"
        }

        self.assertEqual(expected_policy_data, actual_policy_data)