Commit 002b3687 authored by Eliot Berriot's avatar Eliot Berriot
Browse files

Advertise list of known nodes on /api/v1/federation/domains and in nodeinfo if...

Advertise list of known nodes on /api/v1/federation/domains and in nodeinfo if stats sharing is enabled
parent 4adbf5f5
...@@ -27,6 +27,10 @@ class LibraryScanSerializer(serializers.ModelSerializer): ...@@ -27,6 +27,10 @@ class LibraryScanSerializer(serializers.ModelSerializer):
] ]
class DomainSerializer(serializers.Serializer):
name = serializers.CharField()
class LibrarySerializer(serializers.ModelSerializer): class LibrarySerializer(serializers.ModelSerializer):
actor = federation_serializers.APIActorSerializer() actor = federation_serializers.APIActorSerializer()
uploads_count = serializers.SerializerMethodField() uploads_count = serializers.SerializerMethodField()
......
...@@ -7,5 +7,6 @@ router.register(r"fetches", api_views.FetchViewSet, "fetches") ...@@ -7,5 +7,6 @@ router.register(r"fetches", api_views.FetchViewSet, "fetches")
router.register(r"follows/library", api_views.LibraryFollowViewSet, "library-follows") router.register(r"follows/library", api_views.LibraryFollowViewSet, "library-follows")
router.register(r"inbox", api_views.InboxItemViewSet, "inbox") router.register(r"inbox", api_views.InboxItemViewSet, "inbox")
router.register(r"libraries", api_views.LibraryViewSet, "libraries") router.register(r"libraries", api_views.LibraryViewSet, "libraries")
router.register(r"domains", api_views.DomainViewSet, "domains")
urlpatterns = router.urls urlpatterns = router.urls
...@@ -9,6 +9,8 @@ from rest_framework import permissions ...@@ -9,6 +9,8 @@ from rest_framework import permissions
from rest_framework import response from rest_framework import response
from rest_framework import viewsets from rest_framework import viewsets
from funkwhale_api.common import preferences
from funkwhale_api.common.permissions import ConditionalAuthentication
from funkwhale_api.music import models as music_models from funkwhale_api.music import models as music_models
from funkwhale_api.users.oauth import permissions as oauth_permissions from funkwhale_api.users.oauth import permissions as oauth_permissions
...@@ -197,3 +199,22 @@ class FetchViewSet(mixins.RetrieveModelMixin, viewsets.GenericViewSet): ...@@ -197,3 +199,22 @@ class FetchViewSet(mixins.RetrieveModelMixin, viewsets.GenericViewSet):
queryset = models.Fetch.objects.select_related("actor") queryset = models.Fetch.objects.select_related("actor")
serializer_class = api_serializers.FetchSerializer serializer_class = api_serializers.FetchSerializer
permission_classes = [permissions.IsAuthenticated] permission_classes = [permissions.IsAuthenticated]
class DomainViewSet(
mixins.RetrieveModelMixin, mixins.ListModelMixin, viewsets.GenericViewSet
):
queryset = models.Domain.objects.order_by("name").external()
permission_classes = [ConditionalAuthentication]
serializer_class = api_serializers.DomainSerializer
ordering_fields = ("creation_date", "name")
max_page_size = 100
def get_queryset(self):
qs = super().get_queryset()
qs = qs.exclude(
instance_policy__is_active=True, instance_policy__block_all=True
)
if preferences.get("moderation__allow_list_enabled"):
qs = qs.filter(allowed=True)
return qs
import memoize.djangocache import memoize.djangocache
from django.urls import reverse
import funkwhale_api import funkwhale_api
from funkwhale_api.common import preferences from funkwhale_api.common import preferences
from funkwhale_api.federation import actors, models as federation_models from funkwhale_api.federation import actors, models as federation_models
...@@ -18,6 +20,7 @@ def get(): ...@@ -18,6 +20,7 @@ def get():
share_stats = all_preferences.get("instance__nodeinfo_stats_enabled") share_stats = all_preferences.get("instance__nodeinfo_stats_enabled")
allow_list_enabled = all_preferences.get("moderation__allow_list_enabled") allow_list_enabled = all_preferences.get("moderation__allow_list_enabled")
allow_list_public = all_preferences.get("moderation__allow_list_public") allow_list_public = all_preferences.get("moderation__allow_list_public")
auth_required = all_preferences.get("common__api_authentication_required")
banner = all_preferences.get("instance__banner") banner = all_preferences.get("instance__banner")
unauthenticated_report_types = all_preferences.get( unauthenticated_report_types = all_preferences.get(
"moderation__unauthenticated_report_types" "moderation__unauthenticated_report_types"
...@@ -67,6 +70,7 @@ def get(): ...@@ -67,6 +70,7 @@ def get():
"instance__funkwhale_support_message_enabled" "instance__funkwhale_support_message_enabled"
), ),
"instanceSupportMessage": all_preferences.get("instance__support_message"), "instanceSupportMessage": all_preferences.get("instance__support_message"),
"knownNodesListUrl": None,
}, },
} }
...@@ -87,4 +91,8 @@ def get(): ...@@ -87,4 +91,8 @@ def get():
"favorites": {"tracks": {"total": statistics["track_favorites"]}}, "favorites": {"tracks": {"total": statistics["track_favorites"]}},
"listenings": {"total": statistics["listenings"]}, "listenings": {"total": statistics["listenings"]},
} }
if not auth_required:
data["metadata"]["knownNodesListUrl"] = federation_utils.full_url(
reverse("api:v1:federation:domains-list")
)
return data return data
...@@ -179,3 +179,21 @@ def test_can_detail_fetch(logged_in_api_client, factories): ...@@ -179,3 +179,21 @@ def test_can_detail_fetch(logged_in_api_client, factories):
assert response.status_code == 200 assert response.status_code == 200
assert response.data == expected assert response.data == expected
def test_user_can_list_domains(factories, api_client, preferences):
preferences["common__api_authentication_required"] = False
allowed = factories["federation.Domain"]()
factories["moderation.InstancePolicy"](
actor=None, for_domain=True, block_all=True
).target_domain
url = reverse("api:v1:federation:domains-list")
response = api_client.get(url)
expected = {
"count": 1,
"next": None,
"previous": None,
"results": [api_serializers.DomainSerializer(allowed).data],
}
assert response.data == expected
import pytest import pytest
from django.urls import reverse
import funkwhale_api import funkwhale_api
from funkwhale_api.instance import nodeinfo from funkwhale_api.instance import nodeinfo
from funkwhale_api.federation import actors from funkwhale_api.federation import actors
...@@ -10,6 +12,7 @@ from funkwhale_api.music import utils as music_utils ...@@ -10,6 +12,7 @@ from funkwhale_api.music import utils as music_utils
def test_nodeinfo_dump(preferences, mocker, avatar): def test_nodeinfo_dump(preferences, mocker, avatar):
preferences["instance__banner"] = avatar preferences["instance__banner"] = avatar
preferences["instance__nodeinfo_stats_enabled"] = True preferences["instance__nodeinfo_stats_enabled"] = True
preferences["common__api_authentication_required"] = False
preferences["moderation__unauthenticated_report_types"] = [ preferences["moderation__unauthenticated_report_types"] = [
"takedown_request", "takedown_request",
"other", "other",
...@@ -91,6 +94,9 @@ def test_nodeinfo_dump(preferences, mocker, avatar): ...@@ -91,6 +94,9 @@ def test_nodeinfo_dump(preferences, mocker, avatar):
"instance__funkwhale_support_message_enabled" "instance__funkwhale_support_message_enabled"
], ],
"instanceSupportMessage": preferences["instance__support_message"], "instanceSupportMessage": preferences["instance__support_message"],
"knownNodesListUrl": federation_utils.full_url(
reverse("api:v1:federation:domains-list")
),
}, },
} }
assert nodeinfo.get() == expected assert nodeinfo.get() == expected
...@@ -159,6 +165,7 @@ def test_nodeinfo_dump_stats_disabled(preferences, mocker): ...@@ -159,6 +165,7 @@ def test_nodeinfo_dump_stats_disabled(preferences, mocker):
"instance__funkwhale_support_message_enabled" "instance__funkwhale_support_message_enabled"
], ],
"instanceSupportMessage": preferences["instance__support_message"], "instanceSupportMessage": preferences["instance__support_message"],
"knownNodesListUrl": None,
}, },
} }
assert nodeinfo.get() == expected assert nodeinfo.get() == expected
......
Advertise list of known nodes on /api/v1/federation/domains and in nodeinfo if stats sharing is enabled
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment