__filename__ = "daemon_get_masto_api.py" __author__ = "Bob Mottram" __license__ = "AGPL3+" __version__ = "1.5.0" __maintainer__ = "Bob Mottram" __email__ = "bob@libreserver.org" __status__ = "Production" __module_group__ = "Core GET" import json from httpheaders import set_headers from httpcodes import write2 from mastoapiv1 import masto_api_v1_response from mastoapiv2 import masto_api_v2_response from siteactive import referer_is_active from httpcodes import http_400 from httpcodes import http_404 from httpcodes import http_503 from utils import get_json_content_from_accept from utils import convert_domains from utils import local_network_host from crawlers import update_known_crawlers from blocking import broch_mode_is_active from daemon_utils import has_accept def masto_api(self, path: str, calling_domain: str, ua_str: str, authorized: bool, http_prefix: str, base_dir: str, nickname: str, domain: str, domain_full: str, onion_domain: str, i2p_domain: str, translate: {}, registration: bool, system_language: str, project_version: str, custom_emoji: [], show_node_info_accounts: bool, referer_domain: str, debug: bool, known_crawlers: {}, sites_unavailable: [], unit_test: bool, allow_local_network_access: bool) -> bool: if _masto_api_v2(self, path, calling_domain, ua_str, authorized, http_prefix, base_dir, nickname, domain, domain_full, onion_domain, i2p_domain, translate, registration, system_language, project_version, show_node_info_accounts, referer_domain, debug, 5, known_crawlers, sites_unavailable, unit_test, allow_local_network_access): return True return _masto_api_v1(self, path, calling_domain, ua_str, authorized, http_prefix, base_dir, nickname, domain, domain_full, onion_domain, i2p_domain, translate, registration, system_language, project_version, custom_emoji, show_node_info_accounts, referer_domain, debug, 5, known_crawlers, sites_unavailable, unit_test, allow_local_network_access) def _masto_api_v1(self, path: str, calling_domain: str, ua_str: str, authorized: bool, http_prefix: str, base_dir: str, nickname: str, domain: str, domain_full: str, onion_domain: str, i2p_domain: str, translate: {}, registration: bool, system_language: str, project_version: str, custom_emoji: [], show_node_info_accounts: bool, referer_domain: str, debug: bool, calling_site_timeout: int, known_crawlers: {}, sites_unavailable: [], unit_test: bool, allow_local_network_access: bool) -> bool: """This is a vestigil mastodon API for the purpose of returning an empty result to sites like https://mastopeek.app-dist.eu """ if not path.startswith('/api/v1/'): return False if not referer_domain: if not (debug and unit_test): print('mastodon api request has no referer domain ' + str(ua_str)) http_400(self) return True if referer_domain == domain_full: print('mastodon api request from self') http_400(self) return True if self.server.masto_api_is_active: print('mastodon api is busy during request from ' + referer_domain) http_503(self) return True self.server.masto_api_is_active = True # is this a real website making the call ? if not debug and not unit_test and referer_domain: # Does calling_domain look like a domain? if ' ' in referer_domain or \ ';' in referer_domain or \ '.' not in referer_domain: print('mastodon api ' + 'referer does not look like a domain ' + referer_domain) http_400(self) self.server.masto_api_is_active = False return True if not allow_local_network_access: if local_network_host(referer_domain): print('mastodon api referer domain is from the ' + 'local network ' + referer_domain) http_400(self) self.server.masto_api_is_active = False return True if not referer_is_active(http_prefix, referer_domain, ua_str, calling_site_timeout, sites_unavailable): print('mastodon api referer url is not active ' + referer_domain) http_400(self) self.server.masto_api_is_active = False return True print('mastodon api v1: ' + path) print('mastodon api v1: authorized ' + str(authorized)) print('mastodon api v1: nickname ' + str(nickname)) print('mastodon api v1: referer ' + str(referer_domain)) crawl_time = \ update_known_crawlers(ua_str, base_dir, known_crawlers, self.server.last_known_crawler) if crawl_time is not None: self.server.last_known_crawler = crawl_time broch_mode = broch_mode_is_active(base_dir) send_json, send_json_str = \ masto_api_v1_response(path, calling_domain, ua_str, authorized, http_prefix, base_dir, nickname, domain, domain_full, onion_domain, i2p_domain, translate, registration, system_language, project_version, custom_emoji, show_node_info_accounts, broch_mode) if send_json is not None: msg_str = json.dumps(send_json) msg_str = convert_domains(calling_domain, referer_domain, msg_str, http_prefix, domain, onion_domain, i2p_domain) msg = msg_str.encode('utf-8') msglen = len(msg) if has_accept(self, calling_domain): protocol_str = \ get_json_content_from_accept(self.headers.get('Accept')) set_headers(self, protocol_str, msglen, None, calling_domain, True) else: set_headers(self, 'application/ld+json', msglen, None, calling_domain, True) write2(self, msg) if send_json_str: print(send_json_str) self.server.masto_api_is_active = False return True # no api endpoints were matched http_404(self, 1) self.server.masto_api_is_active = False return True def _masto_api_v2(self, path: str, calling_domain: str, ua_str: str, authorized: bool, http_prefix: str, base_dir: str, nickname: str, domain: str, domain_full: str, onion_domain: str, i2p_domain: str, translate: {}, registration: bool, system_language: str, project_version: str, show_node_info_accounts: bool, referer_domain: str, debug: bool, calling_site_timeout: int, known_crawlers: {}, sites_unavailable: [], unit_test: bool, allow_local_network_access: bool) -> bool: """This is a vestigil mastodon v2 API for the purpose of returning an empty result to sites like https://mastopeek.app-dist.eu """ if not path.startswith('/api/v2/'): return False if not referer_domain: if not (debug and unit_test): print('mastodon api v2 request has no referer domain ' + str(ua_str)) http_400(self) return True if referer_domain == domain_full: print('mastodon api v2 request from self') http_400(self) return True if self.server.masto_api_is_active: print('mastodon api v2 is busy during request from ' + referer_domain) http_503(self) return True self.server.masto_api_is_active = True # is this a real website making the call ? if not debug and not unit_test and referer_domain: # Does calling_domain look like a domain? if ' ' in referer_domain or \ ';' in referer_domain or \ '.' not in referer_domain: print('mastodon api v2 ' + 'referer does not look like a domain ' + referer_domain) http_400(self) self.server.masto_api_is_active = False return True if not allow_local_network_access: if local_network_host(referer_domain): print('mastodon api v2 referer domain is from the ' + 'local network ' + referer_domain) http_400(self) self.server.masto_api_is_active = False return True if not referer_is_active(http_prefix, referer_domain, ua_str, calling_site_timeout, sites_unavailable): print('mastodon api v2 referer url is not active ' + referer_domain) http_400(self) self.server.masto_api_is_active = False return True print('mastodon api v2: ' + path) print('mastodon api v2: authorized ' + str(authorized)) print('mastodon api v2: nickname ' + str(nickname)) print('mastodon api v2: referer ' + str(referer_domain)) crawl_time = \ update_known_crawlers(ua_str, base_dir, known_crawlers, self.server.last_known_crawler) if crawl_time is not None: self.server.last_known_crawler = crawl_time broch_mode = broch_mode_is_active(base_dir) send_json, send_json_str = \ masto_api_v2_response(path, calling_domain, ua_str, http_prefix, base_dir, domain, domain_full, onion_domain, i2p_domain, translate, registration, system_language, project_version, show_node_info_accounts, broch_mode) if send_json is not None: msg_str = json.dumps(send_json) msg_str = convert_domains(calling_domain, referer_domain, msg_str, http_prefix, domain, onion_domain, i2p_domain) msg = msg_str.encode('utf-8') msglen = len(msg) if has_accept(self, calling_domain): protocol_str = \ get_json_content_from_accept(self.headers.get('Accept')) set_headers(self, protocol_str, msglen, None, calling_domain, True) else: set_headers(self, 'application/ld+json', msglen, None, calling_domain, True) write2(self, msg) if send_json_str: print(send_json_str) self.server.masto_api_is_active = False return True # no api v2 endpoints were matched http_404(self, 2) self.server.masto_api_is_active = False return True