ManagerTest.php 19 KB

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