fakeshield-api / backend /app /dependencies.py
Akash4911's picture
Deploy backend updates
33ad6db
Raw
History Blame Contribute Delete
3.25 kB
from fastapi import Header, HTTPException, Depends
import jwt
import os
from datetime import datetime, timezone
from app.database import users_collection
SECRET_KEY = os.getenv("JWT_SECRET", "super-secret-fakeshield-key-for-project")
ALGORITHM = "HS256"
def _as_utc_datetime(value):
if value is None:
return None
if isinstance(value, datetime):
return value.replace(tzinfo=timezone.utc) if value.tzinfo is None else value.astimezone(timezone.utc)
if isinstance(value, str):
try:
normalized = value.replace("Z", "+00:00")
parsed = datetime.fromisoformat(normalized)
return parsed.replace(tzinfo=timezone.utc) if parsed.tzinfo is None else parsed.astimezone(timezone.utc)
except ValueError:
return None
return None
def is_subscription_active(user: dict) -> bool:
if user.get("subscription_tier") != "paid":
return False
expires_at = _as_utc_datetime(user.get("subscription_expires_at"))
if not expires_at:
return False
return expires_at > datetime.now(timezone.utc)
def serialize_subscription_expires_at(user: dict):
expires_at = _as_utc_datetime(user.get("subscription_expires_at"))
return expires_at.isoformat().replace("+00:00", "Z") if expires_at else None
def public_user_payload(user: dict) -> dict:
active = is_subscription_active(user)
return {
"name": user.get("fullName") or user.get("name") or user.get("full_name"),
"email": user.get("email"),
"subscription_tier": "paid" if active else "free",
"subscription_expires_at": serialize_subscription_expires_at(user) if active else None,
"profile_pic": user.get("profile_pic"),
}
async def get_current_user(authorization: str = Header(None)):
if not authorization:
raise HTTPException(status_code=401, detail="Authorization header missing")
try:
token = authorization.replace("Bearer ", "")
payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
email = payload.get("sub")
if email is None:
raise HTTPException(status_code=401, detail="Invalid token")
except jwt.PyJWTError:
raise HTTPException(status_code=401, detail="Invalid token")
try:
user = await users_collection.find_one({"email": email})
if user is None:
print(f"[AUTH] User {email} not in DB. Granting limited guest access.")
return {
"email": email,
"full_name": "Guest User",
"subscription_tier": "free",
"is_offline": True
}
return user
except Exception as e:
print(f"[AUTH] DB Error during auth: {e}. Granting limited guest access.")
return {
"email": email,
"full_name": "Offline Tester",
"subscription_tier": "free",
"is_offline": True
}
async def verify_paid_tier(user: dict = Depends(get_current_user)):
if not is_subscription_active(user):
raise HTTPException(
status_code=403,
detail="This feature requires an active Pro subscription. Please upgrade to access."
)
return user