Add independent payment-service (port 8012, payment_db) with foundation licensing, BYO-PSP, merchant accounts, idempotent requests, callbacks, and immutable ledger. Co-authored-by: Cursor <cursoragent@cursor.com>
42 lines
1.3 KiB
Python
42 lines
1.3 KiB
Python
from fastapi import Depends
|
|
|
|
from app.core.config import settings
|
|
from app.core.security import get_current_user
|
|
from shared.exceptions import ForbiddenError
|
|
|
|
_ADMINS = {"platform_admin", "tenant_owner", "tenant_admin"}
|
|
|
|
|
|
def user_has_permission(user, permission: str) -> bool:
|
|
roles = set(user.roles)
|
|
if roles & _ADMINS or "payment.*" in roles:
|
|
return True
|
|
if permission in roles:
|
|
return True
|
|
parts = permission.split(".")
|
|
return len(parts) >= 3 and f"{parts[0]}.{parts[1]}.manage" in roles
|
|
|
|
|
|
def require_permissions(*permissions: str):
|
|
async def dependency(user=Depends(get_current_user)):
|
|
if not settings.auth_required or any(
|
|
user_has_permission(user, permission) for permission in permissions
|
|
):
|
|
return user
|
|
raise ForbiddenError(
|
|
"Permission denied",
|
|
error_code="permission_denied",
|
|
details={"required": list(permissions)},
|
|
)
|
|
|
|
return dependency
|
|
|
|
|
|
async def require_payment_access(user=Depends(get_current_user)):
|
|
if not settings.auth_required:
|
|
return user
|
|
roles = set(user.roles)
|
|
if roles & _ADMINS or any(role.startswith("payment.") for role in roles):
|
|
return user
|
|
raise ForbiddenError("Permission denied", error_code="permission_denied")
|