Hacktoberfest 2026: le issue che i maintainer hanno segnato per ottobre, aperte e adatte ai principianti. Sfoglia le issue Hacktoberfest

[Security] Document is persisted before voters result on securityPostDenormalize

Aperta
#8,429 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
4/5
Tempo stimato
3-5 giorni
Idoneità per principianti
52/100
Tipo di issue
Bug
Chiarezza
Abbastanza chiara
Stato di attività
Tranquilla
Stack tecnologico
php

Direzione di ricerca

Inizia con l'elaborazione di securityPostDenormalize e la riproduzione in AgentRoleTest.php, quindi segui come il DocumentManager gestisce l'oggetto PATCH rifiutato. Esegui lo scenario di test mostrato e verifica che un flush successivo non persista le modifiche della richiesta fallita, continuando però a persistere il ruolo dell'utente corrente modificato esplicitamente.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

API Platform version(s) affected: 4.3.5

Description
When a resource is behind a voter on Patch operation and custom logic is called with a Voter using securityPostDenormalize, the incoming document is still persisted and therefore is written in the database if a flush comes after.

AgentRole.php

#[ApiResource(operations: [
    new Patch(
        securityPostDenormalize: "is_granted('ROLE_UPDATE', object)",
        extraProperties: ['throw_on_access_denied' => true],
    ),
])]

AgentRoleVoter.php

protected function supports(string $attribute, mixed $subject): bool
{
    $supportAttributes = $attribute == 'ROLE_UPDATE';
    $supportSubject = $subject instanceof AgentRole;

    return $supportAttributes && $supportSubject;
}

protected function voteOnAttribute(string $attribute, mixed $subject, TokenInterface $token): bool
{
    // some false logic
}

AgentRoleTest.php

use ResetDatabase;

public function testChangeAgentRoleToDev()
{
    $client = static::createClientWithCredentials();
    $dm = $this->getContainer()->get(DocumentManager::class);

    $agentRoles = AgentRoleFactory::createSequence([
        ['agentId' => '1', 'roles' => ['ROLE_USER']],
        ['agentId' => '2', 'roles' => ['ROLE_USER']]
    ]);

    $client->request('PATCH', '/agent_roles/1', [
        'headers' => ['Content-Type' => 'application/merge-patch+json'],
        'json' => [
            'roles' => ['ROLE_USER', 'ROLE_DEV']
        ]
    ]);

    $this->assertResponseStatusCodeSame(403); // OK

    // I would need to use $dm->clear() to flush previous operation without persisting
    // $dm->clear();

    $currentUserRole = $dm->getRepository(AgentRole::class)->findOneBy([
        'agentId' => 'user' // current logged user
    ]);
    $currentUserRole->setRoles(['ROLE_ADMIN']);
    $dm->persist($currentUserRole);
    $dm->flush(); // <-------- this persist also the request operation which wasn't persisted on request execution
}

Before flush:
Image

After:
Image

Lingua principale
PHP
Stelle
2.6k
Fork
982
Merge medio
1g 16h
PR unite (30g)
59

Guida per i contributori

Apri la guida per i contributori

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di api-platform/core

Tutte le issue di api-platform/core

Issue simili

Altre issue su PHP

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.