| 
									
										
										
										
											2024-03-03 22:01:22 +00:00
										 |  |  | __filename__ = "daemon_post_confirm.py" | 
					
						
							|  |  |  | __author__ = "Bob Mottram" | 
					
						
							|  |  |  | __license__ = "AGPL3+" | 
					
						
							|  |  |  | __version__ = "1.5.0" | 
					
						
							|  |  |  | __maintainer__ = "Bob Mottram" | 
					
						
							|  |  |  | __email__ = "bob@libreserver.org" | 
					
						
							|  |  |  | __status__ = "Production" | 
					
						
							| 
									
										
										
										
											2024-03-23 15:11:05 +00:00
										 |  |  | __module_group__ = "Core POST" | 
					
						
							| 
									
										
										
										
											2024-03-03 22:01:22 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | import errno | 
					
						
							|  |  |  | import urllib.parse | 
					
						
							|  |  |  | from socket import error as SocketError | 
					
						
							|  |  |  | from utils import get_nickname_from_actor | 
					
						
							|  |  |  | from utils import get_domain_from_actor | 
					
						
							|  |  |  | from utils import get_full_domain | 
					
						
							|  |  |  | from utils import local_actor_url | 
					
						
							|  |  |  | from utils import get_status_number | 
					
						
							|  |  |  | from utils import has_group_type | 
					
						
							|  |  |  | from follow import unfollow_account | 
					
						
							|  |  |  | from follow import send_follow_request | 
					
						
							|  |  |  | from follow import remove_follower | 
					
						
							|  |  |  | from daemon_utils import post_to_outbox_thread | 
					
						
							|  |  |  | from httpcodes import write2 | 
					
						
							|  |  |  | from httpheaders import redirect_headers | 
					
						
							|  |  |  | from httpheaders import login_headers | 
					
						
							|  |  |  | from posts import is_moderator | 
					
						
							|  |  |  | from webapp_moderation import html_account_info | 
					
						
							|  |  |  | from session import establish_session | 
					
						
							|  |  |  | from blocking import remove_block | 
					
						
							|  |  |  | from blocking import remove_global_block | 
					
						
							|  |  |  | from blocking import update_blocked_cache | 
					
						
							|  |  |  | from blocking import add_block | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def unfollow_confirm(self, calling_domain: str, cookie: str, | 
					
						
							|  |  |  |                      path: str, base_dir: str, http_prefix: str, | 
					
						
							|  |  |  |                      domain: str, domain_full: str, port: int, | 
					
						
							|  |  |  |                      onion_domain: str, i2p_domain: str, | 
					
						
							|  |  |  |                      debug: bool, | 
					
						
							| 
									
										
										
										
											2024-04-13 12:40:49 +00:00
										 |  |  |                      curr_session, proxy_type: str, | 
					
						
							|  |  |  |                      person_cache: {}) -> None: | 
					
						
							| 
									
										
										
										
											2024-03-03 22:01:22 +00:00
										 |  |  |     """Confirm to unfollow
 | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     users_path = path.split('/unfollowconfirm')[0] | 
					
						
							|  |  |  |     origin_path_str = http_prefix + '://' + domain_full + users_path | 
					
						
							|  |  |  |     follower_nickname = get_nickname_from_actor(origin_path_str) | 
					
						
							|  |  |  |     if not follower_nickname: | 
					
						
							|  |  |  |         self.send_response(400) | 
					
						
							|  |  |  |         self.end_headers() | 
					
						
							|  |  |  |         self.server.postreq_busy = False | 
					
						
							|  |  |  |         return | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     length = int(self.headers['Content-length']) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     try: | 
					
						
							|  |  |  |         follow_confirm_params = self.rfile.read(length).decode('utf-8') | 
					
						
							|  |  |  |     except SocketError as ex: | 
					
						
							|  |  |  |         if ex.errno == errno.ECONNRESET: | 
					
						
							|  |  |  |             print('EX: POST follow_confirm_params ' + | 
					
						
							|  |  |  |                   'connection was reset') | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             print('EX: POST follow_confirm_params socket error') | 
					
						
							|  |  |  |         self.send_response(400) | 
					
						
							|  |  |  |         self.end_headers() | 
					
						
							|  |  |  |         self.server.postreq_busy = False | 
					
						
							|  |  |  |         return | 
					
						
							|  |  |  |     except ValueError as ex: | 
					
						
							|  |  |  |         print('EX: POST follow_confirm_params rfile.read failed, ' + | 
					
						
							|  |  |  |               str(ex)) | 
					
						
							|  |  |  |         self.send_response(400) | 
					
						
							|  |  |  |         self.end_headers() | 
					
						
							|  |  |  |         self.server.postreq_busy = False | 
					
						
							|  |  |  |         return | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if '&submitYes=' in follow_confirm_params: | 
					
						
							|  |  |  |         following_actor = \ | 
					
						
							|  |  |  |             urllib.parse.unquote_plus(follow_confirm_params) | 
					
						
							|  |  |  |         following_actor = following_actor.split('actor=')[1] | 
					
						
							|  |  |  |         if '&' in following_actor: | 
					
						
							|  |  |  |             following_actor = following_actor.split('&')[0] | 
					
						
							|  |  |  |         following_nickname = get_nickname_from_actor(following_actor) | 
					
						
							|  |  |  |         following_domain, following_port = \ | 
					
						
							|  |  |  |             get_domain_from_actor(following_actor) | 
					
						
							|  |  |  |         if not following_nickname or not following_domain: | 
					
						
							|  |  |  |             self.send_response(400) | 
					
						
							|  |  |  |             self.end_headers() | 
					
						
							|  |  |  |             self.server.postreq_busy = False | 
					
						
							|  |  |  |             return | 
					
						
							|  |  |  |         following_domain_full = \ | 
					
						
							|  |  |  |             get_full_domain(following_domain, following_port) | 
					
						
							|  |  |  |         if follower_nickname == following_nickname and \ | 
					
						
							|  |  |  |            following_domain == domain and \ | 
					
						
							|  |  |  |            following_port == port: | 
					
						
							|  |  |  |             if debug: | 
					
						
							|  |  |  |                 print('You cannot unfollow yourself!') | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             if debug: | 
					
						
							|  |  |  |                 print(follower_nickname + ' stops following ' + | 
					
						
							|  |  |  |                       following_actor) | 
					
						
							|  |  |  |             follow_actor = \ | 
					
						
							|  |  |  |                 local_actor_url(http_prefix, | 
					
						
							|  |  |  |                                 follower_nickname, domain_full) | 
					
						
							|  |  |  |             status_number, _ = get_status_number() | 
					
						
							|  |  |  |             follow_id = follow_actor + '/statuses/' + str(status_number) | 
					
						
							|  |  |  |             unfollow_json = { | 
					
						
							|  |  |  |                 '@context': 'https://www.w3.org/ns/activitystreams', | 
					
						
							|  |  |  |                 'id': follow_id + '/undo', | 
					
						
							|  |  |  |                 'type': 'Undo', | 
					
						
							|  |  |  |                 'actor': follow_actor, | 
					
						
							|  |  |  |                 'object': { | 
					
						
							|  |  |  |                     'id': follow_id, | 
					
						
							|  |  |  |                     'type': 'Follow', | 
					
						
							|  |  |  |                     'actor': follow_actor, | 
					
						
							|  |  |  |                     'object': following_actor | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             path_users_section = path.split('/users/')[1] | 
					
						
							|  |  |  |             self.post_to_nickname = path_users_section.split('/')[0] | 
					
						
							|  |  |  |             group_account = has_group_type(base_dir, following_actor, | 
					
						
							| 
									
										
										
										
											2024-04-13 12:40:49 +00:00
										 |  |  |                                            person_cache) | 
					
						
							| 
									
										
										
										
											2024-04-08 09:33:48 +00:00
										 |  |  |             unfollow_account(base_dir, self.post_to_nickname, | 
					
						
							| 
									
										
										
										
											2024-04-08 14:00:47 +00:00
										 |  |  |                              domain, | 
					
						
							| 
									
										
										
										
											2024-03-03 22:01:22 +00:00
										 |  |  |                              following_nickname, following_domain_full, | 
					
						
							| 
									
										
										
										
											2024-04-08 14:00:47 +00:00
										 |  |  |                              debug, group_account, | 
					
						
							| 
									
										
										
										
											2024-03-03 22:01:22 +00:00
										 |  |  |                              'following.txt') | 
					
						
							|  |  |  |             post_to_outbox_thread(self, unfollow_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): | 
					
						
							|  |  |  |         origin_path_str = 'http://' + i2p_domain + users_path | 
					
						
							| 
									
										
										
										
											2024-04-16 13:47:21 +00:00
										 |  |  |     redirect_headers(self, origin_path_str, cookie, calling_domain, 303) | 
					
						
							| 
									
										
										
										
											2024-03-03 22:01:22 +00:00
										 |  |  |     self.server.postreq_busy = False | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def follow_confirm2(self, calling_domain: str, cookie: str, | 
					
						
							|  |  |  |                     path: str, base_dir: str, http_prefix: str, | 
					
						
							|  |  |  |                     domain: str, domain_full: str, port: int, | 
					
						
							|  |  |  |                     onion_domain: str, i2p_domain: str, | 
					
						
							|  |  |  |                     debug: bool, | 
					
						
							| 
									
										
										
										
											2024-04-13 12:40:49 +00:00
										 |  |  |                     curr_session, proxy_type: str, | 
					
						
							|  |  |  |                     translate: {}, | 
					
						
							|  |  |  |                     system_language: str, | 
					
						
							|  |  |  |                     signing_priv_key_pem: str, | 
					
						
							|  |  |  |                     block_federated: [], | 
					
						
							|  |  |  |                     federation_list: [], | 
					
						
							|  |  |  |                     send_threads: [], | 
					
						
							|  |  |  |                     post_log: str, | 
					
						
							|  |  |  |                     cached_webfingers: {}, | 
					
						
							|  |  |  |                     person_cache: {}, | 
					
						
							|  |  |  |                     project_version: str, | 
					
						
							|  |  |  |                     sites_unavailable: []) -> None: | 
					
						
							| 
									
										
										
										
											2024-03-03 22:01:22 +00:00
										 |  |  |     """Confirm to follow
 | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     users_path = path.split('/followconfirm')[0] | 
					
						
							|  |  |  |     origin_path_str = http_prefix + '://' + domain_full + users_path | 
					
						
							|  |  |  |     follower_nickname = get_nickname_from_actor(origin_path_str) | 
					
						
							|  |  |  |     if not follower_nickname: | 
					
						
							|  |  |  |         self.send_response(400) | 
					
						
							|  |  |  |         self.end_headers() | 
					
						
							|  |  |  |         self.server.postreq_busy = False | 
					
						
							|  |  |  |         return | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     length = int(self.headers['Content-length']) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     try: | 
					
						
							|  |  |  |         follow_confirm_params = self.rfile.read(length).decode('utf-8') | 
					
						
							|  |  |  |     except SocketError as ex: | 
					
						
							|  |  |  |         if ex.errno == errno.ECONNRESET: | 
					
						
							|  |  |  |             print('EX: POST follow_confirm_params ' + | 
					
						
							|  |  |  |                   'connection was reset') | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             print('EX: POST follow_confirm_params socket error') | 
					
						
							|  |  |  |         self.send_response(400) | 
					
						
							|  |  |  |         self.end_headers() | 
					
						
							|  |  |  |         self.server.postreq_busy = False | 
					
						
							|  |  |  |         return | 
					
						
							|  |  |  |     except ValueError as ex: | 
					
						
							|  |  |  |         print('EX: POST follow_confirm_params rfile.read failed, ' + | 
					
						
							|  |  |  |               str(ex)) | 
					
						
							|  |  |  |         self.send_response(400) | 
					
						
							|  |  |  |         self.end_headers() | 
					
						
							|  |  |  |         self.server.postreq_busy = False | 
					
						
							|  |  |  |         return | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if '&submitView=' in follow_confirm_params: | 
					
						
							|  |  |  |         following_actor = \ | 
					
						
							|  |  |  |             urllib.parse.unquote_plus(follow_confirm_params) | 
					
						
							|  |  |  |         following_actor = following_actor.split('actor=')[1] | 
					
						
							|  |  |  |         if '&' in following_actor: | 
					
						
							|  |  |  |             following_actor = following_actor.split('&')[0] | 
					
						
							| 
									
										
										
										
											2024-04-16 13:47:21 +00:00
										 |  |  |         redirect_headers(self, following_actor, cookie, calling_domain, 303) | 
					
						
							| 
									
										
										
										
											2024-03-03 22:01:22 +00:00
										 |  |  |         self.server.postreq_busy = False | 
					
						
							|  |  |  |         return | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if '&submitInfo=' in follow_confirm_params: | 
					
						
							|  |  |  |         following_actor = \ | 
					
						
							|  |  |  |             urllib.parse.unquote_plus(follow_confirm_params) | 
					
						
							|  |  |  |         following_actor = following_actor.split('actor=')[1] | 
					
						
							|  |  |  |         if '&' in following_actor: | 
					
						
							|  |  |  |             following_actor = following_actor.split('&')[0] | 
					
						
							|  |  |  |         if is_moderator(base_dir, follower_nickname): | 
					
						
							|  |  |  |             msg = \ | 
					
						
							| 
									
										
										
										
											2024-04-13 12:40:49 +00:00
										 |  |  |                 html_account_info(translate, | 
					
						
							| 
									
										
										
										
											2024-03-03 22:01:22 +00:00
										 |  |  |                                   base_dir, http_prefix, | 
					
						
							|  |  |  |                                   follower_nickname, | 
					
						
							| 
									
										
										
										
											2024-04-08 14:00:47 +00:00
										 |  |  |                                   domain, | 
					
						
							| 
									
										
										
										
											2024-03-03 22:01:22 +00:00
										 |  |  |                                   following_actor, | 
					
						
							| 
									
										
										
										
											2024-04-08 14:00:47 +00:00
										 |  |  |                                   debug, | 
					
						
							| 
									
										
										
										
											2024-04-13 12:40:49 +00:00
										 |  |  |                                   system_language, | 
					
						
							|  |  |  |                                   signing_priv_key_pem, | 
					
						
							| 
									
										
										
										
											2024-03-03 22:01:22 +00:00
										 |  |  |                                   users_path, | 
					
						
							| 
									
										
										
										
											2024-04-13 12:40:49 +00:00
										 |  |  |                                   block_federated) | 
					
						
							| 
									
										
										
										
											2024-03-03 22:01:22 +00:00
										 |  |  |             if msg: | 
					
						
							|  |  |  |                 msg = msg.encode('utf-8') | 
					
						
							|  |  |  |                 msglen = len(msg) | 
					
						
							|  |  |  |                 login_headers(self, 'text/html', | 
					
						
							|  |  |  |                               msglen, calling_domain) | 
					
						
							|  |  |  |                 write2(self, msg) | 
					
						
							|  |  |  |                 self.server.postreq_busy = False | 
					
						
							|  |  |  |                 return | 
					
						
							| 
									
										
										
										
											2024-04-16 13:47:21 +00:00
										 |  |  |         redirect_headers(self, following_actor, cookie, calling_domain, 303) | 
					
						
							| 
									
										
										
										
											2024-03-03 22:01:22 +00:00
										 |  |  |         self.server.postreq_busy = False | 
					
						
							|  |  |  |         return | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if '&submitYes=' in follow_confirm_params: | 
					
						
							|  |  |  |         following_actor = \ | 
					
						
							|  |  |  |             urllib.parse.unquote_plus(follow_confirm_params) | 
					
						
							|  |  |  |         following_actor = following_actor.split('actor=')[1] | 
					
						
							|  |  |  |         if '&' in following_actor: | 
					
						
							|  |  |  |             following_actor = following_actor.split('&')[0] | 
					
						
							|  |  |  |         following_nickname = get_nickname_from_actor(following_actor) | 
					
						
							|  |  |  |         following_domain, following_port = \ | 
					
						
							|  |  |  |             get_domain_from_actor(following_actor) | 
					
						
							|  |  |  |         if not following_nickname or not following_domain: | 
					
						
							|  |  |  |             self.send_response(400) | 
					
						
							|  |  |  |             self.end_headers() | 
					
						
							|  |  |  |             self.server.postreq_busy = False | 
					
						
							|  |  |  |             return | 
					
						
							|  |  |  |         if follower_nickname == following_nickname and \ | 
					
						
							|  |  |  |            following_domain == domain and \ | 
					
						
							|  |  |  |            following_port == port: | 
					
						
							|  |  |  |             if debug: | 
					
						
							|  |  |  |                 print('You cannot follow yourself!') | 
					
						
							|  |  |  |         elif (following_nickname == 'news' and | 
					
						
							|  |  |  |               following_domain == domain and | 
					
						
							|  |  |  |               following_port == port): | 
					
						
							|  |  |  |             if debug: | 
					
						
							|  |  |  |                 print('You cannot follow the news actor') | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             print('Sending follow request from ' + | 
					
						
							|  |  |  |                   follower_nickname + ' to ' + following_actor) | 
					
						
							| 
									
										
										
										
											2024-04-13 12:40:49 +00:00
										 |  |  |             if not signing_priv_key_pem: | 
					
						
							| 
									
										
										
										
											2024-03-03 22:01:22 +00:00
										 |  |  |                 print('Sending follow request with no signing key') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             curr_domain = domain | 
					
						
							|  |  |  |             curr_port = port | 
					
						
							|  |  |  |             curr_http_prefix = http_prefix | 
					
						
							|  |  |  |             curr_proxy_type = proxy_type | 
					
						
							|  |  |  |             if onion_domain: | 
					
						
							|  |  |  |                 if not curr_domain.endswith('.onion') and \ | 
					
						
							|  |  |  |                    following_domain.endswith('.onion'): | 
					
						
							|  |  |  |                     curr_session = self.server.session_onion | 
					
						
							|  |  |  |                     curr_domain = onion_domain | 
					
						
							|  |  |  |                     curr_port = 80 | 
					
						
							|  |  |  |                     following_port = 80 | 
					
						
							|  |  |  |                     curr_http_prefix = 'http' | 
					
						
							|  |  |  |                     curr_proxy_type = 'tor' | 
					
						
							|  |  |  |             if i2p_domain: | 
					
						
							|  |  |  |                 if not curr_domain.endswith('.i2p') and \ | 
					
						
							|  |  |  |                    following_domain.endswith('.i2p'): | 
					
						
							|  |  |  |                     curr_session = self.server.session_i2p | 
					
						
							|  |  |  |                     curr_domain = i2p_domain | 
					
						
							|  |  |  |                     curr_port = 80 | 
					
						
							|  |  |  |                     following_port = 80 | 
					
						
							|  |  |  |                     curr_http_prefix = 'http' | 
					
						
							|  |  |  |                     curr_proxy_type = 'i2p' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             curr_session = \ | 
					
						
							|  |  |  |                 establish_session("follow request", | 
					
						
							|  |  |  |                                   curr_session, | 
					
						
							|  |  |  |                                   curr_proxy_type, | 
					
						
							|  |  |  |                                   self.server) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             send_follow_request(curr_session, | 
					
						
							|  |  |  |                                 base_dir, follower_nickname, | 
					
						
							|  |  |  |                                 domain, curr_domain, curr_port, | 
					
						
							|  |  |  |                                 curr_http_prefix, | 
					
						
							|  |  |  |                                 following_nickname, | 
					
						
							|  |  |  |                                 following_domain, | 
					
						
							|  |  |  |                                 following_actor, | 
					
						
							|  |  |  |                                 following_port, curr_http_prefix, | 
					
						
							| 
									
										
										
										
											2024-04-13 12:40:49 +00:00
										 |  |  |                                 False, federation_list, | 
					
						
							|  |  |  |                                 send_threads, | 
					
						
							|  |  |  |                                 post_log, | 
					
						
							|  |  |  |                                 cached_webfingers, | 
					
						
							|  |  |  |                                 person_cache, debug, | 
					
						
							|  |  |  |                                 project_version, | 
					
						
							|  |  |  |                                 signing_priv_key_pem, | 
					
						
							| 
									
										
										
										
											2024-04-08 14:00:47 +00:00
										 |  |  |                                 domain, | 
					
						
							|  |  |  |                                 onion_domain, | 
					
						
							|  |  |  |                                 i2p_domain, | 
					
						
							| 
									
										
										
										
											2024-04-13 12:40:49 +00:00
										 |  |  |                                 sites_unavailable, | 
					
						
							|  |  |  |                                 system_language) | 
					
						
							| 
									
										
										
										
											2024-03-03 22:01:22 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if '&submitUnblock=' in follow_confirm_params: | 
					
						
							|  |  |  |         blocking_actor = \ | 
					
						
							|  |  |  |             urllib.parse.unquote_plus(follow_confirm_params) | 
					
						
							|  |  |  |         blocking_actor = blocking_actor.split('actor=')[1] | 
					
						
							|  |  |  |         if '&' in blocking_actor: | 
					
						
							|  |  |  |             blocking_actor = blocking_actor.split('&')[0] | 
					
						
							|  |  |  |         blocking_nickname = get_nickname_from_actor(blocking_actor) | 
					
						
							|  |  |  |         blocking_domain, blocking_port = \ | 
					
						
							|  |  |  |             get_domain_from_actor(blocking_actor) | 
					
						
							|  |  |  |         if not blocking_nickname or not blocking_domain: | 
					
						
							|  |  |  |             if calling_domain.endswith('.onion') and onion_domain: | 
					
						
							|  |  |  |                 origin_path_str = 'http://' + onion_domain + users_path | 
					
						
							|  |  |  |             elif (calling_domain.endswith('.i2p') and i2p_domain): | 
					
						
							|  |  |  |                 origin_path_str = 'http://' + i2p_domain + users_path | 
					
						
							|  |  |  |             print('WARN: unable to find blocked nickname or domain in ' + | 
					
						
							|  |  |  |                   blocking_actor) | 
					
						
							|  |  |  |             redirect_headers(self, origin_path_str, | 
					
						
							| 
									
										
										
										
											2024-04-16 13:47:21 +00:00
										 |  |  |                              cookie, calling_domain, 303) | 
					
						
							| 
									
										
										
										
											2024-03-03 22:01:22 +00:00
										 |  |  |             self.server.postreq_busy = False | 
					
						
							|  |  |  |             return | 
					
						
							|  |  |  |         blocking_domain_full = \ | 
					
						
							|  |  |  |             get_full_domain(blocking_domain, blocking_port) | 
					
						
							|  |  |  |         if follower_nickname == blocking_nickname and \ | 
					
						
							|  |  |  |            blocking_domain == domain and \ | 
					
						
							|  |  |  |            blocking_port == port: | 
					
						
							|  |  |  |             if debug: | 
					
						
							|  |  |  |                 print('You cannot unblock yourself!') | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             if debug: | 
					
						
							|  |  |  |                 print(follower_nickname + ' stops blocking ' + | 
					
						
							|  |  |  |                       blocking_actor) | 
					
						
							|  |  |  |             remove_block(base_dir, | 
					
						
							|  |  |  |                          follower_nickname, domain, | 
					
						
							|  |  |  |                          blocking_nickname, blocking_domain_full) | 
					
						
							|  |  |  |             if is_moderator(base_dir, follower_nickname): | 
					
						
							|  |  |  |                 remove_global_block(base_dir, | 
					
						
							|  |  |  |                                     blocking_nickname, | 
					
						
							|  |  |  |                                     blocking_domain_full) | 
					
						
							|  |  |  |                 blocked_cache_last_updated = \ | 
					
						
							|  |  |  |                     self.server.blocked_cache_last_updated | 
					
						
							|  |  |  |                 self.server.blocked_cache_last_updated = \ | 
					
						
							| 
									
										
										
										
											2024-04-08 09:33:48 +00:00
										 |  |  |                     update_blocked_cache(base_dir, | 
					
						
							| 
									
										
										
										
											2024-03-03 22:01:22 +00:00
										 |  |  |                                          self.server.blocked_cache, | 
					
						
							|  |  |  |                                          blocked_cache_last_updated, 0) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if calling_domain.endswith('.onion') and onion_domain: | 
					
						
							|  |  |  |         origin_path_str = 'http://' + onion_domain + users_path | 
					
						
							|  |  |  |     elif (calling_domain.endswith('.i2p') and i2p_domain): | 
					
						
							|  |  |  |         origin_path_str = 'http://' + i2p_domain + users_path | 
					
						
							| 
									
										
										
										
											2024-04-16 13:47:21 +00:00
										 |  |  |     redirect_headers(self, origin_path_str, cookie, calling_domain, 303) | 
					
						
							| 
									
										
										
										
											2024-03-03 22:01:22 +00:00
										 |  |  |     self.server.postreq_busy = False | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def block_confirm2(self, calling_domain: str, cookie: str, | 
					
						
							|  |  |  |                    path: str, base_dir: str, http_prefix: str, | 
					
						
							|  |  |  |                    domain: str, domain_full: str, port: int, | 
					
						
							|  |  |  |                    onion_domain: str, i2p_domain: str, | 
					
						
							|  |  |  |                    debug: bool) -> None: | 
					
						
							|  |  |  |     """Confirms a block from the person options screen
 | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     users_path = path.split('/blockconfirm')[0] | 
					
						
							|  |  |  |     origin_path_str = http_prefix + '://' + domain_full + users_path | 
					
						
							|  |  |  |     blocker_nickname = get_nickname_from_actor(origin_path_str) | 
					
						
							|  |  |  |     if not blocker_nickname: | 
					
						
							|  |  |  |         if calling_domain.endswith('.onion') and onion_domain: | 
					
						
							|  |  |  |             origin_path_str = 'http://' + onion_domain + users_path | 
					
						
							|  |  |  |         elif (calling_domain.endswith('.i2p') and i2p_domain): | 
					
						
							|  |  |  |             origin_path_str = 'http://' + i2p_domain + users_path | 
					
						
							|  |  |  |         print('WARN: unable to find nickname in ' + origin_path_str) | 
					
						
							|  |  |  |         redirect_headers(self, origin_path_str, | 
					
						
							| 
									
										
										
										
											2024-04-16 13:47:21 +00:00
										 |  |  |                          cookie, calling_domain, 303) | 
					
						
							| 
									
										
										
										
											2024-03-03 22:01:22 +00:00
										 |  |  |         self.server.postreq_busy = False | 
					
						
							|  |  |  |         return | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     length = int(self.headers['Content-length']) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     try: | 
					
						
							|  |  |  |         block_confirm_params = self.rfile.read(length).decode('utf-8') | 
					
						
							|  |  |  |     except SocketError as ex: | 
					
						
							|  |  |  |         if ex.errno == errno.ECONNRESET: | 
					
						
							|  |  |  |             print('EX: POST block_confirm_params ' + | 
					
						
							|  |  |  |                   'connection was reset') | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             print('EX: POST block_confirm_params socket error') | 
					
						
							|  |  |  |         self.send_response(400) | 
					
						
							|  |  |  |         self.end_headers() | 
					
						
							|  |  |  |         self.server.postreq_busy = False | 
					
						
							|  |  |  |         return | 
					
						
							|  |  |  |     except ValueError as ex: | 
					
						
							|  |  |  |         print('EX: POST block_confirm_params rfile.read failed, ' + | 
					
						
							|  |  |  |               str(ex)) | 
					
						
							|  |  |  |         self.send_response(400) | 
					
						
							|  |  |  |         self.end_headers() | 
					
						
							|  |  |  |         self.server.postreq_busy = False | 
					
						
							|  |  |  |         return | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if '&submitYes=' in block_confirm_params: | 
					
						
							|  |  |  |         blocking_confirm_str = \ | 
					
						
							|  |  |  |             urllib.parse.unquote_plus(block_confirm_params) | 
					
						
							|  |  |  |         block_reason = blocking_confirm_str.split('blockReason=')[1] | 
					
						
							|  |  |  |         if '&' in block_reason: | 
					
						
							|  |  |  |             block_reason = block_reason.split('&')[0] | 
					
						
							|  |  |  |         blocking_actor = blocking_confirm_str.split('actor=')[1] | 
					
						
							|  |  |  |         if '&' in blocking_actor: | 
					
						
							|  |  |  |             blocking_actor = blocking_actor.split('&')[0] | 
					
						
							|  |  |  |         blocking_nickname = get_nickname_from_actor(blocking_actor) | 
					
						
							|  |  |  |         blocking_domain, blocking_port = \ | 
					
						
							|  |  |  |             get_domain_from_actor(blocking_actor) | 
					
						
							|  |  |  |         if not blocking_nickname or not blocking_domain: | 
					
						
							|  |  |  |             if calling_domain.endswith('.onion') and onion_domain: | 
					
						
							|  |  |  |                 origin_path_str = 'http://' + onion_domain + users_path | 
					
						
							|  |  |  |             elif (calling_domain.endswith('.i2p') and i2p_domain): | 
					
						
							|  |  |  |                 origin_path_str = 'http://' + i2p_domain + users_path | 
					
						
							|  |  |  |             print('WARN: unable to find nickname or domain in ' + | 
					
						
							|  |  |  |                   blocking_actor) | 
					
						
							|  |  |  |             redirect_headers(self, origin_path_str, | 
					
						
							| 
									
										
										
										
											2024-04-16 13:47:21 +00:00
										 |  |  |                              cookie, calling_domain, 303) | 
					
						
							| 
									
										
										
										
											2024-03-03 22:01:22 +00:00
										 |  |  |             self.server.postreq_busy = False | 
					
						
							|  |  |  |             return | 
					
						
							|  |  |  |         blocking_domain_full = \ | 
					
						
							|  |  |  |             get_full_domain(blocking_domain, blocking_port) | 
					
						
							|  |  |  |         if blocker_nickname == blocking_nickname and \ | 
					
						
							|  |  |  |            blocking_domain == domain and \ | 
					
						
							|  |  |  |            blocking_port == port: | 
					
						
							|  |  |  |             if debug: | 
					
						
							|  |  |  |                 print('You cannot block yourself!') | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             print('Adding block by ' + blocker_nickname + | 
					
						
							|  |  |  |                   ' of ' + blocking_actor) | 
					
						
							|  |  |  |             add_block(base_dir, blocker_nickname, | 
					
						
							|  |  |  |                       domain, blocking_nickname, | 
					
						
							|  |  |  |                       blocking_domain_full, block_reason) | 
					
						
							|  |  |  |             remove_follower(base_dir, blocker_nickname, | 
					
						
							|  |  |  |                             domain, | 
					
						
							|  |  |  |                             blocking_nickname, | 
					
						
							|  |  |  |                             blocking_domain_full) | 
					
						
							|  |  |  |     if calling_domain.endswith('.onion') and onion_domain: | 
					
						
							|  |  |  |         origin_path_str = 'http://' + onion_domain + users_path | 
					
						
							|  |  |  |     elif (calling_domain.endswith('.i2p') and i2p_domain): | 
					
						
							|  |  |  |         origin_path_str = 'http://' + i2p_domain + users_path | 
					
						
							| 
									
										
										
										
											2024-04-16 13:47:21 +00:00
										 |  |  |     redirect_headers(self, origin_path_str, cookie, calling_domain, 303) | 
					
						
							| 
									
										
										
										
											2024-03-03 22:01:22 +00:00
										 |  |  |     self.server.postreq_busy = False | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def unblock_confirm(self, calling_domain: str, cookie: str, | 
					
						
							|  |  |  |                     path: str, base_dir: str, http_prefix: str, | 
					
						
							|  |  |  |                     domain: str, domain_full: str, port: int, | 
					
						
							|  |  |  |                     onion_domain: str, i2p_domain: str, | 
					
						
							|  |  |  |                     debug: bool) -> None: | 
					
						
							|  |  |  |     """Confirms a unblock
 | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     users_path = path.split('/unblockconfirm')[0] | 
					
						
							|  |  |  |     origin_path_str = http_prefix + '://' + domain_full + users_path | 
					
						
							|  |  |  |     blocker_nickname = get_nickname_from_actor(origin_path_str) | 
					
						
							|  |  |  |     if not blocker_nickname: | 
					
						
							|  |  |  |         if calling_domain.endswith('.onion') and onion_domain: | 
					
						
							|  |  |  |             origin_path_str = 'http://' + onion_domain + users_path | 
					
						
							|  |  |  |         elif (calling_domain.endswith('.i2p') and i2p_domain): | 
					
						
							|  |  |  |             origin_path_str = 'http://' + i2p_domain + users_path | 
					
						
							|  |  |  |         print('WARN: unable to find nickname in ' + origin_path_str) | 
					
						
							|  |  |  |         redirect_headers(self, origin_path_str, | 
					
						
							| 
									
										
										
										
											2024-04-16 13:47:21 +00:00
										 |  |  |                          cookie, calling_domain, 303) | 
					
						
							| 
									
										
										
										
											2024-03-03 22:01:22 +00:00
										 |  |  |         self.server.postreq_busy = False | 
					
						
							|  |  |  |         return | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     length = int(self.headers['Content-length']) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     try: | 
					
						
							|  |  |  |         block_confirm_params = self.rfile.read(length).decode('utf-8') | 
					
						
							|  |  |  |     except SocketError as ex: | 
					
						
							|  |  |  |         if ex.errno == errno.ECONNRESET: | 
					
						
							|  |  |  |             print('EX: POST block_confirm_params ' + | 
					
						
							|  |  |  |                   'connection was reset') | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             print('EX: POST block_confirm_params socket error') | 
					
						
							|  |  |  |         self.send_response(400) | 
					
						
							|  |  |  |         self.end_headers() | 
					
						
							|  |  |  |         self.server.postreq_busy = False | 
					
						
							|  |  |  |         return | 
					
						
							|  |  |  |     except ValueError as ex: | 
					
						
							|  |  |  |         print('EX: POST block_confirm_params rfile.read failed, ' + | 
					
						
							|  |  |  |               str(ex)) | 
					
						
							|  |  |  |         self.send_response(400) | 
					
						
							|  |  |  |         self.end_headers() | 
					
						
							|  |  |  |         self.server.postreq_busy = False | 
					
						
							|  |  |  |         return | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if '&submitYes=' in block_confirm_params: | 
					
						
							|  |  |  |         blocking_actor = \ | 
					
						
							|  |  |  |             urllib.parse.unquote_plus(block_confirm_params) | 
					
						
							|  |  |  |         blocking_actor = blocking_actor.split('actor=')[1] | 
					
						
							|  |  |  |         if '&' in blocking_actor: | 
					
						
							|  |  |  |             blocking_actor = blocking_actor.split('&')[0] | 
					
						
							|  |  |  |         blocking_nickname = get_nickname_from_actor(blocking_actor) | 
					
						
							|  |  |  |         blocking_domain, blocking_port = \ | 
					
						
							|  |  |  |             get_domain_from_actor(blocking_actor) | 
					
						
							|  |  |  |         if not blocking_nickname or not blocking_domain: | 
					
						
							|  |  |  |             if calling_domain.endswith('.onion') and onion_domain: | 
					
						
							|  |  |  |                 origin_path_str = 'http://' + onion_domain + users_path | 
					
						
							|  |  |  |             elif (calling_domain.endswith('.i2p') and i2p_domain): | 
					
						
							|  |  |  |                 origin_path_str = 'http://' + i2p_domain + users_path | 
					
						
							|  |  |  |             print('WARN: unable to find nickname in ' + blocking_actor) | 
					
						
							|  |  |  |             redirect_headers(self, origin_path_str, | 
					
						
							| 
									
										
										
										
											2024-04-16 13:47:21 +00:00
										 |  |  |                              cookie, calling_domain, 303) | 
					
						
							| 
									
										
										
										
											2024-03-03 22:01:22 +00:00
										 |  |  |             self.server.postreq_busy = False | 
					
						
							|  |  |  |             return | 
					
						
							|  |  |  |         blocking_domain_full = \ | 
					
						
							|  |  |  |             get_full_domain(blocking_domain, blocking_port) | 
					
						
							|  |  |  |         if blocker_nickname == blocking_nickname and \ | 
					
						
							|  |  |  |            blocking_domain == domain and \ | 
					
						
							|  |  |  |            blocking_port == port: | 
					
						
							|  |  |  |             if debug: | 
					
						
							|  |  |  |                 print('You cannot unblock yourself!') | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             if debug: | 
					
						
							|  |  |  |                 print(blocker_nickname + ' stops blocking ' + | 
					
						
							|  |  |  |                       blocking_actor) | 
					
						
							|  |  |  |             remove_block(base_dir, | 
					
						
							|  |  |  |                          blocker_nickname, domain, | 
					
						
							|  |  |  |                          blocking_nickname, blocking_domain_full) | 
					
						
							|  |  |  |             if is_moderator(base_dir, blocker_nickname): | 
					
						
							|  |  |  |                 remove_global_block(base_dir, | 
					
						
							|  |  |  |                                     blocking_nickname, | 
					
						
							|  |  |  |                                     blocking_domain_full) | 
					
						
							|  |  |  |                 blocked_cache_last_updated = \ | 
					
						
							|  |  |  |                     self.server.blocked_cache_last_updated | 
					
						
							|  |  |  |                 self.server.blocked_cache_last_updated = \ | 
					
						
							| 
									
										
										
										
											2024-04-08 09:33:48 +00:00
										 |  |  |                     update_blocked_cache(base_dir, | 
					
						
							| 
									
										
										
										
											2024-03-03 22:01:22 +00:00
										 |  |  |                                          self.server.blocked_cache, | 
					
						
							|  |  |  |                                          blocked_cache_last_updated, 0) | 
					
						
							|  |  |  |     if calling_domain.endswith('.onion') and onion_domain: | 
					
						
							|  |  |  |         origin_path_str = 'http://' + onion_domain + users_path | 
					
						
							|  |  |  |     elif (calling_domain.endswith('.i2p') and i2p_domain): | 
					
						
							|  |  |  |         origin_path_str = 'http://' + i2p_domain + users_path | 
					
						
							|  |  |  |     redirect_headers(self, origin_path_str, | 
					
						
							| 
									
										
										
										
											2024-04-16 13:47:21 +00:00
										 |  |  |                      cookie, calling_domain, 303) | 
					
						
							| 
									
										
										
										
											2024-03-03 22:01:22 +00:00
										 |  |  |     self.server.postreq_busy = False |