from functools import wraps from aiohttp.web import json_response from autogestionale.database import User, Group, Event, Entry def needs(*needed): def decorator(func): @wraps(func) async def wrapper(request): request_json = await request.json() if not all(k in request_json.keys() for k in needed): return json_response({ 'err': 'malformed_request', 'msg': 'Missing one or more keys: {}.'.format( ", ".join(needed)) }, status=400) else: return func(request) return wrapper return decorator def auth_required(func): @wraps(func) async def wrapper(request): db = request.app['db'] headers = request.headers if 'Authorization' not in headers.keys(): return json_response({'err': 'malformed_request', 'msg': 'Missing Authorization header.'}, status=400) else: remote_token = headers['Authorization'] with db.get_session() as session: token = session.query(AccessToken) \ .filter_by(token=remote_token) \ .one_or_none() if not token: return json_response({'err': 'unauthorized', 'msg': 'The token is not valid.'}, status=401) elif not token.is_valid(): return json_response({'err': 'forbidden', 'msg': 'The token has expired.'}, status=403) else: return await func(request) return wrapper @needs('username', 'password') async def token_create(request): db = request.app['db'] request_json = await request.json() username = request_json['username'] password = request_json['password'] with db.get_session() as session: user = session.query(User) \ .filter_by(username=username) \ .one_or_none() if not user or user.password != password: return json_response({'err': 'invalid_credentials'}, status=400) with db.get_session() as session: token = AccessToken(user=user) session.add(token) return json_response({ 'token': token.token, 'created_at': token.created_at.isoformat(), 'expires_at': token.created_at.isoformat() }) @auth_required async def token_destroy(request): db = request.app['db'] remote_token = request.headers['Authorization'] with db.get_session() as session: token = session.query(AccessToken) \ .filter_by(token=remote_token) \ .one_or_none() token.is_active = False session.add(token) return json_response({}, status=200) # @auth_required async def group_list(request): db = request.app['db'] with db.get_session() as session: groups = session.query(Group).all() return json_response({ 'groups': [{ 'uid': grp.uid, 'name': grp.name, 'description': grp.description, 'created_at': grp.created_at.isoformat(), 'events': [{ 'uid': evt.uid, 'name': evt.name, 'starts_at': evt.starts_at.isoformat(), 'ends_at': evt.ends_at.isoformat() if evt.ends_at is not None else None, } for evt in grp.events] } for grp in groups] }) async def group_create(request): db = request.app['db'] request_json = await request.json() name = request_json['name'] description = request_json['description'] with db.get_session() as session: grp = Group(name=name, description=description) session.add(grp) return json_response({ 'group': { 'uid': grp.uid, 'name': grp.name, 'description': grp.description, 'created_at': grp.created_at.isoformat(), } }) async def event_list(request): db = request.app['db'] with db.get_session() as session: events = session.query(Event).all() return json_response({ 'events': [{ 'uid': evt.uid, 'name': evt.name, 'group_uid': evt.group_uid, 'balance': str(evt.get_balance()), 'entries': [{ 'uid': entr.uid, 'amount': str(entr.amount) } for entr in evt.entries] } for evt in events] }) async def event_create(request): db = request.app['db'] request_json = await request.json() group_uid = request_json['group_uid'] name = request_json['name'] # description = request_json['description'] starts_at = request_json['starts_at'] \ if 'starts_at' in request_json else None ends_at = request_json['ends_at'] \ if 'ends_at' in request_json else None with db.get_session() as session: evt = Event( group_uid=group_uid, name=name, starts_at=starts_at, ends_at=ends_at ) session.add(evt) return json_response({ 'event': { 'uid': evt.uid, 'group_uid': evt.group_uid, 'name': evt.name, 'created_at': evt.created_at.isoformat(), } }) async def entry_list(request): db = request.app['db'] with db.get_session() as session: entrys = session.query(Entry).all() return json_response({ 'entries': [{ 'uid': ent.uid, 'event_uid': ent.event_uid, 'amount': str(ent.amount), 'description': ent.description, 'created_at': ent.created_at.isoformat(), } for ent in entrys] }) async def entry_create(request): db = request.app['db'] request_json = await request.json() amount = request_json['amount'] description = request_json['description'] event_uid = request_json['event_uid'] with db.get_session() as session: ent = Entry( amount=amount, description=description, event_uid=event_uid ) session.add(ent) return json_response({ 'entry': { 'uid': ent.uid, 'amount': ent.amount, 'description': ent.description, 'event_uid': ent.event_uid, 'created_at': ent.created_at.isoformat(), } })