From ac8b86059f23035a86ea6eb5f766e1342367c1b0 Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Sun, 1 May 2022 18:14:29 +0100 Subject: [PATCH] Only prevent remote DM deletions during archive --- daemon.py | 10 ++++++---- delete.py | 2 +- happening.py | 2 +- inbox.py | 6 +++--- posts.py | 2 +- tests.py | 17 ++++++++++++----- utils.py | 20 ++++++++++++-------- 7 files changed, 36 insertions(+), 23 deletions(-) diff --git a/daemon.py b/daemon.py index eb4127f76..1a53f123a 100644 --- a/daemon.py +++ b/daemon.py @@ -2363,7 +2363,8 @@ class PubServer(BaseHTTPRequestHandler): nickname, domain, post_filename, debug, - self.server.recent_posts_cache) + self.server.recent_posts_cache, + True) if nickname != 'news': # if this is a local blog post then also remove it # from the news actor @@ -2379,7 +2380,8 @@ class PubServer(BaseHTTPRequestHandler): 'news', domain, post_filename, debug, - self.server.recent_posts_cache) + self.server.recent_posts_cache, + True) self._redirect_headers(actor_str + '/moderation', cookie, calling_domain) @@ -8655,7 +8657,7 @@ class PubServer(BaseHTTPRequestHandler): if self.server.iconsCache.get('repeat_inactive.png'): del self.server.iconsCache['repeat_inactive.png'] - # delete the announce post + # delete the announce post if '?unannounce=' in path: announce_url = path.split('?unannounce=')[1] if '?' in announce_url: @@ -8669,7 +8671,7 @@ class PubServer(BaseHTTPRequestHandler): if post_filename: delete_post(base_dir, http_prefix, nickname, domain, post_filename, - debug, recent_posts_cache) + debug, recent_posts_cache, True) self._post_to_outbox(new_undo_announce, self.server.project_version, diff --git a/delete.py b/delete.py index 6713ceec5..00e83d33a 100644 --- a/delete.py +++ b/delete.py @@ -170,7 +170,7 @@ def outbox_delete(base_dir: str, http_prefix: str, print(message_id) return True delete_post(base_dir, http_prefix, delete_nickname, delete_domain, - post_filename, debug, recent_posts_cache) + post_filename, debug, recent_posts_cache, True) if debug: print('DEBUG: post deleted via c2s - ' + post_filename) diff --git a/happening.py b/happening.py index 39bfd350c..bf2ede6b8 100644 --- a/happening.py +++ b/happening.py @@ -1276,7 +1276,7 @@ def dav_delete_response(base_dir: str, nickname: str, domain: str, token_post_id) delete_post(base_dir, http_prefix, nickname, domain, post_filename, - debug, recent_posts_cache) + debug, recent_posts_cache, True) return 'Ok' diff --git a/inbox.py b/inbox.py index bef69c55c..ef6498d68 100644 --- a/inbox.py +++ b/inbox.py @@ -2058,7 +2058,7 @@ def _receive_delete(session, handle: str, is_group: bool, base_dir: str, return True delete_post(base_dir, http_prefix, handle_nickname, handle_domain, post_filename, debug, - recent_posts_cache) + recent_posts_cache, True) if debug: print('DEBUG: post deleted - ' + post_filename) @@ -2069,7 +2069,7 @@ def _receive_delete(session, handle: str, is_group: bool, base_dir: str, if post_filename: delete_post(base_dir, http_prefix, 'news', handle_domain, post_filename, debug, - recent_posts_cache) + recent_posts_cache, True) if debug: print('DEBUG: blog post deleted - ' + post_filename) return True @@ -4094,7 +4094,7 @@ def _inbox_after_initial(server, inbox_start_time, if edited_filename != destination_filename: delete_post(base_dir, http_prefix, nickname, domain, edited_filename, - debug, recent_posts_cache) + debug, recent_posts_cache, True) # update the indexes for different timelines for boxname in update_index_list: diff --git a/posts.py b/posts.py index f21f76cdb..1780999d7 100644 --- a/posts.py +++ b/posts.py @@ -4294,7 +4294,7 @@ def archive_posts_for_person(http_prefix: str, nickname: str, domain: str, '.json.' + ext)) else: delete_post(base_dir, http_prefix, nickname, domain, - file_path, False, recent_posts_cache) + file_path, False, recent_posts_cache, False) # remove cached html posts post_cache_filename = \ diff --git a/tests.py b/tests.py index d6c30c06c..ecc54ee1f 100644 --- a/tests.py +++ b/tests.py @@ -3393,11 +3393,14 @@ def test_client_to_server(base_dir: str): inbox_path = bob_dir + '/accounts/bob@' + bob_domain + '/inbox' outbox_path = alice_dir + '/accounts/alice@' + alice_domain + '/outbox' - posts_before = \ + bob_posts_before = \ len([name for name in os.listdir(inbox_path) if os.path.isfile(os.path.join(inbox_path, name))]) + alice_posts_before = \ + len([name for name in os.listdir(outbox_path) + if os.path.isfile(os.path.join(outbox_path, name))]) print('\n\nEVENT: Alice deletes her post: ' + outbox_post_id + ' ' + - str(posts_before)) + str(alice_posts_before)) password = 'alicepass' send_delete_via_server(alice_dir, session_alice, 'alice', password, alice_domain, alice_port, @@ -3408,14 +3411,18 @@ def test_client_to_server(base_dir: str): if os.path.isdir(inbox_path): test = len([name for name in os.listdir(inbox_path) if os.path.isfile(os.path.join(inbox_path, name))]) - if test == posts_before-1: + if test == bob_posts_before-1: break time.sleep(1) test = len([name for name in os.listdir(inbox_path) if os.path.isfile(os.path.join(inbox_path, name))]) - assert test == posts_before - 1 - print(">>> post deleted from Alice's outbox and Bob's inbox") + assert test == bob_posts_before - 1 + print(">>> post was deleted from Bob's inbox") +# test = len([name for name in os.listdir(outbox_path) +# if os.path.isfile(os.path.join(outbox_path, name))]) +# assert test == alice_posts_before - 1 +# print(">>> post deleted from Alice's outbox") assert valid_inbox(bob_dir, 'bob', bob_domain) assert valid_inbox_filenames(bob_dir, 'bob', bob_domain, alice_domain, alice_port) diff --git a/utils.py b/utils.py index 61058a600..f5a49d9b4 100644 --- a/utils.py +++ b/utils.py @@ -1619,7 +1619,8 @@ def _is_reply_to_blog_post(base_dir: str, nickname: str, domain: str, def _delete_post_remove_replies(base_dir: str, nickname: str, domain: str, http_prefix: str, post_filename: str, - recent_posts_cache: {}, debug: bool) -> None: + recent_posts_cache: {}, debug: bool, + manual: bool) -> None: """Removes replies when deleting a post """ replies_filename = post_filename.replace('.json', '.replies') @@ -1635,7 +1636,7 @@ def _delete_post_remove_replies(base_dir: str, nickname: str, domain: str, if os.path.isfile(reply_file): delete_post(base_dir, http_prefix, nickname, domain, reply_file, debug, - recent_posts_cache) + recent_posts_cache, manual) # remove the replies file try: os.remove(replies_filename) @@ -1841,14 +1842,15 @@ def _is_remote_dm(domain_full: str, post_json_object: {}) -> bool: this_post_json = post_json_object['object'] if this_post_json.get('attributedTo'): if isinstance(this_post_json['attributedTo'], str): - if '://' + domain_full + '/' not in this_post_json['attributedTo']: + if '://' + domain_full not in this_post_json['attributedTo']: return True return False def delete_post(base_dir: str, http_prefix: str, nickname: str, domain: str, post_filename: str, - debug: bool, recent_posts_cache: {}) -> None: + debug: bool, recent_posts_cache: {}, + manual: bool) -> None: """Recursively deletes a post and its replies and attachments """ post_json_object = load_json(post_filename, 1) @@ -1856,7 +1858,7 @@ def delete_post(base_dir: str, http_prefix: str, # remove any replies _delete_post_remove_replies(base_dir, nickname, domain, http_prefix, post_filename, - recent_posts_cache, debug) + recent_posts_cache, debug, manual) # finally, remove the post itself try: os.remove(post_filename) @@ -1868,8 +1870,10 @@ def delete_post(base_dir: str, http_prefix: str, # don't allow DMs to be deleted if they came from a different instance # otherwise this breaks expectations about how DMs should operate - if _is_remote_dm(domain, post_json_object): - return + # i.e. DMs should only be removed if they are manually deleted + if not manual: + if _is_remote_dm(domain, post_json_object): + return # don't allow deletion of bookmarked posts if _is_bookmarked(base_dir, nickname, domain, post_filename): @@ -1931,7 +1935,7 @@ def delete_post(base_dir: str, http_prefix: str, # remove any replies _delete_post_remove_replies(base_dir, nickname, domain, http_prefix, post_filename, - recent_posts_cache, debug) + recent_posts_cache, debug, manual) # finally, remove the post itself try: os.remove(post_filename)