symfony:voter
Genere un Voter de securite Symfony pour le controle d'acces granulaire
- License 许可
- MIT
- 最近更新
- 2026-03-02
- Stars
- ★ 0
- Forks
- 0
01 前言 Front Matter
- name
- symfony:voter
- model
- sonnet
- license
- MIT
- version
- 1.0.0
- description
- Genere un Voter de securite Symfony pour le controle d'acces granulaire
- allowed-tools
- [ "AskUserQuestion", "Bash", "Read", "Write", "Edit", "Grep", "Glob" ]
02 资源文件 36
- 参考文档ArtIntegration.md2.6 KB
- 参考文档CriticalRules.md3.3 KB
- 参考文档Patterns.md2.9 KB
- 参考文档Tools/package.json574 B
- 参考文档Tools/Ref-3d.md2.2 KB
- 参考文档Tools/Ref-animations.md790 B
- 参考文档Tools/Ref-assets.md1.6 KB
- 参考文档Tools/Ref-audio.md3.7 KB
- 参考文档Tools/Ref-calculate-metadata.md2.9 KB
- 参考文档Tools/Ref-can-decode.md1.5 KB
- 参考文档Tools/Ref-charts.md1.7 KB
- 参考文档Tools/Ref-compositions.md3.4 KB
- 参考文档Tools/Ref-display-captions.md3.6 KB
- 参考文档Tools/Ref-extract-frames.md5.4 KB
- 参考文档Tools/Ref-fonts.md3.4 KB
- 参考文档Tools/Ref-get-audio-duration.md1.3 KB
- 参考文档Tools/Ref-get-video-dimensions.md1.6 KB
- 参考文档Tools/Ref-get-video-duration.md1.3 KB
- 参考文档Tools/Ref-gifs.md3.8 KB
- 参考文档Tools/Ref-images.md2.7 KB
- 参考文档Tools/Ref-import-srt-captions.md2.1 KB
- 参考文档Tools/Ref-lottie.md1.7 KB
- 参考文档Tools/Ref-measuring-dom-nodes.md974 B
- 参考文档Tools/Ref-measuring-text.md2.9 KB
- 参考文档Tools/Ref-sequencing.md2.3 KB
- 参考文档Tools/Ref-tailwind.md422 B
- 参考文档Tools/Ref-text-animations.md700 B
- 参考文档Tools/Ref-timing.md3.8 KB
- 参考文档Tools/Ref-transcribe-captions.md850 B
- 参考文档Tools/Ref-transitions.md3.6 KB
- 参考文档Tools/Ref-trimming.md1.2 KB
- 参考文档Tools/Ref-videos.md3.4 KB
- 脚本Tools/Render.ts9.0 KB
- 脚本Tools/Theme.ts4.4 KB
- 参考文档Tools/tsconfig.json441 B
- 参考文档Workflows/ContentToAnimation.md22.9 KB
03 SKILL.md 正文
Symfony Voter Skill
Genere un Voter Symfony pour le controle d'acces granulaire sur des objets ou des actions specifiques.
Variables
- {VoterName} - Nom du voter en PascalCase (ex: PostVoter)
- {subject} - Type d'objet sur lequel porte le vote
- {permissions} - Liste des permissions gerees
- {namespace} - Namespace du projet (defaut: App)
Outputs
src/Security/Voter/{VoterName}.php
Instructions a Executer
IMPORTANT : Execute ce workflow etape par etape :
1. Demander le nom du voter
- Utilise AskUserQuestion pour demander :
Question: "Quel est le nom du voter ? (ex: Post, Comment, Invoice)" Header: "Voter" - Ajoute le suffixe
Votersi absent
2. Demander le sujet
- Utilise AskUserQuestion pour demander :
Question: "Sur quel type d'objet porte le vote ? (ex: App\Entity\Post, App\Entity\Invoice)" Header: "Sujet"
3. Demander les permissions
- Utilise AskUserQuestion pour demander :
Question: "Quelles permissions gerer ? Format: VIEW,EDIT,DELETE,PUBLISH (separees par des virgules)" Header: "Permissions" - Parse la liste des permissions
- Genere les constantes correspondantes
4. Demander la strategie de decision
- Utilise AskUserQuestion pour demander :
Question: "Comment gerer un utilisateur non connecte ?" Header: "Strategie" Options: - "Refuser (Recommande)" : "Un utilisateur non connecte est toujours refuse" - "Permettre VIEW" : "Permettre la consultation aux anonymes, refuser le reste"
5. Detecter le namespace du projet
- Lis
composer.jsonavec Read - Extrais le namespace depuis
autoload.psr-4 - Si non trouve, utilise
Apppar defaut
6. Generer le Voter
- Cree le fichier
src/Security/Voter/{VoterName}.phpavec Write
<?php
declare(strict_types=1);
namespace {namespace}\Security\Voter;
use {namespace}\Entity\{Subject};
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authorization\Voter\Voter;
use Symfony\Component\Security\Core\User\UserInterface;
final class {VoterName} extends Voter
{
public const string VIEW = 'VIEW';
public const string EDIT = 'EDIT';
public const string DELETE = 'DELETE';
protected function supports(string $attribute, mixed $subject): bool
{
return in_array($attribute, [self::VIEW, self::EDIT, self::DELETE], true)
&& $subject instanceof {Subject};
}
protected function voteOnAttribute(string $attribute, mixed $subject, TokenInterface $token): bool
{
$user = $token->getUser();
if (!$user instanceof UserInterface) {
return false;
}
/** @var {Subject} $subject */
return match ($attribute) {
self::VIEW => $this->canView($subject, $user),
self::EDIT => $this->canEdit($subject, $user),
self::DELETE => $this->canDelete($subject, $user),
default => false,
};
}
private function canView({Subject} $subject, UserInterface $user): bool
{
// Tout utilisateur connecte peut voir
return true;
}
private function canEdit({Subject} $subject, UserInterface $user): bool
{
// Seul le proprietaire peut editer
return $subject->getOwner() === $user;
}
private function canDelete({Subject} $subject, UserInterface $user): bool
{
// Seul le proprietaire peut supprimer
return $subject->getOwner() === $user;
}
}
Regles de generation :
- Classe
finaletendantVoter - Constantes
public const stringpour chaque permission supports()verifie l'attribut ET le type du sujetvoteOnAttribute()utilisematchpour dispatcher- Methodes privees pour chaque permission
- Verification
$user instanceof UserInterfacepour les anonymes - Type-hint
@varsur le sujet apres la verification de type
7. Afficher le resume
Affiche :
Voter {VoterName} genere avec succes
Fichiers crees :
- src/Security/Voter/{VoterName}.php
Permissions :
{liste des permissions}
Utilisation dans un controleur :
$this->denyAccessUnlessGranted('EDIT', $post);
Utilisation dans Twig :
{% if is_granted('EDIT', post) %}...{% endif %}
Utilisation avec attribut :
#[IsGranted('EDIT', subject: 'post')]
Prochaines etapes :
- Implementer la logique de chaque permission
- Ajuster les regles d'acces selon le domaine metier
Patterns appliques
Voter
- Classe
final, extendsVoter - Constantes pour les permissions (string typed)
- Pattern
matchpour le dispatch - Methodes privees par permission
- Verification du type utilisateur
Notes
- Preferer
VoteraVoterInterfacepour le typage automatique du sujet - Les constantes de permission sont reutilisables dans les controleurs et templates
matchplutot queswitchpour le dispatch des permissions- Toujours verifier
$user instanceof UserInterfaceavant de traiter - Utiliser
#[IsGranted]dans les controleurs plutot quedenyAccessUnlessGranted()quand possible
04 同仓库更多 Skills
twig:make-component
Génère un Twig Component Symfony UX (classe PHP + template Twig)
tester:ui-test
Teste automatiquement une interface utilisateur dans Chrome : navigation, clics, validation visuelle, tests fonctionnels, responsive, comportement et debug. Génère un rapport détaillé avec screenshots et optionnellement un GIF du parcours.
symfony:message
Genere un Message Symfony Messenger avec son Handler pour traitement asynchrone
symfony:mailer
Genere un email Symfony (TemplatedEmail ou Notification) avec template Twig
symfony:form
Genere un FormType Symfony avec contraintes de validation et options
symfony:event
Genere un Event Symfony + EventSubscriber ou EventListener