public function testIsTwoFactorAuthenticated() { $this->prepareProviders(); $this->user->expects($this->once())->method('getUID')->will($this->returnValue('user123')); $this->config->expects($this->once())->method('getUserValue')->with('user123', 'core', 'two_factor_auth_disabled', 0)->will($this->returnValue(0)); $this->assertTrue($this->manager->isTwoFactorAuthenticated($this->user)); }
/** * Generate a new access token clients can authenticate with * * @PublicPage * @NoCSRFRequired * * @param string $user * @param string $password * @param string $name the name of the client * @return JSONResponse */ public function generateToken($user, $password, $name = 'unknown client') { if (is_null($user) || is_null($password)) { $response = new JSONResponse(); $response->setStatus(Http::STATUS_UNPROCESSABLE_ENTITY); return $response; } $loginName = $user; $user = $this->userManager->checkPassword($loginName, $password); if ($user === false) { $response = new JSONResponse(); $response->setStatus(Http::STATUS_UNAUTHORIZED); return $response; } if ($this->twoFactorAuthManager->isTwoFactorAuthenticated($user)) { $resp = new JSONResponse(); $resp->setStatus(Http::STATUS_UNAUTHORIZED); return $resp; } $token = $this->secureRandom->generate(128); $this->tokenProvider->generateToken($token, $user->getUID(), $loginName, $password, $name, IToken::PERMANENT_TOKEN); return ['token' => $token]; }
/** * @param Controller $controller * @param string $methodName */ public function beforeController($controller, $methodName) { if ($this->reflector->hasAnnotation('PublicPage')) { // Don't block public pages return; } if ($controller instanceof \OC\Core\Controller\LoginController && $methodName === 'logout') { // Don't block the logout page, to allow canceling the 2FA return; } if ($this->userSession->isLoggedIn()) { $user = $this->userSession->getUser(); if ($this->twoFactorManager->isTwoFactorAuthenticated($user)) { $this->checkTwoFactor($controller, $methodName); } else { if ($controller instanceof TwoFactorChallengeController) { // Allow access to the two-factor controllers only if two-factor authentication // is in progress. throw new UserAlreadyLoggedInException(); } } } // TODO: dont check/enforce 2FA if a auth token is used }
/** * @PublicPage * @UseSession * * @param string $user * @param string $password * @param string $redirect_url * @return RedirectResponse */ public function tryLogin($user, $password, $redirect_url) { $originalUser = $user; // TODO: Add all the insane error handling /* @var $loginResult IUser */ $loginResult = $this->userManager->checkPassword($user, $password); if ($loginResult === false) { $users = $this->userManager->getByEmail($user); // we only allow login by email if unique if (count($users) === 1) { $user = $users[0]->getUID(); $loginResult = $this->userManager->checkPassword($user, $password); } } if ($loginResult === false) { $this->session->set('loginMessages', [['invalidpassword']]); // Read current user and append if possible - we need to return the unmodified user otherwise we will leak the login name $args = !is_null($user) ? ['user' => $originalUser] : []; return new RedirectResponse($this->urlGenerator->linkToRoute('core.login.showLoginForm', $args)); } // TODO: remove password checks from above and let the user session handle failures // requires https://github.com/owncloud/core/pull/24616 $this->userSession->login($user, $password); $this->userSession->createSessionToken($this->request, $loginResult->getUID(), $user, $password); if ($this->twoFactorManager->isTwoFactorAuthenticated($loginResult)) { $this->twoFactorManager->prepareTwoFactorLogin($loginResult); if (!is_null($redirect_url)) { return new RedirectResponse($this->urlGenerator->linkToRoute('core.TwoFactorChallenge.selectChallenge', ['redirect_url' => $redirect_url])); } return new RedirectResponse($this->urlGenerator->linkToRoute('core.TwoFactorChallenge.selectChallenge')); } if (!is_null($redirect_url) && $this->userSession->isLoggedIn()) { $location = $this->urlGenerator->getAbsoluteURL(urldecode($redirect_url)); // Deny the redirect if the URL contains a @ // This prevents unvalidated redirects like ?redirect_url=:user@domain.com if (strpos($location, '@') === false) { return new RedirectResponse($location); } } return new RedirectResponse($this->urlGenerator->linkToRoute('files.view.index')); }