From e8773a9c188e2163679074e24ffceb54475ba04e Mon Sep 17 00:00:00 2001 From: nino Date: Sun, 18 May 2025 01:54:47 +0200 Subject: [PATCH 1/3] add working widget for board + add link for chat and board --- web/templates/view/index.html | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/web/templates/view/index.html b/web/templates/view/index.html index 6c05553..421576d 100644 --- a/web/templates/view/index.html +++ b/web/templates/view/index.html @@ -22,6 +22,8 @@ + chat
{{ user['preferred_username'] }}
-

Mon profil

+ Profil Déconnexion
@@ -71,8 +74,8 @@

Gesthub

-
Zone Trello - +
+
From 00c5bb7f1e9b13f374b1f572c24d104ed8f48ecb Mon Sep 17 00:00:00 2001 From: nino Date: Sun, 18 May 2025 01:56:34 +0200 Subject: [PATCH 2/3] add working widget for board + add link for chat and board --- web/templates/view/index.html | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/web/templates/view/index.html b/web/templates/view/index.html index 6c05553..421576d 100644 --- a/web/templates/view/index.html +++ b/web/templates/view/index.html @@ -22,6 +22,8 @@ + chat
{{ user['preferred_username'] }}
-

Mon profil

+ Profil Déconnexion
@@ -71,8 +74,8 @@

Gesthub

