diff --git a/api/funkwhale_api/federation/activity.py b/api/funkwhale_api/federation/activity.py index 1b03d19f8..b253955c8 100644 --- a/api/funkwhale_api/federation/activity.py +++ b/api/funkwhale_api/federation/activity.py @@ -101,6 +101,20 @@ def get_follow(follow_id, follower, followed): } +def get_undo(id, actor, object): + return { + '@context': [ + 'https://www.w3.org/ns/activitystreams', + 'https://w3id.org/security/v1', + {} + ], + 'type': 'Undo', + 'id': id + '/undo', + 'actor': actor.url, + 'object': object, + } + + def get_accept_follow(accept_id, accept_actor, follow, follow_actor): return { "@context": [ diff --git a/api/funkwhale_api/federation/actors.py b/api/funkwhale_api/federation/actors.py index 8871b1013..0da78fdbe 100644 --- a/api/funkwhale_api/federation/actors.py +++ b/api/funkwhale_api/federation/actors.py @@ -146,6 +146,23 @@ class SystemActor(object): system_actor, ac, sender ) + def handle_undo_follow(self, ac, sender): + actor = self.get_actor_instance() + models.Follow.objects.filter( + actor=sender, + target=actor, + ).delete() + + def handle_undo(self, ac, sender): + if ac['object']['type'] != 'Follow': + return + + if ac['object']['actor'] != sender.url: + # not the same actor, permission issue + return + + self.handle_undo_follow(ac, sender) + class LibraryActor(SystemActor): id = 'library' @@ -268,39 +285,28 @@ class TestActor(SystemActor): to=[ac['actor']], on_behalf_of=test_actor) - def handle_undo(self, ac, sender): - if ac['object']['type'] != 'Follow': - return - - if ac['object']['actor'] != sender.url: - # not the same actor, permission issue - return - - test_actor = self.get_actor_instance() - models.Follow.objects.filter( - actor=sender, - target=test_actor, - ).delete() + def handle_undo_follow(self, ac, sender): + super().handle_undo_follow(ac, sender) + actor = self.get_actor_instance() # we also unfollow the sender, if possible try: follow = models.Follow.objects.get( target=sender, - actor=test_actor, + actor=actor, ) except models.Follow.DoesNotExist: return - undo = { - '@context': serializers.AP_CONTEXT, - 'type': 'Undo', - 'id': follow.get_federation_url() + '/undo', - 'actor': test_actor.url, - 'object': serializers.FollowSerializer(follow).data, - } + undo = activity.get_undo( + id=follow.get_federation_url(), + actor=actor, + object=serializers.FollowSerializer(follow).data, + ) follow.delete() activity.deliver( undo, to=[sender.url], - on_behalf_of=test_actor) + on_behalf_of=actor) + SYSTEM_ACTORS = { 'library': LibraryActor(),