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:
parent
265795c352
commit
2597c95de7
@ -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()
|
||||
|
||||
|
@ -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'])
|
||||
|
@ -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):
|
||||
|
@ -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:
|
||||
|
@ -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)
|
||||
|
@ -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(
|
||||
|
@ -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',
|
||||
|
Loading…
x
Reference in New Issue
Block a user