Django проверка прав пользователя в сериализаторе - PullRequest
0 голосов
/ 17 апреля 2020

У меня есть сериализатор, который я пытаюсь показать все предоставленные разрешения для пользователя для конкретного проекта. У меня он работает в сериализаторе под разными полями, но когда я пытаюсь добавить их все вместе в новое поле с именем my_permissions, я получаю список всех возможных разрешений. Я думаю, что это как-то связано с моим сценарием утилит, но я не могу понять проблему. Вот мой сериализатор:

class ProjectSerializer(LightWeightSerializer):
    id = Field()
    name = Field()
    slug = Field()
    description = Field()
    created_date = Field()
    modified_date = Field()
    owner = MethodField()
    members = MethodField()
    is_private = Field()
    role_permissions = MethodField()
    anon_permissions = Field()
    public_permissions = Field()
    i_am_member = MethodField()
    i_am_admin = MethodField()
    my_permissions = MethodField()

    def get_members(self, project):
        members = Membership.objects.filter(project_id=project.id).select_related()
        return MembershipSerializer(members, many=True, context=self.context).data

    def get_i_am_member(self, project):
        members_list = Membership.objects.filter(project_id=project.id).select_related('user')
        for member in members_list:
            if member.user == self.context['request'].user:
                return True
            return False

    def get_role_permissions(self, project):
        members_list = Membership.objects.filter(project_id=project.id).select_related('user')
        for member in members_list:
            if member.user == self.context['request'].user:
                return RoleSerializer(member.role).data['permissions']
            return []

    def get_i_am_owner(self, obj):
        if "request" in self.context:
            return is_project_owner(self.context["request"].user, obj)
        return False

    def get_i_am_admin(self, project):
        members_list = Membership.objects.filter(project_id=project.id).select_related('user')
        for member in members_list:
            if member.user == self.context['request'].user:
                if member.is_admin:
                    return True
                return False
            return False

    def get_my_permissions(self, obj):
        if "request" in self.context:
            user = self.context["request"].user
            return calculate_permissions(is_authenticated=user.is_authenticated,
                                         is_superuser=user.is_superuser,
                                         is_member=self.get_i_am_member,
                                         is_admin=self.get_i_am_admin,
                                         role_permissions=self.get_my_permissions(obj),
                                         anon_permissions=obj.anon_permissions,
                                         public_permissions=obj.public_permissions
                                         )
        return []

    def get_owner(self, obj):
        return UserBasicInfoSerializer(obj.owner).data

и скрипт utils:

def calculate_permissions(is_authenticated=False, is_superuser=False, is_member=False,
                          is_admin=False, role_permissions=[], anon_permissions=[],
                          public_permissions=[]):
    if is_superuser:
        admins_permissions = list(map(lambda perm: perm[0], ADMINS_PERMISSIONS))
        members_permissions = list(map(lambda perm: perm[0], MEMBERS_PERMISSIONS))
        public_permissions = []
        anon_permissions = list(map(lambda perm: perm[0], ANON_PERMISSIONS))
    elif is_member:
        if is_admin:
            admins_permissions = list(map(lambda perm: perm[0], ADMINS_PERMISSIONS))
            members_permissions = list(map(lambda perm: perm[0], MEMBERS_PERMISSIONS))
        else:
            admins_permissions = []
            members_permissions = []
        members_permissions = members_permissions + role_permissions
        public_permissions = public_permissions if public_permissions is not None else []
        anon_permissions = anon_permissions if anon_permissions is not None else []
    elif is_authenticated:
        admins_permissions = []
        members_permissions = []
        public_permissions = public_permissions if public_permissions is not None else []
        anon_permissions = anon_permissions if anon_permissions is not None else []
    else:
        admins_permissions = []
        members_permissions = []
        public_permissions = []
        anon_permissions = anon_permissions if anon_permissions is not None else []

    return set(admins_permissions + members_permissions + public_permissions + anon_permissions)

и, наконец, фрагмент ответа, который я получаю:

--snip--

"role_permissions": [
            "view_project"
        ],
        "anon_permissions": [
            "view_wiki_links"
        ],
        "public_permissions": [
            "comment_task"
        ],
        "i_am_member": true,
        "i_am_admin": false,
        "my_permissions": [
            "delete_wiki_link",
            "view_wiki_links",
            "delete_task",
            "modify_wiki_link",
            "add_wiki_link",
            "delete_milestone",
            "view_issues",
            "modify_issue",
            "add_milestone",
            "view_wiki_pages",
            "view_milestones",
            "admin_roles",
            "delete_wiki_page",
            "modify_milestone",
            "add_wiki_page",
            "add_task",
            "view_project",
            "delete_issue",
            "modify_project",
            "remove_member",
            "delete_project",
            "add_member",
            "comment_task",
            "view_tasks",
            "modify_wiki_page",
            "comment_issue",
            "admin_project_values",
            "add_issue",
            "comment_wiki_page",
            "modify_task"
        ]

--snip--

Они my_permissions field должен содержать только следующее для этого конкретного пользователя, поскольку он является участником, но не суперпользователем, администратором или владельцем проекта:

  • view_project
  • view_wiki_links
  • comment_task

Но вместо этого все перечислено, как администратор.

1 Ответ

0 голосов
/ 17 апреля 2020

Необходимо добавить obj.pk вместо просто obj в role_permissions=self.get_my_permissions(obj)

Новый код теперь:

    def get_my_permissions(self, obj):
        if "request" in self.context:
            user = self.context["request"].user
            return calculate_permissions(is_authenticated=user.is_authenticated,
                                         is_superuser=user.is_superuser,
                                         is_member=self.get_i_am_member(obj.pk),
                                         is_admin=self.get_i_am_admin(obj.pk),
                                         role_permissions=self.get_role_permissions(obj.pk),
                                         anon_permissions=obj.anon_permissions,
                                         public_permissions=obj.public_permissions
                                         )
        return []
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...