Show domain info in project and user detail panel
Domain info in the user detail panel was previously displayed but it has been broken after the user detail panel was tabbified. This commit fixes the handling of context data. This covers domain_name, project_name and extras. Similar change is applied to the project detail panel too. Change-Id: I575ae9697783c36fdae5dd397d6783b979d0c4a6 Closes-Bug: #1809284
This commit is contained in:
parent
f02e7c5ade
commit
3a584a90c1
@ -17,6 +17,7 @@ from horizon import exceptions
|
||||
from horizon import tabs
|
||||
|
||||
from openstack_dashboard import api
|
||||
from openstack_dashboard import policy
|
||||
|
||||
from openstack_dashboard.dashboards.identity.projects.groups \
|
||||
import tables as groups_tables
|
||||
@ -32,15 +33,36 @@ class OverviewTab(tabs.Tab):
|
||||
|
||||
def get_context_data(self, request):
|
||||
project = self.tab_group.kwargs['project']
|
||||
context = {"project": project}
|
||||
return {
|
||||
"project": project,
|
||||
"domain_name": self._get_domain_name(project),
|
||||
"extras": self._get_extras(project),
|
||||
}
|
||||
|
||||
def _get_domain_name(self, project):
|
||||
domain_name = ''
|
||||
if api.keystone.VERSIONS.active >= 3:
|
||||
try:
|
||||
if policy.check((("identity", "identity:get_domain"),),
|
||||
self.request):
|
||||
domain = api.keystone.domain_get(
|
||||
self.request, project.domain_id)
|
||||
domain_name = domain.name
|
||||
else:
|
||||
domain = api.keystone.get_default_domain(self.request)
|
||||
domain_name = domain.get('name')
|
||||
except Exception:
|
||||
exceptions.handle(self.request,
|
||||
_('Unable to retrieve project domain.'))
|
||||
return domain_name
|
||||
|
||||
def _get_extras(self, project):
|
||||
if api.keystone.VERSIONS.active >= 3:
|
||||
extra_info = getattr(settings, 'PROJECT_TABLE_EXTRA_INFO', {})
|
||||
context['extras'] = dict(
|
||||
(display_key, getattr(project, key, ''))
|
||||
for key, display_key in extra_info.items())
|
||||
|
||||
return context
|
||||
return dict((display_key, getattr(project, key, ''))
|
||||
for key, display_key in extra_info.items())
|
||||
else:
|
||||
return {}
|
||||
|
||||
|
||||
class UsersTab(tabs.TableTab):
|
||||
|
@ -2,14 +2,20 @@
|
||||
|
||||
<div class="detail">
|
||||
<dl class="dl-horizontal">
|
||||
<dt>{% trans "Project Name" %}</dt>
|
||||
<dt>{% trans "Name" %}</dt>
|
||||
<dd data-display="{{ project.name|default:project.id }}">{{ project.name }}</dd>
|
||||
<dt>{% trans "Project ID" %}</dt>
|
||||
<dt>{% trans "ID" %}</dt>
|
||||
<dd>{{ project.id }}</dd>
|
||||
{% if domain_name %}
|
||||
<dt>{% trans "Domain Name" %}</dt>
|
||||
<dd>{{ domain_name }}</dd>
|
||||
{% endif %}
|
||||
<dt>{% trans "Domain ID" %}</dt>
|
||||
<dd>{{ project.domain_id }}</dd>
|
||||
<dt>{% trans "Enabled" %}</dt>
|
||||
<dd>{{ project.enabled|yesno|capfirst }}</dd>
|
||||
<dt>{% trans "Description" %}</dt>
|
||||
<dd>{{ project.description|default:_("None") }}</dd>
|
||||
<dd>{{ project.description|default:_("-") }}</dd>
|
||||
{% if extras %}
|
||||
{% for key, value in extras.items %}
|
||||
<dt>{{ key }}</dt>
|
||||
|
@ -1286,12 +1286,14 @@ class UsageViewTests(test.BaseAdminViewTests):
|
||||
|
||||
class DetailProjectViewTests(test.BaseAdminViewTests):
|
||||
|
||||
@test.create_mocks({api.keystone: ('tenant_get',),
|
||||
@test.create_mocks({api.keystone: ('tenant_get', 'domain_get'),
|
||||
quotas: ('enabled_quotas',)})
|
||||
def test_detail_view(self):
|
||||
project = self.tenants.first()
|
||||
domain = self.domains.first()
|
||||
|
||||
self.mock_tenant_get.return_value = project
|
||||
self.mock_domain_get.return_value = domain
|
||||
self.mock_enabled_quotas.return_value = ('instances',)
|
||||
|
||||
res = self.client.get(PROJECT_DETAIL_URL, args=[project.id])
|
||||
@ -1304,6 +1306,8 @@ 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)
|
||||
self.mock_enabled_quotas.assert_called_once_with(test.IsHttpRequest())
|
||||
|
||||
@test.create_mocks({api.keystone: ('tenant_get',)})
|
||||
@ -1319,7 +1323,7 @@ class DetailProjectViewTests(test.BaseAdminViewTests):
|
||||
self.mock_tenant_get.assert_called_once_with(test.IsHttpRequest(),
|
||||
self.tenant.id)
|
||||
|
||||
@test.create_mocks({api.keystone: ('tenant_get',),
|
||||
@test.create_mocks({api.keystone: ('tenant_get', 'domain_get'),
|
||||
quotas: ('enabled_quotas',)})
|
||||
def test_detail_view_overview_tab(self):
|
||||
"""Test the overview tab of the detail view .
|
||||
@ -1327,8 +1331,10 @@ class DetailProjectViewTests(test.BaseAdminViewTests):
|
||||
Test the overview tab using directly the url targeting the tab.
|
||||
"""
|
||||
project = self.tenants.first()
|
||||
domain = self.domains.first()
|
||||
|
||||
self.mock_tenant_get.return_value = project
|
||||
self.mock_domain_get.return_value = domain
|
||||
self.mock_enabled_quotas.return_value = ('instances',)
|
||||
|
||||
# Url of the overview tab of the detail view
|
||||
@ -1348,6 +1354,8 @@ 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)
|
||||
self.mock_enabled_quotas.assert_called_once_with(test.IsHttpRequest())
|
||||
|
||||
def _get_users_in_group(self, group_id):
|
||||
@ -1375,6 +1383,7 @@ class DetailProjectViewTests(test.BaseAdminViewTests):
|
||||
return roles
|
||||
|
||||
@test.create_mocks({api.keystone: ('tenant_get',
|
||||
'domain_get',
|
||||
'user_list',
|
||||
'get_project_users_roles',
|
||||
'get_project_groups_roles',
|
||||
@ -1383,6 +1392,7 @@ class DetailProjectViewTests(test.BaseAdminViewTests):
|
||||
quotas: ('enabled_quotas',)})
|
||||
def test_detail_view_users_tab(self):
|
||||
project = self.tenants.first()
|
||||
domain = self.domains.first()
|
||||
users = self.users.filter(domain_id=project.domain_id)
|
||||
groups = self.groups.filter(domain_id=project.domain_id)
|
||||
role_assignments = self.role_assignments.filter(
|
||||
@ -1394,6 +1404,7 @@ class DetailProjectViewTests(test.BaseAdminViewTests):
|
||||
|
||||
# Prepare mocks
|
||||
self.mock_tenant_get.return_value = project
|
||||
self.mock_domain_get.return_value = domain
|
||||
self.mock_enabled_quotas.return_value = ('instances',)
|
||||
self.mock_role_list.return_value = self.roles.list()
|
||||
|
||||
@ -1443,6 +1454,8 @@ 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)
|
||||
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())
|
||||
@ -1456,13 +1469,16 @@ class DetailProjectViewTests(test.BaseAdminViewTests):
|
||||
self.mock_user_list.assert_has_calls(calls)
|
||||
|
||||
@test.create_mocks({api.keystone: ("tenant_get",
|
||||
"domain_get",
|
||||
"role_list",),
|
||||
quotas: ('enabled_quotas',)})
|
||||
def test_detail_view_users_tab_exception(self):
|
||||
project = self.tenants.first()
|
||||
domain = self.domains.first()
|
||||
|
||||
# Prepare mocks
|
||||
self.mock_tenant_get.return_value = project
|
||||
self.mock_domain_get.return_value = domain
|
||||
self.mock_enabled_quotas.return_value = ('instances',)
|
||||
self.mock_role_list.side_effect = self.exceptions.keystone
|
||||
|
||||
@ -1483,16 +1499,20 @@ 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)
|
||||
self.mock_enabled_quotas.assert_called_once_with(test.IsHttpRequest())
|
||||
self.mock_role_list.assert_called_once_with(test.IsHttpRequest())
|
||||
|
||||
@test.create_mocks({api.keystone: ("tenant_get",
|
||||
"domain_get",
|
||||
"get_project_groups_roles",
|
||||
"role_list",
|
||||
"group_list"),
|
||||
quotas: ('enabled_quotas',)})
|
||||
def test_detail_view_groups_tab(self):
|
||||
project = self.tenants.first()
|
||||
domain = self.domains.first()
|
||||
groups = self.groups.filter(domain_id=project.domain_id)
|
||||
role_assignments = self.role_assignments.filter(
|
||||
scope={'project': {'id': project.id}})
|
||||
@ -1501,6 +1521,7 @@ class DetailProjectViewTests(test.BaseAdminViewTests):
|
||||
|
||||
# Prepare mocks
|
||||
self.mock_tenant_get.return_value = project
|
||||
self.mock_domain_get.return_value = domain
|
||||
self.mock_enabled_quotas.return_value = ('instances',)
|
||||
self.mock_get_project_groups_roles.return_value = project_groups_roles
|
||||
self.mock_group_list.return_value = groups
|
||||
@ -1535,6 +1556,8 @@ 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)
|
||||
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())
|
||||
@ -1542,13 +1565,16 @@ class DetailProjectViewTests(test.BaseAdminViewTests):
|
||||
test.IsHttpRequest(), project=project.id)
|
||||
|
||||
@test.create_mocks({api.keystone: ("tenant_get",
|
||||
"domain_get",
|
||||
"get_project_groups_roles"),
|
||||
quotas: ('enabled_quotas',)})
|
||||
def test_detail_view_groups_tab_exception(self):
|
||||
project = self.tenants.first()
|
||||
domain = self.domains.first()
|
||||
|
||||
# Prepare mocks
|
||||
self.mock_tenant_get.return_value = project
|
||||
self.mock_domain_get.return_value = domain
|
||||
self.mock_enabled_quotas.return_value = ('instances',)
|
||||
self.mock_get_project_groups_roles.side_effect = \
|
||||
self.exceptions.keystone
|
||||
@ -1570,6 +1596,8 @@ 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)
|
||||
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)
|
||||
|
@ -10,7 +10,9 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import logging
|
||||
|
||||
from django.conf import settings
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from horizon import exceptions
|
||||
@ -21,6 +23,10 @@ from openstack_dashboard.dashboards.identity.users.groups \
|
||||
import tables as groups_tables
|
||||
from openstack_dashboard.dashboards.identity.users.role_assignments \
|
||||
import tables as role_assignments_tables
|
||||
from openstack_dashboard import policy
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class OverviewTab(tabs.Tab):
|
||||
@ -32,8 +38,50 @@ class OverviewTab(tabs.Tab):
|
||||
slug = "overview"
|
||||
template_name = 'identity/users/_detail_overview.html'
|
||||
|
||||
def _get_domain_name(self, user):
|
||||
domain_name = ''
|
||||
if api.keystone.VERSIONS.active >= 3:
|
||||
try:
|
||||
if policy.check((("identity", "identity:get_domain"),),
|
||||
self.request):
|
||||
domain = api.keystone.domain_get(
|
||||
self.request, user.domain_id)
|
||||
domain_name = domain.name
|
||||
else:
|
||||
domain = api.keystone.get_default_domain(self.request)
|
||||
domain_name = domain.get('name')
|
||||
except Exception:
|
||||
exceptions.handle(self.request,
|
||||
_('Unable to retrieve user domain.'))
|
||||
return domain_name
|
||||
|
||||
def _get_project_name(self, user):
|
||||
project_id = user.project_id
|
||||
if not project_id:
|
||||
return
|
||||
try:
|
||||
tenant = api.keystone.tenant_get(self.request, project_id)
|
||||
return tenant.name
|
||||
except Exception as e:
|
||||
LOG.error('Failed to get tenant %(project_id)s: %(reason)s',
|
||||
{'project_id': project_id, 'reason': e})
|
||||
|
||||
def _get_extras(self, user):
|
||||
if api.keystone.VERSIONS.active >= 3:
|
||||
extra_info = getattr(settings, 'USER_TABLE_EXTRA_INFO', {})
|
||||
return dict((display_key, getattr(user, key, ''))
|
||||
for key, display_key in extra_info.items())
|
||||
else:
|
||||
return {}
|
||||
|
||||
def get_context_data(self, request):
|
||||
return {"user": self.tab_group.kwargs['user']}
|
||||
user = self.tab_group.kwargs['user']
|
||||
return {
|
||||
"user": user,
|
||||
"domain_name": self._get_domain_name(user),
|
||||
'extras': self._get_extras(user),
|
||||
'project_name': self._get_project_name(user),
|
||||
}
|
||||
|
||||
|
||||
class RoleAssignmentsTab(tabs.TableTab):
|
||||
|
@ -2,33 +2,32 @@
|
||||
|
||||
<div class="detail">
|
||||
<dl class="dl-horizontal">
|
||||
{% if domain_id %}
|
||||
<dt>{% trans "Domain ID" %}</dt>
|
||||
<dd>{{ domain_id }}</dd>
|
||||
{% endif %}
|
||||
<dt>{% trans "Name" %}</dt>
|
||||
<dd data-display="{{ user.name|default:user.id }}" class="word-wrap">{{ user.name }}</dd>
|
||||
<dt>{% trans "ID" %}</dt>
|
||||
<dd>{{ user.id }}</dd>
|
||||
{% if domain_name %}
|
||||
<dt>{% trans "Domain Name" %}</dt>
|
||||
<dd class="word-wrap">{{ domain_name }}</dd>
|
||||
{% endif %}
|
||||
<dt>{% trans "User Name" %}</dt>
|
||||
<dd data-display="{{ user.name|default:user.id }}" class="word-wrap">{{ user.name }}</dd>
|
||||
{% if description %}
|
||||
<dt>{% trans "Description" %}</dt>
|
||||
<dd>{{ description }}</dd>
|
||||
{% endif %}
|
||||
<dt>{% trans "ID" %}</dt>
|
||||
<dd>{{ user.id }}</dd>
|
||||
<dt>{% trans "Domain ID" %}</dt>
|
||||
<dd>{{ user.domain_id }}</dd>
|
||||
<dt>{% trans "Description" %}</dt>
|
||||
<dd>{{ user.description|default:_("-") }}</dd>
|
||||
<dt>{% trans "Email" %}</dt>
|
||||
<dd>{{ user.email|default:_("None") }}</dd>
|
||||
<dd>{{ user.email|default:_("-") }}</dd>
|
||||
<dt>{% trans "Enabled" %}</dt>
|
||||
<dd>{{ user.enabled|yesno|capfirst }}</dd>
|
||||
<dt>{% trans "Password Expires At" %}</dt>
|
||||
<dd>{{ user.password_expires_at }}</dd>
|
||||
<dt>{% trans "Primary Project ID" %}</dt>
|
||||
<dd>{{ user.project_id }}</dd>
|
||||
{% if tenant_name %}
|
||||
<dt>{% trans "Primary Project Name" %}</dt>
|
||||
<dd class="word-wrap">{{ tenant_name }}</dd>
|
||||
<dt>{% trans "Primary Project" %}</dt>
|
||||
{% if user.project_id %}
|
||||
<dd class="word-wrap">
|
||||
<a href="{% url 'horizon:identity:projects:detail' project_id=user.project_id %}">
|
||||
{{ project_name|default:user.project_id }}</a>
|
||||
</dd>
|
||||
{% else %}
|
||||
<dd>{% trans "-" %}</dd>
|
||||
{% endif %}
|
||||
{% if extras %}
|
||||
{% for key, value in extras.items %}
|
||||
|
@ -864,7 +864,7 @@ class UsersViewTests(test.BaseAdminViewTests):
|
||||
self.assertTemplateUsed(res, 'identity/users/_detail_overview.html')
|
||||
self.assertEqual(res.context['user'].name, user.name)
|
||||
self.assertEqual(res.context['user'].id, user.id)
|
||||
self.assertEqual(res.context['tenant_name'], tenant.name)
|
||||
self.assertEqual(res.context['project_name'], tenant.name)
|
||||
|
||||
self.mock_domain_get.assert_called_once_with(test.IsHttpRequest(), '1')
|
||||
self.mock_user_get.assert_called_once_with(test.IsHttpRequest(), '1',
|
||||
@ -914,7 +914,7 @@ class UsersViewTests(test.BaseAdminViewTests):
|
||||
self.assertTemplateUsed(res, 'identity/users/_detail_overview.html')
|
||||
self.assertEqual(res.context['user'].name, user.name)
|
||||
self.assertEqual(res.context['user'].id, user.id)
|
||||
self.assertEqual(res.context['tenant_name'], tenant.name)
|
||||
self.assertEqual(res.context['project_name'], tenant.name)
|
||||
|
||||
self.mock_domain_get.assert_called_once_with(test.IsHttpRequest(), '1')
|
||||
self.mock_user_get.assert_called_once_with(test.IsHttpRequest(), '1',
|
||||
|
@ -207,48 +207,12 @@ class DetailView(tabs.TabView):
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super(DetailView, self).get_context_data(**kwargs)
|
||||
user = self.get_data()
|
||||
tenant = self.get_tenant(user.project_id)
|
||||
table = project_tables.UsersTable(self.request)
|
||||
domain_id = getattr(user, "domain_id", None)
|
||||
domain_name = ''
|
||||
if api.keystone.VERSIONS.active >= 3:
|
||||
try:
|
||||
if policy.check((("identity", "identity:get_domain"),),
|
||||
self.request):
|
||||
domain = api.keystone.domain_get(
|
||||
self.request, domain_id)
|
||||
domain_name = domain.name
|
||||
else:
|
||||
domain = api.keystone.get_default_domain(self.request)
|
||||
domain_name = domain.get('name')
|
||||
except Exception:
|
||||
exceptions.handle(self.request,
|
||||
_('Unable to retrieve project domain.'))
|
||||
context["description"] = getattr(user, "description", _("None"))
|
||||
extra_info = getattr(settings, 'USER_TABLE_EXTRA_INFO', {})
|
||||
context['extras'] = dict(
|
||||
(display_key, getattr(user, key, ''))
|
||||
for key, display_key in extra_info.items())
|
||||
context["user"] = user
|
||||
if tenant:
|
||||
context["tenant_name"] = tenant.name
|
||||
context["domain_id"] = domain_id
|
||||
context["domain_name"] = domain_name
|
||||
context["url"] = self.get_redirect_url()
|
||||
context["actions"] = table.render_row_actions(user)
|
||||
return context
|
||||
|
||||
@memoized.memoized_method
|
||||
def get_tenant(self, project_id):
|
||||
tenant = None
|
||||
if project_id:
|
||||
try:
|
||||
tenant = api.keystone.tenant_get(self.request, project_id)
|
||||
except Exception as e:
|
||||
LOG.error('Failed to get tenant %(project_id)s: %(reason)s',
|
||||
{'project_id': project_id, 'reason': e})
|
||||
return tenant
|
||||
|
||||
@memoized.memoized_method
|
||||
def get_data(self):
|
||||
try:
|
||||
|
Loading…
x
Reference in New Issue
Block a user