at the moment i have a custom view for example:
class DocumentViewSet(RevisionMixin, viewsets.ViewSet):
def destroy(self, request, pk=None):
...
and these models:
class Company(models.Model):
...
class Document(models.Model):
company = models.ForeignKey('company.Company', ...)
...
A user belongs to a company. A Document belongs also to a company. A user should only interact with a document view if the company from the document and from the user is the same.
On top of this separation a user can have normal Django model permissions like delete or add. Or another custom model permission.
Now i would like to check per view if a user belongs to the same company as the requested ressource and then check if the user have the permission to execute a specific action.
For example in the viewset destroy function above i would like to delete a document from database. So i would like to check if the requested user have the same company as the requested document and then i would like to check if the user have the delete permission for these model.
I try it with a custom permission:
class DocumentPermission(permissions.BasePermission):
def has_permission(self, request, view):
if view.action == 'destroy':
return request.user.has_perm('document_app.delete_document')
return False
if view.action == 'create':
return request.user.has_perm('document_app.add_document')
return False
...
def has_object_permission(self, request, view, obj):
if request.user.company is obj.company:
return True
return False
class DocumentViewSet(RevisionMixin, viewsets.ViewSet):
permission_classes = [IsAuthenticated, DocumentPermission]
def destroy(self, request, pk=None):
obj = get_object_or_404(Document, id=pk)
self.check_object_permissions(self.request, obj)
...
This works for the DocumentViewSet but not for all of my models/viewsets because another objects have not direct foreign key to company. So i would need to create some permission classes or have some ifelse in the has_object_permission function.
But is that the best solution?