ManagerTest.php 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718
  1. <?php
  2. /**
  3. * @author Christoph Wurst <christoph@owncloud.com>
  4. *
  5. * @copyright Copyright (c) 2016, ownCloud, Inc.
  6. * @license AGPL-3.0
  7. *
  8. * This code is free software: you can redistribute it and/or modify
  9. * it under the terms of the GNU Affero General Public License, version 3,
  10. * as published by the Free Software Foundation.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU Affero General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Affero General Public License, version 3,
  18. * along with this program. If not, see <http://www.gnu.org/licenses/>
  19. *
  20. */
  21. namespace Test\Authentication\TwoFactorAuth;
  22. use OC;
  23. use OC\Authentication\Token\IProvider as TokenProvider;
  24. use OC\Authentication\TwoFactorAuth\Manager;
  25. use OC\Authentication\TwoFactorAuth\MandatoryTwoFactor;
  26. use OC\Authentication\TwoFactorAuth\ProviderLoader;
  27. use OCP\Activity\IEvent;
  28. use OCP\Activity\IManager;
  29. use OCP\AppFramework\Utility\ITimeFactory;
  30. use OCP\Authentication\TwoFactorAuth\IActivatableAtLogin;
  31. use OCP\Authentication\TwoFactorAuth\IProvider;
  32. use OCP\Authentication\TwoFactorAuth\IRegistry;
  33. use OCP\EventDispatcher\IEventDispatcher;
  34. use OCP\IConfig;
  35. use OCP\ISession;
  36. use OCP\IUser;
  37. use PHPUnit\Framework\MockObject\MockObject;
  38. use Psr\Log\LoggerInterface;
  39. use Test\TestCase;
  40. use function reset;
  41. class ManagerTest extends TestCase {
  42. /** @var IUser|MockObject */
  43. private $user;
  44. /** @var ProviderLoader|MockObject */
  45. private $providerLoader;
  46. /** @var IRegistry|MockObject */
  47. private $providerRegistry;
  48. /** @var MandatoryTwoFactor|MockObject */
  49. private $mandatoryTwoFactor;
  50. /** @var ISession|MockObject */
  51. private $session;
  52. /** @var Manager */
  53. private $manager;
  54. /** @var IConfig|MockObject */
  55. private $config;
  56. /** @var IManager|MockObject */
  57. private $activityManager;
  58. /** @var LoggerInterface|MockObject */
  59. private $logger;
  60. /** @var IProvider|MockObject */
  61. private $fakeProvider;
  62. /** @var IProvider|MockObject */
  63. private $backupProvider;
  64. /** @var TokenProvider|MockObject */
  65. private $tokenProvider;
  66. /** @var ITimeFactory|MockObject */
  67. private $timeFactory;
  68. /** @var IEventDispatcher|MockObject */
  69. private $dispatcher;
  70. protected function setUp(): void {
  71. parent::setUp();
  72. $this->user = $this->createMock(IUser::class);
  73. $this->providerLoader = $this->createMock(ProviderLoader::class);
  74. $this->providerRegistry = $this->createMock(IRegistry::class);
  75. $this->mandatoryTwoFactor = $this->createMock(MandatoryTwoFactor::class);
  76. $this->session = $this->createMock(ISession::class);
  77. $this->config = $this->createMock(IConfig::class);
  78. $this->activityManager = $this->createMock(IManager::class);
  79. $this->logger = $this->createMock(LoggerInterface::class);
  80. $this->tokenProvider = $this->createMock(TokenProvider::class);
  81. $this->timeFactory = $this->createMock(ITimeFactory::class);
  82. $this->dispatcher = $this->createMock(IEventDispatcher::class);
  83. $this->manager = new Manager(
  84. $this->providerLoader,
  85. $this->providerRegistry,
  86. $this->mandatoryTwoFactor,
  87. $this->session,
  88. $this->config,
  89. $this->activityManager,
  90. $this->logger,
  91. $this->tokenProvider,
  92. $this->timeFactory,
  93. $this->dispatcher,
  94. );
  95. $this->fakeProvider = $this->createMock(IProvider::class);
  96. $this->fakeProvider->method('getId')->willReturn('email');
  97. $this->backupProvider = $this->getMockBuilder('\OCP\Authentication\TwoFactorAuth\IProvider')->getMock();
  98. $this->backupProvider->method('getId')->willReturn('backup_codes');
  99. $this->backupProvider->method('isTwoFactorAuthEnabledForUser')->willReturn(true);
  100. }
  101. private function prepareNoProviders() {
  102. $this->providerLoader->method('getProviders')
  103. ->with($this->user)
  104. ->willReturn([]);
  105. }
  106. private function prepareProviders() {
  107. $this->providerRegistry->expects($this->once())
  108. ->method('getProviderStates')
  109. ->with($this->user)
  110. ->willReturn([
  111. $this->fakeProvider->getId() => true,
  112. ]);
  113. $this->providerLoader->expects($this->once())
  114. ->method('getProviders')
  115. ->with($this->user)
  116. ->willReturn([$this->fakeProvider]);
  117. }
  118. private function prepareProvidersWitBackupProvider() {
  119. $this->providerLoader->method('getProviders')
  120. ->with($this->user)
  121. ->willReturn([
  122. $this->fakeProvider,
  123. $this->backupProvider,
  124. ]);
  125. }
  126. public function testIsTwoFactorAuthenticatedEnforced() {
  127. $this->mandatoryTwoFactor->expects($this->once())
  128. ->method('isEnforcedFor')
  129. ->with($this->user)
  130. ->willReturn(true);
  131. $enabled = $this->manager->isTwoFactorAuthenticated($this->user);
  132. $this->assertTrue($enabled);
  133. }
  134. public function testIsTwoFactorAuthenticatedNoProviders() {
  135. $this->mandatoryTwoFactor->expects($this->once())
  136. ->method('isEnforcedFor')
  137. ->with($this->user)
  138. ->willReturn(false);
  139. $this->providerRegistry->expects($this->once())
  140. ->method('getProviderStates')
  141. ->willReturn([]); // No providers registered
  142. $this->providerLoader->expects($this->once())
  143. ->method('getProviders')
  144. ->willReturn([]); // No providers loadable
  145. $this->assertFalse($this->manager->isTwoFactorAuthenticated($this->user));
  146. }
  147. public function testIsTwoFactorAuthenticatedOnlyBackupCodes() {
  148. $this->mandatoryTwoFactor->expects($this->once())
  149. ->method('isEnforcedFor')
  150. ->with($this->user)
  151. ->willReturn(false);
  152. $this->providerRegistry->expects($this->once())
  153. ->method('getProviderStates')
  154. ->willReturn([
  155. 'backup_codes' => true,
  156. ]);
  157. $backupCodesProvider = $this->createMock(IProvider::class);
  158. $backupCodesProvider
  159. ->method('getId')
  160. ->willReturn('backup_codes');
  161. $this->providerLoader->expects($this->once())
  162. ->method('getProviders')
  163. ->willReturn([
  164. $backupCodesProvider,
  165. ]);
  166. $this->assertFalse($this->manager->isTwoFactorAuthenticated($this->user));
  167. }
  168. public function testIsTwoFactorAuthenticatedFailingProviders() {
  169. $this->mandatoryTwoFactor->expects($this->once())
  170. ->method('isEnforcedFor')
  171. ->with($this->user)
  172. ->willReturn(false);
  173. $this->providerRegistry->expects($this->once())
  174. ->method('getProviderStates')
  175. ->willReturn([
  176. 'twofactor_totp' => true,
  177. 'twofactor_u2f' => false,
  178. ]); // Two providers registered, but …
  179. $this->providerLoader->expects($this->once())
  180. ->method('getProviders')
  181. ->willReturn([]); // … none of them is able to load, however …
  182. // … 2FA is still enforced
  183. $this->assertTrue($this->manager->isTwoFactorAuthenticated($this->user));
  184. }
  185. public function providerStatesFixData(): array {
  186. return [
  187. [false, false],
  188. [true, true],
  189. ];
  190. }
  191. /**
  192. * If the 2FA registry has not been populated when a user logs in,
  193. * the 2FA manager has to first fix the state before it checks for
  194. * enabled providers.
  195. *
  196. * If any of these providers is active, 2FA is enabled
  197. *
  198. * @dataProvider providerStatesFixData
  199. */
  200. public function testIsTwoFactorAuthenticatedFixesProviderStates(bool $providerEnabled, bool $expected) {
  201. $this->providerRegistry->expects($this->once())
  202. ->method('getProviderStates')
  203. ->willReturn([]); // Nothing registered yet
  204. $this->providerLoader->expects($this->once())
  205. ->method('getProviders')
  206. ->willReturn([
  207. $this->fakeProvider
  208. ]);
  209. $this->fakeProvider->expects($this->once())
  210. ->method('isTwoFactorAuthEnabledForUser')
  211. ->with($this->user)
  212. ->willReturn($providerEnabled);
  213. if ($providerEnabled) {
  214. $this->providerRegistry->expects($this->once())
  215. ->method('enableProviderFor')
  216. ->with(
  217. $this->fakeProvider,
  218. $this->user
  219. );
  220. } else {
  221. $this->providerRegistry->expects($this->once())
  222. ->method('disableProviderFor')
  223. ->with(
  224. $this->fakeProvider,
  225. $this->user
  226. );
  227. }
  228. $this->assertEquals($expected, $this->manager->isTwoFactorAuthenticated($this->user));
  229. }
  230. public function testGetProvider() {
  231. $this->providerRegistry->expects($this->once())
  232. ->method('getProviderStates')
  233. ->with($this->user)
  234. ->willReturn([
  235. $this->fakeProvider->getId() => true,
  236. ]);
  237. $this->providerLoader->expects($this->once())
  238. ->method('getProviders')
  239. ->with($this->user)
  240. ->willReturn([$this->fakeProvider]);
  241. $provider = $this->manager->getProvider($this->user, $this->fakeProvider->getId());
  242. $this->assertSame($this->fakeProvider, $provider);
  243. }
  244. public function testGetInvalidProvider() {
  245. $this->providerRegistry->expects($this->once())
  246. ->method('getProviderStates')
  247. ->with($this->user)
  248. ->willReturn([]);
  249. $this->providerLoader->expects($this->once())
  250. ->method('getProviders')
  251. ->with($this->user)
  252. ->willReturn([]);
  253. $provider = $this->manager->getProvider($this->user, 'nonexistent');
  254. $this->assertNull($provider);
  255. }
  256. public function testGetLoginSetupProviders() {
  257. $provider1 = $this->createMock(IProvider::class);
  258. $provider2 = $this->createMock(IActivatableAtLogin::class);
  259. $this->providerLoader->expects($this->once())
  260. ->method('getProviders')
  261. ->with($this->user)
  262. ->willReturn([
  263. $provider1,
  264. $provider2,
  265. ]);
  266. $providers = $this->manager->getLoginSetupProviders($this->user);
  267. $this->assertCount(1, $providers);
  268. $this->assertSame($provider2, reset($providers));
  269. }
  270. public function testGetProviders() {
  271. $this->providerRegistry->expects($this->once())
  272. ->method('getProviderStates')
  273. ->with($this->user)
  274. ->willReturn([
  275. $this->fakeProvider->getId() => true,
  276. ]);
  277. $this->providerLoader->expects($this->once())
  278. ->method('getProviders')
  279. ->with($this->user)
  280. ->willReturn([$this->fakeProvider]);
  281. $expectedProviders = [
  282. 'email' => $this->fakeProvider,
  283. ];
  284. $providerSet = $this->manager->getProviderSet($this->user);
  285. $providers = $providerSet->getProviders();
  286. $this->assertEquals($expectedProviders, $providers);
  287. $this->assertFalse($providerSet->isProviderMissing());
  288. }
  289. public function testGetProvidersOneMissing() {
  290. $this->providerRegistry->expects($this->once())
  291. ->method('getProviderStates')
  292. ->with($this->user)
  293. ->willReturn([
  294. $this->fakeProvider->getId() => true,
  295. ]);
  296. $this->providerLoader->expects($this->once())
  297. ->method('getProviders')
  298. ->with($this->user)
  299. ->willReturn([]);
  300. $expectedProviders = [
  301. 'email' => $this->fakeProvider,
  302. ];
  303. $providerSet = $this->manager->getProviderSet($this->user);
  304. $this->assertTrue($providerSet->isProviderMissing());
  305. }
  306. public function testVerifyChallenge() {
  307. $this->prepareProviders();
  308. $challenge = 'passme';
  309. $event = $this->createMock(IEvent::class);
  310. $this->fakeProvider->expects($this->once())
  311. ->method('verifyChallenge')
  312. ->with($this->user, $challenge)
  313. ->willReturn(true);
  314. $this->session->expects($this->once())
  315. ->method('get')
  316. ->with('two_factor_remember_login')
  317. ->willReturn(false);
  318. $this->session->expects($this->exactly(2))
  319. ->method('remove')
  320. ->withConsecutive(
  321. ['two_factor_auth_uid'],
  322. ['two_factor_remember_login']
  323. );
  324. $this->session->expects($this->once())
  325. ->method('set')
  326. ->with(Manager::SESSION_UID_DONE, 'jos');
  327. $this->session->method('getId')
  328. ->willReturn('mysessionid');
  329. $this->activityManager->expects($this->once())
  330. ->method('generateEvent')
  331. ->willReturn($event);
  332. $this->user->expects($this->any())
  333. ->method('getUID')
  334. ->willReturn('jos');
  335. $event->expects($this->once())
  336. ->method('setApp')
  337. ->with($this->equalTo('core'))
  338. ->willReturnSelf();
  339. $event->expects($this->once())
  340. ->method('setType')
  341. ->with($this->equalTo('security'))
  342. ->willReturnSelf();
  343. $event->expects($this->once())
  344. ->method('setAuthor')
  345. ->with($this->equalTo('jos'))
  346. ->willReturnSelf();
  347. $event->expects($this->once())
  348. ->method('setAffectedUser')
  349. ->with($this->equalTo('jos'))
  350. ->willReturnSelf();
  351. $this->fakeProvider
  352. ->method('getDisplayName')
  353. ->willReturn('Fake 2FA');
  354. $event->expects($this->once())
  355. ->method('setSubject')
  356. ->with($this->equalTo('twofactor_success'), $this->equalTo([
  357. 'provider' => 'Fake 2FA',
  358. ]))
  359. ->willReturnSelf();
  360. $token = $this->createMock(OC\Authentication\Token\IToken::class);
  361. $this->tokenProvider->method('getToken')
  362. ->with('mysessionid')
  363. ->willReturn($token);
  364. $token->method('getId')
  365. ->willReturn(42);
  366. $this->config->expects($this->once())
  367. ->method('deleteUserValue')
  368. ->with('jos', 'login_token_2fa', '42');
  369. $result = $this->manager->verifyChallenge('email', $this->user, $challenge);
  370. $this->assertTrue($result);
  371. }
  372. public function testVerifyChallengeInvalidProviderId() {
  373. $this->prepareProviders();
  374. $challenge = 'passme';
  375. $this->fakeProvider->expects($this->never())
  376. ->method('verifyChallenge')
  377. ->with($this->user, $challenge);
  378. $this->session->expects($this->never())
  379. ->method('remove');
  380. $this->assertFalse($this->manager->verifyChallenge('dontexist', $this->user, $challenge));
  381. }
  382. public function testVerifyInvalidChallenge() {
  383. $this->prepareProviders();
  384. $challenge = 'dontpassme';
  385. $event = $this->createMock(IEvent::class);
  386. $this->fakeProvider->expects($this->once())
  387. ->method('verifyChallenge')
  388. ->with($this->user, $challenge)
  389. ->willReturn(false);
  390. $this->session->expects($this->never())
  391. ->method('remove');
  392. $this->activityManager->expects($this->once())
  393. ->method('generateEvent')
  394. ->willReturn($event);
  395. $this->user->expects($this->any())
  396. ->method('getUID')
  397. ->willReturn('jos');
  398. $event->expects($this->once())
  399. ->method('setApp')
  400. ->with($this->equalTo('core'))
  401. ->willReturnSelf();
  402. $event->expects($this->once())
  403. ->method('setType')
  404. ->with($this->equalTo('security'))
  405. ->willReturnSelf();
  406. $event->expects($this->once())
  407. ->method('setAuthor')
  408. ->with($this->equalTo('jos'))
  409. ->willReturnSelf();
  410. $event->expects($this->once())
  411. ->method('setAffectedUser')
  412. ->with($this->equalTo('jos'))
  413. ->willReturnSelf();
  414. $this->fakeProvider
  415. ->method('getDisplayName')
  416. ->willReturn('Fake 2FA');
  417. $event->expects($this->once())
  418. ->method('setSubject')
  419. ->with($this->equalTo('twofactor_failed'), $this->equalTo([
  420. 'provider' => 'Fake 2FA',
  421. ]))
  422. ->willReturnSelf();
  423. $this->assertFalse($this->manager->verifyChallenge('email', $this->user, $challenge));
  424. }
  425. public function testNeedsSecondFactor() {
  426. $user = $this->createMock(IUser::class);
  427. $this->session->expects($this->exactly(3))
  428. ->method('exists')
  429. ->withConsecutive(
  430. ['app_password'],
  431. ['two_factor_auth_uid'],
  432. [Manager::SESSION_UID_DONE],
  433. )
  434. ->willReturn(false);
  435. $this->session->method('getId')
  436. ->willReturn('mysessionid');
  437. $token = $this->createMock(OC\Authentication\Token\IToken::class);
  438. $this->tokenProvider->method('getToken')
  439. ->with('mysessionid')
  440. ->willReturn($token);
  441. $token->method('getId')
  442. ->willReturn(42);
  443. $user->method('getUID')
  444. ->willReturn('user');
  445. $this->config->method('getUserKeys')
  446. ->with('user', 'login_token_2fa')
  447. ->willReturn([
  448. '42'
  449. ]);
  450. $manager = $this->getMockBuilder(Manager::class)
  451. ->setConstructorArgs([
  452. $this->providerLoader,
  453. $this->providerRegistry,
  454. $this->mandatoryTwoFactor,
  455. $this->session,
  456. $this->config,
  457. $this->activityManager,
  458. $this->logger,
  459. $this->tokenProvider,
  460. $this->timeFactory,
  461. $this->dispatcher,
  462. ])
  463. ->setMethods(['loadTwoFactorApp', 'isTwoFactorAuthenticated'])// Do not actually load the apps
  464. ->getMock();
  465. $manager->method('isTwoFactorAuthenticated')
  466. ->with($user)
  467. ->willReturn(true);
  468. $this->assertTrue($manager->needsSecondFactor($user));
  469. }
  470. public function testNeedsSecondFactorUserIsNull() {
  471. $user = null;
  472. $this->session->expects($this->never())
  473. ->method('exists');
  474. $this->assertFalse($this->manager->needsSecondFactor($user));
  475. }
  476. public function testNeedsSecondFactorWithNoProviderAvailableAnymore() {
  477. $this->prepareNoProviders();
  478. $user = null;
  479. $this->session->expects($this->never())
  480. ->method('exists')
  481. ->with('two_factor_auth_uid')
  482. ->willReturn(true);
  483. $this->session->expects($this->never())
  484. ->method('remove')
  485. ->with('two_factor_auth_uid');
  486. $this->assertFalse($this->manager->needsSecondFactor($user));
  487. }
  488. public function testPrepareTwoFactorLogin() {
  489. $this->user->method('getUID')
  490. ->willReturn('ferdinand');
  491. $this->session->expects($this->exactly(2))
  492. ->method('set')
  493. ->withConsecutive(
  494. ['two_factor_auth_uid', 'ferdinand'],
  495. ['two_factor_remember_login', true]
  496. );
  497. $this->session->method('getId')
  498. ->willReturn('mysessionid');
  499. $token = $this->createMock(OC\Authentication\Token\IToken::class);
  500. $this->tokenProvider->method('getToken')
  501. ->with('mysessionid')
  502. ->willReturn($token);
  503. $token->method('getId')
  504. ->willReturn(42);
  505. $this->timeFactory->method('getTime')
  506. ->willReturn(1337);
  507. $this->config->method('setUserValue')
  508. ->with('ferdinand', 'login_token_2fa', '42', '1337');
  509. $this->manager->prepareTwoFactorLogin($this->user, true);
  510. }
  511. public function testPrepareTwoFactorLoginDontRemember() {
  512. $this->user->method('getUID')
  513. ->willReturn('ferdinand');
  514. $this->session->expects($this->exactly(2))
  515. ->method('set')
  516. ->withConsecutive(
  517. ['two_factor_auth_uid', 'ferdinand'],
  518. ['two_factor_remember_login', false]
  519. );
  520. $this->session->method('getId')
  521. ->willReturn('mysessionid');
  522. $token = $this->createMock(OC\Authentication\Token\IToken::class);
  523. $this->tokenProvider->method('getToken')
  524. ->with('mysessionid')
  525. ->willReturn($token);
  526. $token->method('getId')
  527. ->willReturn(42);
  528. $this->timeFactory->method('getTime')
  529. ->willReturn(1337);
  530. $this->config->method('setUserValue')
  531. ->with('ferdinand', 'login_token_2fa', '42', '1337');
  532. $this->manager->prepareTwoFactorLogin($this->user, false);
  533. }
  534. public function testNeedsSecondFactorSessionAuth() {
  535. $user = $this->createMock(IUser::class);
  536. $user->method('getUID')
  537. ->willReturn('user');
  538. $this->session->method('exists')
  539. ->willReturnCallback(function ($var) {
  540. if ($var === Manager::SESSION_UID_KEY) {
  541. return false;
  542. } elseif ($var === 'app_password') {
  543. return false;
  544. } elseif ($var === 'app_api') {
  545. return false;
  546. }
  547. return true;
  548. });
  549. $this->session->method('get')
  550. ->willReturnCallback(function ($var) {
  551. if ($var === Manager::SESSION_UID_KEY) {
  552. return 'user';
  553. } elseif ($var === 'app_api') {
  554. return true;
  555. }
  556. return null;
  557. });
  558. $this->session->expects($this->once())
  559. ->method('get')
  560. ->willReturnMap([
  561. [Manager::SESSION_UID_DONE, 'user'],
  562. ['app_api', true]
  563. ]);
  564. $this->assertFalse($this->manager->needsSecondFactor($user));
  565. }
  566. public function testNeedsSecondFactorSessionAuthFailDBPass() {
  567. $user = $this->createMock(IUser::class);
  568. $user->method('getUID')
  569. ->willReturn('user');
  570. $this->session->method('exists')
  571. ->willReturn(false);
  572. $this->session->method('getId')
  573. ->willReturn('mysessionid');
  574. $token = $this->createMock(OC\Authentication\Token\IToken::class);
  575. $token->method('getId')
  576. ->willReturn(40);
  577. $this->tokenProvider->method('getToken')
  578. ->with('mysessionid')
  579. ->willReturn($token);
  580. $this->config->method('getUserKeys')
  581. ->with('user', 'login_token_2fa')
  582. ->willReturn([
  583. '42', '43', '44'
  584. ]);
  585. $this->session->expects($this->once())
  586. ->method('set')
  587. ->with(Manager::SESSION_UID_DONE, 'user');
  588. $this->assertFalse($this->manager->needsSecondFactor($user));
  589. }
  590. public function testNeedsSecondFactorInvalidToken() {
  591. $this->prepareNoProviders();
  592. $user = $this->createMock(IUser::class);
  593. $user->method('getUID')
  594. ->willReturn('user');
  595. $this->session->method('exists')
  596. ->willReturn(false);
  597. $this->session->method('getId')
  598. ->willReturn('mysessionid');
  599. $this->tokenProvider->method('getToken')
  600. ->with('mysessionid')
  601. ->willThrowException(new OC\Authentication\Exceptions\InvalidTokenException());
  602. $this->config->method('getUserKeys')->willReturn([]);
  603. $this->assertFalse($this->manager->needsSecondFactor($user));
  604. }
  605. public function testNeedsSecondFactorAppPassword() {
  606. $user = $this->createMock(IUser::class);
  607. $this->session->method('exists')
  608. ->willReturnMap([
  609. ['app_password', true],
  610. ['app_api', true]
  611. ]);
  612. $this->assertFalse($this->manager->needsSecondFactor($user));
  613. }
  614. }