Loading django/contrib/admin/forms.py +14 −21 Original line number Diff line number Diff line Loading @@ -4,30 +4,23 @@ from django import forms from django.contrib.auth import authenticate from django.contrib.auth.forms import AuthenticationForm from django.utils.translation import ugettext_lazy ERROR_MESSAGE = ugettext_lazy("Please enter the correct %(username)s and password " "for a staff account. Note that both fields may be case-sensitive.") from django.utils.translation import ugettext_lazy as _ class AdminAuthenticationForm(AuthenticationForm): """ A custom authentication form used in the admin app. """ this_is_the_login_form = forms.BooleanField(widget=forms.HiddenInput, initial=1, error_messages={'required': ugettext_lazy("Please log in again, because your session has expired.")}) def clean(self): username = self.cleaned_data.get('username') password = self.cleaned_data.get('password') message = ERROR_MESSAGE error_messages = { 'invalid_login': _("Please enter the correct %(username)s and password " "for a staff account. Note that both fields may be " "case-sensitive."), } def confirm_login_allowed(self, user): if not user.is_active or not user.is_staff: raise forms.ValidationError( self.error_messages['invalid_login'], code='invalid_login', params={'username': self.username_field.verbose_name} if username and password: self.user_cache = authenticate(username=username, password=password) if self.user_cache is None: raise forms.ValidationError(message, code='invalid', params=params) elif not self.user_cache.is_active or not self.user_cache.is_staff: raise forms.ValidationError(message, code='invalid', params=params) return self.cleaned_data ) django/contrib/admin/sites.py +0 −4 Original line number Diff line number Diff line Loading @@ -15,8 +15,6 @@ from django.utils.translation import ugettext_lazy, ugettext as _ from django.views.decorators.cache import never_cache from django.conf import settings LOGIN_FORM_KEY = 'this_is_the_login_form' class AlreadyRegistered(Exception): pass Loading Loading @@ -193,8 +191,6 @@ class AdminSite(object): cacheable=True. """ def inner(request, *args, **kwargs): if LOGIN_FORM_KEY in request.POST and request.user.is_authenticated(): auth_logout(request) if not self.has_permission(request): if request.path == reverse('admin:logout', current_app=self.name): index_path = reverse('admin:index', current_app=self.name) Loading django/contrib/admin/templates/admin/login.html +5 −6 Original line number Diff line number Diff line Loading @@ -12,14 +12,14 @@ {% block breadcrumbs %}{% endblock %} {% block content %} {% if form.errors and not form.non_field_errors and not form.this_is_the_login_form.errors %} {% if form.errors and not form.non_field_errors %} <p class="errornote"> {% if form.errors.items|length == 1 %}{% trans "Please correct the error below." %}{% else %}{% trans "Please correct the errors below." %}{% endif %} </p> {% endif %} {% if form.non_field_errors or form.this_is_the_login_form.errors %} {% for error in form.non_field_errors|add:form.this_is_the_login_form.errors %} {% if form.non_field_errors %} {% for error in form.non_field_errors %} <p class="errornote"> {{ error }} </p> Loading @@ -29,13 +29,12 @@ <div id="content-main"> <form action="{{ app_path }}" method="post" id="login-form">{% csrf_token %} <div class="form-row"> {% if not form.this_is_the_login_form.errors %}{{ form.username.errors }}{% endif %} {{ form.username.errors }} <label for="id_username" class="required">{{ form.username.label }}:</label> {{ form.username }} </div> <div class="form-row"> {% if not form.this_is_the_login_form.errors %}{{ form.password.errors }}{% endif %} {{ form.password.errors }} <label for="id_password" class="required">{% trans 'Password:' %}</label> {{ form.password }} <input type="hidden" name="this_is_the_login_form" value="1" /> <input type="hidden" name="next" value="{{ next }}" /> </div> {% url 'admin_password_reset' as password_reset_url %} Loading docs/releases/1.7.txt +4 −0 Original line number Diff line number Diff line Loading @@ -870,6 +870,10 @@ where any unauthorized request to an admin page will be redirected (by HTTP status code 302) to the login page, with the ``next`` parameter set to the referring path. The user will be redirected there after a successful login. Note also that the admin login form has been updated to not contain the ``this_is_the_login_form`` field (now unused) and the ``ValidationError`` code has been set to the more regular ``invalid_login`` key. Miscellaneous ~~~~~~~~~~~~~ Loading tests/admin_views/tests.py +0 −12 Original line number Diff line number Diff line Loading @@ -17,7 +17,6 @@ from django.contrib.auth import get_permission_codename from django.contrib.admin import ModelAdmin from django.contrib.admin.helpers import ACTION_CHECKBOX_NAME from django.contrib.admin.models import LogEntry, DELETION from django.contrib.admin.sites import LOGIN_FORM_KEY from django.contrib.admin.utils import quote from django.contrib.admin.validation import ModelAdminValidator from django.contrib.admin.views.main import IS_POPUP_VAR Loading Loading @@ -769,7 +768,6 @@ class CustomModelAdminTest(AdminViewBasicTestCase): self.assertEqual(response.status_code, 200) login = self.client.post('/test_admin/admin2/login/', { REDIRECT_FIELD_NAME: '/test_admin/admin2/', LOGIN_FORM_KEY: 1, 'username': 'customform', 'password': 'secret', }, follow=True) Loading Loading @@ -874,49 +872,41 @@ class AdminViewPermissionsTest(TestCase): # login POST dicts self.super_login = { REDIRECT_FIELD_NAME: '/test_admin/admin/', LOGIN_FORM_KEY: 1, 'username': 'super', 'password': 'secret', } self.super_email_login = { REDIRECT_FIELD_NAME: '/test_admin/admin/', LOGIN_FORM_KEY: 1, 'username': 'super@example.com', 'password': 'secret', } self.super_email_bad_login = { REDIRECT_FIELD_NAME: '/test_admin/admin/', LOGIN_FORM_KEY: 1, 'username': 'super@example.com', 'password': 'notsecret', } self.adduser_login = { REDIRECT_FIELD_NAME: '/test_admin/admin/', LOGIN_FORM_KEY: 1, 'username': 'adduser', 'password': 'secret', } self.changeuser_login = { REDIRECT_FIELD_NAME: '/test_admin/admin/', LOGIN_FORM_KEY: 1, 'username': 'changeuser', 'password': 'secret', } self.deleteuser_login = { REDIRECT_FIELD_NAME: '/test_admin/admin/', LOGIN_FORM_KEY: 1, 'username': 'deleteuser', 'password': 'secret', } self.joepublic_login = { REDIRECT_FIELD_NAME: '/test_admin/admin/', LOGIN_FORM_KEY: 1, 'username': 'joepublic', 'password': 'secret', } self.no_username_login = { REDIRECT_FIELD_NAME: '/test_admin/admin/', LOGIN_FORM_KEY: 1, 'password': 'secret', } Loading Loading @@ -1391,7 +1381,6 @@ class AdminViewsNoUrlTest(TestCase): # login POST dict self.changeuser_login = { REDIRECT_FIELD_NAME: '/test_admin/admin/', LOGIN_FORM_KEY: 1, 'username': 'changeuser', 'password': 'secret', } Loading Loading @@ -2600,7 +2589,6 @@ class AdminCustomQuerysetTest(TestCase): self.pks = [EmptyModel.objects.create().id for i in range(3)] self.super_login = { REDIRECT_FIELD_NAME: '/test_admin/admin/', LOGIN_FORM_KEY: 1, 'username': 'super', 'password': 'secret', } Loading Loading
django/contrib/admin/forms.py +14 −21 Original line number Diff line number Diff line Loading @@ -4,30 +4,23 @@ from django import forms from django.contrib.auth import authenticate from django.contrib.auth.forms import AuthenticationForm from django.utils.translation import ugettext_lazy ERROR_MESSAGE = ugettext_lazy("Please enter the correct %(username)s and password " "for a staff account. Note that both fields may be case-sensitive.") from django.utils.translation import ugettext_lazy as _ class AdminAuthenticationForm(AuthenticationForm): """ A custom authentication form used in the admin app. """ this_is_the_login_form = forms.BooleanField(widget=forms.HiddenInput, initial=1, error_messages={'required': ugettext_lazy("Please log in again, because your session has expired.")}) def clean(self): username = self.cleaned_data.get('username') password = self.cleaned_data.get('password') message = ERROR_MESSAGE error_messages = { 'invalid_login': _("Please enter the correct %(username)s and password " "for a staff account. Note that both fields may be " "case-sensitive."), } def confirm_login_allowed(self, user): if not user.is_active or not user.is_staff: raise forms.ValidationError( self.error_messages['invalid_login'], code='invalid_login', params={'username': self.username_field.verbose_name} if username and password: self.user_cache = authenticate(username=username, password=password) if self.user_cache is None: raise forms.ValidationError(message, code='invalid', params=params) elif not self.user_cache.is_active or not self.user_cache.is_staff: raise forms.ValidationError(message, code='invalid', params=params) return self.cleaned_data )
django/contrib/admin/sites.py +0 −4 Original line number Diff line number Diff line Loading @@ -15,8 +15,6 @@ from django.utils.translation import ugettext_lazy, ugettext as _ from django.views.decorators.cache import never_cache from django.conf import settings LOGIN_FORM_KEY = 'this_is_the_login_form' class AlreadyRegistered(Exception): pass Loading Loading @@ -193,8 +191,6 @@ class AdminSite(object): cacheable=True. """ def inner(request, *args, **kwargs): if LOGIN_FORM_KEY in request.POST and request.user.is_authenticated(): auth_logout(request) if not self.has_permission(request): if request.path == reverse('admin:logout', current_app=self.name): index_path = reverse('admin:index', current_app=self.name) Loading
django/contrib/admin/templates/admin/login.html +5 −6 Original line number Diff line number Diff line Loading @@ -12,14 +12,14 @@ {% block breadcrumbs %}{% endblock %} {% block content %} {% if form.errors and not form.non_field_errors and not form.this_is_the_login_form.errors %} {% if form.errors and not form.non_field_errors %} <p class="errornote"> {% if form.errors.items|length == 1 %}{% trans "Please correct the error below." %}{% else %}{% trans "Please correct the errors below." %}{% endif %} </p> {% endif %} {% if form.non_field_errors or form.this_is_the_login_form.errors %} {% for error in form.non_field_errors|add:form.this_is_the_login_form.errors %} {% if form.non_field_errors %} {% for error in form.non_field_errors %} <p class="errornote"> {{ error }} </p> Loading @@ -29,13 +29,12 @@ <div id="content-main"> <form action="{{ app_path }}" method="post" id="login-form">{% csrf_token %} <div class="form-row"> {% if not form.this_is_the_login_form.errors %}{{ form.username.errors }}{% endif %} {{ form.username.errors }} <label for="id_username" class="required">{{ form.username.label }}:</label> {{ form.username }} </div> <div class="form-row"> {% if not form.this_is_the_login_form.errors %}{{ form.password.errors }}{% endif %} {{ form.password.errors }} <label for="id_password" class="required">{% trans 'Password:' %}</label> {{ form.password }} <input type="hidden" name="this_is_the_login_form" value="1" /> <input type="hidden" name="next" value="{{ next }}" /> </div> {% url 'admin_password_reset' as password_reset_url %} Loading
docs/releases/1.7.txt +4 −0 Original line number Diff line number Diff line Loading @@ -870,6 +870,10 @@ where any unauthorized request to an admin page will be redirected (by HTTP status code 302) to the login page, with the ``next`` parameter set to the referring path. The user will be redirected there after a successful login. Note also that the admin login form has been updated to not contain the ``this_is_the_login_form`` field (now unused) and the ``ValidationError`` code has been set to the more regular ``invalid_login`` key. Miscellaneous ~~~~~~~~~~~~~ Loading
tests/admin_views/tests.py +0 −12 Original line number Diff line number Diff line Loading @@ -17,7 +17,6 @@ from django.contrib.auth import get_permission_codename from django.contrib.admin import ModelAdmin from django.contrib.admin.helpers import ACTION_CHECKBOX_NAME from django.contrib.admin.models import LogEntry, DELETION from django.contrib.admin.sites import LOGIN_FORM_KEY from django.contrib.admin.utils import quote from django.contrib.admin.validation import ModelAdminValidator from django.contrib.admin.views.main import IS_POPUP_VAR Loading Loading @@ -769,7 +768,6 @@ class CustomModelAdminTest(AdminViewBasicTestCase): self.assertEqual(response.status_code, 200) login = self.client.post('/test_admin/admin2/login/', { REDIRECT_FIELD_NAME: '/test_admin/admin2/', LOGIN_FORM_KEY: 1, 'username': 'customform', 'password': 'secret', }, follow=True) Loading Loading @@ -874,49 +872,41 @@ class AdminViewPermissionsTest(TestCase): # login POST dicts self.super_login = { REDIRECT_FIELD_NAME: '/test_admin/admin/', LOGIN_FORM_KEY: 1, 'username': 'super', 'password': 'secret', } self.super_email_login = { REDIRECT_FIELD_NAME: '/test_admin/admin/', LOGIN_FORM_KEY: 1, 'username': 'super@example.com', 'password': 'secret', } self.super_email_bad_login = { REDIRECT_FIELD_NAME: '/test_admin/admin/', LOGIN_FORM_KEY: 1, 'username': 'super@example.com', 'password': 'notsecret', } self.adduser_login = { REDIRECT_FIELD_NAME: '/test_admin/admin/', LOGIN_FORM_KEY: 1, 'username': 'adduser', 'password': 'secret', } self.changeuser_login = { REDIRECT_FIELD_NAME: '/test_admin/admin/', LOGIN_FORM_KEY: 1, 'username': 'changeuser', 'password': 'secret', } self.deleteuser_login = { REDIRECT_FIELD_NAME: '/test_admin/admin/', LOGIN_FORM_KEY: 1, 'username': 'deleteuser', 'password': 'secret', } self.joepublic_login = { REDIRECT_FIELD_NAME: '/test_admin/admin/', LOGIN_FORM_KEY: 1, 'username': 'joepublic', 'password': 'secret', } self.no_username_login = { REDIRECT_FIELD_NAME: '/test_admin/admin/', LOGIN_FORM_KEY: 1, 'password': 'secret', } Loading Loading @@ -1391,7 +1381,6 @@ class AdminViewsNoUrlTest(TestCase): # login POST dict self.changeuser_login = { REDIRECT_FIELD_NAME: '/test_admin/admin/', LOGIN_FORM_KEY: 1, 'username': 'changeuser', 'password': 'secret', } Loading Loading @@ -2600,7 +2589,6 @@ class AdminCustomQuerysetTest(TestCase): self.pks = [EmptyModel.objects.create().id for i in range(3)] self.super_login = { REDIRECT_FIELD_NAME: '/test_admin/admin/', LOGIN_FORM_KEY: 1, 'username': 'super', 'password': 'secret', } Loading