From 3551611c8571c93e21d4a641d8e9f72d8e6a55ad Mon Sep 17 00:00:00 2001 From: Arti Zirk Date: Thu, 8 Oct 2020 23:11:35 +0300 Subject: [PATCH] Add API auth for doors --- kdoorweb/kdoorweb/api.py | 26 +++++++++++++++----------- kdoorweb/kdoorweb/db.py | 20 +++++++++++++++++++- kdoorweb/kdoorweb/web.py | 3 ++- 3 files changed, 36 insertions(+), 13 deletions(-) diff --git a/kdoorweb/kdoorweb/api.py b/kdoorweb/kdoorweb/api.py index 4a1615c..9a0177f 100644 --- a/kdoorweb/kdoorweb/api.py +++ b/kdoorweb/kdoorweb/api.py @@ -1,29 +1,33 @@ -from bottle import Bottle, request, response +import hashlib +from functools import partial + +from bottle import Bottle, request, response, HTTPError api = Bottle() +scrypt = partial(hashlib.scrypt, n=16384, r=8, p=1) + -# FIXME: Fix door api auth def check_api_auth(callback): def wrapper(*args, **kwargs): print("check api auth") + user, api_key = request.auth or (None, None) if "db" not in kwargs: - request.current_user = None - return callback(*args, **kwargs) - user = None - request.current_user = user - if user: - print(f"logged in as {user['user']}") - print(request.current_user) + return "Auth not possible, db not available" + user = kwargs["db"].get_door_by_name_and_api_key(user) or {} + stored_hash, salt = dict(user).get("api_key", ":").split(":") + api_hash = scrypt(api_key, salt=salt) + if user and api_hash == api_key: + request.current_door = user + print(f"logged in as {user['name']}") + print(user) return callback(*args, **kwargs) else: print("not logged in") return "Invalid authentication" return wrapper -# FIXME: db plugin not available yet -api.install(check_api_auth) @api.route("/") def index(): diff --git a/kdoorweb/kdoorweb/db.py b/kdoorweb/kdoorweb/db.py index aac736d..239c68d 100644 --- a/kdoorweb/kdoorweb/db.py +++ b/kdoorweb/kdoorweb/db.py @@ -83,7 +83,7 @@ class DB: ); create table doors ( id integer primary key, - name text, + name text unique, note text, api_key text, created text, @@ -180,6 +180,24 @@ class DB: """) return cur.fetchall() + def add_door(self, name, note, api_key): + self.add_doors([name, note, api_key, ]) + + def add_doors(self, doors): + self.db.executemany(""" + insert into doors(name, note, api_key, created, disabled) + values(?, ?, ?, ?, ?) + """, doors) + self.db.commit() + + def get_door(self, door_id): + cur = self.db.execute("select id, name, note, api_key, created, disabled from doors where id = ?", (door_id,)) + return cur.fetchone() + + def get_door_by_name(self, name): + cur = self.db.execute("select id, name, note, api_key, created, disabled from doors where name = ?", (name,)) + return cur.fetchone() + @staticmethod def import_ad(json_file): with open(json_file) as fp: diff --git a/kdoorweb/kdoorweb/web.py b/kdoorweb/kdoorweb/web.py index 81f6045..aa7f353 100644 --- a/kdoorweb/kdoorweb/web.py +++ b/kdoorweb/kdoorweb/web.py @@ -5,7 +5,7 @@ from bottle import Bottle, view, TEMPLATE_PATH, static_file, \ request, redirect, response, HTTPError from .db import SQLitePlugin -from .api import api +from .api import api, check_api_auth application = app = Bottle() @@ -56,6 +56,7 @@ app.install(db_plugin) app.install(check_auth) api.install(db_plugin) +api.install(check_api_auth) app.mount("/api/v1", api)