from typing import Annotated from datetime import datetime, timezone from datetime import datetime, timedelta from fastapi import Depends, HTTPException, status, Cookie from fastapi.security import OAuth2PasswordBearer from passlib.context import CryptContext from jose import jwt from jose.exceptions import JWTError from pydantic import ValidationError from service.schemas import TokenData, UserData from service.db_requests import get_user reuseable_oauth = OAuth2PasswordBearer( tokenUrl="login", scheme_name="JWT" ) ACCESS_TOKEN_EXPIRE_MINUTES = 60 * 24 * 7 ALGORITHM = "HS256" JWT_SECRET_KEY = "CHAGEME" password_context = CryptContext(schemes=["bcrypt"], deprecated="auto") def hash_password(password): return password_context.hash(password) def verify_password(password, hashed_pass): return password_context.verify(password, hashed_pass) def create_access_token(subject): expires_delta = datetime.now() + timedelta(minutes= ACCESS_TOKEN_EXPIRE_MINUTES) to_encode = {"exp": expires_delta, "sub": str(subject)} encoded_jwt = jwt.encode(to_encode, JWT_SECRET_KEY, ALGORITHM) return encoded_jwt async def get_current_user(access_token = Cookie()) -> UserData: try: data = jwt.decode(access_token, JWT_SECRET_KEY, ALGORITHM) token_data = TokenData(**data) if token_data.exp < datetime.now(timezone.utc): raise HTTPException( status_code = status.HTTP_401_UNAUTHORIZED, detail="Token expired", headers={"WWW-Authenticate": "Bearer"}, ) except(JWTError, ValidationError): raise HTTPException( status_code=status.HTTP_403_FORBIDDEN, detail="Could not validate credentials", headers={"WWW-Authenticate": "Bearer"}, ) user = get_user(token_data.sub) if user is None: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="Could not find user", ) return user