Search code examples
djangodjango-rest-frameworkdjango-rest-viewsets

Secure a file in endpoint with the same permissions as the endpoint in Django REST


I have a project in Django REST framework with model like this

class Attachment
    attachment_type = models.PositiveSmallIntegerField(choices=constants.AttachmentTypes.CHOICES)
    creator = models.ForeignKey(User, related_name="attachments", on_delete=models.PROTECT)
    file = models.FileField(upload_to='uploads/%Y/%m/%d/', max_length=511)
    name = models.CharField(max_length=255)
    size = models.CharField(max_length=30)

And ModelViewSet using the model with custom permissions

class AttachmentViewSet(viewsets.ModelViewSet):
    queryset = models.Attachment.objects.all() 

Permissions for this ViewSet are based on a user roles and work fine. Problem is with permissions to a file field. It is now accessible to whoever has the link. I need the same permissions to a file as to Attachment endpoint.

What is the proper way to do it?


Solution

  • I have found solution myself.

    At first I made all files inaccessible via URL. Then I created another endpoint - DownloadAttachmentViewSet. This viewset only supports retrieve action. AttachmentViewSet now serves URL to DownloadAttachmentViewSet-detail instead of actual file URL. When retrieve method is run it returns FileResponse.

    In this way I can use custom permissions and filtered querysets to ensure that file downloaded only by users I want.

    QUick solution for someome who needs to serve only small files could be to use https://github.com/Hipo/drf-extra-fields and serialize them as Base64.