diff --git a/buckler.py b/buckler.py index d3dfca0..0877ca5 100644 --- a/buckler.py +++ b/buckler.py @@ -233,7 +233,8 @@ async def get_session(request): session = session[0] data = await conn.fetchrow( "SELECT user_info.username, app_user.session_data " - "FROM user_info, app_user " + "FROM user_info LEFT JOIN app_user " + "ON (user_info.id = app_user.user_id) " "WHERE user_info.id = $1 AND app_user.app_id = $2", session['user_id'], app['id']) @@ -248,11 +249,14 @@ async def get_session(request): await conn.close() data_meta = dict(data) - data_meta.update( - {'last_used': session['last_used'].isoformat()}) + data_meta['last_used'] = session['last_used'].isoformat() + data_meta['user_sid'] = user_sid + data_meta['user_id'] = user_id + session_data = data_meta.pop('session_data') data = { 'meta': data_meta, - 'session_data': json.loads(data_meta.pop('session_data'))} + 'session_data': json.loads(session_data) + } return web.json_response(data) else: @@ -268,7 +272,44 @@ async def get_session(request): @routes.post(config.url_prefix + '/set_session', name='set_session') async def set_session(request): """Allows an application to set a user app session.""" - pass + # TODO: only allow LAN IPs + app_id = request.query.get('app_id') + app_key = request.query.get('app_key') + user_id = request.query.get('userid') + user_sid = request.query.get('session') + + try: + app_id = int(app_id) + user_id = int(user_id) + assert all((app_id, app_key, user_id, user_sid)) + except (ValueError, AssertionError): + return web.json_response({'error': "Invalid credentials."}) + + conn = await request.app['pool'].acquire() + app = await conn.fetchrow("SELECT * FROM app_info WHERE id = $1", app_id) + if app: + if argon2.verify(app_key, app['key_hash']): + session = await conn.fetchrow( + "SELECT * FROM user_session " + "WHERE user_id = $1 AND id = $2 AND expires > NOW()", + user_id, user_sid) + if session: + session_data = await request.text() + # TODO: error handling, verify json + await conn.execute( + "UPDATE app_user SET session_data = $1 " + "WHERE user_id = $2 AND app_id = $3", + session_data, user_id, app_id) + await conn.close() + return web.json_response({'success': True}) + else: + error = {'error': "User ID or Session ID invalid."} + else: + error = {'error': "App ID or Key invalid."} + else: + error = {'error': "App ID or Key invalid."} + await conn.close() + return web.json_response(error) async def init_app(): diff --git a/buckler.sql b/buckler.sql index b576075..e67b2a0 100644 --- a/buckler.sql +++ b/buckler.sql @@ -41,7 +41,7 @@ CREATE TABLE IF NOT EXISTS app_info ( CREATE TABLE IF NOT EXISTS app_user ( user_id INTEGER references user_info(id) ON DELETE CASCADE, app_id INTEGER references app_info(id) ON DELETE CASCADE, - session_data JSON, + session_data JSON DEFAULT '{}', PRIMARY KEY (user_id, app_id) );