Add inherited role assignments tests

Inherited role assignments are really useful when dealing with
hierarchies - we must test that granting an inherited role in a higher
level of the hierarchy has effect in the project's tree.

The verification is done via the "role_assignments" API and its query
parameters, such as "effective" (which lists the role assignments that
take effect in each project layer).

Change-Id: I0f5a54d85a28c8c011fd3489cf55629b9caa1dcf
This commit is contained in:
Rodrigo Duarte 2016-07-08 11:53:53 -03:00 committed by Rodrigo Duarte Sousa
parent 6728df8792
commit 12f8d4a190
5 changed files with 124 additions and 2 deletions

View File

@ -147,3 +147,88 @@ class InheritsV3TestJSON(BaseInheritsV3Test):
(self.inherited_roles_client.
delete_inherited_role_from_group_on_project(
self.project['id'], self.group['id'], src_role['id']))
@test.idempotent_id('3acf666e-5354-42ac-8e17-8b68893bcd36')
def test_inherit_assign_list_revoke_user_roles_on_domain(self):
# Create role
src_role = self.roles_client.create_role(
name=data_utils.rand_name('Role'))['role']
self.addCleanup(self.roles_client.delete_role, src_role['id'])
# Create a project hierarchy
leaf_project_name = data_utils.rand_name('project')
leaf_project = self.projects_client.create_project(
leaf_project_name, domain_id=self.domain['id'],
parent_id=self.project['id'])['project']
self.addCleanup(
self.projects_client.delete_project, leaf_project['id'])
# Assign role on domain
self.inherited_roles_client.create_inherited_role_on_domains_user(
self.domain['id'], self.user['id'], src_role['id'])
# List "effective" role assignments from user on the parent project
assignments = (
self.role_assignments.list_user_project_effective_assignments(
self.project['id'], self.user['id']))['role_assignments']
self.assertNotEmpty(assignments)
# List "effective" role assignments from user on the leaf project
assignments = (
self.role_assignments.list_user_project_effective_assignments(
leaf_project['id'], self.user['id']))['role_assignments']
self.assertNotEmpty(assignments)
# Revoke role from domain
self.inherited_roles_client.delete_inherited_role_from_user_on_domain(
self.domain['id'], self.user['id'], src_role['id'])
# List "effective" role assignments from user on the parent project
# should return an empty list
assignments = (
self.role_assignments.list_user_project_effective_assignments(
self.project['id'], self.user['id']))['role_assignments']
self.assertEmpty(assignments)
# List "effective" role assignments from user on the leaf project
# should return an empty list
assignments = (
self.role_assignments.list_user_project_effective_assignments(
leaf_project['id'], self.user['id']))['role_assignments']
self.assertEmpty(assignments)
@test.idempotent_id('9f02ccd9-9b57-46b4-8f77-dd5a736f3a06')
def test_inherit_assign_list_revoke_user_roles_on_project_tree(self):
# Create role
src_role = self.roles_client.create_role(
name=data_utils.rand_name('Role'))['role']
self.addCleanup(self.roles_client.delete_role, src_role['id'])
# Create a project hierarchy
leaf_project_name = data_utils.rand_name('project')
leaf_project = self.projects_client.create_project(
leaf_project_name, domain_id=self.domain['id'],
parent_id=self.project['id'])['project']
self.addCleanup(
self.projects_client.delete_project, leaf_project['id'])
# Assign role on parent project
self.inherited_roles_client.create_inherited_role_on_projects_user(
self.project['id'], self.user['id'], src_role['id'])
# List "effective" role assignments from user on the leaf project
assignments = (
self.role_assignments.list_user_project_effective_assignments(
leaf_project['id'], self.user['id']))['role_assignments']
self.assertNotEmpty(assignments)
# Revoke role from parent project
self.inherited_roles_client.delete_inherited_role_from_user_on_project(
self.project['id'], self.user['id'], src_role['id'])
# List "effective" role assignments from user on the leaf project
# should return an empty list
assignments = (
self.role_assignments.list_user_project_effective_assignments(
leaf_project['id'], self.user['id']))['role_assignments']
self.assertEmpty(assignments)

View File

@ -182,6 +182,7 @@ class BaseIdentityV3AdminTest(BaseIdentityV3Test):
cls.creds_client = cls.os_adm.credentials_client
cls.groups_client = cls.os_adm.groups_client
cls.projects_client = cls.os_adm.projects_client
cls.role_assignments = cls.os_admin.role_assignments_client
if CONF.identity.admin_domain_scope:
# NOTE(andreaf) When keystone policy requires it, the identity
# admin clients for these tests shall use 'domain' scoped tokens.

View File

@ -250,6 +250,8 @@ class Manager(clients.ServiceClients):
**params_v3)
self.inherited_roles_client = identity.v3.InheritedRolesClient(
self.auth_provider, **params_v3)
self.role_assignments_client = identity.v3.RoleAssignmentsClient(
self.auth_provider, **params_v3)
self.identity_services_v3_client = identity.v3.ServicesClient(
self.auth_provider, **params_v3)
self.policies_client = identity.v3.PoliciesClient(self.auth_provider,

View File

@ -28,8 +28,11 @@ from tempest.lib.services.identity.v3.token_client import V3TokenClient
from tempest.lib.services.identity.v3.trusts_client import TrustsClient
from tempest.lib.services.identity.v3.users_client import UsersClient
from tempest.services.identity.v3.json.domains_client import DomainsClient
from tempest.services.identity.v3.json.role_assignments_client import \
RoleAssignmentsClient
__all__ = ['CredentialsClient', 'EndPointsClient', 'GroupsClient',
'IdentityClient', 'InheritedRolesClient', 'PoliciesClient',
'ProjectsClient', 'RegionsClient', 'RolesClient', 'ServicesClient',
'V3TokenClient', 'TrustsClient', 'UsersClient', 'DomainsClient', ]
'ProjectsClient', 'RegionsClient', 'RoleAssignmentsClient',
'RolesClient', 'ServicesClient', 'V3TokenClient', 'TrustsClient',
'UsersClient', 'DomainsClient', ]

View File

@ -0,0 +1,31 @@
# Copyright 2016 Red Hat, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from oslo_serialization import jsonutils as json
from tempest.lib.common import rest_client
class RoleAssignmentsClient(rest_client.RestClient):
api_version = "v3"
def list_user_project_effective_assignments(
self, project_id, user_id):
"""List the effective role assignments for a user in a project."""
resp, body = self.get(
"role_assignments?scope.project.id=%s&user.id=%s&effective" %
(project_id, user_id))
self.expected_success(200, resp.status)
body = json.loads(body)
return rest_client.ResponseBody(resp, body)