From ffa34815cd64b767f908670fac0441eb855b8696 Mon Sep 17 00:00:00 2001 From: Martin Tazl Date: Tue, 7 Jul 2026 12:20:09 +0200 Subject: [PATCH 1/6] Remove legacy admin UI from RollCalc --- AGENTS.md | 8 +- PROJECT_KNOWLEDGE.md | 22 +- README.md | 27 +- access_log.json | 21 ++ app.py | 26 +- templates/admin.html | 568 ------------------------------------------- 6 files changed, 38 insertions(+), 634 deletions(-) delete mode 100644 templates/admin.html diff --git a/AGENTS.md b/AGENTS.md index 39d9b1f..4af0930 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -31,11 +31,11 @@ Primary files: ## Planned Direction -- The existing admin UI/API in RollCalc is planned for removal. -- Do not expand or repair the admin area unless explicitly requested as a temporary measure. +- The previous admin UI/API has been removed from RollCalc. +- Do not reintroduce admin screens or admin APIs unless explicitly requested as a temporary measure. - Keep login/access logging in RollCalc. - Administration and maintenance of `article-data.json` should move to a separate application. -- Treat `templates/admin.html` and `/api/admin/*` expectations as legacy/transitional, not as target architecture. +- Treat article-data administration as out of scope for RollCalc. ## Code Style @@ -73,7 +73,7 @@ These credentials are hardcoded and are a known risk; do not introduce more secr - Access logging writes to `access_log.json` by reading and rewriting the whole file. - The active UI logic is largely inline in `templates/roll_calculator.html`. - Several `static/*.js` files appear to be older, alternative, or integration modules. Confirm script inclusion before modifying them. -- The admin template and backend admin routes are inconsistent and scheduled for removal rather than expansion. +- The previous admin template and backend admin route have been removed; do not rebuild them by default. - The disclaimer confirmation is client-side only. ## Safety Notes diff --git a/PROJECT_KNOWLEDGE.md b/PROJECT_KNOWLEDGE.md index e812080..b638b7d 100644 --- a/PROJECT_KNOWLEDGE.md +++ b/PROJECT_KNOWLEDGE.md @@ -14,12 +14,11 @@ Backend: - `app.py` creates the Flask app. - HTTP Basic Auth is implemented with `Flask-HTTPAuth`. -- Users are currently hardcoded in `BETA_USERS` and `ADMIN_USERS`. +- Users are currently hardcoded in `BETA_USERS`. - `/` renders the active calculator template. - `/static/` is intended to serve static files behind Basic Auth. - `/api/health` returns health/version information. -- `/api/user` returns the authenticated user and admin flag. -- `/admin/logs` returns access logs for admin users. +- `/api/user` returns the authenticated user. - Access events are appended to `access_log.json`. Frontend: @@ -184,25 +183,14 @@ This is client-side only. It is not persisted, logged, or enforced server-side. ## Admin Area State -Current backend route: +RollCalc no longer contains an admin UI or admin API. The previous `/admin/logs` route and `templates/admin.html` have been removed. -```text -/admin/logs -``` - -Current `templates/admin.html` expects: - -```text -/api/admin/stats -/api/admin/logs -``` - -Those `/api/admin/*` endpoints are not currently implemented in `app.py`, and there is no route rendering `templates/admin.html`. +Login/access logging remains part of RollCalc, but log viewing and article-data administration should not be implemented inside this app. Maintenance of `article-data.json` is planned for a separate application. ## Known Technical Risks - Hardcoded plaintext credentials in `app.py`. -- Basic Auth only; no sessions or role framework beyond user dictionaries. +- Basic Auth only; no sessions or role framework beyond the user dictionary. - `access_log.json` is rewritten on every logged request and is not concurrency-safe. - No log rotation or retention policy is implemented. - Flask's default static route may conflict with the intended authenticated `/static/` behavior; verify effective routing before relying on protected static files. diff --git a/README.md b/README.md index bd3eedd..d25461a 100644 --- a/README.md +++ b/README.md @@ -42,7 +42,7 @@ If port `5000` is already occupied, start through Flask's CLI without changing f flask --app app run --host 127.0.0.1 --port 5001 ``` -The app uses HTTP Basic Auth. Current credentials are defined in `BETA_USERS` and `ADMIN_USERS` in `app.py`. +The app uses HTTP Basic Auth. Current credentials are defined in `BETA_USERS` in `app.py`. ## Project Layout @@ -57,8 +57,7 @@ The app uses HTTP Basic Auth. Current credentials are defined in `BETA_USERS` an ├── fix_article_data.py ├── service-worker.js ├── templates/ -│ ├── roll_calculator.html -│ └── admin.html +│ └── roll_calculator.html ├── static/ │ ├── article-data.json │ ├── config.json @@ -88,10 +87,9 @@ Implemented routes: | `/` | `GET` | Basic Auth | Renders `templates/roll_calculator.html`. | | `/static/` | `GET` | Basic Auth | Intended protected static-file serving from `static/`. | | `/api/health` | `GET` | Basic Auth | Returns app health and version. | -| `/api/user` | `GET` | Basic Auth | Returns current authenticated user and admin flag. | -| `/admin/logs` | `GET` | Basic Auth plus admin check | Returns `access_log.json` contents. | +| `/api/user` | `GET` | Basic Auth | Returns current authenticated user info. | -Authentication is implemented with `Flask-HTTPAuth`. The current code merges `BETA_USERS` and `ADMIN_USERS` and performs direct plaintext string comparison. +Authentication is implemented with `Flask-HTTPAuth`. The current code checks `BETA_USERS` and performs direct plaintext string comparison. Access logging is handled by `log_access()`, which reads `access_log.json`, appends a record, and writes the whole file back. @@ -243,20 +241,9 @@ These provide or describe range calculations for material thickness, area weight ### Admin UI -There are admin-oriented HTML files: +RollCalc no longer contains an admin UI or admin API. Login/access logging remains in the backend, but logs are not exposed through a RollCalc admin screen. -- `templates/admin.html` -- `admin.html` -- `admin_simple.html` - -The backend currently exposes `/admin/logs`, but `templates/admin.html` expects: - -```text -/api/admin/stats -/api/admin/logs -``` - -Those `/api/admin/*` routes are not implemented in `app.py` at the time this README was written. There is also no route currently rendering `templates/admin.html`. +Administration and maintenance of `article-data.json` is planned for a separate application. RollCalc should continue to consume `static/article-data.json` read-only. ## Static Assets and Data Files @@ -293,7 +280,7 @@ Utility script that updates relative frontend fetch/register paths to Flask-styl - `access_log.json` is not safe for concurrent writes. - `access_log.json` grows without rotation or retention limits. - The custom `/static/` route is intended to protect static files, but Flask also creates a default static route unless disabled. Verify effective route behavior before relying on static-file protection. -- Admin frontend and backend routes are currently inconsistent. +- RollCalc no longer includes an admin UI/API; article data administration belongs in a separate application. - There is no visible automated test suite. - The main template is large and mixes layout, styling, data loading, calculations, and UI behavior. - The disclaimer confirmation is client-side only and is not persisted or audited server-side. diff --git a/access_log.json b/access_log.json index 9652746..596ded2 100644 --- a/access_log.json +++ b/access_log.json @@ -600,5 +600,26 @@ "endpoint": "/", "method": "GET", "status": 200 + }, + { + "timestamp": "2026-07-07T11:44:53.524315", + "username": "mtazl", + "endpoint": "/", + "method": "GET", + "status": 200 + }, + { + "timestamp": "2026-07-07T11:47:36.702455", + "username": "mtazl", + "endpoint": "/", + "method": "GET", + "status": 200 + }, + { + "timestamp": "2026-07-07T12:18:47.866971", + "username": "mtazl", + "endpoint": "/", + "method": "GET", + "status": 200 } ] \ No newline at end of file diff --git a/app.py b/app.py index 7975f2f..d93eb7d 100644 --- a/app.py +++ b/app.py @@ -27,11 +27,6 @@ BETA_USERS = { "controlling": "beta2026" # ⚠️ ÄNDERN! } -# Optional: Admin-Features (z.B. Logs, Stats) -ADMIN_USERS = { - "admin": "admin_secure_pwd_2026" # ⚠️ ÄNDERN! -} - # Logging für Auditing LOG_FILE = "access_log.json" @@ -42,8 +37,7 @@ LOG_FILE = "access_log.json" @auth.verify_password def verify_password(username, password): """Verify HTTP Basic Auth credentials""" - all_users = {**BETA_USERS, **ADMIN_USERS} - if username in all_users and all_users[username] == password: + if username in BETA_USERS and BETA_USERS[username] == password: return username return None @@ -96,30 +90,12 @@ def health_check(): def get_user(): """Get current authenticated user info""" user = auth.current_user() - is_admin = user in ADMIN_USERS return jsonify({ "username": user, "authenticated": True, - "is_admin": is_admin, "timestamp": datetime.now().isoformat() }), 200 -@app.route("/admin/logs", methods=["GET"]) -@auth.login_required -def get_logs(): - """View access logs - admin only""" - user = auth.current_user() - if user not in ADMIN_USERS: - log_access(user, "/admin/logs", "GET", 403) - return jsonify({"error": "Unauthorized"}), 403 - - log_access(user, "/admin/logs", "GET") - logs = [] - if os.path.exists(LOG_FILE): - with open(LOG_FILE, "r") as f: - logs = json.load(f) - return jsonify({"logs": logs}), 200 - # ============================================================================ # ERROR HANDLERS # ============================================================================ diff --git a/templates/admin.html b/templates/admin.html deleted file mode 100644 index 8352350..0000000 --- a/templates/admin.html +++ /dev/null @@ -1,568 +0,0 @@ - - - - - - - Admin Panel – Roll Calculator - - - - - -
-
-

