passwordResetter = $passwordResetter; if (empty($auth)) { $auth = StaticContainer::get('Piwik\Auth'); } $this->auth = $auth; if (empty($sessionInitializer)) { $sessionInitializer = new SessionInitializer(); } $this->sessionInitializer = $sessionInitializer; } /** * Default action * * @param none * @return string */ function index() { return $this->login(); } /** * Login form * * @param string $messageNoAccess Access error message * @param bool $infoMessage * @internal param string $currentUrl Current URL * @return string */ function login($messageNoAccess = null, $infoMessage = false) { $form = new FormLogin(); if ($form->validate()) { $nonce = $form->getSubmitValue('form_nonce'); if (Nonce::verifyNonce('Login.login', $nonce)) { $login = $form->getSubmitValue('form_login'); $password = $form->getSubmitValue('form_password'); $rememberMe = $form->getSubmitValue('form_rememberme') == '1'; try { $this->authenticateAndRedirect($login, $password, $rememberMe); } catch (Exception $e) { $messageNoAccess = $e->getMessage(); } } else { $messageNoAccess = $this->getMessageExceptionNoAccess(); } } $view = new View('@Login/login'); $view->AccessErrorString = $messageNoAccess; $view->infoMessage = nl2br($infoMessage); $view->addForm($form); $this->configureView($view); self::setHostValidationVariablesView($view); return $view->render(); } /** * Configure common view properties * * @param View $view */ private function configureView($view) { $this->setBasicVariablesView($view); $view->linkTitle = Piwik::getRandomTitle(); // crsf token: don't trust the submitted value; generate/fetch it from session data $view->nonce = Nonce::getNonce('Login.login'); } /** * Form-less login * @see how to use it on http://piwik.org/faq/how-to/#faq_30 * @throws Exception * @return void */ function logme() { $password = Common::getRequestVar('password', null, 'string'); $login = Common::getRequestVar('login', null, 'string'); if (Piwik::hasTheUserSuperUserAccess($login)) { throw new Exception(Piwik::translate('Login_ExceptionInvalidSuperUserAccessAuthenticationMethod', array("logme"))); } $currentUrl = 'index.php'; if (($idSite = Common::getRequestVar('idSite', false, 'int')) !== false) { $currentUrl .= '?idSite=' . $idSite; } $urlToRedirect = Common::getRequestVar('url', $currentUrl, 'string'); $urlToRedirect = Common::unsanitizeInputValue($urlToRedirect); $this->authenticateAndRedirect($login, $password, false, $urlToRedirect, $passwordHashed = true); } /** * Authenticate user and password. Redirect if successful. * * @param string $login user name * @param string $password md5 password * @param bool $rememberMe Remember me? * @param string $urlToRedirect URL to redirect to, if successfully authenticated * @return string failure message if unable to authenticate */ protected function authenticateAndRedirect($login, $password, $rememberMe, $urlToRedirect = false, $passwordHashed = false) { Nonce::discardNonce('Login.login'); $this->auth->setLogin($login); if ($passwordHashed === false) { $this->auth->setPassword($password); } else { $this->auth->setPasswordHash($password); } $this->sessionInitializer->initSession($this->auth, $rememberMe); // remove password reset entry if it exists $this->passwordResetter->removePasswordResetInfo($login); if (empty($urlToRedirect)) { $urlToRedirect = Url::getCurrentUrlWithoutQueryString(); } Url::redirectToUrl($urlToRedirect); } protected function getMessageExceptionNoAccess() { $message = Piwik::translate('Login_InvalidNonceOrHeadersOrReferrer', array('', '')); // Should mention trusted_hosts or link to FAQ return $message; } /** * Reset password action. Stores new password as hash and sends email * to confirm use. * * @param none */ function resetPassword() { $infoMessage = null; $formErrors = null; $form = new FormResetPassword(); if ($form->validate()) { $nonce = $form->getSubmitValue('form_nonce'); if (Nonce::verifyNonce('Login.login', $nonce)) { $formErrors = $this->resetPasswordFirstStep($form); if (empty($formErrors)) { $infoMessage = Piwik::translate('Login_ConfirmationLinkSent'); } } else { $formErrors = array($this->getMessageExceptionNoAccess()); } } else { // if invalid, display error $formData = $form->getFormData(); $formErrors = $formData['errors']; } $view = new View('@Login/resetPassword'); $view->infoMessage = $infoMessage; $view->formErrors = $formErrors; return $view->render(); } /** * Saves password reset info and sends confirmation email. * * @param QuickForm2 $form * @return array Error message(s) if an error occurs. */ private function resetPasswordFirstStep($form) { $loginMail = $form->getSubmitValue('form_login'); $password = $form->getSubmitValue('form_password'); try { $this->passwordResetter->initiatePasswordResetProcess($loginMail, $password); } catch (Exception $ex) { Log::debug($ex); return array($ex->getMessage()); } return null; } /** * Password reset confirmation action. Finishes the password reset process. * Users visit this action from a link supplied in an email. */ public function confirmResetPassword() { $errorMessage = null; $login = Common::getRequestVar('login', ''); $resetToken = Common::getRequestVar('resetToken', ''); try { $this->passwordResetter->confirmNewPassword($login, $resetToken); } catch (Exception $ex) { Log::debug($ex); $errorMessage = $ex->getMessage(); } if (is_null($errorMessage)) { // if success, show login w/ success message return $this->resetPasswordSuccess(); } else { // show login page w/ error. this will keep the token in the URL return $this->login($errorMessage); } } /** * The action used after a password is successfully reset. Displays the login * screen with an extra message. A separate action is used instead of returning * the HTML in confirmResetPassword so the resetToken won't be in the URL. */ public function resetPasswordSuccess() { return $this->login($errorMessage = null, $infoMessage = Piwik::translate('Login_PasswordChanged')); } /** * Clear session information * * @param none * @return void */ public static function clearSession() { $authCookieName = Config::getInstance()->General['login_cookie_name']; $cookie = new Cookie($authCookieName); $cookie->delete(); Session::expireSessionCookie(); } /** * Logout current user * * @param none * @return void */ public function logout() { self::clearSession(); $logoutUrl = @Config::getInstance()->General['login_logout_url']; if (empty($logoutUrl)) { Piwik::redirectToModule('CoreHome'); } else { Url::redirectToUrl($logoutUrl); } } }