Le rôle "admin" contournait entièrement l'isolation par projet (core/auth_guard.py) : il pouvait ouvrir/modifier/supprimer le jeu de n'importe quel autre compte en connaissant son slug, et la page d'accueil listait sans filtrage tous les projets de tous les comptes. - La propriété d'un projet se vérifie désormais sur le segment "propriétaire" du slug (id du compte), pour tous les rôles y compris admin — un slug "à plat" (sans compte associé) reste réservé à l'admin, comportement historique conservé pour ce cas précis. - routes/games/index.py ne liste plus que les projets du compte connecté. - Le dossier propriétaire d'un projet est maintenant l'id numérique du compte, plus jamais son email slugifié (visible en clair dans chaque URL auparavant) — script de migration fourni et déjà exécuté sur les données existantes. - Changer d'email ne renomme plus aucun dossier (n'en dépend plus). - Deux nouveaux tests de régression, fixtures corrigées en conséquence. - README réécrit pour refléter l'état actuel du produit (jeu 2D uniquement, plus de traces de l'ancien éditeur "document").
69 lines
3.1 KiB
Python
69 lines
3.1 KiB
Python
from flask import g, redirect, render_template, request, url_for
|
|
|
|
import auth
|
|
import db
|
|
import screens
|
|
|
|
from core.flask_app import app
|
|
|
|
|
|
@app.route("/onboarding", methods=["GET", "POST"])
|
|
def onboarding_new():
|
|
"""Point d'entrée UNIQUE pour créer un jeu — comportement SYSTÉMATIQUE
|
|
à chaque création, pas une formalité réservée à la toute première
|
|
inscription : chaque projet (celui d'un compte "user" comme n'importe
|
|
lequel des projets d'un admin) choisit son propre type ici. Prépare
|
|
aussi le futur multi-projet payant (plusieurs jeux de types
|
|
différents pour un même compte "user").
|
|
|
|
Un compte "user" fraîchement inscrit n'a plus de projet créé d'office
|
|
(voir routes/auth/register_2fa.py) : core/auth_guard.py le redirige
|
|
ici tant qu'il n'a pas encore de project_slug — et n'en aura jamais
|
|
qu'UN SEUL (voir core/auth_guard.py). Un admin, lui, n'a PAS de
|
|
project_slug dédié (illimité, voir create_user.py) : repasse ici à
|
|
volonté pour créer un projet de PLUS, jamais redirigé ailleurs.
|
|
|
|
Choisit un type (voir db.ONBOARDING_TYPES) puis nomme son jeu — crée
|
|
le projet ET son premier écran (du "kind" correspondant), puis envoie
|
|
vers son tableau de bord (routes/games/game_dashboard.py y rend une
|
|
version SIMPLIFIÉE pour un type restreint — quiz/embranchement/rpg —
|
|
ou la version complète pour "custom", même route pour tous)."""
|
|
user = g.current_user
|
|
if user["role"] != "admin" and user.get("project_slug"):
|
|
# Retour en arrière après coup (l'onboarding a déjà été fait) —
|
|
# ne recrée rien, renvoie directement vers son tableau de bord. Ne
|
|
# s'applique PAS à un admin (illimité, jamais "déjà fait" une fois
|
|
# pour toutes).
|
|
return redirect(url_for("game_dashboard", slug=user["project_slug"]))
|
|
|
|
error = None
|
|
if request.method == "POST":
|
|
onboarding_type = request.form.get("onboarding_type", "")
|
|
name = request.form.get("name", "").strip()
|
|
if onboarding_type not in db.ONBOARDING_TYPES:
|
|
error = "Choisis un type de jeu."
|
|
elif not name:
|
|
error = "Donne un nom à ton jeu."
|
|
else:
|
|
return redirect(_create_project_for_user(user, onboarding_type, name))
|
|
|
|
return render_template(
|
|
"onboarding/onboarding_new.html",
|
|
onboarding_types=db.ONBOARDING_TYPES, error=error,
|
|
)
|
|
|
|
|
|
def _create_project_for_user(user, onboarding_type, name):
|
|
# owner_folder = l'id du compte, jamais son email (voir
|
|
# routes/games/games_new.py, même convention).
|
|
slug = db.create_game(name, owner_folder=str(user["id"]))
|
|
db.set_onboarding_type(slug, onboarding_type)
|
|
if user["role"] != "admin":
|
|
# project_slug = LE seul projet d'un compte "user" (voir
|
|
# core/auth_guard.py) — un admin n'utilise pas cette colonne, ses
|
|
# projets se retrouvent via db.list_games() comme avant.
|
|
auth.set_project_slug(user["id"], slug)
|
|
screen_kind = db.ONBOARDING_TYPES[onboarding_type]["screen_kind"]
|
|
screens.create_screen(slug, name, kind=screen_kind)
|
|
return url_for("game_dashboard", slug=slug)
|