/convert/: if dest protocol is AP, don't assume source protocol is Web

pull/723/head
Ryan Barrett 2023-11-07 14:34:54 -08:00
rodzic 9327565095
commit d2dee8752f
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 6BE31FDF4776E9D4
4 zmienionych plików z 45 dodań i 15 usunięć

Wyświetl plik

@ -527,8 +527,8 @@ def signed_request(fn, url, data=None, headers=None, **kwargs):
def postprocess_as2(activity, orig_obj=None, wrap=True):
"""Prepare an AS2 object to be served or sent via ActivityPub.
``g.user`` is required. Populates it into the ``actor.id`` and ``publicKey``
fields.
``g.user`` is required (in ``postprocess_as2_actor``). It's populated it
into the ``actor.id`` and ``publicKey`` fields.
Args:
activity (dict): AS2 object or activity

Wyświetl plik

@ -58,13 +58,6 @@ def convert(dest, _, src=None):
logger.info(f'Converting from {src_cls.LABEL} to {dest}: {id}')
# require g.user for AP since postprocess_as2 currently needs it. ugh
if dest_cls == ActivityPub:
domain = util.domain_from_link(id, minimize=False)
g.user = Web.get_by_id(domain)
if not g.user:
error(f'No web user found for {domain}')
# load, and maybe fetch. if it's a post/update, redirect to inner object.
obj = src_cls.load(id)
if not obj:
@ -86,6 +79,22 @@ def convert(dest, _, src=None):
if obj.deleted or type == 'delete':
return '', 410
# load g.user for AP since postprocess_as2 currently needs it. ugh.
if dest_cls == ActivityPub:
actor_id = as1.get_owner(obj.as1)
if not actor_id and src_cls == Web:
actor_id = util.domain_from_link(id, minimize=False)
if not actor_id:
error(f"Couldn't determine actor id for {obj.as1}")
user_key = src_cls.key_for(actor_id)
if not user_key:
error(f"Couldn't determine {src_cls.LABEL} key for {actor_id}")
g.user = user_key.get()
if not g.user:
error(f'No {src_cls.LABEL} user found for {actor_id}')
# convert and serve
return dest_cls.convert(obj), {'Content-Type': dest_cls.CONTENT_TYPE}

Wyświetl plik

@ -13,6 +13,7 @@ from oauth_dropins.webutil.util import json_loads, parse_mf2
from . import testutil
from .testutil import Fake, OtherFake
from activitypub import ActivityPub
from common import CONTENT_TYPE_HTML
COMMENT_AS2 = {
@ -95,6 +96,24 @@ class ConvertTest(testutil.TestCase):
'foo': 'bar',
}, json_loads(resp.get_data()))
def test_fake_to_activitypub(self):
self.make_user('fake:alice', cls=Fake)
self.store_object(id='fake:post', our_as1={
'actor': 'fake:alice',
'foo': 'bar',
})
resp = self.client.get('/convert/ap/fake:post',
base_url='https://fa.brid.gy/')
self.assertEqual(200, resp.status_code)
self.assertEqual(ActivityPub.CONTENT_TYPE, resp.content_type)
self.assertEqual({
'@context': 'https://www.w3.org/ns/activitystreams',
'id': 'https://fa.brid.gy/convert/ap/fake:post',
'actor': 'https://fa.brid.gy/ap/fake:alice',
'foo': 'bar',
'to': ['https://www.w3.org/ns/activitystreams#Public'],
}, json_loads(resp.get_data()))
def test_activitypub_to_web_object(self):
url = 'https://user.com/bar?baz=baj&biff'
Object(id=url, our_as1=COMMENT).put()
@ -274,7 +293,10 @@ A ☕ reply
self.assertEqual(200, resp.status_code)
self.assert_equals(COMMENT_AS2, resp.json, ignore=['to'])
def test_web_to_activitypub_no_user(self):
@patch('requests.get')
def test_web_to_activitypub_no_user(self, mock_get):
mock_get.return_value = requests_response(HTML) # protocol inference
resp = self.client.get(f'/convert/ap/http://nope.com/post',
base_url='https://web.brid.gy/')
self.assertEqual(400, resp.status_code)

9
web.py
Wyświetl plik

@ -245,14 +245,13 @@ class Web(User, Protocol):
If id is a domain, uses it as is. If it's a home page URL or fed.brid.gy
or web.brid.gy AP actor URL, extracts the domain and uses that.
Otherwise, raises AssertionError.
Otherwise, returns None.
Args:
id: str
id (str)
Raises:
ValueError
AssertionError
Returns:
ndb.Key or None:
"""
if not id:
return None