Skip to content

Commit

Permalink
Merge pull request #157 from level12/156-fail-to-find-a-user-by-email…
Browse files Browse the repository at this point in the history
…-when-data-includes-capital-letters

making user lookup use a to-lower expression on both sides of the que…
  • Loading branch information
guruofgentoo committed Jul 8, 2022
2 parents 6d6f959 + f78a842 commit d01c310
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 1 deletion.
4 changes: 3 additions & 1 deletion keg_auth/libs/authenticators.py
Expand Up @@ -831,7 +831,9 @@ def verify_user(self, login_id=None, password=None, allow_unverified=False):
# apply a domain filter before looking up the user record
raise UserNotFound

user = self.user_ent.query.filter_by(username=login_id).one_or_none()
user = self.user_ent.query.filter(
sa.func.lower(self.user_ent.username) == (login_id.lower() if login_id else None)
).one_or_none()

if not user:
raise UserNotFound
Expand Down
18 changes: 18 additions & 0 deletions keg_auth/tests/test_authenticators.py
Expand Up @@ -57,6 +57,24 @@ def test_unverified_user(self):
allow_unverified=True)
assert user is found_user

def test_user_case_insensitive(self):
from keg import db
from sqlalchemy import text

user = User.testing_create(email='abc@foo.bar')

# Downstream in the process of creating a user, the email will be set to all lowercase
# So we need to manually set it to capital letters to test the fix
with db.db.engine.connect() as connection:
connection.execute(
text("UPDATE users SET email = 'ABC@Foo.Bar' WHERE email = 'abc@foo.bar'")
)
authenticator = auth.KegAuthenticator(app=flask.current_app)
found_user = authenticator.verify_user(login_id='aBc@Foo.Bar',
password=user._plaintext_pass)
assert found_user is not None
assert found_user.id == user.id

@mock.patch.dict(
'flask.current_app.config',
{
Expand Down

0 comments on commit d01c310

Please sign in to comment.