diff options
author | cbdev <cb@cbcdn.com> | 2022-07-04 19:21:34 +0200 |
---|---|---|
committer | cbdev <cb@cbcdn.com> | 2022-07-04 19:21:34 +0200 |
commit | 507f0d060da30a8f65bec8b2ac1f08837d536b4c (patch) | |
tree | b2c5a1f9cc5080fb7f2586e2371fce443e43fbaa /backend/RemoteCookieAuth.py | |
parent | 4369d6a7f024f9ebf3c5f41a8fe17bfc65d0a820 (diff) | |
download | cargohold-507f0d060da30a8f65bec8b2ac1f08837d536b4c.tar.gz cargohold-507f0d060da30a8f65bec8b2ac1f08837d536b4c.tar.bz2 cargohold-507f0d060da30a8f65bec8b2ac1f08837d536b4c.zip |
Implement authentication modules for admin panel
Diffstat (limited to 'backend/RemoteCookieAuth.py')
-rw-r--r-- | backend/RemoteCookieAuth.py | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/backend/RemoteCookieAuth.py b/backend/RemoteCookieAuth.py new file mode 100644 index 0000000..4f3ef32 --- /dev/null +++ b/backend/RemoteCookieAuth.py @@ -0,0 +1,68 @@ +import requests +import sqlite3 +import http.cookies as ck +import time + +import config +import utils + +# This authentication provider assumes that a cookie containing a session ID +# has been set by some unspecified means (e.g. a login panel). This session ID +# is verified for authorization by calling a centralized verification endpoint +# which returns any entitlements in JSON. +# Authorized sessions are cached in a table in the local cargohold database +# for a limited time. + +cookie_name = "session" +validator = "https://stumpf.es/auth/cargohold" +session_cache_interval = 60*15 + +db = sqlite3.connect(config.database, check_same_thread = False) + +def login(env, post): + # Check if already using a known session + user = get(env) + if user: + return utils.redirect("/admin") + + # Check if session cookie present + cookies = ck.SimpleCookie(env.get('HTTP_COOKIE', '')) + if cookie_name not in cookies: + return utils.redirect(config.homepage) + + # Check if session ID valid + req = requests.get(validator, headers = {"Cookie": cookie_name + "=" + cookies[cookie_name].value}) + auth = req.json() + + if "entitlement" in auth and auth["entitlement"]["service"] == "cargohold": + # Create the user if not known + utils.ensure_user(auth["user"]) + + # Add to session cache + db.cursor().execute("INSERT INTO sessions (id, user, expire) VALUES (:id, :user, :expire)", {"id": cookies[cookie_name].value, "user": auth["user"], "expire": int(time.time() + min(auth["expire_in"], session_cache_interval))}) + db.commit() + return utils.redirect("/admin") + + return utils.redirect(config.homepage) + +def get(env): + # Check if session cookie present + cookies = ck.SimpleCookie(env.get('HTTP_COOKIE', '')) + if cookie_name not in cookies: + return None + + # Check if session ID is in local cache + data = db.cursor().execute("SELECT user, expire FROM sessions WHERE id = :id", {"id": cookies[cookie_name].value}) + sess = data.fetchone() + if sess and sess[1] > time.time(): + return {"user": sess[0], "expire": sess[1]} + + if sess: + # Prune expired sessions + db.cursor().execute("DELETE FROM sessions WHERE expire < :time", {"time": time.time()}) + db.commit() + return None + +def logout(): + # TODO + return None |