From c97db31cb129e03248e59a2ffc7a99c0b1924998 Mon Sep 17 00:00:00 2001
From: Eliot Berriot <contact@eliotberriot.com>
Date: Mon, 9 Apr 2018 19:00:11 +0200
Subject: [PATCH] Include following state in scan payload

---
 api/funkwhale_api/federation/library.py  | 47 +++++++++++++++++++++++-
 api/tests/federation/test_library.py     |  6 ++-
 api/tests/federation/test_serializers.py |  1 -
 3 files changed, 51 insertions(+), 3 deletions(-)

diff --git a/api/funkwhale_api/federation/library.py b/api/funkwhale_api/federation/library.py
index 6fa3c7183f..f19a7a2914 100644
--- a/api/funkwhale_api/federation/library.py
+++ b/api/funkwhale_api/federation/library.py
@@ -1,3 +1,4 @@
+import json
 import requests
 
 from django.conf import settings
@@ -5,6 +6,7 @@ from django.conf import settings
 from funkwhale_api.common import session
 
 from . import actors
+from . import models
 from . import serializers
 from . import signing
 from . import webfinger
@@ -22,6 +24,39 @@ def scan_from_account_name(account_name):
     """
 
     data = {}
+    try:
+        username, domain = webfinger.clean_acct(
+            account_name, ensure_local=False)
+    except serializers.ValidationError:
+        return {
+            'webfinger': {
+                'errors': ['Invalid account string']
+            }
+        }
+    system_library = actors.SYSTEM_ACTORS['library'].get_actor_instance()
+    library = models.Library.objects.filter(
+        actor__domain=domain,
+        actor__preferred_username=username
+    ).select_related('actor').first()
+    follow_request = None
+    if library:
+        data['local']['following'] = True
+        data['local']['awaiting_approval'] = True
+
+    else:
+        follow_request = models.FollowRequest.objects.filter(
+            target__preferred_username=username,
+            target__domain=username,
+            actor=system_library,
+        ).first()
+        data['local'] = {
+            'following': False,
+            'awaiting_approval': False,
+        }
+        if follow_request:
+            data['awaiting_approval'] = follow_request.approved is None
+
+    follow_request = models.Follow
     try:
         data['webfinger'] = webfinger.get_resource(
             'acct:{}'.format(account_name))
@@ -39,6 +74,12 @@ def scan_from_account_name(account_name):
                         e.response.status_code)]
             }
         }
+    except json.JSONDecodeError as e:
+        return {
+            'webfinger': {
+                'errors': ['Could not process webfinger response']
+            }
+        }
 
     try:
         data['actor'] = actors.get_actor_data(data['webfinger']['actor_url'])
@@ -56,7 +97,11 @@ def scan_from_account_name(account_name):
         return data
 
     serializer = serializers.LibraryActorSerializer(data=data['actor'])
-    serializer.is_valid(raise_exception=True)
+    if not serializer.is_valid():
+        data['actor'] = {
+            'errors': ['Invalid ActivityPub actor']
+        }
+        return data
     data['library'] = get_library_data(
         serializer.validated_data['library_url'])
 
diff --git a/api/tests/federation/test_library.py b/api/tests/federation/test_library.py
index 714a0c306d..7a3abf5d83 100644
--- a/api/tests/federation/test_library.py
+++ b/api/tests/federation/test_library.py
@@ -39,6 +39,10 @@ def test_library_scan_from_account_name(mocker, factories):
         'webfinger': get_resource_result,
         'actor': actor_data,
         'library': get_library_data_result,
+        'local': {
+            'following': False,
+            'awaiting_approval': False,
+        },
     }
 
 
@@ -63,4 +67,4 @@ def test_get_library_data_requires_authentication(r_mock, factories):
     url = 'https://test.library'
     r_mock.get(url, status_code=403)
     result = library.get_library_data(url)
-    assert result['errors'] == ['This library requires authentication']
+    assert result['errors'] == ['Permission denied while scanning library']
diff --git a/api/tests/federation/test_serializers.py b/api/tests/federation/test_serializers.py
index e4fb88040b..7b7dda33cb 100644
--- a/api/tests/federation/test_serializers.py
+++ b/api/tests/federation/test_serializers.py
@@ -218,7 +218,6 @@ def test_paginated_collection_serializer_validation():
     assert serializer.validated_data['totalItems'] == 5
     assert serializer.validated_data['id'] == data['id']
     assert serializer.validated_data['actor'] == data['actor']
-    assert serializer.validated_data['items'] == []
 
 
 def test_collection_page_serializer_validation():
-- 
GitLab