diff --git a/app/main.py b/app/main.py index a50b2c5..28a1294 100644 --- a/app/main.py +++ b/app/main.py @@ -1,11 +1,12 @@ from fastapi import FastAPI -from .routers import users +from .routers import users, token app = FastAPI() app.include_router(users.router) +app.include_router(token.router) @app.get("/") async def root(): diff --git a/app/models/token.py b/app/models/token.py new file mode 100644 index 0000000..c3c0548 --- /dev/null +++ b/app/models/token.py @@ -0,0 +1,9 @@ +from pydantic import BaseModel + +class Token(BaseModel): + access_token: str + token_type: str + + +class TokenData(BaseModel): + username: str | None = None \ No newline at end of file diff --git a/app/models/users.py b/app/models/users.py index e1b9b4d..1888557 100644 --- a/app/models/users.py +++ b/app/models/users.py @@ -5,7 +5,7 @@ class User(BaseModel): id: int username: str password: str - permissions: list[str] = [] + roles: str class UserInDB(User): password: str \ No newline at end of file diff --git a/app/routers/token.py b/app/routers/token.py new file mode 100644 index 0000000..1995ad9 --- /dev/null +++ b/app/routers/token.py @@ -0,0 +1,25 @@ +from typing import Annotated +from fastapi import Depends, FastAPI, HTTPException, status, APIRouter +from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm +from ..dependencies import fake_users, authenticate_user +from ..models import token + +router = APIRouter() + + +@router.post("/token", response_model=token.Token, tags=["token"]) +async def login_for_access_token( + form_data: Annotated[OAuth2PasswordRequestForm, Depends()] +): + user = authenticate_user(fake_users, form_data.username, form_data.password) + if not user: + raise HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, + detail="Incorrect username or password", + headers={"WWW-Authenticate": "Bearer"}, + ) + access_token_expires = timedelta(minutes=dependencies.ACCESS_TOKEN_EXPIRE_MINUTES) + access_token = create_access_token( + data={"sub": user.username}, expires_delta=access_token_expires + ) + return {"access_token": access_token, "token_type": "bearer"} \ No newline at end of file diff --git a/app/routers/users.py b/app/routers/users.py index 2dabaa1..079de7b 100644 --- a/app/routers/users.py +++ b/app/routers/users.py @@ -1,14 +1,6 @@ from fastapi import APIRouter +from ..models import users -fake_users = [ - # password foo - {'id': 1, 'username': 'admin', 'password': '$2b$12$N.i74Kle18n5Toxhas.rVOjZreVC2WM34fCidNDyhSNgxVlbKwX7i', - 'permissions': ['items:read', 'items:write', 'users:read', 'users:write'] - }, - # password bar - {'id': 2, 'username': 'client', 'password': '$2b$12$KUgpw1m0LF/s9NS1ZB5rRO2cA5D13MqRm56ab7ik2ixftXW/aqEyq', - 'permissions': ['items:read']} -] router = APIRouter() diff --git a/requierements.txt b/requierements.txt index 13a6b2c..5bd6d38 100644 --- a/requierements.txt +++ b/requierements.txt @@ -1,3 +1,6 @@ fastapi uvicorn[standard] -pydantic-mongo \ No newline at end of file +pydantic-mongo +python-jose[cryptography] +passlib[bcrypt] +python-multipart \ No newline at end of file