Files
contexta_be/app/dependencies.py
belviskhoremk 9dccc83293 updates Mar6
2026-03-06 22:37:40 +00:00

83 lines
2.6 KiB
Python

from fastapi import Depends, HTTPException, status, Header
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
from typing import Optional
from app.database import get_supabase
from app.config import settings
import logging
logger = logging.getLogger(__name__)
security = HTTPBearer(auto_error=False)
async def get_current_user(
credentials: Optional[HTTPAuthorizationCredentials] = Depends(security),
):
"""Extract and verify the current user from Supabase JWT"""
if not credentials:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Not authenticated",
)
token = credentials.credentials
supabase = get_supabase()
try:
response = supabase.auth.get_user(token)
if not response or not response.user:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Invalid or expired token",
)
return response.user
except Exception as e:
logger.error(f"Auth error: {e}")
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Invalid or expired token",
)
async def get_optional_user(
credentials: Optional[HTTPAuthorizationCredentials] = Depends(security),
):
"""Optional auth - returns None if not authenticated"""
if not credentials:
return None
try:
return await get_current_user(credentials)
except HTTPException:
return None
async def get_user_subscription(user=Depends(get_current_user)):
"""Get user's subscription plan"""
supabase = get_supabase()
try:
result = (
supabase.table("subscriptions")
.select("*")
.eq("user_id", user.id)
.eq("status", "active")
.execute()
)
if result.data:
return result.data[0]
return {"plan": "free", "status": "active", "user_id": user.id}
except Exception:
return {"plan": "free", "status": "active", "user_id": user.id}
async def require_plan(min_plan: str, user=Depends(get_current_user)):
"""Require a minimum plan level"""
plan_order = ["free", "starter", "business", "agency", "enterprise"]
subscription = await get_user_subscription(user)
user_plan = subscription.get("plan", "free")
if plan_order.index(user_plan) < plan_order.index(min_plan):
raise HTTPException(
status_code=status.HTTP_402_PAYMENT_REQUIRED,
detail=f"This feature requires {min_plan} plan or higher",
)
return user