Skip to content

WIKI-170: hook usePermissions et affichage des actions selon les permissions effectives - #70

Open
FireDroX wants to merge 3 commits into
WIKI-167-access-rules-apifrom
WIKI-170-use-permissions
Open

FireDroX wants to merge 3 commits into
WIKI-167-access-rules-apifrom
WIKI-170-use-permissions

Conversation

@FireDroX

@FireDroX FireDroX commented Sep 27, 2026 •

Copy link
Copy Markdown
Owner

Résumé

Remplace toutes les vérifications de rôle côté client (UserRole.Editor, EDITOR_ROLES, MODERATOR_ROLES, page.canEdit) par les permissions effectives renvoyées par l'API (WIKI-166/WIKI-167), via un nouveau hook usePermissions().

  • UserRole : Admin | Member (aligné sur le backend depuis WIKI-165). AuthUser gagne permissions/groups.
  • api/pages.ts : PageDetail.canEdit → permissions: PageAction[] ; PageTreeNode gagne canCreateChild.
  • hooks/usePermissions.ts : hasGlobal(permission), canOnPage(page, action) — bypass total si admin.
  • Remplacements :
    • Sidebar.tsx — "Nouvelle page" (racine) → page.create_root.
    • CommentItem.tsx — modération → comment.moderate.
    • PageEditor.tsx — accès à l'éditeur → page.edit ; suppression de tag → tag.delete ; ajout/retrait de tag → page.manage_tags (aligné sur la vérification déjà faite côté backend dans TagsService, qui n'était pas reflétée côté client jusqu'ici) ; création de tag → tag.create et page.manage_tags (les deux appels backend enchaînés par cette action).
    • PageView.tsx — bouton Éditer → page.edit.
    • PageHistory.tsx — restauration de version → page.restore_version.
    • Médiathèque (MediaLibraryPicker, boutons d'upload de l'éditeur) → media.upload / media.delete (avant ce ticket, n'importe quel accès page.edit, même limité à une seule page, exposait l'upload/suppression sur l'ensemble de la médiathèque globale).
    • ProtectedRoute accepte désormais une prop permission en plus de roles ; la route /new est gardée par page.create_root.
    • ProfileSummary / UsersTable — libellés admin/member, affichage des groupes de l'utilisateur sur son profil.
  • i18n : suppression de roleEditor/roleReader, ajout de roleMember + libellés de chaque permission (permissions.labels.*), réutilisables par les futurs écrans d'administration (WIKI-171/172).

Corrections apportées suite à la revue de code (multi-agent, sur toute la pile de branches)

La revue a scanné main...HEAD, donc au-delà du diff propre à ce ticket. Deux corrections appliquées :

  1. AccessRulesService.applyUpdate (WIKI-167, backend/src/permissions/services/access-rules.service.ts) — vraie faille d'escalade de privilèges : mettre à jour uniquement excludedPageIds d'une règle (sans toucher actions) ne redéclenchait jamais assertNoEscalation. Retirer une exclusion élargit pourtant la couverture effective d'une règle exactement comme changer ses actions. Corrigée directement sur la branche WIKI-167-access-rules-api (PR EPIC-30 / WIKI-167: API des règles d'accès aux pages et gestion des groupes #69, mise à jour), puis mergée dans cette branche. Détail complet dans la description de la PR EPIC-30 / WIKI-167: API des règles d'accès aux pages et gestion des groupes #69.
  2. PageTagsPanel (ce ticket) : le bouton "créer un tag" ne vérifiait que page.manage_tags, alors que l'action enchaîne POST /tags (nécessite le tag.create global) puis l'attache à la page (nécessite page.manage_tags). Un utilisateur avec seulement page.manage_tags voyait un bouton qui aurait échoué en 403 à la création. Corrigé en exigeant les deux permissions pour "créer", en gardant "ajouter un tag existant" sur page.manage_tags seul.

Signalé mais non corrigé dans cette PR

  • frontend/src/App.tsx:53 — route /admin/users toujours gardée par roles={[UserRole.Admin]} plutôt que par la nouvelle prop permission. Delibérément non touché : le contrôleur backend AdminUsersController (liste/rôle/suppression d'utilisateurs) reste strictement @Roles('admin') — seul AdminUserAccessController (routes /permissions et /access-rules ajoutées par WIKI-167) accepte user.manage. Basculer le frontend sur permission="user.manage" maintenant laisserait un utilisateur user.manage-only atteindre la page puis se prendre un 403 sur chaque appel API. C'est le même trou déjà documenté dans la PR EPIC-30 / WIKI-167: API des règles d'accès aux pages et gestion des groupes #69 (incohérence AdminUsersController/AdminUserAccessController, harmonisation prévue par WIKI-168) — la revue a en plus trouvé le même trou côté AdminUserCommentsController (liste/purge des commentaires d'un utilisateur toujours admin-only, alors que la suppression d'un commentaire individuel accepte déjà comment.moderate), ajouté à la description de la PR EPIC-30 / WIKI-167: API des règles d'accès aux pages et gestion des groupes #69 pour ne pas perdre le fil.
  • Autres constats de la revue déjà couverts par la description mise à jour de la PR EPIC-30 / WIKI-167: API des règles d'accès aux pages et gestion des groupes #69 (gap d'audit sur la modération de commentaires, cas limite de la migration WIKI-165 si le dernier admin est supprimé avant son exécution, N+1 sur la suppression en cascade de pages) : hors périmètre de ce ticket-ci, pas dupliqués ici.

Écarts assumés par rapport au ticket (déjà notés avant la revue)

  • PagePermissionsPanel supprimé plutôt que re-gardé : ce panneau et api/page-permissions.ts appelaient les routes /pages/:id/permissions, supprimées par WIKI-165 — il était déjà mort (échec silencieux) depuis ce ticket-là. Le reconstruire sur la nouvelle API d'access-rules est le périmètre de WIKI-173.
  • canCreateChild exposé mais pas encore consommé par une UI dédiée : aucune action "créer une sous-page" par nœud n'existe aujourd'hui dans l'arborescence. Le champ est propagé bout en bout pour que WIKI-172 puisse s'en servir.
  • Pas de bouton Supprimer/Déplacer/Accès ajouté à PageView : ces actions n'existent nulle part dans le frontend actuel. Les ajouter empiète sur le panneau "Accès" de WIKI-173.

Test plan

  • pnpm run build (tsc -b + vite build) : clean.
  • pnpm run lint (oxlint) : clean (uniquement des warnings pré-existants, non liés à ce diff).
  • pnpm exec vitest run (frontend) : 35/35.
  • pnpm exec vitest run (backend, pour la correction Configure pnpm workspace and add MinIO integration with MySQL #1 mergée depuis WIKI-167) : 247/247.

🤖 Generated with Claude Code

Add usePermissions() (hasGlobal/canOnPage, admin bypasses both) and wire
it everywhere the frontend used to check UserRole.Editor/Admin directly:

- UserRole is now Admin | Member, matching the backend (WIKI-165).
- api/pages.ts: PageDetail.canEdit -> permissions: PageAction[];
  PageTreeNode gains canCreateChild.
- Sidebar "New page" -> page.create_root; CommentItem moderation ->
  comment.moderate; PageView edit button and PageHistory restore ->
  page.edit / page.restore_version; PageEditor tag deletion -> tag.delete
  and tag attach/detach/create -> page.manage_tags (matches the backend's
  actual page.manage_tags check on POST/DELETE /pages/:id/tags, which was
  previously ungated on the client).
- Media library upload tab and delete button -> media.upload/media.delete
  (previously any page.edit access implicitly exposed the whole global
  media library's upload/delete actions on the client).
- ProtectedRoute accepts a `permission` prop in addition to `roles`; /new
  now gates on page.create_root instead of the removed editor role.
- Remove PagePermissionsPanel and api/page-permissions.ts: both called
  the /pages/:id/permissions routes removed by WIKI-165 and have been
  dead/non-functional since that ticket merged. The real replacement
  (access-rules based panel) is WIKI-173's scope.
- ProfileSummary/UsersTable: role labels admin/member, profile shows the
  user's groups; i18n gains permission labels reused by future admin
  screens instead of the deleted panel's now-unused strings.

Bump to 0.30.5 with a changelog entry.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AgjQXuhToMzd4FfvJFdgUw
@FireDroX
FireDroX added this pull request to stack #66 September 27, 2026 17:09
FireDroX and others added 2 commits September 27, 2026 19:31
…tags

"Create new tag" both creates the tag (POST /tags, requires the global
tag.create permission) and attaches it to the page (requires
page.manage_tags). PageTagsPanel only checked page.manage_tags, so a
user with page-scoped tag management but no global tag.create saw a
button that would 403 on submit. "Add existing" only attaches, so it
keeps requiring just page.manage_tags.

Found by code review of the WIKI-170 branch stack.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AgjQXuhToMzd4FfvJFdgUw

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant