diff --git a/dms.py b/dms.py index 1161bb8d..c2165bcb 100644 --- a/dms.py +++ b/dms.py @@ -29,6 +29,7 @@ 'ok', 'start', 'stop', + 'unblock', 'username', 'yes', ) @@ -188,7 +189,7 @@ def reply(text, type=None): return reply(str(e)) return reply(f"Your username in {to_proto.PHRASE} has been set to {from_user.user_link(proto=to_proto, name=False, handle=True)}. It should appear soon!") - if cmd == 'block' and arg: + if cmd in ('block', 'unblock') and arg: handle = arg if not to_proto.owns_handle(handle) and handle.startswith('@'): logging.info(f"doesn't look like a handle, trying without leading @") @@ -198,17 +199,30 @@ def reply(text, type=None): if not to_user: return reply(f"Couldn't find {to_proto.PHRASE} user {handle}") - block_id = f'{from_user.key.id()}#bridgy-fed-block-{util.now().isoformat()}' - obj = Object(id=block_id, source_protocol=from_user.LABEL, our_as1={ - 'id': block_id, + obj_as1 = { 'objectType': 'activity', 'verb': 'block', 'actor': from_user.key.id(), 'object': to_user.key.id(), - }) + } + + if cmd == 'block': + msg = f"""OK, you're now blocking {to_user.user_link()} on {to_proto.PHRASE}.""" + elif cmd == 'unblock': + obj_as1 = { + 'objectType': 'activity', + 'verb': 'undo', + 'actor': from_user.key.id(), + 'object': obj_as1, + } + msg = f"""OK, you're not blocking {to_user.user_link()} on {to_proto.PHRASE}.""" + + id = f'{from_user.key.id()}#bridgy-fed-{cmd}-{util.now().isoformat()}' + obj_as1['id'] = id + obj = Object(id=id, source_protocol=from_user.LABEL, our_as1=obj_as1) obj.put() from_user.deliver(obj, from_user=from_user) - return reply(f"""OK, you're now blocking {to_user.user_link()} in {to_proto.PHRASE}.""") + return reply(msg) # are they requesting a user? if not cmd: diff --git a/protocol.py b/protocol.py index acf1c083..a8cdf14c 100644 --- a/protocol.py +++ b/protocol.py @@ -1399,9 +1399,10 @@ def targets(from_cls, obj, from_user, crud_obj=None, internal=False): is_reply = obj.type == 'comment' or in_reply_tos is_self_reply = False + original_ids = [] if is_reply: original_ids = in_reply_tos - else: + elif inner_obj_id: if inner_obj_id == from_user.key.id(): inner_obj_id = from_user.profile_id() original_ids = [inner_obj_id] diff --git a/templates/docs.html b/templates/docs.html index 5d0dba3c..a4a330d3 100644 --- a/templates/docs.html +++ b/templates/docs.html @@ -367,6 +367,7 @@
You can use the block
DM command. First, find the Bridgy Fed bot account for the network they're in. Then, DM that account block [handle]
, where handle is the address of the user you want to block.
For example, if you're on the fediverse, and you want to block @badguy.bsky.social on Bluesky, find the @bsky.brid.gy@bsky.brid.gy account and send it a DM with the text block badguy.bsky.social
.
+
If you change your mind, you can unblock them with the unblock
command, eg unblock badguy.bsky.social
.
*.brid.gy
domain in my bridged account's handle is ugly. Can I get rid of it and use my own domain/web site instead?If you do nothing, your account won't be bridged, and users on efake-phrase won't be able to see or interact with you.
Bridgy Fed will only send you this message once.""" -DM_EFAKE_ALICE_SET_USERNAME_OTHER = { +DM_ALICE_SET_USERNAME_OTHER = { **DM_BASE, 'content': 'username new-handle', } ALICE_USERNAME_CONFIRMATION_CONTENT = 'Your username in other-phrase has been set to other:handle:efake:handle:alice. It should appear soon!' -DM_EFAKE_ALICE_BLOCK_BOB = { +DM_ALICE_BLOCK_BOB = { **DM_BASE, 'content': 'block other:handle:bob', } -ALICE_BLOCK_CONFIRMATION_CONTENT = """OK, you're now blocking other:handle:bob in other-phrase.""" +ALICE_BLOCK_CONFIRMATION_CONTENT = """OK, you're now blocking other:handle:bob on other-phrase.""" + +DM_ALICE_UNBLOCK_BOB = { + **DM_BASE, + 'content': 'unblock other:handle:bob', +} +ALICE_UNBLOCK_CONFIRMATION_CONTENT = """OK, you're not blocking other:handle:bob on other-phrase.""" class DmsTest(TestCase): @@ -221,7 +227,7 @@ def test_receive_no_yes_sets_enabled_protocols(self): def test_receive_prompt_sends_request_dm(self): alice, bob = self.make_alice_bob() - obj = Object(our_as1=DM_EFAKE_ALICE_REQUESTS_OTHER_BOB) + obj = Object(our_as1=DM_ALICE_REQUESTS_BOB) self.assertEqual(('OK', 200), receive(from_user=alice, obj=obj)) self.assert_replied(OtherFake, alice, '?', ALICE_REQUEST_CONFIRMATION_CONTENT) @@ -281,7 +287,7 @@ def test_receive_prompt_fetch_user(self): enabled_protocols=['other'], obj_as1={'x': 'y'}) OtherFake.fetchable['other:bob'] = {'x': 'y'} - obj = Object(our_as1=DM_EFAKE_ALICE_REQUESTS_OTHER_BOB) + obj = Object(our_as1=DM_ALICE_REQUESTS_BOB) self.assertEqual(('OK', 200), receive(from_user=alice, obj=obj)) self.assert_replied(OtherFake, alice, '?', ALICE_REQUEST_CONFIRMATION_CONTENT) self.assert_sent(ExplicitFake, OtherFake(id='other:bob'), @@ -294,7 +300,7 @@ def test_receive_prompt_user_doesnt_exist(self): enabled_protocols=['other'], obj_as1={'x': 'y'}) OtherFake.fetchable = {} - obj = Object(our_as1=DM_EFAKE_ALICE_REQUESTS_OTHER_BOB) + obj = Object(our_as1=DM_ALICE_REQUESTS_BOB) self.assertEqual(('OK', 200), receive(from_user=alice, obj=obj)) self.assert_replied(OtherFake, alice, '?', "Couldn't find other-phrase user other:handle:bob") self.assertEqual([], OtherFake.sent) @@ -305,7 +311,7 @@ def test_receive_prompt_from_user_not_bridged(self): alice.enabled_protocols = ['fake'] alice.put() - obj = Object(our_as1=DM_EFAKE_ALICE_REQUESTS_OTHER_BOB) + obj = Object(our_as1=DM_ALICE_REQUESTS_BOB) self.assertEqual(('OK', 200), receive(from_user=alice, obj=obj)) self.assert_replied(OtherFake, alice, '?', "Looks like you're not bridged to other-phrase yet!") self.assertEqual([], OtherFake.sent) @@ -316,7 +322,7 @@ def test_receive_prompt_already_bridged(self): bob.enabled_protocols = ['efake'] bob.put() - obj = Object(our_as1=DM_EFAKE_ALICE_REQUESTS_OTHER_BOB) + obj = Object(our_as1=DM_ALICE_REQUESTS_BOB) self.assertEqual(('OK', 200), receive(from_user=alice, obj=obj)) self.assert_replied(OtherFake, alice, '?', """other:handle:bob · efake:handle:other:handle:bob is already bridged into efake-phrase.""") self.assertEqual([], OtherFake.sent) @@ -326,7 +332,7 @@ def test_receive_prompt_already_requested(self): bob.sent_dms = [DM(protocol='efake', type='request_bridging')] bob.put() - obj = Object(our_as1=DM_EFAKE_ALICE_REQUESTS_OTHER_BOB) + obj = Object(our_as1=DM_ALICE_REQUESTS_BOB) self.assertEqual(('OK', 200), receive(from_user=alice, obj=obj)) self.assert_replied(OtherFake, alice, '?', """We've already sent other:handle:bob a DM. Fingers crossed!""") self.assertEqual([], OtherFake.sent) @@ -338,7 +344,7 @@ def test_receive_prompt_request_rate_limit(self): eve = self.make_user(id='other:eve', cls=OtherFake, obj_as1={'x': 'y'}) frank = self.make_user(id='other:frank', cls=OtherFake, obj_as1={'x': 'y'}) - obj = Object(our_as1=DM_EFAKE_ALICE_REQUESTS_OTHER_BOB) + obj = Object(our_as1=DM_ALICE_REQUESTS_BOB) self.assertEqual(('OK', 200), receive(from_user=alice, obj=obj)) obj = Object(our_as1={ @@ -381,7 +387,7 @@ def test_receive_prompt_wrong_protocol(self): @mock.patch('ids.translate_handle', side_effect=ValueError('nope')) def test_receive_prompt_not_supported_in_target_protocol(self, _): alice, bob = self.make_alice_bob() - obj = Object(our_as1=DM_EFAKE_ALICE_REQUESTS_OTHER_BOB) + obj = Object(our_as1=DM_ALICE_REQUESTS_BOB) self.assertEqual(('OK', 200), receive(from_user=alice, obj=obj)) self.assert_replied(OtherFake, alice, '?', "Sorry, Bridgy Fed doesn't yet support bridging handle other:handle:bob from other-phrase to efake-phrase.") @@ -392,7 +398,7 @@ def test_receive_username(self): alice = self.make_user(id='efake:alice', cls=ExplicitFake, enabled_protocols=['other'], obj_as1={'x': 'y'}) - obj = Object(our_as1=DM_EFAKE_ALICE_SET_USERNAME_OTHER) + obj = Object(our_as1=DM_ALICE_SET_USERNAME_OTHER) self.assertEqual(('OK', 200), receive(from_user=alice, obj=obj)) self.assert_replied(OtherFake, alice, '?', ALICE_USERNAME_CONFIRMATION_CONTENT) self.assertEqual({'efake:alice': 'new-handle'}, OtherFake.usernames) @@ -416,7 +422,7 @@ def test_receive_username_fails(self, _): alice = self.make_user(id='efake:alice', cls=ExplicitFake, enabled_protocols=['other'], obj_as1={'x': 'y'}) - obj = Object(our_as1=DM_EFAKE_ALICE_SET_USERNAME_OTHER) + obj = Object(our_as1=DM_ALICE_SET_USERNAME_OTHER) self.assertEqual(('OK', 200), receive(from_user=alice, obj=obj)) self.assert_replied(OtherFake, alice, '?', 'nopey') self.assertEqual({}, OtherFake.usernames) @@ -470,7 +476,7 @@ def test_receive_did_atproto(self): def test_receive_block(self): alice, bob = self.make_alice_bob() - obj = Object(our_as1=DM_EFAKE_ALICE_BLOCK_BOB) + obj = Object(our_as1=DM_ALICE_BLOCK_BOB) self.assertEqual(('OK', 200), receive(from_user=alice, obj=obj)) self.assert_replied(OtherFake, alice, '?', ALICE_BLOCK_CONFIRMATION_CONTENT) @@ -491,7 +497,7 @@ def test_receive_block_handle_at_symbol(self): alice, bob = self.make_alice_bob() obj = Object(our_as1={ - **DM_EFAKE_ALICE_BLOCK_BOB, + **DM_ALICE_BLOCK_BOB, 'content': ' block @other:handle:bob ', }) self.assertEqual(('OK', 200), receive(from_user=alice, obj=obj)) @@ -504,3 +510,28 @@ def test_receive_block_handle_at_symbol(self): 'actor': 'efake:alice', 'object': 'other:bob', })], OtherFake.sent) + + def test_receive_unblock(self): + alice, bob = self.make_alice_bob() + + obj = Object(our_as1=DM_ALICE_UNBLOCK_BOB) + self.assertEqual(('OK', 200), receive(from_user=alice, obj=obj)) + + self.assert_replied(OtherFake, alice, '?', ALICE_UNBLOCK_CONFIRMATION_CONTENT) + + unblock_as1 = { + 'objectType': 'activity', + 'verb': 'undo', + 'id': 'efake:alice#bridgy-fed-unblock-2022-01-02T03:04:05+00:00', + 'actor': 'efake:alice', + 'object': { + 'objectType': 'activity', + 'verb': 'block', + 'actor': 'efake:alice', + 'object': 'other:bob', + }, + } + self.assert_object(id='efake:alice#bridgy-fed-unblock-2022-01-02T03:04:05+00:00', + our_as1=unblock_as1, source_protocol='efake', + ignore=['copies']) + self.assertEqual([('other:bob:target', unblock_as1)], OtherFake.sent)