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 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
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
| 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