Django

Code

Ticket #6083: 6083_newforms_auth2.diff

File 6083_newforms_auth2.diff, 33.5 kB (added by brosner, 9 months ago)

more complete with tests and docs. looking for feedback.

  • a/django/contrib/admin/templates/admin/auth/user/add_form.html

    old new  
    88<fieldset class="module aligned"> 
    99 
    1010<div class="form-row"> 
    11   {{ form.username.html_error_list }} 
     11  {{ form.username.errors }} 
     12  {# TODO: get required class on label_tag #} 
    1213  <label for="id_username" class="required">{% trans 'Username' %}:</label> {{ form.username }} 
    13   <p class="help">{{ username_help_text }}</p> 
     14  <p class="help">{{ form.username.help_text }}</p> 
    1415</div> 
    1516 
    1617<div class="form-row"> 
    17   {{ form.password1.html_error_list }} 
     18  {{ form.password1.errors }} 
     19  {# TODO: get required class on label_tag #} 
    1820  <label for="id_password1" class="required">{% trans 'Password' %}:</label> {{ form.password1 }} 
    1921</div> 
    2022 
    2123<div class="form-row"> 
    22   {{ form.password2.html_error_list }} 
     24  {{ form.password2.errors }} 
     25  {# TODO: get required class on label_tag #} 
    2326  <label for="id_password2" class="required">{% trans 'Password (again)' %}:</label> {{ form.password2 }} 
    2427  <p class="help">{% trans 'Enter the same password as above, for verification.' %}</p> 
    2528</div> 
  • a/django/contrib/admin/templates/admin/auth/user/change_password.html

    old new  
    1818<form action="{{ form_url }}" method="post" id="{{ opts.module_name }}_form">{% block form_top %}{% endblock %} 
    1919<div> 
    2020{% if is_popup %}<input type="hidden" name="_popup" value="1" />{% endif %} 
    21 {% if form.error_dict %} 
     21{% if form.errors %} 
    2222    <p class="errornote"> 
    23     {% blocktrans count form.error_dict.items|length as counter %}Please correct the error below.{% plural %}Please correct the errors below.{% endblocktrans %} 
     23    {% blocktrans count form.errors.items|length as counter %}Please correct the error below.{% plural %}Please correct the errors below.{% endblocktrans %} 
    2424    </p> 
    2525{% endif %} 
    2626 
     
    2929<fieldset class="module aligned"> 
    3030 
    3131<div class="form-row"> 
    32   {{ form.password1.html_error_list }} 
     32  {{ form.password1.errors }} 
     33  {# TODO: get required class on label_tag #} 
    3334  <label for="id_password1" class="required">{% trans 'Password' %}:</label> {{ form.password1 }} 
    3435</div> 
    3536 
    3637<div class="form-row"> 
    37   {{ form.password2.html_error_list }} 
     38  {{ form.password2.errors }} 
     39  {# TODO: get required class on label_tag #} 
    3840  <label for="id_password2" class="required">{% trans 'Password (again)' %}:</label> {{ form.password2 }} 
    3941  <p class="help">{% trans 'Enter the same password as above, for verification.' %}</p> 
    4042</div> 
  • a/django/contrib/auth/admin.py

    old new  
    2727    def add_view(self, request): 
    2828        if not self.has_change_permission(request): 
    2929            raise PermissionDenied 
    30         manipulator = UserCreationForm() 
    3130        if request.method == 'POST': 
    32             new_data = request.POST.copy() 
    33             errors = manipulator.get_validation_errors(new_data) 
    34             if not errors: 
    35                 new_user = manipulator.save(new_data) 
     31            form = UserCreationForm(request.POST) 
     32            if form.is_valid(): 
     33                new_user = form.save() 
    3634                msg = _('The %(name)s "%(obj)s" was added successfully.') % {'name': 'user', 'obj': new_user} 
    3735                if "_addanother" in request.POST: 
    3836                    request.user.message_set.create(message=msg) 
     
    4139                    request.user.message_set.create(message=msg + ' ' + ugettext("You may edit it again below.")) 
    4240                    return HttpResponseRedirect('../%s/' % new_user.id) 
    4341        else: 
    44             errors = new_data = {} 
    45         form = oldforms.FormWrapper(manipulator, new_data, errors) 
     42            form = UserCreationForm() 
    4643        return render_to_response('admin/auth/user/add_form.html', { 
    4744            'title': _('Add user'), 
    4845            'form': form, 
  • a/django/contrib/auth/forms.py

    old new  
    33from django.contrib.sites.models import Site 
    44from django.template import Context, loader 
    55from django.core import validators 
    6 from django import oldforms 
     6from django import newforms as forms 
    77from django.utils.translation import ugettext as _ 
    88 
    9 class UserCreationForm(oldforms.Manipulator): 
    10     "A form that creates a user, with no privileges, from the given username and password." 
    11     def __init__(self): 
    12         self.fields = ( 
    13             oldforms.TextField(field_name='username', length=30, max_length=30, is_required=True, 
    14                 validator_list=[validators.isAlphaNumeric, self.isValidUsername]), 
    15             oldforms.PasswordField(field_name='password1', length=30, max_length=60, is_required=True), 
    16             oldforms.PasswordField(field_name='password2', length=30, max_length=60, is_required=True, 
    17                 validator_list=[validators.AlwaysMatchesOtherField('password1', _("The two password fields didn't match."))]), 
    18         ) 
    19  
    20     def isValidUsername(self, field_data, all_data): 
     9class UserCreationForm(forms.ModelForm): 
     10    """ 
     11    A form that creates a user, with no privileges, from the given username and password. 
     12    """ 
     13    username = forms.RegexField(label=_("Username"), max_length=30, regex=r'^\w+$', 
     14        help_text = _("Required. 30 characters or fewer. Alphanumeric characters only (letters, digits and underscores)."), 
     15        error_message = _("This value must contain only letters, numbers and underscores.")) 
     16    password1 = forms.CharField(label=_("Password"), max_length=60, widget=forms.PasswordInput) 
     17    password2 = forms.CharField(label=_("Password confirmation"), max_length=60, widget=forms.PasswordInput) 
     18     
     19    class Meta: 
     20        model = User 
     21        fields = ("username",) 
     22     
     23    def clean_username(self): 
     24        username = self.cleaned_data["username"] 
    2125        try: 
    22             User.objects.get(username=field_data
     26            User.objects.get(username=username
    2327        except User.DoesNotExist: 
    24             return 
    25         raise validators.ValidationError, _('A user with that username already exists.') 
    26  
    27     def save(self, new_data): 
    28         "Creates the user." 
    29         return User.objects.create_user(new_data['username'], '', new_data['password1']) 
     28            return username 
     29        raise forms.ValidationError(_("A user with that username already exists.")) 
     30     
     31    def clean_password2(self): 
     32        password1 = self.cleaned_data["password1"] 
     33        password2 = self.cleaned_data["password2"] 
     34        if password1 != password2: 
     35            raise forms.ValidationError(_("The two password fields didn't match.")) 
     36        return password2 
     37     
     38    def save(self, commit=True): 
     39        user = super(UserCreationForm, self).save(commit=False) 
     40        user.set_password(self.cleaned_data["password1"]) 
     41        if commit: 
     42            user.save() 
     43        return user 
    3044 
    31 class AuthenticationForm(oldforms.Manipulator): 
     45class AuthenticationForm(forms.Form): 
    3246    """ 
    3347    Base class for authenticating users. Extend this to get a form that accepts 
    3448    username/password logins. 
    3549    """ 
    36     def __init__(self, request=None): 
     50    username = forms.CharField(max_length=30) 
     51    password = forms.CharField(max_length=30, widget=forms.PasswordInput) 
     52     
     53    def __init__(self, request=None, *args, **kwargs): 
    3754        """ 
    38         If request is passed in, the manipulator will validate that cookies are 
     55        If request is passed in, the form will validate that cookies are 
    3956        enabled. Note that the request (a HttpRequest object) must have set a 
    4057        cookie with the key TEST_COOKIE_NAME and value TEST_COOKIE_VALUE before 
    41         running this validator
     58        running this validation
    4259        """ 
    4360        self.request = request 
    44         self.fields = [ 
    45             oldforms.TextField(field_name="username", length=15, max_length=30, is_required=True, 
    46                 validator_list=[self.isValidUser, self.hasCookiesEnabled]), 
    47             oldforms.PasswordField(field_name="password", length=15, max_length=30, is_required=True), 
    48         ] 
    4961        self.user_cache = None 
    50  
    51     def hasCookiesEnabled(self, field_data, all_data): 
    52         if self.request and not self.request.session.test_cookie_worked(): 
    53             raise validators.ValidationError, _("Your Web browser doesn't appear to have cookies enabled. Cookies are required for logging in.") 
    54  
    55     def isValidUser(self, field_data, all_data): 
    56         username = field_data 
    57         password = all_data.get('password', None) 
    58         self.user_cache = authenticate(username=username, password=password) 
    59         if self.user_cache is None: 
    60             raise validators.ValidationError, _("Please enter a correct username and password. Note that both fields are case-sensitive.") 
    61         elif not self.user_cache.is_active: 
    62             raise validators.ValidationError, _("This account is inactive.") 
    63  
     62        super(AuthenticationForm, self).__init__(*args, **kwargs) 
     63     
     64    def clean(self): 
     65        username = self.cleaned_data.get('username') 
     66        password = self.cleaned_data.get('password') 
     67         
     68        if username and password: 
     69            self.user_cache = authenticate(username=username, password=password) 
     70            if self.user_cache is None: 
     71                raise forms.ValidationError(_("Please enter a correct username and password. Note that both fields are case-sensitive.")) 
     72            elif not self.user_cache.is_active: 
     73                raise forms.ValidationError(_("This account is inactive.")) 
     74         
     75        # TODO: determine whether this should move to its own method. 
     76        if self.request: 
     77            if not self.request.session.test_cookie_worked(): 
     78                raise forms.ValidationError(_("Your Web browser doesn't appear to have cookies enabled. Cookies are required for logging in.")) 
     79         
     80        return self.cleaned_data 
     81     
    6482    def get_user_id(self): 
    6583        if self.user_cache: 
    6684            return self.user_cache.id 
    6785        return None 
    68  
     86     
    6987    def get_user(self): 
    7088        return self.user_cache 
    7189 
    72 class PasswordResetForm(oldforms.Manipulator): 
    73     "A form that lets a user request a password reset" 
    74     def __init__(self): 
    75         self.fields = ( 
    76             oldforms.EmailField(field_name="email", length=40, is_required=True, 
    77                 validator_list=[self.isValidUserEmail]), 
    78         ) 
    79  
    80     def isValidUserEmail(self, new_data, all_data): 
    81         "Validates that a user exists with the given e-mail address" 
    82         self.users_cache = list(User.objects.filter(email__iexact=new_data)) 
     90class PasswordResetForm(forms.Form): 
     91    # used to be length of 40 
     92    email = forms.EmailField() 
     93     
     94    def clean_email(self): 
     95        """ 
     96        Validates that a user exists with the given e-mail address. 
     97        """ 
     98        email = self.cleaned_data["email"] 
     99        self.users_cache = User.objects.filter(email__iexact=email) 
    83100        if len(self.users_cache) == 0: 
    84             raise validators.ValidationError, _("That e-mail address doesn't have an associated user account. Are you sure you've registered?"
    85  
     101            raise forms.ValidationError(_("That e-mail address doesn't have an associated user account. Are you sure you've registered?")
     102     
    86103    def save(self, domain_override=None, email_template_name='registration/password_reset_email.html'): 
    87         "Calculates a new password randomly and sends it to the user" 
     104        """ 
     105        Calculates a new password randomly and sends it to the user. 
     106        """ 
    88107        from django.core.mail import send_mail 
    89108        for user in self.users_cache: 
    90109            new_pass = User.objects.make_random_password() 
     
    103122                'domain': domain, 
    104123                'site_name': site_name, 
    105124                'user': user, 
    106                 } 
    107             send_mail(_('Password reset on %s') % site_name, t.render(Context(c)), None, [user.email]) 
     125            } 
     126            send_mail(_("Password reset on %s") % site_name, 
     127                t.render(Context(c)), None, [user.email]) 
    108128 
    109 class PasswordChangeForm(oldforms.Manipulator): 
    110     "A form that lets a user change his password." 
    111     def __init__(self, user): 
     129class PasswordChangeForm(forms.Form): 
     130    """ 
     131    A form that lets a user change his/her password. 
     132    """ 
     133    old_password = forms.CharField(max_length=30, widget=forms.PasswordInput) 
     134    new_password1 = forms.CharField(max_length=30, widget=forms.PasswordInput) 
     135    new_password2 = forms.CharField(max_length=30, widget=forms.PasswordInput) 
     136     
     137    def __init__(self, user, *args, **kwargs): 
    112138        self.user = user 
    113         self.fields = ( 
    114             oldforms.PasswordField(field_name="old_password", length=30, max_length=30, is_required=True, 
    115                 validator_list=[self.isValidOldPassword]), 
    116             oldforms.PasswordField(field_name="new_password1", length=30, max_length=30, is_required=True, 
    117                 validator_list=[validators.AlwaysMatchesOtherField('new_password2', _("The two 'new password' fields didn't match."))]), 
    118             oldforms.PasswordField(field_name="new_password2", length=30, max_length=30, is_required=True), 
    119         ) 
    120  
    121     def isValidOldPassword(self, new_data, all_data): 
    122         "Validates that the old_password field is correct." 
    123         if not self.user.check_password(new_data): 
    124             raise validators.ValidationError, _("Your old password was entered incorrectly. Please enter it again.") 
    125  
    126     def save(self, new_data): 
    127         "Saves the new password." 
    128         self.user.set_password(new_data['new_password1']) 
    129         self.user.save() 
    130  
    131 class AdminPasswordChangeForm(oldforms.Manipulator): 
    132     "A form used to change the password of a user in the admin interface." 
    133     def __init__(self, user): 
     139        super(PasswordChangeForm, self).__init__(*args, **kwargs) 
     140     
     141    def clean_old_password(self): 
     142        """ 
     143        Validates that the old_password field is correct. 
     144        """ 
     145        old_password = self.cleaned_data["old_password"] 
     146        if not self.user.check_password(old_password): 
     147            raise forms.ValidationError(_("Your old password was entered incorrectly. Please enter it again.")) 
     148        return old_password 
     149     
     150    def clean_new_password2(self): 
     151        password1 = self.cleaned_data.get('new_password1') 
     152        password2 = self.cleaned_data.get('new_password2') 
     153        if password1 and password2: 
     154            if password1 != password2: 
     155                raise forms.ValidationError(_("The two password fields didn't match.")) 
     156        return password2 
     157     
     158    def save(self, commit=True): 
     159        self.user.set_password(self.cleaned_data['new_password1']) 
     160        if commit: 
     161            self.user.save() 
     162        return self.user 
     163 
     164class AdminPasswordChangeForm(forms.Form): 
     165    """ 
     166    A form used to change the password of a user in the admin interface. 
     167    """ 
     168    password1 = forms.CharField(max_length=60, widget=forms.PasswordInput) 
     169    password2 = forms.CharField(max_length=60, widget=forms.PasswordInput) 
     170     
     171    def __init__(self, user, *args, **kwargs): 
    134172        self.user = user 
    135         self.fields = ( 
    136             oldforms.PasswordField(field_name='password1', length=30, max_length=60, is_required=True), 
    137             oldforms.PasswordField(field_name='password2', length=30, max_length=60, is_required=True, 
    138                 validator_list=[validators.AlwaysMatchesOtherField('password1', _("The two password fields didn't match."))]), 
    139         ) 
    140  
    141     def save(self, new_data): 
    142         "Saves the new password." 
    143         self.user.set_password(new_data['password1']) 
    144         self.user.save() 
     173        super(AdminPasswordChangeForm, self).__init__(*args, **kwargs) 
     174     
     175    def clean_password2(self): 
     176        password1 = self.cleaned_data.get('password1') 
     177        password2 = self.cleaned_data.get('password2') 
     178        if password1 and password2: 
     179            if password1 != password2: 
     180                raise forms.ValidationError(_("The two password fields didn't match.")) 
     181        return password2 
     182     
     183    def save(self, commit=True): 
     184        """ 
     185        Saves the new password. 
     186        """ 
     187        self.user.set_password(self.cleaned_data["password1"]) 
     188        if commit: 
     189            self.user.save() 
     190        return self.user 
  • /dev/null

    old new  
    1 """ 
    2 >>> from models import User, AnonymousUser 
    3 >>> u = User.objects.create_user('testuser', 'test@example.com', 'testpw') 
    4 >>> u.has_usable_password() 
    5 True 
    6 >>> u.check_password('bad') 
    7 False 
    8 >>> u.check_password('testpw') 
    9 True 
    10 >>> u.set_unusable_password() 
    11 >>> u.save() 
    12 >>> u.check_password('testpw') 
    13 False 
    14 >>> u.has_usable_password() 
    15 False 
    16 >>> u2 = User.objects.create_user('testuser2', 'test2@example.com') 
    17 >>> u2.has_usable_password() 
    18 False 
    19  
    20 >>> u.is_authenticated() 
    21 True 
    22 >>> u.is_staff 
    23 False 
    24 >>> u.is_active 
    25 True 
    26  
    27 >>> a = AnonymousUser() 
    28 >>> a.is_authenticated() 
    29 False 
    30 >>> a.is_staff 
    31 False 
    32 >>> a.is_active 
    33 False 
    34 >>> a.groups.all() 
    35 [] 
    36 >>> a.user_permissions.all() 
    37 [] 
    38 """ 
  • /dev/null

    old new  
     1from django.contrib.auth.tests.basic import BASIC_TESTS 
     2from django.contrib.auth.tests.forms import FORM_TESTS, PasswordResetFormTestCase 
     3 
     4__test__ = { 
     5    'BASIC_TESTS': BASIC_TESTS, 
     6    'PASSWORDRESET_TESTS': PasswordResetFormTestCase, 
     7    'FORM_TESTS': FORM_TESTS, 
     8} 
  • /dev/null

    old new  
     1 
     2BASIC_TESTS = """ 
     3>>> from django.contrib.auth.models import User, AnonymousUser 
     4>>> u = User.objects.create_user('testuser', 'test@example.com', 'testpw') 
     5>>> u.has_usable_password() 
     6True 
     7>>> u.check_password('bad') 
     8False 
     9>>> u.check_password('testpw') 
     10True 
     11>>> u.set_unusable_password() 
     12>>> u.save() 
     13>>> u.check_password('testpw') 
     14False 
     15>>> u.has_usable_password() 
     16False 
     17>>> u2 = User.objects.create_user('testuser2', 'test2@example.com') 
     18>>> u2.has_usable_password() 
     19False 
     20 
     21>>> u.is_authenticated() 
     22True 
     23>>> u.is_staff 
     24False 
     25>>> u.is_active 
     26True 
     27 
     28>>> a = AnonymousUser() 
     29>>> a.is_authenticated() 
     30False 
     31>>> a.is_staff 
     32False 
     33>>> a.is_active 
     34False 
     35>>> a.groups.all() 
     36[] 
     37>>> a.user_permissions.all() 
     38[] 
     39""" 
  • /dev/null

    old new  
     1 
     2from django.core import mail 
     3from django.test import TestCase 
     4from django.contrib.auth.models import User 
     5from django.contrib.auth.forms import PasswordResetForm 
     6 
     7class PasswordResetFormTestCase(TestCase): 
     8    def testValidUser(self): 
     9        data = { 
     10            'email': 'nonexistent@example.com', 
     11        } 
     12        form = PasswordResetForm(data) 
     13        self.assertEqual(form.is_valid(), False) 
     14        self.assertEqual(form["email"].errors, [u"That e-mail address doesn't have an associated user account. Are you sure you've registered?"]) 
     15     
     16    def testEmail(self): 
     17        # TODO: remove my email address from the test ;) 
     18        User.objects.create_user('atestuser', 'atestuser@example.com', 'test789') 
     19        data = { 
     20            'email': 'atestuser@example.com', 
     21        } 
     22        form = PasswordResetForm(data) 
     23        self.assertEqual(form.is_valid(), True) 
     24        # TODO: look at why using contrib.sites breaks other tests 
     25        form.save(domain_override="example.com") 
     26        self.assertEqual(len(mail.outbox), 1) 
     27        self.assertEqual(mail.outbox[0].subject, u'Password reset on example.com') 
     28        # TODO: test mail body. need to figure out a way to get the password in plain text 
     29        # self.assertEqual(mail.outbox[0].body, '') 
     30 
     31FORM_TESTS = """ 
     32>>> from django.contrib.auth.models import User 
     33>>> from django.contrib.auth.forms import UserCreationForm, AuthenticationForm 
     34>>> from django.contrib.auth.forms import PasswordChangeForm 
     35 
     36The user already exists. 
     37 
     38>>> user = User.objects.create_user("jsmith", "jsmith@example.com", "test123") 
     39>>> data = { 
     40...     'username': 'jsmith', 
     41...     'password1': 'test123', 
     42...     'password2': 'test123', 
     43... } 
     44>>> form = UserCreationForm(data) 
     45>>> form.is_valid() 
     46False 
     47>>> form["username"].errors 
     48[u'A user with that username already exists.'] 
     49 
     50The username contains invalid data. 
     51 
     52>>> data = { 
     53...     'username': 'jsmith@example.com', 
     54...     'password1': 'test123', 
     55...     'password2': 'test123', 
     56... } 
     57>>> form = UserCreationForm(data) 
     58>>> form.is_valid() 
     59False 
     60>>> form["username"].errors 
     61[u'This value must contain only letters, numbers and underscores.'] 
     62 
     63The verification password is incorrect. 
     64 
     65>>> data = { 
     66...     'username': 'jsmith2', 
     67...     'password1': 'test123', 
     68...     'password2': 'test', 
     69... } 
     70>>> form = UserCreationForm(data) 
     71>>> form.is_valid() 
     72False 
     73>>> form["password2"].errors 
     74[u"The two password fields didn't match."] 
     75 
     76The success case. 
     77 
     78>>> data = { 
     79...     'username': 'jsmith2', 
     80...     'password1': 'test123', 
     81...     'password2': 'test123', 
     82... } 
     83>>> form = UserCreationForm(data) 
     84>>> form.is_valid() 
     85True 
     86>>> form.save() 
     87<User: jsmith2> 
     88 
     89The user submits an invalid username. 
     90 
     91>>> data = { 
     92...     'username': 'jsmith_does_not_exist', 
     93...     'password': 'test123', 
     94... } 
     95 
     96>>> form = AuthenticationForm(None, data) 
     97>>> form.is_valid() 
     98False 
     99>>> form.non_field_errors() 
     100[u'Please enter a correct username and password. Note that both fields are case-sensitive.'] 
     101 
     102The user is inactive. 
     103 
     104>>> data = { 
     105...     'username': 'jsmith', 
     106...     'password': 'test123', 
     107... } 
     108>>> user.is_active = False 
     109>>> user.save() 
     110>>> form = AuthenticationForm(None, data) 
     111>>> form.is_valid() 
     112False 
     113>>> form.non_field_errors() 
     114[u'This account is inactive.'] 
     115 
     116>>> user.is_active = True 
     117>>> user.save() 
     118 
     119The success case 
     120 
     121>>> form = AuthenticationForm(None, data) 
     122>>> form.is_valid() 
     123True 
     124>>> form.non_field_errors() 
     125[] 
     126 
     127The old password is incorrect. 
     128 
     129>>> data = { 
     130...     'old_password': 'test', 
     131...     'new_password1': 'abc123', 
     132...     'new_password2': 'abc123', 
     133... } 
     134>>> form = PasswordChangeForm(user, data) 
     135>>> form.is_valid() 
     136False 
     137>>> form["old_password"].errors 
     138[u'Your old password was entered incorrectly. Please enter it again.'] 
     139 
     140The two new passwords do not match. 
     141 
     142>>> data = { 
     143...     'old_password': 'test123', 
     144...     'new_password1': 'abc123', 
     145...     'new_password2': 'abc', 
     146... } 
     147>>> form = PasswordChangeForm(user, data) 
     148>>> form.is_valid() 
     149False 
     150>>> form["new_password2"].errors 
     151[u"The two password fields didn't match."] 
     152 
     153The success case. 
     154 
     155>>> data = { 
     156...     'old_password': 'test123', 
     157...     'new_password1': 'abc123', 
     158...     'new_password2': 'abc123', 
     159... } 
     160>>> form = PasswordChangeForm(user, data) 
     161>>> form.is_valid() 
     162True 
     163 
     164""" 
  • a/django/contrib/auth/views.py

    old new  
    11from django.contrib.auth.forms import AuthenticationForm 
    22from django.contrib.auth.forms import PasswordResetForm, PasswordChangeForm, AdminPasswordChangeForm 
    33from django.core.exceptions import PermissionDenied 
    4 from django import oldforms 
    54from django.shortcuts import render_to_response, get_object_or_404 
    65from django.template import RequestContext 
    76from django.contrib.sites.models import Site, RequestSite 
     
    1413 
    1514def login(request, template_name='registration/login.html', redirect_field_name=REDIRECT_FIELD_NAME): 
    1615    "Displays the login form and handles the login action." 
    17     manipulator = AuthenticationForm(request) 
    1816    redirect_to = request.REQUEST.get(redirect_field_name, '') 
    19     if request.POST
    20         errors = manipulator.get_validation_errors(request.POST) 
    21         if not errors
     17    if request.method == "POST"
     18        form = AuthenticationForm(request, request.POST) 
     19        if form.is_valid()
    2220            # Light security check -- make sure redirect_to isn't garbage. 
    2321            if not redirect_to or '//' in redirect_to or ' ' in redirect_to: 
    2422                from django.conf import settings 
    2523                redirect_to = settings.LOGIN_REDIRECT_URL 
    2624            from django.contrib.auth import login 
    27             login(request, manipulator.get_user()) 
     25            login(request, form.get_user()) 
    2826            request.session.delete_test_cookie() 
    2927            return HttpResponseRedirect(redirect_to) 
    3028    else: 
    31         errors = {} 
     29        form = AuthenticationForm(request) 
    3230    request.session.set_test_cookie() 
    33  
    3431    if Site._meta.installed: 
    3532        current_site = Site.objects.get_current() 
    3633    else: 
    3734        current_site = RequestSite(request) 
    38  
    3935    return render_to_response(template_name, { 
    40         'form': oldforms.FormWrapper(manipulator, request.POST, errors)
     36        'form': form
    4137        redirect_field_name: redirect_to, 
    4238        'site_name': current_site.name, 
    4339    }, context_instance=RequestContext(request)) 
     
    6864 
    6965def password_reset(request, is_admin_site=False, template_name='registration/password_reset_form.html', 
    7066        email_template_name='registration/password_reset_email.html'): 
    71     new_data, errors = {}, {} 
    72     form = PasswordResetForm() 
    73     if request.POST: 
    74         new_data = request.POST.copy() 
    75         errors = form.get_validation_errors(new_data) 
    76         if not errors: 
     67    if request.method == "POST": 
     68        form = PasswordResetForm(request.POST) 
     69        if form.is_valid(): 
    7770            if is_admin_site: 
    7871                form.save(domain_override=request.META['HTTP_HOST']) 
    7972            else: 
    8073                form.save(email_template_name=email_template_name) 
    8174            return HttpResponseRedirect('%sdone/' % request.path) 
    82     return render_to_response(template_name, {'form': oldforms.FormWrapper(form, new_data, errors)}, 
    83         context_instance=RequestContext(request)) 
     75    else: 
     76        form = PasswordResetForm() 
     77    return render_to_response(template_name, { 
     78        'form': form, 
     79    }, context_instance=RequestContext(request)) 
    8480 
    8581def password_reset_done(request, template_name='registration/password_reset_done.html'): 
    8682    return render_to_response(template_name, context_instance=RequestContext(request)) 
    8783 
    8884def password_change(request, template_name='registration/password_change_form.html'): 
    89     new_data, errors = {}, {} 
    90     form = PasswordChangeForm(request.user) 
    91     if request.POST: 
    92         new_data = request.POST.copy() 
    93         errors = form.get_validation_errors(new_data) 
    94         if not errors: 
    95             form.save(new_data) 
     85    if request.method == "POST": 
     86        form = PasswordChangeForm(request.user, request.POST) 
     87        if form.is_valid(): 
     88            form.save() 
    9689            return HttpResponseRedirect('%sdone/' % request.path) 
    97     return render_to_response(template_name, {'form': oldforms.FormWrapper(form, new_data, errors)}, 
    98         context_instance=RequestContext(request)) 
     90    else: 
     91        form = PasswordChangeForm(request.user) 
     92    return render_to_response(template_name, { 
     93        'form': form, 
     94    }, context_instance=RequestContext(request)) 
    9995password_change = login_required(password_change) 
    10096 
    10197def password_change_done(request, template_name='registration/password_change_done.html'): 
    10298    return render_to_response(template_name, context_instance=RequestContext(request)) 
    10399 
     100# TODO: move to admin.py in the ModelAdmin 
    104101def user_change_password(request, id): 
     102    from django import oldforms 
    105103    if not request.user.has_perm('auth.change_user'): 
    106104        raise PermissionDenied 
    107105    user = get_object_or_404(User, pk=id) 
    108     manipulator = AdminPasswordChangeForm(user) 
    109106    if request.method == 'POST': 
    110         new_data = request.POST.copy() 
    111         errors = manipulator.get_validation_errors(new_data) 
    112         if not errors: 
    113             new_user = manipulator.save(new_data) 
     107        form = AdminPasswordChangeForm(user, request.POST) 
     108        if form.is_valid(): 
     109            new_user = form.save() 
    114110            msg = _('Password changed successfully.') 
    115111            request.user.message_set.create(message=msg) 
    116112            return HttpResponseRedirect('..') 
    117113    else: 
    118         errors = new_data = {} 
    119     form = oldforms.FormWrapper(manipulator, new_data, errors) 
     114        form = AdminPasswordChangeForm(user) 
    120115    return render_to_response('admin/auth/user/change_password.html', { 
    121116        'title': _('Change password: %s') % escape(user.username), 
    122117        'form': form, 
  • a/django/contrib/comments/views/comments.py

    old new  
    1717 
    1818COMMENTS_PER_PAGE = 20 
    1919 
     20class AuthenticationForm(oldforms.Manipulator): 
     21    """ 
     22    Base class for authenticating users. Extend this to get a form that accepts 
     23    username/password logins. 
     24    """ 
     25    def __init__(self, request=None): 
     26        """ 
     27        If request is passed in, the manipulator will validate that cookies are 
     28        enabled. Note that the request (a HttpRequest object) must have set a 
     29        cookie with the key TEST_COOKIE_NAME and value TEST_COOKIE_VALUE before 
     30        running this validator. 
     31        """ 
     32        self.request = request 
     33        self.fields = [ 
     34            oldforms.TextField(field_name="username", length=15, max_length=30, is_required=True, 
     35                validator_list=[self.isValidUser, self.hasCookiesEnabled]), 
     36            oldforms.PasswordField(field_name="password", length=15, max_length=30, is_required=True), 
     37        ] 
     38        self.user_cache = None 
     39 
     40    def hasCookiesEnabled(self, field_data, all_data): 
     41        if self.request and not self.request.session.test_cookie_worked(): 
     42            raise validators.ValidationError, _("Your Web browser doesn't appear to have cookies enabled. Cookies are required for logging in.") 
     43 
     44    def isValidUser(self, field_data, all_data): 
     45        username = field_data 
     46        password = all_data.get('password', None) 
     47        self.user_cache = authenticate(username=username, password=password) 
     48        if self.user_cache is None: 
     49            raise validators.ValidationError, _("Please enter a correct username and password. Note that both fields are case-sensitive.") 
     50        elif not self.user_cache.is_active: 
     51            raise validators.ValidationError, _("This account is inactive.") 
     52 
     53    def get_user_id(self): 
     54        if self.user_cache: 
     55            return self.user_cache.id 
     56        return None 
     57 
     58    def get_user(self): 
     59        return self.user_cache 
     60 
    2061class PublicCommentManipulator(AuthenticationForm): 
    2162    "Manipulator that handles public registered comments" 
    2263    def __init__(self, user, ratings_required, ratings_range, num_rating_choices): 
  • a/docs/authentication.txt

    old new  
    666666    * ``login_url``: The URL of the login page to redirect to. This 
    667667      will default to ``settings.LOGIN_URL`` if not supplied. 
    668668 
    669 Built-in manipulators 
    670 --------------------- 
     669Built-in forms 
     670-------------- 
     671 
     672**New in Django development version.** 
    671673 
    672674If you don't want to use the built-in views, but want the convenience 
    673 of not having to write manipulators for this functionality, the 
    674 authentication system provides several built-in manipulators: 
     675of not having to write forms for this functionality, the authentication 
     676system provides several built-in forms: 
    675677 
    676     * ``django.contrib.auth.forms.AdminPasswordChangeForm``: A 
    677       manipulator used in the admin interface to change a user's 
    678       password. 
     678    * ``django.contrib.auth.forms.AdminPasswordChangeForm``: A form used in 
     679      the admin interface to change a user's password. 
    679680 
    680     * ``django.contrib.auth.forms.AuthenticationForm``: A manipulator 
    681       for logging a user in. 
     681    * ``django.contrib.auth.forms.AuthenticationForm``: A form for logging a 
     682      user in. 
    682683 
    683     * ``django.contrib.auth.forms.PasswordChangeForm``: A manipulator 
    684       for allowing a user to change their password. 
     684    * ``django.contrib.auth.forms.PasswordChangeForm``: A form for allowing a 
     685      user to change their password. 
    685686 
    686     * ``django.contrib.auth.forms.PasswordResetForm``: A manipulator 
    687       for resetting a user's password and emailing the new password to 
    688       them. 
     687    * ``django.contrib.auth.forms.PasswordResetForm``: A form for resetting a 
     688      user's password and emailing the new password to them. 
    689689 
    690     * ``django.contrib.auth.forms.UserCreationForm``: A manipulator 
    691       for creating a new user. 
     690    * ``django.contrib.auth.forms.UserCreationForm``: A form for creating a 
     691      new user. 
    692692 
    693693Limiting access to logged-in users that pass a test 
    694694---------------------------------------------------