代码之家  ›  专栏  ›  技术社区  ›  Jack M.

强制将用户发送到自定义查询集

  •  1
  • Jack M.  · 技术社区  · 14 年前

    我试图保护一个应用程序,这样用户只能看到分配给他们的对象。我有个习惯 QuerySet 这是可行的,但我正在努力寻找一种方法来强制使用这个附加功能。这是我的模型:

    class Inquiry(models.Model):   
        ts = models.DateTimeField(auto_now_add=True)
        assigned_to_user = models.ForeignKey(User,
                blank=True,
                null=True,
                related_name="assigned_inquiries")
        objects = CustomQuerySetManager()
        class QuerySet(QuerySet):
            def for_user(self, user):       
                return self.filter(assigned_to_user=user)
    

    (CustomQuerySetManager记录在案 over here ,如果重要的话。)

    我正试图强制所有内容使用这个过滤,以便其他方法会引发异常。例如:

    Inquiry.objects.all() ## Should raise an exception.
    Inquiry.objects.filter(pk=69) ## Should raise an exception.
    Inquiry.objects.for_user(request.user).filter(pk=69) ## Should work.
    inqs = Inquiry.objects.for_user(request.user) ## Should work.
    inqs.filter(pk=69) ## Should work.
    

    在我看来,应该有一种方法通过只允许某些用户访问这些对象来强制这些对象的安全性。

    我不关心这会如何影响管理界面。

    4 回复  |  直到 14 年前
        1
  •  0
  •   T. Stone    14 年前

    我假设您这样做的原因是为了确保您或其他开发人员永远不会忘记按用户筛选X模型。

    我认为解决这个问题的正确方法不一定是让它抛出一个异常,而是让django的测试框架的用户,并编写测试来确保视图/任何东西不会返回其他用户的数据。

        2
  •  0
  •   Almad    14 年前

    Django并没有真正准备好在域对象/DAO级别上提供安全性。

    我不知道“强制通过此条件筛选所有查询”的任何方法。你当然可以全部覆盖 QuerySet 方法来确保这一点,但这有点老土和乏味。

    常用的方法是保护视图中的代码。这对以前做AOP的人来说是很糟糕的,但它有点管用。

        3
  •  0
  •   Community Mike Kinghan    7 年前

    我建议在模型方法中隔离所有的查询集生成,这样在代码检查期间更容易看到错误的查询,并且更容易开发检查安全性的测试。如果你需要执行某种检查,那么也许 Record Ownership screener middleware 会有帮助的。否则尝试其他方法,比如 django-authority

    (来自问题 How to enforce account based separation in Django How would one organize this... )

        4
  •  0
  •   Tom    14 年前

    管理器中的所有内容都通过函数运行 get_query_set() . 难道你不能用它作为一个阻塞点,检查是否存在在所有情况下都必须设置的某个参数吗?因此,如果没有查看用户关键字参数,则会引发异常。比如:

    def get_query_set(self):
        if not self.viewing_user:
            raise MyCustomException
        return super(CustomQuerySetManager, self).get_query_set()