2017-07-29 3 views
0

Je veux avoir un moyen facile de vérifier si quelqu'un est propriétaire ou administrateur de post, proposal et ainsi de suite, il essaie d'éditer \ delete.Django (drf) autorisations dynamiques de BasePermission

Donc, chaque fois que j'utilise IsAuthenticated permission et dans la méthode de ModelViewSet je reçois par exemple et vérifier si instance.author ou parfois est l'utilisateur qui l'a demandé (request.user == instance.owner sur certains objets c'est request.user == instance.author).

Question

La principale question est: comment puis-je créer la classe d'autorisation qui peut vérifier ce genre de propriété avec le nom d'attribut utilisateur dynamique par exemple?

L'une des solutions mines (pas le meilleur, je pense)

J'ai fonction créée qui prennent le nom d'instance d'attribut utilisateur retourne la classe d'autorisation:

def is_owner_or_admin_permission_factory(owner_prop_name): 
    class IsOwnerOrAdmin(BasePermission): 
     def has_permission(self, request, view, *args, **kwargs): 
      instance = view.get_object() 
      try: 
       owner = getattr(instance, owner_prop_name) 
      except AttributeError: 
       return False 
      return (
       request.user and request.user.id and (owner == request.user or request.user.is_staff) 
      ) 

    return IsOwnerOrAdmin 

Répondre

0

Je suis aussi frustré plus le même problème exact pendant des jours, et j'ai réussi à trouver une solution de rechange appropriée (au moins pour moi, bien sûr), lorsqu'il s'agit de plusieurs modèles avec des noms de recherche différents pour les attributs de l'utilisateur. La solution de rechange était quelque chose comme ceci, dans le ModelViewSet a défini un attribut séparé user_lookup_kwarg dans la vue, qui pourrait être utilisé pour vérifier les autorisations appropriées.

Par exemple,

class YourViewSet(viewsets.ModelViewSet): 
    queryset = YourModel.objects.all() 
    serializer_class = YourSerializer 
    user_lookup_kwarg = 'user' #or 'account/created_by' whatever. 

Maintenant, votre permission_class serait un peu comme ça,

class CustomPermission(BasePermission): 

    def has_object_permission(self, request, view, obj): 
     try: 
      return request.user.is_superuser or getattr(obj, view.user_lookup_kwarg) == request.user 
     except: 
      pass 
     return request.user.is_superuser 

Vous ne juste besoin de passer outre has_object_permission() méthode pour vérifier les autorisations de niveau d'instance.

+0

C'est le travail pour moi parfaitement! Merci encore! – Dionid

+0

Un moment: quand vous vérifiez 'request.user.is_superuser' et ses retours' True', il sera retourné par la méthode, s'il est 'False' et le second argument déclenche une exception, vous pouvez simplement retourner' False', car 'request .user.is_superuser' doit déjà être 'False'. – Dionid

+0

Aussi, je pense qu'il est préférable de vérifier que l'utilisateur est autorisé, car (dans la plupart des cas) 'AnonymousUser' ne peut pas être propriétaire de l'objet, il doit donc être autorisé. – Dionid