From cb9309c29882ebce5b618d0a242f39978a3be286 Mon Sep 17 00:00:00 2001
From: Eliot Berriot <contact@eliotberriot.com>
Date: Wed, 4 Apr 2018 22:40:57 +0200
Subject: [PATCH] Factorized undo follow

---
 api/funkwhale_api/federation/activity.py | 14 +++++++
 api/funkwhale_api/federation/actors.py   | 50 +++++++++++++-----------
 2 files changed, 42 insertions(+), 22 deletions(-)

diff --git a/api/funkwhale_api/federation/activity.py b/api/funkwhale_api/federation/activity.py
index 1b03d19f8e..b253955c85 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 8871b1013b..0da78fdbe8 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(),
-- 
GitLab