59 lines
2.2 KiB
Python
59 lines
2.2 KiB
Python
from fastapi import Depends, HTTPException, status
|
|
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
|
|
from sqlalchemy.orm import Session
|
|
from redis import Redis
|
|
from app.core.db import get_db
|
|
from app.core.security import decode_token
|
|
from app.core.redis import get_redis
|
|
from app.models import User
|
|
from app.models.enums import StatusEnum
|
|
|
|
|
|
bearer_scheme = HTTPBearer()
|
|
|
|
|
|
def get_current_user(
|
|
creds: HTTPAuthorizationCredentials = Depends(bearer_scheme),
|
|
db: Session = Depends(get_db),
|
|
redis: Redis = Depends(get_redis),
|
|
) -> User:
|
|
token = creds.credentials
|
|
try:
|
|
payload = decode_token(token)
|
|
except ValueError:
|
|
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid token")
|
|
|
|
if payload.get("type") != "access":
|
|
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid token")
|
|
|
|
user_id = payload.get("sub")
|
|
# Enforce redis-backed online session; if missing, force re-login
|
|
online_key = f"auth:online:{user_id}"
|
|
if not redis.exists(online_key):
|
|
# Fallback: if refresh token exists for this user, recreate online key
|
|
cursor = 0
|
|
found_ttl = None
|
|
while True:
|
|
cursor, keys = redis.scan(cursor=cursor, match="auth:refresh:*", count=200)
|
|
for key in keys:
|
|
try:
|
|
val = redis.get(key)
|
|
if val == str(user_id):
|
|
ttl = redis.ttl(key)
|
|
if ttl and ttl > 0:
|
|
found_ttl = ttl
|
|
break
|
|
except Exception:
|
|
continue
|
|
if found_ttl is not None or cursor == 0:
|
|
break
|
|
if found_ttl is not None:
|
|
redis.setex(online_key, found_ttl, "1")
|
|
else:
|
|
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Session expired")
|
|
user = db.query(User).filter(User.user_id == int(user_id), User.is_deleted.is_(False)).first()
|
|
if not user or user.status != int(StatusEnum.ENABLED):
|
|
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="User disabled")
|
|
|
|
return user
|