From 8b9ac4b92bac89e1451e65608fff963d5a5b4837 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Madis=20M=C3=A4gi?= Date: Sat, 5 Aug 2023 19:28:10 +0300 Subject: [PATCH] Read user display names from kubernetes --- inventory-app/api.py | 21 ++----------- inventory-app/common.py | 25 +++++++++++----- inventory-app/inventory.py | 30 +++++-------------- inventory-app/main.py | 10 +++++-- inventory-app/templates/inventory_filter.html | 2 +- inventory-app/templates/inventory_grid.html | 4 +-- inventory-app/templates/inventory_pick.html | 4 +-- inventory-app/templates/inventory_view.html | 4 +-- 8 files changed, 43 insertions(+), 57 deletions(-) diff --git a/inventory-app/api.py b/inventory-app/api.py index 3eacd37..9e8e062 100644 --- a/inventory-app/api.py +++ b/inventory-app/api.py @@ -4,13 +4,11 @@ import const 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 -from kubernetes import client, config +from common import CustomForm, build_query, flatten, format_name, spam, users page_api = Blueprint("api", __name__) db = MongoClient(const.MONGO_URI).get_default_database() api_key = os.getenv("INVENTORY_API_KEY") -OIDC_USERS_NAMESPACE = os.getenv("OIDC_USERS_NAMESPACE") def check_api_key(f): @wraps(f) @@ -24,19 +22,10 @@ def check_api_key(f): return f(*args, **kwargs) return decorated_function -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") - resp = [] - for item in ret["items"]: - resp.append(item) - return resp - @page_api.route("/users") @check_api_key def view_users(): - resp = get_users() + resp = users print(resp) return jsonify(resp) @@ -47,7 +36,6 @@ def get_group_cards(): if not groups: return "must specify groups in parameter", 400 print(f"groups requested are: {groups}") - users = get_users() print(f"found users: {users}") gu = [] for u in users: @@ -73,10 +61,7 @@ def get_group_cards(): } found = [] for obj in db.inventory.find(flt, prj): - del obj["_id"] - if obj["inventory"] and obj["inventory"]["owner"] and type(obj["inventory"]["owner"]["foreign_id"]) != str: - del obj["inventory"] - found.append(obj) + found.append({"token": obj["token"]}) fl = list(found) print(f"found tokens are: {fl}") return jsonify(fl) diff --git a/inventory-app/common.py b/inventory-app/common.py index 52f6cfc..0845ed9 100644 --- a/inventory-app/common.py +++ b/inventory-app/common.py @@ -1,3 +1,4 @@ +import os import collections.abc from functools import wraps @@ -6,13 +7,23 @@ from bson.objectid import ObjectId from flask import g, request from flask_wtf import FlaskForm from pymongo import MongoClient +from kubernetes import client, config import const devenv = const.ENVIRONMENT_TYPE == "DEV" +OIDC_USERS_NAMESPACE = os.getenv("OIDC_USERS_NAMESPACE") db = MongoClient(const.MONGO_URI).get_default_database() +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"] + +users = get_users() +users_lookup = {u['metadata']['name'] : u for u in users} class CustomForm(FlaskForm): # quite hacky @@ -33,7 +44,7 @@ def inventory_fetch(owner=True, item_type=None): if item_type: d["type"] = item_type if owner: - d["inventory.owner.foreign_id"] = user["username"] + d["inventory.owner.username"] = user["username"] kwargs["item"] = db.inventory.find_one(d) return f(*args, **kwargs) return decorated_function @@ -70,23 +81,23 @@ def build_query(base_query, fields=[], sort_fields={}): q = base_query.copy() for attr, title, tp in fields: key = attr.replace(".", "_") - if tp == list: + if key in ("inventory_owner_username", "inventory_user_username"): + val = request.args.get(key, type=dict) + elif tp == list: val = request.args.getlist(key) val = list(map(str, val)) else: val = request.args.get(key, type=tp) results = db.inventory.find(base_query).distinct(attr) - if tp == ObjectId: + if key in ("inventory_owner_username", "inventory_user_username"): + results = [{"username": u, "display_name": users_lookup[u]["spec"]["customProfile"]["name"]} for u in results] results = sorted(results, key = lambda k: k["display_name"]) elif tp != list: results = sorted(results) results = list(map(tp, results)) selectors.append((key, title, results, val)) if val: - if tp == ObjectId: - attr = attr + ".foreign_id" - q[attr] = val - elif tp == list and attr == "type": + if tp == list and attr == "type": q[attr] = { "$nin" : val } elif tp == list: q[attr] = { "$in" : val } diff --git a/inventory-app/inventory.py b/inventory-app/inventory.py index cc9f979..18b9ca3 100644 --- a/inventory-app/inventory.py +++ b/inventory-app/inventory.py @@ -360,8 +360,8 @@ def view_inventory(slug=None): template = "inventory_public.html" public_view = True else: - fields.append(("inventory.owner", "Owner", ObjectId)) - fields.append(("inventory.user", "User", ObjectId)) + fields.append(("inventory.owner.username", "Owner", list)) + fields.append(("inventory.user.username", "User", list)) if slug and not public_view: template = "inventory_pick.html" if request.path.startswith("/m/inventory/clone-with-slug"): @@ -378,9 +378,9 @@ def view_inventory(slug=None): if grid: template = "inventory_grid.html" if user: - q["inventory.user.foreign_id"] = user + q["inventory.user.username"] = user if owner: - q["inventory.owner.foreign_id"] = owner + q["inventory.owner.username"] = owner q2 = {"type": {"$ne": "token"}} if not public_view and owner_disabled: @@ -390,22 +390,6 @@ def view_inventory(slug=None): q, selectors, sort_field, sort_field_final, sort_direction = build_query(dict(q), fields, sort_fields) items = db.inventory.aggregate([ { "$match": q }, - { - "$lookup": { - "from": 'member', - "localField": 'inventory.owner.foreign_id', - "foreignField": '_id', - "as": 'Owner' - } - }, - { - "$lookup": { - "from": 'member', - "localField": 'inventory.user.foreign_id', - "foreignField": '_id', - "as": 'User' - } - }, { "$match": q2 }, { "$sort": { sort_field_final : 1 if sort_direction == "asc" else -1 } } ]) @@ -421,7 +405,7 @@ def view_inventory_claim(item_id): "inventory.owner.foreign_id": None }, { "$set": { - "inventory.owner.foreign_id": user["username"], + "inventory.owner.username": user["username"], "inventory.owner.display_name": user["name"], }, }) @@ -444,7 +428,7 @@ def view_inventory_use(item_id): "_id": ObjectId(item["_id"]) }, { "$set": { - "inventory.user.foreign_id": ObjectId(user["username"]), + "inventory.user.username": user["username"], "inventory.user.display_name": user["name"], }, }) @@ -463,7 +447,7 @@ def view_inventory_vacate(item_id): item = db.inventory.find_one({ "_id": ObjectId(item_id), "inventory.usable": True, - "inventory.user.foreign_id": ObjectId(user["username"]) + "inventory.user.username": user["username"] }) if not item: return abort(404) diff --git a/inventory-app/main.py b/inventory-app/main.py index f4cd3f5..0748339 100755 --- a/inventory-app/main.py +++ b/inventory-app/main.py @@ -20,7 +20,6 @@ import markdown import pymongo import requests import safe -from bson.objectid import ObjectId from flask import Flask, abort, g, make_response, redirect, render_template, request, session from flask_wtf import FlaskForm, RecaptchaField from jinja2 import Environment, FileSystemLoader @@ -45,7 +44,7 @@ from wtforms.form import Form from wtforms.validators import DataRequired import const -from common import CustomForm, devenv, flatten, format_name, spam +from common import CustomForm, devenv, flatten, format_name, spam, users_lookup from inventory import page_inventory from oidc import page_oidc, login_required, read_user from api import page_api @@ -58,6 +57,12 @@ def check_foreign_key_format(item): if user.get("foreign_id", False): return not bool(user.get("username")) +def render_user_display_name(username): + if not username: + return "" + display_name = users_lookup.get(username, {}).get("spec", {}).get("customProfile", {}).get("name", False) + return display_name or username + def render_markdown(text): if not text: return "" @@ -104,6 +109,7 @@ jinja2.filters.FILTERS['user_link'] = render_user_link jinja2.filters.FILTERS['is_list'] = is_list jinja2.filters.FILTERS['quote_plus'] = lambda u: urllib.parse.quote_plus(u) jinja2.filters.FILTERS['check_foreign_key_format'] = check_foreign_key_format +jinja2.filters.FILTERS['display_name'] = render_user_display_name env = Environment(loader=FileSystemLoader('templates/')) diff --git a/inventory-app/templates/inventory_filter.html b/inventory-app/templates/inventory_filter.html index 917cec2..b6ea79e 100644 --- a/inventory-app/templates/inventory_filter.html +++ b/inventory-app/templates/inventory_filter.html @@ -18,7 +18,7 @@ {% for value in values %} {% if value is mapping %} - {% else %} diff --git a/inventory-app/templates/inventory_grid.html b/inventory-app/templates/inventory_grid.html index 6339241..60ec201 100644 --- a/inventory-app/templates/inventory_grid.html +++ b/inventory-app/templates/inventory_grid.html @@ -15,8 +15,8 @@ {% if public_view %} {% if item.inventory.user %}

In use

{% endif %} {% else %} -

Owner: {% if item.inventory.owner %}{{item.inventory.owner.display_name}}{% endif %}

-

Current user: {% if item.inventory.user %}{{item.inventory.user.display_name}}{% endif %}

+

Owner: {% if item.inventory.owner %}{{item.inventory.owner.username | display_name}}{% endif %}

+

Current user: {% if item.inventory.user %}{{item.inventory.user.username | display_name}}{% endif %}

{% endif %}

more

diff --git a/inventory-app/templates/inventory_pick.html b/inventory-app/templates/inventory_pick.html index 0f30150..b21f9f1 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.display_name }}{% endif %} - {% if item.inventory.user %}{{ item.inventory.user.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 %}
diff --git a/inventory-app/templates/inventory_view.html b/inventory-app/templates/inventory_view.html index f146fdb..d774e55 100644 --- a/inventory-app/templates/inventory_view.html +++ b/inventory-app/templates/inventory_view.html @@ -57,12 +57,12 @@ Owner - {{ item.inventory.get("owner").display_name }} + {{ item.inventory.get("owner").username | display_name }} Current user - {{ item.inventory.get("user").display_name }} + {{ item.inventory.get("user").username | display_name }}