from datetime import timedelta from typing import Any from fastapi import APIRouter, Depends, HTTPException, status from fastapi.security import OAuth2PasswordRequestForm from sqlalchemy.orm import Session from app import crud from app.api import deps from app.core import security from app.core.config import settings from app.schemas.auth import Login, TokenResponse from app.schemas.user import User, UserCreate router = APIRouter() @router.post("/login", response_model=TokenResponse) def login( db: Session = Depends(deps.get_db), form_data: OAuth2PasswordRequestForm = Depends(), ) -> Any: """ Get an access token for future requests using OAuth2 compatible form. """ user = crud.user.authenticate( db, email=form_data.username, password=form_data.password ) if not user: raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="Incorrect email or password", headers={"WWW-Authenticate": "Bearer"}, ) if not crud.user.is_active(user): raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail="Inactive user", ) access_token_expires = timedelta(minutes=settings.ACCESS_TOKEN_EXPIRE_MINUTES) access_token = security.create_access_token( user.id, expires_delta=access_token_expires ) return { "access_token": access_token, "token_type": "bearer", } @router.post("/login/json", response_model=TokenResponse) def login_json( login_data: Login, db: Session = Depends(deps.get_db), ) -> Any: """ Get an access token for future requests using JSON body. """ user = crud.user.authenticate( db, email=login_data.email, password=login_data.password ) if not user: raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="Incorrect email or password", headers={"WWW-Authenticate": "Bearer"}, ) if not crud.user.is_active(user): raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail="Inactive user", ) access_token_expires = timedelta(minutes=settings.ACCESS_TOKEN_EXPIRE_MINUTES) access_token = security.create_access_token( user.id, expires_delta=access_token_expires ) return { "access_token": access_token, "token_type": "bearer", } @router.post("/register", response_model=User) def register( user_in: UserCreate, db: Session = Depends(deps.get_db), ) -> Any: """ Register a new user. """ user = crud.user.get_by_email(db, email=user_in.email) if user: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail="Email already registered", ) user = crud.user.get_by_username(db, username=user_in.username) if user: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail="Username already registered", ) user = crud.user.create(db, obj_in=user_in) return user @router.get("/me", response_model=User) def read_users_me( current_user: User = Depends(deps.get_current_active_user), ) -> Any: """ Get the current user. """ return current_user