The PasswordResetForm in django.contrib.auth.forms assumes that there
cannot be more than one user with the same email address (see the
isValidUserEmail method), even though there is no database level
constraint for this. So the corresponding view,
django.contrib.auth.views.password_reset, can give you an 'Internal
Server Error' if you have users who share email addresses, as I do.
This use case is not so strange as it seems -- married couples sometimes
seem to share email addresses, but they may need different accounts on
a website.
So, the attached patch changes the form to reset *all* usernames for the
given email address. This isn't perfectly ideal behaviour, but it
seems better than the alternatives (e.g. not allowing password resets
where you have duplicate email addresses). Asking the user "which
account do you want to reset?" would add a lot of complication to the
form for a very small use case. The only downside is that the
passwords for all relevant accounts have been reset, but the person who
has done this will realise this has happened as he/she will by
definition get both emails (which contain already contain the username
that has been reset).
Any objections to me committing this?
Thanks,
Luke
--
"Making it up? Why should I want to make anything up? Life's bad enough
as it is without wanting to invent any more of it." (Marvin the
paranoid android)
Luke Plant || http://lukeplant.me.uk/
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Django developers" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at
http://groups.google.com/group/django-developers?hl=en
-~----------~----~----~----~------~----~------~--~---
Index: django/contrib/auth/forms.py
===================================================================
--- django/contrib/auth/forms.py (revision 5490)
+++ django/contrib/auth/forms.py (working copy)
@@ -79,32 +79,32 @@
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:
+ self.users_cache = list(User.objects.filter(email__iexact=new_data))
+ if len(self.users_cache) == 0:
raise validators.ValidationError, _("That e-mail address doesn't have an associated user account. Are you sure you've registered?")
def save(self, domain_override=None, email_template_name='registration/password_reset_email.html'):
"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(email_template_name)
- 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])
+ for user in self.users_cache:
+ new_pass = User.objects.make_random_password()
+ user.set_password(new_pass)
+ user.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(email_template_name)
+ c = {
+ 'new_password': new_pass,
+ 'email': user.email,
+ 'domain': domain,
+ 'site_name': site_name,
+ 'user': user,
+ }
+ send_mail('Password reset on %s' % site_name, t.render(Context(c)), None, [user.email])
class PasswordChangeForm(oldforms.Manipulator):
"A form that lets a user change his password."