BasicAuthenticateTest.php 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. <?php
  2. /**
  3. * CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
  4. * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
  5. *
  6. * Licensed under The MIT License
  7. * For full copyright and license information, please see the LICENSE.txt
  8. * Redistributions of files must retain the above copyright notice.
  9. *
  10. * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
  11. * @link https://cakephp.org CakePHP(tm) Project
  12. * @since 2.0.0
  13. * @license https://opensource.org/licenses/mit-license.php MIT License
  14. */
  15. namespace Cake\Test\TestCase\Auth;
  16. use Cake\Auth\BasicAuthenticate;
  17. use Cake\Controller\ComponentRegistry;
  18. use Cake\Http\Exception\UnauthorizedException;
  19. use Cake\Http\Response;
  20. use Cake\Http\ServerRequest;
  21. use Cake\I18n\Time;
  22. use Cake\TestSuite\TestCase;
  23. /**
  24. * Test case for BasicAuthentication
  25. */
  26. class BasicAuthenticateTest extends TestCase
  27. {
  28. /**
  29. * Fixtures
  30. *
  31. * @var array
  32. */
  33. public $fixtures = ['core.AuthUsers', 'core.Users'];
  34. /**
  35. * @var \Cake\Auth\BasicAuthenticate
  36. */
  37. protected $auth;
  38. /**
  39. * setup
  40. *
  41. * @return void
  42. */
  43. public function setUp()
  44. {
  45. parent::setUp();
  46. $this->Collection = $this->getMockBuilder(ComponentRegistry::class)->getMock();
  47. $this->auth = new BasicAuthenticate($this->Collection, [
  48. 'userModel' => 'Users',
  49. 'realm' => 'localhost',
  50. ]);
  51. $password = password_hash('password', PASSWORD_BCRYPT);
  52. $User = $this->getTableLocator()->get('Users');
  53. $User->updateAll(['password' => $password], []);
  54. $this->response = $this->getMockBuilder(Response::class)->getMock();
  55. }
  56. /**
  57. * test applying settings in the constructor
  58. *
  59. * @return void
  60. */
  61. public function testConstructor()
  62. {
  63. $object = new BasicAuthenticate($this->Collection, [
  64. 'userModel' => 'AuthUser',
  65. 'fields' => ['username' => 'user', 'password' => 'password'],
  66. ]);
  67. $this->assertEquals('AuthUser', $object->getConfig('userModel'));
  68. $this->assertEquals(['username' => 'user', 'password' => 'password'], $object->getConfig('fields'));
  69. }
  70. /**
  71. * test the authenticate method
  72. *
  73. * @return void
  74. */
  75. public function testAuthenticateNoData()
  76. {
  77. $request = new ServerRequest('posts/index');
  78. $this->response->expects($this->never())
  79. ->method('header');
  80. $this->assertFalse($this->auth->getUser($request));
  81. }
  82. /**
  83. * test the authenticate method
  84. *
  85. * @return void
  86. */
  87. public function testAuthenticateNoUsername()
  88. {
  89. $request = new ServerRequest([
  90. 'url' => 'posts/index',
  91. 'environment' => ['PHP_AUTH_PW' => 'foobar'],
  92. ]);
  93. $this->assertFalse($this->auth->authenticate($request, $this->response));
  94. }
  95. /**
  96. * test the authenticate method
  97. *
  98. * @return void
  99. */
  100. public function testAuthenticateNoPassword()
  101. {
  102. $request = new ServerRequest([
  103. 'url' => 'posts/index',
  104. 'environment' => ['PHP_AUTH_USER' => 'mariano'],
  105. ]);
  106. $this->assertFalse($this->auth->authenticate($request, $this->response));
  107. }
  108. /**
  109. * test the authenticate method
  110. *
  111. * @return void
  112. */
  113. public function testAuthenticateInjection()
  114. {
  115. $request = new ServerRequest([
  116. 'url' => 'posts/index',
  117. 'environment' => [
  118. 'PHP_AUTH_USER' => '> 1',
  119. 'PHP_AUTH_PW' => "' OR 1 = 1",
  120. ],
  121. ]);
  122. $this->assertFalse($this->auth->getUser($request));
  123. $this->assertFalse($this->auth->authenticate($request, $this->response));
  124. }
  125. /**
  126. * Test that username of 0 works.
  127. *
  128. * @return void
  129. */
  130. public function testAuthenticateUsernameZero()
  131. {
  132. $User = $this->getTableLocator()->get('Users');
  133. $User->updateAll(['username' => '0'], ['username' => 'mariano']);
  134. $request = new ServerRequest([
  135. 'url' => 'posts/index',
  136. 'data' => [
  137. 'User' => [
  138. 'user' => '0',
  139. 'password' => 'password',
  140. ],
  141. ],
  142. ]);
  143. $_SERVER['PHP_AUTH_USER'] = '0';
  144. $_SERVER['PHP_AUTH_PW'] = 'password';
  145. $expected = [
  146. 'id' => 1,
  147. 'username' => '0',
  148. 'created' => new Time('2007-03-17 01:16:23'),
  149. 'updated' => new Time('2007-03-17 01:18:31'),
  150. ];
  151. $this->assertEquals($expected, $this->auth->authenticate($request, $this->response));
  152. }
  153. /**
  154. * test that challenge headers are sent when no credentials are found.
  155. *
  156. * @return void
  157. */
  158. public function testAuthenticateChallenge()
  159. {
  160. $request = new ServerRequest('posts/index');
  161. try {
  162. $this->auth->unauthenticated($request, $this->response);
  163. } catch (UnauthorizedException $e) {
  164. }
  165. $this->assertNotEmpty($e);
  166. $expected = ['WWW-Authenticate' => 'Basic realm="localhost"'];
  167. $this->assertEquals($expected, $e->responseHeader());
  168. }
  169. /**
  170. * test authenticate success
  171. *
  172. * @return void
  173. */
  174. public function testAuthenticateSuccess()
  175. {
  176. $request = new ServerRequest([
  177. 'url' => 'posts/index',
  178. 'environment' => [
  179. 'PHP_AUTH_USER' => 'mariano',
  180. 'PHP_AUTH_PW' => 'password',
  181. ],
  182. ]);
  183. $result = $this->auth->authenticate($request, $this->response);
  184. $expected = [
  185. 'id' => 1,
  186. 'username' => 'mariano',
  187. 'created' => new Time('2007-03-17 01:16:23'),
  188. 'updated' => new Time('2007-03-17 01:18:31'),
  189. ];
  190. $this->assertEquals($expected, $result);
  191. }
  192. /**
  193. * test scope failure.
  194. *
  195. * @return void
  196. */
  197. public function testAuthenticateFailReChallenge()
  198. {
  199. $this->expectException(\Cake\Http\Exception\UnauthorizedException::class);
  200. $this->expectExceptionCode(401);
  201. $this->auth->setConfig('scope.username', 'nate');
  202. $request = new ServerRequest([
  203. 'url' => 'posts/index',
  204. 'environment' => [
  205. 'PHP_AUTH_USER' => 'mariano',
  206. 'PHP_AUTH_PW' => 'password',
  207. ],
  208. ]);
  209. $this->auth->unauthenticated($request, $this->response);
  210. }
  211. }