File size: 2,317 Bytes
d57efd6
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
from fastapi import APIRouter, Depends
from fastapi.responses import JSONResponse
from fastapi.security import OAuth2PasswordBearer
from dotenv import load_dotenv

from sqlalchemy.orm import Session
from db.models import User
from starlette import status
from datetime import timedelta, datetime, timezone
from db.database import get_db
from passlib.context import CryptContext
from typing import Annotated
from jose import jwt, JWTError
import os

load_dotenv()

oauth2_scheme = OAuth2PasswordBearer(tokenUrl="login")

# Custom OAuth2 request form to accept email, username, password, and role_id
router = APIRouter(prefix="/auth", tags=["auth"])

SECRET_KEY = os.getenv("SECRET_KEY")
ALGORITHM = "HS256"

bcrypt_context = CryptContext(schemes=["bcrypt"], deprecated="auto")

# Database dependency
db_dependency = Annotated[Session, Depends(get_db)]


def authenticate_user(email: str, password: str, db):
    user = db.query(User).filter(User.email == email).first()
    if not user:
        return False

    if not bcrypt_context.verify(password, user.hashed_password):
        return False
    return user


def create_access_token(
    username: str, name: str, user_id: int, role_id: int, expires_delta: timedelta, email: str
):
    encode = {"sub": username, "name":name, "id": user_id, "role_id": role_id, "email": email}
    expires = datetime.now(timezone.utc) + expires_delta
    encode.update({"exp": expires})
    return jwt.encode(encode, SECRET_KEY, algorithm=ALGORITHM)


async def get_current_user(token: Annotated[str, Depends(oauth2_scheme)]):
    try:
        payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
        username: str = payload.get("sub")
        name: str = payload.get("name")
        user_id: int = payload.get("id")
        role_id: int = payload.get("role_id")
        email: str = payload.get("email")

        if username is None or user_id is None:
            return JSONResponse(
                status_code=status.HTTP_401_UNAUTHORIZED,
                content="Could not validate user.",
            )

        return {"username": username, "name" : name, "id": user_id, "role_id": role_id, "email": email}

    except JWTError:
        return JSONResponse(
            status_code=status.HTTP_401_UNAUTHORIZED, content="Could not validate user."
        )