From 2597c95de74c220de601f97a1848fb34590da455 Mon Sep 17 00:00:00 2001 From: Ali Asgar Adil Date: Mon, 22 Aug 2016 10:52:38 -0400 Subject: [PATCH] Trove user page doesn't show allowed hosts AND databases When creating a user with a --host parameter the database field is not shown in the UI. Added code to support the host parameter when modifying access to the database and when requesting user access list. Change-Id: I16293e9e220ce51e588f60a79ed28752cb89a6cc Closes-Bug: #1615672 --- trove_dashboard/api/trove.py | 9 +- trove_dashboard/content/databases/forms.py | 4 +- trove_dashboard/content/databases/tables.py | 31 +++---- trove_dashboard/content/databases/tabs.py | 3 +- trove_dashboard/content/databases/tests.py | 92 ++++++++++++--------- trove_dashboard/content/databases/urls.py | 3 +- trove_dashboard/content/databases/views.py | 13 +-- 7 files changed, 86 insertions(+), 69 deletions(-) diff --git a/trove_dashboard/api/trove.py b/trove_dashboard/api/trove.py index 3ea9892..079c5d7 100644 --- a/trove_dashboard/api/trove.py +++ b/trove_dashboard/api/trove.py @@ -288,8 +288,8 @@ def user_create(request, instance_id, username, password, return troveclient(request).users.create(instance_id, [user]) -def user_delete(request, instance_id, user): - return troveclient(request).users.delete(instance_id, user) +def user_delete(request, instance_id, user, host=None): + return troveclient(request).users.delete(instance_id, user, hostname=host) def user_update_attributes(request, instance_id, name, host=None, @@ -320,6 +320,11 @@ def user_revoke_access(request, instance_id, username, database, host=None): instance_id, username, database, hostname=host) +def user_show_access(request, instance_id, username, host=None): + return troveclient(request).users.list_access( + instance_id, username, hostname=host) + + def datastore_list(request): return troveclient(request).datastores.list() diff --git a/trove_dashboard/content/databases/forms.py b/trove_dashboard/content/databases/forms.py index 9068d00..478e407 100644 --- a/trove_dashboard/content/databases/forms.py +++ b/trove_dashboard/content/databases/forms.py @@ -199,7 +199,7 @@ class EditUserForm(forms.SelfHandlingForm): user_name = forms.CharField( label=_("Name"), widget=forms.TextInput(attrs={'readonly': 'readonly'})) - host = forms.CharField( + user_host = forms.CharField( label=_("Host"), required=False, widget=forms.TextInput(attrs={'readonly': 'readonly'})) new_name = forms.CharField(label=_("New Name"), required=False) @@ -220,7 +220,7 @@ class EditUserForm(forms.SelfHandlingForm): request, instance, data['user_name'], - host=data['host'], + host=data['user_host'], new_name=data['new_name'], new_password=data['new_password'], new_host=data['new_host']) diff --git a/trove_dashboard/content/databases/tables.py b/trove_dashboard/content/databases/tables.py index 34d4a6d..f1e3039 100644 --- a/trove_dashboard/content/databases/tables.py +++ b/trove_dashboard/content/databases/tables.py @@ -17,7 +17,7 @@ import six.moves.urllib.parse as urlparse from django.conf import settings from django.core import urlresolvers from django.template import defaultfilters as d_filters -from django.utils import http + from django.utils.translation import pgettext_lazy from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ungettext_lazy @@ -197,7 +197,7 @@ class GrantAccess(tables.BatchAction): self.table.kwargs['instance_id'], self.table.kwargs['user_name'], [obj_id], - host=parse_host_param(request)) + host=self.table.kwargs['user_host']) class RevokeAccess(tables.BatchAction): @@ -231,7 +231,7 @@ class RevokeAccess(tables.BatchAction): self.table.kwargs['instance_id'], self.table.kwargs['user_name'], obj_id, - host=parse_host_param(request)) + host=self.table.kwargs['user_host']) def parse_host_param(request): @@ -273,13 +273,9 @@ class ManageAccess(tables.LinkAction): def get_link_url(self, datum): user = datum - url = urlresolvers.reverse(self.url, args=[user.instance.id, - user.name]) - if user.host: - params = http.urlencode({"host": user.host}) - url = "?".join([url, params]) - - return url + return urlresolvers.reverse(self.url, args=[user.instance.id, + user.name, + user.host]) class CreateUser(tables.LinkAction): @@ -313,13 +309,9 @@ class EditUser(tables.LinkAction): def get_link_url(self, datum): user = datum - url = urlresolvers.reverse(self.url, args=[user.instance.id, - user.name]) - if user.host: - params = http.urlencode({"host": user.host}) - url = "?".join([url, params]) - - return url + return urlresolvers.reverse(self.url, args=[user.instance.id, + user.name, + user.host]) def has_user_add_perm(request): @@ -347,8 +339,9 @@ class DeleteUser(tables.DeleteAction): ) def delete(self, request, obj_id): - datum = self.table.get_object_by_id(obj_id) - api.trove.user_delete(request, datum.instance.id, datum.name) + user = self.table.get_object_by_id(obj_id) + api.trove.user_delete(request, user.instance.id, user.name, + host=user.host) class CreateDatabase(tables.LinkAction): diff --git a/trove_dashboard/content/databases/tabs.py b/trove_dashboard/content/databases/tabs.py index d640880..7acabb7 100644 --- a/trove_dashboard/content/databases/tabs.py +++ b/trove_dashboard/content/databases/tabs.py @@ -82,7 +82,8 @@ class UserTab(tabs.TableTab): try: user.access = api.trove.user_list_access(self.request, instance.id, - user.name) + user.name, + host=user.host) except exceptions.NOT_FOUND: pass except Exception: diff --git a/trove_dashboard/content/databases/tests.py b/trove_dashboard/content/databases/tests.py index f974c8b..cdde3a5 100644 --- a/trove_dashboard/content/databases/tests.py +++ b/trove_dashboard/content/databases/tests.py @@ -624,9 +624,10 @@ class DatabaseTests(test.TestCase): self.assertEqual(table.data[0].enabled, True) self.assertEqual(table.data[0].password, "password") - @test.create_stubs( - {api.trove: ('instance_get', 'flavor_get', 'users_list', - 'user_list_access', 'user_delete')}) + @test.create_stubs({ + api.trove: ('instance_get', 'flavor_get', 'user_delete', 'users_list', + 'user_list_access') + }) def test_user_delete(self): database = self.databases.first() user = self.database_users.first() @@ -644,15 +645,16 @@ class DatabaseTests(test.TestCase): # tabs.py: UserTab.get_user_data api.trove.users_list(IsA(http.HttpRequest), - database_id).AndReturn([user]) + IsA(str)).AndReturn([user]) api.trove.user_list_access(IsA(http.HttpRequest), - database_id, - user_id).AndReturn([user_db]) + IsA(str), + IsA(str), + host=IsA(str)).AndReturn([user_db]) # tables.py: DeleteUser.delete api.trove.user_delete(IsA(http.HttpRequest), - database_id, - user_id).AndReturn(None) + IsA(six.text_type), + IsA(six.text_type)).AndReturn(None) self.mox.ReplayAll() @@ -726,18 +728,19 @@ class DatabaseTests(test.TestCase): user = self.users.first() api.trove.user_update_attributes( - IsA(http.HttpRequest), database.id, user.name, host=u'', - new_name=u'new_name', new_password=u'new_password', - new_host=u'127.0.0.1') + IsA(http.HttpRequest), IsA(six.text_type), IsA(six.text_type), + host=IsA(six.text_type), new_name=IsA(six.text_type), + new_password=IsA(six.text_type), new_host=IsA(six.text_type)) self.mox.ReplayAll() url = reverse('horizon:project:databases:edit_user', - args=[database.id, user.name]) + args=[database.id, user.name, '%']) post = { 'method': 'EditUserForm', 'instance_id': database.id, 'user_name': user.name, + 'user_host': '%', 'new_name': 'new_name', 'new_password': 'new_password', 'new_host': '127.0.0.1'} @@ -752,20 +755,20 @@ class DatabaseTests(test.TestCase): user = self.users.first() api.trove.user_update_attributes( - IsA(http.HttpRequest), database.id, user.name, host=u'', - new_name=u'new_name', new_password=u'new_password', - new_host=u'127.0.0.1') \ - .AndRaise(self.exceptions.trove) + IsA(http.HttpRequest), IsA(six.text_type), IsA(six.text_type), + host=IsA(six.text_type), new_name=IsA(six.text_type), + new_password=IsA(six.text_type), new_host=IsA(six.text_type)) self.mox.ReplayAll() url = reverse('horizon:project:databases:edit_user', - args=[database.id, user.name]) + args=[database.id, user.name, '%']) post = { 'method': 'EditUserForm', 'instance_id': database.id, 'user_name': user.name, 'new_name': 'new_name', + 'user_host': '%', 'new_password': 'new_password', 'new_host': '127.0.0.1'} @@ -777,60 +780,66 @@ class DatabaseTests(test.TestCase): user = self.users.first() url = reverse('horizon:project:databases:edit_user', - args=[database.id, user.name]) + args=[database.id, user.name, '%']) post = { 'method': 'EditUserForm', 'instance_id': database.id, - 'user_name': user.name} + 'user_name': user.name, + 'user_host': '%'} res = self.client.post(url, post) msg = forms.EditUserForm.validation_error_message self.assertFormError(res, "form", None, [msg]) - @test.create_stubs({api.trove: ('database_list', 'user_list_access')}) + @test.create_stubs({api.trove: ('database_list', 'user_show_access')}) def test_access_detail_get(self): - api.trove.database_list(IsA(http.HttpRequest), u'id') \ + api.trove.database_list(IsA(http.HttpRequest), IsA(six.text_type)) \ .AndReturn(self.databases.list()) - api.trove.user_list_access(IsA(http.HttpRequest), u'id', u'name') \ + api.trove.user_show_access(IsA(http.HttpRequest), IsA(six.text_type), + IsA(six.text_type), + host=IsA(six.text_type)) \ .AndReturn(self.databases.list()) self.mox.ReplayAll() url = reverse('horizon:project:databases:access_detail', - args=['id', 'name']) + args=['id', 'name', 'host']) res = self.client.get(url) self.assertTemplateUsed( res, 'project/databases/access_detail.html') - @test.create_stubs({api.trove: ('database_list', 'user_list_access')}) + @test.create_stubs({api.trove: ('database_list', 'user_show_access')}) def test_access_detail_get_exception(self): - api.trove.database_list(IsA(http.HttpRequest), u'id') \ + api.trove.database_list(IsA(http.HttpRequest), IsA(six.text_type)) \ .AndReturn(self.databases.list()) - api.trove.user_list_access(IsA(http.HttpRequest), u'id', u'name') \ + api.trove.user_show_access(IsA(http.HttpRequest), IsA(six.text_type), + IsA(six.text_type), + host=IsA(six.text_type)) \ .AndRaise(self.exceptions.trove) self.mox.ReplayAll() url = reverse('horizon:project:databases:access_detail', - args=['id', 'name']) + args=['id', 'name', 'host']) res = self.client.get(url) self.assertRedirectsNoFollow(res, DETAILS_URL) @test.create_stubs({api.trove: ('user_grant_access',)}) def test_detail_grant_access(self): api.trove.user_grant_access( - IsA(http.HttpRequest), u'id', u'name', [u'db1'], None) + IsA(http.HttpRequest), IsA(six.text_type), IsA(six.text_type), + [IsA(six.text_type)], host=IsA(six.text_type)) self.mox.ReplayAll() url = reverse('horizon:project:databases:access_detail', - args=['id', 'name']) + args=['id', 'name', 'host']) form_data = {"action": "access__grant_access__%s" % 'db1'} req = self.factory.post(url, form_data) - kwargs = {'instance_id': 'id', 'user_name': 'name'} + kwargs = {'instance_id': 'id', 'user_name': 'name', 'user_host': '%'} db_access_list = [] db_access = views.DBAccess('db1', False) @@ -845,17 +854,18 @@ class DatabaseTests(test.TestCase): @test.create_stubs({api.trove: ('user_grant_access',)}) def test_detail_grant_access_exception(self): api.trove.user_grant_access( - IsA(http.HttpRequest), u'id', u'name', [u'db1'], None) \ + IsA(http.HttpRequest), IsA(six.text_type), IsA(six.text_type), + [IsA(six.text_type)], host=IsA(six.text_type)) \ .AndRaise(self.exceptions.trove) self.mox.ReplayAll() url = reverse('horizon:project:databases:access_detail', - args=['id', 'name']) + args=['id', 'name', 'host']) form_data = {"action": "access__grant_access__%s" % 'db1'} req = self.factory.post(url, form_data) - kwargs = {'instance_id': 'id', 'user_name': 'name'} + kwargs = {'instance_id': 'id', 'user_name': 'name', 'user_host': '%'} db_access_list = [] db_access = views.DBAccess('db1', False) @@ -871,15 +881,17 @@ class DatabaseTests(test.TestCase): def test_detail_revoke_access(self): api.trove.user_revoke_access( - IsA(http.HttpRequest), u'id', u'name', u'db1', None) + IsA(http.HttpRequest), IsA(six.text_type), IsA(six.text_type), + [IsA(six.text_type)], host=IsA(six.text_type)) + self.mox.ReplayAll() url = reverse('horizon:project:databases:access_detail', - args=['id', 'name']) + args=['id', 'name', 'host']) form_data = {"action": "access__revoke_access__%s" % 'db1'} req = self.factory.post(url, form_data) - kwargs = {'instance_id': 'id', 'user_name': 'name'} + kwargs = {'instance_id': 'id', 'user_name': 'name', 'user_host': '%'} db_access_list = [] db_access = views.DBAccess('db1', True) @@ -895,16 +907,18 @@ class DatabaseTests(test.TestCase): def test_detail_revoke_access_exception(self): api.trove.user_revoke_access( - IsA(http.HttpRequest), u'id', u'name', u'db1', None) \ + IsA(http.HttpRequest), IsA(six.text_type), IsA(six.text_type), + [IsA(six.text_type)], host=IsA(six.text_type)) \ .AndRaise(self.exceptions.trove) + self.mox.ReplayAll() url = reverse('horizon:project:databases:access_detail', - args=['id', 'name']) + args=['id', 'name', 'host']) form_data = {"action": "access__revoke_access__%s" % 'db1'} req = self.factory.post(url, form_data) - kwargs = {'instance_id': 'id', 'user_name': 'name'} + kwargs = {'instance_id': 'id', 'user_name': 'name', 'user_host': '%'} db_access_list = [] db_access = views.DBAccess('db1', True) diff --git a/trove_dashboard/content/databases/urls.py b/trove_dashboard/content/databases/urls.py index 1ae2a49..bf5ffcc 100644 --- a/trove_dashboard/content/databases/urls.py +++ b/trove_dashboard/content/databases/urls.py @@ -21,7 +21,8 @@ from trove_dashboard.content.databases import views BASEINSTANCES = r'^(?P[^/]+)/%s' INSTANCES = BASEINSTANCES + '$' -USERS = r'^(?P[^/]+)/(?P[^/]+)/%s$' +USERS = r'^(?P[^/]+)/(?P[^/]+)/' \ + r'(?P[^/]+)/%s$' urlpatterns = patterns( diff --git a/trove_dashboard/content/databases/views.py b/trove_dashboard/content/databases/views.py index 80f373d..348dc7b 100644 --- a/trove_dashboard/content/databases/views.py +++ b/trove_dashboard/content/databases/views.py @@ -146,16 +146,18 @@ class EditUserView(horizon_forms.ModalFormView): context = super(EditUserView, self).get_context_data(**kwargs) context['instance_id'] = self.kwargs['instance_id'] context['user_name'] = self.kwargs['user_name'] - args = (self.kwargs['instance_id'], self.kwargs['user_name']) + context['user_host'] = self.kwargs['user_host'] + args = (self.kwargs['instance_id'], self.kwargs['user_name'], + self.kwargs['user_host']) context['submit_url'] = reverse(self.submit_url, args=args) return context def get_initial(self): instance_id = self.kwargs['instance_id'] user_name = self.kwargs['user_name'] - host = tables.parse_host_param(self.request) + user_host = self.kwargs['user_host'] return {'instance_id': instance_id, 'user_name': user_name, - 'host': host} + 'user_host': user_host} class AccessDetailView(horizon_tables.DataTableView): @@ -167,6 +169,7 @@ class AccessDetailView(horizon_tables.DataTableView): def get_data(self): instance_id = self.kwargs['instance_id'] user_name = self.kwargs['user_name'] + user_host = self.kwargs['user_host'] try: databases = api.trove.database_list(self.request, instance_id) except Exception: @@ -177,8 +180,8 @@ class AccessDetailView(horizon_tables.DataTableView): _('Unable to retrieve databases.'), redirect=redirect) try: - granted = api.trove.user_list_access( - self.request, instance_id, user_name) + granted = api.trove.user_show_access( + self.request, instance_id, user_name, host=user_host) except Exception: granted = [] redirect = reverse('horizon:project:databases:detail',