From e3bf4258aa741312fc7904a23d1b6f37fe1e2f88 Mon Sep 17 00:00:00 2001 From: Izalia Mae Date: Mon, 7 Nov 2022 08:18:25 -0500 Subject: [PATCH] create WKNodeinfo class and add nodeinfo 2.1 path --- relay/misc.py | 52 ++++++++++++++++++++++++++++++++++++++++++-------- relay/views.py | 22 ++++++++++----------- 2 files changed, 55 insertions(+), 19 deletions(-) diff --git a/relay/misc.py b/relay/misc.py index 1fc109c..64399fb 100644 --- a/relay/misc.py +++ b/relay/misc.py @@ -19,12 +19,18 @@ from .http_debug import http_debug app = None + HASHES = { 'sha1': SHA, 'sha256': SHA256, 'sha512': SHA512 } +NODEINFO_NS = { + '20': 'http://nodeinfo.diaspora.software/ns/schema/2.0', + '21': 'http://nodeinfo.diaspora.software/ns/schema/2.1' +} + def set_app(new_app): global app @@ -122,24 +128,28 @@ async def fetch_actor_key(actor): async def fetch_nodeinfo(domain): nodeinfo_url = None - wk_nodeinfo = await request(f'https://{domain}/.well-known/nodeinfo', sign_headers=False, activity=False) if not wk_nodeinfo: return - for link in wk_nodeinfo.get('links', ''): - if link['rel'] == 'http://nodeinfo.diaspora.software/ns/schema/2.0': - nodeinfo_url = link['href'] - break + wk_nodeinfo = WKNodeinfo(wk_nodeinfo) + + for version in ['20', '21']: + try: + nodeinfo_url = wk_nodeinfo.get_url(version) + + except KeyError: + pass if not nodeinfo_url: - return + logging.verbose(f'Failed to fetch nodeinfo url for domain: {domain}') + return False - nodeinfo_data = await request(nodeinfo_url, sign_headers=False, activity=False) + nodeinfo = await request(nodeinfo_url, sign_headers=False, activity=False) try: - return nodeinfo_data['software']['name'] + return nodeinfo['software']['name'] except KeyError: return False @@ -474,3 +484,29 @@ class Message(DotDict): return self.object.id return self.object + + +class WKNodeinfo(DotDict): + def __setitem__(self, key, value): + if key == 'links': + value = [DotDict(item) for item in value] + + DotDict.__setitem__(self, key, value) + + + @classmethod + def new(cls, v20, v21): + return cls({ + 'links': [ + {'rel': NODEINFO_NS['20'], 'href': v20}, + {'rel': NODEINFO_NS['21'], 'href': v21} + ] + }) + + + def get_url(self, version='20'): + for item in self.links: + if item.rel == NODEINFO_NS[version]: + return item.href + + raise KeyError(version) diff --git a/relay/views.py b/relay/views.py index 676024a..f72da29 100644 --- a/relay/views.py +++ b/relay/views.py @@ -162,10 +162,10 @@ async def webfinger(request): return json_response(data) -@register_route('GET', '/nodeinfo/2.0.json') +@register_route('GET', '/nodeinfo/{version:\d.\d\.json}') async def nodeinfo_2_0(request): + version = request.match_info['version'][:3] data = { - # XXX - is this valid for a relay? 'openRegistrations': True, 'protocols': ['activitypub'], 'services': { @@ -185,22 +185,22 @@ async def nodeinfo_2_0(request): 'metadata': { 'peers': request.app.database.hostnames }, - 'version': '2.0' + 'version': version } + if version == '2.1': + data['software']['repository'] = 'https://git.pleroma.social/pleroma/relay' + return json_response(data) @register_route('GET', '/.well-known/nodeinfo') async def nodeinfo_wellknown(request): - data = { - 'links': [ - { - 'rel': 'http://nodeinfo.diaspora.software/ns/schema/2.0', - 'href': f'https://{request.app.config.host}/nodeinfo/2.0.json' - } - ] - } + data = WKNodeinfo.new( + v20 = f'https://{request.app.config.host}/nodeinfo/2.0.json', + v21 = f'https://{request.app.config.host}/nodeinfo/2.1.json' + ) + return json_response(data)