From 296b73325fa9ea5b65a503399b409e8f0d3f8736 Mon Sep 17 00:00:00 2001 From: Steve Nebes Date: Fri, 24 May 2019 11:39:53 -0500 Subject: [PATCH] Allow arrays of parameters to be used with @IsGranted --- EventListener/IsGrantedListener.php | 28 +++++++++++++++---- Tests/EventListener/IsGrantedListenerTest.php | 21 ++++++++++++++ 2 files changed, 44 insertions(+), 5 deletions(-) diff --git a/EventListener/IsGrantedListener.php b/EventListener/IsGrantedListener.php index 08af82a7..b56cf0fa 100644 --- a/EventListener/IsGrantedListener.php +++ b/EventListener/IsGrantedListener.php @@ -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; @@ -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)) { @@ -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) { diff --git a/Tests/EventListener/IsGrantedListenerTest.php b/Tests/EventListener/IsGrantedListenerTest.php index 8d065a98..a9577707 100644 --- a/Tests/EventListener/IsGrantedListenerTest.php +++ b/Tests/EventListener/IsGrantedListenerTest.php @@ -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 */