2017-07-11 66 views
0

我期待对通过tastypie提供REST接口的django网络应用进行更改。该应用程序可在:
https://github.com/OWASP/django-DefectDojo/django tastypie基于授权用户的REST查询过滤

内的应用程序,用户产品他们有权查看和属于产品端点

该机型是在定义:
https://github.com/OWASP/django-DefectDojo/blob/master/dojo/models.py#L177 https://github.com/OWASP/django-DefectDojo/blob/master/dojo/models.py#L417

我已经加入EndpointResource到dojo/api.py

class EndpointResource(BaseModelResource): 
    class Meta: 
     queryset = Endpoint.objects.all() 
     resource_name = 'endpoints' 
     fields = ['product', 'protocol', 'host', 'path', 'query', 'fragment'] 

     list_allowed_methods = ['get'] 
     detail_allowed_methods = ['get'] 
     include_resource_uri = True 
     filtering = { 
      'product': ALL, 
      'protocol': ALL, 
      'host': ALL, 
     } 
     authorization = DjangoAuthorization() 
     authentication = DojoApiKeyAuthentication() 
     serializer = Serializer(formats=['json']) 

类产品包括:
authorized_users = models.ManyToManyField(User, blank=True)
类端点包含:
product = models.ForeignKey(Product, null=True, blank=True,)

目前,用户可以验证到/api/v1/endpoints/,他们会看到所有端点。

curl -v --header 'Authorization: ApiKey sue:5b632d76ef1a38b8375383e3498d063515b356d4' http://example.com/api/v1/endpoints/ 

然而,所需的行为是用户只能够访问他们被授权产品及其相关的实体,这些产品一起。

在Python会话中我可以这样做:

>>> from dojo.models import User, Product, Endpoint 
>>> User.objects.get(username='sue').product_set.all().get().endpoint_set.all() 
[<Endpoint: goliath.sue.local>, <Endpoint: goliath.suelimited.co>, <Endpoint: 192.168.10.11>] 

这些对象,以“起诉”相关联的是,我想通过API返回的人。
什么是最好的方式让这与tastypie一起去?
任何帮助非常感谢,让我知道如果我需要张贴进一步的信息。

回答

0

最简单的方法是或许子类DjangoAuthorization。详情请参阅文档here

from tastypie.authorization import DjangoAuthorization 

from tastypie.exceptions import Unauthorized 


class UserEndpointAuthorization(DjangoAuthorization): 

    def read_list(self, object_list, bundle): 
     # Do your filter here against the queryset to limit it 
     # to only the endpoints they can see. 
     return object_list.filter(....) 
+0

谢谢jaywhy13,目前的DjangoAuthorization工作正常,所以宁愿离开。我在下面添加了一个工作答案,但有兴趣看看这是否正确。 – user1330734

0

使用代码在作为指导的链接 https://github.com/OWASP/django-DefectDojo/blob/master/dojo/finding/views.py#L68 ,下面的方法添加到类EndpointResource:

def get_object_list(self, request): 
    return super(EndpointResource, self).get_object_list(request).filter(product__authorized_users__in=[request.user]) 

它执行为我描述,但有兴趣得到的反馈,看它是否是适当的做法。

+0

这个效果很好。根据[写在这里](http://django-tastypie.readthedocs.io/en/latest/resources.html#flow-through-the-request-response-cycle),所有进来的请求必须通过''get_object_list'',不要与'get_list''这是API调用列表对象混淆。如果你想在多个资源上重用这个类,''Authorization''方法(我打算继承DjangoAuthorization'')更好。 – jaywhy13

+0

另外,我猜想它的一部分也是设计选择。使用“Authorization”方法可以根据请求类型(列表和详细信息)采取不同的行为。使用过滤方法意味着客户端将尝试访问他们无权访问的端点,而不是在read_detail方法中引发“未授权”。取决于你喜欢哪一个。 “授权”类实际上是为了确定谁可以访问什么,所以这是我的建议。祝一切顺利! – jaywhy13

+0

我倾向于通用404,因此无法为淘气目的列举资源。再次感谢! – user1330734