[#7761] ticket:690 Check all matches in User.by_email_address
diff --git a/Allura/allura/model/auth.py b/Allura/allura/model/auth.py
index 6217f42..093b046 100644
--- a/Allura/allura/model/auth.py
+++ b/Allura/allura/model/auth.py
@@ -617,10 +617,13 @@
@classmethod
def by_email_address(cls, addr):
- ea = EmailAddress.query.get(email=addr, confirmed=True)
- if ea is None:
- return None
- return ea.claimed_by_user()
+ addrs = EmailAddress.query.find(dict(email=addr, confirmed=True))
+ users = [ea.claimed_by_user() for ea in addrs]
+ users = [u for u in users if u is not None]
+ if len(users) > 1:
+ log.warn('Multiple active users matching confirmed email %s %s. '
+ 'Using first one', [u.username for u in users], addr)
+ return users[0] if len(users) > 0 else None
@classmethod
def by_username(cls, name):
diff --git a/Allura/allura/tests/model/test_auth.py b/Allura/allura/tests/model/test_auth.py
index 2b05672..8ae0faa 100644
--- a/Allura/allura/tests/model/test_auth.py
+++ b/Allura/allura/tests/model/test_auth.py
@@ -153,6 +153,35 @@
@with_setup(setUp)
+@patch('allura.model.auth.log')
+def test_user_by_email_address(log):
+ u1 = M.User.register(dict(username='abc1'), make_project=False)
+ u2 = M.User.register(dict(username='abc2'), make_project=False)
+ addr1 = M.EmailAddress(email='abc123@abc.me', confirmed=True,
+ claimed_by_user_id=u1._id)
+ addr2 = M.EmailAddress(email='abc123@abc.me', confirmed=True,
+ claimed_by_user_id=u2._id)
+
+ # both users are disabled
+ u1.disabled, u2.disabled = True, True
+ ThreadLocalORMSession.flush_all()
+ assert_equal(M.User.by_email_address('abc123@abc.me'), None)
+ assert_equal(log.warn.call_count, 0)
+
+ # only u2 is active
+ u1.disabled, u2.disabled = True, False
+ ThreadLocalORMSession.flush_all()
+ assert_equal(M.User.by_email_address('abc123@abc.me'), u2)
+ assert_equal(log.warn.call_count, 0)
+
+ # both are active
+ u1.disabled, u2.disabled = False, False
+ ThreadLocalORMSession.flush_all()
+ assert_in(M.User.by_email_address('abc123@abc.me'), [u1, u2])
+ assert_equal(log.warn.call_count, 1)
+
+
+@with_setup(setUp)
def test_project_role():
role = M.ProjectRole(project_id=c.project._id, name='test_role')
M.ProjectRole.by_user(c.user, upsert=True).roles.append(role._id)