PageRenderTime 48ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 1ms

/tests/TestCase/Controller/Traits/Integration/LoginTraitIntegrationTest.php

https://github.com/CakeDC/users
PHP | 297 lines | 180 code | 25 blank | 92 comment | 0 complexity | 56ac3086ab250183b9330649ad27e6c5 MD5 | raw file
  1. <?php
  2. declare(strict_types=1);
  3. /**
  4. * Copyright 2010 - 2019, Cake Development Corporation (https://www.cakedc.com)
  5. *
  6. * Licensed under The MIT License
  7. * Redistributions of files must retain the above copyright notice.
  8. *
  9. * @copyright Copyright 2010 - 2018, Cake Development Corporation (https://www.cakedc.com)
  10. * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
  11. */
  12. namespace CakeDC\Users\Test\TestCase\Controller\Traits\Integration;
  13. use Cake\Core\Configure;
  14. use Cake\Event\EventManager;
  15. use Cake\ORM\TableRegistry;
  16. use Cake\TestSuite\IntegrationTestTrait;
  17. use Cake\TestSuite\TestCase;
  18. class LoginTraitIntegrationTest extends TestCase
  19. {
  20. use IntegrationTestTrait;
  21. /**
  22. * Fixtures
  23. *
  24. * @var array
  25. */
  26. public $fixtures = [
  27. 'plugin.CakeDC/Users.Users',
  28. ];
  29. /**
  30. * Sets up the session as a logged in user for an user with id $id
  31. *
  32. * @param $id
  33. * @return void
  34. */
  35. public function loginAsUserId($id)
  36. {
  37. $user = TableRegistry::getTableLocator()
  38. ->get('CakeDC/Users.Users')
  39. ->get($id);
  40. $this->session(['Auth' => $user]);
  41. }
  42. /**
  43. * Test login action with get request
  44. *
  45. * @return void
  46. */
  47. public function testRedirectToLogin()
  48. {
  49. $this->enableRetainFlashMessages();
  50. $this->get('/pages/home');
  51. $this->assertRedirectContains('/login?redirect=http%3A%2F%2Flocalhost%2Fpages%2Fhome');
  52. $this->assertFlashMessage('You are not authorized to access that location.');
  53. }
  54. /**
  55. * Test login action with get request
  56. *
  57. * @return void
  58. */
  59. public function testLoginGetRequestNoSocialLogin()
  60. {
  61. EventManager::instance()->on('TestApp.afterPluginBootstrap', function () {
  62. Configure::write(['Users.Social.login' => false]);
  63. });
  64. $this->get('/login');
  65. $this->assertResponseOk();
  66. $this->assertResponseNotContains('Username or password is incorrect');
  67. $this->assertResponseContains('<form method="post" accept-charset="utf-8" action="/login">');
  68. $this->assertResponseContains('<legend>Please enter your username and password</legend>');
  69. $this->assertResponseContains('<input type="text" name="username" required="required" id="username" aria-required="true"/>');
  70. $this->assertResponseContains('<input type="password" name="password" required="required" id="password" aria-required="true"/>');
  71. $this->assertResponseContains('<input type="checkbox" name="remember_me" value="1" checked="checked" id="remember-me">');
  72. $this->assertResponseContains('<button type="submit">Login</button>');
  73. $this->assertResponseContains('<a href="/register">Register</a>');
  74. $this->assertResponseContains('<a href="/users/request-reset-password">Reset Password</a>');
  75. $this->assertResponseNotContains('auth/facebook');
  76. $this->assertResponseNotContains('auth/twitter');
  77. $this->assertResponseNotContains('auth/google');
  78. $this->assertResponseNotContains('auth/cognito');
  79. $this->assertResponseNotContains('auth/amazon');
  80. }
  81. /**
  82. * Test login action with get request
  83. *
  84. * @return void
  85. */
  86. public function testLoginGetRequest()
  87. {
  88. $this->get('/login');
  89. $this->assertResponseOk();
  90. $this->assertResponseNotContains('Username or password is incorrect');
  91. $this->assertResponseContains('<form method="post" accept-charset="utf-8" action="/login">');
  92. $this->assertResponseContains('<legend>Please enter your username and password</legend>');
  93. $this->assertResponseContains('<input type="text" name="username" required="required" id="username" aria-required="true"/>');
  94. $this->assertResponseContains('<input type="password" name="password" required="required" id="password" aria-required="true"/>');
  95. $this->assertResponseContains('<input type="checkbox" name="remember_me" value="1" checked="checked" id="remember-me">');
  96. $this->assertResponseContains('<button type="submit">Login</button>');
  97. $this->assertResponseContains('<a href="/register">Register</a>');
  98. $this->assertResponseContains('<a href="/users/request-reset-password">Reset Password</a>');
  99. $this->assertResponseContains('<a href="/auth/facebook" class="btn btn-social btn-facebook"><i class="fa fa-facebook"></i>Sign in with Facebook</a>');
  100. $this->assertResponseContains('<a href="/auth/twitter" class="btn btn-social btn-twitter"><i class="fa fa-twitter"></i>Sign in with Twitter</a>');
  101. $this->assertResponseContains('<a href="/auth/google" class="btn btn-social btn-google"><i class="fa fa-google"></i>Sign in with Google</a>');
  102. $this->assertResponseNotContains('/auth/cognito');
  103. $this->assertResponseNotContains('/auth/amazon');
  104. }
  105. /**
  106. * Test login action with post request
  107. *
  108. * @return void
  109. */
  110. public function testLoginPostRequestInvalidPassword()
  111. {
  112. $this->post('/login', [
  113. 'username' => 'user-2',
  114. 'password' => '123456789',
  115. ]);
  116. $this->assertResponseOk();
  117. $this->assertResponseContains('Username or password is incorrect');
  118. $this->assertResponseContains('<form method="post" accept-charset="utf-8" action="/login">');
  119. $this->assertResponseContains('<legend>Please enter your username and password</legend>');
  120. $this->assertResponseContains('<input type="text" name="username" required="required" id="username" aria-required="true" value="user-2"/>');
  121. $this->assertResponseContains('<input type="password" name="password" required="required" id="password" aria-required="true" value="123456789"/>');
  122. $this->assertResponseContains('<input type="checkbox" name="remember_me" value="1" checked="checked" id="remember-me">');
  123. $this->assertResponseContains('<button type="submit">Login</button>');
  124. }
  125. /**
  126. * Test login action with post request
  127. *
  128. * @return void
  129. */
  130. public function testLoginPostRequestRightPasswordWithBaseRedirectUrl()
  131. {
  132. $this->enableRetainFlashMessages();
  133. $this->post('/login?redirect=http://localhost/articles', [
  134. 'username' => 'user-2',
  135. 'password' => '12345',
  136. ]);
  137. $this->assertRedirect('http://localhost/articles');
  138. }
  139. /**
  140. * Test login action with post request
  141. *
  142. * @return void
  143. */
  144. public function testLoginPostRequestRightPasswordNoBaseRedirectUrl()
  145. {
  146. $this->enableRetainFlashMessages();
  147. $this->post('/login', [
  148. 'username' => 'user-2',
  149. 'password' => '12345',
  150. ]);
  151. $this->assertRedirect('/pages/home');
  152. }
  153. /**
  154. * Test login action with post request
  155. *
  156. * @return void
  157. */
  158. public function testLoginPostRequestRightPasswordWithBaseRedirectUrlButCantAccess()
  159. {
  160. $this->enableRetainFlashMessages();
  161. $this->post('/login?redirect=http://localhost/articles', [
  162. 'username' => 'user-4',
  163. 'password' => '12345',
  164. ]);
  165. $this->assertRedirect('/pages/home');
  166. }
  167. /**
  168. * Test login action with post request
  169. *
  170. * @return void
  171. */
  172. public function testLoginPostRequestRightPasswordIsEnabledOTP()
  173. {
  174. EventManager::instance()->on('TestApp.afterPluginBootstrap', function () {
  175. Configure::write(['OneTimePasswordAuthenticator.login' => true]);
  176. });
  177. $this->enableRetainFlashMessages();
  178. $this->post('/login', [
  179. 'username' => 'user-2',
  180. 'password' => '12345',
  181. ]);
  182. $this->assertRedirectContains('/verify');
  183. }
  184. /**
  185. * Test login action with post request
  186. *
  187. * @return void
  188. */
  189. public function testLoginPostRequestRightPasswordIsEnabledU2f()
  190. {
  191. EventManager::instance()->on('TestApp.afterPluginBootstrap', function () {
  192. Configure::write(['U2f.enabled' => true]);
  193. });
  194. $this->enableRetainFlashMessages();
  195. $this->post('/login', [
  196. 'username' => 'user-2',
  197. 'password' => '12345',
  198. ]);
  199. $this->assertRedirectContains('/users/u2f');
  200. }
  201. /**
  202. * Test logout action
  203. *
  204. * @return void
  205. */
  206. public function testLogout()
  207. {
  208. $this->loginAsUserId('00000000-0000-0000-0000-000000000002');
  209. $this->get('/logout');
  210. $this->assertRedirect('/login');
  211. }
  212. /**
  213. * Test logout action
  214. *
  215. * @return void
  216. */
  217. public function testLogoutNoUser()
  218. {
  219. $this->get('/logout');
  220. $this->assertRedirect('/login');
  221. }
  222. /**
  223. * Test redirect should not happen if the host is not defined as a known host
  224. *
  225. * @return void
  226. */
  227. public function testRedirectAfterLoginToHostUnknown()
  228. {
  229. $this->post('/login?redirect=http://unknown.com/', [
  230. 'username' => 'user-4',
  231. 'password' => '12345',
  232. ]);
  233. $this->assertRedirect('/pages/home');
  234. }
  235. /**
  236. * Test redirect should happen for defaul localhost
  237. *
  238. * @return void
  239. */
  240. public function testRedirectAfterLoginToAllowedHost()
  241. {
  242. Configure::write('Users.AllowedRedirectHosts', ['example.com']);
  243. $this->post('/login?redirect=http://example.com/login', [
  244. 'username' => 'user-4',
  245. 'password' => '12345',
  246. ]);
  247. // /login is authorized for this user, and example.com is in the allowed hosts
  248. $this->assertRedirect('http://example.com/login');
  249. }
  250. public function testRedirectAfterLoginToFullBase(): void
  251. {
  252. $this->post('/login?redirect=http://example.com/login', [
  253. 'username' => 'user-4',
  254. 'password' => '12345',
  255. ]);
  256. // /login is authorized for this user, and example.com is in the allowed hosts
  257. $this->assertRedirect('http://example.com/login');
  258. }
  259. /**
  260. * Test redirect fails if url is not allowed
  261. *
  262. * @return void
  263. */
  264. public function testRedirectFailsIfUrlNotAllowed()
  265. {
  266. $this->post('/login?redirect=http://localhost/not-allowed', [
  267. 'username' => 'user-4',
  268. 'password' => '12345',
  269. ]);
  270. $this->assertRedirect('/pages/home');
  271. }
  272. }