Files
gesthub/web/app.py
2025-12-16 01:31:23 +01:00

152 lines
5.0 KiB
Python

import os
import uuid
import json
# J'ai ajouté 'request' aux imports
from flask import Flask, redirect, url_for, jsonify, session, render_template, request
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")
# Ta config DB actuelle
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")
db = SQLAlchemy(app)
# --- MODELE DE DONNEES POUR LES BLOCS ---
class Block(db.Model):
id = db.Column(db.Integer, primary_key=True)
block_type = db.Column(db.String(50)) # ex: 'iframe', 'buttons', 'html'
column_name = db.Column(db.String(20)) # ex: 'left', 'center', 'right'
position = db.Column(db.Integer) # pour l'ordre (0, 1, 2...)
data = db.Column(db.Text) # Contenu JSON (url, titre, etc.)
def to_dict(self):
return {
"id": self.id,
"type": self.block_type,
"column": self.column_name,
"position": self.position,
"data": json.loads(self.data) if self.data else {}
}
# Création des tables si elles n'existent pas
with app.app_context():
db.create_all()
# ... (Ici, garde ta configuration OAUTH et tes routes Login/Logout/Auth inchangées) ...
# ... (Garde aussi tes fonctions load_announces, save_announces etc.) ...
oauth = OAuth(app)
keycloak = oauth.register(
name='keycloak',
client_id='flask-app',
client_secret='T5G5jzCBiphnBNh9uuj0f6YNc9HrP8r4',
server_metadata_url='https://keycloak.ninolbt.com/realms/gesthub/.well-known/openid-configuration',
client_kwargs={'scope': 'openid profile email'}
)
@app.route('/')
def index():
user = session.get('user')
if user:
return render_template('view/index.html', user=user)
return redirect(url_for('login'))
@app.route('/login')
def login():
nonce = uuid.uuid4().hex
session['nonce'] = nonce
redirect_uri = url_for('auth', _external=True, _scheme='https')
return keycloak.authorize_redirect(redirect_uri, nonce=nonce)
@app.route('/auth')
def auth():
token = keycloak.authorize_access_token()
nonce = session.pop('nonce', None)
userinfo = keycloak.parse_id_token(token, nonce=nonce)
session['user'] = userinfo
session["id_token"] = token.get("id_token")
return redirect('/')
@app.route("/logout")
def logout():
id_token = session.get("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}"
)
# --- API LAYOUT (Gestion des Blocs) ---
@app.route('/api/layout', methods=['GET'])
def get_layout():
# Récupère tous les blocs triés par position
blocks = Block.query.order_by(Block.position).all()
return jsonify([b.to_dict() for b in blocks])
@app.route('/api/layout/save', methods=['POST'])
def save_layout():
# Sauvegarde l'ordre et la colonne après un drag & drop
user = session.get("user")
if not user or "/admin" not in user.get("groups", []):
return jsonify({"error": "Unauthorized"}), 403
layout_data = request.json # Liste de {id, column, position}
for item in layout_data:
block = Block.query.get(item['id'])
if block:
block.column_name = item['column']
block.position = item['position']
db.session.commit()
return jsonify({"status": "saved"})
@app.route('/api/block/add', methods=['POST'])
def add_block():
user = session.get("user")
if not user or "/admin" not in user.get("groups", []):
return jsonify({"error": "Unauthorized"}), 403
data = request.json
new_block = Block(
block_type=data.get('type'),
column_name=data.get('column', 'center'),
position=99, # Ajoute à la fin par défaut
data=json.dumps(data.get('data', {}))
)
db.session.add(new_block)
db.session.commit()
return jsonify(new_block.to_dict())
@app.route('/api/block/<int:block_id>', methods=['DELETE'])
def delete_block(block_id):
user = session.get("user")
if not user or "/admin" not in user.get("groups", []):
return jsonify({"error": "Unauthorized"}), 403
block = Block.query.get(block_id)
if block:
db.session.delete(block)
db.session.commit()
return jsonify({"status": "deleted"})
return jsonify({"error": "not found"}), 404
# --- API ANNONCES (Tes routes existantes) ---
# ... (Colle ici tes routes /api/annonces existantes, elles sont très bien) ...
# ... (N'oublie pas la route /api/is_admin) ...
@app.route("/api/is_admin")
def is_admin():
user = session.get("user")
# Sécurité : si pas de user, renvoie false
if not user: return jsonify({"admin": False})
return jsonify({"admin": "/admin" in user.get("groups", [])})
if __name__ == '__main__':
app.run(host='0.0.0.0', debug=True)