kopia lustrzana https://github.com/snarfed/bridgy-fed
rodzic
3c55d7c145
commit
20e061f476
74
protocol.py
74
protocol.py
|
@ -865,14 +865,11 @@ class Protocol:
|
||||||
from_obj.our_as1 = from_as1
|
from_obj.our_as1 = from_as1
|
||||||
from_obj.put()
|
from_obj.put()
|
||||||
|
|
||||||
from_target = from_cls.target_for(from_obj)
|
|
||||||
if not from_target:
|
|
||||||
error(f"Couldn't find delivery target for follower {from_obj}")
|
|
||||||
|
|
||||||
from_key = from_cls.key_for(from_id)
|
from_key = from_cls.key_for(from_id)
|
||||||
if not from_key:
|
if not from_key:
|
||||||
error(f'Invalid {from_cls} user key: {from_id}')
|
error(f'Invalid {from_cls} user key: {from_id}')
|
||||||
obj.users = [from_key]
|
obj.users = [from_key]
|
||||||
|
from_user = from_cls.get_or_create(id=from_key.id(), obj=from_obj)
|
||||||
|
|
||||||
# Prepare followee (to) users' data
|
# Prepare followee (to) users' data
|
||||||
to_as1s = as1.get_objects(obj.as1)
|
to_as1s = as1.get_objects(obj.as1)
|
||||||
|
@ -882,9 +879,8 @@ class Protocol:
|
||||||
# Store Followers
|
# Store Followers
|
||||||
for to_as1 in to_as1s:
|
for to_as1 in to_as1s:
|
||||||
to_id = to_as1.get('id')
|
to_id = to_as1.get('id')
|
||||||
if not to_id or not from_id:
|
if not to_id:
|
||||||
error(f'Follow activity requires object(s). Got: {obj.as1}')
|
error(f'Follow activity requires object(s). Got: {obj.as1}')
|
||||||
from_user = from_cls.get_or_create(id=from_key.id(), obj=from_obj)
|
|
||||||
|
|
||||||
logger.info(f'Follow {from_id} => {to_id}')
|
logger.info(f'Follow {from_id} => {to_id}')
|
||||||
|
|
||||||
|
@ -900,43 +896,57 @@ class Protocol:
|
||||||
to_obj.our_as1 = to_as1
|
to_obj.our_as1 = to_as1
|
||||||
to_obj.put()
|
to_obj.put()
|
||||||
|
|
||||||
# If followee user is already direct, follower may not know they're
|
|
||||||
# interacting with a bridge. if followee user is indirect though,
|
|
||||||
# follower should know, so they're direct.
|
|
||||||
to_key = to_cls.key_for(to_id)
|
to_key = to_cls.key_for(to_id)
|
||||||
if not to_key:
|
if not to_key:
|
||||||
logger.info(f'Skipping invalid {from_cls} user key: {from_id}')
|
logger.info(f'Skipping invalid {from_cls} user key: {from_id}')
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
# If followee user is already direct, follower may not know they're
|
||||||
|
# interacting with a bridge. if followee user is indirect though,
|
||||||
|
# follower should know, so they're direct.
|
||||||
to_user = to_cls.get_or_create(id=to_key.id(), obj=to_obj, direct=False)
|
to_user = to_cls.get_or_create(id=to_key.id(), obj=to_obj, direct=False)
|
||||||
|
|
||||||
# HACK: we rewrite direct here for each followee, so the last one
|
|
||||||
# wins. Could we do something better?
|
|
||||||
from_user = from_cls.get_or_create(id=from_key.id(), obj=from_obj,
|
|
||||||
direct=not to_user.direct)
|
|
||||||
follower_obj = Follower.get_or_create(to=to_user, from_=from_user,
|
follower_obj = Follower.get_or_create(to=to_user, from_=from_user,
|
||||||
follow=obj.key, status='active')
|
follow=obj.key, status='active')
|
||||||
obj.add('notify', to_key)
|
obj.add('notify', to_key)
|
||||||
|
from_cls.maybe_accept_follow(follower=from_user, followee=to_user,
|
||||||
|
follow=obj)
|
||||||
|
|
||||||
if not to_user.HAS_FOLLOW_ACCEPTS:
|
@classmethod
|
||||||
# send accept. note that this is one accept for the whole
|
def maybe_accept_follow(_, follower, followee, follow):
|
||||||
# follow, even if it has multiple followees!
|
"""Sends an accept activity for a follow.
|
||||||
id = to_user.id_as('activitypub') + 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 the follower protocol handles accepts. Otherwise, does nothing.
|
||||||
if sent:
|
|
||||||
accept.populate(
|
Args:
|
||||||
delivered=[Target(protocol=from_cls.LABEL, uri=from_target)],
|
follower: :class:`models.User`
|
||||||
status='complete',
|
followee: :class:`models.User`
|
||||||
)
|
follow: :class:`models.Object`
|
||||||
accept.put()
|
"""
|
||||||
|
if followee.HAS_FOLLOW_ACCEPTS:
|
||||||
|
return
|
||||||
|
|
||||||
|
# send accept. note that this is one accept for the whole
|
||||||
|
# follow, even if it has multiple followees!
|
||||||
|
id = followee.id_as('activitypub') + f'/followers#accept-{follow.key.id()}'
|
||||||
|
accept = Object.get_or_create(id, our_as1={
|
||||||
|
'id': id,
|
||||||
|
'objectType': 'activity',
|
||||||
|
'verb': 'accept',
|
||||||
|
'actor': followee.key.id(),
|
||||||
|
'object': follow.as1,
|
||||||
|
})
|
||||||
|
|
||||||
|
from_target = follower.target_for(follower.obj)
|
||||||
|
if not from_target:
|
||||||
|
error(f"Couldn't find delivery target for follower {follower}")
|
||||||
|
|
||||||
|
sent = follower.send(accept, from_target, from_user=followee)
|
||||||
|
if sent:
|
||||||
|
accept.populate(
|
||||||
|
delivered=[Target(protocol=follower.LABEL, uri=from_target)],
|
||||||
|
status='complete',
|
||||||
|
)
|
||||||
|
accept.put()
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def handle_bare_object(cls, obj):
|
def handle_bare_object(cls, obj):
|
||||||
|
|
|
@ -1035,7 +1035,7 @@ class ActivityPubTest(TestCase):
|
||||||
ignore=['created', 'updated'])
|
ignore=['created', 'updated'])
|
||||||
|
|
||||||
self.assert_user(ActivityPub, 'https://mas.to/users/swentel',
|
self.assert_user(ActivityPub, 'https://mas.to/users/swentel',
|
||||||
obj_as2=ACTOR, direct=True)
|
obj_as2=ACTOR, direct=False)
|
||||||
self.assert_user(Web, 'user.com', direct=False,
|
self.assert_user(Web, 'user.com', direct=False,
|
||||||
has_hcard=True, has_redirects=True)
|
has_hcard=True, has_redirects=True)
|
||||||
|
|
||||||
|
|
Ładowanie…
Reference in New Issue