Skip to content

Commit

Permalink
Update security voter (#278)
Browse files Browse the repository at this point in the history
* make published voter compatible with new voter abstract

* change the security voter to the published voter

because you  should only be allowed access when the
workflow checker determines you should be allowed access
and not only when the document isPublishable returns true.
because then documents that are only publised after a period
would slip through
  • Loading branch information
esserj authored Nov 30, 2021
1 parent 4676e05 commit 4419a7c
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 28 deletions.
3 changes: 2 additions & 1 deletion src/Resources/config/publish-workflow.xml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@

<!-- integration with core security service -->

<service id="cmf_core.security.published_voter" class="Symfony\Cmf\Bundle\CoreBundle\PublishWorkflow\Voter\PublishableVoter" public="false">
<service id="cmf_core.security.published_voter" class="Symfony\Cmf\Bundle\CoreBundle\Security\Authorization\Voter\PublishedVoter" public="false">
<argument type="service" id="cmf_core.publish_workflow.checker"/>
<tag name="security.voter"/>
</service>

Expand Down
43 changes: 16 additions & 27 deletions src/Security/Authorization/Voter/PublishedVoter.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,20 @@

namespace Symfony\Cmf\Bundle\CoreBundle\Security\Authorization\Voter;

use function is_subclass_of;
use Symfony\Cmf\Bundle\CoreBundle\PublishWorkflow\PublishableReadInterface;
use Symfony\Cmf\Bundle\CoreBundle\PublishWorkflow\PublishTimePeriodReadInterface;
use Symfony\Cmf\Bundle\CoreBundle\PublishWorkflow\PublishWorkflowChecker;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authorization\Voter\VoterInterface;
use Symfony\Component\Security\Core\Authorization\Voter\Voter;

/**
* This is a security voter registered with the Symfony security system that
* brings the publish workflow into standard Symfony security.
*
* @author David Buchmann <[email protected]>
*/
class PublishedVoter implements VoterInterface
class PublishedVoter extends Voter
{
/**
* @var PublishWorkflowChecker
Expand All @@ -36,41 +39,27 @@ public function __construct(PublishWorkflowChecker $publishWorkflowChecker)
/**
* {@inheritdoc}
*/
public function supportsAttribute($attribute)
public function supportsAttribute($attribute): bool
{
return PublishWorkflowChecker::VIEW_ATTRIBUTE === $attribute
|| PublishWorkflowChecker::VIEW_ANONYMOUS_ATTRIBUTE === $attribute
;
}

/**
* {@inheritdoc}
*/
public function supportsClass($class)
public function supportsType(string $subjectType): bool
{
return $this->publishWorkflowChecker->supportsClass($class);
return is_subclass_of($subjectType, PublishableReadInterface::class)
|| is_subclass_of($subjectType, PublishTimePeriodReadInterface::class);
}

/**
* {@inheritdoc}
*
* @param object $subject
*/
public function vote(TokenInterface $token, $subject, array $attributes)
protected function supports($attribute, $subject)
{
if (!\is_object($subject) || !$this->supportsClass(\get_class($subject))) {
return self::ACCESS_ABSTAIN;
}
foreach ($attributes as $attribute) {
if (!$this->supportsAttribute($attribute)) {
return self::ACCESS_ABSTAIN;
}
}

if ($this->publishWorkflowChecker->isGranted($attributes, $subject)) {
return self::ACCESS_GRANTED;
}
return \is_object($subject) && $this->supportsType(\get_class($subject))
&& $this->supportsAttribute($attribute);
}

return self::ACCESS_DENIED;
protected function voteOnAttribute($attribute, $subject, TokenInterface $token)
{
return $this->publishWorkflowChecker->isGranted($attribute, $subject);
}
}

0 comments on commit 4419a7c

Please sign in to comment.