Files
2026-06-18 12:25:44 -05:00

59 lines
2.0 KiB
Python

import os
import bcrypt
from datetime import datetime, timedelta, timezone
from typing import Optional
from jose import JWTError, jwt
from fastapi import Depends, HTTPException, Request, status
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
# ponytail: fallback inseguro — set RIPS_SECRET_KEY en producción
SECRET_KEY = os.environ.get("RIPS_SECRET_KEY", "rips-manager-secret-key-change-in-production")
ALGORITHM = "HS256"
ACCESS_TOKEN_EXPIRE_HOURS = 12
security = HTTPBearer(auto_error=False)
def hash_password(password: str) -> str:
return bcrypt.hashpw(password.encode(), bcrypt.gensalt()).decode()
def verify_password(password: str, password_hash: str) -> bool:
return bcrypt.checkpw(password.encode(), password_hash.encode())
def create_token(user_id: int, username: str) -> str:
payload = {
"user_id": user_id,
"username": username,
"exp": datetime.now(timezone.utc) + timedelta(hours=ACCESS_TOKEN_EXPIRE_HOURS),
}
return jwt.encode(payload, SECRET_KEY, algorithm=ALGORITHM)
def decode_token(token: str) -> Optional[dict]:
try:
payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
return payload
except JWTError:
return None
def get_current_user(request: Request, credentials: HTTPAuthorizationCredentials = Depends(security)):
if hasattr(request.state, "user") and request.state.user:
return request.state.user
if credentials is None:
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Not authenticated")
payload = decode_token(credentials.credentials)
if payload is None:
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid token")
return payload
def optional_user(request: Request, credentials: HTTPAuthorizationCredentials = Depends(security)):
if hasattr(request.state, "user") and request.state.user:
return request.state.user
if credentials is None:
return None
return decode_token(credentials.credentials)