|
@@ -8,8 +8,10 @@ import json
|
|
|
from datetime import datetime as dt
|
|
from datetime import datetime as dt
|
|
|
from datetime import timedelta as td
|
|
from datetime import timedelta as td
|
|
|
from typing import Any, Optional
|
|
from typing import Any, Optional
|
|
|
|
|
+from functools import wraps
|
|
|
|
|
+from secrets import compare_digest
|
|
|
from databases import Database
|
|
from databases import Database
|
|
|
-from quart import jsonify, request, render_template_string, abort
|
|
|
|
|
|
|
+from quart import jsonify, request, render_template_string, abort, current_app
|
|
|
from quart.json import JSONEncoder
|
|
from quart.json import JSONEncoder
|
|
|
from quart_openapi import Pint, Resource
|
|
from quart_openapi import Pint, Resource
|
|
|
from http import HTTPStatus
|
|
from http import HTTPStatus
|
|
@@ -114,10 +116,6 @@ class AuthMiddleware:
|
|
|
if ((header == bytes(app.config['AUTH_HEADER'].lower(), 'utf-8')) and
|
|
if ((header == bytes(app.config['AUTH_HEADER'].lower(), 'utf-8')) and
|
|
|
(value == bytes(app.config['AUTH_SECRET'], 'utf-8'))):
|
|
(value == bytes(app.config['AUTH_SECRET'], 'utf-8'))):
|
|
|
return await self.app(scope, receive, send)
|
|
return await self.app(scope, receive, send)
|
|
|
- for device in app.cache['devices']:
|
|
|
|
|
- if ((header == bytes('{}_{}'.format(app.config['AUTH_HEADER'].lower(), device), 'utf-8')) and
|
|
|
|
|
- (value == bytes(app.cache['devices'][device], 'utf-8'))):
|
|
|
|
|
- return await self.app(scope, receive, send)
|
|
|
|
|
# Paths "/openapi.json" and "/ui" do not require auth
|
|
# Paths "/openapi.json" and "/ui" do not require auth
|
|
|
if (('path' in scope) and
|
|
if (('path' in scope) and
|
|
|
((scope['path'] in NO_AUTH_ROUTES) or
|
|
((scope['path'] in NO_AUTH_ROUTES) or
|
|
@@ -132,6 +130,19 @@ class AuthMiddleware:
|
|
|
'body': b'Authorization requred',
|
|
'body': b'Authorization requred',
|
|
|
'more_body': False})
|
|
'more_body': False})
|
|
|
|
|
|
|
|
|
|
+def authRequired(func):
|
|
|
|
|
+ @wraps(func)
|
|
|
|
|
+ async def authWrapper(*args, **kwargs):
|
|
|
|
|
+ auth = request.authorization
|
|
|
|
|
+ if ((auth is not None) and
|
|
|
|
|
+ (auth.type == "basic") and
|
|
|
|
|
+ (auth.username in current_app.cache['devices']) and
|
|
|
|
|
+ (compare_digest(auth.password, current_app.cache['devices'][auth.username]))):
|
|
|
|
|
+ return await func(*args, **kwargs)
|
|
|
|
|
+ else:
|
|
|
|
|
+ abort(401)
|
|
|
|
|
+ return authWrapper
|
|
|
|
|
+
|
|
|
app.asgi_app = AuthMiddleware(app.asgi_app)
|
|
app.asgi_app = AuthMiddleware(app.asgi_app)
|
|
|
db = PintDB(app)
|
|
db = PintDB(app)
|
|
|
|
|
|
|
@@ -752,6 +763,7 @@ class Hangup(Resource):
|
|
|
|
|
|
|
|
@app.route('/users/states')
|
|
@app.route('/users/states')
|
|
|
class UsersStates(Resource):
|
|
class UsersStates(Resource):
|
|
|
|
|
+ @authRequired
|
|
|
@app.response(HTTPStatus.OK, 'JSON reply with user:state map or error message')
|
|
@app.response(HTTPStatus.OK, 'JSON reply with user:state map or error message')
|
|
|
@app.response(HTTPStatus.UNAUTHORIZED, 'Authorization required')
|
|
@app.response(HTTPStatus.UNAUTHORIZED, 'Authorization required')
|
|
|
async def get(self):
|
|
async def get(self):
|