kopia lustrzana https://github.com/snarfed/bridgy-fed
handle redirects of signed requests manually, generate a new HTTP sig each time
fixes #326pull/373/head
rodzic
6860d49dd1
commit
e6d4441292
|
@ -124,6 +124,7 @@ def signed_request(fn, url, data=None, user=None, headers=None, **kwargs):
|
|||
logging.info(f'Sending AS2 object: {json_dumps(data, indent=2)}')
|
||||
data = kwargs['data'] = json_dumps(data).encode()
|
||||
|
||||
headers = copy.deepcopy(headers)
|
||||
headers.update({
|
||||
# required for HTTP Signature
|
||||
# https://tools.ietf.org/html/draft-cavage-http-signatures-07#section-2.1.3
|
||||
|
@ -145,9 +146,13 @@ def signed_request(fn, url, data=None, user=None, headers=None, **kwargs):
|
|||
|
||||
# make HTTP request
|
||||
kwargs.setdefault('gateway', True)
|
||||
resp = fn(url, auth=auth, headers=headers, **kwargs)
|
||||
resp = fn(url, auth=auth, headers=headers, allow_redirects=False, **kwargs)
|
||||
|
||||
logger.info(f'Got {resp.status_code} headers: {resp.headers}')
|
||||
# handle redirects manually so that we generate a new HTTP signature
|
||||
if resp.is_redirect:
|
||||
return signed_request(fn, resp.headers['Location'], data=data, user=user,
|
||||
headers=headers, **kwargs)
|
||||
type = content_type(resp)
|
||||
if (type and type != 'text/html' and
|
||||
(type.startswith('text/') or type.endswith('+json') or type.endswith('/json'))):
|
||||
|
|
|
@ -168,3 +168,17 @@ class CommonTest(testutil.TestCase):
|
|||
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'))
|
||||
|
||||
@mock.patch('requests.get')
|
||||
def test_signed_request_redirects_manually_with_new_sig_headers(self, mock_get):
|
||||
mock_get.side_effect = [
|
||||
requests_response(status=302, redirected_url='http://second',
|
||||
allow_redirects=False),
|
||||
requests_response(status=200, allow_redirects=False),
|
||||
]
|
||||
resp = common.signed_get('https://first')
|
||||
|
||||
first = mock_get.call_args_list[0][1]
|
||||
second = mock_get.call_args_list[1][1]
|
||||
self.assertNotEqual(first['headers'], second['headers'])
|
||||
self.assertNotEqual(first['auth'].header_signer.sign(first['headers']),
|
||||
second['auth'].header_signer.sign(second['headers']))
|
||||
|
|
|
@ -586,7 +586,7 @@ class WebmentionTest(testutil.TestCase):
|
|||
self.req('http://a/reply'),
|
||||
self.as2_req('http://not/fediverse'),
|
||||
self.as2_req('http://orig/post'),
|
||||
self.req('http://orig/as2', auth=mock.ANY, headers=as2.CONNEG_HEADERS),
|
||||
self.as2_req('http://orig/as2', headers=as2.CONNEG_HEADERS),
|
||||
self.as2_req('http://orig/author'),
|
||||
))
|
||||
|
||||
|
|
|
@ -45,17 +45,16 @@ class TestCase(unittest.TestCase, testutil.Asserts):
|
|||
return call(url, **kwargs)
|
||||
|
||||
def as2_req(self, url, **kwargs):
|
||||
# TODO: these aren't currently getting checked?!
|
||||
headers = {
|
||||
'Date': 'Wed, 23 Nov 2022 22:29:19 GMT',
|
||||
'Date': 'Sun, 02 Jan 2022 03:04:05 GMT',
|
||||
'Host': util.domain_from_link(url, minimize=False),
|
||||
'Content-Type': 'application/activity+json',
|
||||
'Digest': ANY,
|
||||
**common.CONNEG_HEADERS_AS2_HTML,
|
||||
**kwargs.pop('headers', {}),
|
||||
}
|
||||
return self.req(url, auth=ANY, headers=headers, **kwargs)
|
||||
|
||||
return self.req(url, auth=ANY, headers=headers, allow_redirects=False,
|
||||
**kwargs)
|
||||
def as2_resp(self, obj):
|
||||
return requests_response(obj, content_type=as2.CONTENT_TYPE)
|
||||
|
||||
|
|
Ładowanie…
Reference in New Issue