diff --git a/api/funkwhale_api/federation/library.py b/api/funkwhale_api/federation/library.py index d7c2f817c8ad7a3584a4051e0c9c75def5c35b52..c53ce543067b7a014171ee44baeeafd99d7cc334 100644 --- a/api/funkwhale_api/federation/library.py +++ b/api/funkwhale_api/federation/library.py @@ -22,7 +22,6 @@ def scan_from_account_name(account_name): and return corresponding data in a dictionary. """ - data = {} try: username, domain = webfinger.clean_acct( diff --git a/api/funkwhale_api/federation/serializers.py b/api/funkwhale_api/federation/serializers.py index 620c27698e0301c6a7f1f6f7d6c69a016f7de377..5cea0061521eed7082f9dc86739f8d62093f44cf 100644 --- a/api/funkwhale_api/federation/serializers.py +++ b/api/funkwhale_api/federation/serializers.py @@ -22,40 +22,38 @@ AP_CONTEXT = [ ] -class ActorSerializer(serializers.ModelSerializer): - # left maps to activitypub fields, right to our internal models - id = serializers.URLField(source='url') - outbox = serializers.URLField(source='outbox_url') - inbox = serializers.URLField(source='inbox_url') - following = serializers.URLField( - source='following_url', required=False, allow_null=True) - followers = serializers.URLField( - source='followers_url', required=False, allow_null=True) - preferredUsername = serializers.CharField( - source='preferred_username', required=False) - publicKey = serializers.JSONField(source='public_key', required=False) - manuallyApprovesFollowers = serializers.NullBooleanField( - source='manually_approves_followers', required=False) +class ActorSerializer(serializers.Serializer): + id = serializers.URLField() + outbox = serializers.URLField() + inbox = serializers.URLField() + type = serializers.ChoiceField(choices=models.TYPE_CHOICES) + preferredUsername = serializers.CharField() + manuallyApprovesFollowers = serializers.NullBooleanField(required=False) + name = serializers.CharField(required=False, max_length=200) summary = serializers.CharField(max_length=None, required=False) - - class Meta: - model = models.Actor - fields = [ - 'id', - 'type', - 'name', - 'summary', - 'preferredUsername', - 'publicKey', - 'inbox', - 'outbox', - 'following', - 'followers', - 'manuallyApprovesFollowers', - ] + followers = serializers.URLField(required=False, allow_null=True) + following = serializers.URLField(required=False, allow_null=True) + publicKey = serializers.JSONField(required=False) def to_representation(self, instance): - ret = super().to_representation(instance) + ret = { + 'id': instance.url, + 'outbox': instance.outbox_url, + 'inbox': instance.inbox_url, + 'preferredUsername': instance.preferred_username, + 'type': instance.type, + } + if instance.name: + ret['name'] = instance.name + if instance.followers_url: + ret['followers'] = instance.followers_url + if instance.following_url: + ret['following'] = instance.following_url + if instance.summary: + ret['summary'] = instance.summary + if instance.manually_approves_followers is not None: + ret['manuallyApprovesFollowers'] = instance.manually_approves_followers + ret['@context'] = AP_CONTEXT if instance.public_key: ret['publicKey'] = { @@ -69,8 +67,21 @@ class ActorSerializer(serializers.ModelSerializer): return ret def prepare_missing_fields(self): - kwargs = {} - domain = urllib.parse.urlparse(self.validated_data['url']).netloc + kwargs = { + 'url': self.validated_data['id'], + 'outbox_url': self.validated_data['outbox'], + 'inbox_url': self.validated_data['inbox'], + 'following_url': self.validated_data.get('following'), + 'followers_url': self.validated_data.get('followers'), + 'summary': self.validated_data.get('summary'), + 'type': self.validated_data['type'], + 'name': self.validated_data.get('name'), + 'preferred_username': self.validated_data['preferredUsername'], + } + maf = self.validated_data.get('manuallyApprovesFollowers') + if maf is not None: + kwargs['manually_approves_followers'] = maf + domain = urllib.parse.urlparse(kwargs['url']).netloc kwargs['domain'] = domain for endpoint, url in self.initial_data.get('endpoints', {}).items(): if endpoint == 'sharedInbox': @@ -83,13 +94,15 @@ class ActorSerializer(serializers.ModelSerializer): return kwargs def build(self): - d = self.validated_data.copy() - d.update(self.prepare_missing_fields()) - return self.Meta.model(**d) + d = self.prepare_missing_fields() + return models.Actor(**d) def save(self, **kwargs): - kwargs.update(self.prepare_missing_fields()) - return super().save(**kwargs) + d = self.prepare_missing_fields() + d.update(kwargs) + return models.Actor.objects.create( + **d + ) def validate_summary(self, value): if value: @@ -118,9 +131,6 @@ class LibraryActorSerializer(ActorSerializer): url = serializers.ListField( child=serializers.JSONField()) - class Meta(ActorSerializer.Meta): - fields = ActorSerializer.Meta.fields + ['url'] - def validate(self, validated_data): try: urls = validated_data['url'] diff --git a/api/tests/federation/test_authentication.py b/api/tests/federation/test_authentication.py index c6a97a07a75fc52065f4a7cc7a1a710015788a86..2f69e4d4f1dcd2718e7148ebb9887c22e2def3df 100644 --- a/api/tests/federation/test_authentication.py +++ b/api/tests/federation/test_authentication.py @@ -10,8 +10,10 @@ def test_authenticate(factories, mocker, api_request): 'funkwhale_api.federation.actors.get_actor_data', return_value={ 'id': actor_url, + 'type': 'Person', 'outbox': 'https://test.com', 'inbox': 'https://test.com', + 'preferredUsername': 'test', 'publicKey': { 'publicKeyPem': public.decode('utf-8'), 'owner': actor_url,