49 lines
1.5 KiB
Python
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
|