Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Question] Dealing with unnecessary repetition of DB hits... #81

Open
Ombental opened this issue Jan 25, 2022 · 1 comment
Open

[Question] Dealing with unnecessary repetition of DB hits... #81

Ombental opened this issue Jan 25, 2022 · 1 comment

Comments

@Ombental
Copy link

So,
I have a Membership model, with 3 roles - viewer, member, manager
I created a group for all users that aren't django staff or admins to filter out some processing
My problem is I have to repeat the same calls to get the membership instance to check for the permission.
(A member can be a part of multiple schedules)

class ShiftAccessPolicy(BaseAccessPolicy):

    statements = [
        {
            "action": "*",
            "principal": ["admin", "staff"],
            "effect": "allow",
        },
        {
            "action": ["list", "retrieve"],
            "principal": "group:auth_user",
            "effect": "allow",
            "condition": "is_schedule_member"
        },
        {
            "action": "create",
            "principal": "group:auth_user",
            "effect": "allow",
            "condition_expression": "is_not_viewer_only"
        },
        {
            "action": [ "archive"],
            "principal": "group:auth_user",
            "effect": "allow",
            "condition_expression": "is_schedule_manager"
        }
    ]

    def is_schedule_manager(self, request, view, action):
        membership = request.user.member.membership_set.filter(schedule__id=view.kwargs.get('schedule_pk'))
        if membership.exists():
            membership = membership[0]
            return Roles.SCHEDULE_MANAGER == membership.role
        else:
            return False

    def is_schedule_member(self, request, view, action):
        membership = request.user.member.membership_set.filter(schedule__id=view.kwargs.get('schedule_pk'))
        return membership.exists()

    def is_viewer_only(self, request, view, action):
        membership = request.user.member.membership_set.filter(schedule__id=view.kwargs.get('schedule_pk'))
        if membership.exists():
            membership = membership[0]
            return Roles.VIEWER != membership.role
        else:
            return False

As can be seen - each time I have to get the membership...
3 questions came into mind:

  1. Is there a better way to use the access policy module that I'm missing?
  2. Should we implement a "shared" instance for the types of cases?
  3. in the case that I would use the same condition (lets say is_schedule_member would have been called multiple times) shouldn't we cache the result from the first time it was called?
@rsinger86
Copy link
Owner

I have never faced this issue, but maybe there could be a method on the policy class called get_membership()?

You could implement caching there, with the key based on the combination of user id and schedule id.

I can't think of an approach specific to this package.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants