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