diff --git a/redirect.py b/redirect.py index d15db27..2a8c71e 100644 --- a/redirect.py +++ b/redirect.py @@ -89,7 +89,7 @@ def redir(to): if accept_as2: # AS2 requested, fetch and convert and serve - obj = Webmention.load(to) + obj = Webmention.load(to, check_backlink=False) if not obj or obj.deleted: return f'Object not found: {to}', 404 ret = activitypub.postprocess_as2(as2.from_as1(obj.as1)) diff --git a/tests/test_redirect.py b/tests/test_redirect.py index 0bcac57..8c2a9cc 100644 --- a/tests/test_redirect.py +++ b/tests/test_redirect.py @@ -69,11 +69,11 @@ class RedirectTest(testutil.TestCase): def test_as2_no_user(self): with self.request_context: - Object(id='https://user.com/post', as2=EXTERNAL_REPOST_AS2).put() + Object(id='https://user.com/repost', as2=EXTERNAL_REPOST_AS2).put() self.user.key.delete() - resp = self.client.get('/r/https://user.com/post', + resp = self.client.get('/r/https://user.com/repost', headers={'Accept': as2.CONTENT_TYPE}) self.assertEqual(200, resp.status_code, resp.get_data(as_text=True)) self.assert_equals(EXTERNAL_REPOST_AS2, resp.json) @@ -82,7 +82,20 @@ class RedirectTest(testutil.TestCase): def test_as2_fetch_post(self, mock_get): mock_get.return_value = requests_response(REPOST_HTML) - resp = self.client.get('/r/https://user.com/post', + resp = self.client.get('/r/https://user.com/repost', + headers={'Accept': as2.CONTENT_TYPE}) + self.assertEqual(200, resp.status_code, resp.get_data(as_text=True)) + self.assert_equals({ + **REPOST_AS2, + 'actor': ACTOR_AS2, + }, resp.json) + + @patch('requests.get') + def test_as2_fetch_post_no_backlink(self, mock_get): + mock_get.return_value = requests_response( + REPOST_HTML.replace('', '')) + + resp = self.client.get('/r/https://user.com/repost', headers={'Accept': as2.CONTENT_TYPE}) self.assertEqual(200, resp.status_code, resp.get_data(as_text=True)) self.assert_equals({ diff --git a/tests/test_webmention.py b/tests/test_webmention.py index 921cdb0..0a71b7f 100644 --- a/tests/test_webmention.py +++ b/tests/test_webmention.py @@ -514,7 +514,7 @@ class WebmentionTest(testutil.TestCase): data={'source': 'https://user.com/reply'}) self.assertEqual(502, got.status_code) - def test_no_backlink(self, mock_get, mock_post): + def test_missing_backlink(self, mock_get, mock_post): mock_get.return_value = requests_response( self.reply_html.replace('', ''), url='https://user.com/reply', content_type=CONTENT_TYPE_HTML) @@ -1375,6 +1375,15 @@ class WebmentionUtilTest(testutil.TestCase): with self.assertRaises(BadGateway) as e: Webmention.fetch(Object(id='https://foo'), gateway=True) + def test_fetch_check_backlink_false(self, mock_get, mock_post): + mock_get.return_value = requests_response( + REPOST_HTML.replace('', '')) + + obj = Object(id='https://foo') + Webmention.fetch(obj, check_backlink=False) + self.assert_equals(REPOST_MF2, obj.mf2) + mock_get.assert_has_calls((self.req('https://foo'),)) + def test_fetch_run_authorship(self, mock_get, __): mock_get.side_effect = [ # post diff --git a/webmention.py b/webmention.py index a052c43..5d2d27e 100644 --- a/webmention.py +++ b/webmention.py @@ -52,7 +52,7 @@ class Webmention(Protocol): return True @classmethod - def fetch(cls, obj, gateway=False): + def fetch(cls, obj, gateway=False, check_backlink=None): """Fetches a URL over HTTP and extracts its microformats2. Follows redirects, but doesn't change the original URL in obj's id! The @@ -64,11 +64,16 @@ class Webmention(Protocol): Args: gateway: passed through to :func:`webutil.util.fetch_mf2` + check_backlink: bool, optional, whether to require a link to Bridgy Fed """ url = obj.key.id() is_homepage = ((g.user and g.user.is_homepage(url)) or (g.external_user and g.external_user == url)) - require_backlink = common.host_url().rstrip('/') if not is_homepage else None + + + require_backlink = None + if check_backlink or (check_backlink is None and not is_homepage): + require_backlink = common.host_url().rstrip('/') try: parsed = util.fetch_mf2(url, gateway=gateway,