Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions aiohttp_admin/backends/abc.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
from aiohttp_security import check_permission, permits
from pydantic import Json

from ..security import check, permissions_as_dict
from ..security import check
from ..types import ComponentState, InputState, fk, resources_key

if sys.version_info >= (3, 10):
Expand Down Expand Up @@ -435,8 +435,8 @@ def _process_list_query(self, query: _ListQuery, request: web.Request) -> None:
query["filter"] = merged_filter

# Add filters from advanced permissions.
# The permissions will be cached on the request from a previous permissions check.
permissions = permissions_as_dict(request["aiohttpadmin_permissions"])
# The parsed permissions are cached on the request from a previous check.
permissions = request["aiohttpadmin_permissions"]
filters = permissions.get(f"admin.{self.name}.view",
permissions.get(f"admin.{self.name}.*", {}))
for k, v in filters.items():
Expand Down
14 changes: 9 additions & 5 deletions aiohttp_admin/security.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,16 +94,20 @@ async def permits(
except (TypeError, ValueError):
raise TypeError("Context must be `(request, record)` or `(request, None)`")

permissions: Optional[Collection[str]] = request.get("aiohttpadmin_permissions")
permissions = request.get("aiohttpadmin_permissions")
if permissions is None:
raw: Collection[str]
if self._identity_callback is None:
permissions = (Permissions.all,)
raw = (Permissions.all,)
else:
user = await self._identity_callback(identity)
permissions = user["permissions"]
# Cache permissions per request to avoid potentially dozens of DB calls.
raw = user["permissions"]
# Cache the parsed permissions per request to avoid both repeat DB calls
# and re-parsing the permission strings on every check (permits() runs
# O(records * fields) times per request).
permissions = permissions_as_dict(raw)
request["aiohttpadmin_permissions"] = permissions
return has_permission(permission, permissions_as_dict(permissions), record)
return has_permission(permission, permissions, record)


class TokenIdentityPolicy(SessionIdentityPolicy):
Expand Down
Loading