Code dedupe Webfinger and fix SystemActor inbox URL

This commit is contained in:
Michael Manfre 2022-11-22 23:53:02 -05:00 committed by GitHub
parent 96f863d5d8
commit f88efa40d4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 53 additions and 61 deletions

View File

@ -1,4 +1,5 @@
import os import os
import sys
from .base import * # noqa from .base import * # noqa
@ -18,7 +19,10 @@ SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https")
EMAIL_BACKEND = "django.core.mail.backends.console.EmailBackend" EMAIL_BACKEND = "django.core.mail.backends.console.EmailBackend"
SERVER_EMAIL = "test@example.com" SERVER_EMAIL = "test@example.com"
MAIN_DOMAIN = os.environ.get("TAKAHE_MAIN_DOMAIN", "https://example.com") MAIN_DOMAIN = os.environ.get("TAKAHE_MAIN_DOMAIN", "example.com")
if "/" in MAIN_DOMAIN:
print("TAKAHE_MAIN_DOMAIN should be just the domain name - no https:// or path")
sys.exit(1)
MEDIA_URL = os.environ.get("TAKAHE_MEDIA_URL", "/media/") MEDIA_URL = os.environ.get("TAKAHE_MEDIA_URL", "/media/")
MEDIA_ROOT = os.environ.get("TAKAHE_MEDIA_ROOT", BASE_DIR / "media") MEDIA_ROOT = os.environ.get("TAKAHE_MEDIA_ROOT", BASE_DIR / "media")

View File

@ -74,7 +74,7 @@ def identity(user):
""" """
domain = Domain.objects.create(domain="example.com", local=True, public=True) domain = Domain.objects.create(domain="example.com", local=True, public=True)
identity = Identity.objects.create( identity = Identity.objects.create(
actor_uri="https://example.com/test-actor/", actor_uri="https://example.com/@test@example.com/",
username="test", username="test",
domain=domain, domain=domain,
name="Test User", name="Test User",

View File

@ -1,26 +1,11 @@
import pytest import pytest
from users.models import Domain, Identity, User
@pytest.mark.django_db @pytest.mark.django_db
def test_webfinger_actor(client): def test_webfinger_actor(client, identity):
""" """
Ensures the webfinger and actor URLs are working properly Ensures the webfinger and actor URLs are working properly
""" """
# Make a user
user = User.objects.create(email="test@example.com")
# Make a domain
domain = Domain.objects.create(domain="example.com", local=True)
domain.users.add(user)
# Make an identity for them
identity = Identity.objects.create(
actor_uri="https://example.com/@test@example.com/",
username="test",
domain=domain,
name="Test User",
local=True,
)
identity.generate_keypair() identity.generate_keypair()
# Fetch their webfinger # Fetch their webfinger
data = client.get("/.well-known/webfinger?resource=acct:test@example.com").json() data = client.get("/.well-known/webfinger?resource=acct:test@example.com").json()
@ -29,3 +14,20 @@ def test_webfinger_actor(client):
# Fetch their actor # Fetch their actor
data = client.get("/@test@example.com/", HTTP_ACCEPT="application/ld+json").json() data = client.get("/@test@example.com/", HTTP_ACCEPT="application/ld+json").json()
assert data["id"] == "https://example.com/@test@example.com/" assert data["id"] == "https://example.com/@test@example.com/"
@pytest.mark.django_db
def test_webfinger_system_actor(client):
"""
Ensures the webfinger and actor URLs are working properly for system actor
"""
# Fetch their webfinger
data = client.get(
"/.well-known/webfinger?resource=acct:__system__@example.com"
).json()
assert data["subject"] == "acct:__system__@example.com"
assert data["aliases"][0] == "https://example.com/about/"
# Fetch their actor
data = client.get("/actor/", HTTP_ACCEPT="application/ld+json").json()
assert data["id"] == "https://example.com/actor/"
assert data["inbox"] == "https://example.com/actor/inbox/"

View File

@ -22,6 +22,9 @@ class SystemActor:
self.profile_uri = f"https://{settings.MAIN_DOMAIN}/about/" self.profile_uri = f"https://{settings.MAIN_DOMAIN}/about/"
self.username = "__system__" self.username = "__system__"
def absolute_profile_uri(self):
return self.profile_uri
def generate_keys(self): def generate_keys(self):
self.private_key, self.public_key = RsaKeys.generate_keypair() self.private_key, self.public_key = RsaKeys.generate_keypair()
Config.set_system("system_actor_private_key", self.private_key) Config.set_system("system_actor_private_key", self.private_key)
@ -39,7 +42,7 @@ class SystemActor:
return { return {
"id": self.actor_uri, "id": self.actor_uri,
"type": "Application", "type": "Application",
"inbox": self.actor_uri + "/inbox/", "inbox": self.actor_uri + "inbox/",
"preferredUsername": self.username, "preferredUsername": self.username,
"url": self.profile_uri, "url": self.profile_uri,
"as:manuallyApprovesFollowers": True, "as:manuallyApprovesFollowers": True,

View File

@ -99,51 +99,34 @@ class Webfinger(View):
if not resource.startswith("acct:"): if not resource.startswith("acct:"):
return HttpResponseBadRequest("Not an account resource") return HttpResponseBadRequest("Not an account resource")
handle = resource[5:] handle = resource[5:]
if handle.startswith("__system__@"): if handle.startswith("__system__@"):
# They are trying to webfinger the system actor # They are trying to webfinger the system actor
system_actor = SystemActor() actor = SystemActor()
return JsonResponse(
{
"subject": f"acct:{handle}",
"aliases": [
system_actor.profile_uri,
],
"links": [
{
"rel": "http://webfinger.net/rel/profile-page",
"type": "text/html",
"href": system_actor.profile_uri,
},
{
"rel": "self",
"type": "application/activity+json",
"href": system_actor.actor_uri,
},
],
}
)
else: else:
identity = by_handle_or_404(request, handle) actor = by_handle_or_404(request, handle)
return JsonResponse( handle = actor.handle
{
"subject": f"acct:{identity.handle}", return JsonResponse(
"aliases": [ {
identity.absolute_profile_uri(), "subject": f"acct:{handle}",
], "aliases": [
"links": [ actor.absolute_profile_uri(),
{ ],
"rel": "http://webfinger.net/rel/profile-page", "links": [
"type": "text/html", {
"href": identity.absolute_profile_uri(), "rel": "http://webfinger.net/rel/profile-page",
}, "type": "text/html",
{ "href": actor.absolute_profile_uri(),
"rel": "self", },
"type": "application/activity+json", {
"href": identity.actor_uri, "rel": "self",
}, "type": "application/activity+json",
], "href": actor.actor_uri,
} },
) ],
}
)
@method_decorator(csrf_exempt, name="dispatch") @method_decorator(csrf_exempt, name="dispatch")