Loading django/contrib/auth/admin.py +2 −0 Original line number Diff line number Diff line Loading @@ -127,6 +127,8 @@ class UserAdmin(admin.ModelAdmin): 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('..') Loading django/contrib/auth/forms.py +8 −0 Original line number Diff line number Diff line Loading @@ -350,3 +350,11 @@ class AdminPasswordChangeForm(forms.Form): 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) django/contrib/auth/tests/test_views.py +62 −4 Original line number Diff line number Diff line Loading @@ -8,6 +8,7 @@ except ImportError: # Python 2 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 Loading Loading @@ -54,6 +55,11 @@ class AuthViewsTestCase(TestCase): 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())) Loading Loading @@ -670,18 +676,70 @@ class LogoutTest(AuthViewsTestCase): 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') Loading
django/contrib/auth/admin.py +2 −0 Original line number Diff line number Diff line Loading @@ -127,6 +127,8 @@ class UserAdmin(admin.ModelAdmin): 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('..') Loading
django/contrib/auth/forms.py +8 −0 Original line number Diff line number Diff line Loading @@ -350,3 +350,11 @@ class AdminPasswordChangeForm(forms.Form): 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)
django/contrib/auth/tests/test_views.py +62 −4 Original line number Diff line number Diff line Loading @@ -8,6 +8,7 @@ except ImportError: # Python 2 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 Loading Loading @@ -54,6 +55,11 @@ class AuthViewsTestCase(TestCase): 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())) Loading Loading @@ -670,18 +676,70 @@ class LogoutTest(AuthViewsTestCase): 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')