Skip to content
Snippets Groups Projects
serializers.py 3.34 KiB
Newer Older
  • Learn to ignore specific revisions
  • import urllib.parse
    
    
    from django.urls import reverse
    from django.conf import settings
    
    
    from rest_framework import serializers
    
    from dynamic_preferences.registries import global_preferences_registry
    
    
    from . import models
    
    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)
        followers = serializers.URLField(source='followers_url', required=False)
        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)
    
        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',
            ]
    
        def to_representation(self, instance):
            ret = super().to_representation(instance)
            ret['@context'] = [
    
                'https://www.w3.org/ns/activitystreams',
                'https://w3id.org/security/v1',
                {},
    
            ]
            if instance.public_key:
                ret['publicKey'] = {
                    'owner': instance.url,
                    'publicKeyPem': instance.public_key,
                    'id': '{}#main-key'.format(instance.url)
                }
            ret['endpoints'] = {}
            if instance.shared_inbox_url:
                ret['endpoints']['sharedInbox'] = instance.shared_inbox_url
            return ret
    
        def prepare_missing_fields(self):
            kwargs = {}
            domain = urllib.parse.urlparse(self.validated_data['url']).netloc
            kwargs['domain'] = domain
            for endpoint, url in self.initial_data.get('endpoints', {}).items():
                if endpoint == 'sharedInbox':
                    kwargs['shared_inbox_url'] = url
                    break
            try:
                kwargs['public_key'] = self.initial_data['publicKey']['publicKeyPem']
            except KeyError:
                pass
            return kwargs
    
        def build(self):
            d = self.validated_data.copy()
            d.update(self.prepare_missing_fields())
            return self.Meta.model(**d)
    
        def save(self, **kwargs):
            kwargs.update(self.prepare_missing_fields())
            return super().save(**kwargs)
    
    
        def validate_summary(self, value):
            if value:
                return value[:500]
    
    
    
    class ActorWebfingerSerializer(serializers.ModelSerializer):
        class Meta:
            model = models.Actor
            fields = ['url']
    
        def to_representation(self, instance):
            data = {}
            data['subject'] = 'acct:{}'.format(instance.webfinger_subject)
            data['links'] = [
                {
                    'rel': 'self',
                    'href': instance.url,
                    'type': 'application/activity+json'
                }
            ]
            data['aliases'] = [
                instance.url
            ]
            return data