mirror of
https://code.eliotberriot.com/funkwhale/funkwhale.git
synced 2025-10-05 07:49:23 +02:00
Can now have multiple system actors
We also handle webfinger/activity serialization properly
This commit is contained in:
parent
6c3b7ce154
commit
0c8faf83c5
13 changed files with 493 additions and 152 deletions
|
@ -1,38 +1,101 @@
|
|||
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
|
||||
from . import utils
|
||||
|
||||
|
||||
def repr_instance_actor():
|
||||
"""
|
||||
We do not use a serializer here, since it's pretty static
|
||||
"""
|
||||
actor_url = utils.full_url(reverse('federation:instance-actor'))
|
||||
preferences = global_preferences_registry.manager()
|
||||
public_key = preferences['federation__public_key']
|
||||
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)
|
||||
|
||||
return {
|
||||
'@context': [
|
||||
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',
|
||||
{},
|
||||
],
|
||||
'id': utils.full_url(reverse('federation:instance-actor')),
|
||||
'type': 'Person',
|
||||
'inbox': utils.full_url(reverse('federation:instance-inbox')),
|
||||
'outbox': utils.full_url(reverse('federation:instance-outbox')),
|
||||
'preferredUsername': 'service',
|
||||
'name': 'Service Bot - {}'.format(settings.FEDERATION_HOSTNAME),
|
||||
'summary': 'Bot account for federating with {}'.format(
|
||||
settings.FEDERATION_HOSTNAME
|
||||
),
|
||||
'publicKey': {
|
||||
'id': '{}#main-key'.format(actor_url),
|
||||
'owner': actor_url,
|
||||
'publicKeyPem': public_key
|
||||
},
|
||||
]
|
||||
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)
|
||||
|
||||
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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue