Fix decision logic in AbstractStoredObjectVoter

Amend the condition to ensure proper attribute validation before checking workflow association. This prevents unintended execution paths and potential exceptions when the workflow document service is not provided.
This commit is contained in:
Julien Fastré 2024-07-25 23:34:36 +02:00
parent b19dd4fc11
commit 5fed42a623
Signed by: julienfastre
GPG Key ID: BDE2190974723FCB
3 changed files with 14 additions and 4 deletions

View File

@ -12,6 +12,7 @@ declare(strict_types=1);
namespace Chill\DocStoreBundle\Security\Authorization;
use Chill\DocStoreBundle\Entity\StoredObject;
use Psr\Log\LoggerInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authorization\Voter\Voter;
use Symfony\Component\Security\Core\Security;
@ -23,7 +24,9 @@ use Symfony\Component\Security\Core\Security;
*/
class StoredObjectVoter extends Voter
{
public function __construct(private readonly Security $security, private readonly iterable $storedObjectVoters) {}
public const LOG_PREFIX = '[stored object voter] ';
public function __construct(private readonly Security $security, private readonly iterable $storedObjectVoters, private readonly LoggerInterface $logger) {}
protected function supports($attribute, $subject): bool
{
@ -39,7 +42,13 @@ class StoredObjectVoter extends Voter
// Loop through context-specific voters
foreach ($this->storedObjectVoters as $storedObjectVoter) {
if ($storedObjectVoter->supports($attributeAsEnum, $subject)) {
return $storedObjectVoter->voteOnAttribute($attributeAsEnum, $subject, $token);
$grant = $storedObjectVoter->voteOnAttribute($attributeAsEnum, $subject, $token);
if (false === $grant) {
$this->logger->debug(self::LOG_PREFIX.'deny access by storedObjectVoter', ['stored_object_voter' => get_class($storedObjectVoter)]);
}
return $grant;
}
}

View File

@ -56,7 +56,7 @@ abstract class AbstractStoredObjectVoter implements StoredObjectVoterInterface
return false;
}
if ($this->canBeAssociatedWithWorkflow()) {
if (StoredObjectRoleEnum::SEE !== $attribute && $this->canBeAssociatedWithWorkflow()) {
if (null === $this->workflowDocumentService) {
throw new \LogicException('Provide a workflow document service');
}

View File

@ -17,6 +17,7 @@ use Chill\DocStoreBundle\Security\Authorization\StoredObjectVoter;
use Chill\DocStoreBundle\Security\Authorization\StoredObjectVoterInterface;
use Chill\MainBundle\Entity\User;
use PHPUnit\Framework\TestCase;
use Psr\Log\NullLogger;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
use Symfony\Component\Security\Core\Authorization\Voter\VoterInterface;
@ -43,7 +44,7 @@ class StoredObjectVoterTest extends TestCase
->with($this->logicalOr($this->identicalTo('ROLE_USER'), $this->identicalTo('ROLE_ADMIN')))
->willReturn($securityIsGrantedResult);
$voter = new StoredObjectVoter($security, $storedObjectVoters);
$voter = new StoredObjectVoter($security, $storedObjectVoters, new NullLogger());
self::assertEquals($expected, $voter->vote($token, $subject, [$attribute]));
}