Skip to content
This repository has been archived by the owner on Feb 24, 2023. It is now read-only.

Allow arrays of parameters to be used with @IsGranted #618

Merged
merged 1 commit into from Jul 3, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
28 changes: 23 additions & 5 deletions EventListener/IsGrantedListener.php
Expand Up @@ -39,6 +39,7 @@ public function __construct(ArgumentNameConverter $argumentNameConverter, Author
public function onKernelControllerArguments(FilterControllerArgumentsEvent $event)
{
$request = $event->getRequest();

/** @var $configurations IsGranted[] */
if (!$configurations = $request->attributes->get('_is_granted')) {
return;
Expand All @@ -51,13 +52,25 @@ public function onKernelControllerArguments(FilterControllerArgumentsEvent $even
$arguments = $this->argumentNameConverter->getControllerArguments($event);

foreach ($configurations as $configuration) {
$subjectRef = $configuration->getSubject();
$subject = null;
if ($configuration->getSubject()) {
if (!isset($arguments[$configuration->getSubject()])) {
throw new \RuntimeException(sprintf('Could not find the subject "%s" for the @IsGranted annotation. Try adding a "$%s" argument to your controller method.', $configuration->getSubject(), $configuration->getSubject()));
}

$subject = $arguments[$configuration->getSubject()];
if ($subjectRef) {
if (\is_array($subjectRef)) {
foreach ($subjectRef as $ref) {
if (!isset($arguments[$ref])) {
throw $this->createMissingSubjectException($ref);
}

$subject[$ref] = $arguments[$ref];
}
} else {
if (!isset($arguments[$subjectRef])) {
throw $this->createMissingSubjectException($subjectRef);
}

$subject = $arguments[$subjectRef];
}
}

if (!$this->authChecker->isGranted($configuration->getAttributes(), $subject)) {
Expand All @@ -74,6 +87,11 @@ public function onKernelControllerArguments(FilterControllerArgumentsEvent $even
}
}

private function createMissingSubjectException(string $subject)
{
return new \RuntimeException(sprintf('Could not find the subject "%s" for the @IsGranted annotation. Try adding a "$%s" argument to your controller method.', $subject, $subject));
}

private function getIsGrantedString(IsGranted $isGranted)
{
$attributes = array_map(function ($attribute) {
Expand Down
21 changes: 21 additions & 0 deletions Tests/EventListener/IsGrantedListenerTest.php
Expand Up @@ -77,6 +77,27 @@ public function testIsGrantedSubjectFromArguments()
$listener->onKernelControllerArguments($this->createFilterControllerEvent($request));
}

public function testIsGrantedSubjectFromArgumentsWithArray()
{
$authChecker = $this->getMockBuilder(AuthorizationCheckerInterface::class)->getMock();
// createRequest() puts 2 IsGranted annotations into the config
$authChecker->expects($this->exactly(2))
->method('isGranted')
// the subject => arg2name will eventually resolve to the 2nd argument, which has this value
->with('ROLE_ADMIN', [
'arg1Name' => 'arg1Value',
'arg2Name' => 'arg2Value',
])
->will($this->returnValue(true));

// create metadata for 2 named args for the controller
$listener = new IsGrantedListener($this->createArgumentNameConverter(['arg1Name' => 'arg1Value', 'arg2Name' => 'arg2Value']), $authChecker);
$isGranted = new IsGranted(['attributes' => 'ROLE_ADMIN', 'subject' => ['arg1Name', 'arg2Name']]);
$request = $this->createRequest($isGranted);

$listener->onKernelControllerArguments($this->createFilterControllerEvent($request));
}

/**
* @expectedException \RuntimeException
*/
Expand Down