feat: add authentication for administration #2

Merged
agatha merged 9 commits from feature-auth into dev 2024-04-06 19:56:48 +00:00
2 changed files with 26 additions and 6 deletions
Showing only changes of commit 353218aca7 - Show all commits

View File

@ -5,3 +5,4 @@ passlib[bcrypt]
pydantic pydantic
starlette starlette
python-multipart python-multipart
python-jose[cryptography]

View File

@ -1,3 +1,4 @@
from datetime import timedelta, datetime
from typing import Annotated from typing import Annotated
from fastapi import APIRouter, Depends from fastapi import APIRouter, Depends
from pydantic import BaseModel from pydantic import BaseModel
@ -5,12 +6,16 @@ from passlib.context import CryptContext
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from starlette import status from starlette import status
from fastapi.security import OAuth2PasswordRequestForm from fastapi.security import OAuth2PasswordRequestForm
from jose import jwt
from models import User from models import User
from database import SessionLocal from database import SessionLocal
router = APIRouter() router = APIRouter()
SECRET_KEY = '3b004eeae34b43bd05226f210d9bdc2ad99abdd3c52bf32802906085b762ff55'
ALGORITHM = 'HS256'
bcrypt_context = CryptContext(schemes=['bcrypt'], deprecated='auto') bcrypt_context = CryptContext(schemes=['bcrypt'], deprecated='auto')
@ -31,7 +36,15 @@ def authenticate_user(username: str, password: str, db):
return False return False
if not bcrypt_context.verify(password, user.password): if not bcrypt_context.verify(password, user.password):
return False return False
return True return user
def create_access_token(username: str, user_id: int, expires_delta: timedelta):
encode = {'sub': username, 'id': user_id}
expire = datetime.now() + expires_delta
encode.update({'exp': expire})
return jwt.encode(encode, SECRET_KEY, ALGORITHM)
class CreateUser(BaseModel): class CreateUser(BaseModel):
@ -40,6 +53,11 @@ class CreateUser(BaseModel):
password: str password: str
class Token(BaseModel):
access_token: str
token_type: str
@router.post('/auth/create', status_code=status.HTTP_201_CREATED) @router.post('/auth/create', status_code=status.HTTP_201_CREATED)
async def create_user(db: db_dependency, data: CreateUser): async def create_user(db: db_dependency, data: CreateUser):
create_user_model = User( create_user_model = User(
@ -53,13 +71,14 @@ async def create_user(db: db_dependency, data: CreateUser):
db.commit() db.commit()
@router.post('/auth/token', status_code=status.HTTP_200_OK) @router.post('/auth/token', status_code=status.HTTP_200_OK, response_model=Token)
async def get_token( async def get_token(
form_data: Annotated[OAuth2PasswordRequestForm, Depends()], form_data: Annotated[OAuth2PasswordRequestForm, Depends()],
db: db_dependency db: db_dependency
): ):
user = authenticate_user(form_data.username, form_data.password, db) user = authenticate_user(form_data.username, form_data.password, db)
if user: if not user:
return "you good fam" return "authentication failed"
return "failed authentication" token = create_access_token(user.username, user.id, timedelta(minutes=20))
return {'access_token': token, 'token_type': 'bearer'}