4 # Copyright 2017 RIFT.IO Inc
6 # Licensed under the Apache License, Version 2.0 (the "License");
7 # you may not use this file except in compliance with the License.
8 # You may obtain a copy of the License at
10 # http://www.apache.org/licenses/LICENSE-2.0
12 # Unless required by applicable law or agreed to in writing, software
13 # distributed under the License is distributed on an "AS IS" BASIS,
14 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 # See the License for the specific language governing permissions and
16 # limitations under the License.
23 from rift
.auto
.session
import NetconfSession
, RestconfSession
26 gi
.require_version('RwUserYang', '1.0')
27 gi
.require_version('RwProjectYang', '1.0')
28 gi
.require_version('RwRbacPlatformYang', '1.0')
29 gi
.require_version('RwRbacInternalYang', '1.0')
30 from gi
.repository
import (
36 gi
.require_version('RwKeyspec', '1.0')
37 from gi
.repository
.RwKeyspec
import quoted_key
39 @pytest.fixture(scope
='session')
41 """Fixture which returns rbac test data: users, roles, projects being used in the test.
42 users: tuple of user names
43 projects: tuple of project names
44 map_platform_roles: mapping of a user to multiple platform roles
45 map_project_roles: mapping of a user to multiple projects (project, list of roles in that project)"""
46 users
= ('admin3', 'user1', 'user2', )
48 projects
= ('project1', 'project2', )
50 map_platform_roles
= {
51 'admin3': ['rw-rbac-platform:platform-admin'],
56 ('project1', ['rw-project:project-admin']),
57 ('project2', ['rw-project:project-oper']),
61 ('project1', ['rw-project:project-admin']),
67 return {'users': users
, 'projects': projects
, 'roles': (map_platform_roles
, map_project_roles
)}
70 @pytest.mark
.setup('rbac_setup')
71 @pytest.mark
.incremental
72 class TestRbacSetup(object):
73 def test_create_users(self
, rbac_test_data
, rw_user_proxy
, user_domain
, rbac_user_passwd
, logger
):
74 """Creates all users as per rbac test-data and verify if they are successfully created."""
75 users_test_data
= rbac_test_data
['users']
77 # Create all users mentioned in users_test_data
78 for user
in users_test_data
:
79 rift
.auto
.mano
.create_user(rw_user_proxy
, user
, rbac_user_passwd
, user_domain
)
81 # Verify users are created
82 user_config
= rw_user_proxy
.get_config('/user-config')
85 user_config_test_data
= [user
.user_name
for user
in user_config
.user
if user
.user_name
in users_test_data
]
86 logger
.debug('Users: {} have been successfully created'.format(user_config_test_data
))
88 assert len(user_config_test_data
) == len(users_test_data
)
90 def test_create_projects(self
, logger
, rw_conman_proxy
, rbac_test_data
):
91 """Creates all projects as per rbac test-data and verify them."""
92 projects_test_data
= rbac_test_data
['projects']
94 # Create all projects mentioned in projects_test_data and verify if they are created
95 for project
in projects_test_data
:
96 logger
.debug('Creating project {}'.format(project
))
97 rift
.auto
.mano
.create_project(rw_conman_proxy
, project
)
99 def test_assign_platform_roles_to_users(self
, rbac_platform_proxy
, logger
, rbac_test_data
, user_domain
, rw_rbac_int_proxy
):
100 """Assign platform roles to an user as per test data mapping and verify them."""
101 platform_roles_test_data
, _
= rbac_test_data
['roles']
103 # Loop through the user & platform-roles mapping and assign roles to the user
104 for user
, roles
in platform_roles_test_data
.items():
106 rift
.auto
.mano
.assign_platform_role_to_user(rbac_platform_proxy
, role
, user
, user_domain
, rw_rbac_int_proxy
)
108 # Verify if the roles are assigned as per test data mapping
109 platform_config
= rbac_platform_proxy
.get_config('/rbac-platform-config')
111 platform_config_test_data_match
= 0
112 logger
.debug('Matching platform_roles_test_data with rbac-platform-config')
113 for user
in platform_config
.user
:
114 if user
.user_name
in platform_roles_test_data
:
115 logger
.debug('Matched user: {}'.format(user
.as_dict()))
116 platform_config_test_data_match
+= 1
118 test_data_user_platform_roles
= platform_roles_test_data
[user
.user_name
]
119 assert len(test_data_user_platform_roles
) == len(user
.role
)
120 assert len(test_data_user_platform_roles
) == len([role
for role
in user
.role
if role
.role
in test_data_user_platform_roles
])
122 assert platform_config_test_data_match
== len(platform_roles_test_data
)
124 def test_assign_users_to_projects_roles(self
, rbac_test_data
, rw_project_proxy
, user_domain
, rw_rbac_int_proxy
):
125 """Assign projects and roles to an user as per test data mapping."""
126 _
, project_roles_test_data
= rbac_test_data
['roles']
128 # Loop through the user & (project, role) mapping and asign the project, role to the user
129 for user
, project_role_tuple
in project_roles_test_data
.items():
130 for project
, role_list
in project_role_tuple
:
131 for role
in role_list
:
132 rift
.auto
.mano
.assign_project_role_to_user(rw_project_proxy
, role
, user
, project
, user_domain
, rw_rbac_int_proxy
)
135 @pytest.mark
.depends('rbac_setup')
136 @pytest.mark
.incremental
137 class TestRbacVerification(object):
138 def test_match_rbac_internal(self
, mgmt_session
, logger
, rbac_test_data
):
139 """Verifies the test data with rw-rbac-internal"""
140 rbac_intl_proxy
= mgmt_session
.proxy(RwRbacInternalYang
)
141 rbac_intl
= rbac_intl_proxy
.get('/rw-rbac-internal')
143 # Verify users in show rw-rbac-internal
144 users_test_data
= rbac_test_data
['users']
145 assert len(rbac_intl
.user
) == len(users_test_data
) + 2 # 'admin', 'oper' are two default users
147 for user
in rbac_intl
.user
:
148 if user
.user_name
in users_test_data
:
149 logger
.info('User matched: {}'.format(user
.as_dict()))
151 assert users_match
== len(users_test_data
)
153 # Verify roles (only project roles mapping, not the platform roles mapping)
154 # Each role in rw-rbac-internal is associated with a project through the field 'keys'. All mapping from users to project
155 # is part of project roles mapping.
156 _
, project_roles_test_data
= rbac_test_data
['roles']
157 for user
, project_role_tuple
in project_roles_test_data
.items():
158 for project
, role_list
in project_role_tuple
:
159 for role
in role_list
:
160 logger
.debug("Matching user: '{}' and its role '{}' in project '{}'".format(user
, role
, project
))
162 # Verify there exists a role entry in rw-rbac-internal which matches 'role', 'project'
163 rbac_intl_role
= [role_
for role_
in rbac_intl
.role
if (role_
.role
==role
and role_
.keys
==project
)]
165 # Each role is identified through its key 'project'. So there can be only one such role which matches
166 # the above 'role.role==role and role.keys=project'
167 assert len(rbac_intl_role
) == 1
168 logger
.info('Matched role in rw-rbac-internal: {}'.format(rbac_intl_role
[0].as_dict()))
170 # Verify the user list in this rw-rbac-internal role carries 'user'
171 assert len([user_
for user_
in rbac_intl_role
[0].user
if user_
.user_name
==user
]) == 1
173 def test_role_access(self
, logger
, session_class
, confd_host
, rbac_test_data
, rbac_user_passwd
, project_keyed_xpath
):
174 """Verifies the roles assigned to users for a project. Login as each user and verify the user can only access
175 the projects linked to it."""
176 _
, project_roles_test_data
= rbac_test_data
['roles']
177 projects_test_data
= rbac_test_data
['projects']
179 for user
, project_role_tuple
in project_roles_test_data
.items():
180 logger
.debug('Verifying user: {}'.format(user
))
181 projects_not_accessible
= list(projects_test_data
)
183 # Establish a session with this current user
184 user_session
= rift
.auto
.mano
.get_session(session_class
, confd_host
, user
, rbac_user_passwd
)
185 print ("Connected using username {} password {}".format(user
, rbac_user_passwd
))
187 rw_project_proxy_
= user_session
.proxy(RwProjectYang
)
189 if project_role_tuple
: # Skip the for loop for users who are not associated with any project e.g admin3
190 for project
, role_list
in project_role_tuple
:
191 projects_not_accessible
.remove(project
)
192 project_config
= rw_project_proxy_
.get_config(project_keyed_xpath
.format(project_name
=quoted_key(project
))+'/project-config')
193 user_
= [user_
for user_
in project_config
.user
if user_
.user_name
==user
]
194 logger
.debug('User: {}'.format(user_
[0].as_dict()))
195 assert len(user_
) == 1
197 # Match the roles for this user
198 assert set(role_list
) == set([role_
.role
for role_
in user_
[0].role
])
200 # It can't access any other project.
201 for project
in projects_not_accessible
:
202 assert rw_project_proxy_
.get_config(project_keyed_xpath
.format(project_name
=quoted_key(project
))+'/project-config') is None # It should
203 # return None as the project is not mapped to this user.
205 def test_admin_user(self
, logger
, rw_project_proxy
, project_keyed_xpath
, rbac_test_data
):
206 """Verify admin can see all projects as part of test-data as well as the default project"""
207 projects_test_data
= rbac_test_data
['projects']
208 projects_test_data
= projects_test_data
+ ('default', )
210 # Verify admin user can see all projects including default
211 # If it is post-reboot verification, then check default project should not be listed
212 for project
in projects_test_data
:
213 project_
= rw_project_proxy
.get_config(project_keyed_xpath
.format(project_name
=quoted_key(project
))+'/project-state', list_obj
=True)
214 if project
=='default' and pytest
.config
.getoption('--default-project-deleted'):
215 assert project_
is None
217 assert project_
# If the project doesn't exist, it returns None
220 @pytest.mark
.depends('rbac_setup')
221 @pytest.mark
.teardown('rbac_setup')
222 @pytest.mark
.incremental
223 class TestRbacTeardown(object):
224 def test_delete_default_project(self
, logger
, rw_conman_proxy
):
225 """Only deletes the default project"""
226 logger
.debug('Deleting the default project')
227 rift
.auto
.mano
.delete_project(rw_conman_proxy
, 'default')
229 def test_delete_projects(self
, logger
, rbac_test_data
, rw_conman_proxy
):
230 """Deletes the projects which are part of rbac test-data and verify their deletion"""
231 projects_test_data
= rbac_test_data
['projects']
233 # Delete the projects
234 for project
in projects_test_data
:
235 logger
.debug('Deleting project {}'.format(project
))
236 rift
.auto
.mano
.delete_project(rw_conman_proxy
, project
)
238 def test_delete_users(self
, logger
, rw_user_proxy
, rbac_platform_proxy
, platform_config_keyed_xpath
,
239 user_keyed_xpath
, rbac_test_data
, user_domain
):
240 """Deletes the users which are part of rbac test-data and verify their deletion"""
241 users_test_data
= rbac_test_data
['users']
242 map_platform_roles
, _
= rbac_test_data
['roles']
245 # If an user is associated with a platform role, at first it needs be removed from rbac-platform-config
246 # before deleting it from user-config
247 for user
in users_test_data
:
248 if user
in map_platform_roles
:
249 rbac_platform_proxy
.delete_config(platform_config_keyed_xpath
.format(user
=quoted_key(user
), domain
=quoted_key(user_domain
)))
250 rw_user_proxy
.delete_config(user_keyed_xpath
.format(user
=quoted_key(user
), domain
=quoted_key(user_domain
)))
252 # Verify if the users are deleted
253 user_config
= rw_user_proxy
.get_config('/user-config')
254 default_users
= [user
.user_name
for user
in user_config
.user
]
256 logger
.debug('Default users list: {}'.format(default_users
))
257 expected_empty_user_list
= [user
for user
in users_test_data
if user
in default_users
]
258 assert not expected_empty_user_list