userWith2Fa, $this->userWithout2Fa] as $user) { API::getInstance()->addUser($user, $this->userPassword, $user . '@matomo.org'); $userUpdater = new UserUpdater(); $userUpdater->setSuperUserAccessWithoutCurrentPassword($user, 1); } $this->dao = StaticContainer::get(RecoveryCodeDao::class); $this->settings = new SystemSettings(); $secretGenerator = new TwoFaSecretRandomGenerator(); $this->twoFa = new TwoFactorAuthentication($this->settings, $this->dao, $secretGenerator); $this->dao->createRecoveryCodesForLogin($this->userWith2Fa); $this->twoFa->saveSecret($this->userWith2Fa, $this->user2faSecret); unset($_GET['authCode']); } public function tearDown(): void { unset($_GET['authCode']); } public function test_onCreateAppSpecificTokenAuth_canAuthenticateWhenUserNotUsesTwoFA() { $token = Request::processRequest('UsersManager.createAppSpecificTokenAuth', array( 'userLogin' => $this->userWithout2Fa, 'passwordConfirmation' => $this->userPassword, 'description' => 'twofa test' )); $this->assertEquals(32, strlen($token)); } public function test_onCreateAppSpecificTokenAuth_failsWhenNotAuthenticatedEvenWhen2FAenabled() { $this->expectException(\Exception::class); $this->expectExceptionMessage('UsersManager_CurrentPasswordNotCorrect'); Request::processRequest('UsersManager.createAppSpecificTokenAuth', array( 'userLogin' => $this->userWith2Fa, 'passwordConfirmation' => 'invalidPAssword', 'description' => 'twofa test' )); } public function test_onCreateAppSpecificTokenAuth_throwsErrorWhenMissingTokenWhenUsing2FaAndAuthenticatedCorrectly() { $this->expectException(\Exception::class); $this->expectExceptionMessage('TwoFactorAuth_MissingAuthCodeAPI'); Request::processRequest('UsersManager.createAppSpecificTokenAuth', array( 'userLogin' => $this->userWith2Fa, 'passwordConfirmation' => $this->userPassword, 'description' => 'twofa test' )); } public function test_onCreateAppSpecificTokenAuth_throwsErrorWhenInvalidTokenWhenUsing2FaAndAuthenticatedCorrectly() { $this->expectException(\Exception::class); $this->expectExceptionMessage('TwoFactorAuth_InvalidAuthCode'); $_GET['authCode'] = '111222'; Request::processRequest('UsersManager.createAppSpecificTokenAuth', array( 'userLogin' => $this->userWith2Fa, 'passwordConfirmation' => $this->userPassword, 'description' => 'twofa test' )); } public function test_onCreateAppSpecificTokenAuth_returnsCorrectTokenWhenProvidingCorrectAuthTokenOnAuthentication() { $_GET['authCode'] = $this->generateValidAuthCode($this->user2faSecret); $token = Request::processRequest('UsersManager.createAppSpecificTokenAuth', array( 'userLogin' => $this->userWith2Fa, 'passwordConfirmation' => $this->userPassword, 'description' => 'twofa test' )); $this->assertEquals(32, strlen($token)); } public function test_onDeleteUser_RemovesAllRecoveryCodesWhenUsingTwoFa() { $this->assertNotEmpty($this->dao->getAllRecoveryCodesForLogin($this->userWith2Fa)); Request::processRequest('UsersManager.deleteUser', array( 'userLogin' => $this->userWith2Fa )); $this->assertEmpty($this->dao->getAllRecoveryCodesForLogin($this->userWith2Fa)); } public function test_onDeleteUser_DoesNotFailToDeleteUserNotUsingTwoFa() { $this->expectNotToPerformAssertions(); Request::processRequest('UsersManager.deleteUser', array( 'userLogin' => $this->userWithout2Fa )); } private function generateValidAuthCode($secret) { $code = new \TwoFactorAuthenticator(); return $code->getCode($secret); } }