From 4cd0c6902839368c25f543d966279043a622e988 Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Tue, 15 Feb 2022 15:01:18 +0000 Subject: [PATCH] Option to display actor vcard --- daemon.py | 10 ++++---- epicyon.py | 16 ++++++++++++ session.py | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 93 insertions(+), 5 deletions(-) diff --git a/daemon.py b/daemon.py index abbe0cacd..5c798e949 100644 --- a/daemon.py +++ b/daemon.py @@ -1187,8 +1187,8 @@ class PubServer(BaseHTTPRequestHandler): show_node_info_accounts, referer_domain, debug, 5) - def _get_vcard(self, base_dir: str, path: str, calling_domain: str, - referer_domain: str, domain: str, debug: bool) -> bool: + def _show_vcard(self, base_dir: str, path: str, calling_domain: str, + referer_domain: str, domain: str, debug: bool) -> bool: if not self._has_accept(calling_domain): return False if 'text/vcard' not in self.headers['Accept']: @@ -13653,9 +13653,9 @@ class PubServer(BaseHTTPRequestHandler): fitness_performance(getreq_start_time, self.server.fitness, '_GET', 'start', self.server.debug) - if self._get_vcard(self.server.base_dir, - self.path, calling_domain, referer_domain, - self.server.domain, self.server.debug): + if self._show_vcard(self.server.base_dir, + self.path, calling_domain, referer_domain, + self.server.domain, self.server.debug): return # Since fediverse crawlers are quite active, diff --git a/epicyon.py b/epicyon.py index 4e5eb7128..75584c378 100644 --- a/epicyon.py +++ b/epicyon.py @@ -43,6 +43,7 @@ from posts import get_user_url from posts import check_domains from session import create_session from session import get_json +from session import get_vcard from session import download_html from newswire import get_rss from filters import add_filter @@ -288,6 +289,8 @@ parser.add_argument('--socnet', dest='socnet', type=str, parser.add_argument('--postsraw', dest='postsraw', type=str, default=None, help='Show raw json of posts for the given handle') +parser.add_argument('--vcard', dest='vcard', type=str, default=None, + help='Show the vcard for a given activitypub actor url') parser.add_argument('--json', dest='json', type=str, default=None, help='Show the json for a given activitypub url') parser.add_argument('--htmlpost', dest='htmlpost', type=str, default=None, @@ -967,6 +970,19 @@ if args.json: pprint(test_json) sys.exit() +if args.vcard: + session = create_session(None) + if not args.domain: + args.domain = get_config_param(base_dir, 'domain') + domain = '' + if args.domain: + domain = args.domain + test_vcard = get_vcard(session, args.vcard, as_header, + None, debug, __version__, http_prefix, domain) + if test_vcard: + print(test_vcard) + sys.exit() + if args.htmlpost: session = create_session(None) profile_str = 'https://www.w3.org/ns/activitystreams' diff --git a/session.py b/session.py index e4c4aa69e..7ef9eba38 100644 --- a/session.py +++ b/session.py @@ -246,6 +246,78 @@ def get_json(signing_priv_key_pem: str, None, quiet, debug, True) +def get_vcard(session, url: str, params: {}, debug: bool, + version: str = '1.3.0', http_prefix: str = 'https', + domain: str = 'testdomain', + timeout_sec: int = 20, quiet: bool = False) -> {}: + if not isinstance(url, str): + if debug and not quiet: + print('url: ' + str(url)) + print('ERROR: get_vcard failed, url should be a string') + return None + headers = { + 'Accept': 'text/vcard' + } + session_params = {} + session_headers = {} + if headers: + session_headers = headers + if params: + session_params = params + session_headers['User-Agent'] = 'Epicyon/' + version + if domain: + session_headers['User-Agent'] += \ + '; +' + http_prefix + '://' + domain + '/' + if not session: + if not quiet: + print('WARN: get_vcard failed, no session specified for get_vcard') + return None + + if debug: + HTTPConnection.debuglevel = 1 + + try: + result = session.get(url, headers=session_headers, + params=session_params, timeout=timeout_sec) + if result.status_code != 200: + if result.status_code == 401: + print("WARN: get_vcard " + url + ' rejected by secure mode') + elif result.status_code == 403: + print('WARN: get_vcard Forbidden url: ' + url) + elif result.status_code == 404: + print('WARN: get_vcard Not Found url: ' + url) + elif result.status_code == 410: + print('WARN: get_vcard no longer available url: ' + url) + else: + print('WARN: get_vcard url: ' + url + + ' failed with error code ' + + str(result.status_code) + + ' headers: ' + str(session_headers)) + return result.content + except requests.exceptions.RequestException as ex: + session_headers2 = session_headers.copy() + if session_headers2.get('Authorization'): + session_headers2['Authorization'] = 'REDACTED' + if debug and not quiet: + print('EX: get_vcard failed, url: ' + str(url) + ', ' + + 'headers: ' + str(session_headers2) + ', ' + + 'params: ' + str(session_params) + ', ' + str(ex)) + except ValueError as ex: + session_headers2 = session_headers.copy() + if session_headers2.get('Authorization'): + session_headers2['Authorization'] = 'REDACTED' + if debug and not quiet: + print('EX: get_vcard failed, url: ' + str(url) + ', ' + + 'headers: ' + str(session_headers2) + ', ' + + 'params: ' + str(session_params) + ', ' + str(ex)) + except SocketError as ex: + if not quiet: + if ex.errno == errno.ECONNRESET: + print('EX: get_vcard failed, ' + + 'connection was reset during get_vcard ' + str(ex)) + return None + + def download_html(signing_priv_key_pem: str, session, url: str, headers: {}, params: {}, debug: bool, version: str = '1.3.0', http_prefix: str = 'https',