You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
70 lines
2.0 KiB
70 lines
2.0 KiB
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 |