| 
									
										
										
										
											2020-04-01 19:11:39 +00:00
										 |  |  | __filename__ = "announce.py" | 
					
						
							|  |  |  | __author__ = "Bob Mottram" | 
					
						
							|  |  |  | __license__ = "AGPL3+" | 
					
						
							| 
									
										
										
										
											2022-02-03 13:58:20 +00:00
										 |  |  | __version__ = "1.3.0" | 
					
						
							| 
									
										
										
										
											2020-04-01 19:11:39 +00:00
										 |  |  | __maintainer__ = "Bob Mottram" | 
					
						
							| 
									
										
										
										
											2021-09-10 16:14:50 +00:00
										 |  |  | __email__ = "bob@libreserver.org" | 
					
						
							| 
									
										
										
										
											2020-04-01 19:11:39 +00:00
										 |  |  | __status__ = "Production" | 
					
						
							| 
									
										
										
										
											2021-06-15 15:08:12 +00:00
										 |  |  | __module_group__ = "ActivityPub" | 
					
						
							| 
									
										
										
										
											2019-07-02 09:25:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-26 15:54:46 +00:00
										 |  |  | from utils import has_object_string_object | 
					
						
							| 
									
										
										
										
											2021-12-26 17:53:07 +00:00
										 |  |  | from utils import has_group_type | 
					
						
							| 
									
										
										
										
											2022-03-02 13:49:51 +00:00
										 |  |  | from utils import has_object_dict | 
					
						
							| 
									
										
										
										
											2021-12-26 18:17:37 +00:00
										 |  |  | from utils import remove_domain_port | 
					
						
							| 
									
										
										
										
											2021-12-27 11:20:57 +00:00
										 |  |  | from utils import remove_id_ending | 
					
						
							| 
									
										
										
										
											2021-12-26 12:19:00 +00:00
										 |  |  | from utils import has_users_path | 
					
						
							| 
									
										
										
										
											2021-12-26 12:45:03 +00:00
										 |  |  | from utils import get_full_domain | 
					
						
							| 
									
										
										
										
											2021-12-27 17:42:35 +00:00
										 |  |  | from utils import get_status_number | 
					
						
							| 
									
										
										
										
											2021-12-27 17:57:27 +00:00
										 |  |  | from utils import create_outbox_dir | 
					
						
							| 
									
										
										
										
											2021-12-27 20:47:05 +00:00
										 |  |  | from utils import url_permitted | 
					
						
							| 
									
										
										
										
											2021-12-27 22:19:18 +00:00
										 |  |  | from utils import get_nickname_from_actor | 
					
						
							| 
									
										
										
										
											2021-12-27 19:05:25 +00:00
										 |  |  | from utils import get_domain_from_actor | 
					
						
							| 
									
										
										
										
											2021-12-26 20:36:08 +00:00
										 |  |  | from utils import locate_post | 
					
						
							| 
									
										
										
										
											2021-12-26 14:47:21 +00:00
										 |  |  | from utils import save_json | 
					
						
							| 
									
										
										
										
											2021-12-27 10:55:48 +00:00
										 |  |  | from utils import undo_announce_collection_entry | 
					
						
							| 
									
										
										
										
											2021-12-26 23:41:34 +00:00
										 |  |  | from utils import update_announce_collection | 
					
						
							| 
									
										
										
										
											2021-12-26 10:19:59 +00:00
										 |  |  | from utils import local_actor_url | 
					
						
							| 
									
										
										
										
											2021-12-26 17:21:37 +00:00
										 |  |  | from utils import replace_users_with_at | 
					
						
							| 
									
										
										
										
											2021-12-26 17:15:04 +00:00
										 |  |  | from utils import has_actor | 
					
						
							| 
									
										
										
										
											2022-04-09 15:11:22 +00:00
										 |  |  | from utils import has_object_string_type | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  | from posts import send_signed_json | 
					
						
							|  |  |  | from posts import get_person_box | 
					
						
							|  |  |  | from session import post_json | 
					
						
							|  |  |  | from webfinger import webfinger_handle | 
					
						
							| 
									
										
										
										
											2021-12-28 21:36:27 +00:00
										 |  |  | from auth import create_basic_auth_header | 
					
						
							| 
									
										
										
										
											2019-07-02 09:25:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-01 19:11:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-02 13:49:51 +00:00
										 |  |  | def no_of_announces(post_json_object: {}) -> int: | 
					
						
							|  |  |  |     """Returns the number of announces on a given post
 | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     obj = post_json_object | 
					
						
							|  |  |  |     if has_object_dict(post_json_object): | 
					
						
							|  |  |  |         obj = post_json_object['object'] | 
					
						
							|  |  |  |     if not obj.get('shares'): | 
					
						
							|  |  |  |         return 0 | 
					
						
							|  |  |  |     if not isinstance(obj['shares'], dict): | 
					
						
							|  |  |  |         return 0 | 
					
						
							|  |  |  |     if not obj['shares'].get('items'): | 
					
						
							|  |  |  |         obj['shares']['items'] = [] | 
					
						
							|  |  |  |         obj['shares']['totalItems'] = 0 | 
					
						
							|  |  |  |     return len(obj['shares']['items']) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  | def is_self_announce(post_json_object: {}) -> bool: | 
					
						
							| 
									
										
										
										
											2021-06-22 19:43:03 +00:00
										 |  |  |     """Is the given post a self announce?
 | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2021-12-25 22:09:19 +00:00
										 |  |  |     if not post_json_object.get('actor'): | 
					
						
							| 
									
										
										
										
											2021-06-22 19:43:03 +00:00
										 |  |  |         return False | 
					
						
							| 
									
										
										
										
											2021-12-25 22:09:19 +00:00
										 |  |  |     if not post_json_object.get('type'): | 
					
						
							| 
									
										
										
										
											2021-06-22 19:43:03 +00:00
										 |  |  |         return False | 
					
						
							| 
									
										
										
										
											2021-12-25 22:09:19 +00:00
										 |  |  |     if post_json_object['type'] != 'Announce': | 
					
						
							| 
									
										
										
										
											2021-06-22 19:43:03 +00:00
										 |  |  |         return False | 
					
						
							| 
									
										
										
										
											2021-12-25 22:09:19 +00:00
										 |  |  |     if not post_json_object.get('object'): | 
					
						
							| 
									
										
										
										
											2021-06-22 19:43:03 +00:00
										 |  |  |         return False | 
					
						
							| 
									
										
										
										
											2021-12-25 22:09:19 +00:00
										 |  |  |     if not isinstance(post_json_object['actor'], str): | 
					
						
							| 
									
										
										
										
											2021-06-22 19:43:03 +00:00
										 |  |  |         return False | 
					
						
							| 
									
										
										
										
											2021-12-25 22:09:19 +00:00
										 |  |  |     if not isinstance(post_json_object['object'], str): | 
					
						
							| 
									
										
										
										
											2021-06-22 19:43:03 +00:00
										 |  |  |         return False | 
					
						
							| 
									
										
										
										
											2021-12-25 22:09:19 +00:00
										 |  |  |     return post_json_object['actor'] in post_json_object['object'] | 
					
						
							| 
									
										
										
										
											2021-06-22 19:43:03 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  | def outbox_announce(recent_posts_cache: {}, | 
					
						
							|  |  |  |                     base_dir: str, message_json: {}, debug: bool) -> bool: | 
					
						
							| 
									
										
										
										
											2019-08-01 11:43:22 +00:00
										 |  |  |     """ Adds or removes announce entries from the shares collection
 | 
					
						
							|  |  |  |     within a given post | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2021-12-26 17:15:04 +00:00
										 |  |  |     if not has_actor(message_json, debug): | 
					
						
							| 
									
										
										
										
											2019-08-01 11:43:22 +00:00
										 |  |  |         return False | 
					
						
							| 
									
										
										
										
											2021-12-25 23:51:19 +00:00
										 |  |  |     if not isinstance(message_json['actor'], str): | 
					
						
							| 
									
										
										
										
											2021-06-03 08:33:50 +00:00
										 |  |  |         return False | 
					
						
							| 
									
										
										
										
											2021-12-25 23:51:19 +00:00
										 |  |  |     if not message_json.get('type'): | 
					
						
							| 
									
										
										
										
											2019-08-01 11:43:22 +00:00
										 |  |  |         return False | 
					
						
							| 
									
										
										
										
											2021-12-25 23:51:19 +00:00
										 |  |  |     if not message_json.get('object'): | 
					
						
							| 
									
										
										
										
											2019-08-01 11:43:22 +00:00
										 |  |  |         return False | 
					
						
							| 
									
										
										
										
											2021-12-25 23:51:19 +00:00
										 |  |  |     if message_json['type'] == 'Announce': | 
					
						
							|  |  |  |         if not isinstance(message_json['object'], str): | 
					
						
							| 
									
										
										
										
											2019-09-02 09:43:43 +00:00
										 |  |  |             return False | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |         if is_self_announce(message_json): | 
					
						
							| 
									
										
										
										
											2021-06-03 08:33:50 +00:00
										 |  |  |             return False | 
					
						
							| 
									
										
										
										
											2021-12-27 22:19:18 +00:00
										 |  |  |         nickname = get_nickname_from_actor(message_json['actor']) | 
					
						
							| 
									
										
										
										
											2019-09-02 09:43:43 +00:00
										 |  |  |         if not nickname: | 
					
						
							| 
									
										
										
										
											2021-12-25 23:51:19 +00:00
										 |  |  |             print('WARN: no nickname found in ' + message_json['actor']) | 
					
						
							| 
									
										
										
										
											2019-09-02 09:43:43 +00:00
										 |  |  |             return False | 
					
						
							| 
									
										
										
										
											2021-12-27 19:05:25 +00:00
										 |  |  |         domain, _ = get_domain_from_actor(message_json['actor']) | 
					
						
							| 
									
										
										
										
											2021-12-26 23:41:34 +00:00
										 |  |  |         post_filename = locate_post(base_dir, nickname, domain, | 
					
						
							|  |  |  |                                     message_json['object']) | 
					
						
							|  |  |  |         if post_filename: | 
					
						
							|  |  |  |             update_announce_collection(recent_posts_cache, | 
					
						
							|  |  |  |                                        base_dir, post_filename, | 
					
						
							|  |  |  |                                        message_json['actor'], | 
					
						
							|  |  |  |                                        nickname, domain, debug) | 
					
						
							| 
									
										
										
										
											2019-08-01 11:43:22 +00:00
										 |  |  |             return True | 
					
						
							| 
									
										
										
										
											2021-12-25 23:51:19 +00:00
										 |  |  |     elif message_json['type'] == 'Undo': | 
					
						
							| 
									
										
										
										
											2022-04-09 15:11:22 +00:00
										 |  |  |         if not has_object_string_type(message_json, debug): | 
					
						
							| 
									
										
										
										
											2019-08-01 11:43:22 +00:00
										 |  |  |             return False | 
					
						
							| 
									
										
										
										
											2021-12-25 23:51:19 +00:00
										 |  |  |         if message_json['object']['type'] == 'Announce': | 
					
						
							|  |  |  |             if not isinstance(message_json['object']['object'], str): | 
					
						
							| 
									
										
										
										
											2019-09-02 09:43:43 +00:00
										 |  |  |                 return False | 
					
						
							| 
									
										
										
										
											2021-12-27 22:19:18 +00:00
										 |  |  |             nickname = get_nickname_from_actor(message_json['actor']) | 
					
						
							| 
									
										
										
										
											2019-09-02 09:43:43 +00:00
										 |  |  |             if not nickname: | 
					
						
							| 
									
										
										
										
											2021-12-25 23:51:19 +00:00
										 |  |  |                 print('WARN: no nickname found in ' + message_json['actor']) | 
					
						
							| 
									
										
										
										
											2019-09-02 09:43:43 +00:00
										 |  |  |                 return False | 
					
						
							| 
									
										
										
										
											2021-12-27 19:05:25 +00:00
										 |  |  |             domain, _ = get_domain_from_actor(message_json['actor']) | 
					
						
							| 
									
										
										
										
											2021-12-26 23:41:34 +00:00
										 |  |  |             post_filename = locate_post(base_dir, nickname, domain, | 
					
						
							|  |  |  |                                         message_json['object']['object']) | 
					
						
							|  |  |  |             if post_filename: | 
					
						
							| 
									
										
										
										
											2021-12-27 10:55:48 +00:00
										 |  |  |                 undo_announce_collection_entry(recent_posts_cache, | 
					
						
							|  |  |  |                                                base_dir, post_filename, | 
					
						
							|  |  |  |                                                message_json['actor'], | 
					
						
							|  |  |  |                                                domain, debug) | 
					
						
							| 
									
										
										
										
											2019-08-01 11:43:22 +00:00
										 |  |  |                 return True | 
					
						
							|  |  |  |     return False | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-01 19:11:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-29 22:45:26 +00:00
										 |  |  | def announced_by_person(is_announced: bool, post_actor: str, | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |                         nickname: str, domain_full: str) -> bool: | 
					
						
							| 
									
										
										
										
											2019-08-01 09:31:38 +00:00
										 |  |  |     """Returns True if the given post is announced by the given person
 | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2021-12-29 22:45:26 +00:00
										 |  |  |     if not post_actor: | 
					
						
							| 
									
										
										
										
											2021-05-07 13:26:00 +00:00
										 |  |  |         return False | 
					
						
							| 
									
										
										
										
											2021-12-29 22:45:26 +00:00
										 |  |  |     if is_announced and \ | 
					
						
							|  |  |  |        post_actor.endswith(domain_full + '/users/' + nickname): | 
					
						
							| 
									
										
										
										
											2021-05-07 21:10:55 +00:00
										 |  |  |         return True | 
					
						
							| 
									
										
										
										
											2019-08-01 09:31:38 +00:00
										 |  |  |     return False | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-01 19:11:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  | def create_announce(session, base_dir: str, federation_list: [], | 
					
						
							|  |  |  |                     nickname: str, domain: str, port: int, | 
					
						
							| 
									
										
										
										
											2021-12-29 22:45:26 +00:00
										 |  |  |                     to_url: str, ccUrl: str, http_prefix: str, | 
					
						
							|  |  |  |                     object_url: str, saveToFile: bool, | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |                     client_to_server: bool, | 
					
						
							|  |  |  |                     send_threads: [], postLog: [], | 
					
						
							|  |  |  |                     person_cache: {}, cached_webfingers: {}, | 
					
						
							|  |  |  |                     debug: bool, project_version: str, | 
					
						
							| 
									
										
										
										
											2022-03-13 20:16:39 +00:00
										 |  |  |                     signing_priv_key_pem: str, | 
					
						
							|  |  |  |                     curr_domain: str, | 
					
						
							|  |  |  |                     onion_domain: str, i2p_domain: str) -> {}: | 
					
						
							| 
									
										
										
										
											2019-07-02 09:25:29 +00:00
										 |  |  |     """Creates an announce message
 | 
					
						
							| 
									
										
										
										
											2021-12-29 22:45:26 +00:00
										 |  |  |     Typically to_url will be https://www.w3.org/ns/activitystreams#Public | 
					
						
							| 
									
										
										
										
											2019-07-06 17:00:22 +00:00
										 |  |  |     and ccUrl might be a specific person favorited or repeated and the | 
					
						
							| 
									
										
										
										
											2021-12-29 22:45:26 +00:00
										 |  |  |     followers url object_url is typically the url of the message, | 
					
						
							| 
									
										
										
										
											2019-07-06 17:00:22 +00:00
										 |  |  |     corresponding to url or atomUri in createPostBase | 
					
						
							| 
									
										
										
										
											2019-07-02 09:25:29 +00:00
										 |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2021-12-29 22:45:26 +00:00
										 |  |  |     if not url_permitted(object_url, federation_list): | 
					
						
							| 
									
										
										
										
											2019-07-02 10:43:54 +00:00
										 |  |  |         return None | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-26 18:17:37 +00:00
										 |  |  |     domain = remove_domain_port(domain) | 
					
						
							| 
									
										
										
										
											2021-12-29 22:45:26 +00:00
										 |  |  |     full_domain = get_full_domain(domain, port) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     status_number, published = get_status_number() | 
					
						
							|  |  |  |     new_announce_id = http_prefix + '://' + full_domain + \ | 
					
						
							|  |  |  |         '/users/' + nickname + '/statuses/' + status_number | 
					
						
							|  |  |  |     atom_uri_str = local_actor_url(http_prefix, nickname, full_domain) + \ | 
					
						
							|  |  |  |         '/statuses/' + status_number | 
					
						
							|  |  |  |     new_announce = { | 
					
						
							| 
									
										
										
										
											2019-08-18 11:07:06 +00:00
										 |  |  |         "@context": "https://www.w3.org/ns/activitystreams", | 
					
						
							| 
									
										
										
										
											2021-12-29 22:45:26 +00:00
										 |  |  |         'actor': local_actor_url(http_prefix, nickname, full_domain), | 
					
						
							|  |  |  |         'atomUri': atom_uri_str, | 
					
						
							| 
									
										
										
										
											2019-07-02 09:25:29 +00:00
										 |  |  |         'cc': [], | 
					
						
							| 
									
										
										
										
											2021-12-29 22:45:26 +00:00
										 |  |  |         'id': new_announce_id + '/activity', | 
					
						
							|  |  |  |         'object': object_url, | 
					
						
							| 
									
										
										
										
											2019-07-02 09:25:29 +00:00
										 |  |  |         'published': published, | 
					
						
							| 
									
										
										
										
											2021-12-29 22:45:26 +00:00
										 |  |  |         'to': [to_url], | 
					
						
							| 
									
										
										
										
											2019-07-02 09:25:29 +00:00
										 |  |  |         'type': 'Announce' | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if ccUrl: | 
					
						
							| 
									
										
										
										
											2020-04-01 19:11:39 +00:00
										 |  |  |         if len(ccUrl) > 0: | 
					
						
							| 
									
										
										
										
											2021-12-29 22:45:26 +00:00
										 |  |  |             new_announce['cc'] = [ccUrl] | 
					
						
							| 
									
										
										
										
											2019-07-02 09:25:29 +00:00
										 |  |  |     if saveToFile: | 
					
						
							| 
									
										
										
										
											2021-12-29 22:45:26 +00:00
										 |  |  |         outbox_dir = create_outbox_dir(nickname, domain, base_dir) | 
					
						
							|  |  |  |         filename = \ | 
					
						
							|  |  |  |             outbox_dir + '/' + new_announce_id.replace('/', '#') + '.json' | 
					
						
							|  |  |  |         save_json(new_announce, filename) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     announce_nickname = None | 
					
						
							|  |  |  |     announce_domain = None | 
					
						
							|  |  |  |     announce_port = None | 
					
						
							| 
									
										
										
										
											2021-12-26 00:07:44 +00:00
										 |  |  |     group_account = False | 
					
						
							| 
									
										
										
										
											2021-12-29 22:45:26 +00:00
										 |  |  |     if has_users_path(object_url): | 
					
						
							|  |  |  |         announce_nickname = get_nickname_from_actor(object_url) | 
					
						
							| 
									
										
										
										
											2022-03-23 23:59:29 +00:00
										 |  |  |         if announce_nickname: | 
					
						
							|  |  |  |             announce_domain, announce_port = get_domain_from_actor(object_url) | 
					
						
							|  |  |  |             if '/' + str(announce_nickname) + '/' in object_url: | 
					
						
							|  |  |  |                 announce_actor = \ | 
					
						
							|  |  |  |                     object_url.split('/' + announce_nickname + '/')[0] + \ | 
					
						
							|  |  |  |                     '/' + announce_nickname | 
					
						
							|  |  |  |                 if has_group_type(base_dir, announce_actor, person_cache): | 
					
						
							|  |  |  |                     group_account = True | 
					
						
							| 
									
										
										
										
											2019-07-11 17:55:10 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-29 22:45:26 +00:00
										 |  |  |     if announce_nickname and announce_domain: | 
					
						
							|  |  |  |         send_signed_json(new_announce, session, base_dir, | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |                          nickname, domain, port, | 
					
						
							| 
									
										
										
										
											2021-12-29 22:45:26 +00:00
										 |  |  |                          announce_nickname, announce_domain, | 
					
						
							|  |  |  |                          announce_port, None, | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |                          http_prefix, True, client_to_server, federation_list, | 
					
						
							|  |  |  |                          send_threads, postLog, cached_webfingers, | 
					
						
							|  |  |  |                          person_cache, | 
					
						
							|  |  |  |                          debug, project_version, None, group_account, | 
					
						
							| 
									
										
										
										
											2022-03-13 20:16:39 +00:00
										 |  |  |                          signing_priv_key_pem, 639633, | 
					
						
							|  |  |  |                          curr_domain, onion_domain, i2p_domain) | 
					
						
							| 
									
										
										
										
											2020-03-22 21:16:02 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-29 22:45:26 +00:00
										 |  |  |     return new_announce | 
					
						
							| 
									
										
										
										
											2019-07-02 09:25:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-01 19:11:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  | def announce_public(session, base_dir: str, federation_list: [], | 
					
						
							|  |  |  |                     nickname: str, domain: str, port: int, http_prefix: str, | 
					
						
							| 
									
										
										
										
											2021-12-29 22:45:26 +00:00
										 |  |  |                     object_url: str, client_to_server: bool, | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |                     send_threads: [], postLog: [], | 
					
						
							|  |  |  |                     person_cache: {}, cached_webfingers: {}, | 
					
						
							|  |  |  |                     debug: bool, project_version: str, | 
					
						
							| 
									
										
										
										
											2022-03-13 20:16:39 +00:00
										 |  |  |                     signing_priv_key_pem: str, | 
					
						
							|  |  |  |                     curr_domain: str, | 
					
						
							|  |  |  |                     onion_domain: str, i2p_domain: str) -> {}: | 
					
						
							| 
									
										
										
										
											2019-07-02 09:25:29 +00:00
										 |  |  |     """Makes a public announcement
 | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2021-12-29 22:45:26 +00:00
										 |  |  |     from_domain = get_full_domain(domain, port) | 
					
						
							| 
									
										
										
										
											2020-04-01 19:11:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-29 22:45:26 +00:00
										 |  |  |     to_url = 'https://www.w3.org/ns/activitystreams#Public' | 
					
						
							|  |  |  |     ccUrl = local_actor_url(http_prefix, nickname, from_domain) + '/followers' | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |     return create_announce(session, base_dir, federation_list, | 
					
						
							|  |  |  |                            nickname, domain, port, | 
					
						
							| 
									
										
										
										
											2021-12-29 22:45:26 +00:00
										 |  |  |                            to_url, ccUrl, http_prefix, | 
					
						
							|  |  |  |                            object_url, True, client_to_server, | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |                            send_threads, postLog, | 
					
						
							|  |  |  |                            person_cache, cached_webfingers, | 
					
						
							|  |  |  |                            debug, project_version, | 
					
						
							| 
									
										
										
										
											2022-03-13 20:16:39 +00:00
										 |  |  |                            signing_priv_key_pem, curr_domain, | 
					
						
							|  |  |  |                            onion_domain, i2p_domain) | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def send_announce_via_server(base_dir: str, session, | 
					
						
							| 
									
										
										
										
											2022-05-26 22:52:32 +00:00
										 |  |  |                              from_nickname: str, password: str, | 
					
						
							| 
									
										
										
										
											2021-12-29 22:45:26 +00:00
										 |  |  |                              from_domain: str, fromPort: int, | 
					
						
							|  |  |  |                              http_prefix: str, repeat_object_url: str, | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |                              cached_webfingers: {}, person_cache: {}, | 
					
						
							|  |  |  |                              debug: bool, project_version: str, | 
					
						
							|  |  |  |                              signing_priv_key_pem: str) -> {}: | 
					
						
							| 
									
										
										
										
											2019-07-16 19:07:45 +00:00
										 |  |  |     """Creates an announce message via c2s
 | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     if not session: | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |         print('WARN: No session for send_announce_via_server') | 
					
						
							| 
									
										
										
										
											2019-07-16 19:07:45 +00:00
										 |  |  |         return 6 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-29 22:45:26 +00:00
										 |  |  |     from_domain_full = get_full_domain(from_domain, fromPort) | 
					
						
							| 
									
										
										
										
											2019-07-16 19:07:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-29 22:45:26 +00:00
										 |  |  |     to_url = 'https://www.w3.org/ns/activitystreams#Public' | 
					
						
							| 
									
										
										
										
											2022-05-26 22:52:32 +00:00
										 |  |  |     actor_str = local_actor_url(http_prefix, from_nickname, from_domain_full) | 
					
						
							| 
									
										
										
										
											2021-12-29 22:45:26 +00:00
										 |  |  |     cc_url = actor_str + '/followers' | 
					
						
							| 
									
										
										
										
											2019-07-16 19:07:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-29 22:45:26 +00:00
										 |  |  |     status_number, published = get_status_number() | 
					
						
							|  |  |  |     new_announce_id = actor_str + '/statuses/' + status_number | 
					
						
							|  |  |  |     new_announce_json = { | 
					
						
							| 
									
										
										
										
											2019-08-18 11:07:06 +00:00
										 |  |  |         "@context": "https://www.w3.org/ns/activitystreams", | 
					
						
							| 
									
										
										
										
											2021-12-29 22:45:26 +00:00
										 |  |  |         'actor': actor_str, | 
					
						
							|  |  |  |         'atomUri': new_announce_id, | 
					
						
							|  |  |  |         'cc': [cc_url], | 
					
						
							|  |  |  |         'id': new_announce_id + '/activity', | 
					
						
							|  |  |  |         'object': repeat_object_url, | 
					
						
							| 
									
										
										
										
											2019-07-16 19:07:45 +00:00
										 |  |  |         'published': published, | 
					
						
							| 
									
										
										
										
											2021-12-29 22:45:26 +00:00
										 |  |  |         'to': [to_url], | 
					
						
							| 
									
										
										
										
											2019-07-16 19:07:45 +00:00
										 |  |  |         'type': 'Announce' | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-26 22:52:32 +00:00
										 |  |  |     handle = http_prefix + '://' + from_domain_full + '/@' + from_nickname | 
					
						
							| 
									
										
										
										
											2019-07-16 19:07:45 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # lookup the inbox for the To handle | 
					
						
							| 
									
										
										
										
											2021-12-29 22:45:26 +00:00
										 |  |  |     wf_request = webfinger_handle(session, handle, http_prefix, | 
					
						
							|  |  |  |                                   cached_webfingers, | 
					
						
							|  |  |  |                                   from_domain, project_version, debug, False, | 
					
						
							|  |  |  |                                   signing_priv_key_pem) | 
					
						
							|  |  |  |     if not wf_request: | 
					
						
							| 
									
										
										
										
											2019-07-16 19:07:45 +00:00
										 |  |  |         if debug: | 
					
						
							| 
									
										
										
										
											2020-04-01 19:11:39 +00:00
										 |  |  |             print('DEBUG: announce webfinger failed for ' + handle) | 
					
						
							| 
									
										
										
										
											2019-07-16 19:07:45 +00:00
										 |  |  |         return 1 | 
					
						
							| 
									
										
										
										
											2021-12-29 22:45:26 +00:00
										 |  |  |     if not isinstance(wf_request, dict): | 
					
						
							| 
									
										
										
										
											2021-03-18 10:01:01 +00:00
										 |  |  |         print('WARN: announce webfinger for ' + handle + | 
					
						
							| 
									
										
										
										
											2021-12-29 22:45:26 +00:00
										 |  |  |               ' did not return a dict. ' + str(wf_request)) | 
					
						
							| 
									
										
										
										
											2020-06-23 10:41:12 +00:00
										 |  |  |         return 1 | 
					
						
							| 
									
										
										
										
											2019-07-16 19:07:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-29 22:45:26 +00:00
										 |  |  |     post_to_box = 'outbox' | 
					
						
							| 
									
										
										
										
											2019-07-16 19:07:45 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # get the actor inbox for the To handle | 
					
						
							| 
									
										
										
										
											2021-12-29 22:45:26 +00:00
										 |  |  |     origin_domain = from_domain | 
					
						
							|  |  |  |     (inbox_url, _, _, from_person_id, | 
					
						
							|  |  |  |      _, _, _, _) = get_person_box(signing_priv_key_pem, | 
					
						
							|  |  |  |                                   origin_domain, | 
					
						
							|  |  |  |                                   base_dir, session, wf_request, | 
					
						
							|  |  |  |                                   person_cache, | 
					
						
							|  |  |  |                                   project_version, http_prefix, | 
					
						
							| 
									
										
										
										
											2022-05-26 22:52:32 +00:00
										 |  |  |                                   from_nickname, from_domain, | 
					
						
							| 
									
										
										
										
											2021-12-29 22:45:26 +00:00
										 |  |  |                                   post_to_box, 73528) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if not inbox_url: | 
					
						
							| 
									
										
										
										
											2019-07-16 19:07:45 +00:00
										 |  |  |         if debug: | 
					
						
							| 
									
										
										
										
											2021-12-29 22:45:26 +00:00
										 |  |  |             print('DEBUG: announce no ' + post_to_box + | 
					
						
							| 
									
										
										
										
											2021-03-18 10:01:01 +00:00
										 |  |  |                   ' was found for ' + handle) | 
					
						
							| 
									
										
										
										
											2019-07-16 19:07:45 +00:00
										 |  |  |         return 3 | 
					
						
							| 
									
										
										
										
											2021-12-29 22:45:26 +00:00
										 |  |  |     if not from_person_id: | 
					
						
							| 
									
										
										
										
											2019-07-16 19:07:45 +00:00
										 |  |  |         if debug: | 
					
						
							| 
									
										
										
										
											2021-03-18 10:01:01 +00:00
										 |  |  |             print('DEBUG: announce no actor was found for ' + handle) | 
					
						
							| 
									
										
										
										
											2019-07-16 19:07:45 +00:00
										 |  |  |         return 4 | 
					
						
							| 
									
										
										
										
											2020-03-22 21:16:02 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-26 22:52:32 +00:00
										 |  |  |     auth_header = create_basic_auth_header(from_nickname, password) | 
					
						
							| 
									
										
										
										
											2020-03-22 21:16:02 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-01 19:11:39 +00:00
										 |  |  |     headers = { | 
					
						
							| 
									
										
										
										
											2021-12-29 22:45:26 +00:00
										 |  |  |         'host': from_domain, | 
					
						
							| 
									
										
										
										
											2020-04-01 19:11:39 +00:00
										 |  |  |         'Content-type': 'application/json', | 
					
						
							| 
									
										
										
										
											2021-12-29 22:45:26 +00:00
										 |  |  |         'Authorization': auth_header | 
					
						
							| 
									
										
										
										
											2020-03-22 20:36:19 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-12-29 22:45:26 +00:00
										 |  |  |     post_result = post_json(http_prefix, from_domain_full, | 
					
						
							|  |  |  |                             session, new_announce_json, [], inbox_url, | 
					
						
							|  |  |  |                             headers, 3, True) | 
					
						
							|  |  |  |     if not post_result: | 
					
						
							| 
									
										
										
										
											2021-03-18 10:01:01 +00:00
										 |  |  |         print('WARN: announce not posted') | 
					
						
							| 
									
										
										
										
											2019-07-16 19:07:45 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if debug: | 
					
						
							|  |  |  |         print('DEBUG: c2s POST announce success') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-29 22:45:26 +00:00
										 |  |  |     return new_announce_json | 
					
						
							| 
									
										
										
										
											2021-03-18 20:56:08 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  | def send_undo_announce_via_server(base_dir: str, session, | 
					
						
							| 
									
										
										
										
											2021-12-29 22:45:26 +00:00
										 |  |  |                                   undo_post_json_object: {}, | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |                                   nickname: str, password: str, | 
					
						
							|  |  |  |                                   domain: str, port: int, | 
					
						
							| 
									
										
										
										
											2021-12-29 22:45:26 +00:00
										 |  |  |                                   http_prefix: str, repeat_object_url: str, | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |                                   cached_webfingers: {}, person_cache: {}, | 
					
						
							|  |  |  |                                   debug: bool, project_version: str, | 
					
						
							|  |  |  |                                   signing_priv_key_pem: str) -> {}: | 
					
						
							| 
									
										
										
										
											2021-03-18 20:56:08 +00:00
										 |  |  |     """Undo an announce message via c2s
 | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     if not session: | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |         print('WARN: No session for send_undo_announce_via_server') | 
					
						
							| 
									
										
										
										
											2021-03-18 20:56:08 +00:00
										 |  |  |         return 6 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-26 12:45:03 +00:00
										 |  |  |     domain_full = get_full_domain(domain, port) | 
					
						
							| 
									
										
										
										
											2021-03-18 20:56:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-26 10:19:59 +00:00
										 |  |  |     actor = local_actor_url(http_prefix, nickname, domain_full) | 
					
						
							| 
									
										
										
										
											2021-12-26 17:21:37 +00:00
										 |  |  |     handle = replace_users_with_at(actor) | 
					
						
							| 
									
										
										
										
											2021-03-18 20:56:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-29 22:45:26 +00:00
										 |  |  |     status_number, _ = get_status_number() | 
					
						
							|  |  |  |     unannounce_json = { | 
					
						
							| 
									
										
										
										
											2021-03-18 20:56:08 +00:00
										 |  |  |         '@context': 'https://www.w3.org/ns/activitystreams', | 
					
						
							| 
									
										
										
										
											2021-12-29 22:45:26 +00:00
										 |  |  |         'id': actor + '/statuses/' + str(status_number) + '/undo', | 
					
						
							| 
									
										
										
										
											2021-03-18 20:56:08 +00:00
										 |  |  |         'type': 'Undo', | 
					
						
							|  |  |  |         'actor': actor, | 
					
						
							| 
									
										
										
										
											2021-12-29 22:45:26 +00:00
										 |  |  |         'object': undo_post_json_object['object'] | 
					
						
							| 
									
										
										
										
											2021-03-18 20:56:08 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # lookup the inbox for the To handle | 
					
						
							| 
									
										
										
										
											2021-12-29 22:45:26 +00:00
										 |  |  |     wf_request = webfinger_handle(session, handle, http_prefix, | 
					
						
							|  |  |  |                                   cached_webfingers, | 
					
						
							|  |  |  |                                   domain, project_version, debug, False, | 
					
						
							|  |  |  |                                   signing_priv_key_pem) | 
					
						
							|  |  |  |     if not wf_request: | 
					
						
							| 
									
										
										
										
											2021-03-18 20:56:08 +00:00
										 |  |  |         if debug: | 
					
						
							|  |  |  |             print('DEBUG: undo announce webfinger failed for ' + handle) | 
					
						
							|  |  |  |         return 1 | 
					
						
							| 
									
										
										
										
											2021-12-29 22:45:26 +00:00
										 |  |  |     if not isinstance(wf_request, dict): | 
					
						
							| 
									
										
										
										
											2021-03-18 20:56:08 +00:00
										 |  |  |         print('WARN: undo announce webfinger for ' + handle + | 
					
						
							| 
									
										
										
										
											2021-12-29 22:45:26 +00:00
										 |  |  |               ' did not return a dict. ' + str(wf_request)) | 
					
						
							| 
									
										
										
										
											2021-03-18 20:56:08 +00:00
										 |  |  |         return 1 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-29 22:45:26 +00:00
										 |  |  |     post_to_box = 'outbox' | 
					
						
							| 
									
										
										
										
											2021-03-18 20:56:08 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # get the actor inbox for the To handle | 
					
						
							| 
									
										
										
										
											2021-12-29 22:45:26 +00:00
										 |  |  |     origin_domain = domain | 
					
						
							|  |  |  |     (inbox_url, _, _, from_person_id, | 
					
						
							|  |  |  |      _, _, _, _) = get_person_box(signing_priv_key_pem, | 
					
						
							|  |  |  |                                   origin_domain, | 
					
						
							|  |  |  |                                   base_dir, session, wf_request, | 
					
						
							|  |  |  |                                   person_cache, | 
					
						
							|  |  |  |                                   project_version, http_prefix, | 
					
						
							|  |  |  |                                   nickname, domain, | 
					
						
							|  |  |  |                                   post_to_box, 73528) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if not inbox_url: | 
					
						
							| 
									
										
										
										
											2021-03-18 20:56:08 +00:00
										 |  |  |         if debug: | 
					
						
							| 
									
										
										
										
											2021-12-29 22:45:26 +00:00
										 |  |  |             print('DEBUG: undo announce no ' + post_to_box + | 
					
						
							| 
									
										
										
										
											2021-03-18 20:56:08 +00:00
										 |  |  |                   ' was found for ' + handle) | 
					
						
							|  |  |  |         return 3 | 
					
						
							| 
									
										
										
										
											2021-12-29 22:45:26 +00:00
										 |  |  |     if not from_person_id: | 
					
						
							| 
									
										
										
										
											2021-03-18 20:56:08 +00:00
										 |  |  |         if debug: | 
					
						
							|  |  |  |             print('DEBUG: undo announce no actor was found for ' + handle) | 
					
						
							|  |  |  |         return 4 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-29 22:45:26 +00:00
										 |  |  |     auth_header = create_basic_auth_header(nickname, password) | 
					
						
							| 
									
										
										
										
											2021-03-18 20:56:08 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     headers = { | 
					
						
							|  |  |  |         'host': domain, | 
					
						
							|  |  |  |         'Content-type': 'application/json', | 
					
						
							| 
									
										
										
										
											2021-12-29 22:45:26 +00:00
										 |  |  |         'Authorization': auth_header | 
					
						
							| 
									
										
										
										
											2021-03-18 20:56:08 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-12-29 22:45:26 +00:00
										 |  |  |     post_result = post_json(http_prefix, domain_full, | 
					
						
							|  |  |  |                             session, unannounce_json, [], inbox_url, | 
					
						
							|  |  |  |                             headers, 3, True) | 
					
						
							|  |  |  |     if not post_result: | 
					
						
							| 
									
										
										
										
											2021-03-18 20:56:08 +00:00
										 |  |  |         print('WARN: undo announce not posted') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if debug: | 
					
						
							|  |  |  |         print('DEBUG: c2s POST undo announce success') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-29 22:45:26 +00:00
										 |  |  |     return unannounce_json | 
					
						
							| 
									
										
										
										
											2021-05-08 13:14:52 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  | def outbox_undo_announce(recent_posts_cache: {}, | 
					
						
							|  |  |  |                          base_dir: str, http_prefix: str, | 
					
						
							|  |  |  |                          nickname: str, domain: str, port: int, | 
					
						
							|  |  |  |                          message_json: {}, debug: bool) -> None: | 
					
						
							| 
									
										
										
										
											2021-05-08 13:14:52 +00:00
										 |  |  |     """ When an undo announce is received by the outbox from c2s
 | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2021-12-25 23:51:19 +00:00
										 |  |  |     if not message_json.get('type'): | 
					
						
							| 
									
										
										
										
											2021-05-08 13:14:52 +00:00
										 |  |  |         return | 
					
						
							| 
									
										
										
										
											2021-12-25 23:51:19 +00:00
										 |  |  |     if not message_json['type'] == 'Undo': | 
					
						
							| 
									
										
										
										
											2021-05-08 13:14:52 +00:00
										 |  |  |         return | 
					
						
							| 
									
										
										
										
											2022-04-09 15:11:22 +00:00
										 |  |  |     if not has_object_string_type(message_json, debug): | 
					
						
							| 
									
										
										
										
											2021-05-08 13:14:52 +00:00
										 |  |  |         return | 
					
						
							| 
									
										
										
										
											2021-12-25 23:51:19 +00:00
										 |  |  |     if not message_json['object']['type'] == 'Announce': | 
					
						
							| 
									
										
										
										
											2021-05-08 13:14:52 +00:00
										 |  |  |         if debug: | 
					
						
							|  |  |  |             print('DEBUG: not a undo announce') | 
					
						
							|  |  |  |         return | 
					
						
							| 
									
										
										
										
											2021-12-26 15:54:46 +00:00
										 |  |  |     if not has_object_string_object(message_json, debug): | 
					
						
							| 
									
										
										
										
											2021-05-08 13:14:52 +00:00
										 |  |  |         return | 
					
						
							|  |  |  |     if debug: | 
					
						
							|  |  |  |         print('DEBUG: c2s undo announce request arrived in outbox') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-29 22:45:26 +00:00
										 |  |  |     message_id = remove_id_ending(message_json['object']['object']) | 
					
						
							| 
									
										
										
										
											2021-12-26 18:17:37 +00:00
										 |  |  |     domain = remove_domain_port(domain) | 
					
						
							| 
									
										
										
										
											2021-12-29 22:45:26 +00:00
										 |  |  |     post_filename = locate_post(base_dir, nickname, domain, message_id) | 
					
						
							| 
									
										
										
										
											2021-12-26 23:41:34 +00:00
										 |  |  |     if not post_filename: | 
					
						
							| 
									
										
										
										
											2021-05-08 13:14:52 +00:00
										 |  |  |         if debug: | 
					
						
							|  |  |  |             print('DEBUG: c2s undo announce post not found in inbox or outbox') | 
					
						
							| 
									
										
										
										
											2021-12-29 22:45:26 +00:00
										 |  |  |             print(message_id) | 
					
						
							| 
									
										
										
										
											2021-05-08 13:14:52 +00:00
										 |  |  |         return True | 
					
						
							| 
									
										
										
										
											2021-12-27 10:55:48 +00:00
										 |  |  |     undo_announce_collection_entry(recent_posts_cache, base_dir, post_filename, | 
					
						
							|  |  |  |                                    message_json['actor'], domain, debug) | 
					
						
							| 
									
										
										
										
											2021-05-08 13:14:52 +00:00
										 |  |  |     if debug: | 
					
						
							| 
									
										
										
										
											2021-12-26 23:41:34 +00:00
										 |  |  |         print('DEBUG: post undo announce via c2s - ' + post_filename) |