From 438b6d59ce12f2293c10e24aa0510e38c632fe76 Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Mon, 14 Mar 2022 14:50:44 +0000 Subject: [PATCH 1/5] Debug for rejected announces --- posts.py | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/posts.py b/posts.py index 5171b6422..ff569038c 100644 --- a/posts.py +++ b/posts.py @@ -4842,18 +4842,22 @@ def download_announce(session, base_dir: str, http_prefix: str, return None if not isinstance(announced_json, dict): - print('WARN: announce json is not a dict - ' + + print('WARN: announced post json is not a dict - ' + post_json_object['object']) _reject_announce(announce_filename, base_dir, nickname, domain, post_id, recent_posts_cache) return None if not announced_json.get('id'): + print('WARN: announced post does not have an id ' + + str(announced_json)) _reject_announce(announce_filename, base_dir, nickname, domain, post_id, recent_posts_cache) return None if not announced_json.get('type'): + print('WARN: announced post does not have a type ' + + str(announced_json)) _reject_announce(announce_filename, base_dir, nickname, domain, post_id, recent_posts_cache) @@ -4866,11 +4870,15 @@ def download_announce(session, base_dir: str, http_prefix: str, if converted_json: announced_json = converted_json if '/statuses/' not in announced_json['id']: + print('WARN: announced post id does not contain /statuses/ ' + + str(announced_json)) _reject_announce(announce_filename, base_dir, nickname, domain, post_id, recent_posts_cache) return None if not has_users_path(announced_json['id']): + print('WARN: announced post id does not contain /users/ ' + + str(announced_json)) _reject_announce(announce_filename, base_dir, nickname, domain, post_id, recent_posts_cache) @@ -4878,22 +4886,30 @@ def download_announce(session, base_dir: str, http_prefix: str, if announced_json['type'] != 'Note' and \ announced_json['type'] != 'Page' and \ announced_json['type'] != 'Article': + print('WARN: announced post is not Note/Page/Article ' + + str(announced_json)) # You can only announce Note or Article types _reject_announce(announce_filename, base_dir, nickname, domain, post_id, recent_posts_cache) return None if not announced_json.get('content'): + print('WARN: announced post does not have content ' + + str(announced_json)) _reject_announce(announce_filename, base_dir, nickname, domain, post_id, recent_posts_cache) return None if not announced_json.get('published'): + print('WARN: announced post does not have published ' + + str(announced_json)) _reject_announce(announce_filename, base_dir, nickname, domain, post_id, recent_posts_cache) return None if not valid_post_date(announced_json['published'], 90, debug): + print('WARN: announced post is not recently published ' + + str(announced_json)) _reject_announce(announce_filename, base_dir, nickname, domain, post_id, recent_posts_cache) @@ -4906,18 +4922,24 @@ def download_announce(session, base_dir: str, http_prefix: str, # Check the content of the announce content_str = announced_json['content'] if dangerous_markup(content_str, allow_local_network_access): + print('WARN: announced post contains dangerous markup ' + + str(announced_json)) _reject_announce(announce_filename, base_dir, nickname, domain, post_id, recent_posts_cache) return None if is_filtered(base_dir, nickname, domain, content_str): + print('WARN: announced post has been filtered ' + + str(announced_json)) _reject_announce(announce_filename, base_dir, nickname, domain, post_id, recent_posts_cache) return None if invalid_ciphertext(content_str): + print('WARN: announced post contains invalid ciphertext ' + + str(announced_json)) _reject_announce(announce_filename, base_dir, nickname, domain, post_id, recent_posts_cache) @@ -4943,6 +4965,8 @@ def download_announce(session, base_dir: str, http_prefix: str, actor_nickname, actor_domain, actor_port, announced_json) if announced_json['type'] != 'Create': + print('WARN: announced post could not be wrapped in Create ' + + str(announced_json)) # Create wrap failed _reject_announce(announce_filename, base_dir, nickname, domain, post_id, @@ -4963,6 +4987,8 @@ def download_announce(session, base_dir: str, http_prefix: str, get_full_domain(attributed_domain, attributed_port) if is_blocked(base_dir, nickname, domain, attributed_nickname, attributed_domain): + print('WARN: announced post handle is blocked ' + + str(attributed_nickname) + '@' + attributed_domain) _reject_announce(announce_filename, base_dir, nickname, domain, post_id, recent_posts_cache) From 2f58bade3aa2871898af9bfe4bad0eb444560c1c Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Mon, 14 Mar 2022 15:51:12 +0000 Subject: [PATCH 2/5] Add alternate domains to alsoKnownAs --- daemon.py | 4 +++- person.py | 26 ++++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/daemon.py b/daemon.py index 110ced53f..f3a09c420 100644 --- a/daemon.py +++ b/daemon.py @@ -60,6 +60,7 @@ from donate import get_donation_url from donate import set_donation_url from donate import get_website from donate import set_website +from person import add_alternate_domains from person import add_actor_update_timestamp from person import set_person_notes from person import get_default_person_context @@ -428,7 +429,7 @@ class PubServer(BaseHTTPRequestHandler): def _convert_domains(self, calling_domain, referer_domain, msg_str: str) -> str: - """Convert domains to onion or i2p + """Convert domains to onion or i2p, depending upon who is asking """ curr_http_prefix = self.server.http_prefix + '://' if is_onion_request(calling_domain, referer_domain, @@ -13428,6 +13429,7 @@ class PubServer(BaseHTTPRequestHandler): actor_json = person_lookup(domain, path, base_dir) if not actor_json: return False + add_alternate_domains(actor_json, domain, onion_domain, i2p_domain) if self._request_http(): curr_session = \ self._establish_session("showPersonProfile", diff --git a/person.py b/person.py index 69026c9fc..c6ddc773c 100644 --- a/person.py +++ b/person.py @@ -38,6 +38,7 @@ from roles import set_role from roles import set_rolesFromList from roles import get_actor_roles_list from media import process_meta_data +from utils import get_nickname_from_actor from utils import remove_html from utils import contains_invalid_chars from utils import replace_users_with_at @@ -861,6 +862,31 @@ def person_upgrade_actor(base_dir: str, person_json: {}, save_json(person_json, actor_cache_filename) +def add_alternate_domains(actor_json: {}, domain: str, + onion_domain: str, i2p_domain: str) -> None: + """Adds alternate onion and/or i2p domains to alsoKnownAs + """ + if not onion_domain and not i2p_domain: + return + if not actor_json.get('id'): + return + if domain not in actor_json['id']: + return + nickname = get_nickname_from_actor(actor_json['id']) + if not nickname: + return + if 'alsoKnownAs' not in actor_json: + actor_json['alsoKnownAs'] = [] + if onion_domain: + onion_actor = 'http://' + onion_domain + '/users/' + nickname + if onion_actor not in actor_json['alsoKnownAs']: + actor_json['alsoKnownAs'].append(onion_actor) + if i2p_domain: + i2p_actor = 'http://' + i2p_domain + '/users/' + nickname + if i2p_actor not in actor_json['alsoKnownAs']: + actor_json['alsoKnownAs'].append(i2p_actor) + + def person_lookup(domain: str, path: str, base_dir: str) -> {}: """Lookup the person for an given nickname """ From b08acd0cf0943ea610ad2c9734e209c0d250adaf Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Mon, 14 Mar 2022 17:37:46 +0000 Subject: [PATCH 3/5] Write a file to indicate that a post was delivered via a third party --- inbox.py | 18 ++++++++++++++++-- utils.py | 2 +- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/inbox.py b/inbox.py index b3ba36255..2fcd611a4 100644 --- a/inbox.py +++ b/inbox.py @@ -3297,7 +3297,8 @@ def _inbox_after_initial(server, default_reply_interval_hrs: int, cw_lists: {}, lists_enabled: str, content_license_url: str, - languages_understood: []) -> bool: + languages_understood: [], + mitm: bool) -> bool: """ Anything which needs to be done after initial checks have passed """ # if this is a clearnet instance then replace any onion/i2p @@ -3634,6 +3635,16 @@ def _inbox_after_initial(server, # save the post to file if save_json(post_json_object, destination_filename): + if mitm: + # write a file to indicate that this post was delivered + # via a third party + destination_filename_mitm = destination_filename + '.mitm' + try: + with open(destination_filename_mitm, 'w+') as mitm_file: + mitm_file.write('\n') + except OSError: + print('EX: unable to write ' + destination_filename_mitm) + _low_frequency_post_notification(base_dir, http_prefix, nickname, domain, port, handle, post_is_dm, json_obj) @@ -4728,6 +4739,9 @@ def run_inbox_queue(server, destination = \ queue_json['destination'].replace(inbox_handle, handle) languages_understood = [] + mitm = False + if queue_json.get('mitm'): + mitm = True _inbox_after_initial(server, recent_posts_cache, max_recent_posts, @@ -4759,7 +4773,7 @@ def run_inbox_queue(server, default_reply_interval_hrs, cw_lists, lists_enabled, content_license_url, - languages_understood) + languages_understood, mitm) if debug: pprint(queue_json['post']) print('Queue: Queue post accepted') diff --git a/utils.py b/utils.py index a4b9b8396..e647e5680 100644 --- a/utils.py +++ b/utils.py @@ -1788,7 +1788,7 @@ def delete_post(base_dir: str, http_prefix: str, # remove any attachment _remove_attachment(base_dir, http_prefix, domain, post_json_object) - extensions = ('votes', 'arrived', 'muted', 'tts', 'reject') + extensions = ('votes', 'arrived', 'muted', 'tts', 'reject', 'mitm') for ext in extensions: ext_filename = post_filename + '.' + ext if os.path.isfile(ext_filename): From b68fd5c5615ad810f35bf0efad59a32a13b4325f Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Mon, 14 Mar 2022 19:55:36 +0000 Subject: [PATCH 4/5] mitm parameter available when generating posts --- daemon.py | 60 +++++++++++++++++++++++++++++++++++-------- inbox.py | 50 +++++++++++++++++++++++++++--------- outbox.py | 6 ++++- posts.py | 15 +++++++++++ webapp_confirm.py | 5 +++- webapp_create_post.py | 2 +- webapp_frontscreen.py | 2 +- webapp_likers.py | 5 +++- webapp_post.py | 19 +++++++++----- webapp_profile.py | 4 +-- webapp_search.py | 4 +-- webapp_timeline.py | 5 +++- 12 files changed, 138 insertions(+), 39 deletions(-) diff --git a/daemon.py b/daemon.py index f3a09c420..6eb73c27b 100644 --- a/daemon.py +++ b/daemon.py @@ -8364,6 +8364,10 @@ class PubServer(BaseHTTPRequestHandler): if self.server.account_timezone.get(self.post_to_nickname): timezone = \ self.server.account_timezone.get(self.post_to_nickname) + mitm = False + if os.path.isfile(announce_filename.replace('.json', '') + + '.mitm'): + mitm = True individual_post_as_html(self.server.signing_priv_key_pem, False, self.server.recent_posts_cache, self.server.max_recent_posts, @@ -8392,7 +8396,7 @@ class PubServer(BaseHTTPRequestHandler): False, True, False, self.server.cw_lists, self.server.lists_enabled, - timezone) + timezone, mitm) actor_absolute = self._get_instance_url(calling_domain) + actor actor_path_str = \ @@ -8895,6 +8899,10 @@ class PubServer(BaseHTTPRequestHandler): if self.server.account_timezone.get(self.post_to_nickname): timezone = \ self.server.account_timezone.get(self.post_to_nickname) + mitm = False + if os.path.isfile(liked_post_filename.replace('.json', '') + + '.mitm'): + mitm = True individual_post_as_html(self.server.signing_priv_key_pem, False, self.server.recent_posts_cache, @@ -8925,7 +8933,7 @@ class PubServer(BaseHTTPRequestHandler): False, True, False, self.server.cw_lists, self.server.lists_enabled, - timezone) + timezone, mitm) else: print('WARN: Liked post not found: ' + liked_post_filename) # clear the icon from the cache so that it gets updated @@ -9073,6 +9081,10 @@ class PubServer(BaseHTTPRequestHandler): if self.server.account_timezone.get(self.post_to_nickname): timezone = \ self.server.account_timezone.get(self.post_to_nickname) + mitm = False + if os.path.isfile(liked_post_filename.replace('.json', '') + + '.mitm'): + mitm = True individual_post_as_html(self.server.signing_priv_key_pem, False, self.server.recent_posts_cache, @@ -9103,7 +9115,7 @@ class PubServer(BaseHTTPRequestHandler): False, True, False, self.server.cw_lists, self.server.lists_enabled, - timezone) + timezone, mitm) else: print('WARN: Unliked post not found: ' + liked_post_filename) # clear the icon from the cache so that it gets updated @@ -9280,6 +9292,10 @@ class PubServer(BaseHTTPRequestHandler): if self.server.account_timezone.get(self.post_to_nickname): timezone = \ self.server.account_timezone.get(self.post_to_nickname) + mitm = False + if os.path.isfile(reaction_post_filename.replace('.json', '') + + '.mitm'): + mitm = True individual_post_as_html(self.server.signing_priv_key_pem, False, self.server.recent_posts_cache, @@ -9310,7 +9326,7 @@ class PubServer(BaseHTTPRequestHandler): False, True, False, self.server.cw_lists, self.server.lists_enabled, - timezone) + timezone, mitm) else: print('WARN: Emoji reaction post not found: ' + reaction_post_filename) @@ -9477,6 +9493,10 @@ class PubServer(BaseHTTPRequestHandler): if self.server.account_timezone.get(self.post_to_nickname): timezone = \ self.server.account_timezone.get(self.post_to_nickname) + mitm = False + if os.path.isfile(reaction_post_filename.replace('.json', '') + + '.mitm'): + mitm = True individual_post_as_html(self.server.signing_priv_key_pem, False, self.server.recent_posts_cache, @@ -9507,7 +9527,7 @@ class PubServer(BaseHTTPRequestHandler): False, True, False, self.server.cw_lists, self.server.lists_enabled, - timezone) + timezone, mitm) else: print('WARN: Unreaction post not found: ' + reaction_post_filename) @@ -9724,6 +9744,10 @@ class PubServer(BaseHTTPRequestHandler): if self.server.account_timezone.get(self.post_to_nickname): timezone = \ self.server.account_timezone.get(self.post_to_nickname) + mitm = False + if os.path.isfile(bookmark_filename.replace('.json', '') + + '.mitm'): + mitm = True individual_post_as_html(self.server.signing_priv_key_pem, False, self.server.recent_posts_cache, @@ -9754,7 +9778,7 @@ class PubServer(BaseHTTPRequestHandler): False, True, False, self.server.cw_lists, self.server.lists_enabled, - timezone) + timezone, mitm) else: print('WARN: Bookmarked post not found: ' + bookmark_filename) # self._post_to_outbox(bookmark_json, @@ -9876,6 +9900,10 @@ class PubServer(BaseHTTPRequestHandler): if self.server.account_timezone.get(self.post_to_nickname): timezone = \ self.server.account_timezone.get(self.post_to_nickname) + mitm = False + if os.path.isfile(bookmark_filename.replace('.json', '') + + '.mitm'): + mitm = True individual_post_as_html(self.server.signing_priv_key_pem, False, self.server.recent_posts_cache, @@ -9906,7 +9934,7 @@ class PubServer(BaseHTTPRequestHandler): False, True, False, self.server.cw_lists, self.server.lists_enabled, - timezone) + timezone, mitm) else: print('WARN: Unbookmarked post not found: ' + bookmark_filename) @@ -10101,6 +10129,10 @@ class PubServer(BaseHTTPRequestHandler): if self.server.account_timezone.get(nickname): timezone = \ self.server.account_timezone.get(nickname) + mitm = False + if os.path.isfile(mute_filename.replace('.json', '') + + '.mitm'): + mitm = True individual_post_as_html(self.server.signing_priv_key_pem, allow_downloads, self.server.recent_posts_cache, @@ -10132,7 +10164,7 @@ class PubServer(BaseHTTPRequestHandler): use_cache_only, self.server.cw_lists, self.server.lists_enabled, - timezone) + timezone, mitm) else: print('WARN: Muted post not found: ' + mute_filename) @@ -10218,6 +10250,10 @@ class PubServer(BaseHTTPRequestHandler): if self.server.account_timezone.get(nickname): timezone = \ self.server.account_timezone.get(nickname) + mitm = False + if os.path.isfile(mute_filename.replace('.json', '') + + '.mitm'): + mitm = True individual_post_as_html(self.server.signing_priv_key_pem, allow_downloads, self.server.recent_posts_cache, @@ -10249,7 +10285,7 @@ class PubServer(BaseHTTPRequestHandler): use_cache_only, self.server.cw_lists, self.server.lists_enabled, - timezone) + timezone, mitm) else: print('WARN: Unmuted post not found: ' + mute_filename) if calling_domain.endswith('.onion') and onion_domain: @@ -11009,6 +11045,10 @@ class PubServer(BaseHTTPRequestHandler): if self.server.account_timezone.get(nickname): timezone = \ self.server.account_timezone.get(nickname) + mitm = False + if os.path.isfile(post_filename.replace('.json', '') + + '.mitm'): + mitm = True msg = \ html_individual_post(self.server.css_cache, self.server.recent_posts_cache, @@ -11035,7 +11075,7 @@ class PubServer(BaseHTTPRequestHandler): self.server.signing_priv_key_pem, self.server.cw_lists, self.server.lists_enabled, - timezone) + timezone, mitm) msg = msg.encode('utf-8') msglen = len(msg) self._set_headers('text/html', msglen, diff --git a/inbox.py b/inbox.py index 2fcd611a4..7006a156d 100644 --- a/inbox.py +++ b/inbox.py @@ -296,7 +296,8 @@ def _inbox_store_post_to_html_cache(recent_posts_cache: {}, signing_priv_key_pem: str, cw_lists: {}, lists_enabled: str, - timezone: str) -> None: + timezone: str, + mitm: bool) -> None: """Converts the json post into html and stores it in a cache This enables the post to be quickly displayed later """ @@ -321,7 +322,7 @@ def _inbox_store_post_to_html_cache(recent_posts_cache: {}, peertube_instances, allow_local_network_access, theme_name, system_language, max_like_count, not_dm, True, True, False, True, False, - cw_lists, lists_enabled, timezone) + cw_lists, lists_enabled, timezone, mitm) def valid_inbox(base_dir: str, nickname: str, domain: str) -> bool: @@ -1133,6 +1134,9 @@ def _receive_like(recent_posts_cache: {}, follower_approval_active(base_dir, handle_name, domain) not_dm = not is_dm(liked_post_json) timezone = get_account_timezone(base_dir, handle_name, domain) + mitm = False + if os.path.isfile(post_filename.replace('.json', '') + '.mitm'): + mitm = True individual_post_as_html(signing_priv_key_pem, False, recent_posts_cache, max_recent_posts, translate, page_number, base_dir, @@ -1151,7 +1155,7 @@ def _receive_like(recent_posts_cache: {}, show_individual_post_icons, manually_approve_followers, False, True, False, cw_lists, - lists_enabled, timezone) + lists_enabled, timezone, mitm) return True @@ -1247,6 +1251,9 @@ def _receive_undo_like(recent_posts_cache: {}, follower_approval_active(base_dir, handle_name, domain) not_dm = not is_dm(liked_post_json) timezone = get_account_timezone(base_dir, handle_name, domain) + mitm = False + if os.path.isfile(post_filename.replace('.json', '') + '.mitm'): + mitm = True individual_post_as_html(signing_priv_key_pem, False, recent_posts_cache, max_recent_posts, translate, page_number, base_dir, @@ -1265,7 +1272,7 @@ def _receive_undo_like(recent_posts_cache: {}, show_individual_post_icons, manually_approve_followers, False, True, False, cw_lists, - lists_enabled, timezone) + lists_enabled, timezone, mitm) return True @@ -1393,6 +1400,9 @@ def _receive_reaction(recent_posts_cache: {}, follower_approval_active(base_dir, handle_name, domain) not_dm = not is_dm(reaction_post_json) timezone = get_account_timezone(base_dir, handle_name, domain) + mitm = False + if os.path.isfile(post_filename.replace('.json', '') + '.mitm'): + mitm = True individual_post_as_html(signing_priv_key_pem, False, recent_posts_cache, max_recent_posts, translate, page_number, base_dir, @@ -1412,7 +1422,7 @@ def _receive_reaction(recent_posts_cache: {}, show_individual_post_icons, manually_approve_followers, False, True, False, cw_lists, - lists_enabled, timezone) + lists_enabled, timezone, mitm) return True @@ -1527,6 +1537,9 @@ def _receive_undo_reaction(recent_posts_cache: {}, follower_approval_active(base_dir, handle_name, domain) not_dm = not is_dm(reaction_post_json) timezone = get_account_timezone(base_dir, handle_name, domain) + mitm = False + if os.path.isfile(post_filename.replace('.json', '') + '.mitm'): + mitm = True individual_post_as_html(signing_priv_key_pem, False, recent_posts_cache, max_recent_posts, translate, page_number, base_dir, @@ -1546,7 +1559,7 @@ def _receive_undo_reaction(recent_posts_cache: {}, show_individual_post_icons, manually_approve_followers, False, True, False, cw_lists, - lists_enabled, timezone) + lists_enabled, timezone, mitm) return True @@ -1639,6 +1652,9 @@ def _receive_bookmark(recent_posts_cache: {}, follower_approval_active(base_dir, nickname, domain) not_dm = not is_dm(bookmarked_post_json) timezone = get_account_timezone(base_dir, nickname, domain) + mitm = False + if os.path.isfile(post_filename.replace('.json', '') + '.mitm'): + mitm = True individual_post_as_html(signing_priv_key_pem, False, recent_posts_cache, max_recent_posts, translate, page_number, base_dir, @@ -1657,7 +1673,7 @@ def _receive_bookmark(recent_posts_cache: {}, show_individual_post_icons, manually_approve_followers, False, True, False, cw_lists, - lists_enabled, timezone) + lists_enabled, timezone, mitm) return True @@ -1754,6 +1770,9 @@ def _receive_undo_bookmark(recent_posts_cache: {}, follower_approval_active(base_dir, nickname, domain) not_dm = not is_dm(bookmarked_post_json) timezone = get_account_timezone(base_dir, nickname, domain) + mitm = False + if os.path.isfile(post_filename.replace('.json', '') + '.mitm'): + mitm = True individual_post_as_html(signing_priv_key_pem, False, recent_posts_cache, max_recent_posts, translate, page_number, base_dir, @@ -1772,7 +1791,7 @@ def _receive_undo_bookmark(recent_posts_cache: {}, show_individual_post_icons, manually_approve_followers, False, True, False, cw_lists, lists_enabled, - timezone) + timezone, mitm) return True @@ -1963,6 +1982,9 @@ def _receive_announce(recent_posts_cache: {}, if debug: print('Generating html for announce ' + message_json['id']) timezone = get_account_timezone(base_dir, nickname, domain) + mitm = False + if os.path.isfile(post_filename.replace('.json', '') + '.mitm'): + mitm = True announce_html = \ individual_post_as_html(signing_priv_key_pem, True, recent_posts_cache, max_recent_posts, @@ -1982,7 +2004,7 @@ def _receive_announce(recent_posts_cache: {}, show_individual_post_icons, manually_approve_followers, False, True, False, cw_lists, - lists_enabled, timezone) + lists_enabled, timezone, mitm) if not announce_html: print('WARN: Unable to generate html for announce ' + str(message_json)) @@ -3110,6 +3132,9 @@ def _receive_question_vote(server, base_dir: str, nickname: str, domain: str, follower_approval_active(base_dir, nickname, domain) not_dm = not is_dm(question_json) timezone = get_account_timezone(base_dir, nickname, domain) + mitm = False + if os.path.isfile(question_post_filename.replace('.json', '') + '.mitm'): + mitm = True individual_post_as_html(signing_priv_key_pem, False, recent_posts_cache, max_recent_posts, translate, page_number, base_dir, @@ -3128,7 +3153,7 @@ def _receive_question_vote(server, base_dir: str, nickname: str, domain: str, show_individual_post_icons, manually_approve_followers, False, True, False, cw_lists, - lists_enabled, timezone) + lists_enabled, timezone, mitm) # add id to inbox index inbox_update_index('inbox', base_dir, handle, @@ -3638,7 +3663,8 @@ def _inbox_after_initial(server, if mitm: # write a file to indicate that this post was delivered # via a third party - destination_filename_mitm = destination_filename + '.mitm' + destination_filename_mitm = \ + destination_filename.replace('.json', '') + '.mitm' try: with open(destination_filename_mitm, 'w+') as mitm_file: mitm_file.write('\n') @@ -3704,7 +3730,7 @@ def _inbox_after_initial(server, signing_priv_key_pem, cw_lists, lists_enabled, - timezone) + timezone, mitm) if debug: time_diff = \ str(int((time.time() - html_cache_start_time) * diff --git a/outbox.py b/outbox.py index 5e2943b8e..3b8215d52 100644 --- a/outbox.py +++ b/outbox.py @@ -457,6 +457,10 @@ def post_message_to_outbox(session, translate: {}, timezone = \ get_account_timezone(base_dir, post_to_nickname, domain) + mitm = False + if os.path.isfile(saved_filename.replace('.json', '') + + '.mitm'): + mitm = True individual_post_as_html(signing_priv_key_pem, False, recent_posts_cache, max_recent_posts, @@ -481,7 +485,7 @@ def post_message_to_outbox(session, translate: {}, manually_approve_followers, False, True, use_cache_only, cw_lists, lists_enabled, - timezone) + timezone, mitm) if outbox_announce(recent_posts_cache, base_dir, message_json, debug): diff --git a/posts.py b/posts.py index ff569038c..9d43ae88a 100644 --- a/posts.py +++ b/posts.py @@ -3779,6 +3779,11 @@ def _add_post_to_timeline(file_path: str, boxname: str, # append a replies identifier, which will later be removed post_str += '' + mitm_filename = file_path.replace('.json', '.mitm') + if os.path.isfile(mitm_filename): + # append a mitm identifier, which will later be removed + post_str += '' + return _add_post_string_to_timeline(post_str, boxname, posts_in_box, box_actor) return False @@ -4078,6 +4083,13 @@ def _create_box_indexed(recent_posts_cache: {}, # remove the replies identifier post_str = post_str.replace('', '') + # Check if the post was delivered via a third party + mitm = False + if post_str.endswith(''): + mitm = True + # remove the mitm identifier + post_str = post_str.replace('', '') + pst = None try: pst = json.loads(post_str) @@ -4090,6 +4102,9 @@ def _create_box_indexed(recent_posts_cache: {}, # created by individual_post_as_html pst['hasReplies'] = has_replies + # was the post delivered via a third party? + pst['mitm'] = mitm + if not authorized: if not remove_post_interactions(pst, False): continue diff --git a/webapp_confirm.py b/webapp_confirm.py index 7e64348de..12e32c64e 100644 --- a/webapp_confirm.py +++ b/webapp_confirm.py @@ -66,6 +66,9 @@ def html_confirm_delete(css_cache: {}, delete_post_str = \ html_header_with_external_style(css_filename, instance_title, None) timezone = get_account_timezone(base_dir, nickname, domain) + mitm = False + if os.path.isfile(post_filename.replace('.json', '') + '.mitm'): + mitm = True delete_post_str += \ individual_post_as_html(signing_priv_key_pem, True, recent_posts_cache, max_recent_posts, @@ -81,7 +84,7 @@ def html_confirm_delete(css_cache: {}, peertube_instances, allow_local_network_access, theme_name, system_language, max_like_count, False, False, False, False, False, False, - cw_lists, lists_enabled, timezone) + cw_lists, lists_enabled, timezone, mitm) delete_post_str += '
' delete_post_str += \ '

' + \ diff --git a/webapp_create_post.py b/webapp_create_post.py index 4dff64b43..0812ea207 100644 --- a/webapp_create_post.py +++ b/webapp_create_post.py @@ -286,7 +286,7 @@ def html_new_post(css_cache: {}, media_instance: bool, translate: {}, False, False, False, False, False, False, cw_lists, lists_enabled, - timezone) + timezone, False) reply_str = '\n' diff --git a/webapp_frontscreen.py b/webapp_frontscreen.py index 1d135d5eb..68df1b6de 100644 --- a/webapp_frontscreen.py +++ b/webapp_frontscreen.py @@ -87,7 +87,7 @@ def _html_front_screen_posts(recent_posts_cache: {}, max_recent_posts: int, False, False, False, True, False, False, cw_lists, lists_enabled, - timezone) + timezone, False) if post_str: profile_str += post_str + separator_str ctr += 1 diff --git a/webapp_likers.py b/webapp_likers.py index 7cfe6e8b0..0625f151e 100644 --- a/webapp_likers.py +++ b/webapp_likers.py @@ -78,6 +78,9 @@ def html_likers_of_post(base_dir: str, nickname: str, # show the post which was liked timezone = get_account_timezone(base_dir, nickname, domain) + mitm = False + if os.path.isfile(filename.replace('.json', '') + '.mitm'): + mitm = True html_str += \ individual_post_as_html(signing_priv_key_pem, True, recent_posts_cache, @@ -102,7 +105,7 @@ def html_likers_of_post(base_dir: str, nickname: str, False, False, False, False, False, False, cw_lists, lists_enabled, - timezone) + timezone, mitm) # show likers beneath the post obj = post_json_object diff --git a/webapp_post.py b/webapp_post.py index 5100eeb09..3055f1ac7 100644 --- a/webapp_post.py +++ b/webapp_post.py @@ -1416,7 +1416,8 @@ def individual_post_as_html(signing_priv_key_pem: str, use_cache_only: bool, cw_lists: {}, lists_enabled: str, - timezone: str) -> str: + timezone: str, + mitm: bool) -> str: """ Shows a single post as html """ if not post_json_object: @@ -2094,7 +2095,7 @@ def html_individual_post(css_cache: {}, theme_name: str, system_language: str, max_like_count: int, signing_priv_key_pem: str, cw_lists: {}, lists_enabled: str, - timezone: str) -> str: + timezone: str, mitm: bool) -> str: """Show an individual post as html """ original_post_json = post_json_object @@ -2160,7 +2161,7 @@ def html_individual_post(css_cache: {}, allow_local_network_access, theme_name, system_language, max_like_count, False, authorized, False, False, False, False, - cw_lists, lists_enabled, timezone) + cw_lists, lists_enabled, timezone, mitm) message_id = remove_id_ending(post_json_object['id']) # show the previous posts @@ -2173,6 +2174,10 @@ def html_individual_post(css_cache: {}, break post_json_object = load_json(post_filename) if post_json_object: + mitm = False + if os.path.isfile(post_filename.replace('.json', '') + + '.mitm'): + mitm = True post_str = \ individual_post_as_html(signing_priv_key_pem, True, recent_posts_cache, @@ -2196,7 +2201,7 @@ def html_individual_post(css_cache: {}, False, authorized, False, False, False, False, cw_lists, lists_enabled, - timezone) + post_str + timezone, mitm) + post_str # show the following posts post_filename = locate_post(base_dir, nickname, domain, message_id) @@ -2234,7 +2239,7 @@ def html_individual_post(css_cache: {}, False, authorized, False, False, False, False, cw_lists, lists_enabled, - timezone) + timezone, False) css_filename = base_dir + '/epicyon-profile.css' if os.path.isfile(base_dir + '/epicyon.css'): css_filename = base_dir + '/epicyon.css' @@ -2288,7 +2293,7 @@ def html_post_replies(css_cache: {}, False, False, False, False, False, False, cw_lists, lists_enabled, - timezone) + timezone, False) css_filename = base_dir + '/epicyon-profile.css' if os.path.isfile(base_dir + '/epicyon.css'): @@ -2341,7 +2346,7 @@ def html_emoji_reaction_picker(css_cache: {}, theme_name, system_language, max_like_count, False, False, False, False, False, False, - cw_lists, lists_enabled, timezone) + cw_lists, lists_enabled, timezone, False) reactions_filename = base_dir + '/emoji/reactions.json' if not os.path.isfile(reactions_filename): diff --git a/webapp_profile.py b/webapp_profile.py index e4a8d2de6..505c43cd2 100644 --- a/webapp_profile.py +++ b/webapp_profile.py @@ -368,7 +368,7 @@ def html_profile_after_search(css_cache: {}, False, False, False, False, False, False, cw_lists, lists_enabled, - timezone) + timezone, False) i += 1 if i >= 8: break @@ -1125,7 +1125,7 @@ def _html_profile_posts(recent_posts_cache: {}, max_recent_posts: int, False, False, False, True, False, False, cw_lists, lists_enabled, - timezone) + timezone, False) if post_str: profile_str += post_str + separator_str ctr += 1 diff --git a/webapp_search.py b/webapp_search.py index 712c0329c..33b9bca3e 100644 --- a/webapp_search.py +++ b/webapp_search.py @@ -699,7 +699,7 @@ def html_history_search(css_cache: {}, translate: {}, base_dir: str, show_individual_post_icons, False, False, False, False, cw_lists, lists_enabled, - timezone) + timezone, False) if post_str: history_search_form += separator_str + post_str index += 1 @@ -885,7 +885,7 @@ def html_hashtag_search(css_cache: {}, manually_approves_followers, show_public_only, store_to_sache, False, cw_lists, - lists_enabled, timezone) + lists_enabled, timezone, False) if post_str: hashtag_search_form += separator_str + post_str index += 1 diff --git a/webapp_timeline.py b/webapp_timeline.py index 47d18b765..6da01cf05 100644 --- a/webapp_timeline.py +++ b/webapp_timeline.py @@ -906,6 +906,9 @@ def html_timeline(css_cache: {}, default_timeline: str, timeline_start_time, box_name, '11') + mitm = False + if item.get('mitm'): + mitm = True # read the post from disk curr_tl_str = \ individual_post_as_html(signing_priv_key_pem, @@ -932,7 +935,7 @@ def html_timeline(css_cache: {}, default_timeline: str, manually_approve_followers, False, True, use_cache_only, cw_lists, lists_enabled, - timezone) + timezone, mitm) _log_timeline_timing(enable_timing_log, timeline_start_time, box_name, '12') From fd1db142a517dae39b31a683939c18ac1c83263b Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Mon, 14 Mar 2022 20:47:13 +0000 Subject: [PATCH 5/5] Show icon when post is delivered via a cloudflare-like intermediary --- theme/blue/icons/mitm.png | Bin 0 -> 1457 bytes theme/debian/icons/mitm.png | Bin 0 -> 1457 bytes theme/default/icons/mitm.png | Bin 0 -> 1457 bytes theme/hacker/icons/mitm.png | Bin 0 -> 5216 bytes theme/henge/icons/mitm.png | Bin 0 -> 5446 bytes theme/indymediaclassic/icons/mitm.png | Bin 0 -> 5674 bytes theme/indymediamodern/icons/mitm.png | Bin 0 -> 5893 bytes theme/lcd/icons/mitm.png | Bin 0 -> 13679 bytes theme/light/icons/mitm.png | Bin 0 -> 5893 bytes theme/night/icons/mitm.png | Bin 0 -> 1457 bytes theme/pixel/icons/mitm.png | Bin 0 -> 11817 bytes theme/purple/icons/mitm.png | Bin 0 -> 5219 bytes theme/rc3/icons/mitm.png | Bin 0 -> 5448 bytes theme/solidaric/icons/mitm.png | Bin 0 -> 5667 bytes theme/starlight/icons/mitm.png | Bin 0 -> 5895 bytes theme/zen/icons/mitm.png | Bin 0 -> 6124 bytes translations/ar.json | 3 ++- translations/ca.json | 3 ++- translations/cy.json | 3 ++- translations/de.json | 3 ++- translations/en.json | 3 ++- translations/es.json | 3 ++- translations/fr.json | 3 ++- translations/ga.json | 3 ++- translations/hi.json | 3 ++- translations/it.json | 3 ++- translations/ja.json | 3 ++- translations/ko.json | 3 ++- translations/ku.json | 3 ++- translations/oc.json | 3 ++- translations/pl.json | 3 ++- translations/pt.json | 3 ++- translations/ru.json | 3 ++- translations/sw.json | 3 ++- translations/uk.json | 3 ++- translations/zh.json | 3 ++- webapp_post.py | 33 ++++++++++++++++++++------ 37 files changed, 66 insertions(+), 27 deletions(-) create mode 100644 theme/blue/icons/mitm.png create mode 100644 theme/debian/icons/mitm.png create mode 100644 theme/default/icons/mitm.png create mode 100644 theme/hacker/icons/mitm.png create mode 100644 theme/henge/icons/mitm.png create mode 100644 theme/indymediaclassic/icons/mitm.png create mode 100644 theme/indymediamodern/icons/mitm.png create mode 100644 theme/lcd/icons/mitm.png create mode 100644 theme/light/icons/mitm.png create mode 100644 theme/night/icons/mitm.png create mode 100644 theme/pixel/icons/mitm.png create mode 100644 theme/purple/icons/mitm.png create mode 100644 theme/rc3/icons/mitm.png create mode 100644 theme/solidaric/icons/mitm.png create mode 100644 theme/starlight/icons/mitm.png create mode 100644 theme/zen/icons/mitm.png diff --git a/theme/blue/icons/mitm.png b/theme/blue/icons/mitm.png new file mode 100644 index 0000000000000000000000000000000000000000..19bce88c3abc0e9bd477bd43581418fb4ba2276c GIT binary patch literal 1457 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 f3f7xV9Sm6)FqGgCwD2jy9iZ~gJhLs{A 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 Xqgh&OpLyE@{h-*MJ|4fgg{J%ka55@# literal 0 HcmV?d00001 diff --git a/theme/indymediaclassic/icons/mitm.png b/theme/indymediaclassic/icons/mitm.png new file mode 100644 index 0000000000000000000000000000000000000000..ccce2caae6fc42a2ec6869ef9f985fac8dfcc553 GIT binary patch literal 5674 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 AI{*Lx literal 0 HcmV?d00001 diff --git a/theme/lcd/icons/mitm.png b/theme/lcd/icons/mitm.png new file mode 100644 index 0000000000000000000000000000000000000000..acecff810dfaf2b1c4460cc1ddad2e9e87bb936d GIT binary patch literal 13679 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 literal 0 HcmV?d00001 diff --git a/theme/light/icons/mitm.png b/theme/light/icons/mitm.png new file mode 100644 index 0000000000000000000000000000000000000000..8c1a044f8048d70b709bf3439b6b1ee9045e432a GIT binary patch literal 5893 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 AI{*Lx literal 0 HcmV?d00001 diff --git a/theme/night/icons/mitm.png b/theme/night/icons/mitm.png new file mode 100644 index 0000000000000000000000000000000000000000..19bce88c3abc0e9bd477bd43581418fb4ba2276c GIT binary patch literal 1457 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 literal 0 HcmV?d00001 diff --git a/theme/solidaric/icons/mitm.png b/theme/solidaric/icons/mitm.png new file mode 100644 index 0000000000000000000000000000000000000000..176f6b52251a8d40202e2e3c721dc2de4bca2502 GIT binary patch literal 5667 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 D4fCbi literal 0 HcmV?d00001 diff --git a/theme/zen/icons/mitm.png b/theme/zen/icons/mitm.png new file mode 100644 index 0000000000000000000000000000000000000000..c04ad28c7dd0040b30ad64e9cc6e8f481a6ad777 GIT binary patch literal 6124 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 literal 0 HcmV?d00001 diff --git a/translations/ar.json b/translations/ar.json index 25d3a03c4..8a4d3c7ee 100644 --- a/translations/ar.json +++ b/translations/ar.json @@ -517,5 +517,6 @@ "Repeated by": "يتكرر بواسطة", "Register": "يسجل", "Web Bots Allowed": "مسموح روبوتات الويب", - "Known Search Bots": "روبوتات بحث الويب المعروفة" + "Known Search Bots": "روبوتات بحث الويب المعروفة", + "mitm": "يمكن قراءة الرسالة أو تعديلها من قبل طرف ثالث" } diff --git a/translations/ca.json b/translations/ca.json index 839c0035d..10dd483f7 100644 --- a/translations/ca.json +++ b/translations/ca.json @@ -517,5 +517,6 @@ "Repeated by": "Repetit per", "Register": "Registra't", "Web Bots Allowed": "Bots web permesos", - "Known Search Bots": "Bots de cerca web coneguts" + "Known Search Bots": "Bots de cerca web coneguts", + "mitm": "El missatge podria haver estat llegit o modificat per un tercer" } diff --git a/translations/cy.json b/translations/cy.json index 7567962b7..eef7ecbd4 100644 --- a/translations/cy.json +++ b/translations/cy.json @@ -517,5 +517,6 @@ "Repeated by": "Ailadrodd gan", "Register": "Cofrestrwch", "Web Bots Allowed": "Web Bots a Ganiateir", - "Known Search Bots": "Bots Chwilio Gwe Hysbys" + "Known Search Bots": "Bots Chwilio Gwe Hysbys", + "mitm": "Gallai'r neges fod wedi cael ei darllen neu ei haddasu gan drydydd parti" } diff --git a/translations/de.json b/translations/de.json index e8a88b053..a33f20caf 100644 --- a/translations/de.json +++ b/translations/de.json @@ -517,5 +517,6 @@ "Repeated by": "Wiederholt von", "Register": "Registrieren", "Web Bots Allowed": "Webbots erlaubt", - "Known Search Bots": "Bekannte Bots für die Websuche" + "Known Search Bots": "Bekannte Bots für die Websuche", + "mitm": "Die Nachricht könnte von einem Dritten gelesen oder geändert worden sein" } diff --git a/translations/en.json b/translations/en.json index 76758fb36..848aeb093 100644 --- a/translations/en.json +++ b/translations/en.json @@ -517,5 +517,6 @@ "Repeated by": "Repeated by", "Register": "Register", "Web Bots Allowed": "Web Search Bots Allowed", - "Known Search Bots": "Known Web Search Bots" + "Known Search Bots": "Known Web Search Bots", + "mitm": "Message could have been read or modified by a third party" } diff --git a/translations/es.json b/translations/es.json index aa88cfafd..b611d7366 100644 --- a/translations/es.json +++ b/translations/es.json @@ -517,5 +517,6 @@ "Repeated by": "Repetido por", "Register": "Registrarse", "Web Bots Allowed": "Bots web permitidos", - "Known Search Bots": "Bots de búsqueda web conocidos" + "Known Search Bots": "Bots de búsqueda web conocidos", + "mitm": "El mensaje podría haber sido leído o modificado por un tercero" } diff --git a/translations/fr.json b/translations/fr.json index 71ce41fb1..f50d7a4d4 100644 --- a/translations/fr.json +++ b/translations/fr.json @@ -517,5 +517,6 @@ "Repeated by": "Répété par", "Register": "S'inscrire", "Web Bots Allowed": "Robots Web autorisés", - "Known Search Bots": "Robots de recherche Web connus" + "Known Search Bots": "Robots de recherche Web connus", + "mitm": "Le message a pu être lu ou modifié par un tiers" } diff --git a/translations/ga.json b/translations/ga.json index 597385634..7fdcece92 100644 --- a/translations/ga.json +++ b/translations/ga.json @@ -517,5 +517,6 @@ "Repeated by": "Arís agus arís eile ag", "Register": "Clár", "Web Bots Allowed": "Róbónna Gréasáin Ceadaithe", - "Known Search Bots": "Róbónna Cuardach Gréasáin Aitheanta" + "Known Search Bots": "Róbónna Cuardach Gréasáin Aitheanta", + "mitm": "D'fhéadfadh tríú páirtí an teachtaireacht a léamh nó a mhodhnú" } diff --git a/translations/hi.json b/translations/hi.json index 348f31bdb..668b8aab6 100644 --- a/translations/hi.json +++ b/translations/hi.json @@ -517,5 +517,6 @@ "Repeated by": "द्वारा दोहराया गया", "Register": "रजिस्टर करें", "Web Bots Allowed": "वेब बॉट्स की अनुमति है", - "Known Search Bots": "ज्ञात वेब खोज बॉट्स" + "Known Search Bots": "ज्ञात वेब खोज बॉट्स", + "mitm": "संदेश किसी तीसरे पक्ष द्वारा पढ़ा या संशोधित किया जा सकता था" } diff --git a/translations/it.json b/translations/it.json index f66199075..23e96d921 100644 --- a/translations/it.json +++ b/translations/it.json @@ -517,5 +517,6 @@ "Repeated by": "Ripetuto da", "Register": "Registrati", "Web Bots Allowed": "Web bot consentiti", - "Known Search Bots": "Bot di ricerca Web noti" + "Known Search Bots": "Bot di ricerca Web noti", + "mitm": "Il messaggio potrebbe essere stato letto o modificato da terzi" } diff --git a/translations/ja.json b/translations/ja.json index b524984d9..e722405f8 100644 --- a/translations/ja.json +++ b/translations/ja.json @@ -517,5 +517,6 @@ "Repeated by": "によって繰り返される", "Register": "登録", "Web Bots Allowed": "許可されたWebボット", - "Known Search Bots": "既知のWeb検索ボット" + "Known Search Bots": "既知のWeb検索ボット", + "mitm": "メッセージが第三者によって読み取られたり変更されたりした可能性があります" } diff --git a/translations/ko.json b/translations/ko.json index 5df692faa..e9bdb5d38 100644 --- a/translations/ko.json +++ b/translations/ko.json @@ -517,5 +517,6 @@ "Repeated by": "반복한 사람", "Register": "등록", "Web Bots Allowed": "웹 봇 허용", - "Known Search Bots": "알려진 웹 검색 봇" + "Known Search Bots": "알려진 웹 검색 봇", + "mitm": "제3자가 메시지를 읽거나 수정했을 수 있습니다." } diff --git a/translations/ku.json b/translations/ku.json index 2a94f25de..e491e585c 100644 --- a/translations/ku.json +++ b/translations/ku.json @@ -517,5 +517,6 @@ "Repeated by": "Ji hêla dubare kirin", "Register": "Fêhrist", "Web Bots Allowed": "Web Bots Destûrdar in", - "Known Search Bots": "Botên Lêgerîna Webê yên naskirî" + "Known Search Bots": "Botên Lêgerîna Webê yên naskirî", + "mitm": "Peyam dikaribû ji hêla aliyek sêyemîn ve were xwendin an guhertin" } diff --git a/translations/oc.json b/translations/oc.json index fc4a357a6..5c0858299 100644 --- a/translations/oc.json +++ b/translations/oc.json @@ -513,5 +513,6 @@ "Repeated by": "Repeated by", "Register": "Register", "Web Bots Allowed": "Web Search Bots Allowed", - "Known Search Bots": "Known Web Search Bots" + "Known Search Bots": "Known Web Search Bots", + "mitm": "Message could have been read or modified by a third party" } diff --git a/translations/pl.json b/translations/pl.json index 301c70145..3184a3a52 100644 --- a/translations/pl.json +++ b/translations/pl.json @@ -517,5 +517,6 @@ "Repeated by": "Powtórzone przez", "Register": "Zarejestrować", "Web Bots Allowed": "Dozwolone boty internetowe", - "Known Search Bots": "Znane boty wyszukiwania w sieci" + "Known Search Bots": "Znane boty wyszukiwania w sieci", + "mitm": "Wiadomość mogła zostać przeczytana lub zmodyfikowana przez osobę trzecią" } diff --git a/translations/pt.json b/translations/pt.json index 4c8e848cc..5a543440b 100644 --- a/translations/pt.json +++ b/translations/pt.json @@ -517,5 +517,6 @@ "Repeated by": "Repetido por", "Register": "Registro", "Web Bots Allowed": "Webbots permitidos", - "Known Search Bots": "Bots de pesquisa na Web conhecidos" + "Known Search Bots": "Bots de pesquisa na Web conhecidos", + "mitm": "A mensagem pode ter sido lida ou modificada por terceiros" } diff --git a/translations/ru.json b/translations/ru.json index a5f545bcd..b9540fc12 100644 --- a/translations/ru.json +++ b/translations/ru.json @@ -517,5 +517,6 @@ "Repeated by": "Повторено", "Register": "регистр", "Web Bots Allowed": "Веб-боты разрешены", - "Known Search Bots": "Известные боты веб-поиска" + "Known Search Bots": "Известные боты веб-поиска", + "mitm": "Сообщение могло быть прочитано или изменено третьим лицом" } diff --git a/translations/sw.json b/translations/sw.json index bda0f5299..9f047b434 100644 --- a/translations/sw.json +++ b/translations/sw.json @@ -517,5 +517,6 @@ "Repeated by": "Imerudiwa na", "Register": "Sajili", "Web Bots Allowed": "Mtandao wa Boti Unaruhusiwa", - "Known Search Bots": "Vijibu vya Utafutaji wa Wavuti vinavyojulikana" + "Known Search Bots": "Vijibu vya Utafutaji wa Wavuti vinavyojulikana", + "mitm": "Ujumbe ungeweza kusomwa au kurekebishwa na mtu mwingine" } diff --git a/translations/uk.json b/translations/uk.json index 2f1d65fc4..89e9273bd 100644 --- a/translations/uk.json +++ b/translations/uk.json @@ -517,5 +517,6 @@ "Repeated by": "Повторюється за", "Register": "Реєстрація", "Web Bots Allowed": "Веб-боти дозволені", - "Known Search Bots": "Відомі пошукові роботи в Інтернеті" + "Known Search Bots": "Відомі пошукові роботи в Інтернеті", + "mitm": "Повідомлення могло бути прочитане або змінене третьою стороною" } diff --git a/translations/zh.json b/translations/zh.json index 280ce1fcf..b0acdfbde 100644 --- a/translations/zh.json +++ b/translations/zh.json @@ -517,5 +517,6 @@ "Repeated by": "重复", "Register": "登记", "Web Bots Allowed": "允许网络机器人", - "Known Search Bots": "已知的网络搜索机器人" + "Known Search Bots": "已知的网络搜索机器人", + "mitm": "消息可能已被第三方阅读或修改" } diff --git a/webapp_post.py b/webapp_post.py index 3055f1ac7..7c69692a3 100644 --- a/webapp_post.py +++ b/webapp_post.py @@ -1026,8 +1026,8 @@ def _get_post_title_announce_html(base_dir: str, page_number: int, message_id_str: str, container_class_icons: str, - container_class: str) -> (str, str, - str, str): + container_class: str, + mitm: bool) -> (str, str, str, str): """Returns the announce title of a post containing names of participants x announces y """ @@ -1081,6 +1081,10 @@ def _get_post_title_announce_html(base_dir: str, title_str += \ _announce_with_display_name_html(translate, post_json_object, announce_display_name) + + if mitm: + title_str += _mitm_warning_html(translate) + # show avatar of person replied to announce_actor = attributed_to announce_avatar_url = \ @@ -1141,6 +1145,16 @@ def _reply_to_unknown_html(translate: {}, '" class="announceOrReply">@unknown\n' +def _mitm_warning_html(translate: {}) -> str: + """Returns the html title for a reply to an unknown handle + """ + mitm_warning_str = translate['mitm'] + return ' ' + \
+        mitm_warning_str + '\n' + + def _reply_with_unknown_path_html(translate: {}, post_json_object: {}, post_domain: str) -> str: @@ -1196,7 +1210,8 @@ def _get_post_title_reply_html(base_dir: str, page_number: int, message_id_str: str, container_class_icons: str, - container_class: str) -> (str, str, str, str): + container_class: str, + mitm: bool) -> (str, str, str, str): """Returns the reply title of a post containing names of participants x replies to y """ @@ -1264,6 +1279,9 @@ def _get_post_title_reply_html(base_dir: str, title_str += _get_reply_html(translate, in_reply_to, reply_display_name) + if mitm: + title_str += _mitm_warning_html(translate) + _log_post_timing(enable_timing_log, post_start_time, '13.7') # show avatar of person replied to @@ -1309,7 +1327,8 @@ def _get_post_title_html(base_dir: str, page_number: int, message_id_str: str, container_class_icons: str, - container_class: str) -> (str, str, str, str): + container_class: str, + mitm: bool) -> (str, str, str, str): """Returns the title of a post containing names of participants x replies to y, x announces y, etc """ @@ -1337,7 +1356,7 @@ def _get_post_title_html(base_dir: str, page_number, message_id_str, container_class_icons, - container_class) + container_class, mitm) return _get_post_title_reply_html(base_dir, http_prefix, @@ -1356,7 +1375,7 @@ def _get_post_title_html(base_dir: str, page_number, message_id_str, container_class_icons, - container_class) + container_class, mitm) def _get_footer_with_icons(show_icons: bool, @@ -1846,7 +1865,7 @@ def individual_post_as_html(signing_priv_key_pem: str, page_number, message_id_str, container_class_icons, - container_class) + container_class, mitm) title_str += title_str2 _log_post_timing(enable_timing_log, post_start_time, '14')