#
#
# WARNING: don't merge this in utils, you would have cyclic imports errors
#
#
from typing import List
from backend_app.utils import is_member, clean_route
from backend_app.viewsets import ALL_API_VIEWSETS
from base_app.models import User
from .utils import FakeUser, Request
def build_permissions_info(method: str) -> dict:
"""
Builds permissions information for a request method (eg: "POST").
Cached permissions are returned for all the kind of users in the app.
Returns a list of allowed end_points.
"""
def find_permissions_for_user(user):
allowed_end_points = []
request = Request(user, method)
for viewset in ALL_API_VIEWSETS:
user_can_post = True
for permission_class in viewset().get_permissions():
if not permission_class.has_permission(request, None):
user_can_post = False
break
if user_can_post:
allowed_end_points.append(clean_route(viewset.end_point_route))
return allowed_end_points
staff_user = FakeUser([], True)
dri_user = FakeUser(["DRI"])
moderator_user = FakeUser(["Moderators"])
default_user = FakeUser(["authenticated_user"])
return dict(
staff=find_permissions_for_user(staff_user),
dri=find_permissions_for_user(dri_user),
moderator=find_permissions_for_user(moderator_user),
default=find_permissions_for_user(default_user),
)
CACHE = {"POST": build_permissions_info("POST")}
def list_user_permission_for_request_type(user: User, method: str) -> List[str]:
"""
Function that list the endpoints to which a user can submit request
of type `method` to.
It uses cached data for faster lookups; as a result this is determined
only on the user type.
"""
if method not in ["POST"]:
raise AttributeError("Method is not supported yet")
if user.is_staff:
return CACHE[method]["staff"]
elif is_member("DRI", user):
return CACHE[method]["dri"]
elif is_member("Moderators", user):
return CACHE[method]["moderator"]
else:
return CACHE[method]["default"]
|