kopia lustrzana https://github.com/snarfed/bridgy-fed
ids: use subdomain-wrapped URLs to convert ATProto to Web/AP
rodzic
98bb29b333
commit
bca034c4f8
41
ids.py
41
ids.py
|
@ -13,6 +13,9 @@ import models
|
|||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
# Protocols to check User.copies and Object.copies before translating
|
||||
COPIES_PROTOCOLS = ('atproto', 'fake', 'other', 'nostr')
|
||||
|
||||
|
||||
def translate_user_id(*, id, from_proto, to_proto):
|
||||
"""Translate a user id from one protocol to another.
|
||||
|
@ -41,7 +44,7 @@ def translate_user_id(*, id, from_proto, to_proto):
|
|||
if user:
|
||||
id = user.key.id()
|
||||
|
||||
def copy_or_original():
|
||||
if from_proto.LABEL in COPIES_PROTOCOLS or to_proto.LABEL in COPIES_PROTOCOLS:
|
||||
if user:
|
||||
if copy := user.get_copy(to_proto):
|
||||
return copy
|
||||
|
@ -50,10 +53,8 @@ def translate_user_id(*, id, from_proto, to_proto):
|
|||
return orig.key.id()
|
||||
|
||||
match from_proto.LABEL, to_proto.LABEL:
|
||||
case ('atproto', _) | (_, 'atproto'):
|
||||
if found := copy_or_original():
|
||||
return found
|
||||
logger.warning(f"Can't translate user id {id} to {to_proto} , haven't copied it to/from there yet!")
|
||||
case _, 'atproto' | 'nostr':
|
||||
logger.warning(f"Can't translate user id {id} to {to_proto.LABEL} , haven't copied it there yet!")
|
||||
return None
|
||||
|
||||
case 'web', 'activitypub':
|
||||
|
@ -62,19 +63,17 @@ def translate_user_id(*, id, from_proto, to_proto):
|
|||
else f'https://{PRIMARY_DOMAIN}/')
|
||||
return urljoin(base, id)
|
||||
|
||||
case _, 'activitypub':
|
||||
return subdomain_wrap(from_proto, f'/ap/{id}')
|
||||
|
||||
case 'activitypub', 'web':
|
||||
return id
|
||||
|
||||
case _, 'activitypub' | 'web':
|
||||
return subdomain_wrap(from_proto, f'/{to_proto.ABBREV}/{id}')
|
||||
|
||||
# only for unit tests
|
||||
case _, 'fake':
|
||||
return copy_or_original() or f'fake:u:{id}'
|
||||
case _, 'other':
|
||||
return copy_or_original() or f'other:u:{id}'
|
||||
case _, 'fake' | 'other':
|
||||
return f'{to_proto.LABEL}:u:{id}'
|
||||
case 'fake' | 'other', _:
|
||||
return copy_or_original() or id
|
||||
return id
|
||||
|
||||
assert False, (id, from_proto, to_proto)
|
||||
|
||||
|
@ -143,7 +142,7 @@ def translate_object_id(*, id, from_proto, to_proto):
|
|||
if from_proto == to_proto:
|
||||
return id
|
||||
|
||||
def copy_or_original():
|
||||
if from_proto.LABEL in COPIES_PROTOCOLS or to_proto.LABEL in COPIES_PROTOCOLS:
|
||||
if obj := from_proto.load(id, remote=False):
|
||||
if copy := obj.get_copy(to_proto):
|
||||
return copy
|
||||
|
@ -151,10 +150,8 @@ def translate_object_id(*, id, from_proto, to_proto):
|
|||
return orig.key.id()
|
||||
|
||||
match from_proto.LABEL, to_proto.LABEL:
|
||||
case ('atproto' | 'nostr', _) | (_, 'atproto' | 'nostr'):
|
||||
if found := copy_or_original():
|
||||
return found
|
||||
logger.warning(f"Can't translate object id {id} to {to_proto} , haven't copied it to/from there yet!")
|
||||
case _, 'atproto' | 'nostr':
|
||||
logger.warning(f"Can't translate object id {id} to {to_proto.LABEL} , haven't copied it there yet!")
|
||||
return id
|
||||
|
||||
case 'web', 'activitypub':
|
||||
|
@ -164,12 +161,10 @@ def translate_object_id(*, id, from_proto, to_proto):
|
|||
return urljoin(base, f'/r/{id}')
|
||||
|
||||
case _, 'activitypub' | 'web':
|
||||
return subdomain_wrap(from_proto, f'convert/{to_proto.ABBREV}/{id}')
|
||||
return subdomain_wrap(from_proto, f'/convert/{to_proto.ABBREV}/{id}')
|
||||
|
||||
# only for unit tests
|
||||
case _, 'fake':
|
||||
return copy_or_original() or f'fake:o:{from_proto.ABBREV}:{id}'
|
||||
case _, 'other':
|
||||
return copy_or_original() or f'other:o:{from_proto.ABBREV}:{id}'
|
||||
case _, 'fake' | 'other':
|
||||
return f'{to_proto.LABEL}:o:{from_proto.ABBREV}:{id}'
|
||||
|
||||
assert False, (id, from_proto, to_proto)
|
||||
|
|
|
@ -541,7 +541,7 @@ class ActivityPubTest(TestCase):
|
|||
self.assertEqual(202, got.status_code, got.get_data(as_text=True))
|
||||
self.assert_req(mock_get, 'https://user.com/post')
|
||||
|
||||
convert_id = reply['id'].replace('://', ':/')
|
||||
convert_id = reply['id']
|
||||
if reply['type'] != 'Create':
|
||||
convert_id += '%23bridgy-fed-create'
|
||||
|
||||
|
@ -672,14 +672,13 @@ class ActivityPubTest(TestCase):
|
|||
got = self.post('/user.com/inbox', json=repost)
|
||||
self.assertEqual(202, got.status_code, got.get_data(as_text=True))
|
||||
|
||||
convert_id = REPOST['id'].replace('://', ':/')
|
||||
self.assert_req(
|
||||
mock_post,
|
||||
'https://user.com/webmention',
|
||||
headers={'Accept': '*/*'},
|
||||
allow_redirects=False,
|
||||
data={
|
||||
'source': f'https://ap.brid.gy/convert/web/{convert_id}',
|
||||
'source': f'https://ap.brid.gy/convert/web/{REPOST["id"]}',
|
||||
'target': orig_url,
|
||||
},
|
||||
)
|
||||
|
@ -797,7 +796,7 @@ class ActivityPubTest(TestCase):
|
|||
args, kwargs = mock_post.call_args
|
||||
self.assertEqual(('https://user.com/webmention',), args)
|
||||
self.assertEqual({
|
||||
'source': 'https://ap.brid.gy/convert/web/http:/mas.to/like%23ok',
|
||||
'source': 'https://ap.brid.gy/convert/web/http://mas.to/like%23ok',
|
||||
'target': 'https://user.com/post',
|
||||
}, kwargs['data'])
|
||||
|
||||
|
@ -941,7 +940,7 @@ class ActivityPubTest(TestCase):
|
|||
args, kwargs = mock_post.call_args_list[1]
|
||||
self.assertEqual(('https://user.com/webmention',), args)
|
||||
self.assertEqual({
|
||||
'source': 'https://ap.brid.gy/convert/web/https:/mas.to/6d1a',
|
||||
'source': 'https://ap.brid.gy/convert/web/https://mas.to/6d1a',
|
||||
'target': 'https://user.com/',
|
||||
}, kwargs['data'])
|
||||
|
||||
|
|
|
@ -22,14 +22,19 @@ class IdsTest(TestCase):
|
|||
(ActivityPub, 'https://inst/user', ATProto, 'did:plc:456'),
|
||||
(ActivityPub, 'https://inst/user', Fake, 'fake:u:https://inst/user'),
|
||||
(ActivityPub, 'https://inst/user', Web, 'https://inst/user'),
|
||||
(ATProto, 'did:plc:456', ATProto, 'did:plc:456'),
|
||||
# copies
|
||||
(ATProto, 'did:plc:123', Web, 'user.com'),
|
||||
(ATProto, 'did:plc:456', ActivityPub, 'https://inst/user'),
|
||||
(ATProto, 'did:plc:456', ATProto, 'did:plc:456'),
|
||||
(ATProto, 'did:plc:789', Fake, 'fake:user'),
|
||||
# no copies
|
||||
(ATProto, 'did:plc:x', Web, 'https://atproto.brid.gy/web/did:plc:x'),
|
||||
(ATProto, 'did:plc:x', ActivityPub, 'https://atproto.brid.gy/ap/did:plc:x'),
|
||||
(ATProto, 'did:plc:x', Fake, 'fake:u:did:plc:x'),
|
||||
(Fake, 'fake:user', ActivityPub, 'https://fa.brid.gy/ap/fake:user'),
|
||||
(Fake, 'fake:user', ATProto, 'did:plc:789'),
|
||||
(Fake, 'fake:user', Fake, 'fake:user'),
|
||||
(Fake, 'fake:user', Web, 'fake:user'),
|
||||
(Fake, 'fake:user', Web, 'https://fa.brid.gy/web/fake:user'),
|
||||
(Web, 'user.com', ActivityPub, 'http://localhost/user.com'),
|
||||
(Web, 'https://user.com/', ActivityPub, 'http://localhost/user.com'),
|
||||
(Web, 'user.com', ATProto, 'did:plc:123'),
|
||||
|
@ -55,8 +60,6 @@ class IdsTest(TestCase):
|
|||
with self.subTest(proto=proto.LABEL):
|
||||
self.assertIsNone(translate_user_id(
|
||||
id=id, from_proto=proto, to_proto=ATProto))
|
||||
self.assertIsNone(translate_user_id(
|
||||
id='did:plc:123', from_proto=ATProto, to_proto=proto))
|
||||
|
||||
def test_translate_user_id_use_instead(self):
|
||||
did = Target(uri='did:plc:123', protocol='atproto')
|
||||
|
@ -124,11 +127,16 @@ class IdsTest(TestCase):
|
|||
(ActivityPub, 'https://inst/post', ATProto, 'at://did/ap/post'),
|
||||
(ActivityPub, 'https://inst/post', Fake, 'fake:o:ap:https://inst/post'),
|
||||
(ActivityPub, 'https://inst/post',
|
||||
Web, 'https://ap.brid.gy/convert/web/https:/inst/post'),
|
||||
Web, 'https://ap.brid.gy/convert/web/https://inst/post'),
|
||||
(ATProto, 'at://did/atp/post', ATProto, 'at://did/atp/post'),
|
||||
# copies
|
||||
(ATProto, 'at://did/web/post', Web, 'http://post'),
|
||||
(ATProto, 'at://did/ap/post', ActivityPub, 'https://inst/post'),
|
||||
(ATProto, 'at://did/atp/post', ATProto, 'at://did/atp/post'),
|
||||
(ATProto, 'at://did/fa/post', Fake, 'fake:post'),
|
||||
# no copies
|
||||
(ATProto, 'did:plc:x', Web, 'https://atproto.brid.gy/convert/web/did:plc:x'),
|
||||
(ATProto, 'did:plc:x', ActivityPub, 'https://atproto.brid.gy/convert/ap/did:plc:x'),
|
||||
(ATProto, 'did:plc:x', Fake, 'fake:o:atproto:did:plc:x'),
|
||||
(Fake, 'fake:post',
|
||||
ActivityPub, 'https://fa.brid.gy/convert/ap/fake:post'),
|
||||
(Fake, 'fake:post', ATProto, 'at://did/fa/post'),
|
||||
|
|
|
@ -2219,7 +2219,7 @@ class WebUtilTest(TestCase):
|
|||
args, kwargs = mock_post.call_args
|
||||
self.assertEqual(('https://user.com/webmention',), args)
|
||||
self.assertEqual({
|
||||
'source': 'https://fed.brid.gy/convert/web/http:/mas.to/like%23ok',
|
||||
'source': 'https://fed.brid.gy/convert/web/http://mas.to/like%23ok',
|
||||
'target': 'https://user.com/post',
|
||||
}, kwargs['data'])
|
||||
|
||||
|
@ -2266,7 +2266,7 @@ class WebUtilTest(TestCase):
|
|||
args, kwargs = mock_post.call_args
|
||||
self.assertEqual(('https://user.com/webmention',), args)
|
||||
self.assertEqual({
|
||||
'source': 'https://fed.brid.gy/convert/web/http:/mas.to/like%23ok',
|
||||
'source': 'https://fed.brid.gy/convert/web/http://mas.to/like%23ok',
|
||||
'target': 'https://user.com/post',
|
||||
}, kwargs['data'])
|
||||
|
||||
|
@ -2293,13 +2293,13 @@ class WebUtilTest(TestCase):
|
|||
<article class="h-entry">
|
||||
<span class="p-uid">https://fa.brid.gy/convert/web/fake:reply</span>
|
||||
<span class="p-author h-card">
|
||||
<data class="p-uid" value="fake:alice"></data>
|
||||
<data class="p-uid" value="https://fa.brid.gy/web/fake:alice"></data>
|
||||
<span class="p-name">Ms. Alice</span>
|
||||
</span>
|
||||
<span class="p-name"></span>
|
||||
<div class="">
|
||||
</div>
|
||||
<a class="u-in-reply-to" href="https://ap.brid.gy/convert/web/http:/fed/post"></a>
|
||||
<a class="u-in-reply-to" href="https://ap.brid.gy/convert/web/http://fed/post"></a>
|
||||
</article>""", Web.convert(Object(our_as1={
|
||||
'objectType': 'activity',
|
||||
'verb': 'post',
|
||||
|
|
Ładowanie…
Reference in New Issue