Disable download by default on track urls exposed over federation

This commit is contained in:
Eliot Berriot 2019-12-09 16:37:04 +01:00
parent 828f602b79
commit dd9cca432d
No known key found for this signature in database
GPG Key ID: 6B501DFD73514E14
6 changed files with 45 additions and 6 deletions

View File

@ -1159,7 +1159,7 @@ class UploadSerializer(jsonld.JsonLdSerializer):
"duration": instance.duration,
"url": [
{
"href": utils.full_url(instance.listen_url),
"href": utils.full_url(instance.listen_url_no_download),
"type": "Link",
"mediaType": instance.mimetype,
},
@ -1235,7 +1235,7 @@ class ChannelUploadSerializer(serializers.Serializer):
{
"type": "Link",
"mimeType": upload.mimetype,
"href": utils.full_url(upload.listen_url),
"href": utils.full_url(upload.listen_url_no_download),
},
{
"type": "Link",

View File

@ -846,6 +846,11 @@ class Upload(models.Model):
def listen_url(self):
return self.track.listen_url + "?upload={}".format(self.uuid)
@property
def listen_url_no_download(self):
# Not using reverse because this is slow
return self.listen_url + "&download=false"
def get_transcoded_version(self, format, max_bitrate=None):
if format:
mimetype = utils.EXTENSION_TO_MIMETYPE[format]

View File

@ -393,7 +393,9 @@ def get_content_disposition(filename):
return "attachment; {}".format(filename)
def handle_serve(upload, user, format=None, max_bitrate=None, proxy_media=True):
def handle_serve(
upload, user, format=None, max_bitrate=None, proxy_media=True, download=True
):
f = upload
# we update the accessed_date
now = timezone.now()
@ -450,7 +452,8 @@ def handle_serve(upload, user, format=None, max_bitrate=None, proxy_media=True):
mapping = {"nginx": "X-Accel-Redirect", "apache2": "X-Sendfile"}
file_header = mapping[settings.REVERSE_PROXY_TYPE]
response[file_header] = file_path
response["Content-Disposition"] = get_content_disposition(filename)
if download:
response["Content-Disposition"] = get_content_disposition(filename)
if mt:
response["Content-Type"] = mt
@ -476,6 +479,7 @@ class ListenViewSet(mixins.RetrieveModelMixin, viewsets.GenericViewSet):
"track__album__artist", "track__artist"
)
explicit_file = request.GET.get("upload")
download = request.GET.get("download", "true").lower() == "true"
if explicit_file:
queryset = queryset.filter(uuid=explicit_file)
queryset = queryset.playable_by(actor)
@ -499,6 +503,7 @@ class ListenViewSet(mixins.RetrieveModelMixin, viewsets.GenericViewSet):
format=format,
max_bitrate=max_bitrate,
proxy_media=settings.PROXY_MEDIA,
download=download,
)

View File

@ -953,7 +953,7 @@ def test_activity_pub_audio_serializer_to_ap(factories):
"attributedTo": upload.library.actor.fid,
"url": [
{
"href": utils.full_url(upload.listen_url),
"href": utils.full_url(upload.listen_url_no_download),
"type": "Link",
"mediaType": "audio/mp3",
},
@ -1105,7 +1105,7 @@ def test_channel_upload_serializer(factories):
{
"type": "Link",
"mimeType": upload.mimetype,
"href": utils.full_url(upload.listen_url),
"href": utils.full_url(upload.listen_url_no_download),
},
{
"type": "Link",

View File

@ -437,6 +437,13 @@ def test_upload_listen_url(factories):
assert upload.listen_url == expected
def test_upload_listen_url_no_download(factories):
upload = factories["music.Upload"]()
expected = upload.track.listen_url + "?upload={}&download=false".format(upload.uuid)
assert upload.listen_url_no_download == expected
def test_library_schedule_scan(factories, now, mocker):
on_commit = mocker.patch("funkwhale_api.common.utils.on_commit")
library = factories["music.Library"](uploads_count=5)

View File

@ -382,10 +382,28 @@ def test_listen_correct_access(factories, logged_in_api_client):
library__privacy_level="me",
import_status="finished",
)
expected_filename = upload.track.full_name + ".ogg"
url = reverse("api:v1:listen-detail", kwargs={"uuid": upload.track.uuid})
response = logged_in_api_client.get(url)
assert response.status_code == 200
assert response["Content-Disposition"] == "attachment; filename*=UTF-8''{}".format(
urllib.parse.quote(expected_filename)
)
def test_listen_correct_access_download_false(factories, logged_in_api_client):
logged_in_api_client.user.create_actor()
upload = factories["music.Upload"](
library__actor=logged_in_api_client.user.actor,
library__privacy_level="me",
import_status="finished",
)
url = reverse("api:v1:listen-detail", kwargs={"uuid": upload.track.uuid})
response = logged_in_api_client.get(url, {"download": "false"})
assert response.status_code == 200
assert "Content-Disposition" not in response
def test_listen_explicit_file(factories, logged_in_api_client, mocker, settings):
@ -406,6 +424,7 @@ def test_listen_explicit_file(factories, logged_in_api_client, mocker, settings)
format=None,
max_bitrate=None,
proxy_media=settings.PROXY_MEDIA,
download=True,
)
@ -500,6 +519,7 @@ def test_listen_transcode(factories, now, logged_in_api_client, mocker, settings
format="mp3",
max_bitrate=None,
proxy_media=settings.PROXY_MEDIA,
download=True,
)
@ -532,6 +552,7 @@ def test_listen_transcode_bitrate(
format=None,
max_bitrate=expected,
proxy_media=settings.PROXY_MEDIA,
download=True,
)
@ -562,6 +583,7 @@ def test_listen_transcode_in_place(
format="mp3",
max_bitrate=None,
proxy_media=settings.PROXY_MEDIA,
download=True,
)