sedi-relay/relay/middleware.py
2022-04-08 22:05:02 -04:00

49 lines
1.5 KiB
Python

import logging
from aiohttp.web import HTTPUnauthorized
from json.decoder import JSONDecodeError
from urllib.parse import urlparse
from . import misc
# This will probably get merged into views.inbox
async def http_signatures_middleware(app, handler):
async def http_signatures_handler(request):
request['validated'] = False
request['actor'] = None
request['actor_domain'] = None
try:
request['data'] = await request.json()
except JSONDecodeError:
request['data'] = None
if 'signature' in request.headers and request.method == 'POST':
if 'actor' not in request['data']:
logging.verbose('Actor not in data')
raise HTTPUnauthorized(body='signature check failed, no actor in message')
if app['config'].is_banned(request['data']['actor']):
logging.verbose(f'Ignored request from banned actor: {request["actor"]["id"]}')
raise HTTPUnauthorized(body='banned')
request['actor'] = await misc.request(request['data']['actor'])
if not request['actor']:
logging.verbose(f'Failed to fetch actor: {request["actor"]["id"]}')
raise HTTPUnauthorized('failed to fetch actor')
actor_id = request['actor']['id']
request['actor_domain'] = urlparse(actor_id).hostname
if not (await misc.validate_signature(actor_id, request)):
logging.verbose(f'signature validation failed for: {actor_id}')
raise HTTPUnauthorized(body='signature check failed, signature did not match key')
return (await handler(request))
return (await handler(request))
return http_signatures_handler