symfonyvoter
Genere un Voter de securite Symfony pour le controle d'acces granulaire
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
メニュー
Genere un Voter de securite Symfony pour le controle d'acces granulaire
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
Audite un projet API Platform existant et produit un rapport de bonnes pratiques, performances et sécurité
Génère des DTOs (input/output) API Platform avec mapping vers les entités
Génère des filtres API Platform (search, date, range, order, boolean, exists, custom)
Génère un State Processor API Platform pour personnaliser la persistence des données
Génère un State Provider API Platform pour personnaliser la récupération de données
Génère une API Resource complète avec attribut
SOC 職業分類に基づく
| name | symfony:voter |
| description | Genere un Voter de securite Symfony pour le controle d'acces granulaire |
| model | sonnet |
| allowed-tools | ["AskUserQuestion","Bash","Read","Write","Edit","Grep","Glob"] |
| version | 1.0.0 |
| license | MIT |
Genere un Voter Symfony pour le controle d'acces granulaire sur des objets ou des actions specifiques.
src/Security/Voter/{VoterName}.phpIMPORTANT : Execute ce workflow etape par etape :
Question: "Quel est le nom du voter ? (ex: Post, Comment, Invoice)"
Header: "Voter"
Voter si absentQuestion: "Sur quel type d'objet porte le vote ? (ex: App\Entity\Post, App\Entity\Invoice)"
Header: "Sujet"
Question: "Quelles permissions gerer ? Format: VIEW,EDIT,DELETE,PUBLISH (separees par des virgules)"
Header: "Permissions"
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"
composer.json avec Readautoload.psr-4App par defautsrc/Security/Voter/{VoterName}.php avec 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 :
final etendant Voterpublic const string pour chaque permissionsupports() verifie l'attribut ET le type du sujetvoteOnAttribute() utilise match pour dispatcher$user instanceof UserInterface pour les anonymes@var sur le sujet apres la verification de typeAffiche :
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
final, extends Votermatch pour le dispatchVoter a VoterInterface pour le typage automatique du sujetmatch plutot que switch pour le dispatch des permissions$user instanceof UserInterface avant de traiter#[IsGranted] dans les controleurs plutot que denyAccessUnlessGranted() quand possible