From 4936fec3a7a2cc5494d4c2c2d6c202f10366c6f2 Mon Sep 17 00:00:00 2001 From: Zhang Hua Date: Tue, 27 Feb 2024 15:26:28 +0800 Subject: [PATCH] Fix Users/Groups tab list when a domain context is set The list of users assigned to a project becomes invisible when a domain context is set in Horizon. If a domain context is set, the user list call should provide a list of users within the specified domain context, rather than users within the user's own domain. Groups tab of project also has the same problem. Change-Id: Ia778317acc41fe589765e6cd04c7fe8cad2360ab Closes-Bug: #2054799 (cherry picked from commit ed768ab5071307ee15f95636ea548050cb894f9e) --- .../dashboards/identity/projects/tabs.py | 13 ++++++--- .../dashboards/identity/projects/tests.py | 27 ++++++++++++------- 2 files changed, 26 insertions(+), 14 deletions(-) diff --git a/openstack_dashboard/dashboards/identity/projects/tabs.py b/openstack_dashboard/dashboards/identity/projects/tabs.py index 5899efd760..80ace64fb6 100644 --- a/openstack_dashboard/dashboards/identity/projects/tabs.py +++ b/openstack_dashboard/dashboards/identity/projects/tabs.py @@ -23,6 +23,7 @@ from openstack_dashboard.dashboards.identity.projects.groups \ import tables as groups_tables from openstack_dashboard.dashboards.identity.projects.users \ import tables as users_tables +from openstack_dashboard.utils import identity class OverviewTab(tabs.Tab): @@ -93,7 +94,8 @@ class UsersTab(tabs.TableTab): # For keystone.user_list project_id is not passed as argument because # it is ignored when using admin credentials # Get all users (to be able to find user name) - users = api.keystone.user_list(self.request) + domain_id = identity.get_domain_id_for_operation(self.request) + users = api.keystone.user_list(self.request, domain=domain_id) users = {user.id: user for user in users} # Get project_users_roles ({user_id: [role_id_1, role_id_2]}) @@ -128,7 +130,8 @@ class UsersTab(tabs.TableTab): # For keystone.group_list project_id is not passed as argument because # it is ignored when using admin credentials # Get all groups (to be able to find group name) - groups = api.keystone.group_list(self.request) + domain_id = identity.get_domain_id_for_operation(self.request) + groups = api.keystone.group_list(self.request, domain=domain_id) group_names = {group.id: group.name for group in groups} # Get a dictionary {group_id: [role_id_1, role_id_2]} @@ -138,7 +141,8 @@ class UsersTab(tabs.TableTab): for group_id in project_groups_roles: group_users = api.keystone.user_list(self.request, - group=group_id) + group=group_id, + domain=domain_id) group_roles_names = [ role.name for role in roles if role.id in project_groups_roles[group_id]] @@ -202,6 +206,7 @@ class GroupsTab(tabs.TableTab): project = self.tab_group.kwargs['project'] try: + domain_id = identity.get_domain_id_for_operation(self.request) # Get project_groups_roles: {group_id: [role_id_1, role_id_2]} project_groups_roles = api.keystone.get_project_groups_roles( self.request, @@ -210,7 +215,7 @@ class GroupsTab(tabs.TableTab): roles = api.keystone.role_list(self.request) # For keystone.group_list, we do not give the project_id because it # is ignored when called with admin creds. - groups = api.keystone.group_list(self.request) + groups = api.keystone.group_list(self.request, domain=domain_id) groups = {group.id: group for group in groups} except Exception: exceptions.handle(self.request, diff --git a/openstack_dashboard/dashboards/identity/projects/tests.py b/openstack_dashboard/dashboards/identity/projects/tests.py index 635f981238..9fae5fd426 100644 --- a/openstack_dashboard/dashboards/identity/projects/tests.py +++ b/openstack_dashboard/dashboards/identity/projects/tests.py @@ -31,6 +31,7 @@ from openstack_dashboard.dashboards.identity.projects import workflows from openstack_dashboard.test import helpers as test from openstack_dashboard import usage from openstack_dashboard.usage import quotas +from openstack_dashboard.utils import identity INDEX_URL = reverse('horizon:identity:projects:index') @@ -1339,7 +1340,8 @@ class DetailProjectViewTests(test.BaseAdminViewTests): 'get_project_groups_roles', 'role_list', 'group_list'), - quotas: ('enabled_quotas',)}) + quotas: ('enabled_quotas',), + identity: ('get_domain_id_for_operation',)}) def test_detail_view_users_tab(self): project = self.tenants.first() domain = self.domains.first() @@ -1357,8 +1359,9 @@ class DetailProjectViewTests(test.BaseAdminViewTests): self.mock_domain_get.return_value = domain self.mock_enabled_quotas.return_value = ('instances',) self.mock_role_list.return_value = self.roles.list() + self.mock_get_domain_id_for_operation.return_value = domain.id - def _user_list_side_effect(request, group=None): + def _user_list_side_effect(request, group=None, domain=None): if group: return self._get_users_in_group(group) return users @@ -1408,13 +1411,14 @@ class DetailProjectViewTests(test.BaseAdminViewTests): domain.id) self.mock_enabled_quotas.assert_called_once_with(test.IsHttpRequest()) self.mock_role_list.assert_called_once_with(test.IsHttpRequest()) - self.mock_group_list.assert_called_once_with(test.IsHttpRequest()) + self.mock_group_list.assert_called_once_with(test.IsHttpRequest(), + domain="1") self.mock_get_project_users_roles.assert_called_once_with( test.IsHttpRequest(), project=project.id) self.mock_get_project_groups_roles.assert_called_once_with( test.IsHttpRequest(), project=project.id) - calls = [mock.call(test.IsHttpRequest()), - mock.call(test.IsHttpRequest(), group="1"), ] + calls = [mock.call(test.IsHttpRequest(), domain="1"), + mock.call(test.IsHttpRequest(), group="1", domain="1"), ] self.mock_user_list.assert_has_calls(calls) @@ -1506,11 +1510,13 @@ class DetailProjectViewTests(test.BaseAdminViewTests): self.mock_tenant_get.assert_called_once_with(test.IsHttpRequest(), self.tenant.id) - self.mock_domain_get.assert_called_once_with(test.IsHttpRequest(), - domain.id) + calls = [mock.call(test.IsHttpRequest(), "1"), + mock.call(test.IsHttpRequest(), None), ] + self.mock_domain_get.assert_has_calls(calls) self.mock_enabled_quotas.assert_called_once_with(test.IsHttpRequest()) self.mock_role_list.assert_called_once_with(test.IsHttpRequest()) - self.mock_group_list.assert_called_once_with(test.IsHttpRequest()) + self.mock_group_list.assert_called_once_with(test.IsHttpRequest(), + domain=None) self.mock_get_project_groups_roles.assert_called_once_with( test.IsHttpRequest(), project=project.id) @@ -1546,8 +1552,9 @@ class DetailProjectViewTests(test.BaseAdminViewTests): self.mock_tenant_get.assert_called_once_with(test.IsHttpRequest(), self.tenant.id) - self.mock_domain_get.assert_called_once_with(test.IsHttpRequest(), - domain.id) + calls = [mock.call(test.IsHttpRequest(), "1"), + mock.call(test.IsHttpRequest(), None), ] + self.mock_domain_get.assert_has_calls(calls) self.mock_enabled_quotas.assert_called_once_with(test.IsHttpRequest()) self.mock_get_project_groups_roles.assert_called_once_with( test.IsHttpRequest(), project=project.id)