diff --git a/CHANGELOG b/CHANGELOG index 2a9a79cf5..b05a7be7b 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -78,6 +78,7 @@ Mediafiles: - Fixed reloading of PDF on page change [#3274]. - Custom CKEditor plugin for browsing mediafiles [#3337]. - Project images always in fullscreen [#3355]. +- Protect mediafiles for forbidden access [#3384]. General: - Several bugfixes and minor improvements. diff --git a/openslides/mediafiles/static/js/mediafiles/forms.js b/openslides/mediafiles/static/js/mediafiles/forms.js index 4001dadc0..8a4c7c4d3 100644 --- a/openslides/mediafiles/static/js/mediafiles/forms.js +++ b/openslides/mediafiles/static/js/mediafiles/forms.js @@ -75,8 +75,6 @@ angular.module('OpenSlidesApp.mediafiles.forms', [ type: 'checkbox', templateOptions: { label: gettextCatalog.getString('Hidden'), - description: gettextCatalog.getString('This does not protect the ' + - 'file but hides it for non authorized users.'), }, hide: !operator.hasPerms('mediafiles.can_see_hidden'), }, diff --git a/openslides/mediafiles/views.py b/openslides/mediafiles/views.py index 9a1216fab..5cc38bda3 100644 --- a/openslides/mediafiles/views.py +++ b/openslides/mediafiles/views.py @@ -1,3 +1,6 @@ +from django.http import HttpResponseForbidden, HttpResponseNotFound +from django.views.static import serve + from ..utils.auth import has_perm from ..utils.rest_api import ModelViewSet, ValidationError from .access_permissions import MediafileAccessPermissions @@ -66,3 +69,16 @@ class MediafileViewSet(ModelViewSet): mediafile = self.get_object() mediafile.mediafile.storage.delete(mediafile.mediafile.name) return super().destroy(request, *args, **kwargs) + + +def protected_serve(request, path, document_root=None, show_indexes=False): + try: + mediafile = Mediafile.objects.get(mediafile=path) + except Mediafile.DoesNotExist: + return HttpResponseNotFound(content="Not found.") + + if (not has_perm(request.user, 'mediafiles.can_see') or + (mediafile.hidden and not has_perm(request.user, 'mediafiles.can_see_hidden'))): + return HttpResponseForbidden(content="Forbidden.") + else: + return serve(request, path, document_root, show_indexes) diff --git a/openslides/urls.py b/openslides/urls.py index b804cbb30..7079461d3 100644 --- a/openslides/urls.py +++ b/openslides/urls.py @@ -1,15 +1,15 @@ from django.conf import settings from django.conf.urls import include, url from django.views.generic import RedirectView -from django.views.static import serve +from openslides.mediafiles.views import protected_serve from openslides.utils.plugins import get_all_plugin_urlpatterns from openslides.utils.rest_api import router urlpatterns = get_all_plugin_urlpatterns() urlpatterns += [ - url(r'^%s(?P.*)$' % settings.MEDIA_URL.lstrip('/'), serve, {'document_root': settings.MEDIA_ROOT}), + url(r'^%s(?P.*)$' % settings.MEDIA_URL.lstrip('/'), protected_serve, {'document_root': settings.MEDIA_ROOT}), url(r'^(?P.*[^/])$', RedirectView.as_view(url='/%(url)s/', permanent=True)), url(r'^rest/', include(router.urls)), url(r'^motions/', include('openslides.motions.urls')),