don't automatically accept follows from protocols that support them natively

for #710. adds per-protocol `HAS_FOLLOW_ACCEPTS` constant
pull/737/head
Ryan Barrett 2023-11-27 14:44:05 -08:00
rodzic 443506c425
commit 8f7facda97
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 6BE31FDF4776E9D4
4 zmienionych plików z 50 dodań i 17 usunięć

Wyświetl plik

@ -63,6 +63,7 @@ class ActivityPub(User, Protocol):
ABBREV = 'ap'
LOGO_HTML = '<img src="/static/fediverse_logo.svg">'
CONTENT_TYPE = as2.CONTENT_TYPE
HAS_FOLLOW_ACCEPTS = True
def _pre_put_hook(self):
"""Validate id, require URL, don't allow Bridgy Fed domains.

Wyświetl plik

@ -60,11 +60,14 @@ class Protocol:
LOGO_HTML (str): logo emoji or ``<img>`` tag
CONTENT_TYPE (str): MIME type of this protocol's native data format,
appropriate for the ``Content-Type`` HTTP header.
HAS_FOLLOW_ACCEPTS (bool): whether this protocol supports explicit
accept/reject activities in response to follows, eg ActivityPub
"""
ABBREV = None
OTHER_LABELS = ()
LOGO_HTML = ''
CONTENT_TYPE = None
HAS_FOLLOW_ACCEPTS = False
def __init__(self):
assert False
@ -798,24 +801,25 @@ class Protocol:
follow=obj.key, status='active')
obj.add('notify', to_key)
# send accept. note that this is one accept for the whole follow, even
# if it has multiple followees!
id = to_user.ap_actor(f'followers#accept-{obj.key.id()}')
accept = Object.get_or_create(id, our_as1={
'id': id,
'objectType': 'activity',
'verb': 'accept',
'actor': to_id,
'object': obj.as1,
})
if not to_user.HAS_FOLLOW_ACCEPTS:
# send accept. note that this is one accept for the whole
# follow, even if it has multiple followees!
id = to_user.ap_actor(f'followers#accept-{obj.key.id()}')
accept = Object.get_or_create(id, our_as1={
'id': id,
'objectType': 'activity',
'verb': 'accept',
'actor': to_id,
'object': obj.as1,
})
sent = from_cls.send(accept, from_target, from_user=to_user)
if sent:
accept.populate(
delivered=[Target(protocol=from_cls.LABEL, uri=from_target)],
status='complete',
)
accept.put()
sent = from_cls.send(accept, from_target, from_user=to_user)
if sent:
accept.populate(
delivered=[Target(protocol=from_cls.LABEL, uri=from_target)],
status='complete',
)
accept.put()
@classmethod
def handle_bare_object(cls, obj):

Wyświetl plik

@ -1317,6 +1317,33 @@ class ProtocolReceiveTest(TestCase):
ignore=['created', 'updated'],
)
def test_follow_with_accepts_protocol(self, **extra):
OtherFake.fetchable['other:user'] = {}
follow_as1 = {
'id': 'fake:follow',
'objectType': 'activity',
'verb': 'follow',
'actor': 'fake:alice',
'object': 'other:user',
}
self.assertEqual(('OK', 202), Fake.receive_as1(follow_as1))
other = OtherFake.get_by_id('other:user')
follow_obj = self.assert_object('fake:follow',
our_as1=follow_as1,
status='complete',
users=[self.alice.key],
notify=[other.key],
delivered=['other:user:target'],
delivered_protocol='other',
)
self.assertIsNone(Object.get_by_id(
'https://fa.brid.gy/ap/other:user/followers#accept-fake:follow'))
self.assertEqual(0, Object.query(Object.type == 'accept').count())
self.assertEqual([], Fake.sent)
def test_follow_no_actor(self):
with self.assertRaises(BadRequest):
Fake.receive_as1({

Wyświetl plik

@ -150,6 +150,7 @@ class OtherFake(Fake):
"""Different class because the same-protocol check special cases Fake."""
LABEL = ABBREV = 'other'
CONTENT_TYPE = 'ot/her'
HAS_FOLLOW_ACCEPTS = True
fetchable = {}
sent = []