Compare commits

..

4 commits

Author SHA1 Message Date
Izalia Mae f7e1c6b0b8 make sure db config is a string when saving 2022-12-02 11:43:39 -05:00
Izalia Mae dcca1eb0dc fix HttpClient fetch_nodeinfo and get 2022-12-02 00:52:15 -05:00
Izalia Mae d5b9053f71 replace various classes with aputils classes 2022-12-02 00:50:57 -05:00
Izalia Mae d172439fac update aputils 2022-12-02 00:11:22 -05:00
6 changed files with 35 additions and 84 deletions

View file

@ -234,7 +234,8 @@ class RelayConfig(DotDict):
def save(self): def save(self):
config = { config = {
'db': self['db'], # just turning config.db into a string is good enough for now
'db': str(self.db),
'listen': self.listen, 'listen': self.listen,
'port': self.port, 'port': self.port,
'note': self.note, 'note': self.note,

View file

@ -1,9 +1,9 @@
import aputils
import logging import logging
import traceback import traceback
from aiohttp import ClientSession, ClientTimeout, TCPConnector from aiohttp import ClientSession, ClientTimeout, TCPConnector
from aiohttp.client_exceptions import ClientConnectorError, ServerTimeoutError from aiohttp.client_exceptions import ClientConnectorError, ServerTimeoutError
from aputils import Nodeinfo, WellKnownNodeinfo
from datetime import datetime from datetime import datetime
from cachetools import LRUCache from cachetools import LRUCache
from json.decoder import JSONDecodeError from json.decoder import JSONDecodeError
@ -87,7 +87,7 @@ class HttpClient:
headers = {} headers = {}
if sign_headers: if sign_headers:
headers.update(self.database.signer.sign_headers('GET', url)) headers.update(self.database.signer.sign_headers('GET', url, algorithm='original'))
try: try:
logging.verbose(f'Fetching resource: {url}') logging.verbose(f'Fetching resource: {url}')
@ -103,11 +103,7 @@ class HttpClient:
return return
if loads: if loads:
if issubclass(loads, DotDict): message = await resp.json(loads=loads)
message = await resp.json(loads=loads.new_from_json)
else:
message = await resp.json(loads=loads)
elif resp.content_type == MIMETYPES['activity']: elif resp.content_type == MIMETYPES['activity']:
message = await resp.json(loads=Message.new_from_json) message = await resp.json(loads=Message.new_from_json)
@ -142,11 +138,11 @@ class HttpClient:
instance = self.database.get_inbox(url) instance = self.database.get_inbox(url)
## Using the old algo by default is probably a better idea right now ## Using the old algo by default is probably a better idea right now
if instance and instance.get('software') not in {'mastodon'}: if instance and instance.get('software') in {'mastodon'}:
algorithm = aputils.Algorithm.RSASHA256 algorithm = 'hs2019'
else: else:
algorithm = aputils.Algorithm.HS2019 algorithm = 'original'
headers = {'Content-Type': 'application/activity+json'} headers = {'Content-Type': 'application/activity+json'}
headers.update(self.database.signer.sign_headers('POST', url, message, algorithm=algorithm)) headers.update(self.database.signer.sign_headers('POST', url, message, algorithm=algorithm))
@ -173,7 +169,10 @@ class HttpClient:
## Additional methods ## ## Additional methods ##
async def fetch_nodeinfo(self, domain): async def fetch_nodeinfo(self, domain):
nodeinfo_url = None nodeinfo_url = None
wk_nodeinfo = await self.get(f'https://{domain}/.well-known/nodeinfo', loads=WKNodeinfo) wk_nodeinfo = await self.get(
f'https://{domain}/.well-known/nodeinfo',
loads = WellKnownNodeinfo.new_from_json
)
for version in ['20', '21']: for version in ['20', '21']:
try: try:
@ -186,4 +185,4 @@ class HttpClient:
logging.verbose(f'Failed to fetch nodeinfo url for domain: {domain}') logging.verbose(f'Failed to fetch nodeinfo url for domain: {domain}')
return False return False
return await request(nodeinfo_url, loads=Nodeinfo) or False return await self.get(nodeinfo_url, loads=Nodeinfo.new_from_json) or False

View file

@ -37,10 +37,6 @@ def set_app(new_app):
app = new_app app = new_app
def build_signing_string(headers, used_headers):
return '\n'.join(map(lambda x: ': '.join([x.lower(), headers[x]]), used_headers))
def boolean(value): def boolean(value):
if isinstance(value, str): if isinstance(value, str):
if value.lower() in ['on', 'y', 'yes', 'true', 'enable', 'enabled', '1']: if value.lower() in ['on', 'y', 'yes', 'true', 'enable', 'enabled', '1']:
@ -279,12 +275,6 @@ class Message(DotDict):
return aputils.Signer.new_from_actor(self) return aputils.Signer.new_from_actor(self)
class Nodeinfo(DotDict):
@property
def swname(self):
return self.software.name
class Response(AiohttpResponse): class Response(AiohttpResponse):
@classmethod @classmethod
def new(cls, body='', status=200, headers=None, ctype='text'): def new(cls, body='', status=200, headers=None, ctype='text'):
@ -350,22 +340,3 @@ class View(AiohttpView):
@property @property
def database(self): def database(self):
return self.app.database return self.app.database
class WKNodeinfo(DotDict):
@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)

View file

@ -23,7 +23,7 @@ async def handle_relay(request):
cache[request.message.objectid] = message.id cache[request.message.objectid] = message.id
logging.debug(f'>> relay: {message}') logging.debug(f'>> relay: {message}')
niboxes = request.database.distill_inboxes(request.message) inboxes = request.database.distill_inboxes(request.message)
for inbox in inboxes: for inbox in inboxes:
request.app.push_message(inbox, message) request.app.push_message(inbox, message)

View file

@ -8,7 +8,7 @@ from pathlib import Path
from . import __version__, misc from . import __version__, misc
from .http_debug import STATS from .http_debug import STATS
from .misc import DotDict, Message, Response, WKNodeinfo from .misc import DotDict, Message, Response
from .processors import run_processor from .processors import run_processor
@ -158,57 +158,37 @@ async def webfinger(request):
if subject != f'acct:relay@{request.config.host}': if subject != f'acct:relay@{request.config.host}':
return Response.new_error(404, 'user not found', 'json') return Response.new_error(404, 'user not found', 'json')
data = { data = aputils.Webfinger.new(
'subject': subject, handle = 'relay',
'aliases': [request.config.actor], domain = request.config.host,
'links': [ actor = request.config.actor
{'href': request.config.actor, 'rel': 'self', 'type': 'application/activity+json'}, )
{'href': request.config.actor, 'rel': 'self', 'type': 'application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\"'}
]
}
return Response.new(data, ctype='json') return Response.new(data, ctype='json')
@register_route('GET', '/nodeinfo/{version:\d.\d\.json}') @register_route('GET', '/nodeinfo/{version:\d.\d\.json}')
async def nodeinfo_2_0(request): async def nodeinfo(request):
niversion = request.match_info['version'][:3] niversion = request.match_info['version'][:3]
data = {
'openRegistrations': not request.config.whitelist_enabled,
'protocols': ['activitypub'],
'services': {
'inbound': [],
'outbound': []
},
'software': {
'name': 'activityrelay',
'version': version
},
'usage': {
'localPosts': 0,
'users': {
'total': 1
}
},
'metadata': {
'peers': request.database.hostnames
},
'version': niversion
}
if version == '2.1': data = dict(
data['software']['repository'] = 'https://git.pleroma.social/pleroma/relay' name = 'activityrelay',
version = version,
protocols = ['activitypub'],
open_regs = not request.config.whitelist_enabled,
users = 1,
metadata = {'peers': request.database.hostnames}
)
return Response.new(data, ctype='json') if niversion == '2.1':
data['repo'] = 'https://git.pleroma.social/pleroma/relay'
return Response.new(aputils.Nodeinfo.new(**data), ctype='json')
@register_route('GET', '/.well-known/nodeinfo') @register_route('GET', '/.well-known/nodeinfo')
async def nodeinfo_wellknown(request): async def nodeinfo_wellknown(request):
data = WKNodeinfo.new( data = aputils.WellKnownNodeinfo.new_template(request.config.host)
v20 = f'https://{request.config.host}/nodeinfo/2.0.json',
v21 = f'https://{request.config.host}/nodeinfo/2.1.json'
)
return Response.new(data, ctype='json') return Response.new(data, ctype='json')

View file

@ -28,7 +28,7 @@ install_requires =
click >= 8.1.2 click >= 8.1.2
pycryptodome >= 3.14.1 pycryptodome >= 3.14.1
PyYAML >= 5.0.0 PyYAML >= 5.0.0
aputils @ https://git.barkshark.xyz/barkshark/aputils/archive/0.1.1.tar.gz aputils @ https://git.barkshark.xyz/barkshark/aputils/archive/0.1.2.tar.gz
python_requires = >=3.6 python_requires = >=3.6
[options.extras_require] [options.extras_require]