UserTest.php 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. <?php
  2. // Copyright 2019 Hackware SpA <human@hackware.cl>
  3. // "Hackware Web Services Core" is released under the MIT License terms.
  4. namespace Hawese\Tests;
  5. use Hawese\Core\User;
  6. use Hawese\Core\Token;
  7. use Laravel\Lumen\Testing\DatabaseTransactions;
  8. class UserTest extends TestCase
  9. {
  10. use DatabaseTransactions;
  11. public function setUp(): void
  12. {
  13. parent::setUp();
  14. $this->user = new User([
  15. 'uid' => 'user',
  16. 'email' => 'user@domain.name',
  17. 'password' => password_hash('password', PASSWORD_DEFAULT),
  18. 'display_name' => 'User',
  19. 'info' => null
  20. ]);
  21. $this->user->insert();
  22. }
  23. public function testChangePassword()
  24. {
  25. $this->user->changePassword('new_password');
  26. $this->assertTrue(
  27. password_verify('new_password', $this->user->password)
  28. );
  29. }
  30. public function testLogin()
  31. {
  32. $this->assertNull(app('session')->get('user_uid'));
  33. $this->user->login();
  34. $this->assertSame($this->user->uid, app('session')->get('user_uid'));
  35. }
  36. public function testLoginByPassword()
  37. {
  38. $_SERVER['REMOTE_ADDR'] = '127.0.0.1';
  39. $this->assertEqualsCanonicalizing(
  40. $this->user,
  41. User::loginByPassword($this->user->uid, 'password')
  42. );
  43. $this->assertSame(app('session')->get('user_uid'), $this->user->uid);
  44. }
  45. public function testFailedLoginByPassword()
  46. {
  47. $_SERVER['REMOTE_ADDR'] = '127.0.0.240';
  48. $this->expectExceptionMessage('Too many failed requests');
  49. for ($i = 0; $i < 5; $i++) {
  50. try {
  51. User::loginByPassword($this->user->uid, 'notpassword');
  52. } catch (\Hawese\Core\Exceptions\WrongCredentialsException $e) {
  53. // nothing, continue
  54. }
  55. }
  56. }
  57. public function testLoginByPasswordRemember()
  58. {
  59. $_SERVER['REMOTE_ADDR'] = '127.0.0.1';
  60. $this->assertEqualsCanonicalizing(
  61. $this->user,
  62. User::loginByPassword($this->user->uid, 'password', true),
  63. );
  64. $this->assertSame($this->user->uid, app('session')->get('user_uid'));
  65. // I should test cookies!! ... and probably don't set cookies here
  66. $this->assertSame(1, Token::select()->count());
  67. }
  68. public function testLoginByTokenHumanDontRemember()
  69. {
  70. $_SERVER['REMOTE_ADDR'] = '127.0.0.1';
  71. $token = Token::generate(Token::HUMAN, $this->user->uid);
  72. $this->assertEqualsCanonicalizing(
  73. $this->user,
  74. User::loginByToken($token->key, $token->secret, false)
  75. );
  76. $this->assertSame($this->user->uid, app('session')->get('user_uid'));
  77. // Verify previous token has been deleted after login
  78. $this->assertSame(0, Token::select()->count());
  79. }
  80. public function testLoginByTokenRemember()
  81. {
  82. $_SERVER['REMOTE_ADDR'] = '127.0.0.1';
  83. $token = Token::generate(Token::HUMAN, $this->user->uid);
  84. $this->assertEqualsCanonicalizing(
  85. $this->user,
  86. User::loginByToken($token->key, $token->secret)
  87. );
  88. $this->assertSame($this->user->uid, app('session')->get('user_uid'));
  89. // Verify previous token has been deleted after login
  90. $this->assertSame(1, Token::select()->count());
  91. $this->assertNotSame($token->key, Token::select()->first()->key);
  92. }
  93. public function testLoginByTokenSystem()
  94. {
  95. $_SERVER['REMOTE_ADDR'] = '127.0.0.1';
  96. $token = Token::generate(Token::SYSTEM, $this->user->uid);
  97. $this->assertEqualsCanonicalizing(
  98. $this->user,
  99. // 3rd param shouldn't be considered for system tokens
  100. User::loginByToken($token->key, $token->secret, true)
  101. );
  102. // Verify previous token has NOT been deleted after login
  103. $this->assertSame($token->key, Token::select()->first()->key);
  104. }
  105. public function testFailedLoginByToken()
  106. {
  107. $_SERVER['REMOTE_ADDR'] = '127.0.0.241';
  108. $token = Token::generate(Token::HUMAN, $this->user->uid);
  109. $this->expectExceptionMessage('Too many failed requests');
  110. for ($i = 0; $i < 5; $i++) {
  111. try {
  112. User::loginByToken($token->key, 'notsecret');
  113. } catch (\Hawese\Core\Exceptions\WrongCredentialsException $e) {
  114. // nothing, continue
  115. }
  116. }
  117. }
  118. public function testGenerateHumanToken()
  119. {
  120. $token = $this->user->generateHumanToken();
  121. $this->assertInstanceOf(Token::class, $token);
  122. $this->assertSame(Token::HUMAN, $token->type);
  123. }
  124. public function testGenerateSystemToken()
  125. {
  126. $token = $this->user->generateSystemToken();
  127. $this->assertInstanceOf(Token::class, $token);
  128. $this->assertSame(Token::SYSTEM, $token->type);
  129. }
  130. public function testLogout()
  131. {
  132. app('session')->set('user_uid', $this->user->uid);
  133. $token = Token::generate(Token::HUMAN, $this->user->uid);
  134. $_COOKIE['auth_token'] = $token->key . ':' . $token->secret;
  135. $this->assertTrue($this->user->logout());
  136. $this->assertSame(0, Token::select()->count());
  137. $this->assertNull(app('session')->get('user_uid'));
  138. }
  139. public function testLogoutSystemToken()
  140. {
  141. $token = Token::generate(Token::SYSTEM, $this->user->uid);
  142. $_COOKIE['auth_token'] = $token->key . ':' . $token->secret;
  143. $this->assertFalse($this->user->logout());
  144. }
  145. public function testEmailToken()
  146. {
  147. $origin = preg_split('/, ?/', env('CORS_ALLOW_ORIGINS'))[0];
  148. $this->assertInstanceOf(
  149. \Hawese\Core\Mailer::class,
  150. User::emailToken($this->user->uid, $origin)
  151. );
  152. }
  153. public function testEmailTokenException()
  154. {
  155. $origin = preg_split('/, ?/', env('CORS_ALLOW_ORIGINS'))[0];
  156. $this->user->email = null;
  157. $this->user->update(['email']);
  158. $this->expectException(\PHPMailer\PHPMailer\Exception::class);
  159. User::emailToken($this->user->uid, $origin);
  160. }
  161. public function testEmailTokenWrongOrigin()
  162. {
  163. $this->expectExceptionMessage('Unacceptable origin');
  164. User::emailToken($this->user->uid, 'not_origin');
  165. }
  166. public function testAmI()
  167. {
  168. $this->assertFalse($this->user->amI());
  169. app('session')->set('user_uid', $this->user->uid);
  170. $this->assertTrue($this->user->amI());
  171. }
  172. public function testIsOwner()
  173. {
  174. $this->assertTrue($this->user->isOwner($this->user));
  175. $otherUser = new User();
  176. $this->assertFalse($this->user->isOwner($otherUser));
  177. }
  178. public function testIsSuperUser()
  179. {
  180. $this->assertFalse($this->user->isSuperUser());
  181. $user = new User(['uid' => 'hawese']);
  182. $this->assertTrue($user->isSuperUser());
  183. }
  184. }