Les gardes de workflow, et un paquet installé jamais utilisé

Une transition de workflow gardée par une expression reçoit sa réponse des mêmes votants que tout le reste. Y parvenir suppose un paquet qu’il faut installer et qui ne sert jamais, et la raison vaut d’être lue avant de rencontrer le message d’erreur.

framework:
    workflows:
        article:
            type: state_machine
            supports: [App\Entity\Article]
            places: [draft, published, discarded]
            transitions:
                publish:
                    guard: "is_granted('PUBLISH', subject)"
                    from: draft
                    to: published

subject dans une garde est l’objet auquel le workflow s’applique, et is_valid(subject) continue de fonctionner : Workflow l’ajoute au langage qu’il emprunte à Security, et cela n’a rien à voir avec l’accès. Toutes les gardes atteignent un même écouteur, chacune associée à la transition pour laquelle elle a été écrite.

La reprise est conditionnelle ici

Contrairement au reste de la passerelle, l’écouteur de garde n’est remplacé que lorsque Security est absent. Avec SecurityBundle installé, l’écouteur de Symfony reste, et il atteint déjà ce composant à travers le gestionnaire de décision.

Le remplacer n’apporterait rien, et coûterait le résolveur de confiance qu’une expression peut nommer. Une passerelle qui reprend à son compte ce qu’elle ne sait pas améliorer est une passerelle avec plus de surface où se tromper.

Installé, jamais utilisé

Dans une application sans Security du tout, une garde de workflow exige quand même la présence de symfony/security-core :

composer require symfony/security-core

Le FrameworkExtension de Symfony refuse une garde de workflow à la compilation tant que ce paquet n’est pas installé, et il le fait avant que la passe de compilation de ce bundle n’ait la moindre chance de remplacer l’écouteur. Sans lui, le conteneur ne se construit tout simplement pas, avec un message disant qu’il faut security.token_storage.

Installez-le et rien de plus. La passe de compilation échange alors l’écouteur, et le paquet reste là, inemployé.

Pourquoi ce n’est pas simplement corrigé

Le bon correctif est en amont, et ce n’est pas affaire de nommer ce paquet dans FrameworkExtension. Ce qu’il y faudrait, c’est un point d’extension générique : un moyen pour un bundle de dire qu’il sait répondre à une expression de garde, plutôt qu’une liste de paquets écrite en dur.

Ajouter la mention d’un paquet qui vit hors du dépôt de Symfony réglerait le problème de ce composant et de personne d’autre, ce à quoi une contribution à un framework ne devrait pas ressembler. Deux correctifs plus modestes trouvés en chemin sont bien partis en amont et sont fusionnés ; celui-ci attend la bonne forme.

Le contrôle qui ne doit pas s’élargir

Il y a un piège de l’autre côté, et il est épinglé par un test : une garde sans Security ni ce bundle pour l’appliquer refuse toujours de compiler.

Relâcher le contrôle en amont sans cette garantie transformerait un échec de compilation en une transition que personne ne garde, ce qui est de nouveau la panne silencieuse, cette fois inscrite dans le framework. Un contournement qui ouvre un trou n’est pas un contournement, et c’est le genre de chose qu’un test existe pour tenir en place pendant des années.

La page des gardes de workflow donne le tableau de l’écouteur qui tourne dans chacune des trois configurations.