Browse Source

Handle multiple users returned by get_by_username_or_email

rafalp 6 years ago
parent
commit
351ebdc693
2 changed files with 27 additions and 7 deletions
  1. 12 3
      misago/users/models/user.py
  2. 15 4
      misago/users/tests/test_user_model.py

+ 12 - 3
misago/users/models/user.py

@@ -7,6 +7,7 @@ from django.contrib.auth.password_validation import validate_password
 from django.contrib.postgres.fields import ArrayField, HStoreField, JSONField
 from django.core.mail import send_mail
 from django.db import IntegrityError, models, transaction
+from django.db.models import Q
 from django.urls import reverse
 from django.utils import timezone
 from django.utils.translation import ugettext_lazy as _
@@ -129,9 +130,17 @@ class UserManager(BaseUserManager):
         return self.get(email_hash=hash_email(email))
 
     def get_by_username_or_email(self, login):
-        queryset = models.Q(slug=slugify(login))
-        queryset = queryset | models.Q(email_hash=hash_email(login))
-        return self.get(queryset)
+        email_hash = hash_email(login)
+        slug = slugify(login)
+        
+        users = list(self.filter(Q(slug=slug) | Q(email_hash=email_hash)))
+        for user in users:
+            if user.email_hash == email_hash:
+                return user
+        for user in users:
+            if user.slug == slug:
+                return user
+        raise User.DoesNotExist()
 
 
 class User(AbstractBaseUser, PermissionsMixin):

+ 15 - 4
misago/users/tests/test_user_model.py

@@ -50,16 +50,27 @@ class UserManagerTests(TestCase):
         user = User.objects.create_user('Bob', 'bob@test.com', 'Pass.123')
 
         db_user = User.objects.get_by_username(user.username)
-        self.assertEqual(user.pk, db_user.pk)
+        self.assertEqual(user, db_user)
 
         db_user = User.objects.get_by_email(user.email)
-        self.assertEqual(user.pk, db_user.pk)
+        self.assertEqual(user, db_user)
 
         db_user = User.objects.get_by_username_or_email(user.username)
-        self.assertEqual(user.pk, db_user.pk)
+        self.assertEqual(user, db_user)
 
         db_user = User.objects.get_by_username_or_email(user.email)
-        self.assertEqual(user.pk, db_user.pk)
+        self.assertEqual(user, db_user)
+
+    def test_get_by_username_or_email_multiple_results(self):
+        """get_by_username_or_email method handles multiple results"""
+        email_match = User.objects.create_user('Bob', 'test@test.test', 'Pass.123')
+        slug_match = User.objects.create_user('TestTestTest', 'bob@test.com', 'Pass.123')
+
+        db_user = User.objects.get_by_username_or_email('test@test.test')
+        self.assertEqual(email_match, db_user)
+
+        db_user = User.objects.get_by_username_or_email('TestTestTest')
+        self.assertEqual(slug_match, db_user)
 
     def test_getters_unicode_handling(self):
         """get_by_ methods handle unicode"""