Django Rest Framework:基于对象属性/所有权的权限

时间:2014-05-31 21:58:55

标签: python django django-rest-framework

我想允许用户创建和查看资源,但仅限于:

  1. 他们是职员或
  2. 他们是他们试图创建/查看的对象的“所有者”
  3. 我已经获得了只读权限,因为用户只有在使用主键生成视图集时才能获取对象列表。例如:GET / api / users / 1 / notes只返回pk = 1的用户注释。

    但是,在测试中,我发现用户可以通过将其发布到自己的列表端点来创建另一个用户“拥有”的对象。例如,用户1可以向/ api / users / 1 / notes发送POST,但是将注释数据指定为{user:“http://host.tld/users/2/”,text:“Look!我在另一个人的帐户中创建了一个注释!” }

    我已经得到了一个似乎工作得很好的修复,虽然我感觉我正在逆流而行。现在,在自定义权限内,我创建了一个将要创建的对象的实例,并检查其所有者是否是发出请求的用户。

    有更简洁的方法吗?

    当前修复:

    def has_permission(self, request, view):
        if request.user.is_staff:
            return True
        elif request.method in permissions.SAFE_METHODS:
            # check that the user is looking for their own list
            return request.user == User.objects.get(pk=view.kwargs['user_pk'])
        elif request.method not in permissions.SAFE_METHODS:
            # the user can create/modify the object if the new object's user == the request user
            # roundabout way of figuring this out... probably a better way
            user_path = request.POST['user'].split(request.get_host())[1]
            func = resolve(user_path).func
            kwargs = resolve(user_path).kwargs
            user_for_object = func.cls.model.objects.get(pk=kwargs['pk'])
            return user_for_object == request.user
        else:
            return False
    

1 个答案:

答案 0 :(得分:2)

这取决于你的其余代码。

通常,DRF会在ViewSet或权限后端中的check_object_permissions方法中执行对象级检查。

此方法由get_object的(默认实现)调用,以在任何泛型尝试使对象工作时检查权限。

如果您只使用通用ViewSet,/notes@action,这将是最简单的方法。

如果这些ViewSet中的对象note,我建议构建类似的东西(例如,在添加到/user/下的每个ViewSet的mixin中)。 有许多不同的方法来构建嵌套资源及其路由。