From eb03db2dff205bdc381a81f4e24a107fd75703ad Mon Sep 17 00:00:00 2001 From: Alexandre Iooss <erdnaxe@crans.org> Date: Thu, 21 Oct 2021 21:06:51 +0200 Subject: [PATCH] Use NGINX X-Accel-Redirect to protect media --- docs/nginx_photos | 8 +++++++- photo21/urls.py | 6 ++++-- photo21/views.py | 12 +++++++++++- 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/docs/nginx_photos b/docs/nginx_photos index 243653e..77454b4 100644 --- a/docs/nginx_photos +++ b/docs/nginx_photos @@ -34,8 +34,14 @@ server { error_log /var/log/nginx/photos.crans.org_error.log; access_log /var/log/nginx/photos.crans.org_access.log; + # Allow 2Go upload at once + client_max_body_size 2G; + # Django statics and media - location /media { + # Do not directly serve media, it must be authorized + # by a Django view to check permissions + location /protected/media { + internal; alias /var/www/photos/photo21/media; } location /static { diff --git a/photo21/urls.py b/photo21/urls.py index d3ffe9d..3b6c278 100644 --- a/photo21/urls.py +++ b/photo21/urls.py @@ -14,11 +14,11 @@ Including another URLconf 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) """ from django.contrib import admin -from django.urls import include, path +from django.urls import include, path, re_path from django.conf import settings from django.conf.urls.static import static -from .views import IndexView +from .views import IndexView, MediaAccess # photologue_custom overrides some photologue patterns urlpatterns = [ @@ -33,3 +33,5 @@ urlpatterns = [ if settings.DEBUG: urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) +else: + urlpatterns.append(re_path('^media/(?P<path>.*)', MediaAccess.as_view(), name='media')) diff --git a/photo21/views.py b/photo21/views.py index 0533c20..90f4b55 100644 --- a/photo21/views.py +++ b/photo21/views.py @@ -2,10 +2,20 @@ # SPDX-License-Identifier: GPL-3.0-or-later from django.contrib.auth.mixins import LoginRequiredMixin -from django.views.generic import ListView +from django.views.generic import ListView, View +from django.http import HttpResponse from photologue.models import Gallery +class MediaAccess(LoginRequiredMixin, View): + def get(self, request, path): + response = HttpResponse() + # Content-type will be detected by nginx + del response['Content-Type'] + response['X-Accel-Redirect'] = '/protected/media/' + path + return response + + class IndexView(LoginRequiredMixin, ListView): queryset = Gallery.objects.on_site().is_public() paginate_by = 4 -- GitLab