238 lines
6.4 KiB
Python
238 lines
6.4 KiB
Python
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(),
|
|
}
|
|
})
|