Browse Source

Basic auth test

Hal De 4 years ago
parent
commit
0fb07de36f
1 changed files with 17 additions and 5 deletions
  1. 17 5
      app/app.py

+ 17 - 5
app/app.py

@@ -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):