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
This commit is contained in:
Ali Asgar Adil 2016-08-22 10:52:38 -04:00 committed by Ali Adil
parent 265795c352
commit 2597c95de7
7 changed files with 86 additions and 69 deletions

View File

@ -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()

View File

@ -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'])

View File

@ -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):

View File

@ -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:

View File

@ -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)

View File

@ -21,7 +21,8 @@ from trove_dashboard.content.databases import views
BASEINSTANCES = r'^(?P<instance_id>[^/]+)/%s'
INSTANCES = BASEINSTANCES + '$'
USERS = r'^(?P<instance_id>[^/]+)/(?P<user_name>[^/]+)/%s$'
USERS = r'^(?P<instance_id>[^/]+)/(?P<user_name>[^/]+)/' \
r'(?P<user_host>[^/]+)/%s$'
urlpatterns = patterns(

View File

@ -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',