kopia lustrzana https://github.com/snarfed/bridgy-fed
switch webfinger and AP actors to mostly protocol subdomains
except Web, it still mostly serves on fed.brid.gy for backcompat, don't want to change existing Web users' AP actor ids.pull/653/head
rodzic
ef44dae317
commit
ad0a942034
|
@ -703,13 +703,24 @@ def postprocess_as2_actor(actor, wrap=True):
|
||||||
return actor
|
return actor
|
||||||
|
|
||||||
|
|
||||||
|
# source protocol in subdomain.
|
||||||
|
# WARNING: the user page handler in pages.py overrides this for fediverse
|
||||||
|
# addresses with leading @ character. be careful when changing this route!
|
||||||
|
@app.get(f'/ap/<handle_or_id>', defaults={'protocol': None})
|
||||||
|
# source protocol in path; primarily for localhost testing
|
||||||
@app.get(f'/ap/<any({",".join(PROTOCOLS)}):protocol>/<handle_or_id>')
|
@app.get(f'/ap/<any({",".join(PROTOCOLS)}):protocol>/<handle_or_id>')
|
||||||
# special case Web users without /ap/web/ prefix, for backward compatibility
|
# special case Web users without /ap/web/ prefix, for backward compatibility
|
||||||
@app.get(f'/<regex("{DOMAIN_RE}"):handle_or_id>', defaults={'protocol': 'web'})
|
@app.get(f'/<regex("{DOMAIN_RE}"):handle_or_id>', defaults={'protocol': 'web'})
|
||||||
@flask_util.cached(cache, CACHE_TIME)
|
@flask_util.cached(cache, CACHE_TIME)
|
||||||
def actor(protocol, handle_or_id):
|
def actor(protocol, handle_or_id):
|
||||||
"""Serves a user's AS2 actor from the datastore."""
|
"""Serves a user's AS2 actor from the datastore."""
|
||||||
cls = PROTOCOLS[protocol]
|
if protocol:
|
||||||
|
cls = PROTOCOLS[protocol]
|
||||||
|
else:
|
||||||
|
cls = Protocol.for_request(fed=None)
|
||||||
|
|
||||||
|
if not cls:
|
||||||
|
error(f"Couldn't determine protocol")
|
||||||
|
|
||||||
if cls.owns_id(handle_or_id) is False:
|
if cls.owns_id(handle_or_id) is False:
|
||||||
if cls.owns_handle(handle_or_id) is False:
|
if cls.owns_handle(handle_or_id) is False:
|
||||||
|
@ -739,7 +750,7 @@ def actor(protocol, handle_or_id):
|
||||||
'following': g.user.ap_actor('following'),
|
'following': g.user.ap_actor('following'),
|
||||||
'followers': g.user.ap_actor('followers'),
|
'followers': g.user.ap_actor('followers'),
|
||||||
'endpoints': {
|
'endpoints': {
|
||||||
'sharedInbox': host_url('/ap/sharedInbox'),
|
'sharedInbox': cls.subdomain_url('/ap/sharedInbox'),
|
||||||
},
|
},
|
||||||
# add this if we ever change the Web actor ids to be /web/[id]
|
# add this if we ever change the Web actor ids to be /web/[id]
|
||||||
# 'alsoKnownAs': [host_url(id)],
|
# 'alsoKnownAs': [host_url(id)],
|
||||||
|
@ -764,6 +775,8 @@ def actor(protocol, handle_or_id):
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# note that this path overlaps with the /ap/<handle_or_id> actor route above,
|
||||||
|
# but doesn't collide because this is POST and that one is GET.
|
||||||
@app.post('/ap/sharedInbox')
|
@app.post('/ap/sharedInbox')
|
||||||
@app.post(f'/ap/<any({",".join(PROTOCOLS)}):protocol>/<regex("{DOMAIN_RE}"):domain>/inbox')
|
@app.post(f'/ap/<any({",".join(PROTOCOLS)}):protocol>/<regex("{DOMAIN_RE}"):domain>/inbox')
|
||||||
# special case Web users without /ap/web/ prefix, for backward compatibility
|
# special case Web users without /ap/web/ prefix, for backward compatibility
|
||||||
|
|
|
@ -403,7 +403,7 @@ class User(StringIdModel, metaclass=ProtocolUserMeta):
|
||||||
def ap_actor(self, rest=None):
|
def ap_actor(self, rest=None):
|
||||||
"""Returns this user's ActivityPub/AS2 actor id.
|
"""Returns this user's ActivityPub/AS2 actor id.
|
||||||
|
|
||||||
Eg ``https://fed.brid.gy/ap/atproto/foo.com`.
|
Eg ``https://atproto.brid.gy/ap/foo.com`.
|
||||||
|
|
||||||
May be overridden by subclasses.
|
May be overridden by subclasses.
|
||||||
|
|
||||||
|
@ -414,7 +414,7 @@ class User(StringIdModel, metaclass=ProtocolUserMeta):
|
||||||
str
|
str
|
||||||
"""
|
"""
|
||||||
# must match the URL route for activitypub.actor()
|
# must match the URL route for activitypub.actor()
|
||||||
url = common.host_url(f'/ap/{self.ABBREV}/{self.key.id()}')
|
url = self.subdomain_url(f'/ap/{self.key.id()}')
|
||||||
if rest:
|
if rest:
|
||||||
url += f'/{rest.lstrip("/")}'
|
url += f'/{rest.lstrip("/")}'
|
||||||
return url
|
return url
|
||||||
|
|
6
pages.py
6
pages.py
|
@ -91,7 +91,13 @@ def web_user_redirects(**kwargs):
|
||||||
|
|
||||||
|
|
||||||
@app.get(f'/<any({",".join(PROTOCOLS)}):protocol>/<id>')
|
@app.get(f'/<any({",".join(PROTOCOLS)}):protocol>/<id>')
|
||||||
|
# WARNING: this overrides the /ap/... actor URL route in activitypub.py, *only*
|
||||||
|
# for handles with leading @ character. be careful when changing this route!
|
||||||
|
@app.get(f'/ap/@<id>', defaults={'protocol': 'ap'})
|
||||||
def user(protocol, id):
|
def user(protocol, id):
|
||||||
|
if protocol == 'ap' and not id.startswith('@'):
|
||||||
|
id = '@' + id
|
||||||
|
|
||||||
load_user(protocol, id)
|
load_user(protocol, id)
|
||||||
|
|
||||||
query = Object.query(OR(Object.users == g.user.key,
|
query = Object.query(OR(Object.users == g.user.key,
|
||||||
|
|
|
@ -56,7 +56,7 @@ ACTOR_BASE = {
|
||||||
'following': 'http://localhost/user.com/following',
|
'following': 'http://localhost/user.com/following',
|
||||||
'followers': 'http://localhost/user.com/followers',
|
'followers': 'http://localhost/user.com/followers',
|
||||||
'endpoints': {
|
'endpoints': {
|
||||||
'sharedInbox': 'http://localhost/ap/sharedInbox',
|
'sharedInbox': 'https://web.brid.gy/ap/sharedInbox',
|
||||||
},
|
},
|
||||||
'publicKey': {
|
'publicKey': {
|
||||||
'id': 'http://localhost/user.com#key',
|
'id': 'http://localhost/user.com#key',
|
||||||
|
@ -74,20 +74,23 @@ ACTOR_BASE_FULL = {
|
||||||
}],
|
}],
|
||||||
}
|
}
|
||||||
ACTOR_FAKE = {
|
ACTOR_FAKE = {
|
||||||
'@context': ['https://w3id.org/security/v1'],
|
'@context': [
|
||||||
|
'https://www.w3.org/ns/activitystreams',
|
||||||
|
'https://w3id.org/security/v1',
|
||||||
|
],
|
||||||
'type': 'Person',
|
'type': 'Person',
|
||||||
'id': 'http://localhost/ap/fa/fake:user',
|
'id': 'https://fa.brid.gy/ap/fake:user',
|
||||||
|
'url': 'https://fa.brid.gy/r/fake:user',
|
||||||
|
'inbox': 'https://fa.brid.gy/ap/fake:user/inbox',
|
||||||
|
'outbox': 'https://fa.brid.gy/ap/fake:user/outbox',
|
||||||
|
'following': 'https://fa.brid.gy/ap/fake:user/following',
|
||||||
|
'followers': 'https://fa.brid.gy/ap/fake:user/followers',
|
||||||
|
'endpoints': {'sharedInbox': 'https://fa.brid.gy/ap/sharedInbox'},
|
||||||
'preferredUsername': 'fake:user',
|
'preferredUsername': 'fake:user',
|
||||||
'url': 'http://localhost/r/fake:user',
|
|
||||||
'summary': '',
|
'summary': '',
|
||||||
'inbox': 'http://localhost/ap/fa/fake:user/inbox',
|
|
||||||
'outbox': 'http://localhost/ap/fa/fake:user/outbox',
|
|
||||||
'following': 'http://localhost/ap/fa/fake:user/following',
|
|
||||||
'followers': 'http://localhost/ap/fa/fake:user/followers',
|
|
||||||
'endpoints': {'sharedInbox': 'http://localhost/ap/sharedInbox'},
|
|
||||||
'publicKey': {
|
'publicKey': {
|
||||||
'id': 'http://localhost/fake#key',
|
'id': 'https://fa.brid.gy/fake#key',
|
||||||
'owner': 'http://localhost/fake',
|
'owner': 'https://fa.brid.gy/fake',
|
||||||
'publicKeyPem': 'populated in setUp()',
|
'publicKeyPem': 'populated in setUp()',
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -298,9 +301,8 @@ class ActivityPubTest(TestCase):
|
||||||
self.swentel_key = ndb.Key(ActivityPub, 'https://mas.to/users/swentel')
|
self.swentel_key = ndb.Key(ActivityPub, 'https://mas.to/users/swentel')
|
||||||
self.masto_actor_key = ndb.Key(ActivityPub, 'https://mas.to/actor')
|
self.masto_actor_key = ndb.Key(ActivityPub, 'https://mas.to/actor')
|
||||||
|
|
||||||
ACTOR_BASE['publicKey']['publicKeyPem'] = \
|
for obj in ACTOR_BASE, ACTOR_FAKE:
|
||||||
ACTOR_FAKE['publicKey']['publicKeyPem'] = \
|
obj['publicKey']['publicKeyPem'] = self.user.public_pem().decode()
|
||||||
self.user.public_pem().decode()
|
|
||||||
|
|
||||||
self.key_id_obj = Object(id='http://my/key/id', as2={
|
self.key_id_obj = Object(id='http://my/key/id', as2={
|
||||||
**ACTOR,
|
**ACTOR,
|
||||||
|
@ -336,17 +338,19 @@ class ActivityPubTest(TestCase):
|
||||||
return self.client.post(path, data=body, headers=self.sign(path, body))
|
return self.client.post(path, data=body, headers=self.sign(path, body))
|
||||||
|
|
||||||
def test_actor_fake(self, *_):
|
def test_actor_fake(self, *_):
|
||||||
self.make_user('fake:user', cls=Fake, obj_as2={
|
self.make_user('fake:user', cls=Fake)
|
||||||
'type': 'Person',
|
got = self.client.get('/ap/fake:user', base_url='https://fa.brid.gy/')
|
||||||
'id': 'fake:user',
|
|
||||||
})
|
|
||||||
|
|
||||||
got = self.client.get('/ap/fake/fake:user')
|
|
||||||
self.assertEqual(200, got.status_code, got.get_data(as_text=True))
|
self.assertEqual(200, got.status_code, got.get_data(as_text=True))
|
||||||
type = got.headers['Content-Type']
|
type = got.headers['Content-Type']
|
||||||
self.assertTrue(type.startswith(as2.CONTENT_TYPE), type)
|
self.assertTrue(type.startswith(as2.CONTENT_TYPE), type)
|
||||||
self.assertEqual(ACTOR_FAKE, got.json)
|
self.assertEqual(ACTOR_FAKE, got.json)
|
||||||
|
|
||||||
|
def test_actor_fake_protocol_subdomain(self, *_):
|
||||||
|
self.make_user('fake:user', cls=Fake)
|
||||||
|
got = self.client.get('/ap/fake:user', base_url='https://fa.brid.gy/')
|
||||||
|
self.assertEqual(200, got.status_code)
|
||||||
|
self.assertEqual(ACTOR_FAKE, got.json)
|
||||||
|
|
||||||
def test_actor_web(self, *_):
|
def test_actor_web(self, *_):
|
||||||
"""Web users are special cased to drop the /web/ prefix."""
|
"""Web users are special cased to drop the /web/ prefix."""
|
||||||
got = self.client.get('/user.com')
|
got = self.client.get('/user.com')
|
||||||
|
@ -393,7 +397,7 @@ class ActivityPubTest(TestCase):
|
||||||
|
|
||||||
def test_actor_handle_existing_user(self, _, __, ___):
|
def test_actor_handle_existing_user(self, _, __, ___):
|
||||||
self.make_user('fake:user', cls=Fake, obj_as2=ACTOR)
|
self.make_user('fake:user', cls=Fake, obj_as2=ACTOR)
|
||||||
got = self.client.get('/ap/fake/fake:handle:user')
|
got = self.client.get('/ap/fake:handle:user', base_url='https://fa.brid.gy/')
|
||||||
self.assertEqual(200, got.status_code)
|
self.assertEqual(200, got.status_code)
|
||||||
self.assert_equals({
|
self.assert_equals({
|
||||||
**ACTOR,
|
**ACTOR,
|
||||||
|
@ -402,7 +406,7 @@ class ActivityPubTest(TestCase):
|
||||||
|
|
||||||
def test_actor_handle_new_user(self, _, __, ___):
|
def test_actor_handle_new_user(self, _, __, ___):
|
||||||
Fake.fetchable['fake:user'] = as2.to_as1(ACTOR)
|
Fake.fetchable['fake:user'] = as2.to_as1(ACTOR)
|
||||||
got = self.client.get('/ap/fake/fake:handle:user')
|
got = self.client.get('/ap/fake:handle:user', base_url='https://fa.brid.gy/')
|
||||||
self.assertEqual(200, got.status_code)
|
self.assertEqual(200, got.status_code)
|
||||||
self.assert_equals({
|
self.assert_equals({
|
||||||
**ACTOR,
|
**ACTOR,
|
||||||
|
@ -557,6 +561,9 @@ class ActivityPubTest(TestCase):
|
||||||
def test_shared_inbox_create_obj(self, *mocks):
|
def test_shared_inbox_create_obj(self, *mocks):
|
||||||
self._test_inbox_create_obj('/inbox', *mocks)
|
self._test_inbox_create_obj('/inbox', *mocks)
|
||||||
|
|
||||||
|
def test_ap_sharedInbox_create_obj(self, *mocks):
|
||||||
|
self._test_inbox_create_obj('/ap/sharedInbox', *mocks)
|
||||||
|
|
||||||
def _test_inbox_create_obj(self, path, mock_head, mock_get, mock_post):
|
def _test_inbox_create_obj(self, path, mock_head, mock_get, mock_post):
|
||||||
swentel = self.make_user('https://mas.to/users/swentel', cls=ActivityPub)
|
swentel = self.make_user('https://mas.to/users/swentel', cls=ActivityPub)
|
||||||
Follower.get_or_create(to=swentel, from_=self.user)
|
Follower.get_or_create(to=swentel, from_=self.user)
|
||||||
|
@ -1593,21 +1600,21 @@ class ActivityPubUtilsTest(TestCase):
|
||||||
'id': 'baj',
|
'id': 'baj',
|
||||||
'preferredUsername': 'site',
|
'preferredUsername': 'site',
|
||||||
'url': 'http://localhost/r/site',
|
'url': 'http://localhost/r/site',
|
||||||
'inbox': 'http://localhost/ap/fa/site/inbox',
|
'inbox': 'https://fa.brid.gy/ap/site/inbox',
|
||||||
'outbox': 'http://localhost/ap/fa/site/outbox',
|
'outbox': 'https://fa.brid.gy/ap/site/outbox',
|
||||||
},
|
},
|
||||||
'attributedTo': [{
|
'attributedTo': [{
|
||||||
'id': 'bar',
|
'id': 'bar',
|
||||||
'preferredUsername': 'site',
|
'preferredUsername': 'site',
|
||||||
'url': 'http://localhost/r/site',
|
'url': 'http://localhost/r/site',
|
||||||
'inbox': 'http://localhost/ap/fa/site/inbox',
|
'inbox': 'https://fa.brid.gy/ap/site/inbox',
|
||||||
'outbox': 'http://localhost/ap/fa/site/outbox',
|
'outbox': 'https://fa.brid.gy/ap/site/outbox',
|
||||||
}, {
|
}, {
|
||||||
'id': 'baz',
|
'id': 'baz',
|
||||||
'preferredUsername': 'site',
|
'preferredUsername': 'site',
|
||||||
'url': 'http://localhost/r/site',
|
'url': 'http://localhost/r/site',
|
||||||
'inbox': 'http://localhost/ap/fa/site/inbox',
|
'inbox': 'https://fa.brid.gy/ap/site/inbox',
|
||||||
'outbox': 'http://localhost/ap/fa/site/outbox',
|
'outbox': 'https://fa.brid.gy/ap/site/outbox',
|
||||||
}],
|
}],
|
||||||
'to': [as2.PUBLIC_AUDIENCE],
|
'to': [as2.PUBLIC_AUDIENCE],
|
||||||
}, postprocess_as2({
|
}, postprocess_as2({
|
||||||
|
|
|
@ -140,11 +140,12 @@ class UserTest(TestCase):
|
||||||
self.assertEqual('fake:handle:user', user.handle_as('fake'))
|
self.assertEqual('fake:handle:user', user.handle_as('fake'))
|
||||||
self.assertEqual('@fake:handle:user@fa.brid.gy', user.handle_as('ap'))
|
self.assertEqual('@fake:handle:user@fa.brid.gy', user.handle_as('ap'))
|
||||||
|
|
||||||
def test_ap_actor(self):
|
@patch('requests.get', return_value=requests_response(DID_DOC))
|
||||||
|
def test_ap_actor(self, mock_get):
|
||||||
user = self.make_user('did:plc:abc', cls=ATProto)
|
user = self.make_user('did:plc:abc', cls=ATProto)
|
||||||
self.assertEqual('http://localhost/ap/atproto/did:plc:abc',
|
self.assertEqual('https://atproto.brid.gy/ap/did:plc:abc',
|
||||||
user.ap_actor())
|
user.ap_actor())
|
||||||
self.assertEqual('http://localhost/ap/atproto/did:plc:abc/foo',
|
self.assertEqual('https://atproto.brid.gy/ap/did:plc:abc/foo',
|
||||||
user.ap_actor(rest='foo'))
|
user.ap_actor(rest='foo'))
|
||||||
|
|
||||||
def test_load_multi(self):
|
def test_load_multi(self):
|
||||||
|
|
|
@ -32,7 +32,7 @@ class PagesTest(TestCase):
|
||||||
self.user = self.make_user('user.com')
|
self.user = self.make_user('user.com')
|
||||||
|
|
||||||
def test_user(self):
|
def test_user(self):
|
||||||
got = self.client.get('/web/user.com')
|
got = self.client.get('/web/user.com', base_url='https://fed.brid.gy/')
|
||||||
self.assert_equals(200, got.status_code)
|
self.assert_equals(200, got.status_code)
|
||||||
|
|
||||||
def test_user_fake(self):
|
def test_user_fake(self):
|
||||||
|
|
|
@ -1031,7 +1031,7 @@ class ProtocolReceiveTest(TestCase):
|
||||||
delivered=['fake:user:target'],
|
delivered=['fake:user:target'],
|
||||||
)
|
)
|
||||||
|
|
||||||
accept_id = 'http://localhost/ap/fa/fake:user/followers#accept-fake:follow'
|
accept_id = 'https://fa.brid.gy/ap/fake:user/followers#accept-fake:follow'
|
||||||
accept_as1 = {
|
accept_as1 = {
|
||||||
'id': accept_id,
|
'id': accept_id,
|
||||||
'objectType': 'activity',
|
'objectType': 'activity',
|
||||||
|
@ -1233,10 +1233,10 @@ class ProtocolReceiveTest(TestCase):
|
||||||
Fake.receive_as1(follow_as1)
|
Fake.receive_as1(follow_as1)
|
||||||
|
|
||||||
(bob_obj, bob_target), (eve_obj, eve_target) = Fake.sent
|
(bob_obj, bob_target), (eve_obj, eve_target) = Fake.sent
|
||||||
self.assertEqual('http://localhost/ap/fa/http://x.com/bob/followers#accept-http://x.com/follow',
|
self.assertEqual('https://fa.brid.gy/ap/http://x.com/bob/followers#accept-http://x.com/follow',
|
||||||
bob_obj.key.id())
|
bob_obj.key.id())
|
||||||
self.assertEqual('http://x.com/alice:target', bob_target)
|
self.assertEqual('http://x.com/alice:target', bob_target)
|
||||||
self.assertEqual('http://localhost/ap/fa/http://x.com/eve/followers#accept-http://x.com/follow',
|
self.assertEqual('https://fa.brid.gy/ap/http://x.com/eve/followers#accept-http://x.com/follow',
|
||||||
eve_obj.key.id())
|
eve_obj.key.id())
|
||||||
self.assertEqual('http://x.com/alice:target', eve_target)
|
self.assertEqual('http://x.com/alice:target', eve_target)
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,7 @@ WEBFINGER = {
|
||||||
}, {
|
}, {
|
||||||
'rel': 'sharedInbox',
|
'rel': 'sharedInbox',
|
||||||
'type': 'application/activity+json',
|
'type': 'application/activity+json',
|
||||||
'href': 'http://localhost/ap/sharedInbox',
|
'href': 'https://web.brid.gy/ap/sharedInbox',
|
||||||
}, {
|
}, {
|
||||||
'rel': 'http://ostatus.org/schema/1.0/subscribe',
|
'rel': 'http://ostatus.org/schema/1.0/subscribe',
|
||||||
'template': 'http://localhost/web/user.com?url={uri}',
|
'template': 'http://localhost/web/user.com?url={uri}',
|
||||||
|
@ -74,7 +74,7 @@ WEBFINGER_NO_HCARD = {
|
||||||
}, {
|
}, {
|
||||||
'rel': 'sharedInbox',
|
'rel': 'sharedInbox',
|
||||||
'type': 'application/activity+json',
|
'type': 'application/activity+json',
|
||||||
'href': 'http://localhost/ap/sharedInbox',
|
'href': 'https://web.brid.gy/ap/sharedInbox',
|
||||||
}, {
|
}, {
|
||||||
'rel': 'http://ostatus.org/schema/1.0/subscribe',
|
'rel': 'http://ostatus.org/schema/1.0/subscribe',
|
||||||
'template': 'http://localhost/web/user.com?url={uri}',
|
'template': 'http://localhost/web/user.com?url={uri}',
|
||||||
|
@ -98,17 +98,18 @@ WEBFINGER_FAKE = {
|
||||||
}, {
|
}, {
|
||||||
'rel': 'sharedInbox',
|
'rel': 'sharedInbox',
|
||||||
'type': 'application/activity+json',
|
'type': 'application/activity+json',
|
||||||
'href': 'http://localhost/ap/sharedInbox',
|
'href': 'https://web.brid.gy/ap/sharedInbox',
|
||||||
}, {
|
}, {
|
||||||
'rel': 'http://ostatus.org/schema/1.0/subscribe',
|
'rel': 'http://ostatus.org/schema/1.0/subscribe',
|
||||||
'template': 'http://localhost/fa/fake:user?url={uri}',
|
'template': 'http://localhost/fa/fake:user?url={uri}',
|
||||||
}],
|
}],
|
||||||
}
|
}
|
||||||
WEBFINGER_FAKE_FED_BRID_GY = copy.deepcopy(WEBFINGER_FAKE)
|
WEBFINGER_FAKE_FA_BRID_GY = copy.deepcopy(WEBFINGER_FAKE)
|
||||||
for link in WEBFINGER_FAKE_FED_BRID_GY['links']:
|
for link in WEBFINGER_FAKE_FA_BRID_GY['links']:
|
||||||
if 'href' in link:
|
if 'href' in link:
|
||||||
link['href'] = link['href'].replace('http://localhost', 'https://fed.brid.gy')
|
link['href'] = link['href'].replace('http://localhost/ap/fa', 'https://fa.brid.gy/ap')
|
||||||
WEBFINGER_FAKE_FED_BRID_GY['links'][4]['template'] = 'https://fed.brid.gy/fa/fake:user?url={uri}'
|
WEBFINGER_FAKE_FA_BRID_GY['links'][3]['href'] = 'https://fa.brid.gy/ap/sharedInbox'
|
||||||
|
WEBFINGER_FAKE_FA_BRID_GY['links'][4]['template'] = 'https://fed.brid.gy/fa/fake:user?url={uri}'
|
||||||
|
|
||||||
|
|
||||||
class HostMetaTest(TestCase):
|
class HostMetaTest(TestCase):
|
||||||
|
@ -163,10 +164,11 @@ class WebfingerTest(TestCase):
|
||||||
def test_user_infer_protocol_from_resource_subdomain(self):
|
def test_user_infer_protocol_from_resource_subdomain(self):
|
||||||
got = self.client.get(
|
got = self.client.get(
|
||||||
'/.well-known/webfinger?resource=acct:fake:handle:user@fake.brid.gy',
|
'/.well-known/webfinger?resource=acct:fake:handle:user@fake.brid.gy',
|
||||||
|
base_url='https://fed.brid.gy/',
|
||||||
headers={'Accept': 'application/json'})
|
headers={'Accept': 'application/json'})
|
||||||
self.assertEqual(200, got.status_code)
|
self.assertEqual(200, got.status_code)
|
||||||
self.assertEqual('application/jrd+json', got.headers['Content-Type'])
|
self.assertEqual('application/jrd+json', got.headers['Content-Type'])
|
||||||
self.assert_equals(WEBFINGER_FAKE, got.json)
|
self.assert_equals(WEBFINGER_FAKE_FA_BRID_GY, got.json)
|
||||||
|
|
||||||
def test_user_infer_protocol_from_request_subdomain(self):
|
def test_user_infer_protocol_from_request_subdomain(self):
|
||||||
self.make_user('fake:user', cls=Fake)
|
self.make_user('fake:user', cls=Fake)
|
||||||
|
@ -176,7 +178,7 @@ class WebfingerTest(TestCase):
|
||||||
headers={'Accept': 'application/json'})
|
headers={'Accept': 'application/json'})
|
||||||
self.assertEqual(200, got.status_code)
|
self.assertEqual(200, got.status_code)
|
||||||
self.assertEqual('application/jrd+json', got.headers['Content-Type'])
|
self.assertEqual('application/jrd+json', got.headers['Content-Type'])
|
||||||
self.assert_equals(WEBFINGER_FAKE_FED_BRID_GY, got.json)
|
self.assert_equals(WEBFINGER_FAKE_FA_BRID_GY, got.json)
|
||||||
|
|
||||||
def test_user_infer_protocol_resource_overrides_request(self):
|
def test_user_infer_protocol_resource_overrides_request(self):
|
||||||
got = self.client.get(
|
got = self.client.get(
|
||||||
|
@ -185,14 +187,15 @@ class WebfingerTest(TestCase):
|
||||||
headers={'Accept': 'application/json'})
|
headers={'Accept': 'application/json'})
|
||||||
self.assertEqual(200, got.status_code)
|
self.assertEqual(200, got.status_code)
|
||||||
self.assertEqual('application/jrd+json', got.headers['Content-Type'])
|
self.assertEqual('application/jrd+json', got.headers['Content-Type'])
|
||||||
self.assert_equals(WEBFINGER_FAKE_FED_BRID_GY, got.json)
|
self.assert_equals(WEBFINGER_FAKE_FA_BRID_GY, got.json)
|
||||||
|
|
||||||
def test_handle(self):
|
def test_handle(self):
|
||||||
got = self.client.get(
|
got = self.client.get(
|
||||||
'/.well-known/webfinger?resource=acct:fake:handle:user@fake.brid.gy',
|
'/.well-known/webfinger?resource=acct:fake:handle:user@fake.brid.gy',
|
||||||
|
base_url='https://fed.brid.gy/',
|
||||||
headers={'Accept': 'application/json'})
|
headers={'Accept': 'application/json'})
|
||||||
self.assertEqual(200, got.status_code, got.get_data(as_text=True))
|
self.assertEqual(200, got.status_code, got.get_data(as_text=True))
|
||||||
self.assert_equals(WEBFINGER_FAKE, got.json)
|
self.assert_equals(WEBFINGER_FAKE_FA_BRID_GY, got.json)
|
||||||
|
|
||||||
def test_urlencoded(self):
|
def test_urlencoded(self):
|
||||||
"""https://github.com/snarfed/bridgy-fed/issues/535"""
|
"""https://github.com/snarfed/bridgy-fed/issues/535"""
|
||||||
|
|
|
@ -134,7 +134,7 @@ class Webfinger(flask_util.XrdOrJrd):
|
||||||
# https://www.w3.org/TR/activitypub/#sharedInbox
|
# https://www.w3.org/TR/activitypub/#sharedInbox
|
||||||
'rel': 'sharedInbox',
|
'rel': 'sharedInbox',
|
||||||
'type': as2.CONTENT_TYPE,
|
'type': as2.CONTENT_TYPE,
|
||||||
'href': common.host_url('/ap/sharedInbox'),
|
'href': cls.subdomain_url('/ap/sharedInbox'),
|
||||||
},
|
},
|
||||||
|
|
||||||
# remote follow
|
# remote follow
|
||||||
|
|
Ładowanie…
Reference in New Issue