switch Protocol.translate_ids from using subdomain_wrap to translate_object_id

pull/701/head
Ryan Barrett 2023-10-26 17:18:01 -07:00
rodzic 8e4e95914d
commit c280a3f213
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 6BE31FDF4776E9D4
4 zmienionych plików z 64 dodań i 34 usunięć

18
ids.py
Wyświetl plik

@ -39,10 +39,12 @@ def translate_user_id(*, id, from_proto, to_proto):
return subdomain_wrap(from_proto, f'/ap/{id}')
case 'activitypub', 'web':
return id
# fake protocol is only for unit tests
# only for unit tests
case _, 'fake':
return f'fake:{id}'
case 'fake', _:
case _, 'other':
return f'other:{id}'
case 'fake' | 'other', _:
return id
assert False, (id, from_proto, to_proto)
@ -82,8 +84,11 @@ def translate_handle(*, handle, from_proto, to_proto):
return f'instance/@user' # TODO
case _, 'web':
return handle
# only for unit tests
case _, 'fake':
return f'fake:handle:{handle}'
case _, 'other':
return f'other:handle:{handle}'
assert False, (id, from_proto, to_proto)
@ -119,10 +124,13 @@ def translate_object_id(*, id, from_proto, to_proto):
logger.warning(f"Can't translate {id} to {to_proto} , haven't copied it to/from there yet!")
return id
case _, 'fake':
return f'fake:{from_proto.ABBREV}:{id}'
case _, 'activitypub' | 'web':
return subdomain_wrap(from_proto, f'convert/{to_proto.ABBREV}/{id}')
# only for unit tests
case _, 'fake':
return f'fake:{from_proto.ABBREV}:{id}'
case _, 'other':
return f'other:{from_proto.ABBREV}:{id}'
assert False, (id, from_proto, to_proto)

Wyświetl plik

@ -19,6 +19,7 @@ import werkzeug.exceptions
import common
from common import add, DOMAIN_BLOCKLIST, DOMAINS, error, subdomain_wrap
from flask_app import app
from ids import translate_object_id
from models import Follower, get_for_copies, Object, PROTOCOLS, Target, User
SUPPORTED_TYPES = (
@ -500,25 +501,25 @@ class Protocol:
outer_obj = copy.deepcopy(obj)
inner_obj = outer_obj['object'] = as1.get_object(outer_obj)
def convert(elem, field):
def translate(elem, field):
elem[field] = as1.get_object(elem, field)
val = elem[field].get('id')
if val and util.domain_from_link(val) not in DOMAINS:
from_proto = Protocol.for_id(val)
if from_proto != to_cls:
elem[field]['id'] = subdomain_wrap(
from_proto, f'convert/{to_cls.ABBREV}/{val}')
id = elem[field].get('id')
if id and util.domain_from_link(id) not in DOMAINS:
from_cls = Protocol.for_id(id)
if from_cls != to_cls:
elem[field]['id'] = translate_object_id(
id=id, from_proto=from_cls, to_proto=to_cls)
if elem[field].keys() == {'id'}:
elem[field] = elem[field]['id']
for o in outer_obj, inner_obj:
for field in ('actor', 'author', 'id', 'inReplyTo'):
convert(o, field)
translate(o, field)
for tag in (as1.get_objects(outer_obj, 'tags')
+ as1.get_objects(inner_obj, 'tags')):
if tag.get('objectType') == 'mention':
convert(tag, 'url')
translate(tag, 'url')
outer_obj = util.trim_nulls(outer_obj)
if outer_obj['object'].keys() == {'id'}:

Wyświetl plik

@ -423,16 +423,16 @@ class ProtocolTest(TestCase):
Target(uri='fake:post:target', protocol='fake'),
Target(uri='fake:alice:target', protocol='fake'),
Target(uri='fake:bob:target', protocol='fake'),
Target(uri='other:bob:target', protocol='otherfake'),
Target(uri='other:bob:target', protocol='other'),
], Protocol.targets(obj).keys())
def test_translate_ids_follow(self):
self.assert_equals({
'id': 'https://fa.brid.gy/convert/other/fake:follow',
'id': 'other:fa:fake:follow',
'objectType': 'activity',
'verb': 'follow',
'actor': 'https://fa.brid.gy/convert/other/fake:alice',
'object': 'https://fa.brid.gy/convert/other/fake:bob',
'actor': 'other:fa:fake:alice',
'object': 'other:fa:fake:bob',
}, OtherFake.translate_ids({
'id': 'fake:follow',
'objectType': 'activity',
@ -446,13 +446,13 @@ class ProtocolTest(TestCase):
'objectType': 'activity',
'verb': 'create',
'object': {
'id': 'https://fa.brid.gy/convert/other/fake:reply',
'id': 'other:fa:fake:reply',
'objectType': 'note',
'inReplyTo': 'https://fa.brid.gy/convert/other/fake:post',
'author': 'https://fa.brid.gy/convert/other/fake:alice',
'inReplyTo': 'other:fa:fake:post',
'author': 'other:fa:fake:alice',
'tags': [{
'objectType': 'mention',
'url': 'https://fa.brid.gy/convert/other/fake:bob',
'url': 'other:fa:fake:bob',
}],
},
}, OtherFake.translate_ids({
@ -470,6 +470,30 @@ class ProtocolTest(TestCase):
},
}))
def test_translate_ids_copies(self):
self.store_object(id='fake:post',
copies=[Target(uri='other:post', protocol='other')])
self.make_user('other:user', cls=OtherFake,
copies=[Target(uri='fake:user', protocol='fake')])
self.assert_equals({
'objectType': 'activity',
'verb': 'create',
'actor': 'other:fa:fake:user',
'object': {
'id': 'other:fa:fake:reply',
'inReplyTo': 'other:fa:fake:post',
},
}, OtherFake.translate_ids({
'objectType': 'activity',
'verb': 'create',
'actor': 'fake:user',
'object': {
'id': 'fake:reply',
'inReplyTo': 'fake:post',
},
}))
class ProtocolReceiveTest(TestCase):

