2013-03-18 2 views
4

Я пишу API, используя django-tastypie. У меня есть две проблемы с пользовательскими разрешениями, которые я надеюсь, что можно исправить django-guardian.Ограничение доступа только к принадлежащему контенту django

У меня есть две группы пользователей Клиницисты и пациенты. Клиницисты должны иметь доступ к объектам, принадлежащим только их пациентам, и пациенты должны иметь доступ только к объектам, созданным ими самим.

Мой код выглядит следующим образом:

class UserResource(ModelResource): 
    class Meta: 
     queryset = User.objects.all() 
     resource_name = 'auth/user' 
     excludes = ['email', 'password', 'is_superuser'] 


class BlogPostResource(ModelResource): 
    author = fields.ToOneField(UserResource, 'author', full=True) 

    class Meta: 
     queryset = BlogPost.objects.all() 
     resource_name = 'posts' 
     allowed_methods = ["get", "post"] 
     # Add it here. 
     authentication = BasicAuthentication() 
     authorization = DjangoAuthorization() 
     filtering = { 
      'author': ALL_WITH_RELATIONS, 
     } 

Как я могу использоваться разрешения, чтобы ограничить доступ на этой BlogPostResource?

ответ

2

я на основе моего окончательного решения прочь answer от @JamesO. Проблема с его ответом была написана для более старой версии django-tastypie до того, как класс Authorization был переписан. Вот мой код для справок в будущем:

from tastypie.authorization import Authorization 
from django.contrib.auth.models import Group 
from extendedusers.models import ExtendedUser 


class CustomAuthorization(Authorization): 
    def read_list(self, object_list, bundle): 
     clinician_group = Group.objects.get(name='clinician') 
     if bundle.request and hasattr(bundle.request, 'user'): 
      if clinician_group in bundle.request.user.groups.all(): 
       patients = ExtendedUser.objects.filter(clinician_id=bundle.request.user.id) 
       object_list = object_list.filter(author__id__in=patients) 
      else: 
       object_list = object_list.filter(author=bundle.request.user) 
      return object_list 
     else: 
      return object_list.none() 
+0

для долгосрочной масштабируемости, посмотрите http://stackoverflow.com/a/16261711/454615 – airtonix

4

Вы могли бы добиться этого с помощью пользовательского класса Authorization, например, что-то вроде:

class CustomAuthorization(Authorization): 
    def apply_limits(self, request, object_list):  
     ... 
     clin_group = Group.objects.get(name='YOUR GROUP') 
     if request and hasattr(request, 'user'): 
      if clin_group in request.user.groups.all(): 
       object_list = object_list.filter(user__in=request.user.patients.all()) # or however you stop clinician>patient relation 
      else: 
       object_list = object_list.filter(user=request.user) 
     return object_list 
+0

Спасибо, это подход, который я рассматривал. Единственное, что я забыл упомянуть в своем вопросе, что у нас также есть обычный веб-интерфейс django для контента, которому нужны точные разрешения, и я не хочу фрагментировать код политики доступа ... – Prydie

+0

@Приди - ах, я вижу. Вы могли бы создавать менеджеров, где вы устанавливаете контроль доступа, а затем вызывать менеджера как в вашем основном приложении/admin, так и в вашем приложении tastypie? сохраняя код в одном месте. – JamesO

+0

Мне стыдно сказать, что я понятия не имею, что такое менеджер ... – Prydie

Смежные вопросы