음성 재생과 운영 배포 정리
This commit is contained in:
parent
8ed185ce6c
commit
ac7db95542
1020 changed files with 46863 additions and 2175 deletions
|
|
@ -6,8 +6,9 @@ from enum import Enum
|
|||
from typing import Annotated, AsyncIterator, Optional
|
||||
|
||||
import asyncpg
|
||||
from fastapi import Cookie, Depends, HTTPException, status
|
||||
from fastapi import Cookie, Depends, HTTPException, Request, status
|
||||
|
||||
from .auth_types import AccountStatus
|
||||
from .auth_sessions import get_session
|
||||
from .config import Settings, get_settings
|
||||
from .db import acquire
|
||||
|
|
@ -32,17 +33,48 @@ class Principal:
|
|||
self,
|
||||
user_id: str,
|
||||
role: Role,
|
||||
admin_access: bool = False,
|
||||
super_admin: bool = False,
|
||||
account_status: AccountStatus = "approved",
|
||||
cohort_ids: Optional[list[str]] = None,
|
||||
email: str = "",
|
||||
display_name: str = "",
|
||||
consent_at: float | None = None,
|
||||
profile_completed_at: float | None = None,
|
||||
) -> None:
|
||||
self.user_id = user_id
|
||||
self.role = role
|
||||
self.admin_access = admin_access
|
||||
self.super_admin = super_admin
|
||||
self.account_status = account_status
|
||||
self.cohort_ids = cohort_ids or []
|
||||
self.email = email
|
||||
self.display_name = display_name
|
||||
self.consent_at = consent_at
|
||||
self.profile_completed_at = profile_completed_at
|
||||
|
||||
def can_access_role(self, role: Role) -> bool:
|
||||
if self.role == role:
|
||||
return True
|
||||
if self.super_admin:
|
||||
return True
|
||||
if role == Role.ADMIN:
|
||||
return self.admin_access
|
||||
return False
|
||||
|
||||
def with_role(self, role: Role) -> "Principal":
|
||||
return Principal(
|
||||
user_id=self.user_id,
|
||||
role=role,
|
||||
admin_access=self.admin_access,
|
||||
super_admin=self.super_admin,
|
||||
account_status=self.account_status,
|
||||
cohort_ids=list(self.cohort_ids),
|
||||
email=self.email,
|
||||
display_name=self.display_name,
|
||||
consent_at=self.consent_at,
|
||||
profile_completed_at=self.profile_completed_at,
|
||||
)
|
||||
|
||||
|
||||
def get_settings_dep() -> Settings:
|
||||
|
|
@ -50,6 +82,7 @@ def get_settings_dep() -> Settings:
|
|||
|
||||
|
||||
async def get_current_principal(
|
||||
request: Request,
|
||||
session_cookie: Annotated[Optional[str], Cookie(alias="__Host-vignette_sid")] = None,
|
||||
dev_session_cookie: Annotated[Optional[str], Cookie(alias="vignette_sid")] = None,
|
||||
) -> Principal:
|
||||
|
|
@ -70,13 +103,23 @@ async def get_current_principal(
|
|||
detail="invalid session role",
|
||||
) from exc
|
||||
|
||||
if session.account_status != "approved" and request.url.path != "/auth/me":
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_403_FORBIDDEN,
|
||||
detail=f"account_{session.account_status}",
|
||||
)
|
||||
|
||||
return Principal(
|
||||
user_id=session.user_id,
|
||||
role=role,
|
||||
admin_access=session.admin_access,
|
||||
super_admin=session.super_admin,
|
||||
account_status=session.account_status,
|
||||
cohort_ids=session.cohort_ids,
|
||||
email=session.email,
|
||||
display_name=session.display_name,
|
||||
consent_at=session.consent_at,
|
||||
profile_completed_at=session.profile_completed_at,
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -86,10 +129,29 @@ def require_role(*allowed: Role):
|
|||
async def _checker(
|
||||
principal: Annotated[Principal, Depends(get_current_principal)],
|
||||
) -> Principal:
|
||||
if principal.role not in allowed:
|
||||
if principal.role in allowed:
|
||||
return principal
|
||||
if principal.super_admin:
|
||||
effective = Role.ADMIN if Role.ADMIN in allowed else allowed[0]
|
||||
return principal.with_role(effective)
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_403_FORBIDDEN,
|
||||
detail=f"role {principal.role.value} not permitted",
|
||||
)
|
||||
|
||||
return _checker
|
||||
|
||||
|
||||
def require_admin_access():
|
||||
"""기본 역할과 별개로 관리자 권한을 가진 사용자만 통과시킨다."""
|
||||
|
||||
async def _checker(
|
||||
principal: Annotated[Principal, Depends(get_current_principal)],
|
||||
) -> Principal:
|
||||
if not principal.admin_access:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_403_FORBIDDEN,
|
||||
detail=f"role {principal.role.value} not permitted",
|
||||
detail="admin access required",
|
||||
)
|
||||
return principal
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue