This commit is contained in:
2024-03-27 20:00:59 +03:00
parent f92171ff84
commit 717596f55c
12 changed files with 226 additions and 133 deletions

View File

@ -1,11 +1,18 @@
from fastapi import APIRouter, Depends, FastAPI, HTTPException, status
from datetime import datetime, timedelta, timezone
from typing import Annotated, Union
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
from sqlalchemy.orm import Session
from . import crud
from fastapi import APIRouter, Depends, HTTPException, status
from fastapi.security import OAuth2PasswordRequestForm
from pydantic import BaseModel
from ...config import jwt_config
from ...dependencies import get_db
from ...db import schemas
from . import schemas
from . import services
router = APIRouter(
prefix="/auth",
@ -13,92 +20,57 @@ router = APIRouter(
dependencies=[Depends(get_db)],
responses={404: {"description": "Not found"}},
)
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
@router.post("/users/", response_model=schemas.User)
def create_user(user: schemas.UserCreate, db: Session = Depends(get_db)):
db_user = crud.get_user_by_email(db, email=user.email)
if db_user:
raise HTTPException(status_code=400, detail="Email already registered")
return crud.create_user(db=db, user=user)
@router.get("/", response_model=list[schemas.User])
def read_users(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
users = crud.get_users(db, skip=skip, limit=limit)
return users
@router.get("/users/{user_id}", response_model=schemas.User)
def read_user(user_id: int, db: Session = Depends(get_db)):
db_user = crud.get_user(db, user_id=user_id)
if db_user is None:
raise HTTPException
def fake_hash_password(password: str):
return "fakehashed" + password
class User(BaseModel):
username: str
email: Union[str, None] = None
full_name: Union[str, None] = None
disabled: Union[bool, None] = None
class UserInDB(User):
hashed_password: str
def get_user(db, username: str):
if username in db:
user_dict = db[username]
return UserInDB(**user_dict)
def fake_decode_token(token):
# This doesn't provide any security at all
# Check the next version
user = get_user(fake_users_db, token)
return user
async def get_current_user(token: Annotated[str, Depends(oauth2_scheme)]):
user = fake_decode_token(token)
@router.post("/token")
async def login_for_access_token(
form_data: Annotated[OAuth2PasswordRequestForm, Depends()],
db: Annotated[Session, Depends(get_db)],
) -> schemas.Token:
user = services.authenticate_user(db, form_data.username, form_data.password)
if not user:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Invalid authentication credentials",
status_code=status.HTTP_409_CONFLICT,
detail="Incorrect username or password",
headers={"WWW-Authenticate": "Bearer"},
)
access_token_expires = timedelta(minutes=jwt_config.ACCESS_TOKEN_EXPIRE_MINUTES)
access_token = services.create_access_token(
data={"sub": user.username}, expires_delta=access_token_expires
)
return schemas.Token(access_token=access_token, token_type="bearer")
@router.post("/register")
async def register(
user_data: Annotated[schemas.UserRegister, Depends()],
db: Annotated[Session, Depends(get_db)],
) -> schemas.User:
user = services.get_user_by_username(db, user_data.username)
if user:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="User with this username already exists",
headers={"WWW-Authenticate": "Bearer"},
)
user = services.create_user(
db=db,
username=user_data.username,
plain_password=user_data.password,
name=user_data.name,
)
return user
async def get_current_active_user(
current_user: Annotated[User, Depends(get_current_user)],
):
if current_user.disabled:
raise HTTPException(status_code=400, detail="Inactive user")
return current_user
@app.post("/token")
async def login(form_data: Annotated[OAuth2PasswordRequestForm, Depends()]):
user_dict = fake_users_db.get(form_data.username)
if not user_dict:
raise HTTPException(status_code=400, detail="Incorrect username or password")
user = UserInDB(**user_dict)
hashed_password = fake_hash_password(form_data.password)
if not hashed_password == user.hashed_password:
raise HTTPException(status_code=400, detail="Incorrect username or password")
return {"access_token": user.username, "token_type": "bearer"}
@app.get("/users/me")
@router.get("/users/me/", response_model=schemas.User)
async def read_users_me(
current_user: Annotated[User, Depends(get_current_active_user)],
current_user: Annotated[schemas.User, Depends(services.get_current_active_user)],
):
return current_user
# @app.get("/users/me/items/")
# async def read_own_items(
# current_user: Annotated[User, Depends(get_current_active_user)],
# ):
# return [{"item_id": "Foo", "owner": current_user.username}]