🔐 Admin Panel

-
Roll Calculator – Naue GmbH & Co. KG
-
- -
- - -
- - -
-
- ⏳ Statistiken werden geladen... -
-
- - -
- - -
-

📋 Access Logs

-
- - -
-
- - -
- - -
- - -
- - - - - - - - - - - - - - - - -
ZeitstempelBenutzerEndpointMethodeStatus
Logs werden geladen...
- -
- - - - -
- - - - - - From 8f64760add790978d00c0b0575d6cf121fedc678 Mon Sep 17 00:00:00 2001 From: Martin Tazl Date: Tue, 7 Jul 2026 16:12:12 +0200 Subject: [PATCH 2/6] show build on website footer --- PROJECT_KNOWLEDGE.md | 21 +++++++++++++++++++ README.md | 15 ++++++++++++++ access_log.json | 7 +++++++ app.py | 37 ++++++++++++++++++++++++++++++++++ build_info.json | 6 ++++++ scripts/update_build_info.sh | 16 +++++++++++++++ templates/roll_calculator.html | 4 ++++ 7 files changed, 106 insertions(+) create mode 100644 build_info.json create mode 100755 scripts/update_build_info.sh diff --git a/PROJECT_KNOWLEDGE.md b/PROJECT_KNOWLEDGE.md index b638b7d..517bf4a 100644 --- a/PROJECT_KNOWLEDGE.md +++ b/PROJECT_KNOWLEDGE.md @@ -20,6 +20,7 @@ Backend: - `/api/health` returns health/version information. - `/api/user` returns the authenticated user. - Access events are appended to `access_log.json`. +- `build_info.json` is loaded at startup and exposed to all templates as `build_info`. Frontend: @@ -28,6 +29,26 @@ Frontend: - `window.ARTICLE_DATA` is loaded from `/static/article-data.json`. - `window.APP_CONFIG` is currently defined inline for forklift rules. - A disclaimer modal blocks use until the user checks the confirmation checkbox. +- The footer displays build metadata: version, branch, commit, and timestamp. + +## Build Info + +Build/deployment metadata is read from: + +```text +build_info.json +``` + +Expected fields: + +- `version` +- `branch` +- `commit` +- `timestamp` + +If `build_info.json` is missing, malformed, or does not contain a usable value, RollCalc falls back to `unknown` for that value and continues serving the site. + +The data is loaded centrally in `app.py` and made available to every template as `build_info`. ## Roll Geometry diff --git a/README.md b/README.md index d25461a..914894c 100644 --- a/README.md +++ b/README.md @@ -51,6 +51,7 @@ The app uses HTTP Basic Auth. Current credentials are defined in `BETA_USERS` in ├── app.py ├── requirements.txt ├── README.md +├── build_info.json ├── access_log.json ├── config.json ├── article-data_.json @@ -101,6 +102,7 @@ The template contains: - Page layout and all main CSS. - A disclaimer modal shown after Basic Auth login and before calculator use. +- Footer build metadata from `build_info`. - Global state: - `window.ARTICLE_DATA` - `window.APP_CONFIG` @@ -261,6 +263,19 @@ JSON audit log written by `app.py`. Important implementation detail: each logged access reads and rewrites the entire JSON file. This is simple but not concurrency-safe and can become inefficient as the file grows. +### `build_info.json` + +Deployment/build metadata displayed in the site footer. + +Expected fields: + +- `version` +- `branch` +- `commit` +- `timestamp` + +`app.py` loads this file centrally at startup and exposes it to all templates as `build_info`. If the file is missing, invalid, or a field is empty, the affected values fall back to `unknown` and the website continues to work. + ### `fix_article_data.py` Utility script that updates relative frontend fetch/register paths to Flask-style `/static/...` paths and checks that key static files exist. diff --git a/access_log.json b/access_log.json index 596ded2..6f51800 100644 --- a/access_log.json +++ b/access_log.json @@ -621,5 +621,12 @@ "endpoint": "/", "method": "GET", "status": 200 + }, + { + "timestamp": "2026-07-07T14:46:22.335316", + "username": "mtazl", + "endpoint": "/", + "method": "GET", + "status": 200 } ] \ No newline at end of file diff --git a/app.py b/app.py index d93eb7d..76f3c24 100644 --- a/app.py +++ b/app.py @@ -29,6 +29,43 @@ BETA_USERS = { # Logging für Auditing LOG_FILE = "access_log.json" +BUILD_INFO_FILE = "build_info.json" +UNKNOWN_BUILD_INFO = { + "version": "unknown", + "branch": "unknown", + "commit": "unknown", + "timestamp": "unknown" +} + +# ============================================================================ +# BUILD INFO +# ============================================================================ + +def load_build_info(): + """Load deployment/build metadata for templates.""" + try: + with open(BUILD_INFO_FILE, "r") as f: + data = json.load(f) + except Exception as e: + print(f"[Build Info Error] {e}") + return UNKNOWN_BUILD_INFO.copy() + + if not isinstance(data, dict): + return UNKNOWN_BUILD_INFO.copy() + + build_info = UNKNOWN_BUILD_INFO.copy() + for key in build_info: + value = data.get(key) + if isinstance(value, str) and value.strip(): + build_info[key] = value.strip() + return build_info + +BUILD_INFO = load_build_info() + +@app.context_processor +def inject_build_info(): + """Make build metadata available in all templates.""" + return {"build_info": BUILD_INFO} # ============================================================================ # AUTHENTICATION diff --git a/build_info.json b/build_info.json new file mode 100644 index 0000000..213cbe8 --- /dev/null +++ b/build_info.json @@ -0,0 +1,6 @@ +{ + "version": "0.4", + "branch": "develop/v0.4", + "commit": "ffa3481", + "timestamp": "2026-07-07T10:26:13Z" +} diff --git a/scripts/update_build_info.sh b/scripts/update_build_info.sh new file mode 100755 index 0000000..4cb9780 --- /dev/null +++ b/scripts/update_build_info.sh @@ -0,0 +1,16 @@ +#!/bin/bash +set -e + +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" + +cd "$PROJECT_ROOT" + +cat > build_info.json < Naue GmbH & Co. KG · Roll Diameter Calculator · Internal Application +