Fix #245 : handle email as case insensitive while retrieving user in DB (#250)

* Add unit tests to enforce email case insensitivity

* Handle email as case insentitive while retrieving user in DB

* Apply isort/black

* Add migration doc
This commit is contained in:
François Voron
2020-07-09 18:44:25 +02:00
committed by GitHub
parent e63a67ead3
commit b7dbdf6ea6
12 changed files with 70 additions and 25 deletions

View File

@@ -28,7 +28,9 @@ class MongoDBUserDatabase(BaseUserDatabase[UD]):
return self.user_db_model(**user) if user else None
async def get_by_email(self, email: str) -> Optional[UD]:
user = await self.collection.find_one({"email": email})
user = await self.collection.find_one(
{"email": {"$regex": email, "$options": "i"}}
)
return self.user_db_model(**user) if user else None
async def get_by_oauth_account(self, oauth: str, account_id: str) -> Optional[UD]:

View File

@@ -3,7 +3,7 @@ from typing import Mapping, Optional, Type
from databases import Database
from pydantic import UUID4
from sqlalchemy import Boolean, Column, ForeignKey, Integer, String, Table, select
from sqlalchemy import Boolean, Column, ForeignKey, Integer, String, Table, func, select
from sqlalchemy.dialects.postgresql import UUID
from sqlalchemy.ext.declarative import declared_attr
from sqlalchemy.types import CHAR, TypeDecorator
@@ -120,7 +120,9 @@ class SQLAlchemyUserDatabase(BaseUserDatabase[UD]):
return await self._make_user(user) if user else None
async def get_by_email(self, email: str) -> Optional[UD]:
query = self.users.select().where(self.users.c.email == email)
query = self.users.select().where(
func.lower(self.users.c.email) == func.lower(email)
)
user = await self.database.fetch_one(query)
return await self._make_user(user) if user else None

View File

@@ -77,19 +77,19 @@ class TortoiseUserDatabase(BaseUserDatabase[UD]):
return None
async def get_by_email(self, email: str) -> Optional[UD]:
try:
query = self.model.get(email=email)
query = self.model.filter(email__iexact=email).first()
if self.oauth_account_model is not None:
query = query.prefetch_related("oauth_accounts")
if self.oauth_account_model is not None:
query = query.prefetch_related("oauth_accounts")
user = await query
user_dict = await user.to_dict()
user = await query
return self.user_db_model(**user_dict)
except DoesNotExist:
if user is None:
return None
user_dict = await user.to_dict()
return self.user_db_model(**user_dict)
async def get_by_oauth_account(self, oauth: str, account_id: str) -> Optional[UD]:
try:
query = self.model.get(