Changeset 7191
- Timestamp:
- 03/03/08 14:37:41 (2 months ago)
- Files:
-
- django/branches/newforms-admin/django/contrib/admin/templates/admin/auth/user/add_form.html (modified) (1 diff)
- django/branches/newforms-admin/django/contrib/admin/templates/admin/auth/user/change_password.html (modified) (2 diffs)
- django/branches/newforms-admin/django/contrib/auth/admin.py (modified) (2 diffs)
- django/branches/newforms-admin/django/contrib/auth/forms.py (modified) (2 diffs)
- django/branches/newforms-admin/django/contrib/auth/tests (added)
- django/branches/newforms-admin/django/contrib/auth/tests/basic.py (moved) (moved from django/branches/newforms-admin/django/contrib/auth/tests.py) (1 diff)
- django/branches/newforms-admin/django/contrib/auth/tests/forms.py (added)
- django/branches/newforms-admin/django/contrib/auth/tests/__init__.py (added)
- django/branches/newforms-admin/django/contrib/auth/views.py (modified) (7 diffs)
- django/branches/newforms-admin/django/contrib/comments/views/comments.py (modified) (1 diff)
- django/branches/newforms-admin/docs/authentication.txt (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
django/branches/newforms-admin/django/contrib/admin/templates/admin/auth/user/add_form.html
r4375 r7191 9 9 10 10 <div class="form-row"> 11 {{ form.username.html_error_list }} 11 {{ form.username.errors }} 12 {# TODO: get required class on label_tag #} 12 13 <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> 14 15 </div> 15 16 16 17 <div class="form-row"> 17 {{ form.password1.html_error_list }} 18 {{ form.password1.errors }} 19 {# TODO: get required class on label_tag #} 18 20 <label for="id_password1" class="required">{% trans 'Password' %}:</label> {{ form.password1 }} 19 21 </div> 20 22 21 23 <div class="form-row"> 22 {{ form.password2.html_error_list }} 24 {{ form.password2.errors }} 25 {# TODO: get required class on label_tag #} 23 26 <label for="id_password2" class="required">{% trans 'Password (again)' %}:</label> {{ form.password2 }} 24 27 <p class="help">{% trans 'Enter the same password as above, for verification.' %}</p> django/branches/newforms-admin/django/contrib/admin/templates/admin/auth/user/change_password.html
r5926 r7191 19 19 <div> 20 20 {% if is_popup %}<input type="hidden" name="_popup" value="1" />{% endif %} 21 {% if form.error _dict%}21 {% if form.errors %} 22 22 <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 %} 24 24 </p> 25 25 {% endif %} … … 30 30 31 31 <div class="form-row"> 32 {{ form.password1.html_error_list }} 32 {{ form.password1.errors }} 33 {# TODO: get required class on label_tag #} 33 34 <label for="id_password1" class="required">{% trans 'Password' %}:</label> {{ form.password1 }} 34 35 </div> 35 36 36 37 <div class="form-row"> 37 {{ form.password2.html_error_list }} 38 {{ form.password2.errors }} 39 {# TODO: get required class on label_tag #} 38 40 <label for="id_password2" class="required">{% trans 'Password (again)' %}:</label> {{ form.password2 }} 39 41 <p class="help">{% trans 'Enter the same password as above, for verification.' %}</p> django/branches/newforms-admin/django/contrib/auth/admin.py
r6812 r7191 28 28 if not self.has_change_permission(request): 29 29 raise PermissionDenied 30 manipulator = UserCreationForm()31 30 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() 36 34 msg = _('The %(name)s "%(obj)s" was added successfully.') % {'name': 'user', 'obj': new_user} 37 35 if "_addanother" in request.POST: … … 42 40 return HttpResponseRedirect('../%s/' % new_user.id) 43 41 else: 44 errors = new_data = {} 45 form = oldforms.FormWrapper(manipulator, new_data, errors) 42 form = UserCreationForm() 46 43 return render_to_response('admin/auth/user/add_form.html', { 47 44 'title': _('Add user'), django/branches/newforms-admin/django/contrib/auth/forms.py
r6656 r7191 4 4 from django.template import Context, loader 5 5 from django.core import validators 6 from django import oldforms6 from django import newforms as forms 7 7 from django.utils.translation import ugettext as _ 8 8 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 ) 9 class 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"] 25 try: 26 User.objects.get(username=username) 27 except User.DoesNotExist: 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 19 44 20 def isValidUsername(self, field_data, all_data): 21 try: 22 User.objects.get(username=field_data) 23 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']) 30 31 class AuthenticationForm(oldforms.Manipulator): 45 class AuthenticationForm(forms.Form): 32 46 """ 33 47 Base class for authenticating users. Extend this to get a form that accepts 34 48 username/password logins. 35 49 """ 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): 37 54 """ 38 If request is passed in, the manipulatorwill validate that cookies are55 If request is passed in, the form will validate that cookies are 39 56 enabled. Note that the request (a HttpRequest object) must have set a 40 57 cookie with the key TEST_COOKIE_NAME and value TEST_COOKIE_VALUE before 41 running this validat or.58 running this validation. 42 59 """ 43 60 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 ]49 61 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 64 82 def get_user_id(self): 65 83 if self.user_cache: 66 84 return self.user_cache.id 67 85 return None 68 86 69 87 def get_user(self): 70 88 return self.user_cache 71 89 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)) 90 class PasswordResetForm(forms.Form): 91 email = forms.EmailField(max_length=40) 92 93 def clean_email(self): 94 """ 95 Validates that a user exists with the given e-mail address. 96 """ 97 email = self.cleaned_data["email"] 98 self.users_cache = User.objects.filter(email__iexact=email) 83 99 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 100 raise forms.ValidationError(_("That e-mail address doesn't have an associated user account. Are you sure you've registered?")) 101 86 102 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" 103 """ 104 Calculates a new password randomly and sends it to the user. 105 """ 88 106 from django.core.mail import send_mail 89 107 for user in self.users_cache: … … 104 122 'site_name': site_name, 105 123 'user': user, 106 } 107 send_mail(_('Password reset on %s') % site_name, t.render(Context(c)), None, [user.email]) 124 } 125 send_mail(_("Password reset on %s") % site_name, 126 t.render(Context(c)), None, [user.email]) 108 127 109 class PasswordChangeForm(oldforms.Manipulator): 110 "A form that lets a user change his password." 111 def __init__(self, user): 128 class PasswordChangeForm(forms.Form): 129 """ 130 A form that lets a user change his/her password. 131 """ 132 old_password = forms.CharField(max_length=30, widget=forms.PasswordInput) 133 new_password1 = forms.CharField(max_length=30, widget=forms.PasswordInput) 134 new_password2 = forms.CharField(max_length=30, widget=forms.PasswordInput) 135 136 def __init__(self, user, *args, **kwargs): 112 137 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 ) 138 super(PasswordChangeForm, self).__init__(*args, **kwargs) 139 140 def clean_old_password(self): 141 """ 142 Validates that the old_password field is correct. 143 """ 144 old_password = self.cleaned_data["old_password"] 145 if not self.user.check_password(old_password): 146 raise forms.ValidationError(_("Your old password was entered incorrectly. Please enter it again.")) 147 return old_password 148 149 def clean_new_password2(self): 150 password1 = self.cleaned_data.get('new_password1') 151 password2 = self.cleaned_data.get('new_password2') 152 if password1 and password2: 153 if password1 != password2: 154 raise forms.ValidationError(_("The two password fields didn't match.")) 155 return password2 156 157 def save(self, commit=True): 158 self.user.set_password(self.cleaned_data['new_password1']) 159 if commit: 160 self.user.save() 161 return self.user 120 162 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): 163 class AdminPasswordChangeForm(forms.Form): 164 """ 165 A form used to change the password of a user in the admin interface. 166 """ 167 password1 = forms.CharField(max_length=60, widget=forms.PasswordInput) 168 password2 = forms.CharField(max_length=60, widget=forms.PasswordInput) 169 170 def __init__(self, user, *args, **kwargs): 134 171 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() 172 super(AdminPasswordChangeForm, self).__init__(*args, **kwargs) 173 174 def clean_password2(self): 175 password1 = self.cleaned_data.get('password1') 176 password2 = self.cleaned_data.get('password2') 177 if password1 and password2: 178 if password1 != password2: 179 raise forms.ValidationError(_("The two password fields didn't match.")) 180 return password2 181 182 def save(self, commit=True): 183 """ 184 Saves the new password. 185 """ 186 self.user.set_password(self.cleaned_data["password1"]) 187 if commit: 188 self.user.save() 189 return self.user django/branches/newforms-admin/django/contrib/auth/tests/basic.py
r6955 r7191 1 """ 2 >>> from models import User, AnonymousUser 1 2 BASIC_TESTS = """ 3 >>> from django.contrib.auth.models import User, AnonymousUser 3 4 >>> u = User.objects.create_user('testuser', 'test@example.com', 'testpw') 4 5 >>> u.has_usable_password() django/branches/newforms-admin/django/contrib/auth/views.py
r6811 r7191 2 2 from django.contrib.auth.forms import PasswordResetForm, PasswordChangeForm, AdminPasswordChangeForm 3 3 from django.core.exceptions import PermissionDenied 4 from django import oldforms5 4 from django.shortcuts import render_to_response, get_object_or_404 6 5 from django.template import RequestContext … … 15 14 def login(request, template_name='registration/login.html', redirect_field_name=REDIRECT_FIELD_NAME): 16 15 "Displays the login form and handles the login action." 17 manipulator = AuthenticationForm(request)18 16 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(): 22 20 # Light security check -- make sure redirect_to isn't garbage. 23 21 if not redirect_to or '//' in redirect_to or ' ' in redirect_to: … … 25 23 redirect_to = settings.LOGIN_REDIRECT_URL 26 24 from django.contrib.auth import login 27 login(request, manipulator.get_user())25 login(request, form.get_user()) 28 26 request.session.delete_test_cookie() 29 27 return HttpResponseRedirect(redirect_to) 30 28 else: 31 errors = {}29 form = AuthenticationForm(request) 32 30 request.session.set_test_cookie() 33 34 31 if Site._meta.installed: 35 32 current_site = Site.objects.get_current() 36 33 else: 37 34 current_site = RequestSite(request) 38 39 35 return render_to_response(template_name, { 40 'form': oldforms.FormWrapper(manipulator, request.POST, errors),36 'form': form, 41 37 redirect_field_name: redirect_to, 42 38 'site_name': current_site.name, … … 69 65 def password_reset(request, is_admin_site=False, template_name='registration/password_reset_form.html', 70 66 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(): 77 70 if is_admin_site: 78 71 form.save(domain_override=request.META['HTTP_HOST']) … … 80 73 form.save(email_template_name=email_template_name) 81 74 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)) 84 80 85 81 def password_reset_done(request, template_name='registration/password_reset_done.html'): … … 87 83 88 84 def 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() 96 89 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)) 99 95 password_change = login_required(password_change) 100 96 … … 102 98 return render_to_response(template_name, context_instance=RequestContext(request)) 103 99 100 # TODO: move to admin.py in the ModelAdmin 104 101 def user_change_password(request, id): 102 from django import oldforms 105 103 if not request.user.has_perm('auth.change_user'): 106 104 raise PermissionDenied 107 105 user = get_object_or_404(User, pk=id) 108 manipulator = AdminPasswordChangeForm(user)109 106 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() 114 110 msg = _('Password changed successfully.') 115 111 request.user.message_set.create(message=msg) 116 112 return HttpResponseRedirect('..') 117 113 else: 118 errors = new_data = {} 119 form = oldforms.FormWrapper(manipulator, new_data, errors) 114 form = AdminPasswordChangeForm(user) 120 115 return render_to_response('admin/auth/user/change_password.html', { 121 116 'title': _('Change password: %s') % escape(user.username), django/branches/newforms-admin/django/contrib/comments/views/comments.py
r6342 r7191 17 17 18 18 COMMENTS_PER_PAGE = 20 19 20 class 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 19 60 20 61 class PublicCommentManipulator(AuthenticationForm): django/branches/newforms-admin/docs/authentication.txt
r6955 r7191 667 667 will default to ``settings.LOGIN_URL`` if not supplied. 668 668 669 Built-in manipulators 670 --------------------- 669 Built-in forms 670 -------------- 671 672 **New in Django development version.** 671 673 672 674 If 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: 675 676 * ``django.contrib.auth.forms.AdminPasswordChangeForm``: A 677 manipulator used in the admin interface to change a user's 678 password. 679 680 * ``django.contrib.auth.forms.AuthenticationForm``: A manipulator 681 for logging a user in. 682 683 * ``django.contrib.auth.forms.PasswordChangeForm``: A manipulator 684 for allowing a user to change their password. 685 686 * ``django.contrib.auth.forms.PasswordResetForm``: A manipulator 687 for resetting a user's password and emailing the new password to 688 them. 689 690 * ``django.contrib.auth.forms.UserCreationForm``: A manipulator 691 for creating a new user. 675 of not having to write forms for this functionality, the authentication 676 system provides several built-in forms: 677 678 * ``django.contrib.auth.forms.AdminPasswordChangeForm``: A form used in 679 the admin interface to change a user's password. 680 681 * ``django.contrib.auth.forms.AuthenticationForm``: A form for logging a 682 user in. 683 684 * ``django.contrib.auth.forms.PasswordChangeForm``: A form for allowing a 685 user to change their password. 686 687 * ``django.contrib.auth.forms.PasswordResetForm``: A form for resetting a 688 user's password and emailing the new password to them. 689 690 * ``django.contrib.auth.forms.UserCreationForm``: A form for creating a 691 new user. 692 692 693 693 Limiting access to logged-in users that pass a test
