| 
									
										
										
										
											2020-04-04 14:14:25 +00:00
										 |  |  |  | __filename__ = "webfinger.py" | 
					
						
							|  |  |  |  | __author__ = "Bob Mottram" | 
					
						
							|  |  |  |  | __license__ = "AGPL3+" | 
					
						
							| 
									
										
										
										
											2022-02-03 13:58:20 +00:00
										 |  |  |  | __version__ = "1.3.0" | 
					
						
							| 
									
										
										
										
											2020-04-04 14:14:25 +00:00
										 |  |  |  | __maintainer__ = "Bob Mottram" | 
					
						
							| 
									
										
										
										
											2021-09-10 16:14:50 +00:00
										 |  |  |  | __email__ = "bob@libreserver.org" | 
					
						
							| 
									
										
										
										
											2020-04-04 14:14:25 +00:00
										 |  |  |  | __status__ = "Production" | 
					
						
							| 
									
										
										
										
											2021-06-15 15:08:12 +00:00
										 |  |  |  | __module_group__ = "ActivityPub" | 
					
						
							| 
									
										
										
										
											2019-06-28 18:55:29 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | import os | 
					
						
							| 
									
										
										
										
											2020-04-15 11:10:30 +00:00
										 |  |  |  | import urllib.parse | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |  | from session import get_json | 
					
						
							|  |  |  |  | from cache import store_webfinger_in_cache | 
					
						
							|  |  |  |  | from cache import get_webfinger_from_cache | 
					
						
							| 
									
										
										
										
											2022-05-11 17:17:23 +00:00
										 |  |  |  | from utils import get_attachment_property_value | 
					
						
							| 
									
										
										
										
											2021-12-26 12:45:03 +00:00
										 |  |  |  | from utils import get_full_domain | 
					
						
							| 
									
										
										
										
											2021-12-26 15:13:34 +00:00
										 |  |  |  | from utils import load_json | 
					
						
							|  |  |  |  | from utils import load_json_onionify | 
					
						
							| 
									
										
										
										
											2021-12-26 14:47:21 +00:00
										 |  |  |  | from utils import save_json | 
					
						
							| 
									
										
										
										
											2021-12-27 17:20:01 +00:00
										 |  |  |  | from utils import get_protocol_prefixes | 
					
						
							| 
									
										
										
										
											2021-12-26 18:17:37 +00:00
										 |  |  |  | from utils import remove_domain_port | 
					
						
							| 
									
										
										
										
											2021-12-26 12:24:40 +00:00
										 |  |  |  | from utils import get_user_paths | 
					
						
							| 
									
										
										
										
											2021-12-26 17:53:07 +00:00
										 |  |  |  | from utils import get_group_paths | 
					
						
							| 
									
										
										
										
											2021-12-26 10:19:59 +00:00
										 |  |  |  | from utils import local_actor_url | 
					
						
							| 
									
										
										
										
											2019-06-28 18:55:29 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-04 14:14:25 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |  | def _parse_handle(handle: str) -> (str, str, bool): | 
					
						
							| 
									
										
										
										
											2021-07-29 22:41:27 +00:00
										 |  |  |  |     """Parses a handle and returns nickname and domain
 | 
					
						
							|  |  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2021-12-26 00:07:44 +00:00
										 |  |  |  |     group_account = False | 
					
						
							| 
									
										
										
										
											2019-06-28 18:55:29 +00:00
										 |  |  |  |     if '.' not in handle: | 
					
						
							| 
									
										
										
										
											2021-07-30 13:00:23 +00:00
										 |  |  |  |         return None, None, False | 
					
						
							| 
									
										
										
										
											2021-12-27 17:20:01 +00:00
										 |  |  |  |     prefixes = get_protocol_prefixes() | 
					
						
							| 
									
										
										
										
											2022-01-03 21:17:44 +00:00
										 |  |  |  |     handle_str = handle | 
					
						
							| 
									
										
										
										
											2020-06-11 12:16:45 +00:00
										 |  |  |  |     for prefix in prefixes: | 
					
						
							| 
									
										
										
										
											2022-01-03 21:17:44 +00:00
										 |  |  |  |         handle_str = handle_str.replace(prefix, '') | 
					
						
							| 
									
										
										
										
											2021-07-29 22:41:27 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |     # try domain/@nick | 
					
						
							| 
									
										
										
										
											2019-06-28 18:55:29 +00:00
										 |  |  |  |     if '/@' in handle: | 
					
						
							| 
									
										
										
										
											2022-01-03 21:17:44 +00:00
										 |  |  |  |         domain, nickname = handle_str.split('/@') | 
					
						
							| 
									
										
										
										
											2021-07-30 13:00:23 +00:00
										 |  |  |  |         return nickname, domain, False | 
					
						
							| 
									
										
										
										
											2021-07-29 22:41:27 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |     # try nick@domain | 
					
						
							|  |  |  |  |     if '@' in handle: | 
					
						
							| 
									
										
										
										
											2021-07-30 13:00:23 +00:00
										 |  |  |  |         if handle.startswith('!'): | 
					
						
							|  |  |  |  |             handle = handle[1:] | 
					
						
							| 
									
										
										
										
											2021-12-26 00:07:44 +00:00
										 |  |  |  |             group_account = True | 
					
						
							| 
									
										
										
										
											2021-07-29 22:41:27 +00:00
										 |  |  |  |         nickname, domain = handle.split('@') | 
					
						
							| 
									
										
										
										
											2021-12-26 00:07:44 +00:00
										 |  |  |  |         return nickname, domain, group_account | 
					
						
							| 
									
										
										
										
											2021-07-29 22:41:27 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |     # try for different /users/ paths | 
					
						
							| 
									
										
										
										
											2022-01-03 21:17:44 +00:00
										 |  |  |  |     users_paths = get_user_paths() | 
					
						
							|  |  |  |  |     group_paths = get_group_paths() | 
					
						
							|  |  |  |  |     for possible_users_path in users_paths: | 
					
						
							|  |  |  |  |         if possible_users_path in handle: | 
					
						
							|  |  |  |  |             if possible_users_path in group_paths: | 
					
						
							| 
									
										
										
										
											2021-12-26 00:07:44 +00:00
										 |  |  |  |                 group_account = True | 
					
						
							| 
									
										
										
										
											2022-01-03 21:17:44 +00:00
										 |  |  |  |             domain, nickname = handle_str.split(possible_users_path) | 
					
						
							| 
									
										
										
										
											2021-12-26 00:07:44 +00:00
										 |  |  |  |             return nickname, domain, group_account | 
					
						
							| 
									
										
										
										
											2021-07-29 22:41:27 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-30 13:00:23 +00:00
										 |  |  |  |     return None, None, False | 
					
						
							| 
									
										
										
										
											2019-06-28 18:55:29 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |  | def webfinger_handle(session, handle: str, http_prefix: str, | 
					
						
							|  |  |  |  |                      cached_webfingers: {}, | 
					
						
							| 
									
										
										
										
											2022-01-03 21:17:44 +00:00
										 |  |  |  |                      from_domain: str, project_version: str, | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |  |                      debug: bool, group_account: bool, | 
					
						
							|  |  |  |  |                      signing_priv_key_pem: str) -> {}: | 
					
						
							| 
									
										
										
										
											2020-06-23 10:41:12 +00:00
										 |  |  |  |     """Gets webfinger result for the given ActivityPub handle
 | 
					
						
							| 
									
										
										
										
											2020-05-07 13:21:58 +00:00
										 |  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2019-07-16 10:19:04 +00:00
										 |  |  |  |     if not session: | 
					
						
							| 
									
										
										
										
											2022-03-11 15:00:01 +00:00
										 |  |  |  |         print('WARN: No session specified for webfinger_handle') | 
					
						
							| 
									
										
										
										
											2019-07-16 10:19:04 +00:00
										 |  |  |  |         return None | 
					
						
							| 
									
										
										
										
											2019-07-19 13:32:58 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-03 21:17:44 +00:00
										 |  |  |  |     nickname, domain, _ = _parse_handle(handle) | 
					
						
							| 
									
										
										
										
											2019-07-03 09:40:27 +00:00
										 |  |  |  |     if not nickname: | 
					
						
							| 
									
										
										
										
											2022-03-11 15:00:01 +00:00
										 |  |  |  |         print('WARN: No nickname found in handle ' + handle) | 
					
						
							| 
									
										
										
										
											2019-06-28 18:55:29 +00:00
										 |  |  |  |         return None | 
					
						
							| 
									
										
										
										
											2022-01-03 21:17:44 +00:00
										 |  |  |  |     wf_domain = remove_domain_port(domain) | 
					
						
							| 
									
										
										
										
											2021-06-23 21:31:50 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-03 21:17:44 +00:00
										 |  |  |  |     wf_handle = nickname + '@' + wf_domain | 
					
						
							| 
									
										
										
										
											2022-02-26 10:25:27 +00:00
										 |  |  |  |     if debug: | 
					
						
							|  |  |  |  |         print('Parsed webfinger handle: ' + handle + ' -> ' + wf_handle) | 
					
						
							| 
									
										
										
										
											2022-01-03 21:17:44 +00:00
										 |  |  |  |     wfg = get_webfinger_from_cache(wf_handle, cached_webfingers) | 
					
						
							|  |  |  |  |     if wfg: | 
					
						
							| 
									
										
										
										
											2021-03-14 19:22:58 +00:00
										 |  |  |  |         if debug: | 
					
						
							| 
									
										
										
										
											2022-01-03 21:17:44 +00:00
										 |  |  |  |             print('Webfinger from cache: ' + str(wfg)) | 
					
						
							|  |  |  |  |         return wfg | 
					
						
							| 
									
										
										
										
											2021-12-25 17:09:22 +00:00
										 |  |  |  |     url = '{}://{}/.well-known/webfinger'.format(http_prefix, domain) | 
					
						
							| 
									
										
										
										
											2020-04-04 14:14:25 +00:00
										 |  |  |  |     hdr = { | 
					
						
							| 
									
										
										
										
											2020-03-22 20:36:19 +00:00
										 |  |  |  |         'Accept': 'application/jrd+json' | 
					
						
							|  |  |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-11-18 17:14:59 +00:00
										 |  |  |  |     par = { | 
					
						
							| 
									
										
										
										
											2022-01-03 21:17:44 +00:00
										 |  |  |  |         'resource': 'acct:{}'.format(wf_handle) | 
					
						
							| 
									
										
										
										
											2021-11-18 17:14:59 +00:00
										 |  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-07-04 17:31:41 +00:00
										 |  |  |  |     try: | 
					
						
							| 
									
										
										
										
											2020-04-04 14:14:25 +00:00
										 |  |  |  |         result = \ | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |  |             get_json(signing_priv_key_pem, session, url, hdr, par, | 
					
						
							| 
									
										
										
										
											2022-01-03 21:17:44 +00:00
										 |  |  |  |                      debug, project_version, http_prefix, from_domain) | 
					
						
							| 
									
										
										
										
											2021-12-25 15:28:52 +00:00
										 |  |  |  |     except Exception as ex: | 
					
						
							| 
									
										
										
										
											2022-02-26 10:25:27 +00:00
										 |  |  |  |         print('ERROR: webfinger_handle ' + wf_handle + ' ' + str(ex)) | 
					
						
							| 
									
										
										
										
											2021-07-30 13:00:23 +00:00
										 |  |  |  |         return None | 
					
						
							| 
									
										
										
										
											2020-05-07 13:21:58 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-26 11:01:50 +00:00
										 |  |  |  |     # if the first attempt fails then try specifying the webfinger | 
					
						
							|  |  |  |  |     # resource in a different way | 
					
						
							|  |  |  |  |     if not result: | 
					
						
							|  |  |  |  |         resource = handle | 
					
						
							|  |  |  |  |         if handle == wf_handle: | 
					
						
							|  |  |  |  |             # reconstruct the actor | 
					
						
							|  |  |  |  |             resource = http_prefix + '://' + wf_domain + '/users/' + nickname | 
					
						
							|  |  |  |  |         # try again using the actor as the resource | 
					
						
							|  |  |  |  |         # See https://datatracker.ietf.org/doc/html/rfc7033 section 4.5 | 
					
						
							|  |  |  |  |         par = { | 
					
						
							|  |  |  |  |             'resource': '{}'.format(resource) | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  |         try: | 
					
						
							|  |  |  |  |             result = \ | 
					
						
							|  |  |  |  |                 get_json(signing_priv_key_pem, session, url, hdr, par, | 
					
						
							|  |  |  |  |                          debug, project_version, http_prefix, from_domain) | 
					
						
							|  |  |  |  |         except Exception as ex: | 
					
						
							|  |  |  |  |             print('ERROR: webfinger_handle ' + wf_handle + ' ' + str(ex)) | 
					
						
							|  |  |  |  |             return None | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-07 13:21:58 +00:00
										 |  |  |  |     if result: | 
					
						
							| 
									
										
										
										
											2022-01-03 21:17:44 +00:00
										 |  |  |  |         store_webfinger_in_cache(wf_handle, result, cached_webfingers) | 
					
						
							| 
									
										
										
										
											2020-05-07 13:26:55 +00:00
										 |  |  |  |     else: | 
					
						
							| 
									
										
										
										
											2022-05-28 17:01:43 +00:00
										 |  |  |  |         print("WARN: Unable to webfinger " + str(url) + ' ' + | 
					
						
							|  |  |  |  |               'from_domain: ' + str(from_domain) + ' ' + | 
					
						
							| 
									
										
										
										
											2022-03-11 15:00:01 +00:00
										 |  |  |  |               'nickname: ' + str(nickname) + ' ' + | 
					
						
							|  |  |  |  |               'handle: ' + str(handle) + ' ' + | 
					
						
							|  |  |  |  |               'wf_handle: ' + str(wf_handle) + ' ' + | 
					
						
							|  |  |  |  |               'domain: ' + str(wf_domain) + ' ' + | 
					
						
							|  |  |  |  |               'headers: ' + str(hdr) + ' ' + | 
					
						
							|  |  |  |  |               'params: ' + str(par)) | 
					
						
							| 
									
										
										
										
											2020-05-07 13:26:55 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-28 18:55:29 +00:00
										 |  |  |  |     return result | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-04 14:14:25 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |  | def store_webfinger_endpoint(nickname: str, domain: str, port: int, | 
					
						
							| 
									
										
										
										
											2022-01-03 21:17:44 +00:00
										 |  |  |  |                              base_dir: str, wf_json: {}) -> bool: | 
					
						
							| 
									
										
										
										
											2019-06-28 18:55:29 +00:00
										 |  |  |  |     """Stores webfinger endpoint for a user to a file
 | 
					
						
							|  |  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2022-01-03 21:17:44 +00:00
										 |  |  |  |     original_domain = domain | 
					
						
							| 
									
										
										
										
											2021-12-26 12:45:03 +00:00
										 |  |  |  |     domain = get_full_domain(domain, port) | 
					
						
							| 
									
										
										
										
											2020-04-04 14:14:25 +00:00
										 |  |  |  |     handle = nickname + '@' + domain | 
					
						
							| 
									
										
										
										
											2022-01-03 21:17:44 +00:00
										 |  |  |  |     wf_subdir = '/wfendpoints' | 
					
						
							|  |  |  |  |     if not os.path.isdir(base_dir + wf_subdir): | 
					
						
							|  |  |  |  |         os.mkdir(base_dir + wf_subdir) | 
					
						
							|  |  |  |  |     filename = base_dir + wf_subdir + '/' + handle + '.json' | 
					
						
							|  |  |  |  |     save_json(wf_json, filename) | 
					
						
							| 
									
										
										
										
											2020-04-04 14:14:25 +00:00
										 |  |  |  |     if nickname == 'inbox': | 
					
						
							| 
									
										
										
										
											2022-01-03 21:17:44 +00:00
										 |  |  |  |         handle = original_domain + '@' + domain | 
					
						
							|  |  |  |  |         filename = base_dir + wf_subdir + '/' + handle + '.json' | 
					
						
							|  |  |  |  |         save_json(wf_json, filename) | 
					
						
							| 
									
										
										
										
											2019-06-28 18:55:29 +00:00
										 |  |  |  |     return True | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-04 14:14:25 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |  | def create_webfinger_endpoint(nickname: str, domain: str, port: int, | 
					
						
							| 
									
										
										
										
											2022-01-03 21:17:44 +00:00
										 |  |  |  |                               http_prefix: str, public_key_pem: str, | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |  |                               group_account: bool) -> {}: | 
					
						
							| 
									
										
										
										
											2019-06-28 18:55:29 +00:00
										 |  |  |  |     """Creates a webfinger endpoint for a user
 | 
					
						
							|  |  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2022-01-03 21:17:44 +00:00
										 |  |  |  |     original_domain = domain | 
					
						
							| 
									
										
										
										
											2021-12-26 12:45:03 +00:00
										 |  |  |  |     domain = get_full_domain(domain, port) | 
					
						
							| 
									
										
										
										
											2020-04-04 14:14:25 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-03 21:17:44 +00:00
										 |  |  |  |     person_name = nickname | 
					
						
							|  |  |  |  |     person_id = local_actor_url(http_prefix, person_name, domain) | 
					
						
							|  |  |  |  |     subject_str = "acct:" + person_name + "@" + original_domain | 
					
						
							|  |  |  |  |     profile_page_href = http_prefix + "://" + domain + "/@" + nickname | 
					
						
							|  |  |  |  |     if nickname in ('inbox', original_domain): | 
					
						
							|  |  |  |  |         person_name = 'actor' | 
					
						
							|  |  |  |  |         person_id = http_prefix + "://" + domain + "/" + person_name | 
					
						
							|  |  |  |  |         subject_str = "acct:" + original_domain + "@" + original_domain | 
					
						
							|  |  |  |  |         profile_page_href = http_prefix + '://' + domain + \ | 
					
						
							| 
									
										
										
										
											2020-04-04 14:14:25 +00:00
										 |  |  |  |             '/about/more?instance_actor=true' | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-03 21:17:44 +00:00
										 |  |  |  |     person_link = http_prefix + "://" + domain + "/@" + person_name | 
					
						
							|  |  |  |  |     blog_url = http_prefix + "://" + domain + "/blog/" + person_name | 
					
						
							| 
									
										
										
										
											2020-04-04 14:14:25 +00:00
										 |  |  |  |     account = { | 
					
						
							| 
									
										
										
										
											2019-06-28 18:55:29 +00:00
										 |  |  |  |         "aliases": [ | 
					
						
							| 
									
										
										
										
											2022-01-03 21:17:44 +00:00
										 |  |  |  |             person_link, | 
					
						
							|  |  |  |  |             person_id | 
					
						
							| 
									
										
										
										
											2019-06-28 18:55:29 +00:00
										 |  |  |  |         ], | 
					
						
							|  |  |  |  |         "links": [ | 
					
						
							| 
									
										
										
										
											2021-10-28 09:33:27 +00:00
										 |  |  |  |             { | 
					
						
							| 
									
										
										
										
											2022-01-03 21:17:44 +00:00
										 |  |  |  |                 "href": person_link + "/avatar.png", | 
					
						
							| 
									
										
										
										
											2021-10-28 09:33:27 +00:00
										 |  |  |  |                 "rel": "http://webfinger.net/rel/avatar", | 
					
						
							|  |  |  |  |                 "type": "image/png" | 
					
						
							|  |  |  |  |             }, | 
					
						
							| 
									
										
										
										
											2021-10-28 09:41:18 +00:00
										 |  |  |  |             { | 
					
						
							| 
									
										
										
										
											2022-01-03 21:17:44 +00:00
										 |  |  |  |                 "href": blog_url, | 
					
						
							| 
									
										
										
										
											2021-10-28 09:41:18 +00:00
										 |  |  |  |                 "rel": "http://webfinger.net/rel/blog" | 
					
						
							|  |  |  |  |             }, | 
					
						
							| 
									
										
										
										
											2019-06-28 18:55:29 +00:00
										 |  |  |  |             { | 
					
						
							| 
									
										
										
										
											2022-01-03 21:17:44 +00:00
										 |  |  |  |                 "href": profile_page_href, | 
					
						
							| 
									
										
										
										
											2019-06-28 18:55:29 +00:00
										 |  |  |  |                 "rel": "http://webfinger.net/rel/profile-page", | 
					
						
							|  |  |  |  |                 "type": "text/html" | 
					
						
							|  |  |  |  |             }, | 
					
						
							| 
									
										
										
										
											2022-02-16 10:24:04 +00:00
										 |  |  |  |             { | 
					
						
							|  |  |  |  |                 "href": profile_page_href, | 
					
						
							|  |  |  |  |                 "rel": "http://webfinger.net/rel/profile-page", | 
					
						
							|  |  |  |  |                 "type": "text/vcard" | 
					
						
							|  |  |  |  |             }, | 
					
						
							| 
									
										
										
										
											2019-06-28 18:55:29 +00:00
										 |  |  |  |             { | 
					
						
							| 
									
										
										
										
											2022-01-03 21:17:44 +00:00
										 |  |  |  |                 "href": person_id, | 
					
						
							| 
									
										
										
										
											2019-06-28 18:55:29 +00:00
										 |  |  |  |                 "rel": "self", | 
					
						
							|  |  |  |  |                 "type": "application/activity+json" | 
					
						
							|  |  |  |  |             } | 
					
						
							|  |  |  |  |         ], | 
					
						
							| 
									
										
										
										
											2022-01-03 21:17:44 +00:00
										 |  |  |  |         "subject": subject_str | 
					
						
							| 
									
										
										
										
											2019-06-28 18:55:29 +00:00
										 |  |  |  |     } | 
					
						
							|  |  |  |  |     return account | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-04 14:14:25 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-28 17:09:43 +00:00
										 |  |  |  | def webfinger_node_info(http_prefix: str, domain_full: str) -> {}: | 
					
						
							| 
									
										
										
										
											2019-11-13 10:32:12 +00:00
										 |  |  |  |     """ /.well-known/nodeinfo endpoint
 | 
					
						
							|  |  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2020-04-04 14:14:25 +00:00
										 |  |  |  |     nodeinfo = { | 
					
						
							| 
									
										
										
										
											2019-11-13 10:32:12 +00:00
										 |  |  |  |         'links': [ | 
					
						
							|  |  |  |  |             { | 
					
						
							| 
									
										
										
										
											2021-12-26 10:00:46 +00:00
										 |  |  |  |                 'href': http_prefix + '://' + domain_full + '/nodeinfo/2.0', | 
					
						
							| 
									
										
										
										
											2019-11-13 10:32:12 +00:00
										 |  |  |  |                 'rel': 'http://nodeinfo.diaspora.software/ns/schema/2.0' | 
					
						
							|  |  |  |  |             } | 
					
						
							|  |  |  |  |         ] | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  |     return nodeinfo | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-04 14:14:25 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-28 17:06:24 +00:00
										 |  |  |  | def webfinger_meta(http_prefix: str, domain_full: str) -> str: | 
					
						
							| 
									
										
										
										
											2019-08-16 20:52:55 +00:00
										 |  |  |  |     """Return /.well-known/host-meta
 | 
					
						
							| 
									
										
										
										
											2019-06-28 18:55:29 +00:00
										 |  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2022-01-03 21:17:44 +00:00
										 |  |  |  |     meta_str = \ | 
					
						
							| 
									
										
										
										
											2021-07-06 12:50:38 +00:00
										 |  |  |  |         "<?xml version=’1.0' encoding=’UTF-8'?>" + \ | 
					
						
							|  |  |  |  |         "<XRD xmlns=’http://docs.oasis-open.org/ns/xri/xrd-1.0'" + \ | 
					
						
							|  |  |  |  |         " xmlns:hm=’http://host-meta.net/xrd/1.0'>" + \ | 
					
						
							|  |  |  |  |         "" + \ | 
					
						
							| 
									
										
										
										
											2021-12-26 10:00:46 +00:00
										 |  |  |  |         "<hm:Host>" + domain_full + "</hm:Host>" + \ | 
					
						
							| 
									
										
										
										
											2021-07-06 12:50:38 +00:00
										 |  |  |  |         "" + \ | 
					
						
							|  |  |  |  |         "<Link rel=’lrdd’" + \ | 
					
						
							| 
									
										
										
										
											2021-12-26 10:00:46 +00:00
										 |  |  |  |         " template=’" + http_prefix + "://" + domain_full + \ | 
					
						
							| 
									
										
										
										
											2021-07-06 12:50:38 +00:00
										 |  |  |  |         "/describe?uri={uri}'>" + \ | 
					
						
							|  |  |  |  |         " <Title>Resource Descriptor</Title>" + \ | 
					
						
							|  |  |  |  |         " </Link>" + \ | 
					
						
							|  |  |  |  |         "</XRD>" | 
					
						
							| 
									
										
										
										
											2022-01-03 21:17:44 +00:00
										 |  |  |  |     return meta_str | 
					
						
							| 
									
										
										
										
											2019-08-16 20:52:55 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-04 14:14:25 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-28 17:20:43 +00:00
										 |  |  |  | def webfinger_lookup(path: str, base_dir: str, | 
					
						
							| 
									
										
										
										
											2022-03-13 20:58:05 +00:00
										 |  |  |  |                      domain: str, onion_domain: str, i2p_domain: str, | 
					
						
							| 
									
										
										
										
											2021-12-28 17:20:43 +00:00
										 |  |  |  |                      port: int, debug: bool) -> {}: | 
					
						
							| 
									
										
										
										
											2019-06-28 18:55:29 +00:00
										 |  |  |  |     """Lookup the webfinger endpoint for an account
 | 
					
						
							|  |  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2020-03-22 21:16:02 +00:00
										 |  |  |  |     if not path.startswith('/.well-known/webfinger?'): | 
					
						
							| 
									
										
										
										
											2019-06-28 18:55:29 +00:00
										 |  |  |  |         return None | 
					
						
							| 
									
										
										
										
											2020-04-04 14:14:25 +00:00
										 |  |  |  |     handle = None | 
					
						
							| 
									
										
										
										
											2022-01-03 21:17:44 +00:00
										 |  |  |  |     res_type = 'acct' | 
					
						
							|  |  |  |  |     if 'resource=' + res_type + ':' in path: | 
					
						
							|  |  |  |  |         handle = path.split('resource=' + res_type + ':')[1].strip() | 
					
						
							| 
									
										
										
										
											2021-11-18 17:14:59 +00:00
										 |  |  |  |         handle = urllib.parse.unquote(handle) | 
					
						
							|  |  |  |  |         if debug: | 
					
						
							|  |  |  |  |             print('DEBUG: WEBFINGER handle ' + handle) | 
					
						
							| 
									
										
										
										
											2022-01-03 21:17:44 +00:00
										 |  |  |  |     elif 'resource=' + res_type + '%3A' in path: | 
					
						
							|  |  |  |  |         handle = path.split('resource=' + res_type + '%3A')[1] | 
					
						
							| 
									
										
										
										
											2021-11-18 17:14:59 +00:00
										 |  |  |  |         handle = urllib.parse.unquote(handle.strip()) | 
					
						
							|  |  |  |  |         if debug: | 
					
						
							|  |  |  |  |             print('DEBUG: WEBFINGER handle ' + handle) | 
					
						
							| 
									
										
										
										
											2019-06-28 18:55:29 +00:00
										 |  |  |  |     if not handle: | 
					
						
							| 
									
										
										
										
											2019-07-19 14:19:36 +00:00
										 |  |  |  |         if debug: | 
					
						
							|  |  |  |  |             print('DEBUG: WEBFINGER handle missing') | 
					
						
							| 
									
										
										
										
											2019-06-28 18:55:29 +00:00
										 |  |  |  |         return None | 
					
						
							|  |  |  |  |     if '&' in handle: | 
					
						
							| 
									
										
										
										
											2020-04-04 14:14:25 +00:00
										 |  |  |  |         handle = handle.split('&')[0].strip() | 
					
						
							| 
									
										
										
										
											2021-10-28 13:27:25 +00:00
										 |  |  |  |         print('DEBUG: WEBFINGER handle with & removed ' + handle) | 
					
						
							| 
									
										
										
										
											2019-06-28 18:55:29 +00:00
										 |  |  |  |     if '@' not in handle: | 
					
						
							| 
									
										
										
										
											2019-07-19 14:19:36 +00:00
										 |  |  |  |         if debug: | 
					
						
							| 
									
										
										
										
											2020-04-04 14:14:25 +00:00
										 |  |  |  |             print('DEBUG: WEBFINGER no @ in handle ' + handle) | 
					
						
							| 
									
										
										
										
											2019-06-28 18:55:29 +00:00
										 |  |  |  |         return None | 
					
						
							| 
									
										
										
										
											2021-12-26 12:45:03 +00:00
										 |  |  |  |     handle = get_full_domain(handle, port) | 
					
						
							| 
									
										
										
										
											2019-08-23 14:18:31 +00:00
										 |  |  |  |     # convert @domain@domain to inbox@domain | 
					
						
							|  |  |  |  |     if '@' in handle: | 
					
						
							| 
									
										
										
										
											2022-01-03 21:17:44 +00:00
										 |  |  |  |         handle_domain = handle.split('@')[1] | 
					
						
							|  |  |  |  |         if handle.startswith(handle_domain + '@'): | 
					
						
							|  |  |  |  |             handle = 'inbox@' + handle_domain | 
					
						
							| 
									
										
										
										
											2020-03-02 14:35:44 +00:00
										 |  |  |  |     # if this is a lookup for a handle using its onion domain | 
					
						
							|  |  |  |  |     # then swap the onion domain for the clearnet version | 
					
						
							| 
									
										
										
										
											2020-04-04 14:14:25 +00:00
										 |  |  |  |     onionify = False | 
					
						
							| 
									
										
										
										
											2021-12-25 20:43:43 +00:00
										 |  |  |  |     if onion_domain: | 
					
						
							|  |  |  |  |         if onion_domain in handle: | 
					
						
							|  |  |  |  |             handle = handle.replace(onion_domain, domain) | 
					
						
							| 
									
										
										
										
											2020-04-04 14:14:25 +00:00
										 |  |  |  |             onionify = True | 
					
						
							| 
									
										
										
										
											2022-03-13 20:58:05 +00:00
										 |  |  |  |     i2pify = False | 
					
						
							|  |  |  |  |     if i2p_domain: | 
					
						
							|  |  |  |  |         if i2p_domain in handle: | 
					
						
							|  |  |  |  |             handle = handle.replace(i2p_domain, domain) | 
					
						
							|  |  |  |  |             i2pify = True | 
					
						
							| 
									
										
										
										
											2021-08-31 19:04:29 +00:00
										 |  |  |  |     # instance actor | 
					
						
							|  |  |  |  |     if handle.startswith('actor@'): | 
					
						
							|  |  |  |  |         handle = handle.replace('actor@', 'inbox@', 1) | 
					
						
							|  |  |  |  |     elif handle.startswith('Actor@'): | 
					
						
							|  |  |  |  |         handle = handle.replace('Actor@', 'inbox@', 1) | 
					
						
							| 
									
										
										
										
											2021-12-25 16:17:53 +00:00
										 |  |  |  |     filename = base_dir + '/wfendpoints/' + handle + '.json' | 
					
						
							| 
									
										
										
										
											2019-07-19 14:19:36 +00:00
										 |  |  |  |     if debug: | 
					
						
							| 
									
										
										
										
											2020-04-04 14:14:25 +00:00
										 |  |  |  |         print('DEBUG: WEBFINGER filename ' + filename) | 
					
						
							| 
									
										
										
										
											2019-06-28 18:55:29 +00:00
										 |  |  |  |     if not os.path.isfile(filename): | 
					
						
							| 
									
										
										
										
											2019-07-19 14:19:36 +00:00
										 |  |  |  |         if debug: | 
					
						
							| 
									
										
										
										
											2020-04-04 14:14:25 +00:00
										 |  |  |  |             print('DEBUG: WEBFINGER filename not found ' + filename) | 
					
						
							| 
									
										
										
										
											2019-06-28 18:55:29 +00:00
										 |  |  |  |         return None | 
					
						
							| 
									
										
										
										
											2022-03-13 20:58:05 +00:00
										 |  |  |  |     if not onionify and not i2pify: | 
					
						
							| 
									
										
										
										
											2022-01-03 21:17:44 +00:00
										 |  |  |  |         wf_json = load_json(filename) | 
					
						
							| 
									
										
										
										
											2022-03-13 20:58:05 +00:00
										 |  |  |  |     elif onionify: | 
					
						
							| 
									
										
										
										
											2020-04-04 14:14:25 +00:00
										 |  |  |  |         print('Webfinger request for onionified ' + handle) | 
					
						
							| 
									
										
										
										
											2022-01-03 21:17:44 +00:00
										 |  |  |  |         wf_json = load_json_onionify(filename, domain, onion_domain) | 
					
						
							| 
									
										
										
										
											2022-03-13 20:58:05 +00:00
										 |  |  |  |     else: | 
					
						
							|  |  |  |  |         print('Webfinger request for i2pified ' + handle) | 
					
						
							|  |  |  |  |         wf_json = load_json_onionify(filename, domain, i2p_domain) | 
					
						
							| 
									
										
										
										
											2022-01-03 21:17:44 +00:00
										 |  |  |  |     if not wf_json: | 
					
						
							|  |  |  |  |         wf_json = {"nickname": "unknown"} | 
					
						
							|  |  |  |  |     return wf_json | 
					
						
							| 
									
										
										
										
											2020-05-04 13:58:24 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-16 10:24:04 +00:00
										 |  |  |  | def _webfinger_update_avatar(wf_json: {}, actor_json: {}) -> bool: | 
					
						
							| 
									
										
										
										
											2021-10-28 10:08:41 +00:00
										 |  |  |  |     """Updates the avatar image link
 | 
					
						
							|  |  |  |  |     """
 | 
					
						
							|  |  |  |  |     found = False | 
					
						
							| 
									
										
										
										
											2022-01-03 21:17:44 +00:00
										 |  |  |  |     avatar_url = actor_json['icon']['url'] | 
					
						
							|  |  |  |  |     media_type = actor_json['icon']['mediaType'] | 
					
						
							|  |  |  |  |     for link in wf_json['links']: | 
					
						
							| 
									
										
										
										
											2021-10-28 10:08:41 +00:00
										 |  |  |  |         if not link.get('rel'): | 
					
						
							|  |  |  |  |             continue | 
					
						
							|  |  |  |  |         if not link['rel'].endswith('://webfinger.net/rel/avatar'): | 
					
						
							|  |  |  |  |             continue | 
					
						
							|  |  |  |  |         found = True | 
					
						
							| 
									
										
										
										
											2022-01-03 21:17:44 +00:00
										 |  |  |  |         if link['href'] != avatar_url or link['type'] != media_type: | 
					
						
							|  |  |  |  |             link['href'] = avatar_url | 
					
						
							|  |  |  |  |             link['type'] = media_type | 
					
						
							| 
									
										
										
										
											2021-10-28 10:08:41 +00:00
										 |  |  |  |             return True | 
					
						
							|  |  |  |  |         break | 
					
						
							|  |  |  |  |     if found: | 
					
						
							|  |  |  |  |         return False | 
					
						
							| 
									
										
										
										
											2022-01-03 21:17:44 +00:00
										 |  |  |  |     wf_json['links'].append({ | 
					
						
							|  |  |  |  |         "href": avatar_url, | 
					
						
							| 
									
										
										
										
											2021-10-28 10:08:41 +00:00
										 |  |  |  |         "rel": "http://webfinger.net/rel/avatar", | 
					
						
							| 
									
										
										
										
											2022-01-03 21:17:44 +00:00
										 |  |  |  |         "type": media_type | 
					
						
							| 
									
										
										
										
											2021-10-28 10:08:41 +00:00
										 |  |  |  |     }) | 
					
						
							|  |  |  |  |     return True | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-16 10:24:04 +00:00
										 |  |  |  | def _webfinger_update_vcard(wf_json: {}, actor_json: {}) -> bool: | 
					
						
							|  |  |  |  |     """Updates the vcard link
 | 
					
						
							|  |  |  |  |     """
 | 
					
						
							|  |  |  |  |     for link in wf_json['links']: | 
					
						
							| 
									
										
										
										
											2022-02-24 11:17:32 +00:00
										 |  |  |  |         if link.get('type'): | 
					
						
							|  |  |  |  |             if link['type'] == 'text/vcard': | 
					
						
							|  |  |  |  |                 return False | 
					
						
							| 
									
										
										
										
											2022-02-16 10:24:04 +00:00
										 |  |  |  |     wf_json['links'].append({ | 
					
						
							|  |  |  |  |         "href": actor_json['url'], | 
					
						
							|  |  |  |  |         "rel": "http://webfinger.net/rel/profile-page", | 
					
						
							|  |  |  |  |         "type": "text/vcard" | 
					
						
							|  |  |  |  |     }) | 
					
						
							|  |  |  |  |     return True | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-03 21:17:44 +00:00
										 |  |  |  | def _webfinger_add_blog_link(wf_json: {}, actor_json: {}) -> bool: | 
					
						
							| 
									
										
										
										
											2021-10-28 10:21:28 +00:00
										 |  |  |  |     """Adds a blog link to webfinger if needed
 | 
					
						
							|  |  |  |  |     """
 | 
					
						
							|  |  |  |  |     found = False | 
					
						
							| 
									
										
										
										
											2021-12-26 10:29:52 +00:00
										 |  |  |  |     if '/users/' in actor_json['id']: | 
					
						
							| 
									
										
										
										
											2022-01-03 21:17:44 +00:00
										 |  |  |  |         blog_url = \ | 
					
						
							| 
									
										
										
										
											2021-12-26 10:29:52 +00:00
										 |  |  |  |             actor_json['id'].split('/users/')[0] + '/blog/' + \ | 
					
						
							|  |  |  |  |             actor_json['id'].split('/users/')[1] | 
					
						
							| 
									
										
										
										
											2021-10-28 10:21:28 +00:00
										 |  |  |  |     else: | 
					
						
							| 
									
										
										
										
											2022-01-03 21:17:44 +00:00
										 |  |  |  |         blog_url = \ | 
					
						
							| 
									
										
										
										
											2021-12-26 10:29:52 +00:00
										 |  |  |  |             actor_json['id'].split('/@')[0] + '/blog/' + \ | 
					
						
							|  |  |  |  |             actor_json['id'].split('/@')[1] | 
					
						
							| 
									
										
										
										
											2022-01-03 21:17:44 +00:00
										 |  |  |  |     for link in wf_json['links']: | 
					
						
							| 
									
										
										
										
											2021-10-28 10:21:28 +00:00
										 |  |  |  |         if not link.get('rel'): | 
					
						
							|  |  |  |  |             continue | 
					
						
							|  |  |  |  |         if not link['rel'].endswith('://webfinger.net/rel/blog'): | 
					
						
							|  |  |  |  |             continue | 
					
						
							|  |  |  |  |         found = True | 
					
						
							| 
									
										
										
										
											2022-01-03 21:17:44 +00:00
										 |  |  |  |         if link['href'] != blog_url: | 
					
						
							|  |  |  |  |             link['href'] = blog_url | 
					
						
							| 
									
										
										
										
											2021-10-28 10:21:28 +00:00
										 |  |  |  |             return True | 
					
						
							|  |  |  |  |         break | 
					
						
							|  |  |  |  |     if found: | 
					
						
							|  |  |  |  |         return False | 
					
						
							| 
									
										
										
										
											2022-01-03 21:17:44 +00:00
										 |  |  |  |     wf_json['links'].append({ | 
					
						
							|  |  |  |  |         "href": blog_url, | 
					
						
							| 
									
										
										
										
											2021-10-28 10:21:28 +00:00
										 |  |  |  |         "rel": "http://webfinger.net/rel/blog" | 
					
						
							|  |  |  |  |     }) | 
					
						
							|  |  |  |  |     return True | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-03 21:17:44 +00:00
										 |  |  |  | def _webfinger_updateFromProfile(wf_json: {}, actor_json: {}) -> bool: | 
					
						
							| 
									
										
										
										
											2020-05-04 13:58:24 +00:00
										 |  |  |  |     """Updates webfinger Email/blog/xmpp links from profile
 | 
					
						
							|  |  |  |  |     Returns true if one or more tags has been changed | 
					
						
							|  |  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2021-12-26 10:29:52 +00:00
										 |  |  |  |     if not actor_json.get('attachment'): | 
					
						
							| 
									
										
										
										
											2020-05-04 13:58:24 +00:00
										 |  |  |  |         return False | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     changed = False | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-03 21:17:44 +00:00
										 |  |  |  |     webfinger_property_name = { | 
					
						
							| 
									
										
										
										
											2020-05-04 13:58:24 +00:00
										 |  |  |  |         "xmpp": "xmpp", | 
					
						
							| 
									
										
										
										
											2020-05-04 14:10:27 +00:00
										 |  |  |  |         "matrix": "matrix", | 
					
						
							| 
									
										
										
										
											2020-05-04 13:58:24 +00:00
										 |  |  |  |         "email": "mailto", | 
					
						
							|  |  |  |  |         "ssb": "ssb", | 
					
						
							| 
									
										
										
										
											2021-07-06 12:53:10 +00:00
										 |  |  |  |         "briar": "briar", | 
					
						
							|  |  |  |  |         "cwtch": "cwtch", | 
					
						
							| 
									
										
										
										
											2020-05-04 13:58:24 +00:00
										 |  |  |  |         "tox": "toxId" | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-03 21:17:44 +00:00
										 |  |  |  |     aliases_not_found = [] | 
					
						
							|  |  |  |  |     for name, alias in webfinger_property_name.items(): | 
					
						
							|  |  |  |  |         aliases_not_found.append(alias) | 
					
						
							| 
									
										
										
										
											2021-07-06 13:11:00 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-26 10:32:45 +00:00
										 |  |  |  |     for property_value in actor_json['attachment']: | 
					
						
							| 
									
										
										
										
											2022-05-11 16:10:38 +00:00
										 |  |  |  |         name_value = None | 
					
						
							|  |  |  |  |         if property_value.get('name'): | 
					
						
							|  |  |  |  |             name_value = property_value['name'] | 
					
						
							|  |  |  |  |         elif property_value.get('schema:name'): | 
					
						
							|  |  |  |  |             name_value = property_value['schema:name'] | 
					
						
							|  |  |  |  |         if not name_value: | 
					
						
							| 
									
										
										
										
											2020-05-04 13:58:24 +00:00
										 |  |  |  |             continue | 
					
						
							| 
									
										
										
										
											2022-05-11 16:10:38 +00:00
										 |  |  |  |         property_name = name_value.lower() | 
					
						
							| 
									
										
										
										
											2021-07-06 12:50:38 +00:00
										 |  |  |  |         found = False | 
					
						
							| 
									
										
										
										
											2022-01-03 21:17:44 +00:00
										 |  |  |  |         for name, alias in webfinger_property_name.items(): | 
					
						
							| 
									
										
										
										
											2021-12-26 18:19:58 +00:00
										 |  |  |  |             if name == property_name: | 
					
						
							| 
									
										
										
										
											2022-01-03 21:17:44 +00:00
										 |  |  |  |                 if alias in aliases_not_found: | 
					
						
							|  |  |  |  |                     aliases_not_found.remove(alias) | 
					
						
							| 
									
										
										
										
											2021-07-06 12:50:38 +00:00
										 |  |  |  |                 found = True | 
					
						
							|  |  |  |  |                 break | 
					
						
							|  |  |  |  |         if not found: | 
					
						
							| 
									
										
										
										
											2020-05-04 13:58:24 +00:00
										 |  |  |  |             continue | 
					
						
							| 
									
										
										
										
											2021-12-26 10:32:45 +00:00
										 |  |  |  |         if not property_value.get('type'): | 
					
						
							| 
									
										
										
										
											2020-05-04 13:58:24 +00:00
										 |  |  |  |             continue | 
					
						
							| 
									
										
										
										
											2022-05-11 17:17:23 +00:00
										 |  |  |  |         prop_value_name, _ = \ | 
					
						
							|  |  |  |  |             get_attachment_property_value(property_value) | 
					
						
							|  |  |  |  |         if not prop_value_name: | 
					
						
							| 
									
										
										
										
											2020-05-04 13:58:24 +00:00
										 |  |  |  |             continue | 
					
						
							| 
									
										
										
										
											2022-05-11 16:16:34 +00:00
										 |  |  |  |         if not property_value['type'].endswith('PropertyValue'): | 
					
						
							| 
									
										
										
										
											2020-05-04 13:58:24 +00:00
										 |  |  |  |             continue | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-11 17:17:23 +00:00
										 |  |  |  |         new_value = property_value[prop_value_name].strip() | 
					
						
							| 
									
										
										
										
											2022-01-03 21:17:44 +00:00
										 |  |  |  |         if '://' in new_value: | 
					
						
							|  |  |  |  |             new_value = new_value.split('://')[1] | 
					
						
							| 
									
										
										
										
											2021-07-06 13:02:00 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-03 21:17:44 +00:00
										 |  |  |  |         alias_index = 0 | 
					
						
							| 
									
										
										
										
											2020-05-04 13:58:24 +00:00
										 |  |  |  |         found = False | 
					
						
							| 
									
										
										
										
											2022-01-03 21:17:44 +00:00
										 |  |  |  |         for alias in wf_json['aliases']: | 
					
						
							|  |  |  |  |             if alias.startswith(webfinger_property_name[property_name] + ':'): | 
					
						
							| 
									
										
										
										
											2020-05-04 13:58:24 +00:00
										 |  |  |  |                 found = True | 
					
						
							|  |  |  |  |                 break | 
					
						
							| 
									
										
										
										
											2022-01-03 21:17:44 +00:00
										 |  |  |  |             alias_index += 1 | 
					
						
							|  |  |  |  |         new_alias = webfinger_property_name[property_name] + ':' + new_value | 
					
						
							| 
									
										
										
										
											2020-05-04 13:58:24 +00:00
										 |  |  |  |         if found: | 
					
						
							| 
									
										
										
										
											2022-01-03 21:17:44 +00:00
										 |  |  |  |             if wf_json['aliases'][alias_index] != new_alias: | 
					
						
							| 
									
										
										
										
											2020-05-04 13:58:24 +00:00
										 |  |  |  |                 changed = True | 
					
						
							| 
									
										
										
										
											2022-01-03 21:17:44 +00:00
										 |  |  |  |                 wf_json['aliases'][alias_index] = new_alias | 
					
						
							| 
									
										
										
										
											2020-05-04 13:58:24 +00:00
										 |  |  |  |         else: | 
					
						
							| 
									
										
										
										
											2022-01-03 21:17:44 +00:00
										 |  |  |  |             wf_json['aliases'].append(new_alias) | 
					
						
							| 
									
										
										
										
											2020-05-04 13:58:24 +00:00
										 |  |  |  |             changed = True | 
					
						
							| 
									
										
										
										
											2021-07-06 13:11:00 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |     # remove any aliases which are no longer in the actor profile | 
					
						
							| 
									
										
										
										
											2022-01-03 21:17:44 +00:00
										 |  |  |  |     remove_alias = [] | 
					
						
							|  |  |  |  |     for alias in aliases_not_found: | 
					
						
							|  |  |  |  |         for full_alias in wf_json['aliases']: | 
					
						
							|  |  |  |  |             if full_alias.startswith(alias + ':'): | 
					
						
							|  |  |  |  |                 remove_alias.append(full_alias) | 
					
						
							|  |  |  |  |     for full_alias in remove_alias: | 
					
						
							|  |  |  |  |         wf_json['aliases'].remove(full_alias) | 
					
						
							| 
									
										
										
										
											2021-07-06 13:11:00 +00:00
										 |  |  |  |         changed = True | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-16 10:24:04 +00:00
										 |  |  |  |     if _webfinger_update_avatar(wf_json, actor_json): | 
					
						
							|  |  |  |  |         changed = True | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     if _webfinger_update_vcard(wf_json, actor_json): | 
					
						
							| 
									
										
										
										
											2021-10-28 10:21:28 +00:00
										 |  |  |  |         changed = True | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-03 21:17:44 +00:00
										 |  |  |  |     if _webfinger_add_blog_link(wf_json, actor_json): | 
					
						
							| 
									
										
										
										
											2021-10-28 10:08:41 +00:00
										 |  |  |  |         changed = True | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-04 13:58:24 +00:00
										 |  |  |  |     return changed | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-28 17:20:43 +00:00
										 |  |  |  | def webfinger_update(base_dir: str, nickname: str, domain: str, | 
					
						
							|  |  |  |  |                      onion_domain: str, | 
					
						
							|  |  |  |  |                      cached_webfingers: {}) -> None: | 
					
						
							| 
									
										
										
										
											2022-01-03 21:17:44 +00:00
										 |  |  |  |     """Regenerates stored webfinger
 | 
					
						
							|  |  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2020-05-04 13:58:24 +00:00
										 |  |  |  |     handle = nickname + '@' + domain | 
					
						
							| 
									
										
										
										
											2022-01-03 21:17:44 +00:00
										 |  |  |  |     wf_subdir = '/wfendpoints' | 
					
						
							|  |  |  |  |     if not os.path.isdir(base_dir + wf_subdir): | 
					
						
							| 
									
										
										
										
											2020-05-04 13:58:24 +00:00
										 |  |  |  |         return | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-03 21:17:44 +00:00
										 |  |  |  |     filename = base_dir + wf_subdir + '/' + handle + '.json' | 
					
						
							| 
									
										
										
										
											2020-05-04 13:58:24 +00:00
										 |  |  |  |     onionify = False | 
					
						
							| 
									
										
										
										
											2021-12-25 20:43:43 +00:00
										 |  |  |  |     if onion_domain: | 
					
						
							|  |  |  |  |         if onion_domain in handle: | 
					
						
							|  |  |  |  |             handle = handle.replace(onion_domain, domain) | 
					
						
							| 
									
										
										
										
											2020-05-04 13:58:24 +00:00
										 |  |  |  |             onionify = True | 
					
						
							|  |  |  |  |     if not onionify: | 
					
						
							| 
									
										
										
										
											2022-01-03 21:17:44 +00:00
										 |  |  |  |         wf_json = load_json(filename) | 
					
						
							| 
									
										
										
										
											2020-05-04 13:58:24 +00:00
										 |  |  |  |     else: | 
					
						
							| 
									
										
										
										
											2022-01-03 21:17:44 +00:00
										 |  |  |  |         wf_json = load_json_onionify(filename, domain, onion_domain) | 
					
						
							|  |  |  |  |     if not wf_json: | 
					
						
							| 
									
										
										
										
											2020-05-04 13:58:24 +00:00
										 |  |  |  |         return | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-03 21:17:44 +00:00
										 |  |  |  |     actor_filename = base_dir + '/accounts/' + handle + '.json' | 
					
						
							|  |  |  |  |     actor_json = load_json(actor_filename) | 
					
						
							| 
									
										
										
										
											2021-12-26 10:29:52 +00:00
										 |  |  |  |     if not actor_json: | 
					
						
							| 
									
										
										
										
											2020-05-04 13:58:24 +00:00
										 |  |  |  |         return | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-03 21:17:44 +00:00
										 |  |  |  |     if _webfinger_updateFromProfile(wf_json, actor_json): | 
					
						
							|  |  |  |  |         if save_json(wf_json, filename): | 
					
						
							|  |  |  |  |             store_webfinger_in_cache(handle, wf_json, cached_webfingers) |