From cfa43135a515867390d38384f1701064005f65f5 Mon Sep 17 00:00:00 2001 From: Ryan Barrett Date: Mon, 10 Jul 2023 11:37:40 -0700 Subject: [PATCH] Web.fetch default author bug fix, only add if URL is not homepage --- tests/test_web.py | 26 +++++++++++++++----------- tests/testutil.py | 2 +- web.py | 44 +++++++++++++++++++++++--------------------- 3 files changed, 39 insertions(+), 33 deletions(-) diff --git a/tests/test_web.py b/tests/test_web.py index 715e543..71f35fb 100644 --- a/tests/test_web.py +++ b/tests/test_web.py @@ -200,12 +200,15 @@ REPLY = requests_response(REPLY_HTML, content_type=CONTENT_TYPE_HTML, url='https://user.com/reply') REPLY_MF2 = util.parse_mf2(REPLY_HTML)['items'][0] REPLY_AS1 = microformats2.json_to_object(REPLY_MF2) +REPLY_AS1['id'] = 'https://user.com/reply' +REPLY_AS1['author']['id'] = 'https://user.com/' CREATE_REPLY_AS1 = { 'objectType': 'activity', 'verb': 'post', 'id': 'https://user.com/reply#bridgy-fed-create', - 'actor': 'http://localhost/user.com', + 'actor': ACTOR_AS1_UNWRAPPED, 'object': REPLY_AS1, + 'published': '2022-01-02T03:04:05+00:00', } REPLY_AS2 = as2.from_as1(REPLY_AS1) @@ -405,6 +408,8 @@ class WebTest(TestCase): obj.put() g.user = self.make_user('user.com', has_redirects=True, obj=obj) + self.mrs_foo = ndb.Key(ActivityPub, 'https://mas.to/mrs-foo') + def assert_deliveries(self, mock_post, inboxes, data, ignore=()): self.assertEqual(len(inboxes), len(mock_post.call_args_list), mock_post.call_args_list) @@ -719,19 +724,19 @@ class WebTest(TestCase): self.assert_deliveries(mock_post, ['https://mas.to/inbox'], AS2_CREATE) self.assert_object('https://user.com/reply', - users=[g.user.key], source_protocol='web', - mf2=REPLY_MF2, + our_as1=REPLY_AS1, type='comment', ) + author = ndb.Key(ActivityPub, 'https://mas.to/author') self.assert_object('https://user.com/reply#bridgy-fed-create', - users=[g.user.key], + users=[g.user.key, author], source_protocol='web', status='complete', our_as1=CREATE_REPLY_AS1, delivered=['https://mas.to/inbox'], type='post', - labels=['user', 'activity'], + labels=['user', 'activity', 'notification'], ) def test_update_reply(self, mock_get, mock_post): @@ -1151,9 +1156,8 @@ class WebTest(TestCase): self.assert_deliveries(mock_post, ['https://mas.to/inbox'], FOLLOW_AS2) - mrs_foo = ndb.Key(ActivityPub, 'https://mas.to/mrs-foo') obj = self.assert_object('https://user.com/follow', - users=[g.user.key, mrs_foo], + users=[g.user.key, self.mrs_foo], source_protocol='web', status='complete', mf2=FOLLOW_MF2, @@ -1239,14 +1243,14 @@ class WebTest(TestCase): FOLLOW_FRAGMENT_AS2) self.assert_object('https://user.com/follow#2', - users=[g.user.key], + users=[g.user.key, self.mrs_foo], source_protocol='web', status='complete', mf2=FOLLOW_FRAGMENT_MF2, delivered=['https://mas.to/inbox'], type='follow', object_ids=['https://mas.to/mrs-foo'], - labels=['user', 'activity'], + labels=['user', 'activity', 'notification',], ) followers = Follower.query().fetch() @@ -1420,14 +1424,14 @@ class WebTest(TestCase): self.assert_deliveries(mock_post, ['https://mas.to/inbox'], FOLLOW_AS2) self.assert_object('https://user.com/follow', - users=[g.user.key], + users=[g.user.key, self.mrs_foo], source_protocol='web', status='failed', mf2=FOLLOW_MF2, failed=['https://mas.to/inbox'], type='follow', object_ids=['https://mas.to/mrs-foo'], - labels=['user', 'activity'], + labels=['user', 'activity', 'notification',], ) def test_repost_twitter_blocklisted(self, *mocks): diff --git a/tests/testutil.py b/tests/testutil.py index 2d66edc..6d6740d 100644 --- a/tests/testutil.py +++ b/tests/testutil.py @@ -183,7 +183,7 @@ class TestCase(unittest.TestCase, testutil.Asserts): def prune(results): return [ - (tc, re.sub(r'\n File ".+/(local|.venv|Python.framework)/.+\n.+\n', + (tc, re.sub(r'\n File ".+/(local|.venv|oauth-dropins|Python.framework)/.+\n.+\n', '\n', tb)) for tc, tb in results] diff --git a/web.py b/web.py index 7565115..9f60fca 100644 --- a/web.py +++ b/web.py @@ -346,28 +346,30 @@ class Web(User, Protocol): props.setdefault('url', [parsed['url']]) logger.info(f'Extracted microformats2 entry: {json_dumps(entry, indent=2)}') - # default actor/author to home page URL - if not props.get('author'): - homepage = urljoin(url, '/') - logger.info(f'Defaulting author to {homepage}') - props['author'] = [homepage] + if not is_homepage: + # default actor/author to home page URL + if not props.get('author'): + homepage = urljoin(url, '/') + logger.info(f'Defaulting author to {homepage}') + props['author'] = [homepage] - # run full authorship algorithm if necessary: https://indieweb.org/authorship - # duplicated in microformats2.json_to_object - author = util.get_first(props, 'author') - if not isinstance(author, dict) and not is_homepage: - logger.info(f'Fetching full authorship for author {author}') - author = mf2util.find_author({'items': [entry]}, hentry=entry, - fetch_mf2_func=util.fetch_mf2) - logger.info(f'Got: {author}') - if author: - props['author'] = util.trim_nulls([{ - "type": ["h-card"], - 'properties': { - field: [author[field]] if author.get(field) else [] - for field in ('name', 'photo', 'url') - }, - }]) + # run full authorship algorithm if necessary: + # https://indieweb.org/authorship + # duplicated in microformats2.json_to_object + author = util.get_first(props, 'author') + if not isinstance(author, dict) and not is_homepage: + logger.info(f'Fetching full authorship for author {author}') + author = mf2util.find_author({'items': [entry]}, hentry=entry, + fetch_mf2_func=util.fetch_mf2) + logger.info(f'Got: {author}') + if author: + props['author'] = util.trim_nulls([{ + "type": ["h-card"], + 'properties': { + field: [author[field]] if author.get(field) else [] + for field in ('name', 'photo', 'url') + }, + }]) obj.mf2 = entry return obj