/src/Symfony/Component/Security/Http/Tests/Firewall/UsernamePasswordJsonAuthenticationListenerTest.php

https://github.com/deviantintegral/symfony · PHP · 215 lines · 146 code · 35 blank · 34 comment · 2 complexity · 99261b77810e873298a61eeeb22e91d2 MD5 · raw file

  1. <?php
  2. /*
  3. * This file is part of the Symfony package.
  4. *
  5. * (c) Fabien Potencier <fabien@symfony.com>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Symfony\Component\Security\Tests\Http\Firewall;
  11. use PHPUnit\Framework\TestCase;
  12. use Symfony\Component\HttpFoundation\Request;
  13. use Symfony\Component\HttpFoundation\Response;
  14. use Symfony\Component\HttpKernel\Event\GetResponseEvent;
  15. use Symfony\Component\HttpKernel\KernelInterface;
  16. use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface;
  17. use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
  18. use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
  19. use Symfony\Component\Security\Core\Exception\AuthenticationException;
  20. use Symfony\Component\Security\Core\Security;
  21. use Symfony\Component\Security\Http\Authentication\AuthenticationFailureHandlerInterface;
  22. use Symfony\Component\Security\Http\Authentication\AuthenticationSuccessHandlerInterface;
  23. use Symfony\Component\Security\Http\Firewall\UsernamePasswordJsonAuthenticationListener;
  24. use Symfony\Component\Security\Http\HttpUtils;
  25. /**
  26. * @author Kévin Dunglas <dunglas@gmail.com>
  27. */
  28. class UsernamePasswordJsonAuthenticationListenerTest extends TestCase
  29. {
  30. /**
  31. * @var UsernamePasswordJsonAuthenticationListener
  32. */
  33. private $listener;
  34. private function createListener(array $options = array(), $success = true, $matchCheckPath = true)
  35. {
  36. $tokenStorage = $this->getMockBuilder(TokenStorageInterface::class)->getMock();
  37. $httpUtils = $this->getMockBuilder(HttpUtils::class)->getMock();
  38. $httpUtils
  39. ->expects($this->any())
  40. ->method('checkRequestPath')
  41. ->will($this->returnValue($matchCheckPath))
  42. ;
  43. $authenticationManager = $this->getMockBuilder(AuthenticationManagerInterface::class)->getMock();
  44. $authenticatedToken = $this->getMockBuilder(TokenInterface::class)->getMock();
  45. if ($success) {
  46. $authenticationManager->method('authenticate')->willReturn($authenticatedToken);
  47. } else {
  48. $authenticationManager->method('authenticate')->willThrowException(new AuthenticationException());
  49. }
  50. $authenticationSuccessHandler = $this->getMockBuilder(AuthenticationSuccessHandlerInterface::class)->getMock();
  51. $authenticationSuccessHandler->method('onAuthenticationSuccess')->willReturn(new Response('ok'));
  52. $authenticationFailureHandler = $this->getMockBuilder(AuthenticationFailureHandlerInterface::class)->getMock();
  53. $authenticationFailureHandler->method('onAuthenticationFailure')->willReturn(new Response('ko'));
  54. $this->listener = new UsernamePasswordJsonAuthenticationListener($tokenStorage, $authenticationManager, $httpUtils, 'providerKey', $authenticationSuccessHandler, $authenticationFailureHandler, $options);
  55. }
  56. public function testHandleSuccessIfRequestContentTypeIsJson()
  57. {
  58. $this->createListener();
  59. $request = new Request(array(), array(), array(), array(), array(), array('HTTP_CONTENT_TYPE' => 'application/json'), '{"username": "dunglas", "password": "foo"}');
  60. $event = new GetResponseEvent($this->getMockBuilder(KernelInterface::class)->getMock(), $request, KernelInterface::MASTER_REQUEST);
  61. $this->listener->handle($event);
  62. $this->assertEquals('ok', $event->getResponse()->getContent());
  63. }
  64. public function testSuccessIfRequestFormatIsJsonLD()
  65. {
  66. $this->createListener();
  67. $request = new Request(array(), array(), array(), array(), array(), array(), '{"username": "dunglas", "password": "foo"}');
  68. $request->setRequestFormat('json-ld');
  69. $event = new GetResponseEvent($this->getMockBuilder(KernelInterface::class)->getMock(), $request, KernelInterface::MASTER_REQUEST);
  70. $this->listener->handle($event);
  71. $this->assertEquals('ok', $event->getResponse()->getContent());
  72. }
  73. public function testHandleFailure()
  74. {
  75. $this->createListener(array(), false);
  76. $request = new Request(array(), array(), array(), array(), array(), array('HTTP_CONTENT_TYPE' => 'application/json'), '{"username": "dunglas", "password": "foo"}');
  77. $event = new GetResponseEvent($this->getMockBuilder(KernelInterface::class)->getMock(), $request, KernelInterface::MASTER_REQUEST);
  78. $this->listener->handle($event);
  79. $this->assertEquals('ko', $event->getResponse()->getContent());
  80. }
  81. public function testUsePath()
  82. {
  83. $this->createListener(array('username_path' => 'user.login', 'password_path' => 'user.pwd'));
  84. $request = new Request(array(), array(), array(), array(), array(), array('HTTP_CONTENT_TYPE' => 'application/json'), '{"user": {"login": "dunglas", "pwd": "foo"}}');
  85. $event = new GetResponseEvent($this->getMockBuilder(KernelInterface::class)->getMock(), $request, KernelInterface::MASTER_REQUEST);
  86. $this->listener->handle($event);
  87. $this->assertEquals('ok', $event->getResponse()->getContent());
  88. }
  89. /**
  90. * @expectedException \Symfony\Component\HttpKernel\Exception\BadRequestHttpException
  91. * @expectedExceptionMessage Invalid JSON
  92. */
  93. public function testAttemptAuthenticationNoJson()
  94. {
  95. $this->createListener();
  96. $request = new Request();
  97. $request->setRequestFormat('json');
  98. $event = new GetResponseEvent($this->getMockBuilder(KernelInterface::class)->getMock(), $request, KernelInterface::MASTER_REQUEST);
  99. $this->listener->handle($event);
  100. }
  101. /**
  102. * @expectedException \Symfony\Component\HttpKernel\Exception\BadRequestHttpException
  103. * @expectedExceptionMessage The key "username" must be provided
  104. */
  105. public function testAttemptAuthenticationNoUsername()
  106. {
  107. $this->createListener();
  108. $request = new Request(array(), array(), array(), array(), array(), array('HTTP_CONTENT_TYPE' => 'application/json'), '{"usr": "dunglas", "password": "foo"}');
  109. $event = new GetResponseEvent($this->getMockBuilder(KernelInterface::class)->getMock(), $request, KernelInterface::MASTER_REQUEST);
  110. $this->listener->handle($event);
  111. }
  112. /**
  113. * @expectedException \Symfony\Component\HttpKernel\Exception\BadRequestHttpException
  114. * @expectedExceptionMessage The key "password" must be provided
  115. */
  116. public function testAttemptAuthenticationNoPassword()
  117. {
  118. $this->createListener();
  119. $request = new Request(array(), array(), array(), array(), array(), array('HTTP_CONTENT_TYPE' => 'application/json'), '{"username": "dunglas", "pass": "foo"}');
  120. $event = new GetResponseEvent($this->getMockBuilder(KernelInterface::class)->getMock(), $request, KernelInterface::MASTER_REQUEST);
  121. $this->listener->handle($event);
  122. }
  123. /**
  124. * @expectedException \Symfony\Component\HttpKernel\Exception\BadRequestHttpException
  125. * @expectedExceptionMessage The key "username" must be a string.
  126. */
  127. public function testAttemptAuthenticationUsernameNotAString()
  128. {
  129. $this->createListener();
  130. $request = new Request(array(), array(), array(), array(), array(), array('HTTP_CONTENT_TYPE' => 'application/json'), '{"username": 1, "password": "foo"}');
  131. $event = new GetResponseEvent($this->getMockBuilder(KernelInterface::class)->getMock(), $request, KernelInterface::MASTER_REQUEST);
  132. $this->listener->handle($event);
  133. }
  134. /**
  135. * @expectedException \Symfony\Component\HttpKernel\Exception\BadRequestHttpException
  136. * @expectedExceptionMessage The key "password" must be a string.
  137. */
  138. public function testAttemptAuthenticationPasswordNotAString()
  139. {
  140. $this->createListener();
  141. $request = new Request(array(), array(), array(), array(), array(), array('HTTP_CONTENT_TYPE' => 'application/json'), '{"username": "dunglas", "password": 1}');
  142. $event = new GetResponseEvent($this->getMockBuilder(KernelInterface::class)->getMock(), $request, KernelInterface::MASTER_REQUEST);
  143. $this->listener->handle($event);
  144. }
  145. public function testAttemptAuthenticationUsernameTooLong()
  146. {
  147. $this->createListener();
  148. $username = str_repeat('x', Security::MAX_USERNAME_LENGTH + 1);
  149. $request = new Request(array(), array(), array(), array(), array(), array('HTTP_CONTENT_TYPE' => 'application/json'), sprintf('{"username": "%s", "password": 1}', $username));
  150. $event = new GetResponseEvent($this->getMockBuilder(KernelInterface::class)->getMock(), $request, KernelInterface::MASTER_REQUEST);
  151. $this->listener->handle($event);
  152. $this->assertSame('ko', $event->getResponse()->getContent());
  153. }
  154. public function testDoesNotAttemptAuthenticationIfRequestPathDoesNotMatchCheckPath()
  155. {
  156. $this->createListener(array('check_path' => '/'), true, false);
  157. $request = new Request(array(), array(), array(), array(), array(), array('HTTP_CONTENT_TYPE' => 'application/json'));
  158. $event = new GetResponseEvent($this->getMockBuilder(KernelInterface::class)->getMock(), $request, KernelInterface::MASTER_REQUEST);
  159. $event->setResponse(new Response('original'));
  160. $this->listener->handle($event);
  161. $this->assertSame('original', $event->getResponse()->getContent());
  162. }
  163. public function testDoesNotAttemptAuthenticationIfRequestContentTypeIsNotJson()
  164. {
  165. $this->createListener();
  166. $request = new Request(array(), array(), array(), array(), array(), array(), '{"username": "dunglas", "password": "foo"}');
  167. $event = new GetResponseEvent($this->getMockBuilder(KernelInterface::class)->getMock(), $request, KernelInterface::MASTER_REQUEST);
  168. $event->setResponse(new Response('original'));
  169. $this->listener->handle($event);
  170. $this->assertSame('original', $event->getResponse()->getContent());
  171. }
  172. public function testAttemptAuthenticationIfRequestPathMatchesCheckPath()
  173. {
  174. $this->createListener(array('check_path' => '/'));
  175. $request = new Request(array(), array(), array(), array(), array(), array('HTTP_CONTENT_TYPE' => 'application/json'), '{"username": "dunglas", "password": "foo"}');
  176. $event = new GetResponseEvent($this->getMockBuilder(KernelInterface::class)->getMock(), $request, KernelInterface::MASTER_REQUEST);
  177. $this->listener->handle($event);
  178. $this->assertSame('ok', $event->getResponse()->getContent());
  179. }
  180. }