2017-08-30 12:58:51 +02:00
|
|
|
from django.http import HttpResponseForbidden, HttpResponseNotFound
|
|
|
|
from django.views.static import serve
|
|
|
|
|
2019-03-04 18:40:08 +01:00
|
|
|
from .access_permissions import MediafileAccessPermissions
|
|
|
|
from .models import Mediafile
|
2019-02-19 21:41:49 +01:00
|
|
|
from ..core.config import config
|
2017-01-26 15:34:24 +01:00
|
|
|
from ..utils.auth import has_perm
|
2016-01-24 22:58:45 +01:00
|
|
|
from ..utils.rest_api import ModelViewSet, ValidationError
|
2013-02-16 16:19:20 +01:00
|
|
|
|
|
|
|
|
2015-07-01 23:18:48 +02:00
|
|
|
# Viewsets for the REST API
|
|
|
|
|
2019-01-06 16:22:33 +01:00
|
|
|
|
2015-02-12 18:48:14 +01:00
|
|
|
class MediafileViewSet(ModelViewSet):
|
2015-01-24 16:35:50 +01:00
|
|
|
"""
|
2015-07-01 23:18:48 +02:00
|
|
|
API endpoint for mediafile objects.
|
|
|
|
|
2015-08-31 14:07:24 +02:00
|
|
|
There are the following views: metadata, list, retrieve, create,
|
|
|
|
partial_update, update and destroy.
|
2015-01-24 16:35:50 +01:00
|
|
|
"""
|
2019-01-06 16:22:33 +01:00
|
|
|
|
2016-02-11 22:58:32 +01:00
|
|
|
access_permissions = MediafileAccessPermissions()
|
2015-01-24 16:35:50 +01:00
|
|
|
queryset = Mediafile.objects.all()
|
|
|
|
|
2015-07-01 23:18:48 +02:00
|
|
|
def check_view_permissions(self):
|
2015-01-24 16:35:50 +01:00
|
|
|
"""
|
2015-07-01 23:18:48 +02:00
|
|
|
Returns True if the user has required permissions.
|
2015-01-24 16:35:50 +01:00
|
|
|
"""
|
2019-01-06 16:22:33 +01:00
|
|
|
if self.action in ("list", "retrieve"):
|
2016-09-17 22:26:23 +02:00
|
|
|
result = self.get_access_permissions().check_permissions(self.request.user)
|
2019-01-06 16:22:33 +01:00
|
|
|
elif self.action == "metadata":
|
|
|
|
result = has_perm(self.request.user, "mediafiles.can_see")
|
|
|
|
elif self.action == "create":
|
|
|
|
result = has_perm(self.request.user, "mediafiles.can_see") and has_perm(
|
|
|
|
self.request.user, "mediafiles.can_upload"
|
|
|
|
)
|
|
|
|
elif self.action in ("partial_update", "update"):
|
|
|
|
result = (
|
|
|
|
has_perm(self.request.user, "mediafiles.can_see")
|
|
|
|
and has_perm(self.request.user, "mediafiles.can_upload")
|
|
|
|
and has_perm(self.request.user, "mediafiles.can_manage")
|
|
|
|
)
|
|
|
|
elif self.action == "destroy":
|
|
|
|
result = has_perm(self.request.user, "mediafiles.can_see") and has_perm(
|
|
|
|
self.request.user, "mediafiles.can_manage"
|
|
|
|
)
|
2015-07-01 23:18:48 +02:00
|
|
|
else:
|
|
|
|
result = False
|
|
|
|
return result
|
2016-01-14 22:55:43 +01:00
|
|
|
|
|
|
|
def create(self, request, *args, **kwargs):
|
|
|
|
"""
|
|
|
|
Customized view endpoint to upload a new file.
|
|
|
|
"""
|
|
|
|
# Check permission to check if the uploader has to be changed.
|
2019-01-06 16:22:33 +01:00
|
|
|
uploader_id = self.request.data.get("uploader_id")
|
|
|
|
if (
|
|
|
|
uploader_id
|
|
|
|
and not has_perm(request.user, "mediafiles.can_manage")
|
|
|
|
and str(self.request.user.pk) != str(uploader_id)
|
|
|
|
):
|
2016-01-14 22:55:43 +01:00
|
|
|
self.permission_denied(request)
|
2019-01-06 16:22:33 +01:00
|
|
|
if not self.request.data.get("mediafile"):
|
|
|
|
raise ValidationError({"detail": "You forgot to provide a file."})
|
2016-01-14 22:55:43 +01:00
|
|
|
return super().create(request, *args, **kwargs)
|
2017-03-28 00:17:02 +02:00
|
|
|
|
|
|
|
def destroy(self, request, *args, **kwargs):
|
|
|
|
"""
|
|
|
|
Customized view endpoint to delete uploaded files.
|
|
|
|
|
|
|
|
Does also delete the file from filesystem.
|
|
|
|
"""
|
|
|
|
# To avoid Django calling save() and triggering autoupdate we do not
|
|
|
|
# use the builtin method mediafile.mediafile.delete() but call
|
|
|
|
# mediafile.mediafile.storage.delete(...) directly. This may have
|
|
|
|
# unattended side effects so be careful especially when accessing files
|
|
|
|
# on server via Django methods (file, open(), save(), ...).
|
|
|
|
mediafile = self.get_object()
|
|
|
|
mediafile.mediafile.storage.delete(mediafile.mediafile.name)
|
2019-02-19 21:41:49 +01:00
|
|
|
for logo in config["logos_available"]:
|
|
|
|
if config[logo]["path"] == mediafile.mediafile.url:
|
|
|
|
config[logo] = {
|
|
|
|
"display_name": config[logo]["display_name"],
|
|
|
|
"path": "",
|
|
|
|
}
|
2017-03-28 00:17:02 +02:00
|
|
|
return super().destroy(request, *args, **kwargs)
|
2017-08-30 12:58:51 +02:00
|
|
|
|
|
|
|
|
|
|
|
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.")
|
|
|
|
|
2019-01-06 16:22:33 +01:00
|
|
|
can_see = has_perm(request.user, "mediafiles.can_see")
|
2018-04-04 11:25:45 +02:00
|
|
|
is_special_file = mediafile.is_logo() or mediafile.is_font()
|
2019-01-06 16:22:33 +01:00
|
|
|
is_hidden_but_no_perms = mediafile.hidden and not has_perm(
|
|
|
|
request.user, "mediafiles.can_see_hidden"
|
|
|
|
)
|
2018-04-04 11:25:45 +02:00
|
|
|
|
2018-04-24 10:33:50 +02:00
|
|
|
if not is_special_file and (not can_see or is_hidden_but_no_perms):
|
2017-08-30 12:58:51 +02:00
|
|
|
return HttpResponseForbidden(content="Forbidden.")
|
|
|
|
else:
|
|
|
|
return serve(request, path, document_root, show_indexes)
|