首页 > 解决方案 > Django在序列化程序中检查用户权限

问题描述

我有一个序列化程序,我试图向用户显示特定项目的所有授予权限。我让它在不同字段下的序列化程序中工作,但是当我尝试将它们全部添加到一个名为的新字段中时,my_permissions我会得到每个可能权限的列表。我认为这与我的 utils 脚本有关,但我似乎无法弄清楚这个问题。这是我的序列化程序:

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 字段应仅包含此特定用户的以下内容,因为他们是成员,但不是超级用户、管理员或项目所有者:

而是像管理员一样列出所有内容。

标签: pythondjango

解决方案


需要添加 obj.pk 而不仅仅是 objrole_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 []

推荐阅读