Files
François Voron 104a6c6bf5 Inject every models variations and DB model in DB adapters (#84)
* Inject every model variations in router and DB model in DB adapters

* Update documentation and import Tortoise in db module

* Use path operation decorator dependencies for superuser routes
2020-01-04 15:36:34 +01:00

72 lines
2.2 KiB
Python

from typing import Generic, List, Optional, Type
from fastapi.security import OAuth2PasswordRequestForm
from fastapi_users import password
from fastapi_users.models import UD
class BaseUserDatabase(Generic[UD]):
"""
Base adapter for retrieving, creating and updating users from a database.
:param user_db_model: Pydantic model of a DB representation of a user.
"""
user_db_model: Type[UD]
def __init__(self, user_db_model: Type[UD]):
self.user_db_model = user_db_model
async def list(self) -> List[UD]:
"""List all users."""
raise NotImplementedError()
async def get(self, id: str) -> Optional[UD]:
"""Get a single user by id."""
raise NotImplementedError()
async def get_by_email(self, email: str) -> Optional[UD]:
"""Get a single user by email."""
raise NotImplementedError()
async def create(self, user: UD) -> UD:
"""Create a user."""
raise NotImplementedError()
async def update(self, user: UD) -> UD:
"""Update a user."""
raise NotImplementedError()
async def delete(self, user: UD) -> None:
"""Delete a user."""
raise NotImplementedError()
async def authenticate(
self, credentials: OAuth2PasswordRequestForm
) -> Optional[UD]:
"""
Authenticate and return a user following an email and a password.
Will automatically upgrade password hash if necessary.
"""
user = await self.get_by_email(credentials.username)
if user is None:
# Run the hasher to mitigate timing attack
# Inspired from Django: https://code.djangoproject.com/ticket/20760
password.get_password_hash(credentials.password)
return None
verified, updated_password_hash = password.verify_and_update_password(
credentials.password, user.hashed_password
)
if not verified:
return None
# Update password hash to a more robust one if needed
if updated_password_hash is not None:
user.hashed_password = updated_password_hash
await self.update(user)
return user