diff --git a/api/funkwhale_api/federation/serializers.py b/api/funkwhale_api/federation/serializers.py index a026e8fb2..d27736624 100644 --- a/api/funkwhale_api/federation/serializers.py +++ b/api/funkwhale_api/federation/serializers.py @@ -258,9 +258,15 @@ class ActorSerializer(jsonld.JsonLdSerializer): ) attributedTo = serializers.URLField(max_length=500, required=False) - tags = serializers.ListField( - child=TagSerializer(), min_length=0, required=False, allow_null=True - ) + tags = serializers.ListField(min_length=0, required=False, allow_null=True) + + def validate_tags(self, tags): + valid_tags = [] + for tag in tags: + s = TagSerializer(data=tag) + if s.is_valid(): + valid_tags.append(s.validated_data) + return valid_tags category = serializers.CharField(required=False) # languages = serializers.Char( diff --git a/api/tests/federation/test_third_party_activitypub.py b/api/tests/federation/test_third_party_activitypub.py index f50c36ddb..1e18feda5 100644 --- a/api/tests/federation/test_third_party_activitypub.py +++ b/api/tests/federation/test_third_party_activitypub.py @@ -4,6 +4,75 @@ from funkwhale_api.federation import routes from funkwhale_api.federation import serializers +def test_pleroma_actor_from_ap_with_tags(factories): + + payload = { + "@context": [ + "https://www.w3.org/ns/activitystreams", + "https://test.federation/schemas/litepub-0.1.jsonld", + {"@language": "und"}, + ], + "endpoints": { + "oauthAuthorizationEndpoint": "https://test.federation/oauth/authorize", + "oauthRegistrationEndpoint": "https://test.federation/api/v1/apps", + "oauthTokenEndpoint": "https://test.federation/oauth/token", + "sharedInbox": "https://test.federation/inbox", + "uploadMedia": "https://test.federation/api/ap/upload_media", + }, + "followers": "https://test.federation/internal/fetch/followers", + "following": "https://test.federation/internal/fetch/following", + "id": "https://test.federation/internal/fetch", + "inbox": "https://test.federation/internal/fetch/inbox", + "invisible": True, + "manuallyApprovesFollowers": False, + "name": "Pleroma", + "preferredUsername": "internal.fetch", + "publicKey": { + "id": "https://test.federation/internal/fetch#main-key", + "owner": "https://test.federation/internal/fetch", + "publicKeyPem": "PEM", + }, + "summary": "An internal service actor for this Pleroma instance. No user-serviceable parts inside.", + "type": "Application", + "url": "https://test.federation/internal/fetch", + "tag": [ + { + "type": "Hashtag", + "href": "https://test.federation/explore/funkwhale", + "name": "#funkwhale", + }, + { + "type": "Emoji", + "id": "https://test.federation/emoji/test/custom.png", + "name": ":custom:", + }, + ], + } + + serializer = serializers.ActorSerializer(data=payload) + assert serializer.is_valid(raise_exception=True) + actor = serializer.save() + + assert actor.fid == payload["id"] + assert actor.url == payload["url"] + assert actor.inbox_url == payload["inbox"] + assert actor.shared_inbox_url == payload["endpoints"]["sharedInbox"] + assert actor.outbox_url is None + assert actor.following_url == payload["following"] + assert actor.followers_url == payload["followers"] + assert actor.followers_url == payload["followers"] + assert actor.type == payload["type"] + assert actor.preferred_username == payload["preferredUsername"] + assert actor.name == payload["name"] + assert actor.summary_obj.text == payload["summary"] + assert actor.summary_obj.content_type == "text/html" + assert actor.fid == payload["url"] + assert actor.manually_approves_followers is payload["manuallyApprovesFollowers"] + assert actor.private_key is None + assert actor.public_key == payload["publicKey"]["publicKeyPem"] + assert actor.domain_id == "test.federation" + + def test_pleroma_actor_from_ap(factories): payload = { diff --git a/changes/changelog.d/1342.bugfix b/changes/changelog.d/1342.bugfix new file mode 100644 index 000000000..48adfbbf7 --- /dev/null +++ b/changes/changelog.d/1342.bugfix @@ -0,0 +1 @@ +Fixed follows from Pleroma with custom Emoji as Tag by ignoring not supported tag types #1342