From c8b09d54f83b596d37e8816f72d0fb02e1009928 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Madis=20M=C3=A4gi?= Date: Sun, 6 Aug 2023 05:43:47 +0300 Subject: [PATCH] Fix more foreing key usages Also refactors user info to class --- inventory-app/api.py | 23 +++++--------- inventory-app/common.py | 26 +++++++++++++--- inventory-app/inventory.py | 34 +++++++++------------ inventory-app/main.py | 16 +++++----- inventory-app/templates/inventory_edit.html | 4 +-- inventory-app/templates/inventory_pick.html | 4 +-- 6 files changed, 56 insertions(+), 51 deletions(-) diff --git a/inventory-app/api.py b/inventory-app/api.py index 9e8e062..07aee7b 100644 --- a/inventory-app/api.py +++ b/inventory-app/api.py @@ -32,24 +32,17 @@ def view_users(): @page_api.route("/cards", methods=["POST"]) @check_api_key def get_group_cards(): - groups = request.json.get("groups", False) - if not groups: + request_groups = request.json.get("groups", False) + if not request_groups: return "must specify groups in parameter", 400 - print(f"groups requested are: {groups}") + print(f"groups requested are: {request_groups}") print(f"found users: {users}") - gu = [] + keys = [] for u in users: - for gr in u["status"]["groups"]: - group_name = f"{gr['prefix']}:{gr['name']}" - print(f"prefix is {gr['prefix']}") - print(f"name is {gr['name']}") - print(f"group name is {group_name}") - for group in groups: - print(f"checking {group}") - if group_name == group: - gu.append(u) - print(f"gu is: {gu}") - keys = list(map(lambda u: u["metadata"]["name"], gu)) + for group in u.groups: + if group in request_groups: + keys.append(u.username) + break print(f"keys are {keys}") flt = { "token.uid_hash": {"$exists": True}, diff --git a/inventory-app/common.py b/inventory-app/common.py index bb0f10d..087026d 100644 --- a/inventory-app/common.py +++ b/inventory-app/common.py @@ -8,6 +8,8 @@ from flask import g, request from flask_wtf import FlaskForm from pymongo import MongoClient from kubernetes import client, config +from typing import List +from dataclasses import dataclass, field import const @@ -16,14 +18,30 @@ OIDC_USERS_NAMESPACE = os.getenv("OIDC_USERS_NAMESPACE") db = MongoClient(const.MONGO_URI).get_default_database() +@dataclass +class User: + username: str = None + display_name: str = None + groups: List[str] = field(default_factory=list) + + def __getitem__(self, item): + return getattr(self, item) + + def get_users(): config.load_incluster_config() api_instance = client.CustomObjectsApi() ret = api_instance.list_namespaced_custom_object("codemowers.io", "v1alpha1", OIDC_USERS_NAMESPACE, "oidcgatewayusers") - return ret["items"] + for item in ret["items"]: + username = item['metadata']['name'] + display_name = item.get("spec", {}).get("customProfile", {}).get("name", None) + groups = [] + for group in item.get("status", {}).get("groups", []): + groups.append(f"{group['prefix']}:{group['name']}") + yield User(username, display_name, groups) -users = get_users() -users_lookup = {u['metadata']['name'] : u for u in users} +users = list(get_users()) +users_lookup = {u.username : u for u in users} class CustomForm(FlaskForm): # quite hacky @@ -90,7 +108,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, {}).get("spec", {}).get("customProfile", {}).get("name", u)} for u in results] + results = [{"username": u, "display_name": 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/inventory.py b/inventory-app/inventory.py index 18b9ca3..a7fc931 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 +from common import CustomForm, build_query, flatten, format_name, spam, users_lookup from oidc import page_oidc, login_required, read_user, do_login page_inventory = Blueprint("inventory", __name__) @@ -29,16 +29,10 @@ def view_inventory_view(item_id): photo_url = "%s/kspace-inventory/%s" % (base_url, item_id) return render_template(template , **locals()) -def fetch_members_select(existing_id=None): - q = [{"enabled": True}] - if existing_id: - q.append({"_id": ObjectId(existing_id)}) - objs = db.member.find(filter = { "$or": q }, projection = { - "full_name": 1 - }).sort("full_name", 1) +def fetch_members_select(): choices = [(None, None)] - for obj in objs: - choices.append((obj["_id"], obj["full_name"])) + for username, user in users_lookup.items(): + choices.append((username, user.display_name or username)) choices = list(set(choices)) return choices @@ -54,10 +48,10 @@ def setup_user_select(select_field, name_fields): existing_id = None if select_field.data and select_field.data != 'None': existing_id = select_field.data - select_field.choices = fetch_members_select(existing_id) + select_field.choices = fetch_members_select() if existing_id: values = dict(select_field.choices) - value = values.get(ObjectId(existing_id)) + value = values.get(existing_id) for name_field in name_fields: name_field.data = value @@ -73,18 +67,18 @@ def setup_default_owner(select_field): def member_select_coerce(x): x = str(x) if x and x != "None": - return ObjectId(x) + return x else: return None class MemberForm(Form): label = None - foreign_id = SelectField(choices=[], coerce=member_select_coerce) + username = SelectField(choices=[], coerce=member_select_coerce) display_name = StringField() def __init__(self, label=None, *args, **kwargs): super(MemberForm, self).__init__(*args, **kwargs) self.label = label - setup_user_select(self.foreign_id, [self.display_name]) + setup_user_select(self.username, [self.display_name]) class InventoryForm(Form): owner = FormField(MemberForm, label="Owner") @@ -112,7 +106,7 @@ class InventoryItemForm(CustomForm): _description_placeholder = "Insert Markdown here." description = TextAreaField('Description', [validators.optional(), validators.length(max=3000)], render_kw={"placeholder": _description_placeholder}) def setup_defaults_add(self): - setup_default_owner(self.inventory.form.owner.form.foreign_id) + setup_default_owner(self.inventory.form.owner.form.username) self.inventory.form.public.render_kw = {"checked": "checked"} self.inventory.form.public.data = "y" @@ -190,10 +184,10 @@ def save_inventory_item(item_id=None, **_): if not d["shortener"]["slug"]: d.pop("shortener") if "user" in d["inventory"]: - if not d["inventory"]["user"]["foreign_id"]: + if not d["inventory"]["user"]["username"]: d["inventory"].pop("user") if "owner" in d["inventory"]: - if not d["inventory"]["owner"]["foreign_id"]: + if not d["inventory"]["owner"]["username"]: d["inventory"].pop("owner") item_id = db.inventory.insert_one(d).inserted_id except pymongo.errors.DuplicateKeyError: @@ -402,7 +396,7 @@ def view_inventory_claim(item_id): user = read_user() db.inventory.update_one({ "_id": ObjectId(item_id), - "inventory.owner.foreign_id": None + "inventory.owner.username": None }, { "$set": { "inventory.owner.username": user["username"], @@ -419,7 +413,7 @@ def view_inventory_use(item_id): item = db.inventory.find_one({ "_id": ObjectId(item_id), "inventory.usable": True, - "inventory.user.foreign_id": None + "inventory.user.username": None }) if not item: return abort(404) diff --git a/inventory-app/main.py b/inventory-app/main.py index 0748339..1e46c02 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 +from common import CustomForm, devenv, flatten, format_name, spam, users_lookup, User from inventory import page_inventory from oidc import page_oidc, login_required, read_user from api import page_api @@ -60,7 +60,7 @@ def check_foreign_key_format(item): def render_user_display_name(username): if not username: return "" - display_name = users_lookup.get(username, {}).get("spec", {}).get("customProfile", {}).get("name", False) + display_name = users_lookup.get(username, User()).display_name return display_name or username def render_markdown(text): @@ -82,16 +82,16 @@ def render_last_seen(machine, stale_minutes=30): return Markup("opacity: 25%;") def render_owner_link(item): - owner = item.get("inventory", {}).get("owner") - if owner and owner.get("foreign_id") and owner.get("display_name"): - return Markup("%s" % (owner["foreign_id"], owner["display_name"])) + username = item.get("inventory", {}).get("owner", {}).get("username", False) + if username: + return Markup("%s" % (username, render_user_display_name(username))) else: return Markup("
" % (item["_id"])) def render_user_link(item): - user = item.get("inventory", {}).get("user") - if user and user.get("foreign_id") and user.get("display_name"): - return Markup("%s" % (user["foreign_id"], user["display_name"])) + username = item.get("inventory", {}).get("user", {}).get("username", False) + if username: + return Markup("%s" % (username, render_user_display_name(username))) elif item.get("inventory", {}).get("usable"): return Markup("
" % (item["_id"])) else: diff --git a/inventory-app/templates/inventory_edit.html b/inventory-app/templates/inventory_edit.html index 9ab4fad..1eb5c9d 100644 --- a/inventory-app/templates/inventory_edit.html +++ b/inventory-app/templates/inventory_edit.html @@ -66,12 +66,12 @@ Owner - {{ form.inventory.owner.foreign_id }} + {{ form.inventory.owner.username }} Current user - {{ form.inventory.user.foreign_id }} + {{ form.inventory.user.username }} diff --git a/inventory-app/templates/inventory_pick.html b/inventory-app/templates/inventory_pick.html index b21f9f1..52dbdd5 100644 --- a/inventory-app/templates/inventory_pick.html +++ b/inventory-app/templates/inventory_pick.html @@ -16,8 +16,8 @@ {% for item in items %} {{ item | format_name }} {{ item.comment }} - {% if item.inventory.owner %}{{ item.inventory.owner.username | display_name }}{% endif %} - {% if item.inventory.user %}{{ item.inventory.user.username | display_name }}{% endif %} + {% if item.inventory.owner %}{{ item.inventory.owner.username | display_name }}{% endif %} + {% if item.inventory.user %}{{ item.inventory.user.username | display_name }}{% endif %}