From 242b3184b9314294268433c448081a3c309003f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Tamarelle?= Date: Mon, 15 Jul 2013 22:34:29 +0200 Subject: [PATCH 1/4] [DependencyInjection] Add exception for service name not dumpable in PHP --- .../DependencyInjection/Dumper/PhpDumper.php | 26 ++++++++++++++++--- .../Tests/Dumper/PhpDumperTest.php | 12 +++++++++ 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php index 8ae9b616c5..31be3f416b 100644 --- a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php +++ b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php @@ -436,7 +436,6 @@ class PhpDumper extends Dumper */ private function addService($id, $definition) { - $name = Container::camelize($id); $this->definitionVariables = new \SplObjectStorage(); $this->referenceVariables = array(); $this->variableCount = 0; @@ -479,7 +478,7 @@ EOF; * * $return */ - protected function get{$name}Service() + protected function {$this->getMethodName($id)}() { EOF; @@ -527,7 +526,6 @@ EOF; */ private function addServiceAlias($alias, $id) { - $name = Container::camelize($alias); $type = 'Object'; if ($this->container->hasDefinition($id)) { @@ -542,7 +540,7 @@ EOF; * * @return $type An instance of the $id service */ - protected function get{$name}Service() + protected function {$this->getMethodName($alias)}() { return {$this->getServiceCall($id)}; } @@ -550,6 +548,26 @@ EOF; EOF; } + /** + * Convert a service id to a valid PHP method name. + * + * @param string $id + * + * @return string + * + * @throws InvalidArgumentException + */ + private function getMethodName($id) + { + $name = Container::camelize($id); + + if (!preg_match('/^[a-zA-Z0-9_\x7f-\xff]+$/', $name)) { + throw new InvalidArgumentException(sprintf('Service id "%s" cannot be converted to a valid PHP method name.', $id)); + } + + return 'get'.$name.'Service'; + } + /** * Adds multiple services * diff --git a/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php b/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php index 72d587ff07..369ac81bbe 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php @@ -120,6 +120,18 @@ class PhpDumperTest extends \PHPUnit_Framework_TestCase } } + /** + * @expectedException InvalidArgumentException + * @expectedExceptionMessage Service id "bar$" cannot be converted to a valid PHP method name. + */ + public function testAddServiceInvalidServiceId() + { + $container = new ContainerBuilder(); + $container->register('bar$', 'FooClass'); + $dumper = new PhpDumper($container); + $dumper->dump(); + } + public function testOverrideServiceWhenUsingADumpedContainer() { require_once self::$fixturesPath.'/php/services9.php'; From 2ebb783c058de8f1de7a3a050234669a6df8870e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20Augustin?= Date: Wed, 17 Jul 2013 09:33:13 +0200 Subject: [PATCH 2/4] fix issue #8499 modelChoiceList call getPrimaryKey on a non object --- .../Propel1/Form/ChoiceList/ModelChoiceList.php | 6 +++++- .../Tests/Form/ChoiceList/ModelChoiceListTest.php | 12 ++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Bridge/Propel1/Form/ChoiceList/ModelChoiceList.php b/src/Symfony/Bridge/Propel1/Form/ChoiceList/ModelChoiceList.php index 611139ae69..65356f47e2 100644 --- a/src/Symfony/Bridge/Propel1/Form/ChoiceList/ModelChoiceList.php +++ b/src/Symfony/Bridge/Propel1/Form/ChoiceList/ModelChoiceList.php @@ -289,7 +289,7 @@ class ModelChoiceList extends ObjectChoiceList $choices = $this->fixChoices($models); foreach ($this->getChoices() as $i => $choice) { foreach ($choices as $j => $givenChoice) { - if ($this->getIdentifierValues($choice) === $this->getIdentifierValues($givenChoice)) { + if (null !== $givenChoice && $this->getIdentifierValues($choice) === $this->getIdentifierValues($givenChoice)) { $indices[] = $i; unset($choices[$j]); @@ -416,6 +416,10 @@ class ModelChoiceList extends ObjectChoiceList return array($model->getPrimaryKey()); } + if (null === $model) { + return array(); + } + return $model->getPrimaryKeys(); } diff --git a/src/Symfony/Bridge/Propel1/Tests/Form/ChoiceList/ModelChoiceListTest.php b/src/Symfony/Bridge/Propel1/Tests/Form/ChoiceList/ModelChoiceListTest.php index 59f1367f2a..f98c71ad4c 100644 --- a/src/Symfony/Bridge/Propel1/Tests/Form/ChoiceList/ModelChoiceListTest.php +++ b/src/Symfony/Bridge/Propel1/Tests/Form/ChoiceList/ModelChoiceListTest.php @@ -199,4 +199,16 @@ class ModelChoiceListTest extends Propel1TestCase $this->assertEquals(array(1), $choiceList->getIndicesForChoices(array($choosenItem))); } + + public function testGetIndicesForNullChoices() + { + $item = new Item(1, 'Foo'); + $choiceList = new ModelChoiceList( + self::ITEM_CLASS, + 'value', + array($item) + ); + + $this->assertEquals(array(), $choiceList->getIndicesForChoices(array(null))); + } } From 231744370849df57ff7032e0246fc882d9c26220 Mon Sep 17 00:00:00 2001 From: alcaeus Date: Fri, 14 Jun 2013 20:11:03 +0200 Subject: [PATCH 3/4] [Security] fixed issue where authentication listeners clear unrelated tokens This commit fixes an issue where authentication listeners clear all security tokens in case of authentication failure. This behavior makes it impossible to combine certain authentication mechanisms, notably x509 with form-based login. --- .../AbstractAuthenticationListener.php | 5 +- .../AbstractPreAuthenticatedListener.php | 19 +- .../Firewall/BasicAuthenticationListener.php | 5 +- .../Firewall/DigestAuthenticationListener.php | 5 +- .../AbstractPreAuthenticatedListenerTest.php | 267 ++++++++++++++++++ .../BasicAuthenticationListenerTest.php | 56 +++- .../X509AuthenticationListenerTest.php | 115 ++++++++ 7 files changed, 466 insertions(+), 6 deletions(-) create mode 100644 src/Symfony/Component/Security/Tests/Http/Firewall/AbstractPreAuthenticatedListenerTest.php create mode 100644 src/Symfony/Component/Security/Tests/Http/Firewall/X509AuthenticationListenerTest.php diff --git a/src/Symfony/Component/Security/Http/Firewall/AbstractAuthenticationListener.php b/src/Symfony/Component/Security/Http/Firewall/AbstractAuthenticationListener.php index d33c0f7344..384f7ce475 100644 --- a/src/Symfony/Component/Security/Http/Firewall/AbstractAuthenticationListener.php +++ b/src/Symfony/Component/Security/Http/Firewall/AbstractAuthenticationListener.php @@ -186,7 +186,10 @@ abstract class AbstractAuthenticationListener implements ListenerInterface $this->logger->info(sprintf('Authentication request failed: %s', $failed->getMessage())); } - $this->securityContext->setToken(null); + $token = $this->securityContext->getToken(); + if ($token instanceof UsernamePasswordToken && $this->providerKey === $token->getProviderKey()) { + $this->securityContext->setToken(null); + } $response = $this->failureHandler->onAuthenticationFailure($request, $failed); diff --git a/src/Symfony/Component/Security/Http/Firewall/AbstractPreAuthenticatedListener.php b/src/Symfony/Component/Security/Http/Firewall/AbstractPreAuthenticatedListener.php index c6e47d083b..28f6411f92 100644 --- a/src/Symfony/Component/Security/Http/Firewall/AbstractPreAuthenticatedListener.php +++ b/src/Symfony/Component/Security/Http/Firewall/AbstractPreAuthenticatedListener.php @@ -21,6 +21,7 @@ use Symfony\Component\HttpKernel\Event\GetResponseEvent; use Psr\Log\LoggerInterface; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\EventDispatcher\EventDispatcherInterface; +use Symfony\Component\Security\Core\Exception\BadCredentialsException; /** * AbstractPreAuthenticatedListener is the base class for all listener that @@ -59,7 +60,12 @@ abstract class AbstractPreAuthenticatedListener implements ListenerInterface $this->logger->debug(sprintf('Checking secure context token: %s', $this->securityContext->getToken())); } - list($user, $credentials) = $this->getPreAuthenticatedData($request); + try { + list($user, $credentials) = $this->getPreAuthenticatedData($request); + } catch (BadCredentialsException $exception) { + $this->clearToken(); + return; + } if (null !== $token = $this->securityContext->getToken()) { if ($token instanceof PreAuthenticatedToken && $this->providerKey == $token->getProviderKey() && $token->isAuthenticated() && $token->getUsername() === $user) { @@ -84,6 +90,17 @@ abstract class AbstractPreAuthenticatedListener implements ListenerInterface $this->dispatcher->dispatch(SecurityEvents::INTERACTIVE_LOGIN, $loginEvent); } } catch (AuthenticationException $failed) { + $this->clearToken(); + } + } + + /** + * Clears a PreAuthenticatedToken for this provider (if present) + */ + protected function clearToken() + { + $token = $this->securityContext->getToken(); + if ($token instanceof PreAuthenticatedToken && $this->providerKey === $token->getProviderKey()) { $this->securityContext->setToken(null); if (null !== $this->logger) { diff --git a/src/Symfony/Component/Security/Http/Firewall/BasicAuthenticationListener.php b/src/Symfony/Component/Security/Http/Firewall/BasicAuthenticationListener.php index 5b1c8b318d..bfc4abc834 100644 --- a/src/Symfony/Component/Security/Http/Firewall/BasicAuthenticationListener.php +++ b/src/Symfony/Component/Security/Http/Firewall/BasicAuthenticationListener.php @@ -74,7 +74,10 @@ class BasicAuthenticationListener implements ListenerInterface $token = $this->authenticationManager->authenticate(new UsernamePasswordToken($username, $request->headers->get('PHP_AUTH_PW'), $this->providerKey)); $this->securityContext->setToken($token); } catch (AuthenticationException $failed) { - $this->securityContext->setToken(null); + $token = $this->securityContext->getToken(); + if ($token instanceof UsernamePasswordToken && $this->providerKey === $token->getProviderKey()) { + $this->securityContext->setToken(null); + } if (null !== $this->logger) { $this->logger->info(sprintf('Authentication request failed for user "%s": %s', $username, $failed->getMessage())); diff --git a/src/Symfony/Component/Security/Http/Firewall/DigestAuthenticationListener.php b/src/Symfony/Component/Security/Http/Firewall/DigestAuthenticationListener.php index 7ab3dcf757..ea85e776a8 100644 --- a/src/Symfony/Component/Security/Http/Firewall/DigestAuthenticationListener.php +++ b/src/Symfony/Component/Security/Http/Firewall/DigestAuthenticationListener.php @@ -124,7 +124,10 @@ class DigestAuthenticationListener implements ListenerInterface private function fail(GetResponseEvent $event, Request $request, AuthenticationException $authException) { - $this->securityContext->setToken(null); + $token = $this->securityContext->getToken(); + if ($token instanceof UsernamePasswordToken && $this->providerKey === $token->getProviderKey()) { + $this->securityContext->setToken(null); + } if (null !== $this->logger) { $this->logger->info($authException); diff --git a/src/Symfony/Component/Security/Tests/Http/Firewall/AbstractPreAuthenticatedListenerTest.php b/src/Symfony/Component/Security/Tests/Http/Firewall/AbstractPreAuthenticatedListenerTest.php new file mode 100644 index 0000000000..76721ec955 --- /dev/null +++ b/src/Symfony/Component/Security/Tests/Http/Firewall/AbstractPreAuthenticatedListenerTest.php @@ -0,0 +1,267 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Security\Tests\Http\Firewall; + +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\Security\Core\Authentication\Token\PreAuthenticatedToken; +use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken; +use Symfony\Component\Security\Core\Exception\AuthenticationException; + +class AbstractPreAuthenticatedListenerTest extends \PHPUnit_Framework_TestCase +{ + protected function setUp() + { + if (!class_exists('Symfony\Component\EventDispatcher\EventDispatcher')) { + $this->markTestSkipped('The "EventDispatcher" component is not available'); + } + + if (!class_exists('Symfony\Component\HttpFoundation\Request')) { + $this->markTestSkipped('The "HttpFoundation" component is not available'); + } + + if (!class_exists('Symfony\Component\HttpKernel\HttpKernel')) { + $this->markTestSkipped('The "HttpKernel" component is not available'); + } + } + + public function testHandleWithValidValues() + { + $userCredentials = array('TheUser', 'TheCredentials'); + + $request = new Request(array(), array(), array(), array(), array(), array()); + + $token = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface'); + + $context = $this->getMock('Symfony\Component\Security\Core\SecurityContextInterface'); + $context + ->expects($this->any()) + ->method('getToken') + ->will($this->returnValue(null)) + ; + $context + ->expects($this->once()) + ->method('setToken') + ->with($this->equalTo($token)) + ; + + $authenticationManager = $this->getMock('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface'); + $authenticationManager + ->expects($this->once()) + ->method('authenticate') + ->with($this->isInstanceOf('Symfony\Component\Security\Core\Authentication\Token\PreAuthenticatedToken')) + ->will($this->returnValue($token)) + ; + + $listener = $this->getMockForAbstractClass('Symfony\Component\Security\Http\Firewall\AbstractPreAuthenticatedListener', array( + $context, + $authenticationManager, + 'TheProviderKey' + )); + $listener + ->expects($this->once()) + ->method('getPreAuthenticatedData') + ->will($this->returnValue($userCredentials)); + + $event = $this->getMock('Symfony\Component\HttpKernel\Event\GetResponseEvent', array(), array(), '', false); + $event + ->expects($this->any()) + ->method('getRequest') + ->will($this->returnValue($request)) + ; + + $listener->handle($event); + } + + public function testHandleWhenAuthenticationFails() + { + $userCredentials = array('TheUser', 'TheCredentials'); + + $request = new Request(array(), array(), array(), array(), array(), array()); + + $context = $this->getMock('Symfony\Component\Security\Core\SecurityContextInterface'); + $context + ->expects($this->any()) + ->method('getToken') + ->will($this->returnValue(null)) + ; + $context + ->expects($this->never()) + ->method('setToken') + ; + + $exception = new AuthenticationException('Authentication failed.'); + $authenticationManager = $this->getMock('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface'); + $authenticationManager + ->expects($this->once()) + ->method('authenticate') + ->with($this->isInstanceOf('Symfony\Component\Security\Core\Authentication\Token\PreAuthenticatedToken')) + ->will($this->throwException($exception)) + ; + + $listener = $this->getMockForAbstractClass('Symfony\Component\Security\Http\Firewall\AbstractPreAuthenticatedListener', array( + $context, + $authenticationManager, + 'TheProviderKey' + )); + $listener + ->expects($this->once()) + ->method('getPreAuthenticatedData') + ->will($this->returnValue($userCredentials)); + + $event = $this->getMock('Symfony\Component\HttpKernel\Event\GetResponseEvent', array(), array(), '', false); + $event + ->expects($this->any()) + ->method('getRequest') + ->will($this->returnValue($request)) + ; + + $listener->handle($event); + } + + public function testHandleWhenAuthenticationFailsWithDifferentToken() + { + $userCredentials = array('TheUser', 'TheCredentials'); + + $token = new UsernamePasswordToken('TheUsername', 'ThePassword', 'TheProviderKey', array('ROLE_FOO')); + + $request = new Request(array(), array(), array(), array(), array(), array()); + + $context = $this->getMock('Symfony\Component\Security\Core\SecurityContextInterface'); + $context + ->expects($this->any()) + ->method('getToken') + ->will($this->returnValue($token)) + ; + $context + ->expects($this->never()) + ->method('setToken') + ; + + $exception = new AuthenticationException('Authentication failed.'); + $authenticationManager = $this->getMock('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface'); + $authenticationManager + ->expects($this->once()) + ->method('authenticate') + ->with($this->isInstanceOf('Symfony\Component\Security\Core\Authentication\Token\PreAuthenticatedToken')) + ->will($this->throwException($exception)) + ; + + $listener = $this->getMockForAbstractClass('Symfony\Component\Security\Http\Firewall\AbstractPreAuthenticatedListener', array( + $context, + $authenticationManager, + 'TheProviderKey' + )); + $listener + ->expects($this->once()) + ->method('getPreAuthenticatedData') + ->will($this->returnValue($userCredentials)); + + $event = $this->getMock('Symfony\Component\HttpKernel\Event\GetResponseEvent', array(), array(), '', false); + $event + ->expects($this->any()) + ->method('getRequest') + ->will($this->returnValue($request)) + ; + + $listener->handle($event); + } + + public function testHandleWithASimilarAuthenticatedToken() + { + $userCredentials = array('TheUser', 'TheCredentials'); + + $request = new Request(array(), array(), array(), array(), array(), array()); + + $token = new PreAuthenticatedToken('TheUser', 'TheCredentials', 'TheProviderKey', array('ROLE_FOO')); + + $context = $this->getMock('Symfony\Component\Security\Core\SecurityContextInterface'); + $context + ->expects($this->any()) + ->method('getToken') + ->will($this->returnValue($token)) + ; + + $authenticationManager = $this->getMock('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface'); + $authenticationManager + ->expects($this->never()) + ->method('authenticate') + ; + + $listener = $this->getMockForAbstractClass('Symfony\Component\Security\Http\Firewall\AbstractPreAuthenticatedListener', array( + $context, + $authenticationManager, + 'TheProviderKey' + )); + $listener + ->expects($this->once()) + ->method('getPreAuthenticatedData') + ->will($this->returnValue($userCredentials)); + + $event = $this->getMock('Symfony\Component\HttpKernel\Event\GetResponseEvent', array(), array(), '', false); + $event + ->expects($this->any()) + ->method('getRequest') + ->will($this->returnValue($request)) + ; + + $listener->handle($event); + } + + public function testHandleWithAnInvalidSimilarToken() + { + $userCredentials = array('TheUser', 'TheCredentials'); + + $request = new Request(array(), array(), array(), array(), array(), array()); + + $token = new PreAuthenticatedToken('AnotherUser', 'TheCredentials', 'TheProviderKey', array('ROLE_FOO')); + + $context = $this->getMock('Symfony\Component\Security\Core\SecurityContextInterface'); + $context + ->expects($this->any()) + ->method('getToken') + ->will($this->returnValue($token)) + ; + $context + ->expects($this->once()) + ->method('setToken') + ->with($this->equalTo(null)) + ; + + $exception = new AuthenticationException('Authentication failed.'); + $authenticationManager = $this->getMock('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface'); + $authenticationManager + ->expects($this->once()) + ->method('authenticate') + ->with($this->isInstanceOf('Symfony\Component\Security\Core\Authentication\Token\PreAuthenticatedToken')) + ->will($this->throwException($exception)) + ; + + $listener = $this->getMockForAbstractClass('Symfony\Component\Security\Http\Firewall\AbstractPreAuthenticatedListener', array( + $context, + $authenticationManager, + 'TheProviderKey' + )); + $listener + ->expects($this->once()) + ->method('getPreAuthenticatedData') + ->will($this->returnValue($userCredentials)); + + $event = $this->getMock('Symfony\Component\HttpKernel\Event\GetResponseEvent', array(), array(), '', false); + $event + ->expects($this->any()) + ->method('getRequest') + ->will($this->returnValue($request)) + ; + + $listener->handle($event); + } +} diff --git a/src/Symfony/Component/Security/Tests/Http/Firewall/BasicAuthenticationListenerTest.php b/src/Symfony/Component/Security/Tests/Http/Firewall/BasicAuthenticationListenerTest.php index 667869f764..84564bf6af 100644 --- a/src/Symfony/Component/Security/Tests/Http/Firewall/BasicAuthenticationListenerTest.php +++ b/src/Symfony/Component/Security/Tests/Http/Firewall/BasicAuthenticationListenerTest.php @@ -12,6 +12,7 @@ namespace Symfony\Component\Security\Tests\Http\Firewall; use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\Security\Core\Authentication\Token\PreAuthenticatedToken; use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Security\Http\Firewall\BasicAuthenticationListener; @@ -96,9 +97,8 @@ class BasicAuthenticationListenerTest extends \PHPUnit_Framework_TestCase ->will($this->returnValue(null)) ; $context - ->expects($this->once()) + ->expects($this->never()) ->method('setToken') - ->with($this->equalTo(null)) ; $response = new Response(); @@ -195,4 +195,56 @@ class BasicAuthenticationListenerTest extends \PHPUnit_Framework_TestCase $listener->handle($event); } + + public function testHandleWithADifferentAuthenticatedToken() + { + $request = new Request(array(), array(), array(), array(), array(), array( + 'PHP_AUTH_USER' => 'TheUsername', + 'PHP_AUTH_PW' => 'ThePassword' + )); + + $token = new PreAuthenticatedToken('TheUser', 'TheCredentials', 'TheProviderKey', array('ROLE_FOO')); + + $context = $this->getMock('Symfony\Component\Security\Core\SecurityContextInterface'); + $context + ->expects($this->any()) + ->method('getToken') + ->will($this->returnValue($token)) + ; + $context + ->expects($this->never()) + ->method('setToken') + ; + + $response = new Response(); + + $authenticationEntryPoint = $this->getMock('Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface'); + $authenticationEntryPoint + ->expects($this->any()) + ->method('start') + ->with($this->equalTo($request), $this->isInstanceOf('Symfony\Component\Security\Core\Exception\AuthenticationException')) + ->will($this->returnValue($response)) + ; + + $listener = new BasicAuthenticationListener( + $context, + new AuthenticationProviderManager(array($this->getMock('Symfony\Component\Security\Core\Authentication\Provider\AuthenticationProviderInterface'))), + 'TheProviderKey', + $authenticationEntryPoint + ); + + $event = $this->getMock('Symfony\Component\HttpKernel\Event\GetResponseEvent', array(), array(), '', false); + $event + ->expects($this->any()) + ->method('getRequest') + ->will($this->returnValue($request)) + ; + $event + ->expects($this->once()) + ->method('setResponse') + ->with($this->equalTo($response)) + ; + + $listener->handle($event); + } } diff --git a/src/Symfony/Component/Security/Tests/Http/Firewall/X509AuthenticationListenerTest.php b/src/Symfony/Component/Security/Tests/Http/Firewall/X509AuthenticationListenerTest.php new file mode 100644 index 0000000000..81ac0f7d5c --- /dev/null +++ b/src/Symfony/Component/Security/Tests/Http/Firewall/X509AuthenticationListenerTest.php @@ -0,0 +1,115 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Security\Tests\Http\Firewall; + +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\Security\Http\Firewall\X509AuthenticationListener; + +class X509AuthenticationListenerTest extends \PHPUnit_Framework_TestCase +{ + protected function setUp() + { + if (!class_exists('Symfony\Component\HttpFoundation\Request')) { + $this->markTestSkipped('The "HttpFoundation" component is not available'); + } + } + + /** + * @dataProvider dataProviderGetPreAuthenticatedData + */ + public function testGetPreAuthenticatedData($user, $credentials) + { + $serverVars = array(); + if ('' !== $user) { + $serverVars['SSL_CLIENT_S_DN_Email'] = $user; + } + if ('' !== $credentials) { + $serverVars['SSL_CLIENT_S_DN'] = $credentials; + } + + $request = new Request(array(), array(), array(), array(), array(), $serverVars); + + $context = $this->getMock('Symfony\Component\Security\Core\SecurityContextInterface'); + + $authenticationManager = $this->getMock('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface'); + + $listener = new X509AuthenticationListener( + $context, + $authenticationManager, + 'TheProviderKey' + ); + + $method = new \ReflectionMethod($listener, 'getPreAuthenticatedData'); + $method->setAccessible(true); + + $result = $method->invokeArgs($listener, array($request)); + $this->assertSame($result, array($user, $credentials)); + } + + public static function dataProviderGetPreAuthenticatedData() + { + return array( + 'validValues' => array('TheUser', 'TheCredentials'), + 'noCredentials' => array('TheUser', ''), + ); + } + + /** + * @expectedException Symfony\Component\Security\Core\Exception\BadCredentialsException + */ + public function testGetPreAuthenticatedDataNoUser() + { + $request = new Request(array(), array(), array(), array(), array(), array()); + + $context = $this->getMock('Symfony\Component\Security\Core\SecurityContextInterface'); + + $authenticationManager = $this->getMock('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface'); + + $listener = new X509AuthenticationListener( + $context, + $authenticationManager, + 'TheProviderKey' + ); + + $method = new \ReflectionMethod($listener, 'getPreAuthenticatedData'); + $method->setAccessible(true); + + $result = $method->invokeArgs($listener, array($request)); + } + + public function testGetPreAuthenticatedDataWithDifferentKeys() + { + $userCredentials = array('TheUser', 'TheCredentials'); + + $request = new Request(array(), array(), array(), array(), array(), array( + 'TheUserKey' => 'TheUser', + 'TheCredentialsKey' => 'TheCredentials' + )); + $context = $this->getMock('Symfony\Component\Security\Core\SecurityContextInterface'); + + $authenticationManager = $this->getMock('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface'); + + $listener = new X509AuthenticationListener( + $context, + $authenticationManager, + 'TheProviderKey', + 'TheUserKey', + 'TheCredentialsKey' + ); + + $method = new \ReflectionMethod($listener, 'getPreAuthenticatedData'); + $method->setAccessible(true); + + $result = $method->invokeArgs($listener, array($request)); + $this->assertSame($result, $userCredentials); + } +} From d6cafcd63c0cd2e2b2313396666452f211061286 Mon Sep 17 00:00:00 2001 From: Ian Phillips Date: Fri, 19 Jul 2013 16:05:19 -0700 Subject: [PATCH 4/4] [PropertyAccess] added moves to pluralMap --- src/Symfony/Component/PropertyAccess/StringUtil.php | 3 +++ src/Symfony/Component/PropertyAccess/Tests/StringUtilTest.php | 1 + 2 files changed, 4 insertions(+) diff --git a/src/Symfony/Component/PropertyAccess/StringUtil.php b/src/Symfony/Component/PropertyAccess/StringUtil.php index d8704f38d2..7c0eadcacd 100644 --- a/src/Symfony/Component/PropertyAccess/StringUtil.php +++ b/src/Symfony/Component/PropertyAccess/StringUtil.php @@ -75,6 +75,9 @@ class StringUtil // lives (life), wives (wife) array('sevi', 4, false, true, 'ife'), + // moves (move) + array('sevom', 5, true, true, 'move'), + // hooves (hoof), dwarves (dwarf), elves (elf), leaves (leaf) array('sev', 3, true, true, 'f'), diff --git a/src/Symfony/Component/PropertyAccess/Tests/StringUtilTest.php b/src/Symfony/Component/PropertyAccess/Tests/StringUtilTest.php index 66bb6c9767..6fc3d9a27b 100644 --- a/src/Symfony/Component/PropertyAccess/Tests/StringUtilTest.php +++ b/src/Symfony/Component/PropertyAccess/Tests/StringUtilTest.php @@ -118,6 +118,7 @@ class StringUtilTest extends \PHPUnit_Framework_TestCase array('cheeses', array('chees', 'cheese', 'cheesis')), array('radii', 'radius'), array('objectives', 'objective'), + array('moves', 'move'), // test casing: if the first letter was uppercase, it should remain so array('Men', 'Man'),