blob: 09fa081b1949d2e74fab5ebb911bfd267f47718a [file] [log] [blame]
DavidPurcellb25f93d2017-01-27 12:46:27 -05001# Copyright 2017 AT&T Corporation.
2# All Rights Reserved.
DavidPurcell029d8c32017-01-06 15:27:41 -05003#
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
Felipe Monteiro9c978502017-01-27 17:07:54 -050016import mock
DavidPurcell029d8c32017-01-06 15:27:41 -050017import os
18
19from tempest import config
20from tempest.tests import base
21
22from patrole_tempest_plugin import rbac_role_converter
23
24CONF = config.CONF
25
26
27class RbacPolicyTest(base.TestCase):
28
29 def setUp(self):
30 super(RbacPolicyTest, self).setUp()
31
32 current_directory = os.path.dirname(os.path.realpath(__file__))
33 self.custom_policy_file = os.path.join(current_directory,
Felipe Monteirob0595652017-01-23 16:51:58 -050034 'resources',
DavidPurcell029d8c32017-01-06 15:27:41 -050035 'custom_rbac_policy.json')
Felipe Monteirob0595652017-01-23 16:51:58 -050036 self.admin_policy_file = os.path.join(current_directory,
37 'resources',
38 'admin_rbac_policy.json')
Felipe Monteiro9c978502017-01-27 17:07:54 -050039 self.alt_admin_policy_file = os.path.join(current_directory,
40 'resources',
41 'alt_admin_rbac_policy.json')
Felipe Monteiro9fc782e2017-02-01 15:38:46 -050042 self.tenant_policy_file = os.path.join(current_directory,
43 'resources',
44 'tenant_rbac_policy.json')
DavidPurcell029d8c32017-01-06 15:27:41 -050045
Felipe Monteiro9c978502017-01-27 17:07:54 -050046 @mock.patch.object(rbac_role_converter, 'LOG', autospec=True)
47 def test_custom_policy(self, m_log):
DavidPurcell029d8c32017-01-06 15:27:41 -050048 default_roles = ['zero', 'one', 'two', 'three', 'four',
49 'five', 'six', 'seven', 'eight', 'nine']
DavidPurcell029d8c32017-01-06 15:27:41 -050050
Felipe Monteirob0595652017-01-23 16:51:58 -050051 converter = rbac_role_converter.RbacPolicyConverter(
52 None, "test", self.custom_policy_file)
DavidPurcell029d8c32017-01-06 15:27:41 -050053
54 expected = {
55 'policy_action_1': ['two', 'four', 'six', 'eight'],
56 'policy_action_2': ['one', 'three', 'five', 'seven', 'nine'],
57 'policy_action_3': ['zero'],
58 'policy_action_4': ['one', 'two', 'three', 'five', 'seven'],
59 'policy_action_5': ['zero', 'one', 'two', 'three', 'four', 'five',
60 'six', 'seven', 'eight', 'nine'],
61 'policy_action_6': ['eight'],
62 }
63
64 fake_rule = 'fake_rule'
65
Felipe Monteirob0595652017-01-23 16:51:58 -050066 for role in default_roles:
Felipe Monteiro9c978502017-01-27 17:07:54 -050067 self.assertFalse(converter.allowed(fake_rule, role))
68 m_log.debug.assert_called_once_with(
69 "{0} not found in policy file.".format('fake_rule'))
70 m_log.debug.reset_mock()
DavidPurcell029d8c32017-01-06 15:27:41 -050071
Felipe Monteirob0595652017-01-23 16:51:58 -050072 for rule, role_list in expected.items():
73 for role in role_list:
74 self.assertTrue(converter.allowed(rule, role))
75 for role in set(default_roles) - set(role_list):
76 self.assertFalse(converter.allowed(rule, role))
77
78 def test_admin_policy_file_with_admin_role(self):
Felipe Monteirob0595652017-01-23 16:51:58 -050079 converter = rbac_role_converter.RbacPolicyConverter(
80 None, "test", self.admin_policy_file)
81
82 role = 'admin'
83 allowed_rules = [
Felipe Monteiro9c978502017-01-27 17:07:54 -050084 'admin_rule', 'is_admin_rule', 'alt_admin_rule'
Felipe Monteirob0595652017-01-23 16:51:58 -050085 ]
Felipe Monteiro9c978502017-01-27 17:07:54 -050086 disallowed_rules = ['non_admin_rule']
Felipe Monteirob0595652017-01-23 16:51:58 -050087
88 for rule in allowed_rules:
89 allowed = converter.allowed(rule, role)
90 self.assertTrue(allowed)
91
92 for rule in disallowed_rules:
93 allowed = converter.allowed(rule, role)
94 self.assertFalse(allowed)
95
96 def test_admin_policy_file_with_member_role(self):
Felipe Monteirob0595652017-01-23 16:51:58 -050097 converter = rbac_role_converter.RbacPolicyConverter(
98 None, "test", self.admin_policy_file)
99
100 role = 'Member'
101 allowed_rules = [
102 'non_admin_rule'
103 ]
104 disallowed_rules = [
105 'admin_rule', 'is_admin_rule', 'alt_admin_rule']
106
107 for rule in allowed_rules:
108 allowed = converter.allowed(rule, role)
109 self.assertTrue(allowed)
110
111 for rule in disallowed_rules:
112 allowed = converter.allowed(rule, role)
113 self.assertFalse(allowed)
Felipe Monteiro9c978502017-01-27 17:07:54 -0500114
115 def test_admin_policy_file_with_context_is_admin(self):
116 converter = rbac_role_converter.RbacPolicyConverter(
117 None, "test", self.alt_admin_policy_file)
118
119 role = 'fake_admin'
120 allowed_rules = ['non_admin_rule']
121 disallowed_rules = ['admin_rule']
122
123 for rule in allowed_rules:
124 allowed = converter.allowed(rule, role)
125 self.assertTrue(allowed)
126
127 for rule in disallowed_rules:
128 allowed = converter.allowed(rule, role)
129 self.assertFalse(allowed)
130
131 role = 'super_admin'
132 allowed_rules = ['admin_rule']
133 disallowed_rules = ['non_admin_rule']
134
135 for rule in allowed_rules:
136 allowed = converter.allowed(rule, role)
137 self.assertTrue(allowed)
138
139 for rule in disallowed_rules:
140 allowed = converter.allowed(rule, role)
141 self.assertFalse(allowed)
Felipe Monteiro9fc782e2017-02-01 15:38:46 -0500142
143 def test_tenant_policy(self):
144 """Test whether rules with format tenant_id:%(tenant_id)s work.
145
146 Test whether Neutron rules that contain project_id, tenant_id, and
147 network:tenant_id pass.
148 """
149 test_tenant_id = mock.sentinel.tenant_id
150 converter = rbac_role_converter.RbacPolicyConverter(
151 test_tenant_id, "test", self.tenant_policy_file)
152
153 # Check whether Member role can perform expected actions.
154 allowed_rules = ['rule1', 'rule2', 'rule3']
155 for rule in allowed_rules:
156 allowed = converter.allowed(rule, 'Member')
157 self.assertTrue(allowed)
158 self.assertFalse(converter.allowed('admin_rule', 'Member'))
159
160 # Check whether admin role can perform expected actions.
161 allowed_rules.append('admin_rule')
162 for rule in allowed_rules:
163 allowed = converter.allowed(rule, 'admin')
164 self.assertTrue(allowed)
165
166 # Check whether _try_rule is called with the correct target dictionary.
167 with mock.patch.object(converter, '_try_rule', autospec=True) \
168 as mock_try_rule:
169 mock_try_rule.return_value = True
170
171 expected_target = {
172 "project_id": test_tenant_id,
173 "tenant_id": test_tenant_id,
174 "network:tenant_id": test_tenant_id
175 }
176
177 for rule in allowed_rules:
178 allowed = converter.allowed(rule, 'Member')
179 self.assertTrue(allowed)
180 mock_try_rule.assert_called_once_with(
181 rule, expected_target, mock.ANY, mock.ANY)
182 mock_try_rule.reset_mock()