#!/usr/bin/env python3 """ Session interface middlewares to integrate the aiohttp app with Buckler. """ import json from datetime import datetime import aiohttp from aiohttp import web import config @web.middleware async def buckler_session(request, handler): """ Verifies the user with the configured Buckler app and retrieves any session data they may have. Redirects them to the login page otherwise. """ user_id = request.cookies.get('userid') user_sid = request.cookies.get('session') url = config.buckler['url'] + '/get_session' params = { 'app_id': config.buckler['app_id'], 'app_key': config.buckler['app_key'], 'userid': user_id, 'session': user_sid } async with aiohttp.ClientSession() as session: async with session.get(url, params=params) as resp: data = await resp.json() if data.get('error'): raise web.HTTPFound(location=config.buckler['login_url']) request['session'] = data['session_data'] request['meta'] = data['meta'] resp = await handler(request) if request['session'] != data['session_data']: # session data modified url = config.buckler['url'] + '/set_session' data = json.dumps(request['session']) session.post(url, params=params, data=data) # TODO: error handle? last_used = datetime.fromisoformat(request['meta']['last_used']) now = datetime.now(last_used.tzinfo) delta = now - last_used if delta.seconds > 600: resp.set_cookie( 'userid', user_id, max_age=30*24*60*60, secure=True, httponly=True) resp.set_cookie( 'session', user_sid, max_age=30*24*60*60, secure=True, httponly=True) return resp