diff --git a/protocol.py b/protocol.py index 914940f7..73910c69 100644 --- a/protocol.py +++ b/protocol.py @@ -676,8 +676,8 @@ class Protocol: logger.info(f'Returning {ret}') return ret - @staticmethod - def _targets(obj): + @classmethod + def _targets(cls, obj): """Collects the targets to send an :class:`models.Object` to. Args: @@ -740,12 +740,17 @@ class Protocol: add(obj.users, user_key) add(obj.labels, 'notification') + user = as1.get_owner(obj.as1) or as1.get_owner(inner_obj_as1) + user_key = cls.key_for(user) if user else g.user.key if g.user else None + if not user_key: + logger.info("Can't tell who this is from! Skipping followers.") + return targets + # deliver to followers? if (obj.type in ('post', 'update', 'delete', 'share') - and not (obj.type == 'comment' or inner_obj_as1.get('inReplyTo'))): - # TODO: use obj's actor/author instead of g.user? - logger.info(f'Delivering to followers of {g.user.key}') - followers = Follower.query(Follower.to == g.user.key, + and not (obj.type == 'comment' or inner_obj_as1.get('inReplyTo'))): + logger.info(f'Delivering to followers of {user_key}') + followers = Follower.query(Follower.to == user_key, Follower.status == 'active' ).fetch() users = [u for u in ndb.get_multi(f.from_ for f in followers) if u] diff --git a/tests/test_protocol.py b/tests/test_protocol.py index a70d2160..417f8bbf 100644 --- a/tests/test_protocol.py +++ b/tests/test_protocol.py @@ -253,7 +253,7 @@ class ProtocolReceiveTest(TestCase): def setUp(self): super().setUp() - g.user = self.make_user('fake:user', cls=Fake, obj_id='fake:user') + g.user = self.user = self.make_user('fake:user', cls=Fake, obj_id='fake:user') self.alice = self.make_user('fake:alice', cls=Fake, obj_id='fake:alice') self.bob = self.make_user('fake:bob', cls=Fake, obj_id='fake:bob') @@ -269,9 +269,9 @@ class ProtocolReceiveTest(TestCase): return super().assert_object(id, ignore=ignore, **props) def make_followers(self): - Follower.get_or_create(to=g.user, from_=self.alice) - Follower.get_or_create(to=g.user, from_=self.bob) - Follower.get_or_create(to=g.user, from_=Fake(id='fake:eve'), + Follower.get_or_create(to=self.user, from_=self.alice) + Follower.get_or_create(to=self.user, from_=self.bob) + Follower.get_or_create(to=self.user, from_=Fake(id='fake:eve'), status='inactive') def test_create_post(self): @@ -655,6 +655,7 @@ class ProtocolReceiveTest(TestCase): self.assertEqual([(like_obj, 'fake:post:target')], Fake.sent) def test_delete(self): + g.user = None # should use activity's actor self.make_followers() post_as1 = { @@ -668,6 +669,7 @@ class ProtocolReceiveTest(TestCase): 'id': 'fake:delete', 'objectType': 'activity', 'verb': 'delete', + 'actor': 'fake:user', 'object': 'fake:post', } self.assertEqual('OK', Fake.receive(delete_as1)) @@ -684,15 +686,17 @@ class ProtocolReceiveTest(TestCase): delivered=['shared:target'], type='delete', labels=['user', 'activity', 'feed'], - users=[g.user.key, self.alice.key, self.bob.key], + users=[self.user.key, self.alice.key, self.bob.key], ) self.assertEqual([(obj, 'shared:target')], Fake.sent) def test_delete_no_followers_no_stored_object(self): + g.user = None # should use activity's actor delete_as1 = { 'id': 'fake:delete', 'objectType': 'activity', 'verb': 'delete', + 'actor': 'fake:user', 'object': 'fake:post', } with self.assertRaises(NoContent): @@ -709,22 +713,25 @@ class ProtocolReceiveTest(TestCase): delivered=[], type='delete', labels=['user', 'activity', 'feed'], - users=[g.user.key], + users=[self.user.key], ) self.assertEqual([], Fake.sent) def test_delete_actor(self): - follower = Follower.get_or_create(to=g.user, from_=self.alice) + g.user = None + + follower = Follower.get_or_create(to=self.user, from_=self.alice) followee = Follower.get_or_create(to=self.alice, from_=self.bob) - other = Follower.get_or_create(to=g.user, from_=self.bob) + other = Follower.get_or_create(to=self.user, from_=self.bob) self.assertEqual(3, Follower.query().count()) - self.assertEqual('OK', Fake.receive({ - 'objectType': 'activity', - 'verb': 'delete', - 'id': 'fake:delete', - 'object': 'fake:alice', - })) + with self.assertRaises(NoContent): + Fake.receive({ + 'objectType': 'activity', + 'verb': 'delete', + 'id': 'fake:delete', + 'object': 'fake:alice', + }) self.assertEqual(3, Follower.query().count()) self.assertEqual('inactive', follower.key.get().status) @@ -735,6 +742,7 @@ class ProtocolReceiveTest(TestCase): deleted=True, source_protocol=None, ) + @patch.object(Fake, 'send') @patch.object(Fake, 'target_for') def test_send_error(self, mock_target_for, mock_send):