Displays role assignment through group in user details

In the tab role assignments of the user details view, the role
assignments the user has got through groups are added.

In the column "role" of the table, the text "(through group GROUP_NAME)"
is specified next to the role name.

Change-Id: I6bbf3ef61a7c4e99e0b1ddce90ae1c12a3e18369
Closes-Bug: #1792524
This commit is contained in:
David Gutman 2018-09-13 15:07:13 +02:00 committed by Akihiro Motoki
parent d66df58e2d
commit 9d68119452
4 changed files with 83 additions and 15 deletions

View File

@ -48,9 +48,17 @@ def get_system_scope(datum):
def get_role_name(datum):
if "name" in datum.role:
return datum.role["name"]
return datum.role["id"]
role_name = datum.role["name"] if "name" in datum.role \
else datum.role["id"]
if hasattr(datum, "group"):
# This is a role assignment through a group
group_name = datum.group["name"] if "name" in datum.group \
else datum.group["id"]
role_name = _("%(role)s (through group %(group)s)") % {
'role': role_name, 'group': group_name}
return role_name
class RoleAssignmentsTable(tables.DataTable):
@ -86,7 +94,13 @@ class RoleAssignmentsTable(tables.DataTable):
elif "domain" in datum.scope:
scope_id = datum.scope["domain"]["id"]
return "%s%s%s" % (datum.user["id"], datum.role["id"], scope_id)
assignee_id = ""
if hasattr(datum, "user"):
assignee_id = datum.user["id"]
elif hasattr(datum, "group"):
assignee_id = datum.group["id"]
return "%s%s%s" % (assignee_id, datum.role["id"], scope_id)
class Meta(object):
name = "roleassignmentstable"

View File

@ -47,20 +47,39 @@ class RoleAssignmentsTab(tabs.TableTab):
def get_roleassignmentstable_data(self):
user = self.tab_group.kwargs['user']
role_assignments = []
try:
# Get all the roles of the user
user_roles = api.keystone.role_assignments_list(
role_assignments = api.keystone.role_assignments_list(
self.request, user=user, include_subtree=False,
include_names=True)
return user_roles
except Exception:
exceptions.handle(
self.request,
_("Unable to display the role assignments of this user."))
else:
# Find all the role assignments through the groups of the user
try:
user_groups = api.keystone.group_list(
self.request, user=user.id)
return []
# Get the role for each group of the user:
for group in user_groups:
group_role_assignments = api.keystone. \
role_assignments_list(
self.request, group=group, include_subtree=False,
include_names=True)
role_assignments.extend(group_role_assignments)
except Exception:
exceptions.handle(
self.request,
_("Unable to display role assignment through groups."))
return role_assignments
class GroupsTab(tabs.TableTab):

View File

@ -925,18 +925,35 @@ class UsersViewTests(test.BaseAdminViewTests):
@test.create_mocks({api.keystone: ('domain_get',
'user_get',
'tenant_get',
'role_assignments_list')})
'role_assignments_list',
'group_list')})
def test_detail_view_role_assignments_tab(self):
"""Test the role assignments tab of the detail view ."""
domain = self._get_default_domain()
user = self.users.get(id="1")
tenant = self.tenants.get(id=user.project_id)
role_assignments = self.role_assignments.filter(user={'id': user.id})
user_role_assignments = self.role_assignments.filter(
user={'id': user.id})
user_group = self.groups.first()
group_role_assignments = self.role_assignments.filter(
group={'id': user_group.id})
self.mock_domain_get.return_value = domain
self.mock_user_get.return_value = user
self.mock_tenant_get.return_value = tenant
self.mock_role_assignments_list.return_value = role_assignments
self.mock_group_list.return_value = [user_group]
def _role_assignments_list_side_effect(request, user=None, group=None,
include_subtree=False,
include_names=True):
# role assignments should be called twice, once with the user and
# another one with the group.
if group:
return group_role_assignments
return user_role_assignments
self.mock_role_assignments_list.side_effect = \
_role_assignments_list_side_effect
# Url of the role assignment tab of the detail view
url = USER_DETAIL_URL % [user.id]
@ -954,7 +971,8 @@ class UsersViewTests(test.BaseAdminViewTests):
"horizon/common/_detail_table.html")
# Check the table contains the expected data
role_assignments_expected = role_assignments
role_assignments_expected = user_role_assignments
role_assignments_expected.extend(group_role_assignments)
role_assignments_observed = res.context["table"].data
self.assertItemsEqual(role_assignments_expected,
role_assignments_observed)
@ -964,9 +982,13 @@ class UsersViewTests(test.BaseAdminViewTests):
admin=False)
self.mock_tenant_get.assert_called_once_with(test.IsHttpRequest(),
user.project_id)
self.mock_role_assignments_list.assert_called_once_with(
test.IsHttpRequest(), user=user, include_subtree=False,
include_names=True)
# role assignments should be called twice, once with the user and
# another one with the group.
calls = [mock.call(test.IsHttpRequest(), user=user,
include_subtree=False, include_names=True),
mock.call(test.IsHttpRequest(), group=user_group,
include_subtree=False, include_names=True), ]
self.mock_role_assignments_list.assert_has_calls(calls)
@test.create_mocks({api.keystone: ('domain_get',
'user_get',

View File

@ -0,0 +1,13 @@
---
features:
- |
[:bug:`1792524`] Modify the user detail view in a multi tabbed view,
composed of:
* ``Overview`` tab displaying general information about the user.
* ``Roles assignments`` tab displaying all the roles that the users have on
project or domain, directly or throw their membership to a group. When
the role comes from a membership to a group this will be indicated into
the role column.
* ``Groups`` tab displaying all groups where the user is a membership to.