blob: 41afe9bbf3580ab4c0e52fa69cce2c53ddd5461d [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."""
17from __future__ import absolute_import
18
19import fixtures
20import mock
Felipe Monteirob18a3f62017-09-19 04:25:51 +010021import time
Felipe Monteiroffa47e62017-07-05 03:37:55 +010022
Felipe Monteiro3e14f472017-08-17 23:02:11 +010023from tempest.common import credentials_factory as credentials
Felipe Monteiroffa47e62017-07-05 03:37:55 +010024from tempest import config
Felipe Monteirob18a3f62017-09-19 04:25:51 +010025from tempest import test
Felipe Monteiroffa47e62017-07-05 03:37:55 +010026
27from patrole_tempest_plugin import rbac_utils
28
29
30CONF = config.CONF
31
32
33class ConfPatcher(fixtures.Fixture):
34 """Fixture to patch and restore global CONF. Adopted from Nova.
35
36 This also resets overrides for everything that is patched during
37 its teardown.
38 """
39
40 def __init__(self, **kwargs):
41 """Constructor
42
43 :params group: if specified all config options apply to that group.
44 :params **kwargs: the rest of the kwargs are processed as a
45 set of key/value pairs to be set as configuration override.
46 """
47 super(ConfPatcher, self).__init__()
48 self.group = kwargs.pop('group', None)
49 self.args = kwargs
50
51 def setUp(self):
52 super(ConfPatcher, self).setUp()
53 for k, v in self.args.items():
54 self.addCleanup(CONF.clear_override, k, self.group)
55 CONF.set_override(k, v, self.group)
56
57
Sergey Vilgelmace8ea32018-11-19 16:25:10 -060058class FakeBaseRbacTest(rbac_utils.RbacUtilsMixin, test.BaseTestCase):
59 os_primary = None
60
61 def runTest(self):
62 pass
63
64
65class RbacUtilsMixinFixture(fixtures.Fixture):
Felipe Monteiro2693bf72017-08-12 22:56:47 +010066 """Fixture for `RbacUtils` class."""
Felipe Monteiroffa47e62017-07-05 03:37:55 +010067
68 USER_ID = mock.sentinel.user_id
69 PROJECT_ID = mock.sentinel.project_id
70
Sergey Vilgelmace8ea32018-11-19 16:25:10 -060071 def __init__(self, do_reset_mocks=True, rbac_test_roles=None):
72 self._do_reset_mocks = do_reset_mocks
73 self._rbac_test_roles = rbac_test_roles or ['member']
Felipe Monteiroffa47e62017-07-05 03:37:55 +010074
Sergey Vilgelmace8ea32018-11-19 16:25:10 -060075 def patchobject(self, target, attribute, *args, **kwargs):
76 p = mock.patch.object(target, attribute, *args, **kwargs)
77 m = p.start()
78 self.addCleanup(p.stop)
79 return m
80
81 def setUp(self):
82 super(RbacUtilsMixinFixture, self).setUp()
83
84 self.useFixture(ConfPatcher(rbac_test_roles=self._rbac_test_roles,
Mykola Yakovlieve0f35502018-09-26 18:26:57 -050085 group='patrole'))
Felipe Monteiroffa47e62017-07-05 03:37:55 +010086 self.useFixture(ConfPatcher(
87 admin_role='admin', auth_version='v3', group='identity'))
Felipe Monteirobf524fb2018-10-03 09:03:35 -050088 self.useFixture(ConfPatcher(
89 api_v3=True, group='identity-feature-enabled'))
Felipe Monteiroffa47e62017-07-05 03:37:55 +010090
Felipe Monteirob18a3f62017-09-19 04:25:51 +010091 # Mock out functionality that can't be used by unit tests. Mocking out
92 # time.sleep is a test optimization.
Sergey Vilgelmace8ea32018-11-19 16:25:10 -060093 self.mock_time = self.patchobject(rbac_utils, 'time',
94 __name__='mock_time', spec=time)
95 self.patchobject(credentials, 'get_configured_admin_credentials',
96 spec=object)
97 mock_admin_mgr = self.patchobject(rbac_utils.clients, 'Manager',
98 spec=rbac_utils.clients.Manager,
99 roles_v3_client=mock.Mock(),
100 roles_client=mock.Mock())
Mykola Yakovlieve0f35502018-09-26 18:26:57 -0500101 self.admin_roles_client = mock_admin_mgr.return_value.roles_v3_client
Sergey Vilgelm19e3bec2019-01-07 11:59:41 -0600102 self.admin_roles_client.list_all_role_inference_rules.return_value = {
Sergey Vilgelmace8ea32018-11-19 16:25:10 -0600103 "role_inferences": [
104 {
105 "implies": [{"id": "reader_id", "name": "reader"}],
106 "prior_role": {"id": "member_id", "name": "member"}
107 },
108 {
109 "implies": [{"id": "member_id", "name": "member"}],
110 "prior_role": {"id": "admin_id", "name": "admin"}
111 }
112 ]
113 }
Felipe Monteiroffa47e62017-07-05 03:37:55 +0100114
Sergey Vilgelmace8ea32018-11-19 16:25:10 -0600115 default_roles = {'admin', 'member', 'reader'}.union(
116 set(self._rbac_test_roles))
117 self.set_roles(list(default_roles), [])
Felipe Monteiro2693bf72017-08-12 22:56:47 +0100118
Sergey Vilgelmace8ea32018-11-19 16:25:10 -0600119 test_obj_kwargs = {
120 'credentials.user_id': self.USER_ID,
121 'credentials.tenant_id': self.PROJECT_ID,
122 'credentials.project_id': self.PROJECT_ID,
123 }
Felipe Monteiroffa47e62017-07-05 03:37:55 +0100124
Sergey Vilgelmace8ea32018-11-19 16:25:10 -0600125 class FakeRbacTest(FakeBaseRbacTest):
126 os_primary = mock.Mock()
Felipe Monteiroffa47e62017-07-05 03:37:55 +0100127
Sergey Vilgelmace8ea32018-11-19 16:25:10 -0600128 FakeRbacTest.os_primary.configure_mock(**test_obj_kwargs)
Felipe Monteiro2693bf72017-08-12 22:56:47 +0100129
Sergey Vilgelmace8ea32018-11-19 16:25:10 -0600130 FakeRbacTest.setUpClass()
131 self.test_obj = FakeRbacTest()
132 if self._do_reset_mocks:
133 self.admin_roles_client.reset_mock()
134 self.test_obj.os_primary.reset_mock()
135 self.mock_time.reset_mock()
Mykola Yakovliev11376ab2018-08-06 15:34:22 -0500136
Felipe Monteiro2693bf72017-08-12 22:56:47 +0100137 def set_roles(self, roles, roles_on_project=None):
138 """Set the list of available roles in the system.
139
140 :param roles: List of roles returned by ``list_roles``.
141 :param roles_on_project: List of roles returned by
142 ``list_user_roles_on_project``.
143 :returns: None.
144 """
145 if not roles_on_project:
146 roles_on_project = []
147 if not isinstance(roles, list):
148 roles = [roles]
149 if not isinstance(roles_on_project, list):
150 roles_on_project = [roles_on_project]
151
152 available_roles = {
Felipe Monteiroffa47e62017-07-05 03:37:55 +0100153 'roles': [{'name': role, 'id': '%s_id' % role} for role in roles]
154 }
Felipe Monteiro2693bf72017-08-12 22:56:47 +0100155 available_project_roles = {
156 'roles': [{'name': role, 'id': '%s_id' % role}
157 for role in roles_on_project]
158 }
159
Mykola Yakovlieve0f35502018-09-26 18:26:57 -0500160 self.admin_roles_client.list_roles.return_value = available_roles
161 self.admin_roles_client.list_user_roles_on_project.return_value = (
Felipe Monteiro2693bf72017-08-12 22:56:47 +0100162 available_project_roles)