Wyświetl plik

@ -77,32 +77,33 @@ class Fake(User, protocol.Protocol):
@ndb.ComputedProperty
def handle(self):
return self.key.id().replace('fake:', 'fake:handle:')
return self.key.id().replace(f'{self.LABEL}:', f'{self.LABEL}:handle:')
def web_url(self):
return self.key.id()
@classmethod
def owns_id(cls, id):
if id.startswith('nope') or id == 'fake:nope':
if id.startswith('nope') or id == f'{cls.LABEL}:nope':
return False
return ((id.startswith('fake:') and not id.startswith('fake:handle:'))
return ((id.startswith(f'{cls.LABEL}:')
and not id.startswith(f'{cls.LABEL}:handle:'))
or id in cls.fetchable)
@classmethod
def owns_handle(cls, handle):
return handle.startswith('fake:handle:')
return handle.startswith(f'{cls.LABEL}:handle:')
@classmethod
def handle_to_id(cls, handle):
if handle == 'fake:handle:nope':
if handle == f'{cls.LABEL}:handle:nope':
return None
return handle.replace('fake:handle:', 'fake:')
return handle.replace(f'{cls.LABEL}:handle:', f'{cls.LABEL}:')
@classmethod
def is_blocklisted(cls, url):
return url.startswith('fake:blocklisted')
return url.startswith(f'{cls.LABEL}:blocklisted')
@classmethod
def send(cls, obj, url, orig_obj=None, log_data=True):
@ -145,16 +146,12 @@ class Fake(User, protocol.Protocol):
class OtherFake(Fake):
"""Different class because the same-protocol check special cases Fake."""
ABBREV = 'other'
LABEL = ABBREV = 'other'
fetchable = {}
sent = []
fetched = []
@classmethod
def owns_id(cls, id):
return id.startswith('other:')
@classmethod
def target_for(cls, obj, shared=False):
"""No shared target."""