From d433dd3abe5b79b2e01d885b57dae69f226b6f15 Mon Sep 17 00:00:00 2001 From: Ryan Barrett Date: Sun, 19 Mar 2023 09:32:12 -0700 Subject: [PATCH] wm => AP: switch actors in outgoing activities from objects to string ids mostly. also inlines single-element attributedTo lists to just the element, without the list. --- activitypub.py | 11 ++++++++--- tests/test_activitypub.py | 6 +----- tests/test_redirect.py | 5 +---- tests/test_webmention.py | 30 ++++++++++-------------------- webmention.py | 8 ++++++-- 5 files changed, 26 insertions(+), 34 deletions(-) diff --git a/activitypub.py b/activitypub.py index 6198b3d..eba7d6e 100644 --- a/activitypub.py +++ b/activitypub.py @@ -306,9 +306,11 @@ def postprocess_as2(activity, *, user=None, target=None, create=True): }) return activity - for actor in (util.get_list(activity, 'attributedTo') + - util.get_list(activity, 'actor')): - postprocess_as2_actor(actor, user=user) + for field in 'actor', 'attributedTo': + activity[field] = [postprocess_as2_actor(actor, user=user) + for actor in util.get_list(activity, field)] + if len(activity[field]) == 1: + activity[field] = activity[field][0] # inReplyTo: singly valued, prefer id over url target_id = target.get('id') if target else None @@ -430,6 +432,9 @@ def postprocess_as2_actor(actor, *, user=None): Returns: actor dict """ + if not actor or isinstance(actor, str): + return user.actor_id() if user.is_homepage(actor) else actor + url = user.homepage if user else None urls = util.get_list(actor, 'url') if not urls and url: diff --git a/tests/test_activitypub.py b/tests/test_activitypub.py index 9001892..d692dfb 100644 --- a/tests/test_activitypub.py +++ b/tests/test_activitypub.py @@ -1218,11 +1218,7 @@ class ActivityPubUtilsTest(testutil.TestCase): '@context': 'https://www.w3.org/ns/activitystreams', 'id': 'http://localhost/r/xyz#bridgy-fed-create', 'type': 'Create', - 'actor': { - 'id': 'http://localhost/site', - 'url': 'http://localhost/r/https://site/', - 'preferredUsername': 'site' - }, + 'object': { 'id': 'http://localhost/r/xyz', 'type': 'Note', diff --git a/tests/test_redirect.py b/tests/test_redirect.py index 1b6be26..f3207fd 100644 --- a/tests/test_redirect.py +++ b/tests/test_redirect.py @@ -79,10 +79,7 @@ class RedirectTest(testutil.TestCase): self.assertEqual(200, resp.status_code, resp.get_data(as_text=True)) self.assertEqual(content_type, resp.content_type) - expected = copy.deepcopy(REPOST_AS2) - # TODO: fix - expected['actor']['id'] = 'https://user.com/' - self.assert_equals(expected, resp.json) + self.assert_equals(REPOST_AS2, resp.json) def test_as2_deleted(self): with app.test_request_context('/'): diff --git a/tests/test_webmention.py b/tests/test_webmention.py index 8f97cec..38eaec0 100644 --- a/tests/test_webmention.py +++ b/tests/test_webmention.py @@ -121,7 +121,7 @@ REPOST_AS2 = { 'https://mas.to/recipient', as2.PUBLIC_AUDIENCE, ], - 'actor': ACTOR_AS2, + 'actor': 'http://localhost/user.com', } REPOST_AS1_UNWRAPPED = { 'objectType': 'activity', @@ -210,11 +210,7 @@ class WebmentionTest(testutil.TestCase): '@context': 'https://www.w3.org/ns/activitystreams', 'type': 'Create', 'id': 'http://localhost/r/https://user.com/reply#bridgy-fed-create', - 'actor': { - 'id': 'http://localhost/user.com', - 'url': 'http://localhost/r/https://user.com/', - 'preferredUsername': 'user.com', - }, + 'actor': 'http://localhost/user.com', 'object': { '@context': 'https://www.w3.org/ns/activitystreams', 'type': 'Note', @@ -233,7 +229,7 @@ class WebmentionTest(testutil.TestCase): 'https://mas.to/bystander', as2.PUBLIC_AUDIENCE, ], - 'attributedTo': [ACTOR_AS2], + 'attributedTo': ACTOR_AS2, 'tag': [{ 'type': 'Mention', 'href': 'https://mas.to/author', @@ -266,7 +262,7 @@ class WebmentionTest(testutil.TestCase): 'id': 'http://localhost/r/https://user.com/follow', 'url': 'http://localhost/r/https://user.com/follow', 'object': 'https://mas.to/mrs-foo', - 'actor': ACTOR_AS2, + 'actor': 'http://localhost/user.com', 'to': [as2.PUBLIC_AUDIENCE], } @@ -317,11 +313,7 @@ class WebmentionTest(testutil.TestCase): '@context': 'https://www.w3.org/ns/activitystreams', 'type': 'Create', 'id': 'http://localhost/r/https://user.com/post#bridgy-fed-create', - 'actor': { - 'id': 'http://localhost/user.com', - 'url': 'http://localhost/r/https://user.com/', - 'preferredUsername': 'user.com', - }, + 'actor': 'http://localhost/user.com', 'object': { '@context': 'https://www.w3.org/ns/activitystreams', 'type': 'Note', @@ -329,7 +321,7 @@ class WebmentionTest(testutil.TestCase): 'url': 'http://localhost/r/https://user.com/post', 'name': 'hello i am a post', 'content': 'hello i am a post', - 'attributedTo': [ACTOR_AS2], + 'attributedTo': ACTOR_AS2, 'to': [as2.PUBLIC_AUDIENCE], }, } @@ -569,10 +561,10 @@ class WebmentionTest(testutil.TestCase): https://github.com/snarfed/bridgy-fed/issues/40 """ del self.toot_as2_data['actor'] - self.toot_as2_data['attributedTo'] = [{ + self.toot_as2_data['attributedTo'] = { 'type': 'Person', 'id': 'https://mas.to/author', - }] + } mock_get.side_effect = [self.reply, self.not_fediverse, self.toot_as2, self.actor] @@ -948,7 +940,7 @@ class WebmentionTest(testutil.TestCase): self.assertEqual(self.follow_as2, followers[0].last_follow) def test_follow_no_actor(self, mock_get, mock_post): - self.user.actor_as2 = self.follow_as2['actor'] + self.user.actor_as2 = ACTOR_AS2 self.user.put() html = self.follow_html.replace( @@ -966,9 +958,7 @@ class WebmentionTest(testutil.TestCase): args, kwargs = mock_post.call_args self.assertEqual(('https://mas.to/inbox',), args) - expected = self.follow_as2 - expected['actor'] = 'http://localhost/user.com' - self.assert_equals(expected, json_loads(kwargs['data'])) + self.assert_equals(self.follow_as2, json_loads(kwargs['data'])) def test_follow_fragment(self, mock_get, mock_post): mock_get.side_effect = [self.follow_fragment, self.actor] diff --git a/webmention.py b/webmention.py index 783e2b0..c9e2858 100644 --- a/webmention.py +++ b/webmention.py @@ -192,8 +192,12 @@ class Webmention(View): if not self.source_as2: self.source_as2 = activitypub.postprocess_as2( as2.from_as1(self.source_as1), target=target_as2, user=self.user) - if not self.source_as2.get('actor'): - self.source_as2['actor'] = self.user.actor_id() + + orig_actor = self.source_as2.get('actor') + if orig_actor: + logging.info(f'Overriding actor with {self.user.actor_id()}; was {orig_actor}') + self.source_as2['actor'] = self.user.actor_id() + if changed: self.source_as2['type'] = 'Update'