diff --git a/django/conf/urls/registration.py b/django/conf/urls/registration.py index be875f5e4d..2d733a898b 100644 --- a/django/conf/urls/registration.py +++ b/django/conf/urls/registration.py @@ -12,8 +12,8 @@ urlpatterns = patterns('', (r'^profile/welcome/$', 'ellington.registration.views.profile.profile_welcome'), (r'^profile/edit/$', 'ellington.registration.views.profile.edit_profile'), - (r'^password_reset/$', 'django.views.registration.passwords.password_reset'), - (r'^password_reset/done/$', 'django.views.registration.passwords.password_reset_done'), - (r'^password_change/$', 'django.views.registration.passwords.password_change'), - (r'^password_change/done/$', 'django.views.registration.passwords.password_change_done'), + (r'^password_reset/$', 'django.contrib.auth.views.password_reset'), + (r'^password_reset/done/$', 'django.contrib.auth.views.password_reset_done'), + (r'^password_change/$', 'django.contrib.auth.views.password_change'), + (r'^password_change/done/$', 'django.contrib.auth.views.password_change_done'), ) diff --git a/django/contrib/admin/urls.py b/django/contrib/admin/urls.py index f7c47f2ae9..41083f32d5 100644 --- a/django/contrib/admin/urls.py +++ b/django/contrib/admin/urls.py @@ -4,8 +4,8 @@ urlpatterns = patterns('', ('^$', 'django.contrib.admin.views.main.index'), ('^jsi18n/$', 'django.views.i18n.javascript_catalog', {'packages': 'django.conf'}), ('^logout/$', 'django.contrib.auth.views.logout'), - ('^password_change/$', 'django.views.registration.passwords.password_change'), - ('^password_change/done/$', 'django.views.registration.passwords.password_change_done'), + ('^password_change/$', 'django.contrib.auth.views.password_change'), + ('^password_change/done/$', 'django.contrib.auth.views.password_change_done'), ('^template_validator/$', 'django.contrib.admin.views.template.template_validator'), # Documentation diff --git a/django/contrib/auth/__init__.py b/django/contrib/auth/__init__.py index e69de29bb2..ac7b40aca6 100644 --- a/django/contrib/auth/__init__.py +++ b/django/contrib/auth/__init__.py @@ -0,0 +1,2 @@ +LOGIN_URL = '/accounts/login/' +REDIRECT_FIELD_NAME = 'next' diff --git a/django/contrib/auth/decorators.py b/django/contrib/auth/decorators.py index 536c00edc0..045f0a84f7 100644 --- a/django/contrib/auth/decorators.py +++ b/django/contrib/auth/decorators.py @@ -1,6 +1,6 @@ -from django.contrib.auth.views import redirect_to_login +from django.contrib.auth import LOGIN_URL, REDIRECT_FIELD_NAME -def user_passes_test(test_func, login_url=login.LOGIN_URL): +def user_passes_test(test_func, login_url=LOGIN_URL): """ Decorator for views that checks that the user passes the given test, redirecting to the log-in page if necessary. The test should be a callable @@ -10,7 +10,8 @@ def user_passes_test(test_func, login_url=login.LOGIN_URL): def _checklogin(request, *args, **kwargs): if test_func(request.user): return view_func(request, *args, **kwargs) - return redirect_to_login(request.path, login_url) + return HttpResponseRedirect('%s?%s=%s' % (login_url, REDIRECT_FIELD_NAME, request.path)) + return _checklogin return _dec diff --git a/django/contrib/auth/forms.py b/django/contrib/auth/forms.py index 44ebd7e5ca..f65e561656 100644 --- a/django/contrib/auth/forms.py +++ b/django/contrib/auth/forms.py @@ -1,4 +1,6 @@ from django.contrib.auth.models import User +from django.contrib.sites.models import Site +from django.template import Context, loader from django.core import validators from django import forms @@ -45,3 +47,62 @@ class AuthenticationForm(forms.Manipulator): def get_user(self): return self.user_cache + +class PasswordResetForm(forms.Manipulator): + "A form that lets a user request a password reset" + def __init__(self): + self.fields = ( + forms.EmailField(field_name="email", length=40, is_required=True, + validator_list=[self.isValidUserEmail]), + ) + + def isValidUserEmail(self, new_data, all_data): + "Validates that a user exists with the given e-mail address" + try: + self.user_cache = User.objects.get(email__iexact=new_data) + except User.DoesNotExist: + raise validators.ValidationError, "That e-mail address doesn't have an associated user acount. Are you sure you've registered?" + + def save(self, domain_override=None): + "Calculates a new password randomly and sends it to the user" + from django.core.mail import send_mail + new_pass = User.objects.make_random_password() + self.user_cache.set_password(new_pass) + self.user_cache.save() + if not domain_override: + current_site = Site.objects.get_current() + site_name = current_site.name + domain = current_site.domain + else: + site_name = domain = domain_override + t = loader.get_template('registration/password_reset_email') + c = { + 'new_password': new_pass, + 'email': self.user_cache.email, + 'domain': domain, + 'site_name': site_name, + 'user': self.user_cache, + } + send_mail('Password reset on %s' % site_name, t.render(Context(c)), None, [self.user_cache.email]) + +class PasswordChangeForm(forms.Manipulator): + "A form that lets a user change his password." + def __init__(self, user): + self.user = user + self.fields = ( + forms.PasswordField(field_name="old_password", length=30, maxlength=30, is_required=True, + validator_list=[self.isValidOldPassword]), + forms.PasswordField(field_name="new_password1", length=30, maxlength=30, is_required=True, + validator_list=[validators.AlwaysMatchesOtherField('new_password2', "The two 'new password' fields didn't match.")]), + forms.PasswordField(field_name="new_password2", length=30, maxlength=30, is_required=True), + ) + + def isValidOldPassword(self, new_data, all_data): + "Validates that the old_password field is correct." + if not self.user.check_password(new_data): + raise validators.ValidationError, "Your old password was entered incorrectly. Please enter it again." + + def save(self, new_data): + "Saves the new password." + self.user.set_password(new_data['new_password1']) + self.user.save() diff --git a/django/contrib/auth/views.py b/django/contrib/auth/views.py index 261a8176fe..eb9bc1650d 100644 --- a/django/contrib/auth/views.py +++ b/django/contrib/auth/views.py @@ -1,13 +1,13 @@ from django.contrib.auth.forms import AuthenticationForm +from django.contrib.auth.forms import PasswordResetForm, PasswordChangeForm from django import forms from django.shortcuts import render_to_response from django.template import RequestContext from django.contrib.auth.models import SESSION_KEY from django.contrib.sites.models import Site from django.http import HttpResponse, HttpResponseRedirect - -REDIRECT_FIELD_NAME = 'next' -LOGIN_URL = '/accounts/login/' +from django.contrib.auth.decorators import login_required +from django.contrib.auth import LOGIN_URL, REDIRECT_FIELD_NAME def login(request): "Displays the login form and handles the login action." @@ -48,3 +48,37 @@ def logout_then_login(request, login_url=LOGIN_URL): def redirect_to_login(next, login_url=LOGIN_URL): "Redirects the user to the login page, passing the given 'next' page" return HttpResponseRedirect('%s?%s=%s' % (login_url, REDIRECT_FIELD_NAME, next)) + +def password_reset(request, is_admin_site=False): + new_data, errors = {}, {} + form = PasswordResetForm() + if request.POST: + new_data = request.POST.copy() + errors = form.get_validation_errors(new_data) + if not errors: + if is_admin_site: + form.save(request.META['HTTP_HOST']) + else: + form.save() + return HttpResponseRedirect('%sdone/' % request.path) + return render_to_response('registration/password_reset_form', {'form': forms.FormWrapper(form, new_data, errors)}, + context_instance=RequestContext(request)) + +def password_reset_done(request): + return render_to_response('registration/password_reset_done', context_instance=RequestContext(request)) + +def password_change(request): + new_data, errors = {}, {} + form = PasswordChangeForm(request.user) + if request.POST: + new_data = request.POST.copy() + errors = form.get_validation_errors(new_data) + if not errors: + form.save(new_data) + return HttpResponseRedirect('%sdone/' % request.path) + return render_to_response('registration/password_change_form', {'form': forms.FormWrapper(form, new_data, errors)}, + context_instance=RequestContext(request)) +password_change = login_required(password_change) + +def password_change_done(request): + return render_to_response('registration/password_change_done', context_instance=RequestContext(request)) diff --git a/django/views/registration/__init__.py b/django/views/registration/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/django/views/registration/passwords.py b/django/views/registration/passwords.py deleted file mode 100644 index 58f1e8da6b..0000000000 --- a/django/views/registration/passwords.py +++ /dev/null @@ -1,101 +0,0 @@ -from django import forms -from django.core import validators -from django.shortcuts import render_to_response -from django.template import Context, RequestContext, loader -from django.contrib.auth.models import User -from django.contrib.sites.models import Site -from django.contrib.auth.decorators import login_required -from django.http import HttpResponseRedirect - -class PasswordResetForm(forms.Manipulator): - "A form that lets a user request a password reset" - def __init__(self): - self.fields = ( - forms.EmailField(field_name="email", length=40, is_required=True, - validator_list=[self.isValidUserEmail]), - ) - - def isValidUserEmail(self, new_data, all_data): - "Validates that a user exists with the given e-mail address" - try: - self.user_cache = User.objects.get(email__iexact=new_data) - except User.DoesNotExist: - raise validators.ValidationError, "That e-mail address doesn't have an associated user acount. Are you sure you've registered?" - - def save(self, domain_override=None): - "Calculates a new password randomly and sends it to the user" - from django.core.mail import send_mail - new_pass = User.objects.make_random_password() - self.user_cache.set_password(new_pass) - self.user_cache.save() - if not domain_override: - current_site = Site.objects.get_current() - site_name = current_site.name - domain = current_site.domain - else: - site_name = domain = domain_override - t = loader.get_template('registration/password_reset_email') - c = { - 'new_password': new_pass, - 'email': self.user_cache.email, - 'domain': domain, - 'site_name': site_name, - 'user': self.user_cache, - } - send_mail('Password reset on %s' % site_name, t.render(Context(c)), None, [self.user_cache.email]) - -class PasswordChangeForm(forms.Manipulator): - "A form that lets a user change his password." - def __init__(self, user): - self.user = user - self.fields = ( - forms.PasswordField(field_name="old_password", length=30, maxlength=30, is_required=True, - validator_list=[self.isValidOldPassword]), - forms.PasswordField(field_name="new_password1", length=30, maxlength=30, is_required=True, - validator_list=[validators.AlwaysMatchesOtherField('new_password2', "The two 'new password' fields didn't match.")]), - forms.PasswordField(field_name="new_password2", length=30, maxlength=30, is_required=True), - ) - - def isValidOldPassword(self, new_data, all_data): - "Validates that the old_password field is correct." - if not self.user.check_password(new_data): - raise validators.ValidationError, "Your old password was entered incorrectly. Please enter it again." - - def save(self, new_data): - "Saves the new password." - self.user.set_password(new_data['new_password1']) - self.user.save() - -def password_reset(request, is_admin_site=False): - new_data, errors = {}, {} - form = PasswordResetForm() - if request.POST: - new_data = request.POST.copy() - errors = form.get_validation_errors(new_data) - if not errors: - if is_admin_site: - form.save(request.META['HTTP_HOST']) - else: - form.save() - return HttpResponseRedirect('%sdone/' % request.path) - return render_to_response('registration/password_reset_form', {'form': forms.FormWrapper(form, new_data, errors)}, - context_instance=RequestContext(request)) - -def password_reset_done(request): - return render_to_response('registration/password_reset_done', context_instance=RequestContext(request)) - -def password_change(request): - new_data, errors = {}, {} - form = PasswordChangeForm(request.user) - if request.POST: - new_data = request.POST.copy() - errors = form.get_validation_errors(new_data) - if not errors: - form.save(new_data) - return HttpResponseRedirect('%sdone/' % request.path) - return render_to_response('registration/password_change_form', {'form': forms.FormWrapper(form, new_data, errors)}, - context_instance=RequestContext(request)) -password_change = login_required(password_change) - -def password_change_done(request): - return render_to_response('registration/password_change_done', context_instance=RequestContext(request))