Add activitypub well-known forwarding

Disabled until needed
This commit is contained in:
Jake Howard 2022-11-17 22:36:22 +00:00
parent d16c8d83f0
commit 37cf309bb0
Signed by: jake
GPG key ID: 57AFB45680EDD477
5 changed files with 75 additions and 3 deletions

View file

@ -29,6 +29,7 @@ django-cors-headers==3.13.0
django-csp==3.7 django-csp==3.7
django-permissions-policy==4.13.0 django-permissions-policy==4.13.0
django-enforce-host==1.1.0 django-enforce-host==1.1.0
django-proxy==1.2.1
# DRF OpenAPI dependencies # DRF OpenAPI dependencies
uritemplate uritemplate

View file

@ -14,6 +14,7 @@ env = environ.Env(
SENTRY_DSN=(str, ""), SENTRY_DSN=(str, ""),
TEST=(bool, False), TEST=(bool, False),
ALLOWED_HOSTS=(list, ["*"]), ALLOWED_HOSTS=(list, ["*"]),
ACTIVITYPUB_HOST=(str, ""),
) )
# Read local secrets # Read local secrets
@ -305,6 +306,8 @@ WAGTAIL_MODERATION_ENABLED = False
UNSPLASH_CLIENT_ID = env("UNSPLASH_CLIENT_ID") UNSPLASH_CLIENT_ID = env("UNSPLASH_CLIENT_ID")
SPOTIFY_PROXY_HOST = env("SPOTIFY_PROXY_HOST") SPOTIFY_PROXY_HOST = env("SPOTIFY_PROXY_HOST")
ACTIVITYPUB_HOST = env("ACTIVITYPUB_HOST")
SEO_INDEX = env("SEO_INDEX") SEO_INDEX = env("SEO_INDEX")
if DEBUG: if DEBUG:

View file

@ -1,4 +1,7 @@
from django.test import SimpleTestCase, TestCase from unittest.mock import patch
from django.http.response import HttpResponse
from django.test import SimpleTestCase, TestCase, override_settings
from django.urls import reverse from django.urls import reverse
@ -36,3 +39,40 @@ class MatrixClientViewTestCase(SimpleTestCase):
self.assertEqual(response.status_code, 200) self.assertEqual(response.status_code, 200)
self.assertEqual(response["Content-Type"], "application/json") self.assertEqual(response["Content-Type"], "application/json")
self.assertTemplateUsed(response, "well-known/matrix-client.json") self.assertTemplateUsed(response, "well-known/matrix-client.json")
class ActivityPubProxyView(TestCase):
PROXIED_PATHS = [
reverse("well-known:webfinger"),
reverse("well-known:hostmeta"),
reverse("well-known:nodeinfo"),
]
def setUp(self):
super().setUp()
proxy_view_patcher = patch("website.well_known.views.proxy_view")
self.proxy_view = proxy_view_patcher.start()
self.addCleanup(proxy_view_patcher.stop)
self.proxy_view.return_value = HttpResponse()
@override_settings(ACTIVITYPUB_HOST="activitypub.example.com")
def test_urls(self):
for path in self.PROXIED_PATHS:
with self.subTest(path):
response = self.client.get(path)
self.assertEqual(response.status_code, 200)
self.assertEqual(
self.proxy_view.call_args[0][1],
f"https://activitypub.example.com{path}",
)
self.assertEqual(response["Cache-Control"], "max-age=60")
@override_settings(ACTIVITYPUB_HOST="")
def test_unconfigured(self):
for path in self.PROXIED_PATHS:
with self.subTest(path):
response = self.client.get(path)
self.assertEqual(response.status_code, 404)
self.assertFalse(self.proxy_view.called)

View file

@ -20,4 +20,19 @@ urlpatterns = [
views.MatrixClientView.as_view(), views.MatrixClientView.as_view(),
name="matrix-client", name="matrix-client",
), ),
path(
"webfinger",
views.activitypub_proxy,
name="webfinger",
),
path(
"hostmeta",
views.activitypub_proxy,
name="hostmeta",
),
path(
"nodeinfo",
views.activitypub_proxy,
name="nodeinfo",
),
] ]

View file

@ -1,11 +1,13 @@
from datetime import timedelta from datetime import timedelta
from django.conf import settings
from django.http.request import HttpRequest from django.http.request import HttpRequest
from django.http.response import HttpResponse from django.http.response import Http404, HttpResponse
from django.utils import timezone from django.utils import timezone
from django.utils.decorators import method_decorator from django.utils.decorators import method_decorator
from django.views.decorators.cache import cache_control from django.views.decorators.cache import cache_control, cache_page
from django.views.generic import TemplateView from django.views.generic import TemplateView
from proxy.views import proxy_view
from website.contact.models import ContactPage from website.contact.models import ContactPage
from website.contrib.singleton_page.utils import SingletonPageCache from website.contrib.singleton_page.utils import SingletonPageCache
@ -46,3 +48,14 @@ class MatrixServerView(TemplateView):
class MatrixClientView(TemplateView): class MatrixClientView(TemplateView):
template_name = "well-known/matrix-client.json" template_name = "well-known/matrix-client.json"
content_type = "application/json" content_type = "application/json"
@cache_page(60)
def activitypub_proxy(request: HttpRequest) -> HttpResponse:
if not settings.ACTIVITYPUB_HOST:
raise Http404
return proxy_view(
request,
f"https://{settings.ACTIVITYPUB_HOST}{request.path}",
)