From 62f2b867b9dbdfde6be79b729515711c5c2cd877 Mon Sep 17 00:00:00 2001 From: Andrew Godwin Date: Sat, 17 Dec 2022 12:00:47 -0700 Subject: Fix serving of system actor Fixes #183 --- core/signatures.py | 2 +- tests/users/models/test_system_actor.py | 33 +++++++++++++++++++++++++++++++++ users/models/identity.py | 8 ++++---- users/models/system_actor.py | 1 + users/views/activitypub.py | 3 ++- 5 files changed, 41 insertions(+), 6 deletions(-) create mode 100644 tests/users/models/test_system_actor.py diff --git a/core/signatures.py b/core/signatures.py index ef354c3..9a544a4 100644 --- a/core/signatures.py +++ b/core/signatures.py @@ -84,7 +84,7 @@ class HttpSignature: headers = {} for header_name in header_names: if header_name == "(request-target)": - value = f"post {request.path}" + value = f"{request.method.lower()} {request.path}" elif header_name == "content-type": value = request.META["CONTENT_TYPE"] else: diff --git a/tests/users/models/test_system_actor.py b/tests/users/models/test_system_actor.py new file mode 100644 index 0000000..855d2f6 --- /dev/null +++ b/tests/users/models/test_system_actor.py @@ -0,0 +1,33 @@ +import pytest +from asgiref.sync import async_to_sync +from django.test.client import RequestFactory +from pytest_httpx import HTTPXMock + +from core.signatures import HttpSignature +from users.models import SystemActor + + +@pytest.mark.django_db +def test_system_actor_signed(config_system, httpx_mock: HTTPXMock): + """ + Tests that the system actor signs requests properly + """ + system_actor = SystemActor() + system_actor.generate_keys() + # Send a fake outbound request + httpx_mock.add_response() + async_to_sync(system_actor.signed_request)( + method="get", + uri="http://example.com/test-actor", + ) + # Retrieve it and construct a fake request object + outbound_request = httpx_mock.get_request() + fake_request = RequestFactory().get( + path="/test-actor", + HTTP_HOST="example.com", + HTTP_DATE=outbound_request.headers["date"], + HTTP_SIGNATURE=outbound_request.headers["signature"], + HTTP_ACCEPT=outbound_request.headers["accept"], + ) + # Verify that + HttpSignature.verify_request(fake_request, system_actor.public_key) diff --git a/users/models/identity.py b/users/models/identity.py index a1167e5..0ea590e 100644 --- a/users/models/identity.py +++ b/users/models/identity.py @@ -398,10 +398,10 @@ class Identity(StatorModel): """ domain = handle.split("@")[1].lower() try: - response = await SystemActor().signed_request( - method="get", - uri=f"https://{domain}/.well-known/webfinger?resource=acct:{handle}", - ) + async with httpx.AsyncClient() as client: + response = await client.get( + f"https://{domain}/.well-known/webfinger?resource=acct:{handle}", + ) except (httpx.RequestError, httpx.ConnectError): return None, None if response.status_code in [404, 410]: diff --git a/users/models/system_actor.py b/users/models/system_actor.py index 46a0007..5869f92 100644 --- a/users/models/system_actor.py +++ b/users/models/system_actor.py @@ -49,6 +49,7 @@ class SystemActor: "preferredUsername": self.username, "url": self.profile_uri, "manuallyApprovesFollowers": True, + "toot:discoverable": False, "publicKey": { "id": self.public_key_id, "owner": self.actor_uri, diff --git a/users/views/activitypub.py b/users/views/activitypub.py index d80a1c8..2d17afd 100644 --- a/users/views/activitypub.py +++ b/users/views/activitypub.py @@ -219,5 +219,6 @@ class SystemActorView(View): canonicalise( SystemActor().to_ap(), include_security=True, - ) + ), + content_type="application/activity+json", ) -- cgit v1.2.3