PublicKeyTokenProviderTest.php 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577
  1. <?php
  2. /**
  3. * @copyright Copyright (c) 2018 Roeland Jago Douma <roeland@famdouma.nl>
  4. *
  5. * @author Roeland Jago Douma <roeland@famdouma.nl>
  6. *
  7. * @license GNU AGPL version 3 or any later version
  8. *
  9. * This program is free software: you can redistribute it and/or modify
  10. * it under the terms of the GNU Affero General Public License as
  11. * published by the Free Software Foundation, either version 3 of the
  12. * License, or (at your option) any later version.
  13. *
  14. * This program is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. * GNU Affero General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU Affero General Public License
  20. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  21. *
  22. */
  23. namespace Test\Authentication\Token;
  24. use OC\Authentication\Exceptions\ExpiredTokenException;
  25. use OC\Authentication\Exceptions\InvalidTokenException;
  26. use OC\Authentication\Token\DefaultToken;
  27. use OC\Authentication\Token\PublicKeyToken;
  28. use OC\Authentication\Token\PublicKeyTokenMapper;
  29. use OC\Authentication\Token\PublicKeyTokenProvider;
  30. use OC\Authentication\Token\IToken;
  31. use OCP\AppFramework\Db\DoesNotExistException;
  32. use OCP\AppFramework\Utility\ITimeFactory;
  33. use OCP\IConfig;
  34. use OCP\ILogger;
  35. use OCP\Security\ICrypto;
  36. use Test\TestCase;
  37. class PublicKeyTokenProviderTest extends TestCase {
  38. /** @var PublicKeyTokenProvider|\PHPUnit_Framework_MockObject_MockObject */
  39. private $tokenProvider;
  40. /** @var PublicKeyTokenMapper|\PHPUnit_Framework_MockObject_MockObject */
  41. private $mapper;
  42. /** @var ICrypto */
  43. private $crypto;
  44. /** @var IConfig|\PHPUnit_Framework_MockObject_MockObject */
  45. private $config;
  46. /** @var ILogger|\PHPUnit_Framework_MockObject_MockObject */
  47. private $logger;
  48. /** @var ITimeFactory|\PHPUnit_Framework_MockObject_MockObject */
  49. private $timeFactory;
  50. /** @var int */
  51. private $time;
  52. protected function setUp() {
  53. parent::setUp();
  54. $this->mapper = $this->createMock(PublicKeyTokenMapper::class);
  55. $this->crypto = \OC::$server->getCrypto();
  56. $this->config = $this->createMock(IConfig::class);
  57. $this->config->method('getSystemValue')
  58. ->will($this->returnValueMap([
  59. ['session_lifetime', 60 * 60 * 24, 150],
  60. ['remember_login_cookie_lifetime', 60 * 60 * 24 * 15, 300],
  61. ['secret', '', '1f4h9s'],
  62. ['openssl', [], []],
  63. ]));
  64. $this->logger = $this->createMock(ILogger::class);
  65. $this->timeFactory = $this->createMock(ITimeFactory::class);
  66. $this->time = 1313131;
  67. $this->timeFactory->method('getTime')
  68. ->willReturn($this->time);
  69. $this->tokenProvider = new PublicKeyTokenProvider($this->mapper, $this->crypto, $this->config, $this->logger,
  70. $this->timeFactory);
  71. }
  72. public function testGenerateToken() {
  73. $token = 'token';
  74. $uid = 'user';
  75. $user = 'User';
  76. $password = 'passme';
  77. $name = 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12'
  78. . 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12'
  79. . 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12'
  80. . 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12';
  81. $type = IToken::PERMANENT_TOKEN;
  82. $actual = $this->tokenProvider->generateToken($token, $uid, $user, $password, $name, $type, IToken::DO_NOT_REMEMBER);
  83. $this->assertInstanceOf(PublicKeyToken::class, $actual);
  84. $this->assertSame($uid, $actual->getUID());
  85. $this->assertSame($user, $actual->getLoginName());
  86. $this->assertSame($name, $actual->getName());
  87. $this->assertSame(IToken::DO_NOT_REMEMBER, $actual->getRemember());
  88. $this->assertSame($password, $this->tokenProvider->getPassword($actual, $token));
  89. }
  90. public function testUpdateToken() {
  91. $tk = new PublicKeyToken();
  92. $tk->setLastActivity($this->time - 200);
  93. $this->mapper->expects($this->once())
  94. ->method('update')
  95. ->with($tk);
  96. $this->tokenProvider->updateTokenActivity($tk);
  97. $this->assertEquals($this->time, $tk->getLastActivity());
  98. }
  99. public function testUpdateTokenDebounce() {
  100. $tk = new PublicKeyToken();
  101. $tk->setLastActivity($this->time - 30);
  102. $this->mapper->expects($this->never())
  103. ->method('update')
  104. ->with($tk);
  105. $this->tokenProvider->updateTokenActivity($tk);
  106. }
  107. public function testGetTokenByUser() {
  108. $this->mapper->expects($this->once())
  109. ->method('getTokenByUser')
  110. ->with('uid')
  111. ->will($this->returnValue(['token']));
  112. $this->assertEquals(['token'], $this->tokenProvider->getTokenByUser('uid'));
  113. }
  114. public function testGetPassword() {
  115. $token = 'token';
  116. $uid = 'user';
  117. $user = 'User';
  118. $password = 'passme';
  119. $name = 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12'
  120. . 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12'
  121. . 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12'
  122. . 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12';
  123. $type = IToken::PERMANENT_TOKEN;
  124. $actual = $this->tokenProvider->generateToken($token, $uid, $user, $password, $name, $type, IToken::DO_NOT_REMEMBER);
  125. $this->assertSame($password, $this->tokenProvider->getPassword($actual, $token));
  126. }
  127. /**
  128. * @expectedException \OC\Authentication\Exceptions\PasswordlessTokenException
  129. */
  130. public function testGetPasswordPasswordLessToken() {
  131. $token = 'token1234';
  132. $tk = new PublicKeyToken();
  133. $tk->setPassword(null);
  134. $this->tokenProvider->getPassword($tk, $token);
  135. }
  136. /**
  137. * @expectedException \OC\Authentication\Exceptions\InvalidTokenException
  138. */
  139. public function testGetPasswordInvalidToken() {
  140. $token = 'token';
  141. $uid = 'user';
  142. $user = 'User';
  143. $password = 'passme';
  144. $name = 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12'
  145. . 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12'
  146. . 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12'
  147. . 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12';
  148. $type = IToken::PERMANENT_TOKEN;
  149. $actual = $this->tokenProvider->generateToken($token, $uid, $user, $password, $name, $type, IToken::DO_NOT_REMEMBER);
  150. $this->tokenProvider->getPassword($actual, 'wrongtoken');
  151. }
  152. public function testSetPassword() {
  153. $token = 'token';
  154. $uid = 'user';
  155. $user = 'User';
  156. $password = 'passme';
  157. $name = 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12'
  158. . 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12'
  159. . 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12'
  160. . 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12';
  161. $type = IToken::PERMANENT_TOKEN;
  162. $actual = $this->tokenProvider->generateToken($token, $uid, $user, $password, $name, $type, IToken::DO_NOT_REMEMBER);
  163. $this->mapper->method('getTokenByUser')
  164. ->with('user')
  165. ->willReturn([$actual]);
  166. $newpass = 'newpass';
  167. $this->mapper->expects($this->once())
  168. ->method('update')
  169. ->with($this->callback(function ($token) use ($newpass) {
  170. return $newpass === $this->tokenProvider->getPassword($token, 'token');
  171. }));
  172. $this->tokenProvider->setPassword($actual, $token, $newpass);
  173. $this->assertSame($newpass, $this->tokenProvider->getPassword($actual, 'token'));
  174. }
  175. /**
  176. * @expectedException \OC\Authentication\Exceptions\InvalidTokenException
  177. */
  178. public function testSetPasswordInvalidToken() {
  179. $token = $this->createMock(IToken::class);
  180. $tokenId = 'token123';
  181. $password = '123456';
  182. $this->tokenProvider->setPassword($token, $tokenId, $password);
  183. }
  184. public function testInvalidateToken() {
  185. $this->mapper->expects($this->once())
  186. ->method('invalidate')
  187. ->with(hash('sha512', 'token7'.'1f4h9s'));
  188. $this->tokenProvider->invalidateToken('token7');
  189. }
  190. public function testInvaildateTokenById() {
  191. $id = 123;
  192. $this->mapper->expects($this->once())
  193. ->method('deleteById')
  194. ->with('uid', $id);
  195. $this->tokenProvider->invalidateTokenById('uid', $id);
  196. }
  197. public function testInvalidateOldTokens() {
  198. $defaultSessionLifetime = 60 * 60 * 24;
  199. $defaultRememberMeLifetime = 60 * 60 * 24 * 15;
  200. $this->config->expects($this->exactly(2))
  201. ->method('getSystemValue')
  202. ->will($this->returnValueMap([
  203. ['session_lifetime', $defaultSessionLifetime, 150],
  204. ['remember_login_cookie_lifetime', $defaultRememberMeLifetime, 300],
  205. ]));
  206. $this->mapper->expects($this->at(0))
  207. ->method('invalidateOld')
  208. ->with($this->time - 150);
  209. $this->mapper->expects($this->at(1))
  210. ->method('invalidateOld')
  211. ->with($this->time - 300);
  212. $this->tokenProvider->invalidateOldTokens();
  213. }
  214. public function testRenewSessionTokenWithoutPassword() {
  215. $token = 'oldId';
  216. $uid = 'user';
  217. $user = 'User';
  218. $password = null;
  219. $name = 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12'
  220. . 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12'
  221. . 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12'
  222. . 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12';
  223. $type = IToken::PERMANENT_TOKEN;
  224. $oldToken = $this->tokenProvider->generateToken($token, $uid, $user, $password, $name, $type, IToken::DO_NOT_REMEMBER);
  225. $this->mapper
  226. ->expects($this->at(0))
  227. ->method('getToken')
  228. ->with(hash('sha512', 'oldId' . '1f4h9s'))
  229. ->willReturn($oldToken);
  230. $this->mapper
  231. ->expects($this->at(1))
  232. ->method('insert')
  233. ->with($this->callback(function (PublicKeyToken $token) use ($user, $uid, $name) {
  234. return $token->getUID() === $uid &&
  235. $token->getLoginName() === $user &&
  236. $token->getName() === $name &&
  237. $token->getType() === IToken::DO_NOT_REMEMBER &&
  238. $token->getLastActivity() === $this->time &&
  239. $token->getPassword() === null;
  240. }));
  241. $this->mapper
  242. ->expects($this->at(2))
  243. ->method('delete')
  244. ->with($this->callback(function($token) use ($oldToken) {
  245. return $token === $oldToken;
  246. }));
  247. $this->tokenProvider->renewSessionToken('oldId', 'newId');
  248. }
  249. public function testRenewSessionTokenWithPassword() {
  250. $token = 'oldId';
  251. $uid = 'user';
  252. $user = 'User';
  253. $password = 'password';
  254. $name = 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12'
  255. . 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12'
  256. . 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12'
  257. . 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12';
  258. $type = IToken::PERMANENT_TOKEN;
  259. $oldToken = $this->tokenProvider->generateToken($token, $uid, $user, $password, $name, $type, IToken::DO_NOT_REMEMBER);
  260. $this->mapper
  261. ->expects($this->at(0))
  262. ->method('getToken')
  263. ->with(hash('sha512', 'oldId' . '1f4h9s'))
  264. ->willReturn($oldToken);
  265. $this->mapper
  266. ->expects($this->at(1))
  267. ->method('insert')
  268. ->with($this->callback(function (PublicKeyToken $token) use ($user, $uid, $name) {
  269. return $token->getUID() === $uid &&
  270. $token->getLoginName() === $user &&
  271. $token->getName() === $name &&
  272. $token->getType() === IToken::DO_NOT_REMEMBER &&
  273. $token->getLastActivity() === $this->time &&
  274. $token->getPassword() !== null &&
  275. $this->tokenProvider->getPassword($token, 'newId') === 'password';
  276. }));
  277. $this->mapper
  278. ->expects($this->at(2))
  279. ->method('delete')
  280. ->with($this->callback(function($token) use ($oldToken) {
  281. return $token === $oldToken;
  282. }));
  283. $this->tokenProvider->renewSessionToken('oldId', 'newId');
  284. }
  285. public function testGetToken() {
  286. $token = new PublicKeyToken();
  287. $this->config->method('getSystemValue')
  288. ->with('secret')
  289. ->willReturn('mysecret');
  290. $this->mapper->method('getToken')
  291. ->with(
  292. $this->callback(function (string $token) {
  293. return hash('sha512', 'unhashedToken'.'1f4h9s') === $token;
  294. })
  295. )->willReturn($token);
  296. $this->assertSame($token, $this->tokenProvider->getToken('unhashedToken'));
  297. }
  298. public function testGetInvalidToken() {
  299. $this->expectException(InvalidTokenException::class);
  300. $this->mapper->method('getToken')
  301. ->with(
  302. $this->callback(function (string $token) {
  303. return hash('sha512', 'unhashedToken'.'1f4h9s') === $token;
  304. })
  305. )->willThrowException(new DoesNotExistException('nope'));
  306. $this->tokenProvider->getToken('unhashedToken');
  307. }
  308. public function testGetExpiredToken() {
  309. $token = 'token';
  310. $uid = 'user';
  311. $user = 'User';
  312. $password = 'passme';
  313. $name = 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12'
  314. . 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12'
  315. . 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12'
  316. . 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12';
  317. $type = IToken::PERMANENT_TOKEN;
  318. $actual = $this->tokenProvider->generateToken($token, $uid, $user, $password, $name, $type, IToken::DO_NOT_REMEMBER);
  319. $actual->setExpires(42);
  320. $this->mapper->method('getToken')
  321. ->with(
  322. $this->callback(function (string $token) {
  323. return hash('sha512', 'token'.'1f4h9s') === $token;
  324. })
  325. )->willReturn($actual);
  326. try {
  327. $this->tokenProvider->getToken('token');
  328. $this->fail();
  329. } catch (ExpiredTokenException $e) {
  330. $this->assertSame($actual, $e->getToken());
  331. }
  332. }
  333. public function testGetTokenById() {
  334. $token = $this->createMock(PublicKeyToken::class);
  335. $this->mapper->expects($this->once())
  336. ->method('getTokenById')
  337. ->with($this->equalTo(42))
  338. ->willReturn($token);
  339. $this->assertSame($token, $this->tokenProvider->getTokenById(42));
  340. }
  341. public function testGetInvalidTokenById() {
  342. $this->expectException(InvalidTokenException::class);
  343. $this->mapper->expects($this->once())
  344. ->method('getTokenById')
  345. ->with($this->equalTo(42))
  346. ->willThrowException(new DoesNotExistException('nope'));
  347. $this->tokenProvider->getTokenById(42);
  348. }
  349. public function testGetExpiredTokenById() {
  350. $token = new PublicKeyToken();
  351. $token->setExpires(42);
  352. $this->mapper->expects($this->once())
  353. ->method('getTokenById')
  354. ->with($this->equalTo(42))
  355. ->willReturn($token);
  356. try {
  357. $this->tokenProvider->getTokenById(42);
  358. $this->fail();
  359. } catch (ExpiredTokenException $e) {
  360. $this->assertSame($token, $e->getToken());
  361. }
  362. }
  363. public function testRotate() {
  364. $token = 'oldtoken';
  365. $uid = 'user';
  366. $user = 'User';
  367. $password = 'password';
  368. $name = 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12'
  369. . 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12'
  370. . 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12'
  371. . 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12';
  372. $type = IToken::PERMANENT_TOKEN;
  373. $actual = $this->tokenProvider->generateToken($token, $uid, $user, $password, $name, $type, IToken::DO_NOT_REMEMBER);
  374. $new = $this->tokenProvider->rotate($actual, 'oldtoken', 'newtoken');
  375. $this->assertSame('password', $this->tokenProvider->getPassword($new, 'newtoken'));
  376. }
  377. public function testRotateNoPassword() {
  378. $token = 'oldtoken';
  379. $uid = 'user';
  380. $user = 'User';
  381. $password = null;
  382. $name = 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12'
  383. . 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12'
  384. . 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12'
  385. . 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12';
  386. $type = IToken::PERMANENT_TOKEN;
  387. $actual = $this->tokenProvider->generateToken($token, $uid, $user, $password, $name, $type, IToken::DO_NOT_REMEMBER);
  388. $oldPrivate = $actual->getPrivateKey();
  389. $new = $this->tokenProvider->rotate($actual, 'oldtoken', 'newtoken');
  390. $newPrivate = $new->getPrivateKey();
  391. $this->assertNotSame($newPrivate, $oldPrivate);
  392. $this->assertNull($new->getPassword());
  393. }
  394. public function testConvertToken() {
  395. $defaultToken = new DefaultToken();
  396. $defaultToken->setId(42);
  397. $defaultToken->setPassword('oldPass');
  398. $defaultToken->setExpires(1337);
  399. $defaultToken->setToken('oldToken');
  400. $defaultToken->setUid('uid');
  401. $defaultToken->setLoginName('loginName');
  402. $defaultToken->setLastActivity(999);
  403. $defaultToken->setName('name');
  404. $defaultToken->setRemember(IToken::REMEMBER);
  405. $defaultToken->setType(IToken::PERMANENT_TOKEN);
  406. $this->mapper->expects($this->once())
  407. ->method('update')
  408. ->willReturnArgument(0);
  409. $newToken = $this->tokenProvider->convertToken($defaultToken, 'newToken', 'newPassword');
  410. $this->assertSame(42, $newToken->getId());
  411. $this->assertSame('newPassword', $this->tokenProvider->getPassword($newToken, 'newToken'));
  412. $this->assertSame(1337, $newToken->getExpires());
  413. $this->assertSame('uid', $newToken->getUID());
  414. $this->assertSame('loginName', $newToken->getLoginName());
  415. $this->assertSame(1313131, $newToken->getLastActivity());
  416. $this->assertSame(1313131, $newToken->getLastCheck());
  417. $this->assertSame('name', $newToken->getName());
  418. $this->assertSame(IToken::REMEMBER, $newToken->getRemember());
  419. $this->assertSame(IToken::PERMANENT_TOKEN, $newToken->getType());
  420. }
  421. public function testMarkPasswordInvalidInvalidToken() {
  422. $token = $this->createMock(DefaultToken::class);
  423. $this->expectException(InvalidTokenException::class);
  424. $this->tokenProvider->markPasswordInvalid($token, 'tokenId');
  425. }
  426. public function testMarkPasswordInvalid() {
  427. $token = $this->createMock(PublicKeyToken::class);
  428. $token->expects($this->once())
  429. ->method('setPasswordInvalid')
  430. ->with(true);
  431. $this->mapper->expects($this->once())
  432. ->method('update')
  433. ->with($token);
  434. $this->tokenProvider->markPasswordInvalid($token, 'tokenId');
  435. }
  436. public function testUpdatePasswords() {
  437. $uid = 'myUID';
  438. $token1 = $this->tokenProvider->generateToken(
  439. 'foo',
  440. $uid,
  441. $uid,
  442. 'bar',
  443. 'random1',
  444. IToken::PERMANENT_TOKEN,
  445. IToken::REMEMBER);
  446. $token2 = $this->tokenProvider->generateToken(
  447. 'foobar',
  448. $uid,
  449. $uid,
  450. 'bar',
  451. 'random2',
  452. IToken::PERMANENT_TOKEN,
  453. IToken::REMEMBER);
  454. $this->mapper->expects($this->once())
  455. ->method('hasExpiredTokens')
  456. ->with($uid)
  457. ->willReturn(true);
  458. $this->mapper->expects($this->once())
  459. ->method('getTokenByUser')
  460. ->with($uid)
  461. ->willReturn([$token1, $token2]);
  462. $this->mapper->expects($this->exactly(2))
  463. ->method('update')
  464. ->with($this->callback(function (PublicKeyToken $t) use ($token1, $token2) {
  465. return $t === $token1 || $t === $token2;
  466. }));
  467. $this->tokenProvider->updatePasswords($uid, 'bar2');
  468. }
  469. public function testUpdatePasswordsNotRequired() {
  470. $uid = 'myUID';
  471. $this->mapper->expects($this->once())
  472. ->method('hasExpiredTokens')
  473. ->with($uid)
  474. ->willReturn(false);
  475. $this->mapper->expects($this->never())
  476. ->method('getTokenByUser');
  477. $this->mapper->expects($this->never())
  478. ->method('update');
  479. $this->tokenProvider->updatePasswords($uid, 'bar2');
  480. }
  481. }