-
Zone Trello - +
+
From 9cab64fe06be9c3e46661d4df30e571a0a3612c3 Mon Sep 17 00:00:00 2001 From: nino Date: Sun, 18 May 2025 20:12:54 +0200 Subject: [PATCH 3/3] website fonctional / front=ok / back=ok / docker=ok --- web/annonces.json | 1 + web/app.py | 86 +++++++++++++++++++++++++++++++-- web/static/assets/css/index.css | 13 ++++- web/static/assets/js/index.js | 72 ++++++++++++++++++++++++++- web/templates/view/index.html | 45 ++++++++++++----- 5 files changed, 198 insertions(+), 19 deletions(-) create mode 100644 web/annonces.json diff --git a/web/annonces.json b/web/annonces.json new file mode 100644 index 0000000..0637a08 --- /dev/null +++ b/web/annonces.json @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/web/app.py b/web/app.py index aba6ea0..61cde0b 100644 --- a/web/app.py +++ b/web/app.py @@ -1,10 +1,12 @@ import os import uuid -from flask import Flask, redirect, url_for, session, render_template +import json +from flask import Flask, redirect, url_for, jsonify, session, render_template from flask_sqlalchemy import SQLAlchemy from authlib.integrations.flask_client import OAuth app = Flask(__name__) +ANNOUNCE_FILE = os.path.join(os.path.dirname(__file__), "annonces.json") app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://flaskuser:flaskpass@mariadb/flaskdb' app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False app.secret_key = os.environ.get("SECRET_KEY", "dev-key") @@ -45,13 +47,89 @@ def auth(): nonce = session.pop('nonce', None) userinfo = keycloak.parse_id_token(token, nonce=nonce) session['user'] = userinfo + session["id_token"] = token.get("id_token") app.logger.debug(f"User info: {userinfo}") return redirect('/') -@app.route('/logout') +@app.route("/logout") def logout(): - session.pop('user', None) - return redirect('/') + id_token = session.get("id_token") + print("ID Token Hint:", id_token) + session.clear() + return redirect( + f"https://keycloak.ninolbt.com/realms/gesthub/protocol/openid-connect/logout" + f"?post_logout_redirect_uri=https://dashboard.ninolbt.com" + f"&id_token_hint={id_token}" + ) +def load_announces(): + try: + with open(ANNOUNCE_FILE, "r", encoding="utf-8") as f: + return json.load(f) + except (FileNotFoundError, json.JSONDecodeError): + return [] + +def save_announces(announces): + with open(ANNOUNCE_FILE, "w", encoding="utf-8") as f: + json.dump(announces, f, ensure_ascii=False, indent=2) + +def get_next_id(announces): + return max((a.get("id", 0) for a in announces), default=0) + 1 + +@app.route("/api/annonces", methods=["GET"]) +def get_announces(): + return jsonify(load_announces()) + +@app.route("/api/annonces", methods=["POST"]) +def create_annonce(): + user = session.get("user") + if not user or "/admin" not in user.get("groups", []): + return jsonify({"error": "unauthorized"}), 403 + data = request.json + if not data.get("text"): + return jsonify({"error": "missing text"}), 400 + + announces = load_announces() + new_announce = { + "id": get_next_id(announces), + "text": data["text"], + "author": user.get("preferred_username", "admin") + } + announces.append(new_announce) + save_announces(announces) + return jsonify({"status": "ok", "announce": new_announce}) + +@app.route("/api/annonces/", methods=["DELETE"]) +def delete_annonce(annonce_id): + user = session.get("user") + if not user or "/admin" not in user.get("groups", []): + return jsonify({"error": "unauthorized"}), 403 + announces = load_announces() + announces = [a for a in announces if a["id"] != annonce_id] + save_announces(announces) + return jsonify({"status": "deleted"}) + +@app.route("/api/annonces/", methods=["PUT"]) +def edit_annonce(annonce_id): + user = session.get("user") + if not user or "/admin" not in user.get("groups", []): + return jsonify({"error": "unauthorized"}), 403 + data = request.json + announces = load_announces() + found = False + for a in announces: + if a["id"] == annonce_id: + a["text"] = data.get("text", a["text"]) + found = True + if not found: + return jsonify({"error": "not found"}), 404 + save_announces(announces) + return jsonify({"status": "updated"}) + +@app.route("/api/is_admin") +def is_admin(): + user = session.get("user") + return jsonify({"admin": "/admin" in user.get("groups", [])}) + if __name__ == '__main__': app.run(host='0.0.0.0', debug=True) diff --git a/web/static/assets/css/index.css b/web/static/assets/css/index.css index c8aa241..d74d640 100644 --- a/web/static/assets/css/index.css +++ b/web/static/assets/css/index.css @@ -388,4 +388,15 @@ .dark .right-column { background-color: #2d2d2d; - } \ No newline at end of file + } + + .postit { + background-color: #fff475; + color: #333; + padding: 0.8rem; + margin-bottom: 0.8rem; + border-radius: 8px; + box-shadow: 2px 2px 6px rgba(0,0,0,0.15); + font-family: 'Comic Sans MS', sans-serif; + font-size: 0.95rem; +} \ No newline at end of file diff --git a/web/static/assets/js/index.js b/web/static/assets/js/index.js index eb1913c..0327ed5 100644 --- a/web/static/assets/js/index.js +++ b/web/static/assets/js/index.js @@ -80,4 +80,74 @@ if (e.target === contactModal) { contactModal.style.display = 'none'; } - }); \ No newline at end of file + }); + +// Gestion des annonces + + let isAdmin = false; + + fetch("/api/is_admin") + .then(res => res.json()) + .then(data => { + isAdmin = data.admin; + if (isAdmin) { + document.getElementById("admin-tools").style.display = "block"; + } + }); + + fetch("/api/annonces") + .then(res => res.json()) + .then(data => { + const container = document.getElementById("annonces-container"); + container.innerHTML = ""; + + data.forEach(item => { + const div = document.createElement("div"); + div.className = "postit"; + div.dataset.id = item.id; + div.innerHTML = ` + ${item.text} +
${item.author} + `; + + if (isAdmin) { + const editBtn = document.createElement("button"); + editBtn.textContent = "✏️"; + editBtn.onclick = () => editAnnonce(item.id, item.text); + div.appendChild(editBtn); + + const delBtn = document.createElement("button"); + delBtn.textContent = "🗑️"; + delBtn.onclick = () => deleteAnnonce(item.id); + div.appendChild(delBtn); + } + + container.appendChild(div); + }); + }); + + function submitAnnonce() { + const txt = document.getElementById("annonce-text").value; + fetch("/api/annonces", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ text: txt }) + }).then(() => location.reload()); + } + + function deleteAnnonce(id) { + fetch(`/api/annonces/${id}`, { + method: "DELETE" + }).then(() => location.reload()); + } + + function editAnnonce(id, oldText) { + const newText = prompt("Modifier l'annonce :", oldText); + if (newText && newText !== oldText) { + fetch(`/api/annonces/${id}`, { + method: "PUT", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ text: newText }) + }).then(() => location.reload()); + } + } \ No newline at end of file diff --git a/web/templates/view/index.html b/web/templates/view/index.html index 421576d..2b00222 100644 --- a/web/templates/view/index.html +++ b/web/templates/view/index.html @@ -40,13 +40,13 @@ - chat + Chat
{{ user['preferred_username'] }}
@@ -68,14 +68,20 @@

Gesthub

- +
@@ -83,15 +89,28 @@ je vais metrre des boutons et autres features comme des doc etc ou jsp je m en occupe --> - +