from functools import wraps from aiohttp.web import json_response from pos.database import User, ProductCategory, AccessToken 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 async def token_create(request): db = request.app['db'] request_json = await request.json() if not all(k in request_json.keys() for k in ['username', 'password']): return json_response({'err': 'malformed_request', 'msg': 'Missing username and/or password keys.'}, status=400) with db.get_session() as session: user = session.query(User) \ .filter_by(username=request_json['username']) \ .one_or_none() if not user or user.password != request_json['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 product_list(request): db = request.app['db'] with db.get_session() as session: categories = session.query(ProductCategory).all() return json_response({ 'categories': [{ 'uid': c.uid, 'name': c.name, 'products': [{ 'uid': p.uid, 'name': p.name, 'price': p.price } for p in c.products] } for c in categories] })