57 lines
1.5 KiB
Python
57 lines
1.5 KiB
Python
|
from typing import Annotated
|
||
|
|
||
|
import bcrypt
|
||
|
from fastapi import APIRouter, Depends, HTTPException, status
|
||
|
from fastapi.security import OAuth2PasswordRequestForm
|
||
|
from fastapi_limiter.depends import RateLimiter
|
||
|
from psycopg_pool import AsyncConnectionPool
|
||
|
|
||
|
from src.neo_neo_todo.models.member import select_member_by_email
|
||
|
from src.neo_neo_todo.utils.database import get_pool
|
||
|
|
||
|
router = APIRouter(
|
||
|
prefix="/token",
|
||
|
tags=["token"],
|
||
|
)
|
||
|
|
||
|
|
||
|
@router.post(
|
||
|
"",
|
||
|
dependencies=[
|
||
|
Depends(RateLimiter(times=100, seconds=600))
|
||
|
], # rate limit login route
|
||
|
status_code=status.HTTP_200_OK, # default status code when login successful
|
||
|
)
|
||
|
async def login(
|
||
|
form_data: Annotated[OAuth2PasswordRequestForm, Depends()],
|
||
|
db_pool: AsyncConnectionPool = Depends(get_pool),
|
||
|
):
|
||
|
"""
|
||
|
Login to the todo app
|
||
|
|
||
|
If successful, save the returned cookie
|
||
|
"""
|
||
|
member = await select_member_by_email(db_pool, form_data.username)
|
||
|
|
||
|
if member is None:
|
||
|
raise HTTPException(
|
||
|
status_code=status.HTTP_400_BAD_REQUEST,
|
||
|
detail="Incorrect email or password",
|
||
|
)
|
||
|
|
||
|
passwords_match = bcrypt.checkpw(
|
||
|
form_data.password.encode("utf-8"),
|
||
|
member.password_hash.encode("utf-8"),
|
||
|
)
|
||
|
|
||
|
if passwords_match:
|
||
|
# to handle login logic here
|
||
|
pass
|
||
|
else:
|
||
|
raise HTTPException(
|
||
|
status_code=status.HTTP_400_BAD_REQUEST,
|
||
|
detail="Incorrect email or password",
|
||
|
)
|
||
|
|
||
|
return {"access_token": member.email, "token_type": "bearer"}
|