diff --git a/openstack_dashboard/dashboards/identity/users/templates/users/_detail_overview.html b/openstack_dashboard/dashboards/identity/users/templates/users/_detail_overview.html
index 196be2c6ca..08a36ddf08 100644
--- a/openstack_dashboard/dashboards/identity/users/templates/users/_detail_overview.html
+++ b/openstack_dashboard/dashboards/identity/users/templates/users/_detail_overview.html
@@ -24,6 +24,10 @@
{{ user.enabled|yesno|capfirst }}
{% trans "Project ID" %}
{{ user.project_id }}
+ {% if tenant_name %}
+ {% trans "Project Name" %}
+ {{ tenant_name }}
+ {% endif %}
diff --git a/openstack_dashboard/dashboards/identity/users/tests.py b/openstack_dashboard/dashboards/identity/users/tests.py
index e513bb92de..e6b0f5b980 100644
--- a/openstack_dashboard/dashboards/identity/users/tests.py
+++ b/openstack_dashboard/dashboards/identity/users/tests.py
@@ -585,11 +585,14 @@ class UsersViewTests(test.BaseAdminViewTests):
u'You are not allowed to delete user: %s'
% self.request.user.username)
- @test.create_stubs({api.keystone: ('user_get',)})
+ @test.create_stubs({api.keystone: ('user_get', 'tenant_get')})
def test_detail_view(self):
user = self.users.get(id="1")
+ tenant = self.tenants.get(id=user.project_id)
api.keystone.user_get(IsA(http.HttpRequest), '1').AndReturn(user)
+ api.keystone.tenant_get(IsA(http.HttpRequest), user.project_id) \
+ .AndReturn(tenant)
self.mox.ReplayAll()
res = self.client.get(USER_DETAIL_URL, args=[user.id])
@@ -599,6 +602,7 @@ class UsersViewTests(test.BaseAdminViewTests):
self.assertEqual(res.context['user'].id, user.id)
self.assertContains(res, "User Details: %s
" % user.name,
1, 200)
+ self.assertEqual(res.context['tenant_name'], tenant.name)
@test.create_stubs({api.keystone: ('user_get',)})
def test_detail_view_with_exception(self):
diff --git a/openstack_dashboard/dashboards/identity/users/views.py b/openstack_dashboard/dashboards/identity/users/views.py
index 73b2a321dc..b635337384 100644
--- a/openstack_dashboard/dashboards/identity/users/views.py
+++ b/openstack_dashboard/dashboards/identity/users/views.py
@@ -16,6 +16,7 @@
# License for the specific language governing permissions and limitations
# under the License.
+import logging
import operator
from django.core.urlresolvers import reverse
@@ -39,6 +40,8 @@ from openstack_dashboard.dashboards.identity.users \
from openstack_dashboard.dashboards.identity.users \
import tables as project_tables
+LOG = logging.getLogger(__name__)
+
class IndexView(tables.DataTableView):
table_class = project_tables.UsersTable
@@ -166,6 +169,7 @@ class DetailView(views.HorizonTemplateView):
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 = ''
@@ -178,12 +182,26 @@ class DetailView(views.HorizonTemplateView):
_('Unable to retrieve project domain.'))
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:
+ msg = ('Failed to get tenant %(project_id)s: %(reason)s' %
+ {'project_id': project_id, 'reason': e})
+ LOG.error(msg)
+ return tenant
+
@memoized.memoized_method
def get_data(self):
try: