76 lines
4.4 KiB
Markdown
76 lines
4.4 KiB
Markdown
# Partie 5 — Rétro-documentation
|
|
|
|
Cette rétro-documentation a été produite par analyse du code source réel de
|
|
`gesthub-v2` (et non rédigée en amont du code), selon la démarche
|
|
décrite au Bloc 4 — C1 : 1) analyse de l'arborescence, 2) lecture du code
|
|
pour comprendre le rôle de chaque fonction, 3) reconstruction des flux à
|
|
partir des appels de fonctions, 4) production du dictionnaire de données.
|
|
|
|
## RD-1 — Architecture en 5 couches
|
|
|
|
| Couche | Répertoire | Responsabilité |
|
|
|---|---|---|
|
|
| Présentation | `templates/`, `static/` | Rendu HTML (Jinja2), CSS, JS (SortableJS pour le drag & drop) |
|
|
| Contrôleur | `routes/` | Orchestration HTTP : authentifie, délègue, répond en JSON/HTML |
|
|
| Service | `services/` | Logique métier, validation, journalisation dans `audit_log` |
|
|
| Accès données | `models/` | Repository Pattern, seules requêtes SQL de tout le projet |
|
|
| Infrastructure | `db.py`, `config.py`, `docker-compose.yml` | Connexion MariaDB, configuration par variables d'environnement, orchestration des conteneurs |
|
|
|
|
## RD-2 — Flux de données détaillés
|
|
|
|
**Consultation des annonces :**
|
|
`Navigateur → GET /api/annonces → routes/annonces.py (vérifie la session)
|
|
→ services/annonce_service.list_annonces → models/annonce_model.fetch_all
|
|
→ MariaDB (SELECT paramétré) → JSON → Navigateur`
|
|
|
|
**Upload de fichier :**
|
|
`Navigateur (multipart/form-data) → routes/fichiers.py → services/
|
|
fichier_service.handle_upload (8 étapes : présence → taille → MIME →
|
|
extension → nom UUID → écriture disque → INSERT métadonnées → INSERT
|
|
audit_log) → réponse JSON {id}`
|
|
|
|
**Téléchargement de fichier :**
|
|
`Navigateur → GET /api/fichiers/{id}/download → vérification des droits
|
|
(propriétaire ou admin) → audit_log (SUCCESS ou REFUSED) → send_file (si
|
|
autorisé) ou 403`
|
|
|
|
## RD-3 — Flux d'authentification OIDC (annoté, 7 étapes)
|
|
|
|
| Étape | Description | Code |
|
|
|---|---|---|
|
|
| 1 | Détection de l'absence de session | `routes/dashboard.py::index` (`is_authenticated()`) |
|
|
| 2 | Génération de l'URL d'autorisation + nonce anti-rejeu | `routes/auth.py::login` |
|
|
| 3 | Redirection vers Keycloak | `keycloak.authorize_redirect(...)` |
|
|
| 4 | Retour sur `/auth` avec le code d'autorisation | Géré automatiquement par Authlib |
|
|
| 5 | Échange du code contre un token | `keycloak.authorize_access_token()` |
|
|
| 6 | Vérification du token (signature + nonce) | `keycloak.parse_id_token(token, nonce=nonce)` |
|
|
| 7 | Création de la session applicative | `session["user"] = userinfo` |
|
|
|
|
## RD-4 — Dictionnaire de données
|
|
|
|
| Champ | Table | Type SQL | Source | Description |
|
|
|---|---|---|---|---|
|
|
| `id` | toutes | `INT UNSIGNED AUTO_INCREMENT` | MariaDB | Clé primaire |
|
|
| `titre` | annonces, evenements | `VARCHAR(150)` | Saisie admin | Titre affiché |
|
|
| `epinglee` | annonces | `TINYINT(1)` | Saisie admin | Priorité d'affichage |
|
|
| `auteur_sub` / `uploader_sub` / `createur_sub` | annonces, fichiers, evenements | `VARCHAR(64)` | Claim `sub` du token OIDC | Référence utilisateur (pas de doublon des données Keycloak) |
|
|
| `nom_stocke` | fichiers | `VARCHAR(64)` | Généré (UUID4) | Nom réel sur disque, anti path-traversal |
|
|
| `taille_octets` | fichiers | `BIGINT UNSIGNED` | Calculé à l'upload | Taille du fichier |
|
|
| `action` / `statut` | audit_log | `VARCHAR(50)` / `VARCHAR(20)` | Généré par les services | Traçabilité (ex. `CREATE_ANNONCE` / `SUCCESS`) |
|
|
|
|
## RD-5 — Table de correspondance claims JWT ↔ champs applicatifs
|
|
|
|
| Claim JWT (Keycloak) | Champ applicatif | Utilisation |
|
|
|---|---|---|
|
|
| `sub` | `session["user"]["sub"]`, colonnes `*_sub` en base | Identifiant utilisateur unique et stable |
|
|
| `preferred_username` | `session["user"]["preferred_username"]` | Affichage du nom d'utilisateur (template `index.html`) |
|
|
| `email` | `session["user"]["email"]` | Non utilisé actuellement (disponible pour évolutions, ex. notifications) |
|
|
| `groups` | `session["user"]["groups"]` | Contrôle d'accès (`/admin` → `is_admin()`) |
|
|
| `iat`, `exp`, `iss` | Vérifiés automatiquement par Authlib | Validité temporelle et émetteur du token |
|
|
|
|
En spécialité Robotique & Systèmes Embarqués, cette même logique de table de
|
|
correspondance s'applique au mapping entre formats de données capteurs
|
|
(ex. trame UART) et structures Python applicatives — la compétence
|
|
transférée est la même : documenter précisément la correspondance entre un
|
|
format source externe et le modèle interne de l'application.
|