From 07772d9d42ade354e5047139464ba905f0c17b0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Madis=20M=C3=A4gi?= Date: Wed, 16 Aug 2023 02:59:42 +0300 Subject: [PATCH] Put users lookup in request context --- inventory-app/api.py | 12 ++++++------ inventory-app/common.py | 10 ++++++---- inventory-app/doorboy.py | 14 +++++++------- inventory-app/inventory.py | 4 ++-- inventory-app/main.py | 8 ++++++-- 5 files changed, 27 insertions(+), 21 deletions(-) diff --git a/inventory-app/api.py b/inventory-app/api.py index d2339ef..673db9a 100644 --- a/inventory-app/api.py +++ b/inventory-app/api.py @@ -5,7 +5,7 @@ from datetime import datetime, timedelta from functools import wraps from pymongo import MongoClient from flask import Blueprint, abort, g, make_response, redirect, render_template, request, jsonify -from common import CustomForm, build_query, flatten, format_name, spam, users, User +from common import CustomForm, build_query, flatten, format_name, spam, User page_api = Blueprint("api", __name__) db = MongoClient(const.MONGO_URI).get_default_database() @@ -26,7 +26,7 @@ def check_api_key(f): @page_api.route("/users") @check_api_key def view_users(): - resp = users + resp = g.users print(resp) return jsonify(resp) @@ -37,9 +37,9 @@ def get_group_cards(): if not request_groups: return "must specify groups in parameter", 400 print(f"groups requested are: {request_groups}") - print(f"found users: {users}") + print(f"found users: {g.users}") keys = [] - for u in users: + for u in g.users: for group in u.groups: if group in request_groups: keys.append(u.username) @@ -80,8 +80,8 @@ def view_slack_doorboy(): return "Invalid command was supplied" member = None - print(users) - for user in users: + print(g.users) + for user in g.users: if user.slack_id == request.form.get("user_id"): member = user diff --git a/inventory-app/common.py b/inventory-app/common.py index 74c11a3..afc7024 100644 --- a/inventory-app/common.py +++ b/inventory-app/common.py @@ -29,7 +29,7 @@ class User: return getattr(self, item) -def get_users(): +def get_users_inner(): config.load_incluster_config() api_instance = client.CustomObjectsApi() ret = api_instance.list_namespaced_custom_object("codemowers.io", "v1alpha1", OIDC_USERS_NAMESPACE, "oidcgatewayusers") @@ -42,8 +42,10 @@ def get_users(): groups.append(f"{group['prefix']}:{group['name']}") yield User(username, display_name, slack_id, groups) -users = list(get_users()) -users_lookup = {u.username : u for u in users} +def get_users(): + users = list(get_users_inner()) + users_lookup = {u.username : u for u in users} + return users, users_lookup class CustomForm(FlaskForm): # quite hacky @@ -108,7 +110,7 @@ def build_query(base_query, fields=[], sort_fields={}): val = request.args.get(key, type=tp) results = db.inventory.find(base_query).distinct(attr) if key in ("inventory_owner_username", "inventory_user_username"): - results = [{"username": u, "display_name": users_lookup.get(u, User()).display_name or u} for u in results] + results = [{"username": u, "display_name": g.users_lookup.get(u, User()).display_name or u} for u in results] results = sorted(results, key = lambda k: k["display_name"]) elif tp != list: results = sorted(results) diff --git a/inventory-app/doorboy.py b/inventory-app/doorboy.py index 9d3da09..afc7264 100644 --- a/inventory-app/doorboy.py +++ b/inventory-app/doorboy.py @@ -10,7 +10,7 @@ from wtforms.validators import DataRequired import pytz import const -from common import spam, users_lookup, users, User +from common import spam, User from oidc import login_required, read_user page_doorboy = Blueprint("doorboy", __name__) @@ -155,7 +155,7 @@ def view_doorboy_open(door): access_group = "k-space:workshop" else: access_group = "k-space:floor" - approved = access_group in users_lookup.get(user["username"], User()).groups + approved = access_group in g.users_lookup.get(user["username"], User()).groups db.eventlog.insert_one({ "method": "web", "approved": approved, @@ -195,7 +195,7 @@ def view_doorboy_slam(): @login_required def view_doorboy(): user = read_user() - workshop_access = "k-space:workshop" in users_lookup.get(user["username"], User()).groups + workshop_access = "k-space:workshop" in g.users_lookup.get(user["username"], User()).groups latest_events = db.eventlog.find({"component": "doorboy", "type":"open-door"}).sort([("timestamp", -1)]).limit(10); latest_swipes = db.inventory.find({"component": "doorboy", "type":"token"}).sort([("last_seen", -1)]).limit(10); return render_template("doorboy.html", **locals()) @@ -213,7 +213,7 @@ def view_own_cards(): def view_user_cards_inner(username): user = read_user() - subject_user = users_lookup.get(username) + subject_user = g.users_lookup.get(username) if not subject_user: return abort(404) is_self = user["username"] == subject_user["username"] @@ -246,7 +246,7 @@ def view_doorboy_admin(): user_keyfobs = {r["_id"] : r["cards"] for r in results} orphaned_keyfobs = user_keyfobs.pop(None) - no_keyfobs = [u for u in users if not user_keyfobs.get(u.username)] + no_keyfobs = [u for u in g.users if not user_keyfobs.get(u.username)] last_seen = {key : max(datetime_handle(card.get("last_seen")) for card in value) for key, value in user_keyfobs.items()} orphaned_keyfobs = sorted(orphaned_keyfobs, key = lambda o : (not bool(o.get("comment")), o.get("comment", ""))) @@ -350,8 +350,8 @@ def view_swipe(): status = "Permitted" if form["success"] else "Denied" username = token.get("inventory", {}).get("owner", {}).get("username", None) - if username and username in users_lookup: - subject = users_lookup[username].display_name or username + if username and username in g.users_lookup: + subject = g.users_lookup[username].display_name or username else: subject = "Unknown" msg = "%s %s door access for %s identified by keycard/keyfob" % (status, form["door"], subject) diff --git a/inventory-app/inventory.py b/inventory-app/inventory.py index ab6e3b5..6233058 100644 --- a/inventory-app/inventory.py +++ b/inventory-app/inventory.py @@ -11,7 +11,7 @@ from wtforms.form import Form from wtforms.validators import Length import const -from common import CustomForm, build_query, flatten, format_name, spam, users_lookup +from common import CustomForm, build_query, flatten, format_name, spam from oidc import page_oidc, login_required, read_user, do_login page_inventory = Blueprint("inventory", __name__) @@ -31,7 +31,7 @@ def view_inventory_view(item_id): def fetch_members_select(): choices = [(None, None)] - for username, user in users_lookup.items(): + for username, user in g.users_lookup.items(): choices.append((username, user.display_name or username)) choices = list(set(choices)) choices = sorted(choices, key = lambda k: k[1] or "") diff --git a/inventory-app/main.py b/inventory-app/main.py index adb5c66..a40eae4 100755 --- a/inventory-app/main.py +++ b/inventory-app/main.py @@ -44,7 +44,7 @@ from wtforms.form import Form from wtforms.validators import DataRequired import const -from common import CustomForm, devenv, flatten, format_name, spam, users_lookup, User +from common import CustomForm, devenv, flatten, format_name, spam, get_users, User from inventory import page_inventory from oidc import page_oidc, login_required, read_user from doorboy import page_doorboy @@ -61,7 +61,7 @@ def check_foreign_key_format(item): def render_user_display_name(username): if not username: return "" - display_name = users_lookup.get(username, User()).display_name + display_name = g.users_lookup.get(username, User()).display_name return display_name or username def render_markdown(text): @@ -182,6 +182,10 @@ def dev_only(f): return decorated_function +@app.before_request +def do_before_request(): + g.users, g.users_lookup = get_users() + @app.context_processor def inject_context(): return dict(devenv=devenv, inventory_assets_base_url=const.INVENTORY_ASSETS_BASE_URL, members_host=const.MEMBERS_HOST)