funkwhale/api/funkwhale_api/federation/library.py

115 wiersze
4.0 KiB
Python
Czysty Zwykły widok Historia

import json
2018-06-10 08:55:16 +00:00
import requests
from django.conf import settings
from funkwhale_api.common import session
2018-06-10 08:55:16 +00:00
from . import actors, models, serializers, signing, webfinger
def scan_from_account_name(account_name):
"""
Given an account name such as library@test.library, will:
1. Perform the webfinger lookup
2. Perform the actor lookup
3. Perform the library's collection lookup
and return corresponding data in a dictionary.
"""
data = {}
try:
2018-06-09 13:36:16 +00:00
username, domain = webfinger.clean_acct(account_name, ensure_local=False)
except serializers.ValidationError:
2018-06-09 13:36:16 +00:00
return {"webfinger": {"errors": ["Invalid account string"]}}
system_library = actors.SYSTEM_ACTORS["library"].get_actor_instance()
data["local"] = {"following": False, "awaiting_approval": False}
try:
follow = models.Follow.objects.get(
target__preferred_username=username,
target__domain=username,
actor=system_library,
)
2018-06-09 13:36:16 +00:00
data["local"]["awaiting_approval"] = not bool(follow.approved)
data["local"]["following"] = True
except models.Follow.DoesNotExist:
pass
try:
2018-06-09 13:36:16 +00:00
data["webfinger"] = webfinger.get_resource("acct:{}".format(account_name))
except requests.ConnectionError:
2018-06-09 13:36:16 +00:00
return {"webfinger": {"errors": ["This webfinger resource is not reachable"]}}
except requests.HTTPError as e:
return {
2018-06-09 13:36:16 +00:00
"webfinger": {
"errors": [
"Error {} during webfinger request".format(e.response.status_code)
]
}
}
except json.JSONDecodeError as e:
2018-06-09 13:36:16 +00:00
return {"webfinger": {"errors": ["Could not process webfinger response"]}}
try:
2018-06-09 13:36:16 +00:00
data["actor"] = actors.get_actor_data(data["webfinger"]["actor_url"])
except requests.ConnectionError:
2018-06-09 13:36:16 +00:00
data["actor"] = {"errors": ["This actor is not reachable"]}
return data
except requests.HTTPError as e:
2018-06-09 13:36:16 +00:00
data["actor"] = {
"errors": ["Error {} during actor request".format(e.response.status_code)]
}
return data
2018-06-09 13:36:16 +00:00
serializer = serializers.LibraryActorSerializer(data=data["actor"])
if not serializer.is_valid():
2018-06-09 13:36:16 +00:00
data["actor"] = {"errors": ["Invalid ActivityPub actor"]}
return data
2018-06-09 13:36:16 +00:00
data["library"] = get_library_data(serializer.validated_data["library_url"])
return data
def get_library_data(library_url, actor):
auth = signing.get_auth(actor.private_key, actor.private_key_id)
try:
response = session.get_session().get(
library_url,
auth=auth,
timeout=5,
verify=settings.EXTERNAL_REQUESTS_VERIFY_SSL,
2018-06-09 13:36:16 +00:00
headers={"Content-Type": "application/activity+json"},
)
except requests.ConnectionError:
2018-06-09 13:36:16 +00:00
return {"errors": ["This library is not reachable"]}
scode = response.status_code
if scode == 401:
2018-06-09 13:36:16 +00:00
return {"errors": ["This library requires authentication"]}
elif scode == 403:
2018-06-09 13:36:16 +00:00
return {"errors": ["Permission denied while scanning library"]}
elif scode >= 400:
2018-06-09 13:36:16 +00:00
return {"errors": ["Error {} while fetching the library".format(scode)]}
serializer = serializers.PaginatedCollectionSerializer(data=response.json())
2018-04-08 18:27:10 +00:00
if not serializer.is_valid():
2018-06-09 13:36:16 +00:00
return {"errors": ["Invalid ActivityPub response from remote library"]}
2018-04-08 18:27:10 +00:00
return serializer.validated_data
2018-04-11 21:13:33 +00:00
def get_library_page(library, page_url, actor):
2018-04-11 21:13:33 +00:00
auth = signing.get_auth(actor.private_key, actor.private_key_id)
response = session.get_session().get(
page_url,
auth=auth,
timeout=5,
verify=settings.EXTERNAL_REQUESTS_VERIFY_SSL,
2018-06-09 13:36:16 +00:00
headers={"Content-Type": "application/activity+json"},
2018-04-11 21:13:33 +00:00
)
serializer = serializers.CollectionPageSerializer(
data=response.json(),
2018-06-09 13:36:16 +00:00
context={"library": library, "item_serializer": serializers.AudioSerializer},
)
2018-04-11 21:13:33 +00:00
serializer.is_valid(raise_exception=True)
return serializer.validated_data