Fixes to the user form, UI behaviors, and tests.
The message you got upon successful user update was misleading as it told you all of the fields were updated, even if no changes were made to those fields. Also there was an issue where in this user edit form, where if can_edit_user was False in the local_settings file, you could not change the default project for a user. Changed the stubbing behavior for tests as well to allow the use of a decorator to stub your tests using Mox instead of having to clutter up the actual test with repetitive Mox stubs. Fixes Bug #993572 Change-Id: Iaebd6525bb4509a2ec6b350df432f4f60dd35114
This commit is contained in:
parent
cc91a19c0a
commit
65824cb8c8
@ -14,7 +14,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="right">
|
<div class="right">
|
||||||
<h3>{% trans "Description" %}:</h3>
|
<h3>{% trans "Description" %}:</h3>
|
||||||
<p>{% trans "From here you can edit the user by changing their username, email, password, and default project." %}</p>
|
<p>{% trans "From here you can edit the user's details, including their default project." %}</p>
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
@ -39,6 +39,7 @@ class BaseUserForm(forms.SelfHandlingForm):
|
|||||||
super(BaseUserForm, self).__init__(*args, **kwargs)
|
super(BaseUserForm, self).__init__(*args, **kwargs)
|
||||||
# Populate tenant choices
|
# Populate tenant choices
|
||||||
tenant_choices = [('', _("Select a project"))]
|
tenant_choices = [('', _("Select a project"))]
|
||||||
|
|
||||||
for tenant in api.tenant_list(request, admin=True):
|
for tenant in api.tenant_list(request, admin=True):
|
||||||
if tenant.enabled:
|
if tenant.enabled:
|
||||||
tenant_choices.append((tenant.id, tenant.name))
|
tenant_choices.append((tenant.id, tenant.name))
|
||||||
@ -107,22 +108,33 @@ class UpdateUserForm(BaseUserForm):
|
|||||||
widget=forms.PasswordInput(render_value=False),
|
widget=forms.PasswordInput(render_value=False),
|
||||||
regex=validators.password_validator(),
|
regex=validators.password_validator(),
|
||||||
required=False,
|
required=False,
|
||||||
error_messages={'invalid': validators.password_validator_msg()})
|
error_messages={'invalid':
|
||||||
|
validators.password_validator_msg()})
|
||||||
confirm_password = forms.CharField(
|
confirm_password = forms.CharField(
|
||||||
label=_("Confirm Password"),
|
label=_("Confirm Password"),
|
||||||
widget=forms.PasswordInput(render_value=False),
|
widget=forms.PasswordInput(render_value=False),
|
||||||
required=False)
|
required=False)
|
||||||
tenant_id = forms.ChoiceField(label=_("Primary Project"))
|
tenant_id = forms.ChoiceField(label=_("Primary Project"))
|
||||||
|
|
||||||
|
def __init__(self, request, *args, **kwargs):
|
||||||
|
super(UpdateUserForm, self).__init__(request, *args, **kwargs)
|
||||||
|
|
||||||
|
if api.keystone_can_edit_user() == False:
|
||||||
|
for field in ('name', 'email', 'password', 'confirm_password'):
|
||||||
|
self.fields.pop(field)
|
||||||
|
|
||||||
def handle(self, request, data):
|
def handle(self, request, data):
|
||||||
failed, succeeded = [], []
|
failed, succeeded = [], []
|
||||||
|
user_is_editable = api.keystone_can_edit_user()
|
||||||
user = data.pop('id')
|
user = data.pop('id')
|
||||||
password = data.pop('password')
|
|
||||||
tenant = data.pop('tenant_id')
|
tenant = data.pop('tenant_id')
|
||||||
# Discard the extra fields so we can pass kwargs to keystoneclient
|
|
||||||
data.pop('method')
|
data.pop('method')
|
||||||
|
|
||||||
|
if user_is_editable:
|
||||||
|
password = data.pop('password')
|
||||||
data.pop('confirm_password', None)
|
data.pop('confirm_password', None)
|
||||||
|
|
||||||
|
if user_is_editable:
|
||||||
# Update user details
|
# Update user details
|
||||||
msg_bits = (_('name'), _('email'))
|
msg_bits = (_('name'), _('email'))
|
||||||
try:
|
try:
|
||||||
@ -141,6 +153,7 @@ class UpdateUserForm(BaseUserForm):
|
|||||||
failed.append(msg_bits)
|
failed.append(msg_bits)
|
||||||
exceptions.handle(request, ignore=True)
|
exceptions.handle(request, ignore=True)
|
||||||
|
|
||||||
|
if user_is_editable:
|
||||||
# If present, update password
|
# If present, update password
|
||||||
# FIXME(gabriel): password change should be its own form and view
|
# FIXME(gabriel): password change should be its own form and view
|
||||||
if password:
|
if password:
|
||||||
@ -153,15 +166,10 @@ class UpdateUserForm(BaseUserForm):
|
|||||||
exceptions.handle(request, ignore=True)
|
exceptions.handle(request, ignore=True)
|
||||||
|
|
||||||
if succeeded:
|
if succeeded:
|
||||||
succeeded = map(force_unicode, succeeded)
|
messages.success(request, _('User has been updated successfully.'))
|
||||||
messages.success(request,
|
|
||||||
_('Updated %(attributes)s for "%(user)s".')
|
|
||||||
% {"user": data["name"],
|
|
||||||
"attributes": ", ".join(succeeded)})
|
|
||||||
if failed:
|
if failed:
|
||||||
failed = map(force_unicode, failed)
|
failed = map(force_unicode, failed)
|
||||||
messages.error(request,
|
messages.error(request,
|
||||||
_('Unable to update %(attributes)s for "%(user)s".')
|
_('Unable to update %(attributes)s for the user.')
|
||||||
% {"user": data["name"],
|
% {"attributes": ", ".join(failed)})
|
||||||
"attributes": ", ".join(failed)})
|
|
||||||
return shortcuts.redirect('horizon:syspanel:users:index')
|
return shortcuts.redirect('horizon:syspanel:users:index')
|
||||||
|
@ -17,6 +17,11 @@ class CreateUserLink(tables.LinkAction):
|
|||||||
url = "horizon:syspanel:users:create"
|
url = "horizon:syspanel:users:create"
|
||||||
classes = ("ajax-modal", "btn-create")
|
classes = ("ajax-modal", "btn-create")
|
||||||
|
|
||||||
|
def allowed(self, request, user):
|
||||||
|
if api.keystone_can_edit_user():
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
class EditUserLink(tables.LinkAction):
|
class EditUserLink(tables.LinkAction):
|
||||||
name = "edit"
|
name = "edit"
|
||||||
@ -93,7 +98,8 @@ class DeleteUsersAction(tables.DeleteAction):
|
|||||||
data_type_plural = _("Users")
|
data_type_plural = _("Users")
|
||||||
|
|
||||||
def allowed(self, request, datum):
|
def allowed(self, request, datum):
|
||||||
if datum and datum.id == request.user.id:
|
if not api.keystone_can_edit_user() or \
|
||||||
|
(datum and datum.id == request.user.id):
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@ -134,11 +140,6 @@ class UsersTable(tables.DataTable):
|
|||||||
class Meta:
|
class Meta:
|
||||||
name = "users"
|
name = "users"
|
||||||
verbose_name = _("Users")
|
verbose_name = _("Users")
|
||||||
if api.keystone_can_edit_user():
|
|
||||||
row_actions = (EditUserLink, EnableUsersAction, DisableUsersAction,
|
row_actions = (EditUserLink, EnableUsersAction, DisableUsersAction,
|
||||||
DeleteUsersAction)
|
DeleteUsersAction)
|
||||||
table_actions = (UserFilterAction, CreateUserLink,
|
table_actions = (UserFilterAction, CreateUserLink, DeleteUsersAction)
|
||||||
DeleteUsersAction)
|
|
||||||
else:
|
|
||||||
row_actions = (EnableUsersAction, DisableUsersAction)
|
|
||||||
table_actions = (UserFilterAction,)
|
|
||||||
|
@ -33,22 +33,25 @@ USER_UPDATE_URL = reverse('horizon:syspanel:users:update', args=[1])
|
|||||||
|
|
||||||
|
|
||||||
class UsersViewTests(test.BaseAdminViewTests):
|
class UsersViewTests(test.BaseAdminViewTests):
|
||||||
|
@test.create_stubs({api.keystone: ('user_list',)})
|
||||||
def test_index(self):
|
def test_index(self):
|
||||||
self.mox.StubOutWithMock(api.keystone, 'user_list')
|
|
||||||
api.keystone.user_list(IgnoreArg()).AndReturn(self.users.list())
|
api.keystone.user_list(IgnoreArg()).AndReturn(self.users.list())
|
||||||
|
|
||||||
self.mox.ReplayAll()
|
self.mox.ReplayAll()
|
||||||
|
|
||||||
res = self.client.get(USERS_INDEX_URL)
|
res = self.client.get(USERS_INDEX_URL)
|
||||||
|
|
||||||
self.assertTemplateUsed(res, 'syspanel/users/index.html')
|
self.assertTemplateUsed(res, 'syspanel/users/index.html')
|
||||||
self.assertItemsEqual(res.context['table'].data, self.users.list())
|
self.assertItemsEqual(res.context['table'].data, self.users.list())
|
||||||
|
|
||||||
def test_create_user(self):
|
@test.create_stubs({api: ('user_create',
|
||||||
|
'tenant_list',
|
||||||
|
'add_tenant_user_role'),
|
||||||
|
api.keystone: ('get_default_role',)})
|
||||||
|
def test_create(self):
|
||||||
user = self.users.get(id="1")
|
user = self.users.get(id="1")
|
||||||
role = self.roles.first()
|
role = self.roles.first()
|
||||||
self.mox.StubOutWithMock(api, 'user_create')
|
|
||||||
self.mox.StubOutWithMock(api, 'tenant_list')
|
|
||||||
self.mox.StubOutWithMock(api.keystone, 'get_default_role')
|
|
||||||
self.mox.StubOutWithMock(api, 'add_tenant_user_role')
|
|
||||||
api.tenant_list(IgnoreArg(), admin=True).AndReturn(self.tenants.list())
|
api.tenant_list(IgnoreArg(), admin=True).AndReturn(self.tenants.list())
|
||||||
api.user_create(IgnoreArg(),
|
api.user_create(IgnoreArg(),
|
||||||
user.name,
|
user.name,
|
||||||
@ -58,6 +61,7 @@ class UsersViewTests(test.BaseAdminViewTests):
|
|||||||
True).AndReturn(user)
|
True).AndReturn(user)
|
||||||
api.keystone.get_default_role(IgnoreArg()).AndReturn(role)
|
api.keystone.get_default_role(IgnoreArg()).AndReturn(role)
|
||||||
api.add_tenant_user_role(IgnoreArg(), self.tenant.id, user.id, role.id)
|
api.add_tenant_user_role(IgnoreArg(), self.tenant.id, user.id, role.id)
|
||||||
|
|
||||||
self.mox.ReplayAll()
|
self.mox.ReplayAll()
|
||||||
|
|
||||||
formData = {'method': 'CreateUserForm',
|
formData = {'method': 'CreateUserForm',
|
||||||
@ -67,13 +71,16 @@ class UsersViewTests(test.BaseAdminViewTests):
|
|||||||
'tenant_id': self.tenant.id,
|
'tenant_id': self.tenant.id,
|
||||||
'confirm_password': user.password}
|
'confirm_password': user.password}
|
||||||
res = self.client.post(USER_CREATE_URL, formData)
|
res = self.client.post(USER_CREATE_URL, formData)
|
||||||
|
|
||||||
self.assertNoFormErrors(res)
|
self.assertNoFormErrors(res)
|
||||||
self.assertMessageCount(success=1)
|
self.assertMessageCount(success=1)
|
||||||
|
|
||||||
def test_create_user_password_mismatch(self):
|
@test.create_stubs({api: ('tenant_list',)})
|
||||||
|
def test_create_with_password_mismatch(self):
|
||||||
user = self.users.get(id="1")
|
user = self.users.get(id="1")
|
||||||
self.mox.StubOutWithMock(api, 'tenant_list')
|
|
||||||
api.tenant_list(IgnoreArg(), admin=True).AndReturn(self.tenants.list())
|
api.tenant_list(IgnoreArg(), admin=True).AndReturn(self.tenants.list())
|
||||||
|
|
||||||
self.mox.ReplayAll()
|
self.mox.ReplayAll()
|
||||||
|
|
||||||
formData = {'method': 'CreateUserForm',
|
formData = {'method': 'CreateUserForm',
|
||||||
@ -84,13 +91,15 @@ class UsersViewTests(test.BaseAdminViewTests):
|
|||||||
'confirm_password': "doesntmatch"}
|
'confirm_password': "doesntmatch"}
|
||||||
|
|
||||||
res = self.client.post(USER_CREATE_URL, formData)
|
res = self.client.post(USER_CREATE_URL, formData)
|
||||||
|
|
||||||
self.assertFormError(res, "form", None, ['Passwords do not match.'])
|
self.assertFormError(res, "form", None, ['Passwords do not match.'])
|
||||||
|
|
||||||
def test_create_user_field_validation(self):
|
@test.create_stubs({api: ('tenant_list',)})
|
||||||
|
def test_create_validation_for_password_too_short(self):
|
||||||
user = self.users.get(id="1")
|
user = self.users.get(id="1")
|
||||||
self.mox.StubOutWithMock(api, 'tenant_list')
|
|
||||||
api.tenant_list(IgnoreArg(), admin=True).AndReturn(self.tenants.list())
|
|
||||||
api.tenant_list(IgnoreArg(), admin=True).AndReturn(self.tenants.list())
|
api.tenant_list(IgnoreArg(), admin=True).AndReturn(self.tenants.list())
|
||||||
|
|
||||||
self.mox.ReplayAll()
|
self.mox.ReplayAll()
|
||||||
|
|
||||||
# check password min-len verification
|
# check password min-len verification
|
||||||
@ -102,27 +111,45 @@ class UsersViewTests(test.BaseAdminViewTests):
|
|||||||
'confirm_password': 'four'}
|
'confirm_password': 'four'}
|
||||||
|
|
||||||
res = self.client.post(USER_CREATE_URL, formData)
|
res = self.client.post(USER_CREATE_URL, formData)
|
||||||
|
|
||||||
self.assertFormError(
|
self.assertFormError(
|
||||||
res, "form", 'password',
|
res, "form", 'password',
|
||||||
['Password must be between 8 and 18 characters.'])
|
['Password must be between 8 and 18 characters.'])
|
||||||
|
|
||||||
# check password max-len verification
|
@test.create_stubs({api: ('tenant_list',)})
|
||||||
formData['password'] = 'MoreThanEighteenChars'
|
def test_create_validation_for_password_too_long(self):
|
||||||
formData['confirm_password'] = 'MoreThanEighteenChars'
|
user = self.users.get(id="1")
|
||||||
|
|
||||||
|
api.tenant_list(IgnoreArg(), admin=True).AndReturn(self.tenants.list())
|
||||||
|
|
||||||
|
self.mox.ReplayAll()
|
||||||
|
|
||||||
|
# check password min-len verification
|
||||||
|
formData = {'method': 'CreateUserForm',
|
||||||
|
'name': user.name,
|
||||||
|
'email': user.email,
|
||||||
|
'password': 'MoreThanEighteenChars',
|
||||||
|
'tenant_id': self.tenant.id,
|
||||||
|
'confirm_password': 'MoreThanEighteenChars'}
|
||||||
|
|
||||||
res = self.client.post(USER_CREATE_URL, formData)
|
res = self.client.post(USER_CREATE_URL, formData)
|
||||||
|
|
||||||
self.assertFormError(
|
self.assertFormError(
|
||||||
res, "form", 'password',
|
res, "form", 'password',
|
||||||
['Password must be between 8 and 18 characters.'])
|
['Password must be between 8 and 18 characters.'])
|
||||||
|
|
||||||
def test_update_user_field_validation(self):
|
@test.create_stubs({api: ('user_get',
|
||||||
|
'tenant_list',
|
||||||
|
'user_update_tenant',
|
||||||
|
'user_update_password'),
|
||||||
|
api.keystone: ('user_update',)})
|
||||||
|
def test_update(self):
|
||||||
user = self.users.get(id="1")
|
user = self.users.get(id="1")
|
||||||
self.mox.StubOutWithMock(api, 'tenant_list')
|
|
||||||
self.mox.StubOutWithMock(api, 'user_get')
|
|
||||||
self.mox.StubOutWithMock(api.keystone, 'user_update')
|
|
||||||
self.mox.StubOutWithMock(api, 'user_update_tenant')
|
|
||||||
self.mox.StubOutWithMock(api, 'user_update_password')
|
|
||||||
|
|
||||||
|
api.user_get(IsA(http.HttpRequest), '1',
|
||||||
|
admin=True).AndReturn(user)
|
||||||
|
api.tenant_list(IgnoreArg(),
|
||||||
|
admin=True).AndReturn(self.tenants.list())
|
||||||
api.keystone.user_update(IsA(http.HttpRequest),
|
api.keystone.user_update(IsA(http.HttpRequest),
|
||||||
user.id,
|
user.id,
|
||||||
email=u'test@example.com',
|
email=u'test@example.com',
|
||||||
@ -133,84 +160,141 @@ class UsersViewTests(test.BaseAdminViewTests):
|
|||||||
api.user_update_password(IsA(http.HttpRequest),
|
api.user_update_password(IsA(http.HttpRequest),
|
||||||
user.id,
|
user.id,
|
||||||
IgnoreArg()).AndReturn(None)
|
IgnoreArg()).AndReturn(None)
|
||||||
api.user_get(IsA(http.HttpRequest), '1', admin=True).AndReturn(user)
|
|
||||||
api.tenant_list(IgnoreArg(), admin=True).AndReturn(self.tenants.list())
|
|
||||||
api.user_get(IsA(http.HttpRequest), '1', admin=True).AndReturn(user)
|
|
||||||
api.tenant_list(IgnoreArg(), admin=True).AndReturn(self.tenants.list())
|
|
||||||
api.user_get(IsA(http.HttpRequest), '1', admin=True).AndReturn(user)
|
|
||||||
api.tenant_list(IgnoreArg(), admin=True).AndReturn(self.tenants.list())
|
|
||||||
self.mox.ReplayAll()
|
self.mox.ReplayAll()
|
||||||
user.tenantId = 1
|
|
||||||
|
|
||||||
formData = {'method': 'UpdateUserForm',
|
formData = {'method': 'UpdateUserForm',
|
||||||
'id': 1,
|
'id': user.id,
|
||||||
'name': user.name,
|
'name': user.name,
|
||||||
'email': user.email,
|
'email': user.email,
|
||||||
'password': 'normalpwd',
|
'password': 'normalpwd',
|
||||||
'tenant_id': self.tenant.id,
|
'tenant_id': self.tenant.id,
|
||||||
'confirm_password': 'normalpwd'}
|
'confirm_password': 'normalpwd'}
|
||||||
|
|
||||||
# check successful update
|
|
||||||
res = self.client.post(USER_UPDATE_URL, formData)
|
res = self.client.post(USER_UPDATE_URL, formData)
|
||||||
|
|
||||||
self.assertNoFormErrors(res)
|
self.assertNoFormErrors(res)
|
||||||
|
|
||||||
# check password min-len verification
|
@test.create_stubs({api: ('user_get',
|
||||||
formData['password'] = 'four'
|
'tenant_list',
|
||||||
formData['confirm_password'] = 'four'
|
'user_update_tenant',
|
||||||
|
'keystone_can_edit_user')})
|
||||||
|
def test_update_with_keystone_can_edit_user_false(self):
|
||||||
|
user = self.users.get(id="1")
|
||||||
|
|
||||||
|
api.user_get(IsA(http.HttpRequest),
|
||||||
|
'1',
|
||||||
|
admin=True).AndReturn(user)
|
||||||
|
api.tenant_list(IgnoreArg(), admin=True).AndReturn(self.tenants.list())
|
||||||
|
api.keystone_can_edit_user().AndReturn(False)
|
||||||
|
api.keystone_can_edit_user().AndReturn(False)
|
||||||
|
api.user_update_tenant(IsA(http.HttpRequest),
|
||||||
|
user.id,
|
||||||
|
self.tenant.id).AndReturn(None)
|
||||||
|
|
||||||
|
self.mox.ReplayAll()
|
||||||
|
|
||||||
|
formData = {'method': 'UpdateUserForm',
|
||||||
|
'tenant_id': self.tenant.id,
|
||||||
|
'id': user.id}
|
||||||
|
|
||||||
res = self.client.post(USER_UPDATE_URL, formData)
|
res = self.client.post(USER_UPDATE_URL, formData)
|
||||||
|
|
||||||
|
self.assertNoFormErrors(res)
|
||||||
|
|
||||||
|
@test.create_stubs({api: ('user_get', 'tenant_list')})
|
||||||
|
def test_update_validation_for_password_too_short(self):
|
||||||
|
user = self.users.get(id="1")
|
||||||
|
|
||||||
|
api.user_get(IsA(http.HttpRequest), '1',
|
||||||
|
admin=True).AndReturn(user)
|
||||||
|
api.tenant_list(IgnoreArg(),
|
||||||
|
admin=True).AndReturn(self.tenants.list())
|
||||||
|
|
||||||
|
self.mox.ReplayAll()
|
||||||
|
|
||||||
|
formData = {'method': 'UpdateUserForm',
|
||||||
|
'id': user.id,
|
||||||
|
'name': user.name,
|
||||||
|
'email': user.email,
|
||||||
|
'password': 't',
|
||||||
|
'tenant_id': self.tenant.id,
|
||||||
|
'confirm_password': 't'}
|
||||||
|
|
||||||
|
res = self.client.post(USER_UPDATE_URL, formData)
|
||||||
|
|
||||||
self.assertFormError(
|
self.assertFormError(
|
||||||
res, "form", 'password',
|
res, "form", 'password',
|
||||||
['Password must be between 8 and 18 characters.'])
|
['Password must be between 8 and 18 characters.'])
|
||||||
|
|
||||||
# check password max-len verification
|
@test.create_stubs({api: ('user_get', 'tenant_list')})
|
||||||
formData['password'] = 'MoreThanEighteenChars'
|
def test_update_validation_for_password_too_long(self):
|
||||||
formData['confirm_password'] = 'MoreThanEighteenChars'
|
user = self.users.get(id="1")
|
||||||
|
|
||||||
|
api.user_get(IsA(http.HttpRequest), '1',
|
||||||
|
admin=True).AndReturn(user)
|
||||||
|
api.tenant_list(IgnoreArg(),
|
||||||
|
admin=True).AndReturn(self.tenants.list())
|
||||||
|
|
||||||
|
self.mox.ReplayAll()
|
||||||
|
|
||||||
|
formData = {'method': 'UpdateUserForm',
|
||||||
|
'id': user.id,
|
||||||
|
'name': user.name,
|
||||||
|
'email': user.email,
|
||||||
|
'password': 'ThisIsASuperLongPassword',
|
||||||
|
'tenant_id': self.tenant.id,
|
||||||
|
'confirm_password': 'ThisIsASuperLongPassword'}
|
||||||
|
|
||||||
res = self.client.post(USER_UPDATE_URL, formData)
|
res = self.client.post(USER_UPDATE_URL, formData)
|
||||||
|
|
||||||
self.assertFormError(
|
self.assertFormError(
|
||||||
res, "form", 'password',
|
res, "form", 'password',
|
||||||
['Password must be between 8 and 18 characters.'])
|
['Password must be between 8 and 18 characters.'])
|
||||||
|
|
||||||
|
@test.create_stubs({api.keystone: ('user_update_enabled', 'user_list')})
|
||||||
def test_enable_user(self):
|
def test_enable_user(self):
|
||||||
user = self.users.get(id="2")
|
user = self.users.get(id="2")
|
||||||
self.mox.StubOutWithMock(api.keystone, 'user_update_enabled')
|
|
||||||
self.mox.StubOutWithMock(api.keystone, 'user_list')
|
|
||||||
api.keystone.user_list(IgnoreArg()).AndReturn(self.users.list())
|
api.keystone.user_list(IgnoreArg()).AndReturn(self.users.list())
|
||||||
api.keystone.user_update_enabled(IgnoreArg(),
|
api.keystone.user_update_enabled(IgnoreArg(),
|
||||||
user.id,
|
user.id,
|
||||||
True).AndReturn(user)
|
True).AndReturn(user)
|
||||||
|
|
||||||
self.mox.ReplayAll()
|
self.mox.ReplayAll()
|
||||||
|
|
||||||
formData = {'action': 'users__enable__%s' % user.id}
|
formData = {'action': 'users__enable__%s' % user.id}
|
||||||
res = self.client.post(USERS_INDEX_URL, formData)
|
res = self.client.post(USERS_INDEX_URL, formData)
|
||||||
|
|
||||||
self.assertRedirectsNoFollow(res, USERS_INDEX_URL)
|
self.assertRedirectsNoFollow(res, USERS_INDEX_URL)
|
||||||
|
|
||||||
|
@test.create_stubs({api.keystone: ('user_update_enabled', 'user_list')})
|
||||||
def test_disable_user(self):
|
def test_disable_user(self):
|
||||||
user = self.users.get(id="2")
|
user = self.users.get(id="2")
|
||||||
|
|
||||||
self.mox.StubOutWithMock(api.keystone, 'user_update_enabled')
|
|
||||||
self.mox.StubOutWithMock(api.keystone, 'user_list')
|
|
||||||
api.keystone.user_list(IgnoreArg()).AndReturn(self.users.list())
|
api.keystone.user_list(IgnoreArg()).AndReturn(self.users.list())
|
||||||
api.keystone.user_update_enabled(IgnoreArg(),
|
api.keystone.user_update_enabled(IgnoreArg(),
|
||||||
user.id,
|
user.id,
|
||||||
False).AndReturn(user)
|
False).AndReturn(user)
|
||||||
|
|
||||||
self.mox.ReplayAll()
|
self.mox.ReplayAll()
|
||||||
|
|
||||||
formData = {'action': 'users__disable__%s' % user.id}
|
formData = {'action': 'users__disable__%s' % user.id}
|
||||||
res = self.client.post(USERS_INDEX_URL, formData)
|
res = self.client.post(USERS_INDEX_URL, formData)
|
||||||
|
|
||||||
self.assertRedirectsNoFollow(res, USERS_INDEX_URL)
|
self.assertRedirectsNoFollow(res, USERS_INDEX_URL)
|
||||||
|
|
||||||
|
@test.create_stubs({api.keystone: ('user_update_enabled', 'user_list')})
|
||||||
def test_enable_disable_user_exception(self):
|
def test_enable_disable_user_exception(self):
|
||||||
user = self.users.get(id="2")
|
user = self.users.get(id="2")
|
||||||
self.mox.StubOutWithMock(api.keystone, 'user_update_enabled')
|
|
||||||
self.mox.StubOutWithMock(api.keystone, 'user_list')
|
|
||||||
api.keystone.user_list(IgnoreArg()).AndReturn(self.users.list())
|
api.keystone.user_list(IgnoreArg()).AndReturn(self.users.list())
|
||||||
api_exception = keystone_exceptions.ClientException('apiException',
|
api_exception = keystone_exceptions.ClientException('apiException',
|
||||||
message='apiException')
|
message='apiException')
|
||||||
api.keystone.user_update_enabled(IgnoreArg(),
|
api.keystone.user_update_enabled(IgnoreArg(),
|
||||||
user.id,
|
user.id,
|
||||||
True).AndRaise(api_exception)
|
True).AndRaise(api_exception)
|
||||||
|
|
||||||
self.mox.ReplayAll()
|
self.mox.ReplayAll()
|
||||||
|
|
||||||
formData = {'action': 'users__enable__%s' % user.id}
|
formData = {'action': 'users__enable__%s' % user.id}
|
||||||
@ -218,24 +302,30 @@ class UsersViewTests(test.BaseAdminViewTests):
|
|||||||
|
|
||||||
self.assertRedirectsNoFollow(res, USERS_INDEX_URL)
|
self.assertRedirectsNoFollow(res, USERS_INDEX_URL)
|
||||||
|
|
||||||
def test_shoot_yourself_in_the_foot(self):
|
@test.create_stubs({api.keystone: ('user_list',)})
|
||||||
self.mox.StubOutWithMock(api.keystone, 'user_list')
|
def test_disabling_current_user(self):
|
||||||
# Four times... one for each post and one for each followed redirect
|
for i in range(0, 2):
|
||||||
api.keystone.user_list(IgnoreArg()).AndReturn(self.users.list())
|
|
||||||
api.keystone.user_list(IgnoreArg()).AndReturn(self.users.list())
|
|
||||||
api.keystone.user_list(IgnoreArg()).AndReturn(self.users.list())
|
|
||||||
api.keystone.user_list(IgnoreArg()).AndReturn(self.users.list())
|
api.keystone.user_list(IgnoreArg()).AndReturn(self.users.list())
|
||||||
|
|
||||||
self.mox.ReplayAll()
|
self.mox.ReplayAll()
|
||||||
|
|
||||||
formData = {'action': 'users__disable__%s' % self.request.user.id}
|
formData = {'action': 'users__disable__%s' % self.request.user.id}
|
||||||
res = self.client.post(USERS_INDEX_URL, formData, follow=True)
|
res = self.client.post(USERS_INDEX_URL, formData, follow=True)
|
||||||
|
|
||||||
self.assertEqual(list(res.context['messages'])[0].message,
|
self.assertEqual(list(res.context['messages'])[0].message,
|
||||||
u'You cannot disable the user you are currently '
|
u'You cannot disable the user you are currently '
|
||||||
u'logged in as.')
|
u'logged in as.')
|
||||||
|
|
||||||
|
@test.create_stubs({api.keystone: ('user_list',)})
|
||||||
|
def test_delete_user_with_improper_permissions(self):
|
||||||
|
for i in range(0, 2):
|
||||||
|
api.keystone.user_list(IgnoreArg()).AndReturn(self.users.list())
|
||||||
|
|
||||||
|
self.mox.ReplayAll()
|
||||||
|
|
||||||
formData = {'action': 'users__delete__%s' % self.request.user.id}
|
formData = {'action': 'users__delete__%s' % self.request.user.id}
|
||||||
res = self.client.post(USERS_INDEX_URL, formData, follow=True)
|
res = self.client.post(USERS_INDEX_URL, formData, follow=True)
|
||||||
|
|
||||||
self.assertEqual(list(res.context['messages'])[0].message,
|
self.assertEqual(list(res.context['messages'])[0].message,
|
||||||
u'You do not have permission to delete user: %s'
|
u'You do not have permission to delete user: %s'
|
||||||
% self.request.user.username)
|
% self.request.user.username)
|
||||||
|
@ -27,6 +27,7 @@ from django.conf import settings
|
|||||||
from django.contrib.messages.storage import default_storage
|
from django.contrib.messages.storage import default_storage
|
||||||
from django.core.handlers import wsgi
|
from django.core.handlers import wsgi
|
||||||
from django.test.client import RequestFactory
|
from django.test.client import RequestFactory
|
||||||
|
from functools import wraps
|
||||||
from glanceclient.v1 import client as glance_client
|
from glanceclient.v1 import client as glance_client
|
||||||
from keystoneclient.v2_0 import client as keystone_client
|
from keystoneclient.v2_0 import client as keystone_client
|
||||||
from novaclient.v1_1 import client as nova_client
|
from novaclient.v1_1 import client as nova_client
|
||||||
@ -48,6 +49,28 @@ from .time import utcnow
|
|||||||
wsgi.WSGIRequest.__repr__ = lambda self: "<class 'django.http.HttpRequest'>"
|
wsgi.WSGIRequest.__repr__ = lambda self: "<class 'django.http.HttpRequest'>"
|
||||||
|
|
||||||
|
|
||||||
|
def create_stubs(stubs_to_create={}):
|
||||||
|
if not isinstance(stubs_to_create, dict):
|
||||||
|
raise TypeError, ("create_stub must be passed a dict, but a %s was " \
|
||||||
|
"given." % type(stubs_to_create).__name__)
|
||||||
|
|
||||||
|
def inner_stub_out(fn):
|
||||||
|
@wraps(fn)
|
||||||
|
def instance_stub_out(self):
|
||||||
|
for key in stubs_to_create:
|
||||||
|
if not (isinstance(stubs_to_create[key], tuple) or \
|
||||||
|
isinstance(stubs_to_create[key], list)):
|
||||||
|
raise TypeError, ("The values of the create_stub " \
|
||||||
|
"dict must be lists or tuples, but is a %s." %
|
||||||
|
type(stubs_to_create[key]).__name__)
|
||||||
|
|
||||||
|
for value in stubs_to_create[key]:
|
||||||
|
self.mox.StubOutWithMock(key, value)
|
||||||
|
return fn(self)
|
||||||
|
return instance_stub_out
|
||||||
|
return inner_stub_out
|
||||||
|
|
||||||
|
|
||||||
class RequestFactoryWithMessages(RequestFactory):
|
class RequestFactoryWithMessages(RequestFactory):
|
||||||
def get(self, *args, **kwargs):
|
def get(self, *args, **kwargs):
|
||||||
req = super(RequestFactoryWithMessages, self).get(*args, **kwargs)
|
req = super(RequestFactoryWithMessages, self).get(*args, **kwargs)
|
||||||
|
@ -104,11 +104,11 @@ def data(TEST):
|
|||||||
'email': 'test@example.com',
|
'email': 'test@example.com',
|
||||||
'password': 'password',
|
'password': 'password',
|
||||||
'token': 'test_token'}
|
'token': 'test_token'}
|
||||||
user = users.User(users.UserManager, user_dict)
|
user = users.User(users.UserManager(None), user_dict)
|
||||||
user_dict.update({'id': "2",
|
user_dict.update({'id': "2",
|
||||||
'name': 'user_two',
|
'name': 'user_two',
|
||||||
'email': 'two@example.com'})
|
'email': 'two@example.com'})
|
||||||
user2 = users.User(users.UserManager, user_dict)
|
user2 = users.User(users.UserManager(None), user_dict)
|
||||||
TEST.users.add(user, user2)
|
TEST.users.add(user, user2)
|
||||||
TEST.user = user # Your "current" user
|
TEST.user = user # Your "current" user
|
||||||
TEST.user.service_catalog = SERVICE_CATALOG
|
TEST.user.service_catalog = SERVICE_CATALOG
|
||||||
|
Loading…
Reference in New Issue
Block a user