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."

Reply via email to