background task bug fix: override task runner host

we were using request.host_url blindly, which was fed.brid.gy for user-facing requests, but bridgy-federated.uc.r.appspot.com for tasks. #335
unfollow
Ryan Barrett 2023-01-05 15:03:21 -08:00
rodzic e653bd6be1
commit 7ac1006021
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 6BE31FDF4776E9D4
8 zmienionych plików z 60 dodań i 32 usunięć

Wyświetl plik

@ -178,7 +178,7 @@ def accept_follow(follow, follow_unwrapped, user):
# send AP Accept
accept = {
'@context': 'https://www.w3.org/ns/activitystreams',
'id': util.tag_uri(request.host, 'accept/%s/%s' % (
'id': util.tag_uri(common.PRIMARY_DOMAIN, 'accept/%s/%s' % (
(followee_domain, follow.get('id')))),
'type': 'Accept',
'actor': followee,

Wyświetl plik

@ -32,5 +32,5 @@ def add_wm(url=None):
resp = flask.make_response(got.content, got.status_code, dict(got.headers))
resp.headers.add('Link', LINK_HEADER % (request.args.get('endpoint') or
request.host_url + 'webmention'))
common.host_url('webmention')))
return resp

Wyświetl plik

@ -65,9 +65,14 @@ SUPPORTED_VERBS = (
PRIMARY_DOMAIN = 'fed.brid.gy'
OTHER_DOMAINS = (
'bridgy-federated.appspot.com',
'localhost',
'bridgy-federated.uc.r.appspot.com',
)
DOMAINS = (PRIMARY_DOMAIN,) + OTHER_DOMAINS
LOCAL_DOMAINS = (
'localhost',
'localhost:8080',
'my.dev.com:8080',
)
DOMAINS = (PRIMARY_DOMAIN,) + OTHER_DOMAINS + LOCAL_DOMAINS
# TODO: unify with Bridgy's
DOMAIN_BLOCKLIST = frozenset((
# https://github.com/snarfed/bridgy-fed/issues/348
@ -83,6 +88,13 @@ _DEFAULT_SIGNATURE_USER = None
CACHE_TIME = datetime.timedelta(seconds=10)
def host_url(path_query=None):
domain = util.domain_from_link(request.host_url)
base = (f'https://{PRIMARY_DOMAIN}' if util.domain_or_parent_in(domain, OTHER_DOMAINS)
else request.host_url)
return urllib.parse.urljoin(base, path_query)
def default_signature_user():
global _DEFAULT_SIGNATURE_USER
if _DEFAULT_SIGNATURE_USER is None:
@ -135,7 +147,7 @@ def signed_request(fn, url, data=None, user=None, headers=None, **kwargs):
domain = user.key.id()
logger.info(f"Signing with {domain}'s key")
key_id = request.host_url + domain
key_id = host_url(domain)
auth = HTTPSignatureAuth(secret=user.private_pem(), key_id=key_id,
algorithm='rsa-sha256', sign_header='signature',
headers=('Date', 'Host', 'Digest'))
@ -262,7 +274,7 @@ def send_webmentions(activity_wrapped, proxy=None, **activity_props):
for tag in tags:
if tag.get('objectType') == 'mention':
url = tag.get('url')
if url and url.startswith(request.host_url):
if url and url.startswith(host_url()):
targets.append(redirect_unwrap(url))
if verb in ('follow', 'like', 'share'):
@ -334,7 +346,7 @@ def postprocess_as2(activity, user=None, target=None, create=True):
# underspecified, inferred from this issue and Mastodon's implementation:
# https://github.com/w3c/activitypub/issues/203#issuecomment-297553229
# https://github.com/tootsuite/mastodon/blob/bc2c263504e584e154384ecc2d804aeb1afb1ba3/app/services/activitypub/process_account_service.rb#L77
actor_url = request.host_url + activity.get('preferredUsername')
actor_url = host_url(activity.get('preferredUsername'))
activity.update({
'publicKey': {
'id': actor_url,
@ -452,7 +464,7 @@ def postprocess_as2_actor(actor, user=None):
domain = util.domain_from_link(urls[0], minimize=False)
urls[0] = redirect_wrap(urls[0])
actor.setdefault('id', request.host_url + domain)
actor.setdefault('id', host_url(domain))
actor.update({
'url': urls if len(urls) > 1 else urls[0],
# This has to be the domain for Mastodon interop/Webfinger discovery!
@ -481,7 +493,7 @@ def redirect_wrap(url):
if not url:
return url
prefix = urllib.parse.urljoin(request.host_url, '/r/')
prefix = host_url('/r/')
if url.startswith(prefix):
return url
@ -508,13 +520,13 @@ def redirect_unwrap(val):
return [redirect_unwrap(v) for v in val]
elif isinstance(val, str):
prefix = urllib.parse.urljoin(request.host_url, '/r/')
prefix = host_url('/r/')
if val.startswith(prefix):
unwrapped = val.removeprefix(prefix)
if util.is_web(unwrapped):
return util.follow_redirects(unwrapped).url
elif val.startswith(request.host_url):
path = val.removeprefix(request.host_url)
elif val.startswith(host_url()):
path = val.removeprefix(host_url())
if re.match(DOMAIN_RE, path):
return util.follow_redirects(path).url
@ -555,19 +567,19 @@ def actor(domain, user=None):
actor = postprocess_as2(
as2.from_as1(microformats2.json_to_object(hcard)), user=user)
actor.update({
'id': f'{request.host_url}{domain}',
'id': host_url(domain),
# This has to be the domain for Mastodon etc interop! It seems like it
# should be the custom username from the acct: u-url in their h-card,
# but that breaks Mastodon's Webfinger discovery. Background:
# https://github.com/snarfed/bridgy-fed/issues/302#issuecomment-1324305460
# https://github.com/snarfed/bridgy-fed/issues/77
'preferredUsername': domain,
'inbox': f'{request.host_url}{domain}/inbox',
'outbox': f'{request.host_url}{domain}/outbox',
'following': f'{request.host_url}{domain}/following',
'followers': f'{request.host_url}{domain}/followers',
'inbox': host_url(f'{domain}/inbox'),
'outbox': host_url(f'{domain}/outbox'),
'following': host_url(f'{domain}/following'),
'followers': host_url(f'{domain}/followers'),
'endpoints': {
'sharedInbox': f'{request.host_url}inbox',
'sharedInbox': host_url('inbox'),
},
})

Wyświetl plik

@ -188,7 +188,7 @@ class User(StringIdModel):
url = urllib.parse.urljoin(site, path)
resp = util.requests_get(url, gateway=False)
domain_urls = ([f'https://{domain}/' for domain in common.DOMAINS] +
[request.host_url])
[common.host_url()])
expected = [urllib.parse.urljoin(url, path) for url in domain_urls]
if resp.ok:
if resp.url in expected:
@ -265,10 +265,10 @@ class Activity(StringIdModel):
"""Returns the Bridgy Fed proxy URL to render this post as HTML."""
if self.source_mf2 or self.source_as2 or self.source_atom:
source, target = self.key.id().split(' ')
return f'{request.host_url}render?' + urllib.parse.urlencode({
return common.host_url('render?' + urllib.parse.urlencode({
'source': source,
'target': target,
})
}))
def to_as1(self):
"""Returns this activity as an ActivityStreams 1 dict, if available."""

Wyświetl plik

@ -120,7 +120,7 @@ FOLLOW_WRAPPED_WITH_ACTOR['actor'] = ACTOR
ACCEPT = {
'@context': 'https://www.w3.org/ns/activitystreams',
'type': 'Accept',
'id': 'tag:localhost:accept/www.realize.be/https://mastodon.social/6d1a',
'id': 'tag:fed.brid.gy:accept/www.realize.be/https://mastodon.social/6d1a',
'actor': 'http://localhost/www.realize.be',
'object': {
'type': 'Follow',

Wyświetl plik

@ -153,3 +153,18 @@ class CommonTest(testutil.TestCase):
'id': 'xyz',
'type': 'Note',
}, user=User(id='foo.com')))
def test_host_url(self):
with app.test_request_context():
self.assertEqual('http://localhost/', common.host_url())
self.assertEqual('http://localhost/asdf', common.host_url('asdf'))
self.assertEqual('http://localhost/foo/bar', common.host_url('/foo/bar'))
with app.test_request_context(base_url='https://a.xyz', path='/foo'):
self.assertEqual('https://a.xyz/', common.host_url())
self.assertEqual('https://a.xyz/asdf', common.host_url('asdf'))
self.assertEqual('https://a.xyz/foo/bar', common.host_url('/foo/bar'))
with app.test_request_context(base_url='http://bridgy-federated.uc.r.appspot.com'):
self.assertEqual('https://fed.brid.gy/asdf', common.host_url('asdf'))

Wyświetl plik

@ -118,18 +118,18 @@ class Actor(flask_util.XrdOrJrd):
# WARNING: in python 2 sometimes request.host_url lost port,
# http://localhost:8080 would become just http://localhost. no
# clue how or why. pay attention here if that happens again.
'href': f'{request.host_url}{domain}',
'href': common.host_url(domain),
}, {
'rel': 'inbox',
'type': common.CONTENT_TYPE_AS2,
'href': f'{request.host_url}{domain}/inbox',
'href': common.host_url(f'{domain}/inbox'),
}, {
# AP reads this from the AS2 actor, not webfinger, so strictly
# speaking, it's probably not needed here.
# https://www.w3.org/TR/activitypub/#sharedInbox
'rel': 'sharedInbox',
'type': common.CONTENT_TYPE_AS2,
'href': f'{request.host_url}inbox',
'href': common.host_url('inbox'),
},
# OStatus
@ -150,7 +150,7 @@ class Actor(flask_util.XrdOrJrd):
# https://github.com/snarfed/bridgy-fed/issues/60#issuecomment-1325589750
{
'rel': 'http://ostatus.org/schema/1.0/subscribe',
'template': f'{request.host_url}user/{domain}?url={{uri}}',
'template': common.host_url(f'user/{domain}?url={{uri}}'),
}]
})
logger.info(f'Returning WebFinger data: {json_dumps(data, indent=2)}')
@ -167,10 +167,11 @@ class Webfinger(Actor):
"""
def template_vars(self):
resource = flask_util.get_required_param('resource').strip()
resource = resource.removeprefix(request.host_url)
resource = resource.removeprefix(common.host_url())
# handle Bridgy Fed actor URLs, eg https://fed.brid.gy/snarfed.org
if resource in ('', '/', f'acct:{request.host}', f'acct:@{request.host}'):
host = util.domain_from_link(common.host_url())
if resource in ('', '/', f'acct:{host}', f'acct:@{host}'):
error('Expected other domain, not fed.brid.gy')
try:
@ -199,13 +200,13 @@ class HostMeta(flask_util.XrdOrJrd):
return 'host-meta'
def template_vars(self):
return {'host_uri': request.host_url}
return {'host_uri': common.host_url()}
@app.get('/.well-known/host-meta.xrds')
def host_meta_xrds():
"""Renders and serves the /.well-known/host-meta.xrds XRDS-Simple file."""
return (render_template('host-meta.xrds', host_uri=request.host_url),
return (render_template('host-meta.xrds', host_uri=common.host_url()),
{'Content-Type': 'application/xrds+xml'})

Wyświetl plik

@ -71,7 +71,7 @@ class Webmention(View):
if domain in source_resp.text:
break
else:
error(f"Couldn't find link to {request.host_url.rstrip('/')}")
error(f"Couldn't find link to {common.host_url().rstrip('/')}")
# convert source page to ActivityStreams
entry = mf2util.find_first_entry(self.source_mf2, ['h-entry'])
@ -118,7 +118,7 @@ class Webmention(View):
source_activity = common.postprocess_as2(
as2.from_as1(self.source_obj), target=target_obj, user=self.user)
if not source_activity.get('actor'):
source_activity['actor'] = f'{request.host_url}{self.source_domain}'
source_activity['actor'] = common.host_url(self.source_domain)
if activity.status == 'complete':
if activity.source_mf2: