From 159c07c2c09bf72065e721415427768949a44bfb Mon Sep 17 00:00:00 2001 From: Eliot Berriot Date: Thu, 30 Jan 2020 14:29:32 +0100 Subject: [PATCH] See #170: don't expose channels libraries in API --- api/funkwhale_api/federation/views.py | 4 +++- api/funkwhale_api/manage/views.py | 14 +++++++++++++- api/funkwhale_api/music/views.py | 3 ++- api/tests/federation/test_views.py | 10 ++++++++++ api/tests/manage/test_views.py | 14 ++++++++++++++ api/tests/music/test_views.py | 15 +++++++++++++++ 6 files changed, 57 insertions(+), 3 deletions(-) diff --git a/api/funkwhale_api/federation/views.py b/api/funkwhale_api/federation/views.py index b57a88261..11840e52c 100644 --- a/api/funkwhale_api/federation/views.py +++ b/api/funkwhale_api/federation/views.py @@ -203,7 +203,9 @@ class MusicLibraryViewSet( authentication_classes = [authentication.SignatureAuthentication] renderer_classes = renderers.get_ap_renderers() serializer_class = serializers.LibrarySerializer - queryset = music_models.Library.objects.all().select_related("actor") + queryset = ( + music_models.Library.objects.all().select_related("actor").filter(channel=None) + ) lookup_field = "uuid" def retrieve(self, request, *args, **kwargs): diff --git a/api/funkwhale_api/manage/views.py b/api/funkwhale_api/manage/views.py index 24e09de47..77ad9f6a7 100644 --- a/api/funkwhale_api/manage/views.py +++ b/api/funkwhale_api/manage/views.py @@ -39,7 +39,18 @@ def get_stats(tracks, target): data["track_favorites"] = favorites_models.TrackFavorite.objects.filter( track__in=tracks ).count() - data["libraries"] = uploads.values_list("library", flat=True).distinct().count() + data["libraries"] = ( + uploads.filter(library__channel=None) + .values_list("library", flat=True) + .distinct() + .count() + ) + data["channels"] = ( + uploads.exclude(library__channel=None) + .values_list("library", flat=True) + .distinct() + .count() + ) data["uploads"] = uploads.count() data["reports"] = moderation_models.Report.objects.get_for_target(target).count() data.update(get_media_stats(uploads)) @@ -233,6 +244,7 @@ class ManageLibraryViewSet( lookup_field = "uuid" queryset = ( music_models.Library.objects.all() + .filter(channel=None) .order_by("-id") .select_related("actor") .annotate( diff --git a/api/funkwhale_api/music/views.py b/api/funkwhale_api/music/views.py index 2ec0c78be..a5ddb5abe 100644 --- a/api/funkwhale_api/music/views.py +++ b/api/funkwhale_api/music/views.py @@ -50,7 +50,7 @@ def get_libraries(filter_uploads): uploads = filter_uploads(obj, uploads) uploads = uploads.playable_by(actor) qs = models.Library.objects.filter( - pk__in=uploads.values_list("library", flat=True) + pk__in=uploads.values_list("library", flat=True), channel=None, ).annotate(_uploads_count=Count("uploads")) qs = qs.prefetch_related("actor") page = self.paginate_queryset(qs) @@ -232,6 +232,7 @@ class LibraryViewSet( lookup_field = "uuid" queryset = ( models.Library.objects.all() + .filter(channel=None) .order_by("-creation_date") .annotate(_uploads_count=Count("uploads")) .annotate(_size=Sum("uploads__size")) diff --git a/api/tests/federation/test_views.py b/api/tests/federation/test_views.py index 4428ae925..800b73789 100644 --- a/api/tests/federation/test_views.py +++ b/api/tests/federation/test_views.py @@ -169,6 +169,16 @@ def test_music_library_retrieve(factories, api_client, privacy_level): assert response.data == expected +def test_music_library_retrieve_excludes_channel_libraries(factories, api_client): + channel = factories["audio.Channel"]() + library = channel.library + + url = reverse("federation:music:libraries-detail", kwargs={"uuid": library.uuid}) + response = api_client.get(url) + + assert response.status_code == 404 + + def test_music_library_retrieve_page_public(factories, api_client): library = factories["music.Library"](privacy_level="everyone") upload = factories["music.Upload"](library=library, import_status="finished") diff --git a/api/tests/manage/test_views.py b/api/tests/manage/test_views.py index aed9c0c11..ca03a4279 100644 --- a/api/tests/manage/test_views.py +++ b/api/tests/manage/test_views.py @@ -185,6 +185,7 @@ def test_artist_detail_stats(factories, superuser_api_client): response = superuser_api_client.get(url) expected = { "libraries": 0, + "channels": 0, "uploads": 0, "listenings": 0, "playlists": 0, @@ -235,6 +236,7 @@ def test_album_detail_stats(factories, superuser_api_client): response = superuser_api_client.get(url) expected = { "libraries": 0, + "channels": 0, "uploads": 0, "listenings": 0, "playlists": 0, @@ -282,6 +284,7 @@ def test_track_detail_stats(factories, superuser_api_client): response = superuser_api_client.get(url) expected = { "libraries": 0, + "channels": 0, "uploads": 0, "listenings": 0, "playlists": 0, @@ -314,6 +317,17 @@ def test_library_list(factories, superuser_api_client, settings): assert response.data["results"][0]["id"] == library.id +def test_library_list_exclude_channel_libraries( + factories, superuser_api_client, settings +): + factories["audio.Channel"]() + url = reverse("api:v1:manage:library:libraries-list") + response = superuser_api_client.get(url) + + assert response.status_code == 200 + assert response.data["count"] == 0 + + def test_library_detail(factories, superuser_api_client): library = factories["music.Library"]() url = reverse( diff --git a/api/tests/music/test_views.py b/api/tests/music/test_views.py index 68ee32b36..6ecea6306 100644 --- a/api/tests/music/test_views.py +++ b/api/tests/music/test_views.py @@ -640,6 +640,16 @@ def test_user_can_list_their_library(factories, logged_in_api_client): assert response.data["results"][0]["uuid"] == str(library.uuid) +def test_library_list_excludes_channel_library(factories, logged_in_api_client): + actor = logged_in_api_client.user.create_actor() + factories["audio.Channel"](attributed_to=actor) + url = reverse("api:v1:libraries-list") + response = logged_in_api_client.get(url) + + assert response.status_code == 200 + assert response.data["count"] == 0 + + def test_user_cannot_delete_other_actors_library(factories, logged_in_api_client): logged_in_api_client.user.create_actor() library = factories["music.Library"](privacy_level="everyone") @@ -859,6 +869,11 @@ def test_can_get_libraries_for_music_entities( "album": upload.track.album, "track": upload.track, } + # libraries in channel should be missing excluded + channel = factories["audio.Channel"](artist=upload.track.artist) + factories["music.Upload"]( + library=channel.library, playable=True, track=upload.track + ) url = reverse("api:v1:{}s-libraries".format(entity), kwargs={"pk": data[entity].pk})