Protocol.targets: give undo same targets as the activity it's undoing

for #1162
pull/1167/head
Ryan Barrett 2024-07-07 17:21:37 -07:00
rodzic dd21c6c301
commit 71ebc99a9f
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 6BE31FDF4776E9D4
2 zmienionych plików z 97 dodań i 4 usunięć

Wyświetl plik

@ -871,6 +871,7 @@ class Protocol:
# fall through to deliver to followers
# TODO: add undo here, test for it
elif obj.type == 'delete':
if not inner_obj_id:
error("Couldn't find id of object to delete")
@ -1225,7 +1226,7 @@ class Protocol:
return 'OK', 202
@classmethod
def targets(cls, obj, from_user):
def targets(from_cls, obj, from_user):
"""Collects the targets to send a :class:`models.Object` to.
Targets are both objects - original posts, events, etc - and actors.
@ -1281,7 +1282,7 @@ class Protocol:
logger.info(f'Adding target {target} for copy {copy.uri} of original {id}')
targets[Target(protocol=copy.protocol, uri=target)] = orig_obj
if protocol == cls and cls.LABEL != 'fake':
if protocol == from_cls and from_cls.LABEL != 'fake':
logger.info(f'Skipping same-protocol target {id}')
continue
@ -1298,10 +1299,20 @@ class Protocol:
logger.info(f'Recipient is {orig_user}')
obj.add('notify', orig_user)
if obj.type == 'undo':
logger.info('Object is an undo; adding targets for inner object')
inner_obj_as1 = as1.get_object(obj.as1)
if set(inner_obj_as1.keys()) == {'id'}:
inner_obj = from_cls.load(inner_obj_as1['id'])
else:
inner_obj = Object(our_as1=inner_obj_as1)
if inner_obj:
targets.update(from_cls.targets(inner_obj, from_user=from_user))
logger.info(f'Direct (and copy) targets: {targets.keys()}')
# deliver to followers, if appropriate
user_key = cls.actor_key(obj)
user_key = from_cls.actor_key(obj)
if not user_key:
logger.info("Can't tell who this is from! Skipping followers.")
return targets
@ -1332,7 +1343,7 @@ class Protocol:
and inner.get('objectType') in as1.ACTOR_TYPES):
inner_id = inner.get('id')
if inner_id:
feed_obj = cls.load(inner_id)
feed_obj = from_cls.load(inner_id)
# include ATProto if this user is enabled there.
# TODO: abstract across protocols. maybe with this, below

Wyświetl plik

@ -933,6 +933,66 @@ class ProtocolReceiveTest(TestCase):
ignore=['created', 'updated'])
self.assertEqual(0, mock_send.call_count)
def test_targets_block(self):
self.bob.obj.our_as1 = {'foo': 'bar'}
self.bob.obj.put()
block = {
'objectType': 'activity',
'verb': 'block',
'id': 'fake:block',
'actor': 'fake:alice',
'object': 'fake:bob',
}
self.assertEqual(
[Target(uri='fake:bob:target', protocol='fake')],
list(Fake.targets(Object(our_as1=block), from_user=self.user).keys()))
def test_targets_undo_composite_object(self):
self.bob.obj.our_as1 = {'foo': 'bar'}
self.bob.obj.put()
undo = {
'objectType': 'activity',
'verb': 'undo',
'id': 'fake:undo',
'actor': 'fake:alice',
'object': {
'objectType': 'activity',
'verb': 'block',
'id': 'fake:block',
'actor': 'fake:alice',
'object': 'fake:bob',
},
}
self.assertEqual(
[Target(uri='fake:bob:target', protocol='fake')],
list(Fake.targets(Object(our_as1=undo), from_user=self.user).keys()))
def test_targets_undo_object_id(self):
self.bob.obj.our_as1 = {'foo': 'bar'}
self.bob.obj.put()
self.store_object(id='fake:block', our_as1={
'objectType': 'activity',
'verb': 'block',
'id': 'fake:block',
'actor': 'fake:alice',
'object': 'fake:bob',
})
undo = {
'objectType': 'activity',
'verb': 'undo',
'id': 'fake:undo',
'actor': 'fake:alice',
'object': 'fake:block',
}
self.assertEqual(
[Target(uri='fake:block:target', protocol='fake'),
Target(uri='fake:bob:target', protocol='fake')],
list(Fake.targets(Object(our_as1=undo), from_user=self.user).keys()))
@patch.object(ATProto, 'send', return_value=True)
def test_atproto_targets_normalize_pds_url(self, mock_send):
# we were over-normalizing our PDS URL https://atproto.brid.gy , adding
@ -1929,6 +1989,28 @@ class ProtocolReceiveTest(TestCase):
self.assertEqual([('fake:block', 'fake:bob:target')], Fake.sent)
def test_undo_block(self):
self.make_user(id='other:eve', cls=OtherFake, obj_as1={})
self.make_followers()
block = {
'objectType': 'activity',
'verb': 'block',
'id': 'fake:block',
'actor': 'fake:user',
'object': 'other:eve',
}
self.store_object(id='fake:block', our_as1=block)
self.assertEqual(('OK', 202), Fake.receive_as1({
'objectType': 'activity',
'verb': 'undo',
'id': 'fake:undo',
'actor': 'fake:user',
'object': block,
}))
self.assertEqual([('fake:undo', 'fake:block:target')], Fake.sent)
@skip
def test_from_bridgy_fed_domain_fails(self):
with self.assertRaises(BadRequest):