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):
config = {
'db': self['db'],
# just turning config.db into a string is good enough for now
'db': str(self.db),
'listen': self.listen,
'port': self.port,
'note': self.note,

View file

@ -1,9 +1,9 @@
import aputils
import logging
import traceback
from aiohttp import ClientSession, ClientTimeout, TCPConnector
from aiohttp.client_exceptions import ClientConnectorError, ServerTimeoutError
from aputils import Nodeinfo, WellKnownNodeinfo
from datetime import datetime
from cachetools import LRUCache
from json.decoder import JSONDecodeError
@ -87,7 +87,7 @@ class HttpClient:
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:
logging.verbose(f'Fetching resource: {url}')
@ -103,11 +103,7 @@ class HttpClient:
return
if loads:
if issubclass(loads, DotDict):
message = await resp.json(loads=loads.new_from_json)
else:
message = await resp.json(loads=loads)
message = await resp.json(loads=loads)
elif resp.content_type == MIMETYPES['activity']:
message = await resp.json(loads=Message.new_from_json)
@ -142,11 +138,11 @@ class HttpClient:
instance = self.database.get_inbox(url)
## Using the old algo by default is probably a better idea right now
if instance and instance.get('software') not in {'mastodon'}:
algorithm = aputils.Algorithm.RSASHA256
if instance and instance.get('software') in {'mastodon'}:
algorithm = 'hs2019'
else:
algorithm = aputils.Algorithm.HS2019
algorithm = 'original'
headers = {'Content-Type': 'application/activity+json'}
headers.update(self.database.signer.sign_headers('POST', url, message, algorithm=algorithm))
@ -173,7 +169,10 @@ class HttpClient:
## Additional methods ##
async def fetch_nodeinfo(self, domain):
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']:
try:
@ -186,4 +185,4 @@ class HttpClient:
logging.verbose(f'Failed to fetch nodeinfo url for domain: {domain}')
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
def build_signing_string(headers, used_headers):
return '\n'.join(map(lambda x: ': '.join([x.lower(), headers[x]]), used_headers))
def boolean(value):
if isinstance(value, str):
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)
class Nodeinfo(DotDict):
@property
def swname(self):
return self.software.name
class Response(AiohttpResponse):
@classmethod
def new(cls, body='', status=200, headers=None, ctype='text'):
@ -350,22 +340,3 @@ class View(AiohttpView):
@property
def database(self):
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
logging.debug(f'>> relay: {message}')
niboxes = request.database.distill_inboxes(request.message)
inboxes = request.database.distill_inboxes(request.message)
for inbox in inboxes:
request.app.push_message(inbox, message)

View file

@ -8,7 +8,7 @@ from pathlib import Path
from . import __version__, misc
from .http_debug import STATS
from .misc import DotDict, Message, Response, WKNodeinfo
from .misc import DotDict, Message, Response
from .processors import run_processor
@ -158,57 +158,37 @@ async def webfinger(request):
if subject != f'acct:relay@{request.config.host}':
return Response.new_error(404, 'user not found', 'json')
data = {
'subject': subject,
'aliases': [request.config.actor],
'links': [
{'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\"'}
]
}
data = aputils.Webfinger.new(
handle = 'relay',
domain = request.config.host,
actor = request.config.actor
)
return Response.new(data, ctype='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]
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['software']['repository'] = 'https://git.pleroma.social/pleroma/relay'
data = dict(
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')
async def nodeinfo_wellknown(request):
data = WKNodeinfo.new(
v20 = f'https://{request.config.host}/nodeinfo/2.0.json',
v21 = f'https://{request.config.host}/nodeinfo/2.1.json'
)
data = aputils.WellKnownNodeinfo.new_template(request.config.host)
return Response.new(data, ctype='json')

View file

@ -28,7 +28,7 @@ install_requires =
click >= 8.1.2
pycryptodome >= 3.14.1
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
[options.extras_require]