70 lines
2.3 KiB
Markdown
70 lines
2.3 KiB
Markdown
# “Proposer” protégé par groupe (whoami / editors)
|
||
|
||
## But
|
||
Le bouton **Proposer** (création d’issue Gitea pré-remplie) doit être :
|
||
- visible **uniquement** pour les membres du groupe `editors`,
|
||
- **absent** pour les autres utilisateurs,
|
||
- robuste (fail-closed), mais **non-collant** (pas de “bloqué” après un échec transitoire).
|
||
|
||
## Pré-requis (build-time)
|
||
Les variables publiques Astro doivent être injectées au build :
|
||
- `PUBLIC_GITEA_BASE`
|
||
- `PUBLIC_GITEA_OWNER`
|
||
- `PUBLIC_GITEA_REPO`
|
||
|
||
Si une seule manque → `giteaReady=false` → Proposer est désactivé.
|
||
|
||
### Vérification NAS (slots blue/green)
|
||
Exemple :
|
||
- blue : http://127.0.0.1:8081/...
|
||
- green : http://127.0.0.1:8082/...
|
||
|
||
Commande (ex) :
|
||
`curl -sS http://127.0.0.1:8081/archicratie/archicrat-ia/chapitre-4/ | grep -n "const GITEA_" | head`
|
||
|
||
## Signal d’auth (runtime) : `/_auth/whoami`
|
||
Le site appelle `/_auth/whoami` (same-origin) pour récupérer :
|
||
- `Remote-User`
|
||
- `Remote-Groups`
|
||
Ces headers sont injectés par la chaîne edge (Traefik → Authelia forward-auth).
|
||
|
||
### Appel robuste
|
||
- cache-bust : `?_=${Date.now()}`
|
||
- `cache: "no-store"`
|
||
- `credentials: "include"`
|
||
|
||
### Critère
|
||
`groups.includes("editors")`
|
||
|
||
## Comportement attendu (UX)
|
||
- utilisateur editors : le bouton “Proposer” est visible, ouvre la modal, puis ouvre Gitea.
|
||
- utilisateur non editors : le bouton “Proposer” n’existe pas (retiré du DOM).
|
||
|
||
## Pièges connus
|
||
1) Tester en direct 8081/8082 ne reflète pas toujours la chaîne Traefik+Authelia.
|
||
2) Un gate “collant” peut rester OFF si l’échec est mis en cache trop agressivement.
|
||
3) Si “Proposer” est caché via `style.display="none"`, il faut le réafficher via `style.display=""` (pas via `hidden=false`).
|
||
|
||
## Debug rapide (console navigateur)
|
||
en js :
|
||
|
||
(async () => {
|
||
const r = await fetch("/_auth/whoami?_=" + Date.now(), {
|
||
credentials: "include",
|
||
cache: "no-store",
|
||
redirect: "follow",
|
||
});
|
||
const t = await r.text();
|
||
const groups = (t.match(/^Remote-Groups:\s*(.*)$/mi)?.[1] || "")
|
||
.split(",").map(s => s.trim()).filter(Boolean);
|
||
console.log({ ok: r.ok, status: r.status, groups, raw: t.slice(0, 220) + "..." });
|
||
})();
|
||
|
||
## Définition “done”
|
||
|
||
Archicratia (editors) voit Proposer et peut ouvrir un ticket.
|
||
|
||
s-FunX (non editors) ne voit pas Proposer.
|
||
|
||
Les deux slots blue/green injectent les constantes Gitea dans le HTML.
|