Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

[1.6.x] Fixed #19019 -- Fixed UserAdmin to log password change.

Thanks Tuttle for the report.

Backport of 33242fe from master
  • Loading branch information...
commit ad898453b71d231402684c9e165bd4df9a1cfb76 1 parent 43f1d51
Kirill Fomichev fanatid authored timgraham committed
2  django/contrib/auth/admin.py
View
@@ -130,6 +130,8 @@ def user_change_password(self, request, id, form_url=''):
form = self.change_password_form(user, request.POST)
if form.is_valid():
form.save()
+ change_message = self.construct_change_message(request, form, None)
+ self.log_change(request, request.user, change_message)
msg = ugettext('Password changed successfully.')
messages.success(request, msg)
return HttpResponseRedirect('..')
8 django/contrib/auth/forms.py
View
@@ -356,3 +356,11 @@ def save(self, commit=True):
if commit:
self.user.save()
return self.user
+
+ def _get_changed_data(self):
+ data = super(AdminPasswordChangeForm, self).changed_data
+ for name in self.fields.keys():
+ if name not in data:
+ return []
+ return ['password']
+ changed_data = property(_get_changed_data)
66 django/contrib/auth/tests/test_views.py
View
@@ -8,6 +8,7 @@
from django.conf import global_settings, settings
from django.contrib.sites.models import Site, RequestSite
+from django.contrib.admin.models import LogEntry
from django.contrib.auth.models import User
from django.core import mail
from django.core.urlresolvers import reverse, NoReverseMatch
@@ -54,6 +55,11 @@ def login(self, password='password'):
self.assertTrue(SESSION_KEY in self.client.session)
return response
+ def logout(self):
+ response = self.client.get('/admin/logout/')
+ self.assertEqual(response.status_code, 200)
+ self.assertTrue(SESSION_KEY not in self.client.session)
+
def assertFormError(self, response, error):
"""Assert that error is found in response.context['form'] errors"""
form_errors = list(itertools.chain(*response.context['form'].errors.values()))
@@ -690,18 +696,70 @@ def test_security_check(self, password='password'):
self.confirm_logged_out()
@skipIfCustomUser
+@override_settings(
+ PASSWORD_HASHERS=('django.contrib.auth.hashers.SHA1PasswordHasher',),
+)
class ChangelistTests(AuthViewsTestCase):
urls = 'django.contrib.auth.tests.urls_admin'
- # #20078 - users shouldn't be allowed to guess password hashes via
- # repeated password__startswith queries.
- def test_changelist_disallows_password_lookups(self):
- # Make me a superuser before loging in.
+ def setUp(self):
+ # Make me a superuser before logging in.
User.objects.filter(username='testclient').update(is_staff=True, is_superuser=True)
self.login()
+ self.admin = User.objects.get(pk=1)
+
+ def get_user_data(self, user):
+ return {
+ 'username': user.username,
+ 'password': user.password,
+ 'email': user.email,
+ 'is_active': user.is_active,
+ 'is_staff': user.is_staff,
+ 'is_superuser': user.is_superuser,
+ 'last_login_0': user.last_login.strftime('%Y-%m-%d'),
+ 'last_login_1': user.last_login.strftime('%H:%M:%S'),
+ 'initial-last_login_0': user.last_login.strftime('%Y-%m-%d'),
+ 'initial-last_login_1': user.last_login.strftime('%H:%M:%S'),
+ 'date_joined_0': user.date_joined.strftime('%Y-%m-%d'),
+ 'date_joined_1': user.date_joined.strftime('%H:%M:%S'),
+ 'initial-date_joined_0': user.date_joined.strftime('%Y-%m-%d'),
+ 'initial-date_joined_1': user.date_joined.strftime('%H:%M:%S'),
+ 'first_name': user.first_name,
+ 'last_name': user.last_name,
+ }
+ # #20078 - users shouldn't be allowed to guess password hashes via
+ # repeated password__startswith queries.
+ def test_changelist_disallows_password_lookups(self):
# A lookup that tries to filter on password isn't OK
with patch_logger('django.security.DisallowedModelAdminLookup', 'error') as logger_calls:
response = self.client.get('/admin/auth/user/?password__startswith=sha1$')
self.assertEqual(response.status_code, 400)
self.assertEqual(len(logger_calls), 1)
+
+ def test_user_change_email(self):
+ data = self.get_user_data(self.admin)
+ data['email'] = 'new_' + data['email']
+ response = self.client.post('/admin/auth/user/%s/' % self.admin.pk, data)
+ self.assertRedirects(response, '/admin/auth/user/')
+ row = LogEntry.objects.latest('id')
+ self.assertEqual(row.change_message, 'Changed email.')
+
+ def test_user_not_change(self):
+ response = self.client.post('/admin/auth/user/%s/' % self.admin.pk,
+ self.get_user_data(self.admin)
+ )
+ self.assertRedirects(response, '/admin/auth/user/')
+ row = LogEntry.objects.latest('id')
+ self.assertEqual(row.change_message, 'No fields changed.')
+
+ def test_user_change_password(self):
+ response = self.client.post('/admin/auth/user/%s/password/' % self.admin.pk, {
+ 'password1': 'password1',
+ 'password2': 'password1',
+ })
+ self.assertRedirects(response, '/admin/auth/user/%s/' % self.admin.pk)
+ row = LogEntry.objects.latest('id')
+ self.assertEqual(row.change_message, 'Changed password.')
+ self.logout()
+ self.login(password='password1')
Please sign in to comment.
Something went wrong with that request. Please try again.