diff --git a/cache.py b/cache.py index 10deff344..1ba24e7e9 100644 --- a/cache.py +++ b/cache.py @@ -141,6 +141,7 @@ def get_person_pub_key(base_dir: str, session, person_url: str, person_cache: {}, debug: bool, project_version: str, http_prefix: str, domain: str, onion_domain: str, + i2p_domain: str, signing_priv_key_pem: str) -> str: if not person_url: return None @@ -162,6 +163,9 @@ def get_person_pub_key(base_dir: str, session, person_url: str, if onion_domain: if '.onion/' in person_url: person_domain = onion_domain + elif i2p_domain: + if '.i2p/' in person_url: + person_domain = i2p_domain profile_str = 'https://www.w3.org/ns/activitystreams' accept_str = \ 'application/activity+json; profile="' + profile_str + '"' diff --git a/daemon.py b/daemon.py index cd615e3f9..14f70c58a 100644 --- a/daemon.py +++ b/daemon.py @@ -22,6 +22,9 @@ from hashlib import sha256 from hashlib import md5 from shutil import copyfile from session import create_session +from session import get_session_for_domain +from session import get_session_for_domains +from session import set_session_for_sender from webfinger import webfinger_meta from webfinger import webfinger_node_info from webfinger import webfinger_lookup @@ -421,6 +424,31 @@ def save_domain_qrcode(base_dir: str, http_prefix: str, class PubServer(BaseHTTPRequestHandler): protocol_version = 'HTTP/1.1' + def _detect_mitm(self) -> bool: + """Detect if a request contains a MiTM + """ + mitm_domains = ['cloudflare'] + check_headers = ( + 'Server', 'Report-To', 'Report-to', 'report-to', + 'Expect-CT', 'Expect-Ct', 'expect-ct' + ) + for interloper in mitm_domains: + for header_name in check_headers: + if self.headers.get(header_name): + if interloper in self.headers[header_name]: + return True + # The presence if these headers on their own indicates a MiTM + mitm_headers = ( + 'CF-Connecting-IP', 'CF-RAY', 'CF-IPCountry', 'CF-Visitor', + 'CDN-Loop', 'CF-Worker' + ) + for header_name in mitm_headers: + if self.headers.get(header_name): + return True + if self.headers.get(header_name.lower()): + return True + return False + def _get_instance_url(self, calling_domain: str) -> str: """Returns the URL for this instance """ @@ -456,7 +484,8 @@ class PubServer(BaseHTTPRequestHandler): pass def _send_reply_to_question(self, nickname: str, message_id: str, - answer: str) -> None: + answer: str, + curr_session, proxy_type: str) -> None: """Sends a reply to a question """ votes_filename = \ @@ -518,7 +547,8 @@ class PubServer(BaseHTTPRequestHandler): # name field contains the answer message_json['object']['name'] = answer if self._post_to_outbox(message_json, - self.server.project_version, nickname): + self.server.project_version, nickname, + curr_session, proxy_type): post_filename = \ locate_post(self.server.base_dir, nickname, self.server.domain, message_id) @@ -641,20 +671,25 @@ class PubServer(BaseHTTPRequestHandler): return key_id return None - def _establish_session(self, calling_function: str) -> bool: + def _establish_session(self, + calling_function: str, + curr_session, + proxy_type: str): """Recreates session if needed """ - if self.server.session: - return True + if curr_session: + return curr_session print('DEBUG: creating new session during ' + calling_function) - self.server.session = create_session(self.server.proxy_type) - if self.server.session: - return True + curr_session = create_session(proxy_type) + if curr_session: + set_session_for_sender(self.server, proxy_type, curr_session) + return curr_session print('ERROR: GET failed to create session during ' + calling_function) - return False + return None - def _secure_mode(self, force: bool = False) -> bool: + def _secure_mode(self, curr_session, proxy_type: str, + force: bool = False) -> bool: """http authentication of GET requests for json """ if not self.server.secure_mode and not force: @@ -673,17 +708,31 @@ class PubServer(BaseHTTPRequestHandler): print('AUTH: Secure mode GET request not permitted: ' + key_id) return False - if not self._establish_session("secure mode"): + if self.server.onion_domain: + if '.onion/' in key_id: + curr_session = self.server.session_onion + proxy_type = 'tor' + if self.server.i2p_domain: + if '.i2p/' in key_id: + curr_session = self.server.session_i2p + proxy_type = 'i2p' + + curr_session = \ + self._establish_session("secure mode", + curr_session, proxy_type) + if not curr_session: return False - # obtain the public key + # obtain the public key. key_id is the actor pub_key = \ get_person_pub_key(self.server.base_dir, - self.server.session, key_id, + curr_session, key_id, self.server.person_cache, self.server.debug, self.server.project_version, self.server.http_prefix, - self.server.domain, self.server.onion_domain, + self.server.domain, + self.server.onion_domain, + self.server.i2p_domain, self.server.signing_priv_key_pem) if not pub_key: if self.server.debug: @@ -1412,11 +1461,15 @@ class PubServer(BaseHTTPRequestHandler): return True def _post_to_outbox(self, message_json: {}, version: str, - post_to_nickname: str) -> bool: + post_to_nickname: str, + curr_session, proxy_type: str) -> bool: """post is received by the outbox Client to server message post https://www.w3.org/TR/activitypub/#client-to-server-outbox-delivery """ + if not curr_session: + return False + city = self.server.city if post_to_nickname: @@ -1430,7 +1483,7 @@ class PubServer(BaseHTTPRequestHandler): self.server.shared_items_federated_domains shared_item_federation_tokens = \ self.server.shared_item_federation_tokens - return post_message_to_outbox(self.server.session, + return post_message_to_outbox(curr_session, self.server.translate, message_json, self.post_to_nickname, self.server, self.server.base_dir, @@ -1448,7 +1501,7 @@ class PubServer(BaseHTTPRequestHandler): self.server.cached_webfingers, self.server.person_cache, self.server.allow_deletion, - self.server.proxy_type, version, + proxy_type, version, self.server.debug, self.server.yt_replace_domain, self.server.twitter_replacement_domain, @@ -1502,7 +1555,8 @@ class PubServer(BaseHTTPRequestHandler): pass return index - def _post_to_outbox_thread(self, message_json: {}) -> bool: + def _post_to_outbox_thread(self, message_json: {}, + curr_session, proxy_type: str) -> bool: """Creates a thread to send a post """ account_outbox_thread_name = self.post_to_nickname @@ -1517,65 +1571,89 @@ class PubServer(BaseHTTPRequestHandler): self.server.outboxThread[account_outbox_thread_name][index] = \ thread_with_trace(target=self._post_to_outbox, args=(message_json.copy(), - self.server.project_version, None), + self.server.project_version, None, + curr_session, proxy_type), daemon=True) print('Starting outbox thread') self.server.outboxThread[account_outbox_thread_name][index].start() return True def _update_inbox_queue(self, nickname: str, message_json: {}, - message_bytes: str) -> int: + message_bytes: str, debug: bool) -> int: """Update the inbox queue """ + if debug: + print('INBOX: checking inbox queue restart') if self.server.restart_inbox_queue_in_progress: self._503() - print('Message arrived but currently restarting inbox queue') + print('INBOX: ' + + 'message arrived but currently restarting inbox queue') self.server.postreq_busy = False return 2 # check that the incoming message has a fully recognized # linked data context + if debug: + print('INBOX: checking valid context') if not has_valid_context(message_json): - print('Message arriving at inbox queue has no valid context') + print('INBOX: ' + + 'message arriving at inbox queue has no valid context') self._400() self.server.postreq_busy = False return 3 # check for blocked domains so that they can be rejected early + if debug: + print('INBOX: checking for actor') message_domain = None if not has_actor(message_json, self.server.debug): - print('Message arriving at inbox queue has no actor') + print('INBOX: message arriving at inbox queue has no actor') self._400() self.server.postreq_busy = False return 3 # actor should be a string + if debug: + print('INBOX: checking that actor is string') if not isinstance(message_json['actor'], str): + print('INBOX: ' + + 'actor should be a string ' + str(message_json['actor'])) self._400() self.server.postreq_busy = False return 3 # check that some additional fields are strings + if debug: + print('INBOX: checking fields 1') string_fields = ('id', 'type', 'published') for check_field in string_fields: if not message_json.get(check_field): continue if not isinstance(message_json[check_field], str): + print('INBOX: ' + + 'id, type and published fields should be strings ' + + check_field + ' ' + str(message_json[check_field])) self._400() self.server.postreq_busy = False return 3 # check that to/cc fields are lists + if debug: + print('INBOX: checking to and cc fields') list_fields = ('to', 'cc') for check_field in list_fields: if not message_json.get(check_field): continue if not isinstance(message_json[check_field], list): + print('INBOX: To and Cc fields should be strings ' + + check_field + ' ' + str(message_json[check_field])) self._400() self.server.postreq_busy = False return 3 if has_object_dict(message_json): + if debug: + print('INBOX: checking object fields') string_fields = ( 'id', 'actor', 'type', 'content', 'published', 'summary', 'url', 'attributedTo' @@ -1584,34 +1662,46 @@ class PubServer(BaseHTTPRequestHandler): if not message_json['object'].get(check_field): continue if not isinstance(message_json['object'][check_field], str): + print('INBOX: ' + + check_field + ' should be a string ' + + str(message_json[check_field])) self._400() self.server.postreq_busy = False return 3 # check that some fields are lists + if debug: + print('INBOX: checking object to and cc fields') list_fields = ('to', 'cc', 'attachment') for check_field in list_fields: if not message_json['object'].get(check_field): continue if not isinstance(message_json['object'][check_field], list): + print('INBOX: ' + + check_field + ' should be a list ' + + str(message_json[check_field])) self._400() self.server.postreq_busy = False return 3 # actor should look like a url + if debug: + print('INBOX: checking that actor looks like a url') if '://' not in message_json['actor'] or \ '.' not in message_json['actor']: - print('POST actor does not look like a url ' + + print('INBOX: POST actor does not look like a url ' + message_json['actor']) self._400() self.server.postreq_busy = False return 3 # sent by an actor on a local network address? + if debug: + print('INBOX: checking for local network access') if not self.server.allow_local_network_access: local_network_pattern_list = get_local_network_addresses() for local_network_pattern in local_network_pattern_list: if local_network_pattern in message_json['actor']: - print('POST actor contains local network address ' + + print('INBOX: POST actor contains local network address ' + message_json['actor']) self._400() self.server.postreq_busy = False @@ -1626,20 +1716,25 @@ class PubServer(BaseHTTPRequestHandler): self.server.blocked_cache_last_updated, self.server.blocked_cache_update_secs) + if debug: + print('INBOX: checking for blocked domain ' + message_domain) if is_blocked_domain(self.server.base_dir, message_domain, self.server.blocked_cache): - print('POST from blocked domain ' + message_domain) + print('INBOX: POST from blocked domain ' + message_domain) self._400() self.server.postreq_busy = False return 3 # if the inbox queue is full then return a busy code + if debug: + print('INBOX: checking for full queue') if len(self.server.inbox_queue) >= self.server.max_queue_length: if message_domain: - print('Queue: Inbox queue is full. Incoming post from ' + + print('INBOX: Queue: ' + + 'Inbox queue is full. Incoming post from ' + message_json['actor']) else: - print('Queue: Inbox queue is full') + print('INBOX: Queue: Inbox queue is full') self._503() clear_queue_items(self.server.base_dir, self.server.inbox_queue) if not self.server.restart_inbox_queue_in_progress: @@ -1681,8 +1776,10 @@ class PubServer(BaseHTTPRequestHandler): # save the json for later queue processing message_bytes_decoded = message_bytes.decode('utf-8') + if debug: + print('INBOX: checking for invalid links') if contains_invalid_local_links(message_bytes_decoded): - print('WARN: post contains invalid local links ' + + print('INBOX: post contains invalid local links ' + str(original_message_json)) return 5 @@ -1692,6 +1789,10 @@ class PubServer(BaseHTTPRequestHandler): self.server.blocked_cache_last_updated, self.server.blocked_cache_update_secs) + mitm = self._detect_mitm() + + if debug: + print('INBOX: saving post to queue') queue_filename = \ save_post_to_inbox_queue(self.server.base_dir, self.server.http_prefix, @@ -1703,7 +1804,8 @@ class PubServer(BaseHTTPRequestHandler): self.path, self.server.debug, self.server.blocked_cache, - self.server.system_language) + self.server.system_language, + mitm) if queue_filename: # add json to the queue if queue_filename not in self.server.inbox_queue: @@ -2446,7 +2548,8 @@ class PubServer(BaseHTTPRequestHandler): base_dir: str, http_prefix: str, domain: str, domain_full: str, port: int, onion_domain: str, i2p_domain: str, - debug: bool) -> None: + debug: bool, + curr_session, proxy_type: str) -> None: """Receive POST from person options screen """ page_number = 1 @@ -2803,7 +2906,8 @@ class PubServer(BaseHTTPRequestHandler): # send block activity self._send_block(http_prefix, chooser_nickname, domain_full, - options_nickname, options_domain_full) + options_nickname, options_domain_full, + curr_session, proxy_type) # person options screen, unblock button # See html_person_options @@ -2899,7 +3003,7 @@ class PubServer(BaseHTTPRequestHandler): conversation_id, self.server.recent_posts_cache, self.server.max_recent_posts, - self.server.session, + curr_session, self.server.cached_webfingers, self.server.person_cache, self.server.port, @@ -3035,7 +3139,7 @@ class PubServer(BaseHTTPRequestHandler): conversation_id, self.server.recent_posts_cache, self.server.max_recent_posts, - self.server.session, + curr_session, self.server.cached_webfingers, self.server.person_cache, self.server.port, @@ -3074,7 +3178,8 @@ class PubServer(BaseHTTPRequestHandler): base_dir: str, http_prefix: str, domain: str, domain_full: str, port: int, onion_domain: str, i2p_domain: str, - debug: bool) -> None: + debug: bool, + curr_session, proxy_type: str) -> None: """Confirm to unfollow """ users_path = path.split('/unfollowconfirm')[0] @@ -3149,7 +3254,8 @@ class PubServer(BaseHTTPRequestHandler): self.server.domain, following_nickname, following_domain_full, self.server.debug, group_account) - self._post_to_outbox_thread(unfollow_json) + self._post_to_outbox_thread(unfollow_json, + curr_session, proxy_type) if calling_domain.endswith('.onion') and onion_domain: origin_path_str = 'http://' + onion_domain + users_path @@ -3163,7 +3269,8 @@ class PubServer(BaseHTTPRequestHandler): base_dir: str, http_prefix: str, domain: str, domain_full: str, port: int, onion_domain: str, i2p_domain: str, - debug: bool) -> None: + debug: bool, + curr_session, proxy_type: str) -> None: """Confirm to follow """ users_path = path.split('/followconfirm')[0] @@ -3226,14 +3333,31 @@ class PubServer(BaseHTTPRequestHandler): follower_nickname + ' to ' + following_actor) if not self.server.signing_priv_key_pem: print('Sending follow request with no signing key') - send_follow_request(self.server.session, + + curr_domain = domain + curr_port = port + curr_http_prefix = http_prefix + if onion_domain: + if following_domain.endswith('.onion'): + curr_session = self.server.session_onion + curr_domain = onion_domain + curr_port = 80 + curr_http_prefix = 'http' + if i2p_domain: + if following_domain.endswith('.i2p'): + curr_session = self.server.session_i2p + curr_domain = i2p_domain + curr_port = 80 + curr_http_prefix = 'http' + + send_follow_request(curr_session, base_dir, follower_nickname, - domain, port, - http_prefix, + domain, curr_domain, curr_port, + curr_http_prefix, following_nickname, following_domain, following_actor, - following_port, http_prefix, + following_port, curr_http_prefix, False, self.server.federation_list, self.server.send_threads, self.server.postLog, @@ -3253,7 +3377,8 @@ class PubServer(BaseHTTPRequestHandler): base_dir: str, http_prefix: str, domain: str, domain_full: str, port: int, onion_domain: str, i2p_domain: str, - debug: bool) -> None: + debug: bool, + curr_session, proxy_type: str) -> None: """Confirms a block """ users_path = path.split('/blockconfirm')[0] @@ -3328,7 +3453,8 @@ class PubServer(BaseHTTPRequestHandler): # send block activity self._send_block(http_prefix, blocker_nickname, domain_full, - blocking_nickname, blocking_domain_full) + blocking_nickname, blocking_domain_full, + curr_session, proxy_type) if calling_domain.endswith('.onion') and onion_domain: origin_path_str = 'http://' + onion_domain + users_path elif (calling_domain.endswith('.i2p') and i2p_domain): @@ -3428,7 +3554,8 @@ class PubServer(BaseHTTPRequestHandler): port: int, search_for_emoji: bool, onion_domain: str, i2p_domain: str, getreq_start_time, getreq_timings: {}, - debug: bool) -> None: + debug: bool, + curr_session, proxy_type: str) -> None: """Receive a search query """ # get the page number @@ -3494,7 +3621,7 @@ class PubServer(BaseHTTPRequestHandler): base_dir, search_str[1:], 1, MAX_POSTS_IN_HASHTAG_FEED, - self.server.session, + curr_session, self.server.cached_webfingers, self.server.person_cache, http_prefix, @@ -3595,7 +3722,7 @@ class PubServer(BaseHTTPRequestHandler): self.server.project_version, self.server.recent_posts_cache, self.server.max_recent_posts, - self.server.session, + curr_session, self.server.cached_webfingers, self.server.person_cache, port, @@ -3668,7 +3795,7 @@ class PubServer(BaseHTTPRequestHandler): self.server.project_version, self.server.recent_posts_cache, self.server.max_recent_posts, - self.server.session, + curr_session, self.server.cached_webfingers, self.server.person_cache, port, @@ -3706,13 +3833,11 @@ class PubServer(BaseHTTPRequestHandler): return # profile search nickname = get_nickname_from_actor(actor_str) - if not self._establish_session("handle search"): - self.server.postreq_busy = False - return profile_path_str = path.replace('/searchhandle', '') # are we already following the searched for handle? if is_following_actor(base_dir, nickname, domain, search_str): + # get the actor if not has_users_path(search_str): search_nickname = get_nickname_from_actor(search_str) search_domain, search_port = \ @@ -3724,8 +3849,27 @@ class PubServer(BaseHTTPRequestHandler): search_domain_full) else: actor = search_str + + # establish the session + curr_proxy_type = proxy_type + if '.onion/' in actor: + curr_proxy_type = 'tor' + curr_session = self.server.session_onion + elif '.i2p/' in actor: + curr_proxy_type = 'i2p' + curr_session = self.server.session_i2p + + curr_session = \ + self._establish_session("handle search", + curr_session, + curr_proxy_type) + if not curr_session: + self.server.postreq_busy = False + return + + # get the avatar url for the actor avatar_url = \ - get_avatar_image_url(self.server.session, + get_avatar_image_url(curr_session, base_dir, http_prefix, actor, self.server.person_cache, @@ -3739,7 +3883,8 @@ class PubServer(BaseHTTPRequestHandler): domain, domain_full, getreq_start_time, onion_domain, i2p_domain, - cookie, debug, authorized) + cookie, debug, authorized, + curr_session, curr_proxy_type) return else: show_published_date_only = \ @@ -3767,6 +3912,28 @@ class PubServer(BaseHTTPRequestHandler): if self.server.account_timezone.get(nickname): timezone = \ self.server.account_timezone.get(nickname) + + profile_handle = search_str.replace('\n', '').strip() + + # establish the session + curr_proxy_type = proxy_type + if '.onion/' in profile_handle or \ + profile_handle.endswith('.onion'): + curr_proxy_type = 'tor' + curr_session = self.server.session_onion + elif ('.i2p/' in profile_handle or + profile_handle.endswith('.i2p')): + curr_proxy_type = 'i2p' + curr_session = self.server.session_i2p + + curr_session = \ + self._establish_session("handle search", + curr_session, + curr_proxy_type) + if not curr_session: + self.server.postreq_busy = False + return + profile_str = \ html_profile_after_search(self.server.css_cache, recent_posts_cache, @@ -3778,8 +3945,8 @@ class PubServer(BaseHTTPRequestHandler): nickname, domain, port, - search_str, - self.server.session, + profile_handle, + curr_session, cached_webfingers, self.server.person_cache, self.server.debug, @@ -3797,7 +3964,9 @@ class PubServer(BaseHTTPRequestHandler): signing_priv_key_pem, self.server.cw_lists, self.server.lists_enabled, - timezone) + timezone, + self.server.onion_domain, + self.server.i2p_domain) if profile_str: msg = profile_str.encode('utf-8') msglen = len(msg) @@ -3891,7 +4060,8 @@ class PubServer(BaseHTTPRequestHandler): base_dir: str, http_prefix: str, domain: str, domain_full: str, onion_domain: str, i2p_domain: str, - debug: bool) -> None: + debug: bool, + curr_session, proxy_type: str) -> None: """Receive a vote via POST """ page_number = 1 @@ -3959,7 +4129,8 @@ class PubServer(BaseHTTPRequestHandler): if '&' in answer: answer = answer.split('&')[0] - self._send_reply_to_question(nickname, message_id, answer) + self._send_reply_to_question(nickname, message_id, answer, + curr_session, proxy_type) if calling_domain.endswith('.onion') and onion_domain: actor = 'http://' + onion_domain + users_path elif (calling_domain.endswith('.i2p') and i2p_domain): @@ -4176,7 +4347,8 @@ class PubServer(BaseHTTPRequestHandler): base_dir: str, http_prefix: str, domain: str, domain_full: str, onion_domain: str, i2p_domain: str, - debug: bool) -> None: + debug: bool, + curr_session, proxy_type: str) -> None: """Endpoint for removing posts after confirmation """ page_number = 1 @@ -4214,6 +4386,7 @@ class PubServer(BaseHTTPRequestHandler): remove_post_confirm_params.split('messageId=')[1] if '&' in remove_message_id: remove_message_id = remove_message_id.split('&')[0] + print('remove_message_id: ' + remove_message_id) if 'pageNumber=' in remove_post_confirm_params: page_number_str = \ remove_post_confirm_params.split('pageNumber=')[1] @@ -4233,9 +4406,13 @@ class PubServer(BaseHTTPRequestHandler): month_str = month_str.split('&')[0] if '/statuses/' in remove_message_id: remove_post_actor = remove_message_id.split('/statuses/')[0] + print('origin_path_str: ' + origin_path_str) + print('remove_post_actor: ' + remove_post_actor) if origin_path_str in remove_post_actor: - toList = ['https://www.w3.org/ns/activitystreams#Public', - remove_post_actor] + toList = [ + 'https://www.w3.org/ns/activitystreams#Public', + remove_post_actor + ] delete_json = { "@context": "https://www.w3.org/ns/activitystreams", 'actor': remove_post_actor, @@ -4256,7 +4433,8 @@ class PubServer(BaseHTTPRequestHandler): domain, year_int, month_int, remove_message_id) - self._post_to_outbox_thread(delete_json) + self._post_to_outbox_thread(delete_json, + curr_session, proxy_type) if calling_domain.endswith('.onion') and onion_domain: origin_path_str = 'http://' + onion_domain + users_path elif (calling_domain.endswith('.i2p') and i2p_domain): @@ -4907,7 +5085,8 @@ class PubServer(BaseHTTPRequestHandler): onion_domain: str, i2p_domain: str, debug: bool, allow_local_network_access: bool, system_language: str, - content_license_url: str) -> None: + content_license_url: str, + curr_session, proxy_type: str) -> None: """Updates your user profile after editing via the Edit button on the profile screen """ @@ -6809,7 +6988,8 @@ class PubServer(BaseHTTPRequestHandler): str(update_actor_json)) self._post_to_outbox(update_actor_json, self.server.project_version, - nickname) + nickname, + curr_session, proxy_type) # deactivate the account if fields.get('deactivateThisAccount'): @@ -7157,7 +7337,8 @@ class PubServer(BaseHTTPRequestHandler): base_dir: str, http_prefix: str, domain: str, port: int, proxy_type: str, getreq_start_time, - debug: bool) -> None: + debug: bool, + curr_session) -> None: """Returns an RSS2 feed for the blog """ nickname = path.split('/blog/')[1] @@ -7166,12 +7347,16 @@ class PubServer(BaseHTTPRequestHandler): if not nickname.startswith('rss.'): account_dir = acct_dir(self.server.base_dir, nickname, domain) if os.path.isdir(account_dir): - if not self._establish_session("RSS request"): + curr_session = \ + self._establish_session("RSS request", + curr_session, + proxy_type) + if not curr_session: return msg = \ html_blog_page_rss2(authorized, - self.server.session, + curr_session, base_dir, http_prefix, self.server.translate, @@ -7205,10 +7390,15 @@ class PubServer(BaseHTTPRequestHandler): domain_full: str, port: int, proxy_type: str, translate: {}, getreq_start_time, - debug: bool) -> None: + debug: bool, + curr_session) -> None: """Returns an RSS2 feed for all blogs on this instance """ - if not self._establish_session("get_rss2site"): + curr_session = \ + self._establish_session("get_rss2site", + curr_session, + proxy_type) + if not curr_session: self._404() return @@ -7221,7 +7411,7 @@ class PubServer(BaseHTTPRequestHandler): domain = acct.split('@')[1] msg += \ html_blog_page_rss2(authorized, - self.server.session, + curr_session, base_dir, http_prefix, self.server.translate, @@ -7259,10 +7449,15 @@ class PubServer(BaseHTTPRequestHandler): base_dir: str, http_prefix: str, domain: str, port: int, proxy_type: str, getreq_start_time, - debug: bool) -> None: + debug: bool, + curr_session) -> None: """Returns the newswire feed """ - if not self._establish_session("get_newswire_feed"): + curr_session = \ + self._establish_session("get_newswire_feed", + curr_session, + proxy_type) + if not curr_session: self._404() return @@ -7293,10 +7488,14 @@ class PubServer(BaseHTTPRequestHandler): base_dir: str, http_prefix: str, domain: str, port: int, proxy_type: str, getreq_start_time, - debug: bool) -> None: + debug: bool, + curr_session) -> None: """Returns the hashtag categories feed """ - if not self._establish_session("get_hashtag_categories_feed"): + curr_session = \ + self._establish_session("get_hashtag_categories_feed", + curr_session, proxy_type) + if not curr_session: self._404() return @@ -7325,7 +7524,8 @@ class PubServer(BaseHTTPRequestHandler): base_dir: str, http_prefix: str, domain: str, port: int, proxy_type: str, getreq_start_time, - debug: bool, system_language: str) -> None: + debug: bool, system_language: str, + curr_session) -> None: """Returns an RSS3 feed """ nickname = path.split('/blog/')[1] @@ -7334,12 +7534,15 @@ class PubServer(BaseHTTPRequestHandler): if not nickname.startswith('rss.'): account_dir = acct_dir(base_dir, nickname, domain) if os.path.isdir(account_dir): - if not self._establish_session("get_rss3feed"): + curr_session = \ + self._establish_session("get_rss3feed", + curr_session, proxy_type) + if not curr_session: self._404() return msg = \ html_blog_page_rss3(authorized, - self.server.session, + curr_session, base_dir, http_prefix, self.server.translate, nickname, domain, port, @@ -7368,7 +7571,8 @@ class PubServer(BaseHTTPRequestHandler): getreq_start_time, onion_domain: str, i2p_domain: str, cookie: str, debug: bool, - authorized: bool) -> None: + authorized: bool, + curr_session, proxy_type: str) -> None: """Show person options screen """ back_to_path = '' @@ -7446,8 +7650,8 @@ class PubServer(BaseHTTPRequestHandler): if actor_json.get('alsoKnownAs'): also_known_as = actor_json['alsoKnownAs'] - if self.server.session: - check_for_changed_actor(self.server.session, + if curr_session: + check_for_changed_actor(curr_session, self.server.base_dir, self.server.http_prefix, self.server.domain_full, @@ -7820,7 +8024,8 @@ class PubServer(BaseHTTPRequestHandler): base_dir: str, http_prefix: str, domain: str, domain_full: str, port: int, onion_domain: str, i2p_domain: str, - getreq_start_time) -> None: + getreq_start_time, + curr_session, proxy_type: str) -> None: """Return the result of a hashtag search """ page_number = 1 @@ -7860,7 +8065,8 @@ class PubServer(BaseHTTPRequestHandler): self.server.max_recent_posts, self.server.translate, base_dir, hashtag, page_number, - MAX_POSTS_IN_HASHTAG_FEED, self.server.session, + MAX_POSTS_IN_HASHTAG_FEED, + curr_session, self.server.cached_webfingers, self.server.person_cache, http_prefix, @@ -7904,7 +8110,8 @@ class PubServer(BaseHTTPRequestHandler): base_dir: str, http_prefix: str, domain: str, domain_full: str, port: int, onion_domain: str, i2p_domain: str, - getreq_start_time) -> None: + getreq_start_time, + curr_session, proxy_type: str) -> None: """Return an RSS 2 feed for a hashtag """ hashtag = path.split('/tags/rss2/')[1] @@ -7924,7 +8131,7 @@ class PubServer(BaseHTTPRequestHandler): self.server.max_recent_posts, self.server.translate, base_dir, hashtag, - MAX_POSTS_IN_FEED, self.server.session, + MAX_POSTS_IN_FEED, curr_session, self.server.cached_webfingers, self.server.person_cache, http_prefix, @@ -7962,7 +8169,8 @@ class PubServer(BaseHTTPRequestHandler): onion_domain: str, i2p_domain: str, getreq_start_time, repeat_private: bool, - debug: bool) -> None: + debug: bool, + curr_session) -> None: """The announce/repeat button was pressed on a post """ page_number = 1 @@ -7999,7 +8207,20 @@ class PubServer(BaseHTTPRequestHandler): self._redirect_headers(actor_path_str, cookie, calling_domain) return - if not self._establish_session("announceButton"): + + if self.server.onion_domain: + if '.onion/' in actor: + curr_session = self.server.session_onion + proxy_type = 'tor' + if self.server.i2p_domain: + if '.onion/' in actor: + curr_session = self.server.session_i2p + proxy_type = 'i2p' + + curr_session = \ + self._establish_session("announceButton", + curr_session, proxy_type) + if not curr_session: self._404() return self.server.actorRepeat = path.split('?actor=')[1] @@ -8010,7 +8231,7 @@ class PubServer(BaseHTTPRequestHandler): if not repeat_private: announce_to_str = 'https://www.w3.org/ns/activitystreams#Public' announce_json = \ - create_announce(self.server.session, + create_announce(curr_session, base_dir, self.server.federation_list, self.post_to_nickname, @@ -8043,7 +8264,8 @@ class PubServer(BaseHTTPRequestHandler): # send out the announce within a separate thread self._post_to_outbox(announce_json, self.server.project_version, - self.post_to_nickname) + self.post_to_nickname, + curr_session, proxy_type) fitness_performance(getreq_start_time, self.server.fitness, '_GET', '_announce_button postToOutboxThread', @@ -8075,7 +8297,7 @@ class PubServer(BaseHTTPRequestHandler): self.server.max_recent_posts, self.server.translate, page_number, base_dir, - self.server.session, + curr_session, self.server.cached_webfingers, self.server.person_cache, self.post_to_nickname, domain, @@ -8117,7 +8339,8 @@ class PubServer(BaseHTTPRequestHandler): onion_domain: str, i2p_domain: str, getreq_start_time, repeat_private: bool, debug: bool, - recent_posts_cache: {}) -> None: + recent_posts_cache: {}, + curr_session) -> None: """Undo announce/repeat button was pressed """ page_number = 1 @@ -8157,7 +8380,20 @@ class PubServer(BaseHTTPRequestHandler): self._redirect_headers(actor_path_str, cookie, calling_domain) return - if not self._establish_session("undoAnnounceButton"): + + if self.server.onion_domain: + if '.onion/' in actor: + curr_session = self.server.session_onion + proxy_type = 'tor' + if self.server.i2p_domain: + if '.onion/' in actor: + curr_session = self.server.session_i2p + proxy_type = 'i2p' + + curr_session = \ + self._establish_session("undoAnnounceButton", + curr_session, proxy_type) + if not curr_session: self._404() return undo_announce_actor = \ @@ -8200,7 +8436,8 @@ class PubServer(BaseHTTPRequestHandler): self._post_to_outbox(new_undo_announce, self.server.project_version, - self.post_to_nickname) + self.post_to_nickname, + curr_session, proxy_type) actor_absolute = self._get_instance_url(calling_domain) + actor actor_path_str = \ @@ -8217,7 +8454,8 @@ class PubServer(BaseHTTPRequestHandler): domain: str, domain_full: str, port: int, onion_domain: str, i2p_domain: str, getreq_start_time, - proxy_type: str, debug: bool) -> None: + proxy_type: str, debug: bool, + curr_session) -> None: """Follow approve button was pressed """ origin_path_str = path.split('/followapprove=')[0] @@ -8231,12 +8469,29 @@ class PubServer(BaseHTTPRequestHandler): handle_nickname + '@' + \ get_full_domain(handle_domain, handle_port) if '@' in following_handle: - if not self._establish_session("followApproveButton"): + + if self.server.onion_domain: + if following_handle.endswith('.onion'): + curr_session = self.server.session_onion + proxy_type = 'tor' + if self.server.i2p_domain: + if following_handle.endswith('.i2p'): + curr_session = self.server.session_i2p + proxy_type = 'i2p' + + curr_session = \ + self._establish_session("followApproveButton", + curr_session, proxy_type) + if not curr_session: self._404() return signing_priv_key_pem = \ self.server.signing_priv_key_pem - manual_approve_follow_request_thread(self.server.session, + manual_approve_follow_request_thread(curr_session, + self.server.session_onion, + self.server.session_i2p, + self.server.onion_domain, + self.server.i2p_domain, base_dir, http_prefix, follower_nickname, domain, port, @@ -8381,7 +8636,8 @@ class PubServer(BaseHTTPRequestHandler): domain: str, domain_full: str, port: int, onion_domain: str, i2p_domain: str, getreq_start_time, - proxy_type: str, debug: bool) -> None: + proxy_type: str, debug: bool, + curr_session) -> None: """Follow deny button was pressed """ origin_path_str = path.split('/followdeny=')[0] @@ -8395,7 +8651,11 @@ class PubServer(BaseHTTPRequestHandler): handle_nickname + '@' + \ get_full_domain(handle_domain, handle_port) if '@' in following_handle: - manual_deny_follow_request_thread(self.server.session, + manual_deny_follow_request_thread(curr_session, + self.server.session_onion, + self.server.session_i2p, + self.server.onion_domain, + self.server.i2p_domain, base_dir, http_prefix, follower_nickname, domain, port, @@ -8428,7 +8688,8 @@ class PubServer(BaseHTTPRequestHandler): onion_domain: str, i2p_domain: str, getreq_start_time, proxy_type: str, cookie: str, - debug: str) -> None: + debug: str, + curr_session) -> None: """Press the like button """ page_number = 1 @@ -8466,7 +8727,20 @@ class PubServer(BaseHTTPRequestHandler): self._redirect_headers(actor_path_str, cookie, calling_domain) return - if not self._establish_session("likeButton"): + + if self.server.onion_domain: + if '.onion/' in actor: + curr_session = self.server.session_onion + proxy_type = 'tor' + if self.server.i2p_domain: + if '.onion/' in actor: + curr_session = self.server.session_i2p + proxy_type = 'i2p' + + curr_session = \ + self._establish_session("likeButton", + curr_session, proxy_type) + if not curr_session: self._404() return like_actor = \ @@ -8495,7 +8769,8 @@ class PubServer(BaseHTTPRequestHandler): } # send out the like to followers - self._post_to_outbox(like_json, self.server.project_version, None) + self._post_to_outbox(like_json, self.server.project_version, None, + curr_session, proxy_type) fitness_performance(getreq_start_time, self.server.fitness, '_GET', '_like_button postToOutbox', @@ -8550,7 +8825,7 @@ class PubServer(BaseHTTPRequestHandler): self.server.max_recent_posts, self.server.translate, page_number, base_dir, - self.server.session, + curr_session, self.server.cached_webfingers, self.server.person_cache, self.post_to_nickname, domain, @@ -8600,7 +8875,8 @@ class PubServer(BaseHTTPRequestHandler): onion_domain: str, i2p_domain: str, getreq_start_time, proxy_type: str, cookie: str, - debug: str) -> None: + debug: str, + curr_session) -> None: """A button is pressed to undo """ page_number = 1 @@ -8637,7 +8913,20 @@ class PubServer(BaseHTTPRequestHandler): self._redirect_headers(actor_path_str, cookie, calling_domain) return - if not self._establish_session("undoLikeButton"): + + if self.server.onion_domain: + if '.onion/' in actor: + curr_session = self.server.session_onion + proxy_type = 'tor' + if self.server.i2p_domain: + if '.onion/' in actor: + curr_session = self.server.session_i2p + proxy_type = 'i2p' + + curr_session = \ + self._establish_session("undoLikeButton", + curr_session, proxy_type) + if not curr_session: self._404() return undo_actor = \ @@ -8672,7 +8961,8 @@ class PubServer(BaseHTTPRequestHandler): # send out the undo like to followers self._post_to_outbox(undo_like_json, - self.server.project_version, None) + self.server.project_version, None, + curr_session, proxy_type) # directly undo the like within the post file if not liked_post_filename: @@ -8713,7 +9003,7 @@ class PubServer(BaseHTTPRequestHandler): self.server.max_recent_posts, self.server.translate, page_number, base_dir, - self.server.session, + curr_session, self.server.cached_webfingers, self.server.person_cache, self.post_to_nickname, domain, @@ -8759,7 +9049,8 @@ class PubServer(BaseHTTPRequestHandler): onion_domain: str, i2p_domain: str, getreq_start_time, proxy_type: str, cookie: str, - debug: str) -> None: + debug: str, + curr_session) -> None: """Press an emoji reaction button Note that this is not the emoji reaction selection icon at the bottom of the post @@ -8813,7 +9104,20 @@ class PubServer(BaseHTTPRequestHandler): self._redirect_headers(actor_path_str, cookie, calling_domain) return - if not self._establish_session("reactionButton"): + + if self.server.onion_domain: + if '.onion/' in actor: + curr_session = self.server.session_onion + proxy_type = 'tor' + if self.server.i2p_domain: + if '.onion/' in actor: + curr_session = self.server.session_i2p + proxy_type = 'i2p' + + curr_session = \ + self._establish_session("reactionButton", + curr_session, proxy_type) + if not curr_session: self._404() return reaction_actor = \ @@ -8844,7 +9148,8 @@ class PubServer(BaseHTTPRequestHandler): } # send out the emoji reaction to followers - self._post_to_outbox(reaction_json, self.server.project_version, None) + self._post_to_outbox(reaction_json, self.server.project_version, None, + curr_session, proxy_type) fitness_performance(getreq_start_time, self.server.fitness, '_GET', '_reaction_button postToOutbox', @@ -8905,7 +9210,7 @@ class PubServer(BaseHTTPRequestHandler): self.server.max_recent_posts, self.server.translate, page_number, base_dir, - self.server.session, + curr_session, self.server.cached_webfingers, self.server.person_cache, self.post_to_nickname, domain, @@ -8953,7 +9258,8 @@ class PubServer(BaseHTTPRequestHandler): onion_domain: str, i2p_domain: str, getreq_start_time, proxy_type: str, cookie: str, - debug: str) -> None: + debug: str, + curr_session) -> None: """A button is pressed to undo emoji reaction """ page_number = 1 @@ -9005,7 +9311,20 @@ class PubServer(BaseHTTPRequestHandler): calling_domain) return emoji_content = urllib.parse.unquote_plus(emoji_content_encoded) - if not self._establish_session("undoReactionButton"): + + if self.server.onion_domain: + if '.onion/' in actor: + curr_session = self.server.session_onion + proxy_type = 'tor' + if self.server.i2p_domain: + if '.onion/' in actor: + curr_session = self.server.session_i2p + proxy_type = 'i2p' + + curr_session = \ + self._establish_session("undoReactionButton", + curr_session, proxy_type) + if not curr_session: self._404() return undo_actor = \ @@ -9041,7 +9360,8 @@ class PubServer(BaseHTTPRequestHandler): # send out the undo emoji reaction to followers self._post_to_outbox(undo_reaction_json, - self.server.project_version, None) + self.server.project_version, None, + curr_session, proxy_type) # directly undo the emoji reaction within the post file if not reaction_post_filename: @@ -9087,7 +9407,7 @@ class PubServer(BaseHTTPRequestHandler): self.server.max_recent_posts, self.server.translate, page_number, base_dir, - self.server.session, + curr_session, self.server.cached_webfingers, self.server.person_cache, self.post_to_nickname, domain, @@ -9131,7 +9451,8 @@ class PubServer(BaseHTTPRequestHandler): onion_domain: str, i2p_domain: str, getreq_start_time, proxy_type: str, cookie: str, - debug: str) -> None: + debug: str, + curr_session) -> None: """Press the emoji reaction picker icon at the bottom of the post """ page_number = 1 @@ -9193,7 +9514,7 @@ class PubServer(BaseHTTPRequestHandler): self.server.max_recent_posts, self.server.translate, self.server.base_dir, - self.server.session, + curr_session, self.server.cached_webfingers, self.server.person_cache, self.post_to_nickname, @@ -9229,7 +9550,8 @@ class PubServer(BaseHTTPRequestHandler): onion_domain: str, i2p_domain: str, getreq_start_time, proxy_type: str, cookie: str, - debug: str) -> None: + debug: str, + curr_session) -> None: """Bookmark button was pressed """ page_number = 1 @@ -9267,14 +9589,27 @@ class PubServer(BaseHTTPRequestHandler): self._redirect_headers(actor_path_str, cookie, calling_domain) return - if not self._establish_session("bookmarkButton"): + + if self.server.onion_domain: + if '.onion/' in actor: + curr_session = self.server.session_onion + proxy_type = 'tor' + if self.server.i2p_domain: + if '.onion/' in actor: + curr_session = self.server.session_i2p + proxy_type = 'i2p' + + curr_session = \ + self._establish_session("bookmarkButton", + curr_session, proxy_type) + if not curr_session: self._404() return bookmark_actor = \ local_actor_url(http_prefix, self.post_to_nickname, domain_full) cc_list = [] bookmark_post(self.server.recent_posts_cache, - self.server.session, + curr_session, base_dir, self.server.federation_list, self.post_to_nickname, @@ -9319,7 +9654,7 @@ class PubServer(BaseHTTPRequestHandler): self.server.max_recent_posts, self.server.translate, page_number, base_dir, - self.server.session, + curr_session, self.server.cached_webfingers, self.server.person_cache, self.post_to_nickname, domain, @@ -9347,7 +9682,8 @@ class PubServer(BaseHTTPRequestHandler): else: print('WARN: Bookmarked post not found: ' + bookmark_filename) # self._post_to_outbox(bookmark_json, - # self.server.project_version, None) + # self.server.project_version, None, + # curr_session, proxy_type) actor_absolute = self._get_instance_url(calling_domain) + actor actor_path_str = \ actor_absolute + '/' + timeline_str + \ @@ -9364,7 +9700,8 @@ class PubServer(BaseHTTPRequestHandler): onion_domain: str, i2p_domain: str, getreq_start_time, proxy_type: str, cookie: str, - debug: str) -> None: + debug: str, + curr_session) -> None: """Button pressed to undo a bookmark """ page_number = 1 @@ -9401,14 +9738,27 @@ class PubServer(BaseHTTPRequestHandler): self._redirect_headers(actor_path_str, cookie, calling_domain) return - if not self._establish_session("undo_bookmarkButton"): + + if self.server.onion_domain: + if '.onion/' in actor: + curr_session = self.server.session_onion + proxy_type = 'tor' + if self.server.i2p_domain: + if '.onion/' in actor: + curr_session = self.server.session_i2p + proxy_type = 'i2p' + + curr_session = \ + self._establish_session("undo_bookmarkButton", + curr_session, proxy_type) + if not curr_session: self._404() return undo_actor = \ local_actor_url(http_prefix, self.post_to_nickname, domain_full) cc_list = [] undo_bookmark_post(self.server.recent_posts_cache, - self.server.session, + curr_session, base_dir, self.server.federation_list, self.post_to_nickname, @@ -9426,7 +9776,8 @@ class PubServer(BaseHTTPRequestHandler): if self.server.iconsCache.get('bookmark_inactive.png'): del self.server.iconsCache['bookmark_inactive.png'] # self._post_to_outbox(undo_bookmark_json, - # self.server.project_version, None) + # self.server.project_version, None, + # curr_session, proxy_type) bookmark_filename = \ locate_post(base_dir, self.post_to_nickname, domain, bookmark_url) if bookmark_filename: @@ -9455,7 +9806,7 @@ class PubServer(BaseHTTPRequestHandler): self.server.max_recent_posts, self.server.translate, page_number, base_dir, - self.server.session, + curr_session, self.server.cached_webfingers, self.server.person_cache, self.post_to_nickname, domain, @@ -9499,7 +9850,8 @@ class PubServer(BaseHTTPRequestHandler): onion_domain: str, i2p_domain: str, getreq_start_time, proxy_type: str, cookie: str, - debug: str) -> None: + debug: str, + curr_session) -> None: """Delete button is pressed on a post """ if not cookie: @@ -9550,7 +9902,20 @@ class PubServer(BaseHTTPRequestHandler): self._redirect_headers(actor + '/' + timeline_str, cookie, calling_domain) return - if not self._establish_session("deleteButton"): + + if self.server.onion_domain: + if '.onion/' in actor: + curr_session = self.server.session_onion + proxy_type = 'tor' + if self.server.i2p_domain: + if '.onion/' in actor: + curr_session = self.server.session_i2p + proxy_type = 'i2p' + + curr_session = \ + self._establish_session("deleteButton", + curr_session, proxy_type) + if not curr_session: self._404() return @@ -9559,7 +9924,7 @@ class PubServer(BaseHTTPRequestHandler): self.server.recent_posts_cache, self.server.max_recent_posts, self.server.translate, page_number, - self.server.session, base_dir, + curr_session, base_dir, delete_url, http_prefix, self.server.project_version, self.server.cached_webfingers, @@ -9598,7 +9963,8 @@ class PubServer(BaseHTTPRequestHandler): onion_domain: str, i2p_domain: str, getreq_start_time, proxy_type: str, cookie: str, - debug: str): + debug: str, + curr_session): """Mute button is pressed """ mute_url = path.split('?mute=')[1] @@ -9665,7 +10031,7 @@ class PubServer(BaseHTTPRequestHandler): self.server.max_recent_posts, self.server.translate, page_number, base_dir, - self.server.session, + curr_session, self.server.cached_webfingers, self.server.person_cache, nickname, domain, @@ -9714,7 +10080,8 @@ class PubServer(BaseHTTPRequestHandler): onion_domain: str, i2p_domain: str, getreq_start_time, proxy_type: str, cookie: str, - debug: str): + debug: str, + curr_session): """Undo mute button is pressed """ mute_url = path.split('?unmute=')[1] @@ -9781,7 +10148,7 @@ class PubServer(BaseHTTPRequestHandler): self.server.max_recent_posts, self.server.translate, page_number, base_dir, - self.server.session, + curr_session, self.server.cached_webfingers, self.server.person_cache, nickname, domain, @@ -9828,7 +10195,8 @@ class PubServer(BaseHTTPRequestHandler): onion_domain: str, i2p_domain: str, getreq_start_time, proxy_type: str, cookie: str, - debug: str, session) -> bool: + debug: str, + curr_session) -> bool: """Shows the replies to a post """ if not ('/statuses/' in path and '/users/' in path): @@ -9885,7 +10253,10 @@ class PubServer(BaseHTTPRequestHandler): } if self._request_http(): - if not self._establish_session("showRepliesToPost"): + curr_session = \ + self._establish_session("showRepliesToPost", + curr_session, proxy_type) + if not curr_session: self._404() return True recent_posts_cache = self.server.recent_posts_cache @@ -9908,7 +10279,7 @@ class PubServer(BaseHTTPRequestHandler): max_recent_posts, translate, base_dir, - session, + curr_session, cached_webfingers, person_cache, nickname, @@ -9938,7 +10309,7 @@ class PubServer(BaseHTTPRequestHandler): '_GET', '_show_replies_to_post', self.server.debug) else: - if self._secure_mode(): + if self._secure_mode(curr_session, proxy_type): msg = json.dumps(replies_json, ensure_ascii=False) msg = msg.encode('utf-8') protocol_str = 'application/json' @@ -9981,7 +10352,10 @@ class PubServer(BaseHTTPRequestHandler): # send the replies json if self._request_http(): - if not self._establish_session("showRepliesToPost2"): + curr_session = \ + self._establish_session("showRepliesToPost2", + curr_session, proxy_type) + if not curr_session: self._404() return True recent_posts_cache = self.server.recent_posts_cache @@ -10004,7 +10378,7 @@ class PubServer(BaseHTTPRequestHandler): max_recent_posts, translate, base_dir, - session, + curr_session, cached_webfingers, person_cache, nickname, @@ -10034,7 +10408,7 @@ class PubServer(BaseHTTPRequestHandler): '_GET', '_show_replies_to_post', self.server.debug) else: - if self._secure_mode(): + if self._secure_mode(curr_session, proxy_type): msg = json.dumps(replies_json, ensure_ascii=False) msg = msg.encode('utf-8') @@ -10058,7 +10432,8 @@ class PubServer(BaseHTTPRequestHandler): onion_domain: str, i2p_domain: str, getreq_start_time, proxy_type: str, cookie: str, - debug: str) -> bool: + debug: str, + curr_session) -> bool: """Show roles within profile screen """ named_status = path.split('/users/')[1] @@ -10121,7 +10496,7 @@ class PubServer(BaseHTTPRequestHandler): self.server.project_version, base_dir, http_prefix, True, get_person, 'roles', - self.server.session, + curr_session, cached_webfingers, self.server.person_cache, yt_replace_domain, @@ -10152,7 +10527,7 @@ class PubServer(BaseHTTPRequestHandler): '_GET', '_show_roles', self.server.debug) else: - if self._secure_mode(): + if self._secure_mode(curr_session, proxy_type): roles_list = get_actor_roles_list(actor_json) msg = json.dumps(roles_list, ensure_ascii=False) @@ -10176,7 +10551,8 @@ class PubServer(BaseHTTPRequestHandler): onion_domain: str, i2p_domain: str, getreq_start_time, proxy_type: str, cookie: str, - debug: str) -> bool: + debug: str, + curr_session) -> bool: """Show skills on the profile screen """ named_status = path.split('/users/')[1] @@ -10246,7 +10622,7 @@ class PubServer(BaseHTTPRequestHandler): self.server.project_version, base_dir, http_prefix, True, get_person, 'skills', - self.server.session, + curr_session, cached_webfingers, self.server.person_cache, yt_replace_domain, @@ -10280,7 +10656,8 @@ class PubServer(BaseHTTPRequestHandler): '_GET', '_show_skills', self.server.debug) else: - if self._secure_mode(): + if self._secure_mode(curr_session, + proxy_type): actor_skills_list = \ get_occupation_skills(actor_json) skills = \ @@ -10313,7 +10690,8 @@ class PubServer(BaseHTTPRequestHandler): onion_domain: str, i2p_domain: str, getreq_start_time, proxy_type: str, cookie: str, - debug: str) -> bool: + debug: str, + curr_session) -> bool: """get an individual post from the path /@nickname/statusnumber """ if '/@' not in path: @@ -10369,7 +10747,8 @@ class PubServer(BaseHTTPRequestHandler): onion_domain, i2p_domain, getreq_start_time, proxy_type, cookie, debug, - include_create_wrapper) + include_create_wrapper, + curr_session) fitness_performance(getreq_start_time, self.server.fitness, '_GET', '_show_individual_at_post', self.server.debug) @@ -10382,7 +10761,8 @@ class PubServer(BaseHTTPRequestHandler): onion_domain: str, i2p_domain: str, getreq_start_time, proxy_type: str, cookie: str, - debug: str) -> bool: + debug: str, + curr_session) -> bool: """Show the likers of a post """ if not authorized: @@ -10407,7 +10787,7 @@ class PubServer(BaseHTTPRequestHandler): self.server.access_keys, self.server.recent_posts_cache, self.server.max_recent_posts, - self.server.session, + curr_session, self.server.cached_webfingers, self.server.person_cache, self.server.project_version, @@ -10442,7 +10822,8 @@ class PubServer(BaseHTTPRequestHandler): onion_domain: str, i2p_domain: str, getreq_start_time, proxy_type: str, cookie: str, - debug: str) -> bool: + debug: str, + curr_session) -> bool: """Show the announcers of a post """ if not authorized: @@ -10468,7 +10849,7 @@ class PubServer(BaseHTTPRequestHandler): self.server.access_keys, self.server.recent_posts_cache, self.server.max_recent_posts, - self.server.session, + curr_session, self.server.cached_webfingers, self.server.person_cache, self.server.project_version, @@ -10506,7 +10887,8 @@ class PubServer(BaseHTTPRequestHandler): onion_domain: str, i2p_domain: str, getreq_start_time, proxy_type: str, cookie: str, - debug: str, include_create_wrapper: bool) -> bool: + debug: str, include_create_wrapper: bool, + curr_session) -> bool: """Shows an individual post from its filename """ if not os.path.isfile(post_filename): @@ -10541,7 +10923,7 @@ class PubServer(BaseHTTPRequestHandler): self.server.max_recent_posts, self.server.translate, base_dir, - self.server.session, + curr_session, self.server.cached_webfingers, self.server.person_cache, nickname, domain, port, @@ -10571,7 +10953,7 @@ class PubServer(BaseHTTPRequestHandler): '_GET', '_show_post_from_file', self.server.debug) else: - if self._secure_mode(): + if self._secure_mode(curr_session, proxy_type): if not include_create_wrapper and \ post_json_object['type'] == 'Create' and \ has_object_dict(post_json_object): @@ -10604,7 +10986,8 @@ class PubServer(BaseHTTPRequestHandler): onion_domain: str, i2p_domain: str, getreq_start_time, proxy_type: str, cookie: str, - debug: str) -> bool: + debug: str, + curr_session) -> bool: """Shows an individual post """ liked_by = None @@ -10654,7 +11037,8 @@ class PubServer(BaseHTTPRequestHandler): onion_domain, i2p_domain, getreq_start_time, proxy_type, cookie, debug, - include_create_wrapper) + include_create_wrapper, + curr_session) fitness_performance(getreq_start_time, self.server.fitness, '_GET', '_show_individual_post', self.server.debug) @@ -10667,7 +11051,8 @@ class PubServer(BaseHTTPRequestHandler): onion_domain: str, i2p_domain: str, getreq_start_time, proxy_type: str, cookie: str, - debug: str) -> bool: + debug: str, + curr_session) -> bool: """Shows an individual post from an account which you are following and where you have the notify checkbox set on person options """ @@ -10699,7 +11084,8 @@ class PubServer(BaseHTTPRequestHandler): onion_domain, i2p_domain, getreq_start_time, proxy_type, cookie, debug, - include_create_wrapper) + include_create_wrapper, + curr_session) fitness_performance(getreq_start_time, self.server.fitness, '_GET', '_show_notify_post', self.server.debug) @@ -10713,7 +11099,7 @@ class PubServer(BaseHTTPRequestHandler): getreq_start_time, proxy_type: str, cookie: str, debug: str, - recent_posts_cache: {}, session, + recent_posts_cache: {}, curr_session, default_timeline: str, max_recent_posts: int, translate: {}, @@ -10729,7 +11115,7 @@ class PubServer(BaseHTTPRequestHandler): if authorized: inbox_feed = \ person_box_json(recent_posts_cache, - session, + curr_session, base_dir, domain, port, @@ -10761,7 +11147,7 @@ class PubServer(BaseHTTPRequestHandler): # if no page was specified then show the first inbox_feed = \ person_box_json(recent_posts_cache, - session, + curr_session, base_dir, domain, port, @@ -10799,7 +11185,7 @@ class PubServer(BaseHTTPRequestHandler): max_recent_posts, translate, page_number, MAX_POSTS_IN_FEED, - session, + curr_session, base_dir, cached_webfingers, person_cache, @@ -10880,21 +11266,22 @@ class PubServer(BaseHTTPRequestHandler): return True return False - def _show_d_ms(self, authorized: bool, - calling_domain: str, path: str, - base_dir: str, http_prefix: str, - domain: str, domain_full: str, port: int, - onion_domain: str, i2p_domain: str, - getreq_start_time, - proxy_type: str, cookie: str, - debug: str) -> bool: + def _show_dms(self, authorized: bool, + calling_domain: str, path: str, + base_dir: str, http_prefix: str, + domain: str, domain_full: str, port: int, + onion_domain: str, i2p_domain: str, + getreq_start_time, + proxy_type: str, cookie: str, + debug: str, + curr_session) -> bool: """Shows the DMs timeline """ if '/users/' in path: if authorized: inbox_dm_feed = \ person_box_json(self.server.recent_posts_cache, - self.server.session, + curr_session, base_dir, domain, port, @@ -10920,7 +11307,7 @@ class PubServer(BaseHTTPRequestHandler): # if no page was specified then show the first inbox_dm_feed = \ person_box_json(self.server.recent_posts_cache, - self.server.session, + curr_session, base_dir, domain, port, @@ -10959,7 +11346,7 @@ class PubServer(BaseHTTPRequestHandler): self.server.max_recent_posts, self.server.translate, page_number, MAX_POSTS_IN_FEED, - self.server.session, + curr_session, base_dir, self.server.cached_webfingers, self.server.person_cache, @@ -11000,7 +11387,7 @@ class PubServer(BaseHTTPRequestHandler): self._write(msg) fitness_performance(getreq_start_time, self.server.fitness, - '_GET', '_show_d_ms', + '_GET', '_show_dms', self.server.debug) else: # don't need authorized fetch here because @@ -11014,7 +11401,7 @@ class PubServer(BaseHTTPRequestHandler): self._write(msg) fitness_performance(getreq_start_time, self.server.fitness, - '_GET', '_show_d_ms json', + '_GET', '_show_dms json', self.server.debug) return True else: @@ -11038,15 +11425,15 @@ class PubServer(BaseHTTPRequestHandler): domain: str, domain_full: str, port: int, onion_domain: str, i2p_domain: str, getreq_start_time, - proxy_type: str, cookie: str, - debug: str) -> bool: + proxy_type: str, cookie: str, debug: str, + curr_session) -> bool: """Shows the replies timeline """ if '/users/' in path: if authorized: inbox_replies_feed = \ person_box_json(self.server.recent_posts_cache, - self.server.session, + curr_session, base_dir, domain, port, @@ -11073,7 +11460,7 @@ class PubServer(BaseHTTPRequestHandler): # if no page was specified then show the first inbox_replies_feed = \ person_box_json(self.server.recent_posts_cache, - self.server.session, + curr_session, base_dir, domain, port, @@ -11111,7 +11498,7 @@ class PubServer(BaseHTTPRequestHandler): self.server.max_recent_posts, self.server.translate, page_number, MAX_POSTS_IN_FEED, - self.server.session, + curr_session, base_dir, self.server.cached_webfingers, self.server.person_cache, @@ -11191,14 +11578,15 @@ class PubServer(BaseHTTPRequestHandler): onion_domain: str, i2p_domain: str, getreq_start_time, proxy_type: str, cookie: str, - debug: str) -> bool: + debug: str, + curr_session) -> bool: """Shows the media timeline """ if '/users/' in path: if authorized: inbox_media_feed = \ person_box_json(self.server.recent_posts_cache, - self.server.session, + curr_session, base_dir, domain, port, @@ -11225,7 +11613,7 @@ class PubServer(BaseHTTPRequestHandler): # if no page was specified then show the first inbox_media_feed = \ person_box_json(self.server.recent_posts_cache, - self.server.session, + curr_session, base_dir, domain, port, @@ -11260,7 +11648,7 @@ class PubServer(BaseHTTPRequestHandler): self.server.max_recent_posts, self.server.translate, page_number, MAX_POSTS_IN_MEDIA_FEED, - self.server.session, + curr_session, base_dir, self.server.cached_webfingers, self.server.person_cache, @@ -11341,14 +11729,15 @@ class PubServer(BaseHTTPRequestHandler): onion_domain: str, i2p_domain: str, getreq_start_time, proxy_type: str, cookie: str, - debug: str) -> bool: + debug: str, + curr_session) -> bool: """Shows the blogs timeline """ if '/users/' in path: if authorized: inbox_blogs_feed = \ person_box_json(self.server.recent_posts_cache, - self.server.session, + curr_session, base_dir, domain, port, @@ -11375,7 +11764,7 @@ class PubServer(BaseHTTPRequestHandler): # if no page was specified then show the first inbox_blogs_feed = \ person_box_json(self.server.recent_posts_cache, - self.server.session, + curr_session, base_dir, domain, port, @@ -11410,7 +11799,7 @@ class PubServer(BaseHTTPRequestHandler): self.server.max_recent_posts, self.server.translate, page_number, MAX_POSTS_IN_BLOGS_FEED, - self.server.session, + curr_session, base_dir, self.server.cached_webfingers, self.server.person_cache, @@ -11492,14 +11881,15 @@ class PubServer(BaseHTTPRequestHandler): onion_domain: str, i2p_domain: str, getreq_start_time, proxy_type: str, cookie: str, - debug: str) -> bool: + debug: str, + curr_session) -> bool: """Shows the news timeline """ if '/users/' in path: if authorized: inbox_news_feed = \ person_box_json(self.server.recent_posts_cache, - self.server.session, + curr_session, base_dir, domain, port, @@ -11529,7 +11919,7 @@ class PubServer(BaseHTTPRequestHandler): # if no page was specified then show the first inbox_news_feed = \ person_box_json(self.server.recent_posts_cache, - self.server.session, + curr_session, base_dir, domain, port, @@ -11568,7 +11958,7 @@ class PubServer(BaseHTTPRequestHandler): self.server.max_recent_posts, self.server.translate, page_number, MAX_POSTS_IN_NEWS_FEED, - self.server.session, + curr_session, base_dir, self.server.cached_webfingers, self.server.person_cache, @@ -11650,14 +12040,15 @@ class PubServer(BaseHTTPRequestHandler): onion_domain: str, i2p_domain: str, getreq_start_time, proxy_type: str, cookie: str, - debug: str) -> bool: + debug: str, + curr_session) -> bool: """Shows the features timeline (all local blogs) """ if '/users/' in path: if authorized: inbox_features_feed = \ person_box_json(self.server.recent_posts_cache, - self.server.session, + curr_session, base_dir, domain, port, @@ -11687,7 +12078,7 @@ class PubServer(BaseHTTPRequestHandler): # if no page was specified then show the first inbox_features_feed = \ person_box_json(self.server.recent_posts_cache, - self.server.session, + curr_session, base_dir, domain, port, @@ -11731,7 +12122,7 @@ class PubServer(BaseHTTPRequestHandler): self.server.translate, page_number, MAX_POSTS_IN_BLOGS_FEED, - self.server.session, + curr_session, base_dir, self.server.cached_webfingers, self.server.person_cache, @@ -11812,7 +12203,8 @@ class PubServer(BaseHTTPRequestHandler): onion_domain: str, i2p_domain: str, getreq_start_time, proxy_type: str, cookie: str, - debug: str) -> bool: + debug: str, + curr_session) -> bool: """Shows the shares timeline """ if '/users/' in path: @@ -11847,7 +12239,7 @@ class PubServer(BaseHTTPRequestHandler): self.server.max_recent_posts, self.server.translate, page_number, MAX_POSTS_IN_FEED, - self.server.session, + curr_session, base_dir, self.server.cached_webfingers, self.server.person_cache, @@ -11902,7 +12294,8 @@ class PubServer(BaseHTTPRequestHandler): onion_domain: str, i2p_domain: str, getreq_start_time, proxy_type: str, cookie: str, - debug: str) -> bool: + debug: str, + curr_session) -> bool: """Shows the wanted timeline """ if '/users/' in path: @@ -11936,7 +12329,7 @@ class PubServer(BaseHTTPRequestHandler): self.server.max_recent_posts, self.server.translate, page_number, MAX_POSTS_IN_FEED, - self.server.session, + curr_session, base_dir, self.server.cached_webfingers, self.server.person_cache, @@ -11992,14 +12385,15 @@ class PubServer(BaseHTTPRequestHandler): onion_domain: str, i2p_domain: str, getreq_start_time, proxy_type: str, cookie: str, - debug: str) -> bool: + debug: str, + curr_session) -> bool: """Shows the bookmarks timeline """ if '/users/' in path: if authorized: bookmarks_feed = \ person_box_json(self.server.recent_posts_cache, - self.server.session, + curr_session, base_dir, domain, port, @@ -12026,7 +12420,7 @@ class PubServer(BaseHTTPRequestHandler): # if no page was specified then show the first bookmarks_feed = \ person_box_json(self.server.recent_posts_cache, - self.server.session, + curr_session, base_dir, domain, port, @@ -12065,7 +12459,7 @@ class PubServer(BaseHTTPRequestHandler): self.server.max_recent_posts, self.server.translate, page_number, MAX_POSTS_IN_FEED, - self.server.session, + curr_session, base_dir, self.server.cached_webfingers, self.server.person_cache, @@ -12145,13 +12539,14 @@ class PubServer(BaseHTTPRequestHandler): onion_domain: str, i2p_domain: str, getreq_start_time, proxy_type: str, cookie: str, - debug: str) -> bool: + debug: str, + curr_session) -> bool: """Shows the outbox timeline """ # get outbox feed for a person outbox_feed = \ person_box_json(self.server.recent_posts_cache, - self.server.session, + curr_session, base_dir, domain, port, path, http_prefix, MAX_POSTS_IN_FEED, 'outbox', authorized, @@ -12177,7 +12572,7 @@ class PubServer(BaseHTTPRequestHandler): page_str = '?page=' + str(page_number) outbox_feed = \ person_box_json(self.server.recent_posts_cache, - self.server.session, + curr_session, base_dir, domain, port, path + page_str, http_prefix, @@ -12210,7 +12605,7 @@ class PubServer(BaseHTTPRequestHandler): self.server.max_recent_posts, self.server.translate, page_number, MAX_POSTS_IN_FEED, - self.server.session, + curr_session, base_dir, self.server.cached_webfingers, self.server.person_cache, @@ -12253,7 +12648,7 @@ class PubServer(BaseHTTPRequestHandler): '_GET', '_show_outbox_timeline', self.server.debug) else: - if self._secure_mode(): + if self._secure_mode(curr_session, proxy_type): msg = json.dumps(outbox_feed, ensure_ascii=False) msg = msg.encode('utf-8') @@ -12277,14 +12672,15 @@ class PubServer(BaseHTTPRequestHandler): onion_domain: str, i2p_domain: str, getreq_start_time, proxy_type: str, cookie: str, - debug: str) -> bool: + debug: str, + curr_session) -> bool: """Shows the moderation timeline """ if '/users/' in path: if authorized: moderation_feed = \ person_box_json(self.server.recent_posts_cache, - self.server.session, + curr_session, base_dir, domain, port, @@ -12310,7 +12706,7 @@ class PubServer(BaseHTTPRequestHandler): # if no page was specified then show the first moderation_feed = \ person_box_json(self.server.recent_posts_cache, - self.server.session, + curr_session, base_dir, domain, port, @@ -12349,7 +12745,7 @@ class PubServer(BaseHTTPRequestHandler): self.server.max_recent_posts, self.server.translate, page_number, MAX_POSTS_IN_FEED, - self.server.session, + curr_session, base_dir, self.server.cached_webfingers, self.server.person_cache, @@ -12426,7 +12822,8 @@ class PubServer(BaseHTTPRequestHandler): onion_domain: str, i2p_domain: str, getreq_start_time, proxy_type: str, cookie: str, - debug: str, shares_file_type: str) -> bool: + debug: str, shares_file_type: str, + curr_session) -> bool: """Shows the shares feed """ shares = \ @@ -12455,7 +12852,10 @@ class PubServer(BaseHTTPRequestHandler): search_path2 = search_path.replace('/' + shares_file_type, '') get_person = person_lookup(domain, search_path2, base_dir) if get_person: - if not self._establish_session("show_shares_feed"): + curr_session = \ + self._establish_session("show_shares_feed", + curr_session, proxy_type) + if not curr_session: self._404() self.server.getreq_busy = False return True @@ -12490,7 +12890,7 @@ class PubServer(BaseHTTPRequestHandler): base_dir, http_prefix, authorized, get_person, shares_file_type, - self.server.session, + curr_session, self.server.cached_webfingers, self.server.person_cache, self.server.yt_replace_domain, @@ -12525,7 +12925,7 @@ class PubServer(BaseHTTPRequestHandler): self.server.getreq_busy = False return True else: - if self._secure_mode(): + if self._secure_mode(curr_session, proxy_type): msg = json.dumps(shares, ensure_ascii=False) msg = msg.encode('utf-8') @@ -12549,7 +12949,8 @@ class PubServer(BaseHTTPRequestHandler): onion_domain: str, i2p_domain: str, getreq_start_time, proxy_type: str, cookie: str, - debug: str) -> bool: + debug: str, + curr_session) -> bool: """Shows the following feed """ following = \ @@ -12581,7 +12982,10 @@ class PubServer(BaseHTTPRequestHandler): search_path.replace('/following', ''), base_dir) if get_person: - if not self._establish_session("show_following_feed"): + curr_session = \ + self._establish_session("show_following_feed", + curr_session, proxy_type) + if not curr_session: self._404() return True @@ -12618,7 +13022,7 @@ class PubServer(BaseHTTPRequestHandler): base_dir, http_prefix, authorized, get_person, 'following', - self.server.session, + curr_session, self.server.cached_webfingers, self.server.person_cache, self.server.yt_replace_domain, @@ -12652,7 +13056,7 @@ class PubServer(BaseHTTPRequestHandler): self.server.debug) return True else: - if self._secure_mode(): + if self._secure_mode(curr_session, proxy_type): msg = json.dumps(following, ensure_ascii=False).encode('utf-8') msglen = len(msg) @@ -12675,7 +13079,8 @@ class PubServer(BaseHTTPRequestHandler): onion_domain: str, i2p_domain: str, getreq_start_time, proxy_type: str, cookie: str, - debug: str) -> bool: + debug: str, + curr_session) -> bool: """Shows the followers feed """ followers = \ @@ -12707,7 +13112,10 @@ class PubServer(BaseHTTPRequestHandler): search_path.replace('/followers', ''), base_dir) if get_person: - if not self._establish_session("show_followers_feed"): + curr_session = \ + self._establish_session("show_followers_feed", + curr_session, proxy_type) + if not curr_session: self._404() return True @@ -12745,7 +13153,7 @@ class PubServer(BaseHTTPRequestHandler): http_prefix, authorized, get_person, 'followers', - self.server.session, + curr_session, self.server.cached_webfingers, self.server.person_cache, self.server.yt_replace_domain, @@ -12779,7 +13187,7 @@ class PubServer(BaseHTTPRequestHandler): self.server.debug) return True else: - if self._secure_mode(): + if self._secure_mode(curr_session, proxy_type): msg = json.dumps(followers, ensure_ascii=False).encode('utf-8') msglen = len(msg) @@ -12844,7 +13252,8 @@ class PubServer(BaseHTTPRequestHandler): onion_domain: str, i2p_domain: str, getreq_start_time, proxy_type: str, cookie: str, - debug: str) -> bool: + debug: str, + curr_session) -> bool: """Shows the profile for a person """ # look up a person @@ -12852,7 +13261,10 @@ class PubServer(BaseHTTPRequestHandler): if not actor_json: return False if self._request_http(): - if not self._establish_session("showPersonProfile"): + curr_session = \ + self._establish_session("showPersonProfile", + curr_session, proxy_type) + if not curr_session: self._404() return True @@ -12886,7 +13298,7 @@ class PubServer(BaseHTTPRequestHandler): http_prefix, authorized, actor_json, 'posts', - self.server.session, + curr_session, self.server.cached_webfingers, self.server.person_cache, self.server.yt_replace_domain, @@ -12919,7 +13331,7 @@ class PubServer(BaseHTTPRequestHandler): if self.server.debug: print('DEBUG: html actor sent') else: - if self._secure_mode(): + if self._secure_mode(curr_session, proxy_type): accept_str = self.headers['Accept'] msg_str = json.dumps(actor_json, ensure_ascii=False) msg = msg_str.encode('utf-8') @@ -13029,7 +13441,8 @@ class PubServer(BaseHTTPRequestHandler): onion_domain: str, i2p_domain: str, getreq_start_time, proxy_type: str, cookie: str, - translate: {}, debug: str) -> bool: + translate: {}, debug: str, + curr_session) -> bool: """Shows a blog page """ page_number = 1 @@ -13050,12 +13463,15 @@ class PubServer(BaseHTTPRequestHandler): page_number = 1 elif page_number > 10: page_number = 10 - if not self._establish_session("showBlogPage"): + curr_session = \ + self._establish_session("showBlogPage", + curr_session, proxy_type) + if not curr_session: self._404() self.server.getreq_busy = False return True msg = html_blog_page(authorized, - self.server.session, + curr_session, base_dir, http_prefix, translate, @@ -13601,7 +14017,8 @@ class PubServer(BaseHTTPRequestHandler): reply_category: str, domain: str, domain_full: str, getreq_start_time, cookie, - no_drop_down: bool, conversation_id: str) -> bool: + no_drop_down: bool, conversation_id: str, + curr_session, proxy_type: str) -> bool: """Shows the new post screen """ is_new_post_endpoint = False @@ -13660,7 +14077,7 @@ class PubServer(BaseHTTPRequestHandler): conversation_id, self.server.recent_posts_cache, self.server.max_recent_posts, - self.server.session, + curr_session, self.server.cached_webfingers, self.server.person_cache, self.server.port, @@ -13901,7 +14318,8 @@ class PubServer(BaseHTTPRequestHandler): def _send_block(self, http_prefix: str, blocker_nickname: str, blocker_domain_full: str, - blocking_nickname: str, blocking_domain_full: str) -> bool: + blocking_nickname: str, blocking_domain_full: str, + curr_session, proxy_type: str) -> bool: if blocker_domain_full == blocking_domain_full: if blocker_nickname == blocking_nickname: # don't block self @@ -13923,7 +14341,8 @@ class PubServer(BaseHTTPRequestHandler): 'cc': [cc_url] } self._post_to_outbox(block_json, self.server.project_version, - blocker_nickname) + blocker_nickname, + curr_session, proxy_type) return True def _get_referer_domain(self, ua_str: str) -> str: @@ -14017,6 +14436,10 @@ class PubServer(BaseHTTPRequestHandler): referer_domain = self._get_referer_domain(ua_str) + curr_session, proxy_type = \ + get_session_for_domains(self.server, + calling_domain, referer_domain) + getreq_start_time = time.time() fitness_performance(getreq_start_time, self.server.fitness, @@ -14109,7 +14532,7 @@ class PubServer(BaseHTTPRequestHandler): self.server.onion_domain, self.server.i2p_domain, getreq_start_time, - self.server.proxy_type, + proxy_type, None, self.server.debug, self.server.enable_shared_inbox): return @@ -14419,7 +14842,10 @@ class PubServer(BaseHTTPRequestHandler): '_GET', '_masto_api[calling_domain]', self.server.debug) - if not self._establish_session("GET"): + curr_session = \ + self._establish_session("GET", curr_session, + proxy_type) + if not curr_session: self._404() fitness_performance(getreq_start_time, self.server.fitness, '_GET', 'session fail', @@ -14520,9 +14946,10 @@ class PubServer(BaseHTTPRequestHandler): self.server.http_prefix, self.server.domain, self.server.port, - self.server.proxy_type, + proxy_type, getreq_start_time, - self.server.debug) + self.server.debug, + curr_session) return if self.path == '/newswire.xml': @@ -14532,9 +14959,10 @@ class PubServer(BaseHTTPRequestHandler): self.server.http_prefix, self.server.domain, self.server.port, - self.server.proxy_type, + proxy_type, getreq_start_time, - self.server.debug) + self.server.debug, + curr_session) return # RSS 2.0 @@ -14547,9 +14975,10 @@ class PubServer(BaseHTTPRequestHandler): self.server.http_prefix, self.server.domain, self.server.port, - self.server.proxy_type, + proxy_type, getreq_start_time, - self.server.debug) + self.server.debug, + curr_session) else: self._get_rss2site(authorized, calling_domain, self.path, @@ -14557,10 +14986,11 @@ class PubServer(BaseHTTPRequestHandler): self.server.http_prefix, self.server.domain_full, self.server.port, - self.server.proxy_type, + proxy_type, self.server.translate, getreq_start_time, - self.server.debug) + self.server.debug, + curr_session) return fitness_performance(getreq_start_time, self.server.fitness, @@ -14576,10 +15006,11 @@ class PubServer(BaseHTTPRequestHandler): self.server.http_prefix, self.server.domain, self.server.port, - self.server.proxy_type, + proxy_type, getreq_start_time, self.server.debug, - self.server.system_language) + self.server.system_language, + curr_session) return users_in_path = False @@ -14795,11 +15226,15 @@ class PubServer(BaseHTTPRequestHandler): self.path == '/blogs' or self.path == '/blogs/'): if '/rss.xml' not in self.path: - if not self._establish_session("show the main blog page"): + curr_session = \ + self._establish_session("show the main blog page", + curr_session, + proxy_type) + if not curr_session: self._404() return msg = html_blog_view(authorized, - self.server.session, + curr_session, self.server.base_dir, self.server.http_prefix, self.server.translate, @@ -14841,9 +15276,10 @@ class PubServer(BaseHTTPRequestHandler): self.server.onion_domain, self.server.i2p_domain, getreq_start_time, - self.server.proxy_type, + proxy_type, cookie, self.server.translate, - self.server.debug): + self.server.debug, + curr_session): return # list of registered devices for e2ee @@ -14886,7 +15322,9 @@ class PubServer(BaseHTTPRequestHandler): self.server.onion_domain, self.server.i2p_domain, cookie, self.server.debug, - authorized) + authorized, + curr_session, + proxy_type) return fitness_performance(getreq_start_time, self.server.fitness, @@ -14902,7 +15340,7 @@ class PubServer(BaseHTTPRequestHandler): if blog_filename and nickname: post_json_object = load_json(blog_filename) if is_blog_post(post_json_object): - msg = html_blog_post(self.server.session, + msg = html_blog_post(curr_session, authorized, self.server.base_dir, self.server.http_prefix, @@ -15812,7 +16250,9 @@ class PubServer(BaseHTTPRequestHandler): self.server.port, self.server.onion_domain, self.server.i2p_domain, - getreq_start_time) + getreq_start_time, + curr_session, + proxy_type) self.server.getreq_busy = False return self._hashtag_search(calling_domain, @@ -15824,7 +16264,9 @@ class PubServer(BaseHTTPRequestHandler): self.server.port, self.server.onion_domain, self.server.i2p_domain, - getreq_start_time) + getreq_start_time, + curr_session, + proxy_type) self.server.getreq_busy = False return @@ -16037,7 +16479,7 @@ class PubServer(BaseHTTPRequestHandler): if authorized and html_getreq and '?repeat=' in self.path: self._announce_button(calling_domain, self.path, self.server.base_dir, - cookie, self.server.proxy_type, + cookie, proxy_type, self.server.http_prefix, self.server.domain, self.server.domain_full, @@ -16046,7 +16488,8 @@ class PubServer(BaseHTTPRequestHandler): self.server.i2p_domain, getreq_start_time, repeat_private, - self.server.debug) + self.server.debug, + curr_session) self.server.getreq_busy = False return @@ -16061,7 +16504,7 @@ class PubServer(BaseHTTPRequestHandler): if authorized and html_getreq and '?unrepeat=' in self.path: self._undo_announce_button(calling_domain, self.path, self.server.base_dir, - cookie, self.server.proxy_type, + cookie, proxy_type, self.server.http_prefix, self.server.domain, self.server.domain_full, @@ -16071,7 +16514,8 @@ class PubServer(BaseHTTPRequestHandler): getreq_start_time, repeat_private, self.server.debug, - self.server.recent_posts_cache) + self.server.recent_posts_cache, + curr_session) self.server.getreq_busy = False return @@ -16092,7 +16536,7 @@ class PubServer(BaseHTTPRequestHandler): self.server.onion_domain, self.server.i2p_domain, getreq_start_time, - self.server.proxy_type, + proxy_type, self.server.debug, self.server.newswire) self.server.getreq_busy = False @@ -16111,7 +16555,7 @@ class PubServer(BaseHTTPRequestHandler): self.server.onion_domain, self.server.i2p_domain, getreq_start_time, - self.server.proxy_type, + proxy_type, self.server.debug, self.server.newswire) self.server.getreq_busy = False @@ -16130,8 +16574,9 @@ class PubServer(BaseHTTPRequestHandler): self.server.onion_domain, self.server.i2p_domain, getreq_start_time, - self.server.proxy_type, - self.server.debug) + proxy_type, + self.server.debug, + curr_session) self.server.getreq_busy = False return @@ -16152,8 +16597,9 @@ class PubServer(BaseHTTPRequestHandler): self.server.onion_domain, self.server.i2p_domain, getreq_start_time, - self.server.proxy_type, - self.server.debug) + proxy_type, + self.server.debug, + curr_session) self.server.getreq_busy = False return @@ -16171,9 +16617,10 @@ class PubServer(BaseHTTPRequestHandler): self.server.onion_domain, self.server.i2p_domain, getreq_start_time, - self.server.proxy_type, + proxy_type, cookie, - self.server.debug) + self.server.debug, + curr_session) self.server.getreq_busy = False return @@ -16191,8 +16638,9 @@ class PubServer(BaseHTTPRequestHandler): self.server.onion_domain, self.server.i2p_domain, getreq_start_time, - self.server.proxy_type, - cookie, self.server.debug) + proxy_type, + cookie, self.server.debug, + curr_session) self.server.getreq_busy = False return @@ -16212,9 +16660,10 @@ class PubServer(BaseHTTPRequestHandler): self.server.onion_domain, self.server.i2p_domain, getreq_start_time, - self.server.proxy_type, + proxy_type, cookie, - self.server.debug) + self.server.debug, + curr_session) self.server.getreq_busy = False return @@ -16234,8 +16683,9 @@ class PubServer(BaseHTTPRequestHandler): self.server.onion_domain, self.server.i2p_domain, getreq_start_time, - self.server.proxy_type, - cookie, self.server.debug) + proxy_type, + cookie, self.server.debug, + curr_session) self.server.getreq_busy = False return @@ -16254,8 +16704,9 @@ class PubServer(BaseHTTPRequestHandler): self.server.onion_domain, self.server.i2p_domain, getreq_start_time, - self.server.proxy_type, - cookie, self.server.debug) + proxy_type, + cookie, self.server.debug, + curr_session) self.server.getreq_busy = False return @@ -16274,8 +16725,9 @@ class PubServer(BaseHTTPRequestHandler): self.server.onion_domain, self.server.i2p_domain, getreq_start_time, - self.server.proxy_type, - cookie, self.server.debug) + proxy_type, + cookie, self.server.debug, + curr_session) self.server.getreq_busy = False return @@ -16294,8 +16746,9 @@ class PubServer(BaseHTTPRequestHandler): self.server.onion_domain, self.server.i2p_domain, getreq_start_time, - self.server.proxy_type, cookie, - self.server.debug) + proxy_type, cookie, + self.server.debug, + curr_session) self.server.getreq_busy = False return @@ -16314,8 +16767,9 @@ class PubServer(BaseHTTPRequestHandler): self.server.onion_domain, self.server.i2p_domain, getreq_start_time, - self.server.proxy_type, cookie, - self.server.debug) + proxy_type, cookie, + self.server.debug, + curr_session) self.server.getreq_busy = False return @@ -16334,8 +16788,9 @@ class PubServer(BaseHTTPRequestHandler): self.server.onion_domain, self.server.i2p_domain, getreq_start_time, - self.server.proxy_type, cookie, - self.server.debug) + proxy_type, cookie, + self.server.debug, + curr_session) self.server.getreq_busy = False return @@ -16354,8 +16809,9 @@ class PubServer(BaseHTTPRequestHandler): self.server.onion_domain, self.server.i2p_domain, getreq_start_time, - self.server.proxy_type, cookie, - self.server.debug) + proxy_type, cookie, + self.server.debug, + curr_session) self.server.getreq_busy = False return @@ -16398,6 +16854,26 @@ class PubServer(BaseHTTPRequestHandler): if self.server.debug: print('DEBUG: replyto path ' + self.path) + # unlisted reply + if '?replyunlisted=' in self.path: + in_reply_to_url = self.path.split('?replyunlisted=')[1] + if '?' in in_reply_to_url: + mentions_list = in_reply_to_url.split('?') + for m in mentions_list: + if m.startswith('mention='): + reply_handle = m.replace('mention=', '') + if reply_handle not in reply_to_list: + reply_to_list.append(reply_handle) + if m.startswith('page='): + reply_page_str = m.replace('page=', '') + if reply_page_str.isdigit(): + reply_page_number = int(reply_page_str) + in_reply_to_url = mentions_list[0] + self.path = \ + self.path.split('?replyunlisted=')[0] + '/newunlisted' + if self.server.debug: + print('DEBUG: replyunlisted path ' + self.path) + # reply to followers if '?replyfollowers=' in self.path: in_reply_to_url = self.path.split('?replyfollowers=')[1] @@ -16570,7 +17046,8 @@ class PubServer(BaseHTTPRequestHandler): self.server.domain, self.server.domain_full, getreq_start_time, - cookie, no_drop_down, conversation_id): + cookie, no_drop_down, conversation_id, + curr_session, proxy_type): self.server.getreq_busy = False return @@ -16589,8 +17066,9 @@ class PubServer(BaseHTTPRequestHandler): self.server.onion_domain, self.server.i2p_domain, getreq_start_time, - self.server.proxy_type, - cookie, self.server.debug): + proxy_type, + cookie, self.server.debug, + curr_session): self.server.getreq_busy = False return @@ -16605,8 +17083,9 @@ class PubServer(BaseHTTPRequestHandler): self.server.onion_domain, self.server.i2p_domain, getreq_start_time, - self.server.proxy_type, - cookie, self.server.debug): + proxy_type, + cookie, self.server.debug, + curr_session): self.server.getreq_busy = False return @@ -16621,8 +17100,9 @@ class PubServer(BaseHTTPRequestHandler): self.server.onion_domain, self.server.i2p_domain, getreq_start_time, - self.server.proxy_type, - cookie, self.server.debug): + proxy_type, + cookie, self.server.debug, + curr_session): self.server.getreq_busy = False return @@ -16642,9 +17122,9 @@ class PubServer(BaseHTTPRequestHandler): self.server.onion_domain, self.server.i2p_domain, getreq_start_time, - self.server.proxy_type, cookie, + proxy_type, cookie, self.server.debug, - self.server.session): + curr_session): self.server.getreq_busy = False return @@ -16664,8 +17144,9 @@ class PubServer(BaseHTTPRequestHandler): self.server.onion_domain, self.server.i2p_domain, getreq_start_time, - self.server.proxy_type, - cookie, self.server.debug): + proxy_type, + cookie, self.server.debug, + curr_session): self.server.getreq_busy = False return @@ -16685,8 +17166,9 @@ class PubServer(BaseHTTPRequestHandler): self.server.onion_domain, self.server.i2p_domain, getreq_start_time, - self.server.proxy_type, - cookie, self.server.debug): + proxy_type, + cookie, self.server.debug, + curr_session): self.server.getreq_busy = False return @@ -16705,8 +17187,9 @@ class PubServer(BaseHTTPRequestHandler): self.server.onion_domain, self.server.i2p_domain, getreq_start_time, - self.server.proxy_type, - cookie, self.server.debug): + proxy_type, + cookie, self.server.debug, + curr_session): self.server.getreq_busy = False return @@ -16723,8 +17206,9 @@ class PubServer(BaseHTTPRequestHandler): self.server.onion_domain, self.server.i2p_domain, getreq_start_time, - self.server.proxy_type, - cookie, self.server.debug): + proxy_type, + cookie, self.server.debug, + curr_session): self.server.getreq_busy = False return @@ -16744,10 +17228,10 @@ class PubServer(BaseHTTPRequestHandler): self.server.onion_domain, self.server.i2p_domain, getreq_start_time, - self.server.proxy_type, + proxy_type, cookie, self.server.debug, self.server.recent_posts_cache, - self.server.session, + curr_session, self.server.default_timeline, self.server.max_recent_posts, self.server.translate, @@ -16766,18 +17250,19 @@ class PubServer(BaseHTTPRequestHandler): # get the direct messages timeline for a given person if self.path.endswith('/dm') or '/dm?page=' in self.path: - if self._show_d_ms(authorized, - calling_domain, self.path, - self.server.base_dir, - self.server.http_prefix, - self.server.domain, - self.server.domain_full, - self.server.port, - self.server.onion_domain, - self.server.i2p_domain, - getreq_start_time, - self.server.proxy_type, - cookie, self.server.debug): + if self._show_dms(authorized, + calling_domain, self.path, + self.server.base_dir, + self.server.http_prefix, + self.server.domain, + self.server.domain_full, + self.server.port, + self.server.onion_domain, + self.server.i2p_domain, + getreq_start_time, + proxy_type, + cookie, self.server.debug, + curr_session): self.server.getreq_busy = False return @@ -16797,8 +17282,9 @@ class PubServer(BaseHTTPRequestHandler): self.server.onion_domain, self.server.i2p_domain, getreq_start_time, - self.server.proxy_type, - cookie, self.server.debug): + proxy_type, + cookie, self.server.debug, + curr_session): self.server.getreq_busy = False return @@ -16818,8 +17304,9 @@ class PubServer(BaseHTTPRequestHandler): self.server.onion_domain, self.server.i2p_domain, getreq_start_time, - self.server.proxy_type, - cookie, self.server.debug): + proxy_type, + cookie, self.server.debug, + curr_session): self.server.getreq_busy = False return @@ -16839,8 +17326,9 @@ class PubServer(BaseHTTPRequestHandler): self.server.onion_domain, self.server.i2p_domain, getreq_start_time, - self.server.proxy_type, - cookie, self.server.debug): + proxy_type, + cookie, self.server.debug, + curr_session): self.server.getreq_busy = False return @@ -16860,8 +17348,9 @@ class PubServer(BaseHTTPRequestHandler): self.server.onion_domain, self.server.i2p_domain, getreq_start_time, - self.server.proxy_type, - cookie, self.server.debug): + proxy_type, + cookie, self.server.debug, + curr_session): self.server.getreq_busy = False return @@ -16878,8 +17367,9 @@ class PubServer(BaseHTTPRequestHandler): self.server.onion_domain, self.server.i2p_domain, getreq_start_time, - self.server.proxy_type, - cookie, self.server.debug): + proxy_type, + cookie, self.server.debug, + curr_session): self.server.getreq_busy = False return @@ -16899,8 +17389,9 @@ class PubServer(BaseHTTPRequestHandler): self.server.onion_domain, self.server.i2p_domain, getreq_start_time, - self.server.proxy_type, - cookie, self.server.debug): + proxy_type, + cookie, self.server.debug, + curr_session): self.server.getreq_busy = False return @@ -16916,8 +17407,9 @@ class PubServer(BaseHTTPRequestHandler): self.server.onion_domain, self.server.i2p_domain, getreq_start_time, - self.server.proxy_type, - cookie, self.server.debug): + proxy_type, + cookie, self.server.debug, + curr_session): self.server.getreq_busy = False return @@ -17016,8 +17508,9 @@ class PubServer(BaseHTTPRequestHandler): self.server.onion_domain, self.server.i2p_domain, getreq_start_time, - self.server.proxy_type, - cookie, self.server.debug): + proxy_type, + cookie, self.server.debug, + curr_session): self.server.getreq_busy = False return @@ -17038,8 +17531,9 @@ class PubServer(BaseHTTPRequestHandler): self.server.onion_domain, self.server.i2p_domain, getreq_start_time, - self.server.proxy_type, - cookie, self.server.debug): + proxy_type, + cookie, self.server.debug, + curr_session): self.server.getreq_busy = False return @@ -17060,8 +17554,9 @@ class PubServer(BaseHTTPRequestHandler): self.server.onion_domain, self.server.i2p_domain, getreq_start_time, - self.server.proxy_type, - cookie, self.server.debug): + proxy_type, + cookie, self.server.debug, + curr_session): self.server.getreq_busy = False return @@ -17079,8 +17574,9 @@ class PubServer(BaseHTTPRequestHandler): self.server.onion_domain, self.server.i2p_domain, getreq_start_time, - self.server.proxy_type, - cookie, self.server.debug, 'shares'): + proxy_type, + cookie, self.server.debug, 'shares', + curr_session): self.server.getreq_busy = False return @@ -17098,8 +17594,9 @@ class PubServer(BaseHTTPRequestHandler): self.server.onion_domain, self.server.i2p_domain, getreq_start_time, - self.server.proxy_type, - cookie, self.server.debug): + proxy_type, + cookie, self.server.debug, + curr_session): self.server.getreq_busy = False return @@ -17117,8 +17614,9 @@ class PubServer(BaseHTTPRequestHandler): self.server.onion_domain, self.server.i2p_domain, getreq_start_time, - self.server.proxy_type, - cookie, self.server.debug): + proxy_type, + cookie, self.server.debug, + curr_session): self.server.getreq_busy = False return @@ -17137,8 +17635,9 @@ class PubServer(BaseHTTPRequestHandler): self.server.onion_domain, self.server.i2p_domain, getreq_start_time, - self.server.proxy_type, - cookie, self.server.debug): + proxy_type, + cookie, self.server.debug, + curr_session): self.server.getreq_busy = False return @@ -17155,7 +17654,8 @@ class PubServer(BaseHTTPRequestHandler): self.server.getreq_busy = False return - if not self._secure_mode(): + if not self._secure_mode(curr_session, + proxy_type): if self.server.debug: print('WARN: Unauthorized GET') self._404() @@ -17400,7 +17900,8 @@ class PubServer(BaseHTTPRequestHandler): length: int, post_bytes, boundary: str, calling_domain: str, cookie: str, authorized: bool, - content_license_url: str) -> int: + content_license_url: str, + curr_session, proxy_type: str) -> int: # Note: this needs to happen synchronously # 0=this is not a new post # 1=new post success @@ -17633,7 +18134,8 @@ class PubServer(BaseHTTPRequestHandler): return 1 if self._post_to_outbox(message_json, self.server.project_version, - nickname): + nickname, + curr_session, proxy_type): populate_replies(self.server.base_dir, self.server.http_prefix, self.server.domain_full, @@ -17716,7 +18218,8 @@ class PubServer(BaseHTTPRequestHandler): return 1 if self._post_to_outbox(message_json, self.server.project_version, - nickname): + nickname, + curr_session, proxy_type): refresh_newswire(self.server.base_dir) populate_replies(self.server.base_dir, self.server.http_prefix, @@ -17771,7 +18274,7 @@ class PubServer(BaseHTTPRequestHandler): tags.append(tag) # get list of tags fields['message'] = \ - replace_emoji_from_tags(self.server.session, + replace_emoji_from_tags(curr_session, self.server.base_dir, fields['message'], tags, 'content', @@ -17877,7 +18380,8 @@ class PubServer(BaseHTTPRequestHandler): return 1 if self._post_to_outbox(message_json, self.server.project_version, - nickname): + nickname, + curr_session, proxy_type): populate_replies(self.server.base_dir, self.server.http_prefix, self.server.domain, @@ -17937,7 +18441,8 @@ class PubServer(BaseHTTPRequestHandler): return 1 if self._post_to_outbox(message_json, self.server.project_version, - nickname): + nickname, + curr_session, proxy_type): populate_replies(self.server.base_dir, self.server.http_prefix, self.server.domain, @@ -18012,7 +18517,8 @@ class PubServer(BaseHTTPRequestHandler): str(message_json['object']['to'])) if self._post_to_outbox(message_json, self.server.project_version, - nickname): + nickname, + curr_session, proxy_type): populate_replies(self.server.base_dir, self.server.http_prefix, self.server.domain, @@ -18076,7 +18582,8 @@ class PubServer(BaseHTTPRequestHandler): str(message_json['object']['to'])) if self._post_to_outbox(message_json, self.server.project_version, - nickname): + nickname, + curr_session, proxy_type): return 1 return -1 elif post_type == 'newreport': @@ -18115,7 +18622,8 @@ class PubServer(BaseHTTPRequestHandler): if message_json: if self._post_to_outbox(message_json, self.server.project_version, - nickname): + nickname, + curr_session, proxy_type): return 1 return -1 elif post_type == 'newquestion': @@ -18165,7 +18673,8 @@ class PubServer(BaseHTTPRequestHandler): print('DEBUG: new Question') if self._post_to_outbox(message_json, self.server.project_version, - nickname): + nickname, + curr_session, proxy_type): return 1 return -1 elif post_type == 'newshare' or post_type == 'newwanted': @@ -18247,7 +18756,8 @@ class PubServer(BaseHTTPRequestHandler): def _receive_new_post(self, post_type: str, path: str, calling_domain: str, cookie: str, authorized: bool, - content_license_url: str) -> int: + content_license_url: str, + curr_session, proxy_type: str) -> int: """A new post has been created This creates a thread to send the new post """ @@ -18351,7 +18861,8 @@ class PubServer(BaseHTTPRequestHandler): post_bytes, boundary, calling_domain, cookie, authorized, - content_license_url) + content_license_url, + curr_session, proxy_type) return page_number def _crypto_ap_iread_handle(self): @@ -18512,15 +19023,9 @@ class PubServer(BaseHTTPRequestHandler): self._400() def do_POST(self): + proxy_type = self.server.proxy_type postreq_start_time = time.time() - if not self._establish_session("POST"): - fitness_performance(postreq_start_time, self.server.fitness, - '_POST', 'create_session', - self.server.debug) - self._404() - return - if self.server.debug: print('DEBUG: POST to ' + self.server.base_dir + ' path: ' + self.path + ' busy: ' + @@ -18583,6 +19088,19 @@ class PubServer(BaseHTTPRequestHandler): self.server.postreq_busy = False return + curr_session, proxy_type = \ + get_session_for_domain(self.server, calling_domain) + + curr_session = \ + self._establish_session("POST", curr_session, + proxy_type) + if not curr_session: + fitness_performance(postreq_start_time, self.server.fitness, + '_POST', 'create_session', + self.server.debug) + self._404() + return + # returns after this point should set postreq_busy to False # remove any trailing slashes from the path @@ -18667,7 +19185,9 @@ class PubServer(BaseHTTPRequestHandler): self.server.i2p_domain, self.server.debug, self.server.allow_local_network_access, self.server.system_language, - self.server.content_license_url) + self.server.content_license_url, + curr_session, + proxy_type) self.server.postreq_busy = False return @@ -18776,7 +19296,9 @@ class PubServer(BaseHTTPRequestHandler): self.server.onion_domain, self.server.i2p_domain, postreq_start_time, {}, - self.server.debug) + self.server.debug, + curr_session, + proxy_type) self.server.postreq_busy = False return @@ -18803,7 +19325,9 @@ class PubServer(BaseHTTPRequestHandler): self.server.domain_full, self.server.onion_domain, self.server.i2p_domain, - self.server.debug) + self.server.debug, + curr_session, + proxy_type) self.server.postreq_busy = False return @@ -18856,7 +19380,8 @@ class PubServer(BaseHTTPRequestHandler): self.server.domain_full, self.server.onion_domain, self.server.i2p_domain, - self.server.debug) + self.server.debug, + curr_session, proxy_type) self.server.postreq_busy = False return @@ -18875,7 +19400,9 @@ class PubServer(BaseHTTPRequestHandler): self.server.port, self.server.onion_domain, self.server.i2p_domain, - self.server.debug) + self.server.debug, + curr_session, + proxy_type) self.server.postreq_busy = False return @@ -18894,7 +19421,8 @@ class PubServer(BaseHTTPRequestHandler): self.server.port, self.server.onion_domain, self.server.i2p_domain, - self.server.debug) + self.server.debug, + curr_session, proxy_type) self.server.postreq_busy = False return @@ -18932,7 +19460,9 @@ class PubServer(BaseHTTPRequestHandler): self.server.port, self.server.onion_domain, self.server.i2p_domain, - self.server.debug) + self.server.debug, + curr_session, + proxy_type) self.server.postreq_busy = False return @@ -18952,7 +19482,9 @@ class PubServer(BaseHTTPRequestHandler): self.server.port, self.server.onion_domain, self.server.i2p_domain, - self.server.debug) + self.server.debug, + curr_session, + proxy_type) self.server.postreq_busy = False return @@ -19085,7 +19617,8 @@ class PubServer(BaseHTTPRequestHandler): self._receive_new_post(curr_post_type, self.path, calling_domain, cookie, authorized, - self.server.content_license_url) + self.server.content_license_url, + curr_session, proxy_type) if page_number: print(curr_post_type + ' post received') nickname = self.path.split('/users/')[1] @@ -19295,7 +19828,8 @@ class PubServer(BaseHTTPRequestHandler): # https://www.w3.org/TR/activitypub/#object-without-create if self.outbox_authenticated: if self._post_to_outbox(message_json, - self.server.project_version, None): + self.server.project_version, None, + curr_session, proxy_type): if message_json.get('id'): locn_str = remove_id_ending(message_json['id']) self.headers['Location'] = locn_str @@ -19373,27 +19907,28 @@ class PubServer(BaseHTTPRequestHandler): self.server.debug) if self.server.debug: - print('DEBUG: POST saving to inbox queue') + print('INBOX: POST saving to inbox queue') if users_in_path: path_users_section = self.path.split('/users/')[1] if '/' not in path_users_section: if self.server.debug: - print('DEBUG: This is not a users endpoint') + print('INBOX: This is not a users endpoint') else: self.post_to_nickname = path_users_section.split('/')[0] if self.post_to_nickname: queue_status = \ self._update_inbox_queue(self.post_to_nickname, - message_json, message_bytes) + message_json, message_bytes, + self.server.debug) if queue_status >= 0 and queue_status <= 3: self.server.postreq_busy = False return if self.server.debug: - print('_update_inbox_queue exited ' + + print('INBOX: _update_inbox_queue exited ' + 'without doing anything') else: if self.server.debug: - print('self.post_to_nickname is None') + print('INBOX: self.post_to_nickname is None') self.send_response(403) self.end_headers() self.server.postreq_busy = False @@ -19401,10 +19936,11 @@ class PubServer(BaseHTTPRequestHandler): else: if self.path == '/sharedInbox' or self.path == '/inbox': if self.server.debug: - print('DEBUG: POST to shared inbox') + print('INBOX: POST to shared inbox') queue_status = \ self._update_inbox_queue('inbox', message_json, - message_bytes) + message_bytes, + self.server.debug) if queue_status >= 0 and queue_status <= 3: self.server.postreq_busy = False return @@ -19844,7 +20380,8 @@ def run_daemon(crawlers_allowed: [], httpd.favicons_cache = {} httpd.proxy_type = proxy_type httpd.session = None - httpd.session_last_update = 0 + httpd.session_onion = None + httpd.session_i2p = None httpd.last_getreq = 0 httpd.last_postreq = 0 httpd.getreq_busy = False diff --git a/epicyon.py b/epicyon.py index 87bcbbaf6..57a62f784 100644 --- a/epicyon.py +++ b/epicyon.py @@ -1262,6 +1262,8 @@ if args.approve: if '@' not in args.approve: print('syntax: --approve nick@domain') sys.exit() + session_onion = None + session_i2p = None session = create_session(proxy_type) send_threads = [] postLog = [] @@ -1272,8 +1274,19 @@ if args.approve: signing_priv_key_pem = None if args.secure_mode: signing_priv_key_pem = get_instance_actor_key(base_dir, domain) - manual_approve_follow_request(session, base_dir, - http_prefix, + onion_domain = get_config_param(base_dir, 'onionDomain') + if args.onion: + onion_domain = args.onion + if onion_domain: + session_onion = create_session('tor') + i2p_domain = get_config_param(base_dir, 'i2pDomain') + if args.i2p_domain: + i2p_domain = args.i2p_domain + if i2p_domain: + session_i2p = create_session('i2p') + manual_approve_follow_request(session, session_onion, session_i2p, + onion_domain, i2p_domain, + base_dir, http_prefix, args.nickname, domain, port, args.approve, federation_list, @@ -1290,6 +1303,8 @@ if args.deny: if '@' not in args.deny: print('syntax: --deny nick@domain') sys.exit() + session_onion = None + session_i2p = None session = create_session(proxy_type) send_threads = [] postLog = [] @@ -1300,8 +1315,19 @@ if args.deny: signing_priv_key_pem = None if args.secure_mode: signing_priv_key_pem = get_instance_actor_key(base_dir, domain) - manual_deny_follow_request(session, base_dir, - http_prefix, + onion_domain = get_config_param(base_dir, 'onionDomain') + if args.onion: + onion_domain = args.onion + if onion_domain: + session_onion = create_session('tor') + i2p_domain = get_config_param(base_dir, 'i2pDomain') + if args.i2p_domain: + i2p_domain = args.i2p_domain + if i2p_domain: + session_i2p = create_session('i2p') + manual_deny_follow_request(session, session_onion, session_i2p, + onion_domain, i2p_domain, + base_dir, http_prefix, args.nickname, domain, port, args.deny, federation_list, @@ -3381,6 +3407,7 @@ if args.defaultCurrency: print('Default currency set to ' + args.defaultCurrency) if __name__ == "__main__": + print('allowdeletion: ' + str(args.allowdeletion)) run_daemon(crawlers_allowed, args.dyslexic_font, content_license_url, diff --git a/follow.py b/follow.py index 0d632184f..3349e3b0b 100644 --- a/follow.py +++ b/follow.py @@ -852,7 +852,8 @@ def followed_account_rejects(session, base_dir: str, http_prefix: str, def send_follow_request(session, base_dir: str, - nickname: str, domain: str, port: int, + nickname: str, domain: str, + sender_domain: str, sender_port: int, http_prefix: str, follow_nickname: str, follow_domain: str, followedActor: str, @@ -870,7 +871,7 @@ def send_follow_request(session, base_dir: str, print('You are not permitted to follow the domain ' + follow_domain) return None - full_domain = get_full_domain(domain, port) + full_domain = get_full_domain(sender_domain, sender_port) follow_actor = local_actor_url(http_prefix, nickname, full_domain) request_domain = get_full_domain(follow_domain, followPort) @@ -934,7 +935,7 @@ def send_follow_request(session, base_dir: str, follow_handle, debug) send_signed_json(new_follow_json, session, base_dir, - nickname, domain, port, + nickname, sender_domain, sender_port, follow_nickname, follow_domain, followPort, 'https://www.w3.org/ns/activitystreams#Public', http_prefix, True, client_to_server, diff --git a/inbox.py b/inbox.py index 9ec1c9d5a..1f83888e7 100644 --- a/inbox.py +++ b/inbox.py @@ -459,7 +459,8 @@ def save_post_to_inbox_queue(base_dir: str, http_prefix: str, message_bytes: str, http_headers: {}, post_path: str, debug: bool, - blocked_cache: [], system_language: str) -> str: + blocked_cache: [], system_language: str, + mitm: bool) -> str: """Saves the given json to the inbox queue for the person key_id specifies the actor sending the post """ @@ -592,7 +593,8 @@ def save_post_to_inbox_queue(base_dir: str, http_prefix: str, 'original': original_post_json_object, 'digest': digest, 'filename': filename, - 'destination': destination + 'destination': destination, + 'mitm': mitm } if debug: @@ -625,8 +627,12 @@ def _inbox_post_recipients_add(base_dir: str, http_prefix: str, toList: [], handle + ' does not exist') else: if debug: - print('DEBUG: ' + recipient + ' is not local to ' + - domain_match) + if recipient.endswith('#Public'): + print('DEBUG: #Public recipient is too non-specific. ' + + recipient + ' ' + domain_match) + else: + print('DEBUG: ' + recipient + ' is not local to ' + + domain_match) print(str(toList)) if recipient.endswith('followers'): if debug: @@ -1824,7 +1830,8 @@ def _receive_delete(session, handle: str, is_group: bool, base_dir: str, def _receive_announce(recent_posts_cache: {}, session, handle: str, is_group: bool, base_dir: str, http_prefix: str, - domain: str, onion_domain: str, port: int, + domain: str, + onion_domain: str, i2p_domain: str, port: int, send_threads: [], post_log: [], cached_webfingers: {}, person_cache: {}, message_json: {}, federation_list: [], debug: bool, translate: {}, @@ -2034,6 +2041,7 @@ def _receive_announce(recent_posts_cache: {}, person_cache, debug, __version__, http_prefix, domain, onion_domain, + i2p_domain, signing_priv_key_pem) if pub_key: if debug: @@ -2322,6 +2330,7 @@ def _valid_post_content(base_dir: str, nickname: str, domain: str, def _obtain_avatar_for_reply_post(session, base_dir: str, http_prefix: str, domain: str, onion_domain: str, + i2p_domain: str, person_cache: {}, post_json_object: {}, debug: bool, signing_priv_key_pem: str) -> None: @@ -2355,7 +2364,8 @@ def _obtain_avatar_for_reply_post(session, base_dir: str, http_prefix: str, get_person_pub_key(base_dir, session, lookup_actor, person_cache, debug, __version__, http_prefix, - domain, onion_domain, signing_priv_key_pem) + domain, onion_domain, i2p_domain, + signing_priv_key_pem) if pub_key: if debug: print('DEBUG: public key obtained for reply: ' + lookup_actor) @@ -2637,7 +2647,8 @@ def _group_handle(base_dir: str, handle: str) -> bool: return actor_json['type'] == 'Group' -def _send_to_group_members(session, base_dir: str, handle: str, port: int, +def _send_to_group_members(session, session_onion, session_i2p, + base_dir: str, handle: str, port: int, post_json_object: {}, http_prefix: str, federation_list: [], send_threads: [], post_log: [], @@ -2698,7 +2709,8 @@ def _send_to_group_members(session, base_dir: str, handle: str, port: int, person_cache, cached_webfingers, debug, __version__, signing_priv_key_pem) - send_to_followers_thread(session, base_dir, nickname, domain, + send_to_followers_thread(session, session_onion, session_i2p, + base_dir, nickname, domain, onion_domain, i2p_domain, port, http_prefix, federation_list, send_threads, post_log, @@ -3023,8 +3035,8 @@ def _is_valid_dm(base_dir: str, nickname: str, domain: str, port: int, def _receive_question_vote(base_dir: str, nickname: str, domain: str, http_prefix: str, handle: str, debug: bool, post_json_object: {}, recent_posts_cache: {}, - session, onion_domain: str, - i2p_domain: str, port: int, + session, session_onion, session_i2p, + onion_domain: str, i2p_domain: str, port: int, federation_list: [], send_threads: [], post_log: [], cached_webfingers: {}, person_cache: {}, signing_priv_key_pem: str, @@ -3100,7 +3112,8 @@ def _receive_question_vote(base_dir: str, nickname: str, domain: str, question_json['type'] = 'Update' shared_items_federated_domains = [] shared_item_federation_tokens = {} - send_to_followers_thread(session, base_dir, nickname, domain, + send_to_followers_thread(session, session_onion, session_i2p, + base_dir, nickname, domain, onion_domain, i2p_domain, port, http_prefix, federation_list, send_threads, post_log, @@ -3228,7 +3241,8 @@ def _check_for_git_patches(base_dir: str, nickname: str, domain: str, def _inbox_after_initial(recent_posts_cache: {}, max_recent_posts: int, - session, key_id: str, handle: str, message_json: {}, + session, session_onion, session_i2p, + key_id: str, handle: str, message_json: {}, base_dir: str, http_prefix: str, send_threads: [], post_log: [], cached_webfingers: {}, person_cache: {}, queue: [], domain: str, @@ -3403,7 +3417,7 @@ def _inbox_after_initial(recent_posts_cache: {}, max_recent_posts: int, if _receive_announce(recent_posts_cache, session, handle, is_group, base_dir, http_prefix, - domain, onion_domain, port, + domain, onion_domain, i2p_domain, port, send_threads, post_log, cached_webfingers, person_cache, @@ -3503,7 +3517,8 @@ def _inbox_after_initial(recent_posts_cache: {}, max_recent_posts: int, _receive_question_vote(base_dir, nickname, domain, http_prefix, handle, debug, post_json_object, recent_posts_cache, - session, onion_domain, i2p_domain, port, + session, session_onion, session_i2p, + onion_domain, i2p_domain, port, federation_list, send_threads, post_log, cached_webfingers, person_cache, signing_priv_key_pem, @@ -3565,7 +3580,8 @@ def _inbox_after_initial(recent_posts_cache: {}, max_recent_posts: int, # get the avatar for a reply/announce _obtain_avatar_for_reply_post(session, base_dir, - http_prefix, domain, onion_domain, + http_prefix, domain, + onion_domain, i2p_domain, person_cache, post_json_object, debug, signing_priv_key_pem) @@ -3668,7 +3684,8 @@ def _inbox_after_initial(recent_posts_cache: {}, max_recent_posts: int, # send the post out to group members if is_group: - _send_to_group_members(session, base_dir, handle, port, + _send_to_group_members(session, session_onion, session_i2p, + base_dir, handle, port, post_json_object, http_prefix, federation_list, send_threads, @@ -3909,13 +3926,14 @@ def _check_json_signature(base_dir: str, queue_json: {}) -> (bool, bool): return has_json_signature, jwebsig_type -def _receive_follow_request(session, base_dir: str, http_prefix: str, +def _receive_follow_request(session, session_onion, session_i2p, + base_dir: str, http_prefix: str, port: int, send_threads: [], post_log: [], cached_webfingers: {}, person_cache: {}, message_json: {}, federation_list: [], debug: bool, project_version: str, max_followers: int, onion_domain: str, - signing_priv_key_pem: str, + i2p_domain: str, signing_priv_key_pem: str, unit_test: bool) -> bool: """Receives a follow request within the POST section of HTTPServer """ @@ -3995,8 +4013,23 @@ def _receive_follow_request(session, base_dir: str, http_prefix: str, approve_handle = nickname + '@' + domain_full + curr_session = session + curr_http_prefix = http_prefix + curr_domain = domain + curr_port = from_port + if onion_domain and domain_to_follow.endswith('.onion'): + curr_session = session_onion + curr_http_prefix = 'http' + curr_domain = onion_domain + curr_port = 80 + elif i2p_domain and domain_to_follow.endswith('.i2p'): + curr_session = session_i2p + curr_http_prefix = 'http' + curr_domain = i2p_domain + curr_port = 80 + # is the actor sending the request valid? - if not valid_sending_actor(session, base_dir, + if not valid_sending_actor(curr_session, base_dir, nickname_to_follow, domain_to_follow, person_cache, message_json, signing_priv_key_pem, debug, unit_test): @@ -4033,10 +4066,12 @@ def _receive_follow_request(session, base_dir: str, http_prefix: str, # Getting their public key has the same result if debug: print('Obtaining the following actor: ' + message_json['actor']) - if not get_person_pub_key(base_dir, session, message_json['actor'], + if not get_person_pub_key(base_dir, curr_session, + message_json['actor'], person_cache, debug, project_version, - http_prefix, domain_to_follow, onion_domain, - signing_priv_key_pem): + curr_http_prefix, + domain_to_follow, onion_domain, + i2p_domain, signing_priv_key_pem): if debug: print('Unable to obtain following actor: ' + message_json['actor']) @@ -4071,10 +4106,12 @@ def _receive_follow_request(session, base_dir: str, http_prefix: str, if debug: print('Obtaining the following actor: ' + message_json['actor']) - if not get_person_pub_key(base_dir, session, message_json['actor'], + if not get_person_pub_key(base_dir, curr_session, + message_json['actor'], person_cache, debug, project_version, - http_prefix, domain_to_follow, - onion_domain, signing_priv_key_pem): + curr_http_prefix, domain_to_follow, + onion_domain, i2p_domain, + signing_priv_key_pem): if debug: print('Unable to obtain following actor: ' + message_json['actor']) @@ -4116,9 +4153,9 @@ def _receive_follow_request(session, base_dir: str, http_prefix: str, print('EX: unable to write ' + followers_filename) print('Beginning follow accept') - return followed_account_accepts(session, base_dir, http_prefix, + return followed_account_accepts(curr_session, base_dir, curr_http_prefix, nickname_to_follow, domain_to_follow, port, - nickname, domain, from_port, + nickname, curr_domain, curr_port, message_json['actor'], federation_list, message_json, send_threads, post_log, cached_webfingers, person_cache, @@ -4153,10 +4190,30 @@ def run_inbox_queue(recent_posts_cache: {}, max_recent_posts: int, """Processes received items and moves them to the appropriate directories """ - curr_session_time = int(time.time()) - session_last_update = curr_session_time print('Starting new session when starting inbox queue') + curr_session_time = int(time.time()) + session_last_update = 0 session = create_session(proxy_type) + if session: + session_last_update = curr_session_time + + # is this is a clearnet instance then optionally start sessions + # for onion and i2p domains + session_onion = None + session_i2p = None + session_last_update_onion = 0 + session_last_update_i2p = 0 + if proxy_type != 'tor' and onion_domain: + print('Starting onion session when starting inbox queue') + session_onion = create_session('tor') + if session_onion: + session_onion = curr_session_time + if proxy_type != 'i2p' and i2p_domain: + print('Starting i2p session when starting inbox queue') + session_i2p = create_session('i2p') + if session_i2p: + session_i2p = curr_session_time + inbox_handle = 'inbox@' + domain if debug: print('DEBUG: Inbox queue running') @@ -4209,16 +4266,6 @@ def run_inbox_queue(recent_posts_cache: {}, max_recent_posts: int, _restore_queue_items(base_dir, queue) continue - curr_time = int(time.time()) - - # recreate the session periodically - if not session or curr_time - session_last_update > 21600: - print('Regenerating inbox queue session at 6hr interval') - session = create_session(proxy_type) - if not session: - continue - session_last_update = curr_time - # oldest item first queue.sort() queue_filename = queue[0] @@ -4249,6 +4296,8 @@ def run_inbox_queue(recent_posts_cache: {}, max_recent_posts: int, str(queue_filename)) continue + curr_time = int(time.time()) + # clear the daily quotas for maximum numbers of received posts if curr_time - quotas_last_update_daily > 60 * 60 * 24: quotas_daily = { @@ -4276,6 +4325,49 @@ def run_inbox_queue(recent_posts_cache: {}, max_recent_posts: int, account_max_posts_per_day, debug): continue + # recreate the session periodically + if not session or curr_time - session_last_update > 21600: + print('Regenerating inbox queue session at 6hr interval') + session = create_session(proxy_type) + if session: + session_last_update = curr_time + else: + print('WARN: inbox session not created') + continue + if onion_domain: + if not session_onion or \ + curr_time - session_last_update_onion > 21600: + print('Regenerating inbox queue onion session at 6hr interval') + session_onion = create_session('tor') + if session_onion: + session_last_update_onion = curr_time + else: + print('WARN: inbox onion session not created') + continue + if i2p_domain: + if not session_i2p or curr_time - session_last_update_i2p > 21600: + print('Regenerating inbox queue i2p session at 6hr interval') + session_i2p = create_session('i2p') + if session_i2p: + session_last_update_i2p = curr_time + else: + print('WARN: inbox i2p session not created') + continue + + curr_session = session + curr_proxy_type = proxy_type + if queue_json.get('actor'): + if isinstance(queue_json['actor'], str): + sender_domain, _ = get_domain_from_actor(queue_json['actor']) + if sender_domain.endswith('.onion') and \ + session_onion and proxy_type != 'tor': + curr_proxy_type = 'tor' + curr_session = session_onion + elif (sender_domain.endswith('.i2p') and + session_i2p and proxy_type != 'i2p'): + curr_proxy_type = 'i2p' + curr_session = session_i2p + if debug and queue_json.get('actor'): print('Obtaining public key for actor ' + queue_json['actor']) @@ -4298,10 +4390,11 @@ def run_inbox_queue(recent_posts_cache: {}, max_recent_posts: int, break pub_key = \ - get_person_pub_key(base_dir, session, key_id, + get_person_pub_key(base_dir, curr_session, key_id, person_cache, debug, project_version, http_prefix, - domain, onion_domain, signing_priv_key_pem) + domain, onion_domain, i2p_domain, + signing_priv_key_pem) if pub_key: if debug: print('DEBUG: public key: ' + str(pub_key)) @@ -4409,7 +4502,7 @@ def run_inbox_queue(recent_posts_cache: {}, max_recent_posts: int, # if queue_json['post'].get('id'): # queue_json['post']['id'] = queue_json['id'] - if _receive_undo(session, + if _receive_undo(curr_session, base_dir, http_prefix, port, send_threads, post_log, cached_webfingers, @@ -4430,7 +4523,7 @@ def run_inbox_queue(recent_posts_cache: {}, max_recent_posts: int, if debug: print('DEBUG: checking for follow requests') - if _receive_follow_request(session, + if _receive_follow_request(curr_session, session_onion, session_i2p, base_dir, http_prefix, port, send_threads, post_log, cached_webfingers, @@ -4438,7 +4531,7 @@ def run_inbox_queue(recent_posts_cache: {}, max_recent_posts: int, queue_json['post'], federation_list, debug, project_version, - max_followers, onion_domain, + max_followers, onion_domain, i2p_domain, signing_priv_key_pem, unit_test): if os.path.isfile(queue_filename): try: @@ -4455,7 +4548,7 @@ def run_inbox_queue(recent_posts_cache: {}, max_recent_posts: int, if debug: print('DEBUG: No follow requests') - if receive_accept_reject(session, + if receive_accept_reject(curr_session, base_dir, http_prefix, domain, port, send_threads, post_log, cached_webfingers, person_cache, @@ -4472,7 +4565,7 @@ def run_inbox_queue(recent_posts_cache: {}, max_recent_posts: int, queue.pop(0) continue - if _receive_update_activity(recent_posts_cache, session, + if _receive_update_activity(recent_posts_cache, curr_session, base_dir, http_prefix, domain, port, send_threads, post_log, @@ -4555,7 +4648,8 @@ def run_inbox_queue(recent_posts_cache: {}, max_recent_posts: int, languages_understood = [] _inbox_after_initial(recent_posts_cache, max_recent_posts, - session, key_id, handle, + session, session_onion, session_i2p, + key_id, handle, queue_json['post'], base_dir, http_prefix, send_threads, post_log, @@ -4563,7 +4657,7 @@ def run_inbox_queue(recent_posts_cache: {}, max_recent_posts: int, person_cache, queue, domain, onion_domain, i2p_domain, - port, proxy_type, + port, curr_proxy_type, federation_list, debug, queue_filename, destination, diff --git a/manualapprove.py b/manualapprove.py index 6e0cd9ca8..df7c7708b 100644 --- a/manualapprove.py +++ b/manualapprove.py @@ -19,8 +19,9 @@ from utils import acct_dir from threads import thread_with_trace -def manual_deny_follow_request(session, base_dir: str, - http_prefix: str, +def manual_deny_follow_request(session, session_onion, session_i2p, + onion_domain: str, i2p_domain: str, + base_dir: str, http_prefix: str, nickname: str, domain: str, port: int, deny_handle: str, federation_list: [], @@ -59,7 +60,9 @@ def manual_deny_follow_request(session, base_dir: str, if ':' in deny_domain: deny_port = get_port_from_domain(deny_domain) deny_domain = remove_domain_port(deny_domain) - followed_account_rejects(session, base_dir, http_prefix, + followed_account_rejects(session, session_onion, session_i2p, + onion_domain, i2p_domain, + base_dir, http_prefix, nickname, domain, port, deny_nickname, deny_domain, deny_port, federation_list, @@ -71,8 +74,9 @@ def manual_deny_follow_request(session, base_dir: str, print('Follow request from ' + deny_handle + ' was denied.') -def manual_deny_follow_request_thread(session, base_dir: str, - http_prefix: str, +def manual_deny_follow_request_thread(session, session_onion, session_i2p, + onion_domain: str, i2p_domain: str, + base_dir: str, http_prefix: str, nickname: str, domain: str, port: int, deny_handle: str, federation_list: [], @@ -86,8 +90,9 @@ def manual_deny_follow_request_thread(session, base_dir: str, """ thr = \ thread_with_trace(target=manual_deny_follow_request, - args=(session, base_dir, - http_prefix, + args=(session, session_onion, session_i2p, + onion_domain, i2p_domain, + base_dir, http_prefix, nickname, domain, port, deny_handle, federation_list, @@ -120,8 +125,9 @@ def _approve_follower_handle(account_dir: str, approve_handle: str) -> None: print('EX: unable to write ' + approved_filename) -def manual_approve_follow_request(session, base_dir: str, - http_prefix: str, +def manual_approve_follow_request(session, session_onion, session_i2p, + onion_domain: str, i2p_domain: str, + base_dir: str, http_prefix: str, nickname: str, domain: str, port: int, approve_handle: str, federation_list: [], @@ -206,12 +212,31 @@ def manual_approve_follow_request(session, base_dir: str, get_port_from_domain(approve_domain) approve_domain = \ remove_domain_port(approve_domain) + + curr_domain = domain + curr_port = port + curr_session = session + curr_http_prefix = http_prefix + if onion_domain and \ + approve_domain.endswith('.onion'): + curr_domain = onion_domain + curr_port = 80 + curr_session = session_onion + curr_http_prefix = 'http' + elif (i2p_domain and + approve_domain.endswith('.i2p')): + curr_domain = i2p_domain + curr_port = 80 + curr_session = session_i2p + curr_http_prefix = 'http' + print('Manual follow accept: Sending Accept for ' + handle + ' follow request from ' + approve_nickname + '@' + approve_domain) - followed_account_accepts(session, base_dir, - http_prefix, - nickname, domain, port, + followed_account_accepts(curr_session, base_dir, + curr_http_prefix, + nickname, + curr_domain, curr_port, approve_nickname, approve_domain, approve_port, @@ -281,8 +306,9 @@ def manual_approve_follow_request(session, base_dir: str, approve_follows_filename + '.new') -def manual_approve_follow_request_thread(session, base_dir: str, - http_prefix: str, +def manual_approve_follow_request_thread(session, session_onion, session_i2p, + onion_domain: str, i2p_domain: str, + base_dir: str, http_prefix: str, nickname: str, domain: str, port: int, approve_handle: str, federation_list: [], @@ -297,8 +323,9 @@ def manual_approve_follow_request_thread(session, base_dir: str, """ thr = \ thread_with_trace(target=manual_approve_follow_request, - args=(session, base_dir, - http_prefix, + args=(session, session_onion, session_i2p, + onion_domain, i2p_domain, + base_dir, http_prefix, nickname, domain, port, approve_handle, federation_list, diff --git a/outbox.py b/outbox.py index 81f65458a..c8bd0f5a0 100644 --- a/outbox.py +++ b/outbox.py @@ -9,7 +9,6 @@ __module_group__ = "Timeline" import os from shutil import copyfile -from session import create_session from auth import create_password from posts import is_image_media from posts import outbox_message_create_wrap @@ -489,12 +488,6 @@ def post_message_to_outbox(session, translate: {}, if debug: print('DEBUG: Updated announcements (shares) collection ' + 'for the post associated with the Announce activity') - if not server.session: - print('DEBUG: creating new session for c2s') - server.session = create_session(proxy_type) - if not server.session: - print('ERROR: Failed to create session for post_message_to_outbox') - return False if debug: print('DEBUG: sending c2s post to followers') # remove inactive threads @@ -517,6 +510,8 @@ def post_message_to_outbox(session, translate: {}, # create a thread to send the post to followers followers_thread = \ send_to_followers_thread(server.session, + server.session_onion, + server.session_i2p, base_dir, post_to_nickname, domain, onion_domain, i2p_domain, @@ -658,8 +653,10 @@ def post_message_to_outbox(session, translate: {}, print('c2s sender: ' + post_to_nickname + '@' + domain + ':' + str(port)) named_addresses_thread = \ - send_to_named_addresses_thread(server.session, base_dir, - post_to_nickname, + send_to_named_addresses_thread(server.session, + server.session_onion, + server.session_i2p, + base_dir, post_to_nickname, domain, onion_domain, i2p_domain, port, http_prefix, federation_list, diff --git a/person.py b/person.py index 835950d47..15e11374e 100644 --- a/person.py +++ b/person.py @@ -1427,10 +1427,10 @@ def _detect_users_path(url: str) -> str: return '/users/' -def get_actor_json(hostDomain: str, handle: str, http: bool, gnunet: bool, +def get_actor_json(host_domain: str, handle: str, http: bool, gnunet: bool, debug: bool, quiet: bool, signing_priv_key_pem: str, - existingSession) -> ({}, {}): + existing_session) -> ({}, {}): """Returns the actor json """ if debug: @@ -1513,10 +1513,16 @@ def get_actor_json(hostDomain: str, handle: str, http: bool, gnunet: bool, http_prefix = 'https' else: http_prefix = 'http' - if existingSession: - session = existingSession + if existing_session: + session = existing_session + if debug: + print('DEBUG: get_actor_json using existing session ' + + str(proxy_type) + ' ' + domain) else: session = create_session(proxy_type) + if debug: + print('DEBUG: get_actor_json using session ' + + str(proxy_type) + ' ' + domain) if nickname == 'inbox': nickname = domain @@ -1541,11 +1547,12 @@ def get_actor_json(hostDomain: str, handle: str, http: bool, gnunet: bool, handle = nickname + '@' + domain wf_request = webfinger_handle(session, handle, http_prefix, cached_webfingers, - hostDomain, __version__, debug, + host_domain, __version__, debug, group_account, signing_priv_key_pem) if not wf_request: if not quiet: - print('get_actor_json Unable to webfinger ' + handle) + print('get_actor_json Unable to webfinger ' + handle + + ' ' + http_prefix + ' proxy: ' + str(proxy_type)) return None, None if not isinstance(wf_request, dict): if not quiet: @@ -1600,7 +1607,7 @@ def get_actor_json(hostDomain: str, handle: str, http: bool, gnunet: bool, } person_json = \ get_json(signing_priv_key_pem, session, person_url, as_header, - None, debug, __version__, http_prefix, hostDomain, + None, debug, __version__, http_prefix, host_domain, 20, quiet) if person_json: if not quiet: diff --git a/posts.py b/posts.py index f452c02b7..c5a15ea24 100644 --- a/posts.py +++ b/posts.py @@ -2981,7 +2981,8 @@ def _is_profile_update(post_json_object: {}) -> bool: return False -def _send_to_named_addresses(session, base_dir: str, +def _send_to_named_addresses(session, session_onion, session_i2p, + base_dir: str, nickname: str, domain: str, onion_domain: str, i2p_domain: str, port: int, http_prefix: str, federation_list: [], @@ -3102,16 +3103,19 @@ def _send_to_named_addresses(session, base_dir: str, from_domain = domain from_domain_full = get_full_domain(domain, port) from_http_prefix = http_prefix + curr_session = session if onion_domain: if to_domain.endswith('.onion'): from_domain = onion_domain from_domain_full = onion_domain from_http_prefix = 'http' - elif i2p_domain: + curr_session = session_onion + if i2p_domain: if to_domain.endswith('.i2p'): from_domain = i2p_domain from_domain_full = i2p_domain from_http_prefix = 'http' + curr_session = session_i2p cc_list = [] # if the "to" domain is within the shared items @@ -3125,7 +3129,7 @@ def _send_to_named_addresses(session, base_dir: str, group_account = has_group_type(base_dir, address, person_cache) - send_signed_json(post_json_object, session, base_dir, + send_signed_json(post_json_object, curr_session, base_dir, nickname, from_domain, port, to_nickname, to_domain, to_port, cc_list, from_http_prefix, True, client_to_server, @@ -3136,8 +3140,8 @@ def _send_to_named_addresses(session, base_dir: str, signing_priv_key_pem, 34436782) -def send_to_named_addresses_thread(session, base_dir: str, - nickname: str, domain: str, +def send_to_named_addresses_thread(session, session_onion, session_i2p, + base_dir: str, nickname: str, domain: str, onion_domain: str, i2p_domain: str, port: int, http_prefix: str, federation_list: [], @@ -3152,8 +3156,8 @@ def send_to_named_addresses_thread(session, base_dir: str, """ send_thread = \ thread_with_trace(target=_send_to_named_addresses, - args=(session, base_dir, - nickname, domain, + args=(session, session_onion, session_i2p, + base_dir, nickname, domain, onion_domain, i2p_domain, port, http_prefix, federation_list, send_threads, post_log, @@ -3209,9 +3213,8 @@ def _sending_profile_update(post_json_object: {}) -> bool: return False -def send_to_followers(session, base_dir: str, - nickname: str, - domain: str, +def send_to_followers(session, session_onion, session_i2p, + base_dir: str, nickname: str, domain: str, onion_domain: str, i2p_domain: str, port: int, http_prefix: str, federation_list: [], send_threads: [], post_log: [], @@ -3224,9 +3227,6 @@ def send_to_followers(session, base_dir: str, """sends a post to the followers of the given nickname """ print('send_to_followers') - if not session: - print('WARN: No session for send_to_followers') - return if not _post_is_addressed_to_followers(base_dir, nickname, domain, port, http_prefix, post_json_object): @@ -3278,9 +3278,25 @@ def send_to_followers(session, base_dir: str, print('Sending post to followers domain is active: ' + follower_domain_url) + # select the appropriate session + curr_session = session + curr_http_prefix = http_prefix + if onion_domain: + if follower_domain.endswith('.onion'): + curr_session = session_onion + curr_http_prefix = 'http' + if i2p_domain: + if follower_domain.endswith('.i2p'): + curr_session = session_i2p + curr_http_prefix = 'http' + if not curr_session: + print('WARN: session not found when sending to follower ' + + follower_domain_url) + continue + with_shared_inbox = \ - _has_shared_inbox(session, http_prefix, follower_domain, debug, - signing_priv_key_pem) + _has_shared_inbox(curr_session, curr_http_prefix, follower_domain, + debug, signing_priv_key_pem) if debug: if with_shared_inbox: print(follower_domain + ' has shared inbox') @@ -3305,7 +3321,7 @@ def send_to_followers(session, base_dir: str, if to_domain.endswith('.onion'): from_domain = onion_domain from_http_prefix = 'http' - elif i2p_domain: + if i2p_domain: if to_domain.endswith('.i2p'): from_domain = i2p_domain from_http_prefix = 'http' @@ -3333,7 +3349,7 @@ def send_to_followers(session, base_dir: str, nickname + '@' + domain + ' to ' + to_nickname + '@' + to_domain) - send_signed_json(post_json_object, session, base_dir, + send_signed_json(post_json_object, curr_session, base_dir, nickname, from_domain, port, to_nickname, to_domain, to_port, cc_list, from_http_prefix, True, @@ -3362,7 +3378,7 @@ def send_to_followers(session, base_dir: str, nickname + '@' + domain + ' to ' + to_nickname + '@' + to_domain) - send_signed_json(post_json_object, session, base_dir, + send_signed_json(post_json_object, curr_session, base_dir, nickname, from_domain, port, to_nickname, to_domain, to_port, cc_list, from_http_prefix, True, @@ -3383,9 +3399,8 @@ def send_to_followers(session, base_dir: str, print('Sending post to followers ends ' + str(sending_mins) + ' mins') -def send_to_followers_thread(session, base_dir: str, - nickname: str, - domain: str, +def send_to_followers_thread(session, session_onion, session_i2p, + base_dir: str, nickname: str, domain: str, onion_domain: str, i2p_domain: str, port: int, http_prefix: str, federation_list: [], send_threads: [], post_log: [], @@ -3399,8 +3414,8 @@ def send_to_followers_thread(session, base_dir: str, """ send_thread = \ thread_with_trace(target=send_to_followers, - args=(session, base_dir, - nickname, domain, + args=(session, session_onion, session_i2p, + base_dir, nickname, domain, onion_domain, i2p_domain, port, http_prefix, federation_list, send_threads, post_log, diff --git a/schedule.py b/schedule.py index b6fae6a4c..46e9b1a19 100644 --- a/schedule.py +++ b/schedule.py @@ -16,6 +16,7 @@ from utils import load_json from utils import is_account_dir from utils import acct_dir from outbox import post_message_to_outbox +from session import create_session def _update_post_schedule(base_dir: str, handle: str, httpd, @@ -93,7 +94,17 @@ def _update_post_schedule(base_dir: str, handle: str, httpd, if nickname: httpd.post_to_nickname = nickname - if not post_message_to_outbox(httpd.session, + + # create session if needed + curr_session = httpd.session + curr_proxy_type = httpd.proxy_type + if not curr_session: + curr_session = create_session(httpd.proxy_type) + httpd.session = curr_session + if not curr_session: + continue + + if not post_message_to_outbox(curr_session, httpd.translate, post_json_object, nickname, httpd, base_dir, @@ -111,7 +122,7 @@ def _update_post_schedule(base_dir: str, handle: str, httpd, httpd.cached_webfingers, httpd.person_cache, httpd.allow_deletion, - httpd.proxy_type, + curr_proxy_type, httpd.project_version, httpd.debug, httpd.yt_replace_domain, diff --git a/session.py b/session.py index dbb471bb6..0f57d03ac 100644 --- a/session.py +++ b/session.py @@ -767,3 +767,48 @@ def get_method(method_name: str, xml_str: str, print('EX: get_method failed, ' + 'connection was reset during get_vcard ' + str(ex)) return None + + +def get_session_for_domains(server, calling_domain: str, referer_domain: str): + """Returns the appropriate session for the given domains + """ + if referer_domain is None: + referer_domain = '' + + if '.onion:' in calling_domain or \ + calling_domain.endswith('.onion') or \ + '.onion:' in referer_domain or \ + referer_domain.endswith('.onion'): + if not server.domain.endswith('.onion'): + if server.onion_domain and server.session_onion: + return server.session_onion, 'tor' + if '.i2p:' in calling_domain or \ + calling_domain.endswith('.i2p') or \ + '.i2p:' in referer_domain or \ + referer_domain.endswith('.i2p'): + if not server.domain.endswith('.i2p'): + if server.i2p_domain and server.session_i2p: + return server.session_i2p, 'i2p' + return server.session, server.proxy_type + + +def get_session_for_domain(server, referer_domain: str): + """Returns the appropriate session for the given domain + """ + return get_session_for_domains(server, referer_domain, referer_domain) + + +def set_session_for_sender(server, proxy_type: str, new_session) -> None: + """Sets the appropriate session for the given sender + """ + if proxy_type == 'tor': + if not server.domain.endswith('.onion'): + if server.onion_domain and server.session_onion: + server.session_onion = new_session + return + if proxy_type == 'i2p': + if not server.domain.endswith('.i2p'): + if server.i2p_domain and server.session_i2p: + server.session_i2p = new_session + return + server.session = new_session diff --git a/tests.py b/tests.py index f4121d76a..d5bed8eb3 100644 --- a/tests.py +++ b/tests.py @@ -1590,7 +1590,8 @@ def test_follow_between_servers(base_dir: str) -> None: signing_priv_key_pem = None send_result = \ send_follow_request(session_alice, alice_dir, - 'alice', alice_domain, alice_port, http_prefix, + 'alice', alice_domain, + alice_domain, alice_port, http_prefix, 'bob', bob_domain, bob_actor, bob_port, http_prefix, client_to_server, federation_list, @@ -1810,7 +1811,8 @@ def test_shared_items_federation(base_dir: str) -> None: bob_actor = http_prefix + '://' + bob_address + '/users/bob' send_result = \ send_follow_request(session_alice, alice_dir, - 'alice', alice_domain, alice_port, http_prefix, + 'alice', alice_domain, + alice_domain, alice_port, http_prefix, 'bob', bob_domain, bob_actor, bob_port, http_prefix, client_to_server, federation_list, @@ -2261,7 +2263,8 @@ def test_group_follow(base_dir: str) -> None: signing_priv_key_pem = None send_result = \ send_follow_request(session_alice, alice_dir, - 'alice', alice_domain, alice_port, http_prefix, + 'alice', alice_domain, + alice_domain, alice_port, http_prefix, 'testgroup', testgroup_domain, testgroup_actor, testgroupPort, http_prefix, client_to_server, federation_list, @@ -2338,7 +2341,8 @@ def test_group_follow(base_dir: str) -> None: signing_priv_key_pem = None send_result = \ send_follow_request(session_bob, bob_dir, - 'bob', bob_domain, bob_port, http_prefix, + 'bob', bob_domain, + bob_domain, bob_port, http_prefix, 'testgroup', testgroup_domain, testgroup_actor, testgroupPort, http_prefix, client_to_server, federation_list, diff --git a/utils.py b/utils.py index 7a866dde2..7f46917b8 100644 --- a/utils.py +++ b/utils.py @@ -2023,6 +2023,32 @@ def is_public_post(post_json_object: {}) -> bool: return False +def is_unlisted_post(post_json_object: {}) -> bool: + """Returns true if the given post is unlisted + """ + if not post_json_object.get('type'): + return False + if post_json_object['type'] != 'Create': + return False + if not has_object_dict(post_json_object): + return False + if not post_json_object['object'].get('to'): + return False + if not post_json_object['object'].get('cc'): + return False + has_followers = False + for recipient in post_json_object['object']['to']: + if recipient.endswith('/followers'): + has_followers = True + break + if not has_followers: + return False + for recipient in post_json_object['object']['cc']: + if recipient.endswith('#Public'): + return True + return False + + def copytree(src: str, dst: str, symlinks: str = False, ignore: bool = None): """Copy a directory """ diff --git a/webapp_create_post.py b/webapp_create_post.py index 7157adebd..4dff64b43 100644 --- a/webapp_create_post.py +++ b/webapp_create_post.py @@ -122,12 +122,12 @@ def _html_new_post_drop_down(scope_icon: str, scope_description: str, 'icons/scope_blog.png"/>' + \ translate['Blog'] + '
' + \ translate['Publicly visible post'] + '\n' - drop_down_content += \ - '
  • ' + \ - translate['Unlisted'] + '
    ' + \ - translate['Not on public timeline'] + '
  • \n' + drop_down_content += \ + '
  • ' + \ + translate['Unlisted'] + '
    ' + \ + translate['Not on public timeline'] + '
  • \n' drop_down_content += \ '
  • ' + \ @@ -300,8 +300,6 @@ def html_new_post(css_cache: {}, media_instance: bool, translate: {}, new_post_path = new_post_path.split('?')[0] if new_post_path.endswith('/newpost'): path = path.replace('/newpost', '/newfollowers') - elif new_post_path.endswith('/newunlisted'): - path = path.replace('/newunlisted', '/newfollowers') show_public_on_dropdown = False else: new_post_text = \ @@ -694,7 +692,7 @@ def html_new_post(css_cache: {}, media_instance: bool, translate: {}, if inReplyTo: dropdown_new_post_suffix += '?replyto=' + inReplyTo dropdown_new_blog_suffix += '?replyto=' + inReplyTo - dropdown_unlisted_suffix += '?replyto=' + inReplyTo + dropdown_unlisted_suffix += '?replyunlisted=' + inReplyTo dropdown_followers_suffix += '?replyfollowers=' + inReplyTo if reply_is_chat: dropdown_dm_suffix += '?replychat=' + inReplyTo diff --git a/webapp_post.py b/webapp_post.py index 59f40e1b8..5100eeb09 100644 --- a/webapp_post.py +++ b/webapp_post.py @@ -57,6 +57,7 @@ from utils import get_nickname_from_actor from utils import get_domain_from_actor from utils import acct_dir from utils import local_actor_url +from utils import is_unlisted_post from content import limit_repeated_words from content import replace_emoji_from_tags from content import html_replace_quote_marks @@ -389,7 +390,7 @@ def _get_avatar_image_html(showAvatarOptions: bool, def _get_reply_icon_html(base_dir: str, nickname: str, domain: str, - is_public_repeat: bool, + is_public_reply: bool, is_unlisted_reply: bool, show_icons: bool, comments_enabled: bool, post_json_object: {}, page_number_param: str, translate: {}, system_language: str, @@ -439,13 +440,20 @@ def _get_reply_icon_html(base_dir: str, nickname: str, domain: str, conversation_str = '' if conversation_id: conversation_str = '?conversationId=' + conversation_id - if is_public_repeat: + if is_public_reply: reply_str += \ ' \n' + elif is_unlisted_reply: + reply_str += \ + ' \n' else: if is_dm(post_json_object): reply_type = 'replydm' @@ -1698,10 +1706,14 @@ def individual_post_as_html(signing_priv_key_pem: str, conversation_id = post_json_object['object']['conversation'] public_reply = False + unlisted_reply = False if is_public_post(post_json_object): public_reply = True + if is_unlisted_post(post_json_object): + public_reply = False + unlisted_reply = True reply_str = _get_reply_icon_html(base_dir, nickname, domain, - public_reply, + public_reply, unlisted_reply, show_icons, comments_enabled, post_json_object, page_number_param, translate, system_language, diff --git a/webapp_profile.py b/webapp_profile.py index 713190bc8..cde8d016b 100644 --- a/webapp_profile.py +++ b/webapp_profile.py @@ -144,7 +144,8 @@ def html_profile_after_search(css_cache: {}, max_like_count: int, signing_priv_key_pem: str, cw_lists: {}, lists_enabled: str, - timezone: str) -> str: + timezone: str, + onion_domain: str, i2p_domain: str) -> str: """Show a profile page after a search for a fediverse address """ http = False @@ -153,8 +154,17 @@ def html_profile_after_search(css_cache: {}, http = True elif http_prefix == 'gnunet': gnunet = True + from_domain = domain + if onion_domain: + if '.onion/' in profile_handle or profile_handle.endswith('.onion'): + from_domain = onion_domain + http = True + if i2p_domain: + if '.i2p/' in profile_handle or profile_handle.endswith('.i2p'): + from_domain = i2p_domain + http = True profile_json, as_header = \ - get_actor_json(domain, profile_handle, http, gnunet, debug, False, + get_actor_json(from_domain, profile_handle, http, gnunet, debug, False, signing_priv_key_pem, session) if not profile_json: return None @@ -327,7 +337,7 @@ def html_profile_after_search(css_cache: {}, user_feed = \ parse_user_feed(signing_priv_key_pem, session, outbox_url, as_header, project_version, - http_prefix, domain, debug) + http_prefix, from_domain, debug) if user_feed: i = 0 for item in user_feed: diff --git a/webfinger.py b/webfinger.py index fa0497513..3432af169 100644 --- a/webfinger.py +++ b/webfinger.py @@ -68,12 +68,12 @@ def webfinger_handle(session, handle: str, http_prefix: str, """Gets webfinger result for the given ActivityPub handle """ if not session: - if debug: - print('WARN: No session specified for webfinger_handle') + print('WARN: No session specified for webfinger_handle') return None nickname, domain, _ = _parse_handle(handle) if not nickname: + print('WARN: No nickname found in handle ' + handle) return None wf_domain = remove_domain_port(domain) @@ -123,14 +123,14 @@ def webfinger_handle(session, handle: str, http_prefix: str, if result: store_webfinger_in_cache(wf_handle, result, cached_webfingers) else: - if debug: - print("WARN: Unable to webfinger " + url + ' ' + - 'nickname: ' + str(nickname) + ' ' + - 'handle: ' + str(handle) + ' ' + - 'wf_handle: ' + str(wf_handle) + ' ' + - 'domain: ' + str(wf_domain) + ' ' + - 'headers: ' + str(hdr) + ' ' + - 'params: ' + str(par)) + print("WARN: Unable to webfinger " + url + ' ' + + 'from_domain: ' + from_domain + ' ' + + 'nickname: ' + str(nickname) + ' ' + + 'handle: ' + str(handle) + ' ' + + 'wf_handle: ' + str(wf_handle) + ' ' + + 'domain: ' + str(wf_domain) + ' ' + + 'headers: ' + str(hdr) + ' ' + + 'params: ' + str(par)) return result