blob: 98eb66c90e1ba84a5471d6997d61d7af3a433b0b [file] [log] [blame]
Felipe Monteiroffa47e62017-07-05 03:37:55 +01001# Copyright 2017 AT&T Corporation.
2# All Rights Reserved.
3#
4# Licensed under the Apache License, Version 2.0 (the "License"); you may
5# not use this file except in compliance with the License. You may obtain
6# a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13# License for the specific language governing permissions and limitations
14# under the License.
15
16"""Fixtures for Patrole tests."""
Sean McGinnisc5ea6f22020-04-18 11:57:10 -050017from unittest import mock
Felipe Monteiroffa47e62017-07-05 03:37:55 +010018
19import fixtures
Felipe Monteirob18a3f62017-09-19 04:25:51 +010020import time
Felipe Monteiroffa47e62017-07-05 03:37:55 +010021
Felipe Monteiro3e14f472017-08-17 23:02:11 +010022from tempest.common import credentials_factory as credentials
Felipe Monteiroffa47e62017-07-05 03:37:55 +010023from tempest import config
Felipe Monteirob18a3f62017-09-19 04:25:51 +010024from tempest import test
Felipe Monteiroffa47e62017-07-05 03:37:55 +010025
26from patrole_tempest_plugin import rbac_utils
27
28
29CONF = config.CONF
30
31
32class ConfPatcher(fixtures.Fixture):
33 """Fixture to patch and restore global CONF. Adopted from Nova.
34
35 This also resets overrides for everything that is patched during
36 its teardown.
37 """
38
39 def __init__(self, **kwargs):
40 """Constructor
41
42 :params group: if specified all config options apply to that group.
43 :params **kwargs: the rest of the kwargs are processed as a
44 set of key/value pairs to be set as configuration override.
45 """
46 super(ConfPatcher, self).__init__()
47 self.group = kwargs.pop('group', None)
48 self.args = kwargs
49
50 def setUp(self):
51 super(ConfPatcher, self).setUp()
52 for k, v in self.args.items():
53 self.addCleanup(CONF.clear_override, k, self.group)
54 CONF.set_override(k, v, self.group)
55
56
Sergey Vilgelmace8ea32018-11-19 16:25:10 -060057class FakeBaseRbacTest(rbac_utils.RbacUtilsMixin, test.BaseTestCase):
58 os_primary = None
59
60 def runTest(self):
61 pass
62
63
64class RbacUtilsMixinFixture(fixtures.Fixture):
Felipe Monteiro2693bf72017-08-12 22:56:47 +010065 """Fixture for `RbacUtils` class."""
Felipe Monteiroffa47e62017-07-05 03:37:55 +010066
67 USER_ID = mock.sentinel.user_id
68 PROJECT_ID = mock.sentinel.project_id
69
Sergey Vilgelmace8ea32018-11-19 16:25:10 -060070 def __init__(self, do_reset_mocks=True, rbac_test_roles=None):
71 self._do_reset_mocks = do_reset_mocks
72 self._rbac_test_roles = rbac_test_roles or ['member']
Felipe Monteiroffa47e62017-07-05 03:37:55 +010073
Sergey Vilgelmace8ea32018-11-19 16:25:10 -060074 def patchobject(self, target, attribute, *args, **kwargs):
75 p = mock.patch.object(target, attribute, *args, **kwargs)
76 m = p.start()
77 self.addCleanup(p.stop)
78 return m
79
80 def setUp(self):
81 super(RbacUtilsMixinFixture, self).setUp()
82
83 self.useFixture(ConfPatcher(rbac_test_roles=self._rbac_test_roles,
Mykola Yakovlieve0f35502018-09-26 18:26:57 -050084 group='patrole'))
Felipe Monteiroffa47e62017-07-05 03:37:55 +010085 self.useFixture(ConfPatcher(
86 admin_role='admin', auth_version='v3', group='identity'))
Felipe Monteirobf524fb2018-10-03 09:03:35 -050087 self.useFixture(ConfPatcher(
88 api_v3=True, group='identity-feature-enabled'))
Felipe Monteiroffa47e62017-07-05 03:37:55 +010089
Felipe Monteirob18a3f62017-09-19 04:25:51 +010090 # Mock out functionality that can't be used by unit tests. Mocking out
91 # time.sleep is a test optimization.
Sergey Vilgelmace8ea32018-11-19 16:25:10 -060092 self.mock_time = self.patchobject(rbac_utils, 'time',
93 __name__='mock_time', spec=time)
94 self.patchobject(credentials, 'get_configured_admin_credentials',
95 spec=object)
96 mock_admin_mgr = self.patchobject(rbac_utils.clients, 'Manager',
97 spec=rbac_utils.clients.Manager,
98 roles_v3_client=mock.Mock(),
99 roles_client=mock.Mock())
Mykola Yakovlieve0f35502018-09-26 18:26:57 -0500100 self.admin_roles_client = mock_admin_mgr.return_value.roles_v3_client
Sergey Vilgelm19e3bec2019-01-07 11:59:41 -0600101 self.admin_roles_client.list_all_role_inference_rules.return_value = {
Sergey Vilgelmace8ea32018-11-19 16:25:10 -0600102 "role_inferences": [
103 {
104 "implies": [{"id": "reader_id", "name": "reader"}],
105 "prior_role": {"id": "member_id", "name": "member"}
106 },
107 {
108 "implies": [{"id": "member_id", "name": "member"}],
109 "prior_role": {"id": "admin_id", "name": "admin"}
110 }
111 ]
112 }
Felipe Monteiroffa47e62017-07-05 03:37:55 +0100113
Sergey Vilgelmace8ea32018-11-19 16:25:10 -0600114 default_roles = {'admin', 'member', 'reader'}.union(
115 set(self._rbac_test_roles))
116 self.set_roles(list(default_roles), [])
Felipe Monteiro2693bf72017-08-12 22:56:47 +0100117
Sergey Vilgelmace8ea32018-11-19 16:25:10 -0600118 test_obj_kwargs = {
119 'credentials.user_id': self.USER_ID,
120 'credentials.tenant_id': self.PROJECT_ID,
121 'credentials.project_id': self.PROJECT_ID,
122 }
Felipe Monteiroffa47e62017-07-05 03:37:55 +0100123
Sergey Vilgelmace8ea32018-11-19 16:25:10 -0600124 class FakeRbacTest(FakeBaseRbacTest):
125 os_primary = mock.Mock()
Felipe Monteiroffa47e62017-07-05 03:37:55 +0100126
Sergey Vilgelmace8ea32018-11-19 16:25:10 -0600127 FakeRbacTest.os_primary.configure_mock(**test_obj_kwargs)
Felipe Monteiro2693bf72017-08-12 22:56:47 +0100128
Sergey Vilgelmace8ea32018-11-19 16:25:10 -0600129 FakeRbacTest.setUpClass()
130 self.test_obj = FakeRbacTest()
131 if self._do_reset_mocks:
132 self.admin_roles_client.reset_mock()
133 self.test_obj.os_primary.reset_mock()
134 self.mock_time.reset_mock()
Mykola Yakovliev11376ab2018-08-06 15:34:22 -0500135
Felipe Monteiro2693bf72017-08-12 22:56:47 +0100136 def set_roles(self, roles, roles_on_project=None):
137 """Set the list of available roles in the system.
138
139 :param roles: List of roles returned by ``list_roles``.
140 :param roles_on_project: List of roles returned by
141 ``list_user_roles_on_project``.
142 :returns: None.
143 """
144 if not roles_on_project:
145 roles_on_project = []
146 if not isinstance(roles, list):
147 roles = [roles]
148 if not isinstance(roles_on_project, list):
149 roles_on_project = [roles_on_project]
150
151 available_roles = {
Felipe Monteiroffa47e62017-07-05 03:37:55 +0100152 'roles': [{'name': role, 'id': '%s_id' % role} for role in roles]
153 }
Felipe Monteiro2693bf72017-08-12 22:56:47 +0100154 available_project_roles = {
155 'roles': [{'name': role, 'id': '%s_id' % role}
156 for role in roles_on_project]
157 }
158
Mykola Yakovlieve0f35502018-09-26 18:26:57 -0500159 self.admin_roles_client.list_roles.return_value = available_roles
160 self.admin_roles_client.list_user_roles_on_project.return_value = (
Felipe Monteiro2693bf72017-08-12 22:56:47 +0100161 available_project_roles)