kopia lustrzana https://github.com/snarfed/bridgy-fed
activitypub: store Create inner objects in their own Objects
rodzic
fa03958d89
commit
fa2a9a1afe
|
@ -135,9 +135,7 @@ def inbox(domain=None):
|
|||
elif obj.type not in SUPPORTED_TYPES:
|
||||
error(f'Sorry, {obj.type} activities are not supported yet.', status=501)
|
||||
|
||||
inner_obj = obj.as1.get('object') or {}
|
||||
if isinstance(inner_obj, str):
|
||||
inner_obj = {'id': inner_obj}
|
||||
inner_obj = as1.get_object(obj.as1)
|
||||
inner_obj_id = inner_obj.get('id')
|
||||
|
||||
# load user
|
||||
|
@ -149,6 +147,20 @@ def inbox(domain=None):
|
|||
|
||||
verify_signature(user)
|
||||
|
||||
# check that this activity is public. only do this check for creates, not
|
||||
# like, follow, or other activity types, since Mastodon doesn't currently
|
||||
# mark those as explicitly public. Use as2's is_public instead of as1's
|
||||
# because as1's interprets unlisted as true.
|
||||
if obj.type in ('post', 'create') and not as2.is_public(obj.as2):
|
||||
logger.info('Dropping non-public activity')
|
||||
return 'OK'
|
||||
|
||||
# store inner object
|
||||
if obj.type in ('post', 'create', 'update') and inner_obj.keys() > set(['id']):
|
||||
to_update = Object.get_by_id(inner_obj_id) or Object(id=inner_obj_id)
|
||||
to_update.populate(as2=obj.as2['object'], source_protocol='activitypub')
|
||||
to_update.put()
|
||||
|
||||
# handle activity!
|
||||
if obj.type == 'stop-following':
|
||||
# granary doesn't yet handle three-actor undo follows, eg Eve undoes
|
||||
|
@ -179,10 +191,6 @@ def inbox(domain=None):
|
|||
if not inner_obj_id:
|
||||
error("Couldn't find id of object to update")
|
||||
|
||||
to_update = Object.get_by_id(inner_obj_id) or Object(id=inner_obj_id)
|
||||
to_update.populate(as2=obj.as2.get('object'), source_protocol='activitypub')
|
||||
to_update.put()
|
||||
|
||||
obj.status = 'complete'
|
||||
obj.put()
|
||||
return 'OK'
|
||||
|
@ -224,25 +232,16 @@ def inbox(domain=None):
|
|||
common.send_webmentions(as2.to_as1(activity), obj, proxy=True)
|
||||
|
||||
# deliver original posts and reposts to followers
|
||||
if obj.type in ('share', 'create', 'post'):
|
||||
# check that this activity is public. only do this check for Creates,
|
||||
# not Like, Follow, or other activity types, since Mastodon doesn't
|
||||
# currently mark those as explicitly public.
|
||||
if not as1.is_public(obj.as1):
|
||||
logger.info('Dropping non-public activity')
|
||||
return 'OK'
|
||||
if obj.type in ('share', 'create', 'post') and actor and actor_id:
|
||||
logger.info(f'Delivering to followers of {actor_id}')
|
||||
for f in Follower.query(Follower.dest == actor_id,
|
||||
projection=[Follower.src]):
|
||||
if f.src not in obj.domains:
|
||||
obj.domains.append(f.src)
|
||||
if obj.domains and 'feed' not in obj.labels:
|
||||
obj.labels.append('feed')
|
||||
|
||||
if actor and actor_id:
|
||||
logger.info(f'Delivering to followers of {actor_id}')
|
||||
for f in Follower.query(Follower.dest == actor_id,
|
||||
projection=[Follower.src]):
|
||||
if f.src not in obj.domains:
|
||||
obj.domains.append(f.src)
|
||||
if obj.domains and 'feed' not in obj.labels:
|
||||
obj.labels.append('feed')
|
||||
|
||||
if (obj.as1.get('objectType') == 'activity'
|
||||
and 'activity' not in obj.labels):
|
||||
if obj.as1.get('objectType') == 'activity' and 'activity' not in obj.labels:
|
||||
obj.labels.append('activity')
|
||||
|
||||
obj.put()
|
||||
|
|
|
@ -303,6 +303,10 @@ class ActivityPubTest(testutil.TestCase):
|
|||
'labels': ['notification', 'activity'],
|
||||
},
|
||||
*mocks)
|
||||
self.assert_object(REPLY_OBJECT['id'],
|
||||
source_protocol='activitypub',
|
||||
as2=REPLY_OBJECT,
|
||||
type='comment')
|
||||
|
||||
def _test_inbox_reply(self, reply, expected_props, mock_head, mock_get, mock_post):
|
||||
mock_head.return_value = requests_response(url='http://or.ig/post')
|
||||
|
@ -380,6 +384,10 @@ class ActivityPubTest(testutil.TestCase):
|
|||
type='post',
|
||||
labels=['activity', 'feed'],
|
||||
object_ids=[NOTE_OBJECT['id']])
|
||||
self.assert_object(NOTE_OBJECT['id'],
|
||||
source_protocol='activitypub',
|
||||
as2=NOTE_OBJECT,
|
||||
type='note')
|
||||
|
||||
def test_repost_of_federated_post(self, mock_head, mock_get, mock_post):
|
||||
mock_head.return_value = requests_response(url='https://foo.com/orig')
|
||||
|
@ -480,7 +488,7 @@ class ActivityPubTest(testutil.TestCase):
|
|||
self.assertEqual(200, got.status_code, got.get_data(as_text=True))
|
||||
|
||||
obj = Object.get_by_id(not_public['id'])
|
||||
self.assertEqual(['activity'], obj.labels)
|
||||
self.assertEqual([], obj.labels)
|
||||
self.assertEqual([], obj.domains)
|
||||
|
||||
self.assertIsNone(Object.get_by_id(not_public['object']['id']))
|
||||
|
@ -506,6 +514,14 @@ class ActivityPubTest(testutil.TestCase):
|
|||
*mocks,
|
||||
)
|
||||
|
||||
# redirect unwrap
|
||||
expected_as2 = copy.deepcopy(MENTION_OBJECT)
|
||||
expected_as2['tag'][1]['href'] = 'https://tar.get/'
|
||||
self.assert_object(MENTION_OBJECT['id'],
|
||||
source_protocol='activitypub',
|
||||
as2=expected_as2,
|
||||
type='note')
|
||||
|
||||
def _test_inbox_mention(self, mention, expected_props, mock_head, mock_get, mock_post):
|
||||
mock_get.return_value = requests_response(
|
||||
'<html><head><link rel="webmention" href="/webmention"></html>')
|
||||
|
|
Ładowanie…
Reference in New Issue