feat: add check_permission, get_current_user_optional, require_permission
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
from typing import Callable
|
||||
|
||||
from fastapi import Depends, HTTPException, Request
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
@@ -11,6 +13,44 @@ class RequiresLoginException(Exception):
|
||||
pass
|
||||
|
||||
|
||||
def check_permission(user: User | None, permissions: list[str]) -> bool:
|
||||
if "public" in permissions:
|
||||
return True
|
||||
if user is None:
|
||||
return False
|
||||
if "authenticated" in permissions:
|
||||
return True
|
||||
if "admin" in permissions and user.is_admin:
|
||||
return True
|
||||
return False # group membership check: Part 2
|
||||
|
||||
|
||||
async def get_current_user_optional(
|
||||
request: Request, db: Session = Depends(get_db)
|
||||
) -> User | None:
|
||||
token = get_token_from_request(request)
|
||||
if not token:
|
||||
return None
|
||||
payload = decode_token(token)
|
||||
if not payload:
|
||||
return None
|
||||
user = get_user(db, payload.get("sub", ""))
|
||||
if user is None or not user.is_active:
|
||||
return None
|
||||
return user
|
||||
|
||||
|
||||
def require_permission(permissions: list[str]) -> Callable:
|
||||
async def _dep(
|
||||
request: Request, db: Session = Depends(get_db)
|
||||
) -> User | None:
|
||||
user = await get_current_user_optional(request, db)
|
||||
if not check_permission(user, permissions):
|
||||
raise RequiresLoginException()
|
||||
return user
|
||||
return _dep
|
||||
|
||||
|
||||
async def get_current_user(
|
||||
request: Request, db: Session = Depends(get_db)
|
||||
) -> User:
|
||||
|
||||
Reference in New Issue
Block a user