from datetime import datetime, timedelta from fastapi import APIRouter, Depends, HTTPException, status from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm from jose import jwt from pydantic import BaseModel from sqlalchemy.orm import Session from ..config import Config from ..db import crud from ..db.connection import Connection router = APIRouter(prefix="/user") SCHEME = OAuth2PasswordBearer(tokenUrl=f".{router.prefix}/token") class Token(BaseModel): access_token: str token_type: str def create_access_token( data: dict, expires_delta: timedelta | None = None, config: Config = Depends(Config.get), ): to_encode = data.copy() if expires_delta is None: expires_delta = timedelta(minutes=15) to_encode.update({"exp": datetime.utcnow() + expires_delta}) return jwt.encode( to_encode, config.jwt.secret, algorithm=config.jwt.hash_algorithm, ) @router.post("/auth", response_model=Token) async def login_for_access_token( form_data: OAuth2PasswordRequestForm = Depends(), config: Config = Depends(Config.get), db: Session = Depends(Connection.get), ): credentials_exception = HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="Could not validate credentials", headers={"WWW-Authenticate": "Bearer"}, ) user = crud.get_user(db, form_data.username) if user is None: config.crypt_context.dummy_verify() raise credentials_exception if not user.verify(form_data.password): raise credentials_exception access_token = create_access_token( data={"sub": user.name}, expires_delta=timedelta(minutes=config.jwt.expiry_minutes), ) return {"access_token": access_token, "token_type": "bearer"}