0

I created a Django app with Video files. I'm using Gunicorn & Nginx. A user (not root) that runs the django server.

I restricted the views so only the users with correct permissions can view these. This works fine.

But when watching a video, I can get the url. (../media/videos/video.mp4) enter image description here

And now everyone with this file-location can see the video.

I'm a little lost now. Do I need to use a package like django-sendfile2’s ? Or do I need to change my server settings and limit access to the media folders ?

jefferson
  • 105
  • 1
  • 9
  • 1
    I'm not a django expert, however in a common case you can solve the tasks like this using `X-Accel-Redirect` nginx feature (see the [example](https://kovyrin.net/2006/11/01/nginx-x-accel-redirect-php-rails/)). As of now this video file is being served directly by nginx itself; your goal is to make it available only after the user passed some credentials check. – Ivan Shatsky Jun 04 '22 at 19:52
  • 1
    @IvanShatsky, I checked the example and think that [django-sendfile2’s](https://django-sendfile2.readthedocs.io/en/latest/index.html) does use this kind a feature. And Nginx is one of the wsgi's they provide. – jefferson Jun 05 '22 at 10:49
  • 1
    I take a look at the documentation link you provide. Yes, I think it is exactly that feature I meant to be used. You'd need an appropriate configuration change from the nginx side too. – Ivan Shatsky Jun 05 '22 at 10:54
  • @IvanShatsky, I ended up using the [django-private-storage](https://github.com/edoburu/django-private-storage). Check my answer below ... Thanks for helping – jefferson Jun 05 '22 at 18:08

1 Answers1

0

I did manage to secure my files using the django-private-storage package. django-sendfile2’s might also work, but I did find the documentation less explanatory. Following the instructions I installed the packages:

pip install django-private-storage

And added following lines to the Settings.py file:

INSTALLED_APPS += (
    'private_storage',
)
PRIVATE_STORAGE_ROOT = os.path.join(BASE_DIR, 'private-media')

in the model I added the field:

video = PrivateFileField(upload_to='videos/%Y/%m/%d', null=True)

In the view I added:

from private_storage.views import PrivateStorageDetailView

class PlayJobVideo(PrivateStorageDetailView):
    model = Video
    model_file_field = "video"
    template_name = "index/play_video.html"

    def get_object(self):
        return Video.objects.get(id=self.kwargs['video_id'])
    
    def can_access_file(self, private_file):
        return True

And then I wrote a decorator owner_only()

def owner-only():
    def decorators(view_func, *args, **kwargs):
        def wrapper_function(request, *args, **kwargs):

        try:
            if request.user:
                if video.user == request.user:
                    return view_func(request, *args, **kwargs)
                else:
                    return redirect('index:home')
        except:
            return redirect('index:home')
    return wrapper_function
return decorators

And the I added this decorator to the view.

@method_decorator(owner_only(), name='dispatch')
class PlayVideo(PrivateStorageDetailView):
               ...
jefferson
  • 105
  • 1
  • 9