kopia lustrzana https://github.com/snarfed/bridgy-fed
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. #335unfollow
rodzic
e653bd6be1
commit
7ac1006021
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
44
common.py
44
common.py
|
@ -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'),
|
||||
},
|
||||
})
|
||||
|
||||
|
|
|
@ -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."""
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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'))
|
||||
|
||||
|
|
17
webfinger.py
17
webfinger.py
|
@ -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'})
|
||||
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
Ładowanie…
Reference in New Issue