İlk commit: Stepstead backend (FastAPI)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
commit
ea049b8ccd
45 changed files with 6751 additions and 0 deletions
76
deps.py
Normal file
76
deps.py
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
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
|
||||
Loading…
Add table
Add a link
Reference in a new issue