incoming Follows: synthesize url into follow object stored in Activity

rendered mf2 HTML proxy pages (in render.py) fall back to redirecting to the follow's AS2 id field, but Mastodon's ids are URLs that don't load in browsers, eg https://jawns.club/ac33c547-ca6b-4351-80d5-d11a6879a7b0. so, set a synthetic URL based on the follower's profile. fixes #336
pull/368/head
Ryan Barrett 2023-01-12 12:28:34 -08:00
rodzic 1cd963e203
commit 6520331627
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 6BE31FDF4776E9D4
5 zmienionych plików z 31 dodań i 15 usunięć

Wyświetl plik

@ -157,10 +157,10 @@ def accept_follow(follow, follow_unwrapped, user):
followee = follow.get('object')
followee_unwrapped = follow_unwrapped.get('object')
if isinstance(followee_unwrapped, dict):
followee_unwrapped = followee_unwrapped.get('id')
followee_id = (followee_unwrapped.get('id')
if isinstance(followee_unwrapped, dict) else followee_unwrapped)
follower = follow.get('actor')
if not followee or not followee_unwrapped or not follower:
if not followee or not followee_id or not follower:
error('Follow activity requires object and actor. Got: %s' % follow)
inbox = follower.get('inbox')
@ -168,8 +168,17 @@ def accept_follow(follow, follow_unwrapped, user):
if not inbox or not follower_id:
error('Follow actor requires id and inbox. Got: %s', follower)
# rendered mf2 HTML proxy pages (in render.py) fall back to redirecting to
# the follow's AS2 id field, but Mastodon's ids are URLs that don't load in
# browsers, eg https://jawns.club/ac33c547-ca6b-4351-80d5-d11a6879a7b0
# so, set a synthetic URL based on the follower's profile.
# https://github.com/snarfed/bridgy-fed/issues/336
follower_url = util.get_url(follower) or follower_id
followee_url = util.get_url(followee_unwrapped) or followee_id
follow_unwrapped.setdefault('url', f'{follower_url}#followed-{followee_url}')
# store Follower
followee_domain = util.domain_from_link(followee_unwrapped, minimize=False)
followee_domain = util.domain_from_link(followee_id, minimize=False)
# follow use_instead, if any
followee_domain = User.get_or_create(followee_domain).key.id()
follower = Follower.get_or_create(dest=followee_domain, src=follower_id,

Wyświetl plik

@ -292,7 +292,7 @@ class Activity(StringIdModel):
actor = util.get_first(as1, 'actor') or util.get_first(as1, 'author') or {}
if isinstance(actor, str):
return util.pretty_link(url)
return util.pretty_link(actor)
url = util.get_first(actor, 'url') or ''
name = actor.get('displayName') or ''

Wyświetl plik

@ -6,6 +6,7 @@ from flask import request
from granary import as2, atom, microformats2
from oauth_dropins.webutil import flask_util
from oauth_dropins.webutil.flask_util import error
from oauth_dropins.webutil import util
from oauth_dropins.webutil.util import json_loads
from app import app, cache
@ -38,5 +39,6 @@ def render():
# browsers but not for webmention receivers (hopefully).
html = microformats2.activities_to_html([as1])
utf8 = '<meta charset="utf-8">'
refresh = f'<meta http-equiv="refresh" content="0;url={source}">'
url = util.get_url(as1) or as1.get('id') or source
refresh = f'<meta http-equiv="refresh" content="0;url={url}">'
return html.replace(utf8, utf8 + '\n' + refresh)

Wyświetl plik

@ -399,7 +399,10 @@ class ActivityPubTest(testutil.TestCase):
mock_head, mock_get, mock_post)
activity = Activity.query().get()
self.assertEqual(FOLLOW_WITH_ACTOR, json_loads(activity.source_as2))
follow = copy.deepcopy(FOLLOW_WITH_ACTOR)
follow['url'] = 'https://mastodon.social/users/swentel#followed-https://www.realize.be/'
self.assertEqual(follow, json_loads(activity.source_as2))
follower = Follower.query().get()
self.assertEqual(FOLLOW_WRAPPED_WITH_ACTOR, json_loads(follower.last_follow))
@ -422,13 +425,6 @@ class ActivityPubTest(testutil.TestCase):
self._test_inbox_follow_accept(follow, accept, mock_head, mock_get, mock_post)
activity = Activity.query().get()
follow.update({
'actor': FOLLOW_WITH_ACTOR['actor'],
'object': unwrapped_user,
})
self.assertEqual(follow, json_loads(activity.source_as2))
follower = Follower.query().get()
follow.update({
'actor': ACTOR,
@ -436,6 +432,14 @@ class ActivityPubTest(testutil.TestCase):
})
self.assertEqual(follow, json_loads(follower.last_follow))
activity = Activity.query().get()
follow.update({
'actor': FOLLOW_WITH_ACTOR['actor'],
'object': unwrapped_user,
'url': 'https://mastodon.social/users/swentel#followed-https://www.realize.be/',
})
self.assertEqual(follow, json_loads(activity.source_as2))
def _test_inbox_follow_accept(self, follow_as2, accept_as2,
mock_head, mock_get, mock_post):
mock_head.return_value = requests_response(url='https://www.realize.be/')

Wyświetl plik

@ -2,6 +2,7 @@
"""Unit tests for render.py."""
from oauth_dropins.webutil.util import json_dumps
import common
from models import Activity
import render
from . import testutil
@ -42,7 +43,7 @@ class RenderTest(testutil.TestCase):
<!DOCTYPE html>
<html>
<head><meta charset="utf-8">
<meta http-equiv="refresh" content="0;url=abc"></head>
<meta http-equiv="refresh" content="0;url=http://this/reply"></head>
<body class="">
<article class="h-entry">
<span class="p-uid">http://this/reply</span>