from typing import Annotated from fastapi import Depends, Header, HTTPException, status from sqlalchemy import select from sqlalchemy.ext.asyncio import AsyncSession from models import Role, User, get_db from security import decode_token # Eski davranışla uyumluluk: bu hesaplar rol atanmasa da tam yetkili. LEGACY_ADMIN_EMAILS = {"jts@jts.rocks", "afm@jts.rocks"} # Panel izin kataloğu (kullanıcı yönetimi UI'ı buradan okur) PERMISSIONS = { "upload": "Dosya yükleme + Asset Takip", "lore": "Lore notları (görme + ekleme + düzenleme)", "map_view": "Harita editörünü görüntüleme (salt okunur)", "npc": "NPC listesi (görme + ekleme + düzenleme)", "map_edit": "Harita etiketi ekleme / düzenleme / silme", "chars": "Karakterler (sınıf + skill tanımları)", "users": "Kullanıcı ve rol yönetimi", } async def get_user_perms(user: User, db: AsyncSession) -> set[str]: if user.email in LEGACY_ADMIN_EMAILS: return {"*"} if not user.role_id: return set() role = (await db.execute(select(Role).where(Role.id == user.role_id))).scalar_one_or_none() return set(role.permissions or []) if role else set() def has_perm(perms: set[str], perm: str) -> bool: return "*" in perms or perm in perms def require_perm(perm: str): async def dep( user: User = Depends(get_current_user), db: AsyncSession = Depends(get_db), ) -> User: perms = await get_user_perms(user, db) if not has_perm(perms, perm): raise HTTPException(status.HTTP_403_FORBIDDEN, "Yetkin yok") return user return dep async def get_current_user( authorization: Annotated[str | None, Header()] = None, db: AsyncSession = Depends(get_db), ) -> User: if not authorization or not authorization.lower().startswith("bearer "): raise HTTPException(status.HTTP_401_UNAUTHORIZED, "Missing bearer token") token = authorization.split(None, 1)[1].strip() try: payload = decode_token(token) except Exception as e: raise HTTPException(status.HTTP_401_UNAUTHORIZED, f"Invalid token: {e}") user_id = int(payload["sub"]) user = (await db.execute(select(User).where(User.id == user_id))).scalar_one_or_none() if not user or not user.is_active: raise HTTPException(status.HTTP_401_UNAUTHORIZED, "User not found or inactive") return user async def require_panel( user: User = Depends(get_current_user), db: AsyncSession = Depends(get_db), ) -> User: """Herhangi bir panel yetkisi olan (bir rolü/izni bulunan) her yetkili.""" perms = await get_user_perms(user, db) if not perms: raise HTTPException(status.HTTP_403_FORBIDDEN, "Panel yetkin yok") return user