mirror of
https://github.com/fastapi-admin/fastapi-admin.git
synced 2026-03-13 10:32:25 +08:00
Simplified "has permission" logic and fixed a major flow in "{resoruce}/grid" not applying correct data to _actions
Function has_resource_permission() need to live in depends.py as it cause circular dependencies if in common.py
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import importlib
|
||||
from copy import deepcopy
|
||||
|
||||
from fastapi import HTTPException
|
||||
from passlib.context import CryptContext
|
||||
from tortoise import Tortoise
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ from starlette.status import HTTP_401_UNAUTHORIZED, HTTP_403_FORBIDDEN, HTTP_404
|
||||
|
||||
from . import enums
|
||||
from .factory import app
|
||||
from .models import AbstractUser
|
||||
|
||||
auth_schema = HTTPBearer()
|
||||
|
||||
@@ -137,21 +138,12 @@ class HasPermission:
|
||||
def __init__(self, action: enums.PermissionAction):
|
||||
self.action = action
|
||||
|
||||
async def __call__(self, resource: str = Path(...), user=Depends(get_current_user)):
|
||||
if not app.permission or user.is_superuser:
|
||||
return True # Hmm. Should superuser really cirumvent all permission checks. not a good practice!?!?!?!!?!!!
|
||||
if not user.is_active:
|
||||
return False
|
||||
has_permission = False
|
||||
await user.fetch_related("roles")
|
||||
for role in user.roles:
|
||||
if await role.permissions.filter(model=resource, action=self.action):
|
||||
return True
|
||||
if not has_permission:
|
||||
return False
|
||||
|
||||
|
||||
has_read_permission = HasPermission(action=enums.PermissionAction.read)
|
||||
has_create_permission = HasPermission(action=enums.PermissionAction.create)
|
||||
has_update_permission = HasPermission(action=enums.PermissionAction.update)
|
||||
has_delete_permission = HasPermission(action=enums.PermissionAction.delete)
|
||||
async def has_resource_permission(
|
||||
action: enums.PermissionAction, resource: str, user: AbstractUser
|
||||
) -> bool:
|
||||
try:
|
||||
await PermissionsChecker(action=action)(resource, user)
|
||||
return True
|
||||
except HTTPException:
|
||||
return False
|
||||
|
||||
@@ -12,6 +12,7 @@ from tortoise.contrib.pydantic import pydantic_model_creator
|
||||
from tortoise.exceptions import IntegrityError
|
||||
from tortoise.fields import ManyToManyRelation
|
||||
|
||||
from .. import enums
|
||||
from ..common import handle_m2m_fields_create_or_update
|
||||
from ..depends import (
|
||||
QueryItem,
|
||||
@@ -23,10 +24,7 @@ from ..depends import (
|
||||
get_current_user,
|
||||
get_model,
|
||||
get_query,
|
||||
has_create_permission,
|
||||
has_delete_permission,
|
||||
has_read_permission,
|
||||
has_update_permission,
|
||||
has_resource_permission,
|
||||
parse_body,
|
||||
read_checker,
|
||||
update_checker,
|
||||
@@ -129,14 +127,16 @@ async def form(resource: str,):
|
||||
|
||||
@router.get("/{resource}/grid", dependencies=[Depends(read_checker)])
|
||||
async def grid(resource: str, user=Depends(get_current_user)):
|
||||
resource = await app.get_resource(resource)
|
||||
resource = resource.dict(by_alias=True, exclude_unset=True)
|
||||
resource["fields"]["_actions"] = {
|
||||
"delete": await has_delete_permission(resource, user),
|
||||
"edit": await has_update_permission(resource, user),
|
||||
"toolbar": {"create": await has_create_permission(resource, user)},
|
||||
fetched_resource = await app.get_resource(resource)
|
||||
resource_response = fetched_resource.dict(by_alias=True, exclude_unset=True)
|
||||
resource_response["fields"]["_actions"] = {
|
||||
"delete": await has_resource_permission(enums.PermissionAction.delete, resource, user),
|
||||
"edit": await has_resource_permission(enums.PermissionAction.update, resource, user),
|
||||
"toolbar": {
|
||||
"create": await has_resource_permission(enums.PermissionAction.create, resource, user)
|
||||
},
|
||||
}
|
||||
return resource
|
||||
return resource_response
|
||||
|
||||
|
||||
@router.get("/{resource}/view", dependencies=[Depends(read_checker)])
|
||||
|
||||
Reference in New Issue
Block a user