Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/matomo-org/matomo.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormattab <matthieu.aubry@gmail.com>2013-03-28 03:42:39 +0400
committermattab <matthieu.aubry@gmail.com>2013-03-28 03:42:40 +0400
commitae4b03163792f0b6e933933e5d37df87dc3fd566 (patch)
treed1d7510a9728f587d3d63ebd03e4ecf3d904838b /plugins/Login
parent158c2150f5f2e13ece459b8d131244c11b763997 (diff)
Mass conversion of all files to the newly agreed coding standard: PSR 1/2
Converting Piwik core source files, PHP, JS, TPL, CSS More info: http://piwik.org/participate/coding-standards/
Diffstat (limited to 'plugins/Login')
-rw-r--r--plugins/Login/Auth.php177
-rw-r--r--plugins/Login/Controller.php972
-rw-r--r--plugins/Login/FormLogin.php36
-rw-r--r--plugins/Login/FormResetPassword.php32
-rw-r--r--plugins/Login/Login.php355
-rw-r--r--plugins/Login/templates/header.tpl114
-rw-r--r--plugins/Login/templates/login.css251
-rwxr-xr-xplugins/Login/templates/login.js191
-rw-r--r--plugins/Login/templates/login.tpl141
-rwxr-xr-xplugins/Login/templates/message.tpl14
10 files changed, 1118 insertions, 1165 deletions
diff --git a/plugins/Login/Auth.php b/plugins/Login/Auth.php
index c8c58e7aaf..a7a8a2e490 100644
--- a/plugins/Login/Auth.php
+++ b/plugins/Login/Auth.php
@@ -15,106 +15,101 @@
*/
class Piwik_Login_Auth implements Piwik_Auth
{
- protected $login = null;
- protected $token_auth = null;
+ protected $login = null;
+ protected $token_auth = null;
- /**
- * Authentication module's name, e.g., "Login"
- *
- * @return string
- */
- public function getName()
- {
- return 'Login';
- }
+ /**
+ * Authentication module's name, e.g., "Login"
+ *
+ * @return string
+ */
+ public function getName()
+ {
+ return 'Login';
+ }
- /**
- * Authenticates user
- *
- * @return Piwik_Auth_Result
- */
- public function authenticate()
- {
- $rootLogin = Piwik_Config::getInstance()->superuser['login'];
- $rootPassword = Piwik_Config::getInstance()->superuser['password'];
- $rootToken = Piwik_UsersManager_API::getInstance()->getTokenAuth($rootLogin, $rootPassword);
+ /**
+ * Authenticates user
+ *
+ * @return Piwik_Auth_Result
+ */
+ public function authenticate()
+ {
+ $rootLogin = Piwik_Config::getInstance()->superuser['login'];
+ $rootPassword = Piwik_Config::getInstance()->superuser['password'];
+ $rootToken = Piwik_UsersManager_API::getInstance()->getTokenAuth($rootLogin, $rootPassword);
- if(is_null($this->login))
- {
- if($this->token_auth === $rootToken)
- {
- return new Piwik_Auth_Result(Piwik_Auth_Result::SUCCESS_SUPERUSER_AUTH_CODE, $rootLogin, $this->token_auth );
- }
+ if (is_null($this->login)) {
+ if ($this->token_auth === $rootToken) {
+ return new Piwik_Auth_Result(Piwik_Auth_Result::SUCCESS_SUPERUSER_AUTH_CODE, $rootLogin, $this->token_auth);
+ }
- $login = Piwik_FetchOne(
- 'SELECT login
- FROM '.Piwik_Common::prefixTable('user').'
+ $login = Piwik_FetchOne(
+ 'SELECT login
+ FROM ' . Piwik_Common::prefixTable('user') . '
WHERE token_auth = ?',
- array($this->token_auth)
- );
- if(!empty($login))
- {
- return new Piwik_Auth_Result(Piwik_Auth_Result::SUCCESS, $login, $this->token_auth );
- }
- }
- else if(!empty($this->login))
- {
- if($this->login === $rootLogin
- && ($this->getHashTokenAuth($rootLogin, $rootToken) === $this->token_auth)
- || $rootToken === $this->token_auth)
- {
- $this->setTokenAuth($rootToken);
- return new Piwik_Auth_Result(Piwik_Auth_Result::SUCCESS_SUPERUSER_AUTH_CODE, $rootLogin, $this->token_auth );
- }
+ array($this->token_auth)
+ );
+ if (!empty($login)) {
+ return new Piwik_Auth_Result(Piwik_Auth_Result::SUCCESS, $login, $this->token_auth);
+ }
+ } else if (!empty($this->login)) {
+ if ($this->login === $rootLogin
+ && ($this->getHashTokenAuth($rootLogin, $rootToken) === $this->token_auth)
+ || $rootToken === $this->token_auth
+ ) {
+ $this->setTokenAuth($rootToken);
+ return new Piwik_Auth_Result(Piwik_Auth_Result::SUCCESS_SUPERUSER_AUTH_CODE, $rootLogin, $this->token_auth);
+ }
- $login = $this->login;
- $userToken = Piwik_FetchOne(
- 'SELECT token_auth
- FROM '.Piwik_Common::prefixTable('user').'
+ $login = $this->login;
+ $userToken = Piwik_FetchOne(
+ 'SELECT token_auth
+ FROM ' . Piwik_Common::prefixTable('user') . '
WHERE login = ?',
- array($login)
- );
- if(!empty($userToken)
- && (($this->getHashTokenAuth($login, $userToken) === $this->token_auth)
- || $userToken === $this->token_auth))
- {
- $this->setTokenAuth($userToken);
- return new Piwik_Auth_Result(Piwik_Auth_Result::SUCCESS, $login, $userToken );
- }
- }
+ array($login)
+ );
+ if (!empty($userToken)
+ && (($this->getHashTokenAuth($login, $userToken) === $this->token_auth)
+ || $userToken === $this->token_auth)
+ ) {
+ $this->setTokenAuth($userToken);
+ return new Piwik_Auth_Result(Piwik_Auth_Result::SUCCESS, $login, $userToken);
+ }
+ }
- return new Piwik_Auth_Result( Piwik_Auth_Result::FAILURE, $this->login, $this->token_auth );
- }
+ return new Piwik_Auth_Result(Piwik_Auth_Result::FAILURE, $this->login, $this->token_auth);
+ }
- /**
- * Accessor to set login name
- *
- * @param string $login user login
- */
- public function setLogin($login)
- {
- $this->login = $login;
- }
+ /**
+ * Accessor to set login name
+ *
+ * @param string $login user login
+ */
+ public function setLogin($login)
+ {
+ $this->login = $login;
+ }
- /**
- * Accessor to set authentication token
- *
- * @param string $token_auth authentication token
- */
- public function setTokenAuth($token_auth)
- {
- $this->token_auth = $token_auth;
- }
+ /**
+ * Accessor to set authentication token
+ *
+ * @param string $token_auth authentication token
+ */
+ public function setTokenAuth($token_auth)
+ {
+ $this->token_auth = $token_auth;
+ }
- /**
- * Accessor to compute the hashed authentication token
- *
- * @param string $login user login
- * @param string $token_auth authentication token
- * @return string hashed authentication token
- */
- public function getHashTokenAuth($login, $token_auth)
- {
- return md5($login . $token_auth);
- }
+ /**
+ * Accessor to compute the hashed authentication token
+ *
+ * @param string $login user login
+ * @param string $token_auth authentication token
+ * @return string hashed authentication token
+ */
+ public function getHashTokenAuth($login, $token_auth)
+ {
+ return md5($login . $token_auth);
+ }
}
diff --git a/plugins/Login/Controller.php b/plugins/Login/Controller.php
index 7031ca4307..912c5f441d 100644
--- a/plugins/Login/Controller.php
+++ b/plugins/Login/Controller.php
@@ -16,510 +16,470 @@
*/
class Piwik_Login_Controller extends Piwik_Controller
{
- /**
- * Generate hash on user info and password
- *
- * @param string $userinfo User name, email, etc
- * @param string $password
- * @return string
- */
- private function generateHash($userInfo, $password)
- {
- // mitigate rainbow table attack
- $passwordLen = strlen($password) / 2;
- $hash = Piwik_Common::hash(
- $userInfo . substr($password, 0, $passwordLen)
- . Piwik_Common::getSalt() . substr($password, $passwordLen)
- );
- return $hash;
- }
-
- /**
- * Default action
- *
- * @param none
- * @return void
- */
- function index()
- {
- $this->login();
- }
-
- /**
- * Login form
- *
- * @param string $messageNoAccess Access error message
- * @param string $currentUrl Current URL
- * @return void
- */
- function login($messageNoAccess = null, $infoMessage = false)
- {
- self::checkForceSslLogin();
-
- $form = new Piwik_Login_FormLogin();
- if($form->validate())
- {
- $nonce = $form->getSubmitValue('form_nonce');
- if(Piwik_Nonce::verifyNonce('Piwik_Login.login', $nonce))
- {
- $login = $form->getSubmitValue('form_login');
- $password = $form->getSubmitValue('form_password');
- $rememberMe = $form->getSubmitValue('form_rememberme') == '1';
- $md5Password = md5($password);
- try {
- $this->authenticateAndRedirect($login, $md5Password, $rememberMe);
- } catch(Exception $e) {
- $messageNoAccess = $e->getMessage();
- }
- }
- else
- {
- $messageNoAccess = $this->getMessageExceptionNoAccess();
- }
- }
-
- $view = Piwik_View::factory('login');
- $view->AccessErrorString = $messageNoAccess;
- $view->infoMessage = nl2br($infoMessage);
- $view->addForm( $form );
- $this->configureView($view);
- self::setHostValidationVariablesView($view);
- echo $view->render();
- }
-
- /**
- * Configure common view properties
- *
- * @param Piwik_View $view
- */
- private function configureView($view)
- {
- $this->setBasicVariablesView($view);
-
- $view->linkTitle = Piwik::getRandomTitle();
-
- $view->forceSslLogin = Piwik_Config::getInstance()->General['force_ssl_login'];
-
- // crsf token: don't trust the submitted value; generate/fetch it from session data
- $view->nonce = Piwik_Nonce::getNonce('Piwik_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()
- {
- self::checkForceSslLogin();
-
- $password = Piwik_Common::getRequestVar('password', null, 'string');
- if(strlen($password) != 32)
- {
- throw new Exception(Piwik_TranslateException('Login_ExceptionPasswordMD5HashExpected'));
- }
-
- $login = Piwik_Common::getRequestVar('login', null, 'string');
- if($login == Piwik_Config::getInstance()->superuser['login'])
- {
- throw new Exception(Piwik_TranslateException('Login_ExceptionInvalidSuperUserAuthenticationMethod', array("logme")));
- }
-
- $currentUrl = 'index.php';
-
- if(($idSite = Piwik_Common::getRequestVar('idSite', false, 'int')) !== false)
- {
- $currentUrl .= '?idSite='.$idSite;
- }
-
- $urlToRedirect = Piwik_Common::getRequestVar('url', $currentUrl, 'string');
- $urlToRedirect = Piwik_Common::unsanitizeInputValue($urlToRedirect);
-
- $this->authenticateAndRedirect($login, $password, false, $urlToRedirect);
- }
-
- /**
- * Authenticate user and password. Redirect if successful.
- *
- * @param string $login user name
- * @param string $md5Password md5 hash of 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, $md5Password, $rememberMe, $urlToRedirect = 'index.php')
- {
- $info = array( 'login' => $login,
- 'md5Password' => $md5Password,
- 'rememberMe' => $rememberMe,
- );
- Piwik_Nonce::discardNonce('Piwik_Login.login');
- Piwik_PostEvent('Login.initSession', $info);
- Piwik_Url::redirectToUrl($urlToRedirect);
- }
-
- protected function getMessageExceptionNoAccess()
- {
- $message = Piwik_Translate('Login_InvalidNonceOrHeadersOrReferer', array('<a href="?module=Proxy&action=redirect&url='.urlencode('http://piwik.org/faq/how-to-install/#faq_98').'" target="_blank">', '</a>'));
- // 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
- * @return void
- */
- function resetPassword()
- {
- self::checkForceSslLogin();
-
- $infoMessage = null;
- $formErrors = null;
-
- $form = new Piwik_Login_FormResetPassword();
- if($form->validate())
- {
- $nonce = $form->getSubmitValue('form_nonce');
- if(Piwik_Nonce::verifyNonce('Piwik_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 = Piwik_View::factory('message');
- $view->infoMessage = $infoMessage;
- $view->formErrors = $formErrors;
- echo $view->render();
- }
-
- /**
- * Saves password reset info and sends confirmation email.
- *
- * @return array Error message(s) if an error occurs.
- */
- private function resetPasswordFirstStep( $form )
- {
- $loginMail = $form->getSubmitValue('form_login');
- $token = $form->getSubmitValue('form_token');
- $password = $form->getSubmitValue('form_password');
-
- // check the password
- try
- {
- Piwik_UsersManager::checkPassword($password);
- }
- catch (Exception $ex)
- {
- return array($ex->getMessage());
- }
-
- // get the user's login
- if ($loginMail === 'anonymous')
- {
- return array(Piwik_Translate('Login_InvalidUsernameEmail'));
- }
-
- $user = self::getUserInformation($loginMail);
- if ($user === null)
- {
- return array(Piwik_Translate('Login_InvalidUsernameEmail'));
- }
-
- $login = $user['login'];
-
- // if valid, store password information in options table, then...
- Piwik_Login::savePasswordResetInfo($login, $password);
-
- // ... send email with confirmation link
- try
- {
- $this->sendEmailConfirmationLink($user);
- }
- catch (Exception $ex)
- {
- // remove password reset info
- Piwik_Login::removePasswordResetInfo($login);
-
- return array($ex->getMessage().'<br/>'.Piwik_Translate('Login_ContactAdmin'));
- }
-
- return null;
- }
-
- /**
- * Sends email confirmation link for a password reset request.
- *
- * @param array $user User info for the requested password reset.
- */
- private function sendEmailConfirmationLink( $user )
- {
- $login = $user['login'];
- $email = $user['email'];
-
- // construct a password reset token from user information
- $resetToken = self::generatePasswordResetToken($user);
-
- $ip = Piwik_IP::getIpFromHeader();
- $url = Piwik_Url::getCurrentUrlWithoutQueryString()
- . "?module=Login&action=confirmResetPassword&login=".urlencode($login)
- . "&resetToken=".urlencode($resetToken);
-
- // send email with new password
- $mail = new Piwik_Mail();
- $mail->addTo($email, $login);
- $mail->setSubject(Piwik_Translate('Login_MailTopicPasswordChange'));
- $bodyText = str_replace(
- '\n',
- "\n",
- sprintf(Piwik_Translate('Login_MailPasswordChangeBody'), $login, $ip, $url)
- ) . "\n";
- $mail->setBodyText($bodyText);
-
- $fromEmailName = Piwik_Config::getInstance()->General['login_password_recovery_email_name'];
- $fromEmailAddress = Piwik_Config::getInstance()->General['login_password_recovery_email_address'];
- $mail->setFrom($fromEmailAddress, $fromEmailName);
- @$mail->send();
- }
-
- /**
- * 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 = Piwik_Common::getRequestVar('login', '');
- $resetToken = Piwik_Common::getRequestVar('resetToken', '');
-
- try
- {
- // get password reset info & user info
- $user = self::getUserInformation($login);
- if ($user === null)
- {
- throw new Exception(Piwik_Translate('Login_InvalidUsernameEmail'));
- }
-
- // check that the reset token is valid
- $resetPassword = Piwik_Login::getPasswordToResetTo($login);
- if ($resetPassword === false || !self::isValidToken($resetToken, $user))
- {
- throw new Exception(Piwik_Translate('Login_InvalidOrExpiredToken'));
- }
-
- // reset password of user
- $this->setNewUserPassword($user, $resetPassword);
- }
- catch (Exception $ex)
- {
- $errorMessage = $ex->getMessage();
- }
-
- if (is_null($errorMessage)) // if success, show login w/ success message
- {
- $this->redirectToIndex('Login', 'resetPasswordSuccess');
- }
- else
- {
- // show login page w/ error. this will keep the token in the URL
- return $this->login($errorMessage);
- }
- }
-
- /**
- * Sets the password for a user.
- *
- * @param array $user User info.
- * @param string $passwordHash The hashed password to use.
- */
- private function setNewUserPassword( $user, $passwordHash )
- {
- if (strlen($passwordHash) !== 32) // sanity check
- {
- throw new Exception(
- "setNewUserPassword called w/ incorrect password hash. Something has gone terribly wrong.");
- }
-
- if( $user['email'] == Piwik::getSuperUserEmail() )
- {
- if(!Piwik_Config::getInstance()->isFileWritable())
- {
- throw new Exception(Piwik_Translate('General_ConfigFileIsNotWritable', array("(config/config.ini.php)","<br/>")));
- }
-
- $user['password'] = $passwordHash;
- Piwik_Config::getInstance()->superuser = $user;
- Piwik_Config::getInstance()->forceSave();
- }
- else
- {
- Piwik_UsersManager_API::getInstance()->updateUser(
- $user['login'], $passwordHash, $email = false, $alias = false, $isPasswordHashed = true);
- }
- }
-
- /**
- * 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'));
- }
-
- /**
- * Get user information
- *
- * @param string $loginMail user login or email address
- * @return array ("login" => '...', "email" => '...', "password" => '...') or null, if user not found
- */
- protected function getUserInformation($loginMail)
- {
- Piwik::setUserIsSuperUser();
-
- $user = null;
- if( $loginMail == Piwik::getSuperUserEmail()
- || $loginMail == Piwik_Config::getInstance()->superuser['login'] )
- {
- $user = array(
- 'login' => Piwik_Config::getInstance()->superuser['login'],
- 'email' => Piwik::getSuperUserEmail(),
- 'password' => Piwik_Config::getInstance()->superuser['password'],
- );
- }
- else if( Piwik_UsersManager_API::getInstance()->userExists($loginMail) )
- {
- $user = Piwik_UsersManager_API::getInstance()->getUser($loginMail);
- }
- else if( Piwik_UsersManager_API::getInstance()->userEmailExists($loginMail) )
- {
- $user = Piwik_UsersManager_API::getInstance()->getUserByEmail($loginMail);
- }
-
- return $user;
- }
-
- /**
- * Generate a password reset token. Expires in (roughly) 24 hours.
- *
- * @param array user information
- * @param int $timestamp Unix timestamp
- * @return string generated token
- */
- protected function generatePasswordResetToken($user, $timestamp = null)
- {
- /*
- * Piwik does not store the generated password reset token.
- * This avoids a database schema change and SQL queries to store, retrieve, and purge (expired) tokens.
- */
- if(!$timestamp)
- {
- $timestamp = time() + 24*60*60; /* +24 hrs */
- }
-
- $expiry = strftime('%Y%m%d%H', $timestamp);
- $token = $this->generateHash(
- $expiry . $user['login'] . $user['email'],
- $user['password']
- );
- return $token;
- }
-
- /**
- * Validate token.
- *
- * @param string $token
- * @param array $user user information
- * @return bool true if valid, false otherwise
- */
- protected function isValidToken($token, $user)
- {
- $now = time();
-
- // token valid for 24 hrs (give or take, due to the coarse granularity in our strftime format string)
- for($i = 0; $i <= 24; $i++)
- {
- $generatedToken = self::generatePasswordResetToken($user, $now + $i*60*60);
- if($generatedToken === $token)
- {
- return true;
- }
- }
-
- // fails if token is invalid, expired, password already changed, other user information has changed, ...
- return false;
- }
-
- /**
- * Clear session information
- *
- * @param none
- * @return void
- */
- static public function clearSession()
- {
- $authCookieName = Piwik_Config::getInstance()->General['login_cookie_name'];
- $cookie = new Piwik_Cookie($authCookieName);
- $cookie->delete();
-
- Piwik_Session::expireSessionCookie();
- }
-
- /**
- * Logout current user
- *
- * @param none
- * @return void
- */
- public function logout()
- {
- self::clearSession();
-
- $logoutUrl = @Piwik_Config::getInstance()->General['login_logout_url'];
- if(empty($logoutUrl)) {
- Piwik::redirectToModule('CoreHome');
- } else {
- Piwik_Url::redirectToUrl($logoutUrl);
- }
- }
-
- /**
- * Check force_ssl_login and redirect if connection isn't secure and not using a reverse proxy
- *
- * @param none
- * @return void
- */
- protected function checkForceSslLogin()
- {
- $forceSslLogin = Piwik_Config::getInstance()->General['force_ssl_login'];
- if($forceSslLogin
- && !Piwik::isHttps())
- {
- $url = 'https://'
- . Piwik_Url::getCurrentHost()
- . Piwik_Url::getCurrentScriptName()
- . Piwik_Url::getCurrentQueryString();
- Piwik_Url::redirectToUrl($url);
- }
- }
+ /**
+ * Generate hash on user info and password
+ *
+ * @param string $userinfo User name, email, etc
+ * @param string $password
+ * @return string
+ */
+ private function generateHash($userInfo, $password)
+ {
+ // mitigate rainbow table attack
+ $passwordLen = strlen($password) / 2;
+ $hash = Piwik_Common::hash(
+ $userInfo . substr($password, 0, $passwordLen)
+ . Piwik_Common::getSalt() . substr($password, $passwordLen)
+ );
+ return $hash;
+ }
+
+ /**
+ * Default action
+ *
+ * @param none
+ * @return void
+ */
+ function index()
+ {
+ $this->login();
+ }
+
+ /**
+ * Login form
+ *
+ * @param string $messageNoAccess Access error message
+ * @param string $currentUrl Current URL
+ * @return void
+ */
+ function login($messageNoAccess = null, $infoMessage = false)
+ {
+ self::checkForceSslLogin();
+
+ $form = new Piwik_Login_FormLogin();
+ if ($form->validate()) {
+ $nonce = $form->getSubmitValue('form_nonce');
+ if (Piwik_Nonce::verifyNonce('Piwik_Login.login', $nonce)) {
+ $login = $form->getSubmitValue('form_login');
+ $password = $form->getSubmitValue('form_password');
+ $rememberMe = $form->getSubmitValue('form_rememberme') == '1';
+ $md5Password = md5($password);
+ try {
+ $this->authenticateAndRedirect($login, $md5Password, $rememberMe);
+ } catch (Exception $e) {
+ $messageNoAccess = $e->getMessage();
+ }
+ } else {
+ $messageNoAccess = $this->getMessageExceptionNoAccess();
+ }
+ }
+
+ $view = Piwik_View::factory('login');
+ $view->AccessErrorString = $messageNoAccess;
+ $view->infoMessage = nl2br($infoMessage);
+ $view->addForm($form);
+ $this->configureView($view);
+ self::setHostValidationVariablesView($view);
+ echo $view->render();
+ }
+
+ /**
+ * Configure common view properties
+ *
+ * @param Piwik_View $view
+ */
+ private function configureView($view)
+ {
+ $this->setBasicVariablesView($view);
+
+ $view->linkTitle = Piwik::getRandomTitle();
+
+ $view->forceSslLogin = Piwik_Config::getInstance()->General['force_ssl_login'];
+
+ // crsf token: don't trust the submitted value; generate/fetch it from session data
+ $view->nonce = Piwik_Nonce::getNonce('Piwik_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()
+ {
+ self::checkForceSslLogin();
+
+ $password = Piwik_Common::getRequestVar('password', null, 'string');
+ if (strlen($password) != 32) {
+ throw new Exception(Piwik_TranslateException('Login_ExceptionPasswordMD5HashExpected'));
+ }
+
+ $login = Piwik_Common::getRequestVar('login', null, 'string');
+ if ($login == Piwik_Config::getInstance()->superuser['login']) {
+ throw new Exception(Piwik_TranslateException('Login_ExceptionInvalidSuperUserAuthenticationMethod', array("logme")));
+ }
+
+ $currentUrl = 'index.php';
+
+ if (($idSite = Piwik_Common::getRequestVar('idSite', false, 'int')) !== false) {
+ $currentUrl .= '?idSite=' . $idSite;
+ }
+
+ $urlToRedirect = Piwik_Common::getRequestVar('url', $currentUrl, 'string');
+ $urlToRedirect = Piwik_Common::unsanitizeInputValue($urlToRedirect);
+
+ $this->authenticateAndRedirect($login, $password, false, $urlToRedirect);
+ }
+
+ /**
+ * Authenticate user and password. Redirect if successful.
+ *
+ * @param string $login user name
+ * @param string $md5Password md5 hash of 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, $md5Password, $rememberMe, $urlToRedirect = 'index.php')
+ {
+ $info = array('login' => $login,
+ 'md5Password' => $md5Password,
+ 'rememberMe' => $rememberMe,
+ );
+ Piwik_Nonce::discardNonce('Piwik_Login.login');
+ Piwik_PostEvent('Login.initSession', $info);
+ Piwik_Url::redirectToUrl($urlToRedirect);
+ }
+
+ protected function getMessageExceptionNoAccess()
+ {
+ $message = Piwik_Translate('Login_InvalidNonceOrHeadersOrReferer', array('<a href="?module=Proxy&action=redirect&url=' . urlencode('http://piwik.org/faq/how-to-install/#faq_98') . '" target="_blank">', '</a>'));
+ // 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
+ * @return void
+ */
+ function resetPassword()
+ {
+ self::checkForceSslLogin();
+
+ $infoMessage = null;
+ $formErrors = null;
+
+ $form = new Piwik_Login_FormResetPassword();
+ if ($form->validate()) {
+ $nonce = $form->getSubmitValue('form_nonce');
+ if (Piwik_Nonce::verifyNonce('Piwik_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 = Piwik_View::factory('message');
+ $view->infoMessage = $infoMessage;
+ $view->formErrors = $formErrors;
+ echo $view->render();
+ }
+
+ /**
+ * Saves password reset info and sends confirmation email.
+ *
+ * @return array Error message(s) if an error occurs.
+ */
+ private function resetPasswordFirstStep($form)
+ {
+ $loginMail = $form->getSubmitValue('form_login');
+ $token = $form->getSubmitValue('form_token');
+ $password = $form->getSubmitValue('form_password');
+
+ // check the password
+ try {
+ Piwik_UsersManager::checkPassword($password);
+ } catch (Exception $ex) {
+ return array($ex->getMessage());
+ }
+
+ // get the user's login
+ if ($loginMail === 'anonymous') {
+ return array(Piwik_Translate('Login_InvalidUsernameEmail'));
+ }
+
+ $user = self::getUserInformation($loginMail);
+ if ($user === null) {
+ return array(Piwik_Translate('Login_InvalidUsernameEmail'));
+ }
+
+ $login = $user['login'];
+
+ // if valid, store password information in options table, then...
+ Piwik_Login::savePasswordResetInfo($login, $password);
+
+ // ... send email with confirmation link
+ try {
+ $this->sendEmailConfirmationLink($user);
+ } catch (Exception $ex) {
+ // remove password reset info
+ Piwik_Login::removePasswordResetInfo($login);
+
+ return array($ex->getMessage() . '<br/>' . Piwik_Translate('Login_ContactAdmin'));
+ }
+
+ return null;
+ }
+
+ /**
+ * Sends email confirmation link for a password reset request.
+ *
+ * @param array $user User info for the requested password reset.
+ */
+ private function sendEmailConfirmationLink($user)
+ {
+ $login = $user['login'];
+ $email = $user['email'];
+
+ // construct a password reset token from user information
+ $resetToken = self::generatePasswordResetToken($user);
+
+ $ip = Piwik_IP::getIpFromHeader();
+ $url = Piwik_Url::getCurrentUrlWithoutQueryString()
+ . "?module=Login&action=confirmResetPassword&login=" . urlencode($login)
+ . "&resetToken=" . urlencode($resetToken);
+
+ // send email with new password
+ $mail = new Piwik_Mail();
+ $mail->addTo($email, $login);
+ $mail->setSubject(Piwik_Translate('Login_MailTopicPasswordChange'));
+ $bodyText = str_replace(
+ '\n',
+ "\n",
+ sprintf(Piwik_Translate('Login_MailPasswordChangeBody'), $login, $ip, $url)
+ ) . "\n";
+ $mail->setBodyText($bodyText);
+
+ $fromEmailName = Piwik_Config::getInstance()->General['login_password_recovery_email_name'];
+ $fromEmailAddress = Piwik_Config::getInstance()->General['login_password_recovery_email_address'];
+ $mail->setFrom($fromEmailAddress, $fromEmailName);
+ @$mail->send();
+ }
+
+ /**
+ * 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 = Piwik_Common::getRequestVar('login', '');
+ $resetToken = Piwik_Common::getRequestVar('resetToken', '');
+
+ try {
+ // get password reset info & user info
+ $user = self::getUserInformation($login);
+ if ($user === null) {
+ throw new Exception(Piwik_Translate('Login_InvalidUsernameEmail'));
+ }
+
+ // check that the reset token is valid
+ $resetPassword = Piwik_Login::getPasswordToResetTo($login);
+ if ($resetPassword === false || !self::isValidToken($resetToken, $user)) {
+ throw new Exception(Piwik_Translate('Login_InvalidOrExpiredToken'));
+ }
+
+ // reset password of user
+ $this->setNewUserPassword($user, $resetPassword);
+ } catch (Exception $ex) {
+ $errorMessage = $ex->getMessage();
+ }
+
+ if (is_null($errorMessage)) // if success, show login w/ success message
+ {
+ $this->redirectToIndex('Login', 'resetPasswordSuccess');
+ } else {
+ // show login page w/ error. this will keep the token in the URL
+ return $this->login($errorMessage);
+ }
+ }
+
+ /**
+ * Sets the password for a user.
+ *
+ * @param array $user User info.
+ * @param string $passwordHash The hashed password to use.
+ */
+ private function setNewUserPassword($user, $passwordHash)
+ {
+ if (strlen($passwordHash) !== 32) // sanity check
+ {
+ throw new Exception(
+ "setNewUserPassword called w/ incorrect password hash. Something has gone terribly wrong.");
+ }
+
+ if ($user['email'] == Piwik::getSuperUserEmail()) {
+ if (!Piwik_Config::getInstance()->isFileWritable()) {
+ throw new Exception(Piwik_Translate('General_ConfigFileIsNotWritable', array("(config/config.ini.php)", "<br/>")));
+ }
+
+ $user['password'] = $passwordHash;
+ Piwik_Config::getInstance()->superuser = $user;
+ Piwik_Config::getInstance()->forceSave();
+ } else {
+ Piwik_UsersManager_API::getInstance()->updateUser(
+ $user['login'], $passwordHash, $email = false, $alias = false, $isPasswordHashed = true);
+ }
+ }
+
+ /**
+ * 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'));
+ }
+
+ /**
+ * Get user information
+ *
+ * @param string $loginMail user login or email address
+ * @return array ("login" => '...', "email" => '...', "password" => '...') or null, if user not found
+ */
+ protected function getUserInformation($loginMail)
+ {
+ Piwik::setUserIsSuperUser();
+
+ $user = null;
+ if ($loginMail == Piwik::getSuperUserEmail()
+ || $loginMail == Piwik_Config::getInstance()->superuser['login']
+ ) {
+ $user = array(
+ 'login' => Piwik_Config::getInstance()->superuser['login'],
+ 'email' => Piwik::getSuperUserEmail(),
+ 'password' => Piwik_Config::getInstance()->superuser['password'],
+ );
+ } else if (Piwik_UsersManager_API::getInstance()->userExists($loginMail)) {
+ $user = Piwik_UsersManager_API::getInstance()->getUser($loginMail);
+ } else if (Piwik_UsersManager_API::getInstance()->userEmailExists($loginMail)) {
+ $user = Piwik_UsersManager_API::getInstance()->getUserByEmail($loginMail);
+ }
+
+ return $user;
+ }
+
+ /**
+ * Generate a password reset token. Expires in (roughly) 24 hours.
+ *
+ * @param array user information
+ * @param int $timestamp Unix timestamp
+ * @return string generated token
+ */
+ protected function generatePasswordResetToken($user, $timestamp = null)
+ {
+ /*
+ * Piwik does not store the generated password reset token.
+ * This avoids a database schema change and SQL queries to store, retrieve, and purge (expired) tokens.
+ */
+ if (!$timestamp) {
+ $timestamp = time() + 24 * 60 * 60; /* +24 hrs */
+ }
+
+ $expiry = strftime('%Y%m%d%H', $timestamp);
+ $token = $this->generateHash(
+ $expiry . $user['login'] . $user['email'],
+ $user['password']
+ );
+ return $token;
+ }
+
+ /**
+ * Validate token.
+ *
+ * @param string $token
+ * @param array $user user information
+ * @return bool true if valid, false otherwise
+ */
+ protected function isValidToken($token, $user)
+ {
+ $now = time();
+
+ // token valid for 24 hrs (give or take, due to the coarse granularity in our strftime format string)
+ for ($i = 0; $i <= 24; $i++) {
+ $generatedToken = self::generatePasswordResetToken($user, $now + $i * 60 * 60);
+ if ($generatedToken === $token) {
+ return true;
+ }
+ }
+
+ // fails if token is invalid, expired, password already changed, other user information has changed, ...
+ return false;
+ }
+
+ /**
+ * Clear session information
+ *
+ * @param none
+ * @return void
+ */
+ static public function clearSession()
+ {
+ $authCookieName = Piwik_Config::getInstance()->General['login_cookie_name'];
+ $cookie = new Piwik_Cookie($authCookieName);
+ $cookie->delete();
+
+ Piwik_Session::expireSessionCookie();
+ }
+
+ /**
+ * Logout current user
+ *
+ * @param none
+ * @return void
+ */
+ public function logout()
+ {
+ self::clearSession();
+
+ $logoutUrl = @Piwik_Config::getInstance()->General['login_logout_url'];
+ if (empty($logoutUrl)) {
+ Piwik::redirectToModule('CoreHome');
+ } else {
+ Piwik_Url::redirectToUrl($logoutUrl);
+ }
+ }
+
+ /**
+ * Check force_ssl_login and redirect if connection isn't secure and not using a reverse proxy
+ *
+ * @param none
+ * @return void
+ */
+ protected function checkForceSslLogin()
+ {
+ $forceSslLogin = Piwik_Config::getInstance()->General['force_ssl_login'];
+ if ($forceSslLogin
+ && !Piwik::isHttps()
+ ) {
+ $url = 'https://'
+ . Piwik_Url::getCurrentHost()
+ . Piwik_Url::getCurrentScriptName()
+ . Piwik_Url::getCurrentQueryString();
+ Piwik_Url::redirectToUrl($url);
+ }
+ }
}
diff --git a/plugins/Login/FormLogin.php b/plugins/Login/FormLogin.php
index 46c02f2f91..a90146f47e 100644
--- a/plugins/Login/FormLogin.php
+++ b/plugins/Login/FormLogin.php
@@ -15,28 +15,28 @@
*/
class Piwik_Login_FormLogin extends Piwik_QuickForm2
{
- function __construct( $id = 'login_form', $method = 'post', $attributes = null, $trackSubmit = false)
- {
- parent::__construct($id, $method, $attributes, $trackSubmit);
- }
+ function __construct($id = 'login_form', $method = 'post', $attributes = null, $trackSubmit = false)
+ {
+ parent::__construct($id, $method, $attributes, $trackSubmit);
+ }
- function init()
- {
- $this->addElement('text', 'form_login')
- ->addRule('required', Piwik_Translate('General_Required', Piwik_Translate('General_Username')));
+ function init()
+ {
+ $this->addElement('text', 'form_login')
+ ->addRule('required', Piwik_Translate('General_Required', Piwik_Translate('General_Username')));
- $this->addElement('password', 'form_password')
- ->addRule('required', Piwik_Translate('General_Required', Piwik_Translate('Login_Password')));
+ $this->addElement('password', 'form_password')
+ ->addRule('required', Piwik_Translate('General_Required', Piwik_Translate('Login_Password')));
- $this->addElement('hidden', 'form_nonce');
+ $this->addElement('hidden', 'form_nonce');
- $this->addElement('checkbox', 'form_rememberme');
+ $this->addElement('checkbox', 'form_rememberme');
- $this->addElement('submit', 'submit');
+ $this->addElement('submit', 'submit');
- // default values
- $this->addDataSource(new HTML_QuickForm2_DataSource_Array(array(
- 'form_rememberme' => 0,
- )));
- }
+ // default values
+ $this->addDataSource(new HTML_QuickForm2_DataSource_Array(array(
+ 'form_rememberme' => 0,
+ )));
+ }
}
diff --git a/plugins/Login/FormResetPassword.php b/plugins/Login/FormResetPassword.php
index 88791060d4..0411beddbb 100644
--- a/plugins/Login/FormResetPassword.php
+++ b/plugins/Login/FormResetPassword.php
@@ -15,25 +15,25 @@
*/
class Piwik_Login_FormResetPassword extends Piwik_QuickForm2
{
- function __construct( $id = 'resetpasswordform', $method = 'post', $attributes = null, $trackSubmit = false)
- {
- parent::__construct($id, $method, $attributes, $trackSubmit);
- }
+ function __construct($id = 'resetpasswordform', $method = 'post', $attributes = null, $trackSubmit = false)
+ {
+ parent::__construct($id, $method, $attributes, $trackSubmit);
+ }
- function init()
- {
- $this->addElement('text', 'form_login')
- ->addRule('required', Piwik_Translate('General_Required', Piwik_Translate('General_Username')));
+ function init()
+ {
+ $this->addElement('text', 'form_login')
+ ->addRule('required', Piwik_Translate('General_Required', Piwik_Translate('General_Username')));
- $password = $this->addElement('password', 'form_password');
- $password->addRule('required', Piwik_Translate('General_Required', Piwik_Translate('Login_Password')));
+ $password = $this->addElement('password', 'form_password');
+ $password->addRule('required', Piwik_Translate('General_Required', Piwik_Translate('Login_Password')));
- $passwordBis = $this->addElement('password', 'form_password_bis');
- $passwordBis->addRule('required', Piwik_Translate('General_Required', Piwik_Translate('Login_PasswordRepeat')));
- $passwordBis->addRule('eq', Piwik_Translate( 'Login_PasswordsDoNotMatch'), $password);
+ $passwordBis = $this->addElement('password', 'form_password_bis');
+ $passwordBis->addRule('required', Piwik_Translate('General_Required', Piwik_Translate('Login_PasswordRepeat')));
+ $passwordBis->addRule('eq', Piwik_Translate('Login_PasswordsDoNotMatch'), $password);
- $this->addElement('hidden', 'form_nonce');
+ $this->addElement('hidden', 'form_nonce');
- $this->addElement('submit', 'submit');
- }
+ $this->addElement('submit', 'submit');
+ }
}
diff --git a/plugins/Login/Login.php b/plugins/Login/Login.php
index e56c4560e2..5b92eaca87 100644
--- a/plugins/Login/Login.php
+++ b/plugins/Login/Login.php
@@ -15,183 +15,180 @@
*/
class Piwik_Login extends Piwik_Plugin
{
- public function getInformation()
- {
- $info = array(
- 'description' => Piwik_Translate('Login_PluginDescription'),
- 'author' => 'Piwik',
- 'author_homepage' => 'http://piwik.org/',
- 'version' => Piwik_Version::VERSION,
- );
- return $info;
- }
-
- function getListHooksRegistered()
- {
- $hooks = array(
- 'FrontController.initAuthenticationObject' => 'initAuthenticationObject',
- 'FrontController.NoAccessException' => 'noAccess',
- 'API.Request.authenticate' => 'ApiRequestAuthenticate',
- 'Login.initSession' => 'initSession',
- );
- return $hooks;
- }
-
- /**
- * Redirects to Login form with error message.
- * Listens to FrontController.NoAccessException hook.
- *
- * @param Piwik_Event_Notification $notification notification object
- */
- function noAccess( $notification )
- {
- /* @var Exception $exception */
- $exception = $notification->getNotificationObject();
- $exceptionMessage = $exception->getMessage();
-
- $controller = new Piwik_Login_Controller();
- $controller->login($exceptionMessage, '' /* $exception->getTraceAsString() */ );
- }
-
- /**
- * Set login name and autehntication token for authentication request.
- * Listens to API.Request.authenticate hook.
- *
- * @param Piwik_Event_Notification $notification notification object
- */
- function ApiRequestAuthenticate($notification)
- {
- $tokenAuth = $notification->getNotificationObject();
- Zend_Registry::get('auth')->setLogin($login = null);
- Zend_Registry::get('auth')->setTokenAuth($tokenAuth);
- }
-
- /**
- * Initializes the authentication object.
- * Listens to FrontController.initAuthenticationObject hook.
- *
- * @param Piwik_Event_Notification $notification notification object
- */
- function initAuthenticationObject($notification)
- {
- $auth = new Piwik_Login_Auth();
- Zend_Registry::set('auth', $auth);
-
- $allowCookieAuthentication = $notification->getNotificationInfo();
-
- $action = Piwik::getAction();
- if (Piwik::getModule() === 'API'
- && (empty($action) || $action == 'index')
- && $allowCookieAuthentication !== true)
- {
- return;
- }
-
- $authCookieName = Piwik_Config::getInstance()->General['login_cookie_name'];
- $authCookieExpiry = 0;
- $authCookiePath = Piwik_Config::getInstance()->General['login_cookie_path'];
- $authCookie = new Piwik_Cookie($authCookieName, $authCookieExpiry, $authCookiePath);
- $defaultLogin = 'anonymous';
- $defaultTokenAuth = 'anonymous';
- if($authCookie->isCookieFound())
- {
- $defaultLogin = $authCookie->get('login');
- $defaultTokenAuth = $authCookie->get('token_auth');
- }
- $auth->setLogin($defaultLogin);
- $auth->setTokenAuth($defaultTokenAuth);
- }
-
- /**
- * Authenticate user and initializes the session.
- * Listens to Login.initSession hook.
- *
- * @param Piwik_Event_Notification $notification notification object
- * @throws Exception
- */
- function initSession($notification)
- {
- $info = $notification->getNotificationObject();
- $login = $info['login'];
- $md5Password = $info['md5Password'];
- $rememberMe = $info['rememberMe'];
-
- $tokenAuth = Piwik_UsersManager_API::getInstance()->getTokenAuth($login, $md5Password);
-
- $auth = Zend_Registry::get('auth');
- $auth->setLogin($login);
- $auth->setTokenAuth($tokenAuth);
- $authResult = $auth->authenticate();
-
- $authCookieName = Piwik_Config::getInstance()->General['login_cookie_name'];
- $authCookieExpiry = $rememberMe ? time() + Piwik_Config::getInstance()->General['login_cookie_expire'] : 0;
- $authCookiePath = Piwik_Config::getInstance()->General['login_cookie_path'];
- $cookie = new Piwik_Cookie($authCookieName, $authCookieExpiry, $authCookiePath);
- if(!$authResult->isValid())
-
- {
- $cookie->delete();
- throw new Exception(Piwik_Translate('Login_LoginPasswordNotCorrect'));
- }
-
- $cookie->set('login', $login);
- $cookie->set('token_auth', $auth->getHashTokenAuth($login, $authResult->getTokenAuth()));
- $cookie->setSecure(Piwik::isHttps());
- $cookie->setHttpOnly(true);
- $cookie->save();
-
- @Piwik_Session::regenerateId();
-
- // remove password reset entry if it exists
- self::removePasswordResetInfo($login);
- }
-
- /**
- * Stores password reset info for a specific login.
- *
- * @param string $login The user login for whom a password change was requested.
- * @param string $password The new password to set.
- */
- public static function savePasswordResetInfo( $login, $password )
- {
- $optionName = self::getPasswordResetInfoOptionName($login);
- $optionData = Piwik_UsersManager::getPasswordHash($password);
-
- Piwik_SetOption($optionName, $optionData);
- }
-
- /**
- * Removes stored password reset info if it exists.
- *
- * @param string $login The user login to check for.
- */
- public static function removePasswordResetInfo( $login )
- {
- $optionName = self::getPasswordResetInfoOptionName($login);
- Piwik_Option::getInstance()->delete($optionName);
- }
-
- /**
- * Gets password hash stored in password reset info.
- *
- * @param string $login The user login to check for.
- * @return string|false The hashed password or false if no reset info exists.
- */
- public static function getPasswordToResetTo( $login )
- {
- $optionName = self::getPasswordResetInfoOptionName($login);
- return Piwik_GetOption($optionName);
- }
-
- /**
- * Gets the option name for the option that will store a user's password change
- * request.
- *
- * @param string $login The user login for whom a password change was requested.
- * @return string
- */
- public static function getPasswordResetInfoOptionName( $login )
- {
- return $login.'_reset_password_info';
- }
+ public function getInformation()
+ {
+ $info = array(
+ 'description' => Piwik_Translate('Login_PluginDescription'),
+ 'author' => 'Piwik',
+ 'author_homepage' => 'http://piwik.org/',
+ 'version' => Piwik_Version::VERSION,
+ );
+ return $info;
+ }
+
+ function getListHooksRegistered()
+ {
+ $hooks = array(
+ 'FrontController.initAuthenticationObject' => 'initAuthenticationObject',
+ 'FrontController.NoAccessException' => 'noAccess',
+ 'API.Request.authenticate' => 'ApiRequestAuthenticate',
+ 'Login.initSession' => 'initSession',
+ );
+ return $hooks;
+ }
+
+ /**
+ * Redirects to Login form with error message.
+ * Listens to FrontController.NoAccessException hook.
+ *
+ * @param Piwik_Event_Notification $notification notification object
+ */
+ function noAccess($notification)
+ {
+ /* @var Exception $exception */
+ $exception = $notification->getNotificationObject();
+ $exceptionMessage = $exception->getMessage();
+
+ $controller = new Piwik_Login_Controller();
+ $controller->login($exceptionMessage, '' /* $exception->getTraceAsString() */);
+ }
+
+ /**
+ * Set login name and autehntication token for authentication request.
+ * Listens to API.Request.authenticate hook.
+ *
+ * @param Piwik_Event_Notification $notification notification object
+ */
+ function ApiRequestAuthenticate($notification)
+ {
+ $tokenAuth = $notification->getNotificationObject();
+ Zend_Registry::get('auth')->setLogin($login = null);
+ Zend_Registry::get('auth')->setTokenAuth($tokenAuth);
+ }
+
+ /**
+ * Initializes the authentication object.
+ * Listens to FrontController.initAuthenticationObject hook.
+ *
+ * @param Piwik_Event_Notification $notification notification object
+ */
+ function initAuthenticationObject($notification)
+ {
+ $auth = new Piwik_Login_Auth();
+ Zend_Registry::set('auth', $auth);
+
+ $allowCookieAuthentication = $notification->getNotificationInfo();
+
+ $action = Piwik::getAction();
+ if (Piwik::getModule() === 'API'
+ && (empty($action) || $action == 'index')
+ && $allowCookieAuthentication !== true
+ ) {
+ return;
+ }
+
+ $authCookieName = Piwik_Config::getInstance()->General['login_cookie_name'];
+ $authCookieExpiry = 0;
+ $authCookiePath = Piwik_Config::getInstance()->General['login_cookie_path'];
+ $authCookie = new Piwik_Cookie($authCookieName, $authCookieExpiry, $authCookiePath);
+ $defaultLogin = 'anonymous';
+ $defaultTokenAuth = 'anonymous';
+ if ($authCookie->isCookieFound()) {
+ $defaultLogin = $authCookie->get('login');
+ $defaultTokenAuth = $authCookie->get('token_auth');
+ }
+ $auth->setLogin($defaultLogin);
+ $auth->setTokenAuth($defaultTokenAuth);
+ }
+
+ /**
+ * Authenticate user and initializes the session.
+ * Listens to Login.initSession hook.
+ *
+ * @param Piwik_Event_Notification $notification notification object
+ * @throws Exception
+ */
+ function initSession($notification)
+ {
+ $info = $notification->getNotificationObject();
+ $login = $info['login'];
+ $md5Password = $info['md5Password'];
+ $rememberMe = $info['rememberMe'];
+
+ $tokenAuth = Piwik_UsersManager_API::getInstance()->getTokenAuth($login, $md5Password);
+
+ $auth = Zend_Registry::get('auth');
+ $auth->setLogin($login);
+ $auth->setTokenAuth($tokenAuth);
+ $authResult = $auth->authenticate();
+
+ $authCookieName = Piwik_Config::getInstance()->General['login_cookie_name'];
+ $authCookieExpiry = $rememberMe ? time() + Piwik_Config::getInstance()->General['login_cookie_expire'] : 0;
+ $authCookiePath = Piwik_Config::getInstance()->General['login_cookie_path'];
+ $cookie = new Piwik_Cookie($authCookieName, $authCookieExpiry, $authCookiePath);
+ if (!$authResult->isValid()) {
+ $cookie->delete();
+ throw new Exception(Piwik_Translate('Login_LoginPasswordNotCorrect'));
+ }
+
+ $cookie->set('login', $login);
+ $cookie->set('token_auth', $auth->getHashTokenAuth($login, $authResult->getTokenAuth()));
+ $cookie->setSecure(Piwik::isHttps());
+ $cookie->setHttpOnly(true);
+ $cookie->save();
+
+ @Piwik_Session::regenerateId();
+
+ // remove password reset entry if it exists
+ self::removePasswordResetInfo($login);
+ }
+
+ /**
+ * Stores password reset info for a specific login.
+ *
+ * @param string $login The user login for whom a password change was requested.
+ * @param string $password The new password to set.
+ */
+ public static function savePasswordResetInfo($login, $password)
+ {
+ $optionName = self::getPasswordResetInfoOptionName($login);
+ $optionData = Piwik_UsersManager::getPasswordHash($password);
+
+ Piwik_SetOption($optionName, $optionData);
+ }
+
+ /**
+ * Removes stored password reset info if it exists.
+ *
+ * @param string $login The user login to check for.
+ */
+ public static function removePasswordResetInfo($login)
+ {
+ $optionName = self::getPasswordResetInfoOptionName($login);
+ Piwik_Option::getInstance()->delete($optionName);
+ }
+
+ /**
+ * Gets password hash stored in password reset info.
+ *
+ * @param string $login The user login to check for.
+ * @return string|false The hashed password or false if no reset info exists.
+ */
+ public static function getPasswordToResetTo($login)
+ {
+ $optionName = self::getPasswordResetInfoOptionName($login);
+ return Piwik_GetOption($optionName);
+ }
+
+ /**
+ * Gets the option name for the option that will store a user's password change
+ * request.
+ *
+ * @param string $login The user login for whom a password change was requested.
+ * @return string
+ */
+ public static function getPasswordResetInfoOptionName($login)
+ {
+ return $login . '_reset_password_info';
+ }
}
diff --git a/plugins/Login/templates/header.tpl b/plugins/Login/templates/header.tpl
index 6b27f66710..e4e1919633 100644
--- a/plugins/Login/templates/header.tpl
+++ b/plugins/Login/templates/header.tpl
@@ -1,60 +1,64 @@
<!DOCTYPE html>
-<!--[if lt IE 9 ]><html class="old-ie"> <![endif]-->
-<!--[if (gte IE 9)|!(IE)]><!--><html><!--<![endif]-->
+<!--[if lt IE 9 ]>
+<html class="old-ie"> <![endif]-->
+<!--[if (gte IE 9)|!(IE)]><!-->
+<html><!--<![endif]-->
<head>
- <title>{if !$isCustomLogo}Piwik &rsaquo; {/if}{'Login_LogIn'|translate}</title>
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
- <link rel="shortcut icon" href="plugins/CoreHome/templates/images/favicon.ico" />
- <link rel="stylesheet" type="text/css" href="plugins/Login/templates/login.css" />
- <meta name="description" content="{'General_OpenSourceWebAnalytics'|translate|escape}" />
- <!--[if lt IE 9]>
- <script src="libs/html5shiv/html5shiv.js"></script>
- <![endif]-->
- <script type="text/javascript" src="libs/jquery/jquery.js"></script>
- <script type="text/javascript" src="libs/jquery/jquery.placeholder.js"></script>
-{if isset($forceSslLogin) && $forceSslLogin}
-{literal}
- <script type="text/javascript">
- if(window.location.protocol !== 'https:') {
- var url = window.location.toString();
- url = url.replace(/^http:/, 'https:');
- window.location.replace(url);
- }
- </script>
-{/literal}
-{/if}
-{literal}
- <script type="text/javascript">
- $(function() {
- $('#form_login').focus();
- $('input').placeholder();
- });
- </script>
-{/literal}
- <script type="text/javascript" src="plugins/Login/templates/login.js"></script>
-{if 'General_LayoutDirection'|translate =='rtl'}
-<link rel="stylesheet" type="text/css" href="themes/default/rtl.css" />
-{/if}
-{include file="CoreHome/templates/iframe_buster_header.tpl"}
+ <title>{if !$isCustomLogo}Piwik &rsaquo; {/if}{'Login_LogIn'|translate}</title>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
+ <link rel="shortcut icon" href="plugins/CoreHome/templates/images/favicon.ico"/>
+ <link rel="stylesheet" type="text/css" href="plugins/Login/templates/login.css"/>
+ <meta name="description" content="{'General_OpenSourceWebAnalytics'|translate|escape}"/>
+ <!--[if lt IE 9]>
+ <script src="libs/html5shiv/html5shiv.js"></script>
+ <![endif]-->
+ <script type="text/javascript" src="libs/jquery/jquery.js"></script>
+ <script type="text/javascript" src="libs/jquery/jquery.placeholder.js"></script>
+ {if isset($forceSslLogin) && $forceSslLogin}
+ {literal}
+ <script type="text/javascript">
+ if (window.location.protocol !== 'https:') {
+ var url = window.location.toString();
+ url = url.replace(/^http:/, 'https:');
+ window.location.replace(url);
+ }
+ </script>
+ {/literal}
+ {/if}
+ {literal}
+ <script type="text/javascript">
+ $(function () {
+ $('#form_login').focus();
+ $('input').placeholder();
+ });
+ </script>
+ {/literal}
+ <script type="text/javascript" src="plugins/Login/templates/login.js"></script>
+ {if 'General_LayoutDirection'|translate =='rtl'}
+ <link rel="stylesheet" type="text/css" href="themes/default/rtl.css"/>
+ {/if}
+ {include file="CoreHome/templates/iframe_buster_header.tpl"}
</head>
<body class="login">
{include file="CoreHome/templates/iframe_buster_body.tpl"}
- <div id="logo">
- {if !$isCustomLogo}<a href="http://piwik.org" title="{$linkTitle}">{/if}
- {if $hasSVGLogo}
- <img src='{$logoSVG}' title="{$linkTitle}" alt="Piwik" width="240" style='margin-right: 20px' class="ie-hide" />
- <!--[if lt IE 9]>
- {/if}
- <img src='{$logoLarge}' title="{$linkTitle}" alt="Piwik" width="240" style='margin-right:20px' />
- {if $hasSVGLogo}<![endif]-->{/if}
- {if $isCustomLogo}
- {capture name='poweredByPiwik'}
- <i><a href="http://piwik.org/" target="_blank">{$linkTitle}</a></i>
- {/capture}
- {/if}
- {if !$isCustomLogo}</a>
- <div class="description"><a href="http://piwik.org" title="{$linkTitle}">{$linkTitle}</a>
- <div class="arrow"> </div>
- </div>
- {/if}
- </div>
+<div id="logo">
+ {if !$isCustomLogo}<a href="http://piwik.org" title="{$linkTitle}">{/if}
+ {if $hasSVGLogo}
+ <img src='{$logoSVG}' title="{$linkTitle}" alt="Piwik" width="240" style='margin-right: 20px' class="ie-hide"/>
+ <!--[if lt IE 9]>
+ {/if}
+ <img src='{$logoLarge}' title="{$linkTitle}" alt="Piwik" width="240" style='margin-right:20px'/>
+ {if $hasSVGLogo}<![endif]-->{/if}
+ {if $isCustomLogo}
+ {capture name='poweredByPiwik'}
+ <i><a href="http://piwik.org/" target="_blank">{$linkTitle}</a></i>
+ {/capture}
+ {/if}
+ {if !$isCustomLogo}</a>
+
+ <div class="description"><a href="http://piwik.org" title="{$linkTitle}">{$linkTitle}</a>
+
+ <div class="arrow"></div>
+ </div>
+ {/if}
+</div>
diff --git a/plugins/Login/templates/login.css b/plugins/Login/templates/login.css
index d8c3f3d87f..7d62cea47a 100644
--- a/plugins/Login/templates/login.css
+++ b/plugins/Login/templates/login.css
@@ -1,227 +1,224 @@
/* shamelessly taken from wordpress 2.5 - thank you guys!!! */
* {
- margin: 0;
- padding: 0;
+ margin: 0;
+ padding: 0;
}
body {
- font: 12px "Lucida Grande", "Lucida Sans Unicode", Tahoma, Verdana, sans-serif;
+ font: 12px "Lucida Grande", "Lucida Sans Unicode", Tahoma, Verdana, sans-serif;
}
form {
- padding: 16px 16px 16px 16px;
- border-radius: 5px;
+ padding: 16px 16px 16px 16px;
+ border-radius: 5px;
}
#login form input.submit {
- font-family: "Lucida Grande", "Lucida Sans Unicode", Tahoma, Verdana, sans-serif;
- -moz-border-radius: 3px;
- -webkit-border-radius: 3px;
- float: right;
- height: 35px;
- padding: 0 20px;
- cursor: pointer;
- font: bold 15px Arial, Helvetica;
+ font-family: "Lucida Grande", "Lucida Sans Unicode", Tahoma, Verdana, sans-serif;
+ -moz-border-radius: 3px;
+ -webkit-border-radius: 3px;
+ float: right;
+ height: 35px;
+ padding: 0 20px;
+ cursor: pointer;
+ font: bold 15px Arial, Helvetica;
}
#login form div {
- margin-bottom: 24px;
+ margin-bottom: 24px;
}
-.updated,.login #login_error,.login .message {
- background-color: #ffffe0;
- border-color: #e6db55;
- margin: 0 auto;
- width: 330px;
+.updated, .login #login_error, .login .message {
+ background-color: #ffffe0;
+ border-color: #e6db55;
+ margin: 0 auto;
+ width: 330px;
}
#login fieldset {
- border: 0;
+ border: 0;
}
#login fieldset.actions {
- line-height: 35px;
- width: 315px;
- margin-top: 10px;
-}
-
-#login h1
-{
- text-align: center;
- color: #666;
- margin: 0 0 30px 0;
- font: normal 26px/1 Verdana, Helvetica;
- position: relative;
-}
-
-#login
-{
- background-color: #fafafa;
- width: 360px;
- padding: 30px;
- margin: 50px auto 0 auto;
- z-index: 0;
- -moz-border-radius: 3px;
- -webkit-border-radius: 3px;
- border-radius: 3px;
- -webkit-box-shadow:
- 0 0 2px rgba(0, 0, 0, 0.2),
- 0 1px 1px rgba(0, 0, 0, .2);
- -moz-box-shadow:
- 0 0 2px rgba(0, 0, 0, 0.2),
- 1px 1px 0 rgba(0, 0, 0, .1);
- box-shadow:
- 0 0 2px rgba(0, 0, 0, 0.2),
- 0 1px 1px rgba(0, 0, 0, .2);
-}
-
-#login form { margin: 0 5px; position: relative; }
+ line-height: 35px;
+ width: 315px;
+ margin-top: 10px;
+}
+
+#login h1 {
+ text-align: center;
+ color: #666;
+ margin: 0 0 30px 0;
+ font: normal 26px/1 Verdana, Helvetica;
+ position: relative;
+}
+
+#login {
+ background-color: #fafafa;
+ width: 360px;
+ padding: 30px;
+ margin: 50px auto 0 auto;
+ z-index: 0;
+ -moz-border-radius: 3px;
+ -webkit-border-radius: 3px;
+ border-radius: 3px;
+ -webkit-box-shadow: 0 0 2px rgba(0, 0, 0, 0.2), 0 1px 1px rgba(0, 0, 0, .2);
+ -moz-box-shadow: 0 0 2px rgba(0, 0, 0, 0.2), 1px 1px 0 rgba(0, 0, 0, .1);
+ box-shadow: 0 0 2px rgba(0, 0, 0, 0.2), 0 1px 1px rgba(0, 0, 0, .2);
+}
+
+#login form {
+ margin: 0 5px;
+ position: relative;
+}
+
#login form input[type="text"],
#login form input[type="password"] {
- padding: 10px 15px 10px 45px;
- margin: 0 0 15px 0;
- width: 253px; /* 258 + 2 + 55 = 315 */
- border: 1px solid #ccc;
- -moz-border-radius: 5px;
- -webkit-border-radius: 5px;
- border-radius: 5px;
- -moz-box-shadow: 0 1px 1px #ccc inset, 0 1px 0 #fff;
- -webkit-box-shadow: 0 1px 1px #ccc inset, 0 1px 0 #fff;
- box-shadow: 0 1px 1px #ccc inset, 0 1px 0 #fff;
+ padding: 10px 15px 10px 45px;
+ margin: 0 0 15px 0;
+ width: 253px; /* 258 + 2 + 55 = 315 */
+ border: 1px solid #ccc;
+ -moz-border-radius: 5px;
+ -webkit-border-radius: 5px;
+ border-radius: 5px;
+ -moz-box-shadow: 0 1px 1px #ccc inset, 0 1px 0 #fff;
+ -webkit-box-shadow: 0 1px 1px #ccc inset, 0 1px 0 #fff;
+ box-shadow: 0 1px 1px #ccc inset, 0 1px 0 #fff;
}
#login_form_rememberme {
- vertical-align: middle;
+ vertical-align: middle;
}
-#login_error,.message {
- margin: 0 0 16px 8px;
- border: 1px solid;
- padding: 12px;
+#login_error, .message {
+ margin: 0 0 16px 8px;
+ border: 1px solid;
+ padding: 12px;
}
#nav, #piwik {
- margin: 0 0 0 8px;
- padding: 16px;
+ margin: 0 0 0 8px;
+ padding: 16px;
}
#nav {
- text-align: center;
+ text-align: center;
}
#nav a:hover {
- text-decoration: underline;
+ text-decoration: underline;
}
-#login_form_password, #reset_form_password,
+#login_form_password, #reset_form_password,
#reset_form_password_bis, #login_form_login, #reset_form_login {
- background: #fff url(../../../themes/default/images/login-sprite.png) no-repeat;
+ background: #fff url(../../../themes/default/images/login-sprite.png) no-repeat;
}
#login_form_password, #reset_form_password, #reset_form_password_bis {
- background-position: 10px -51px !important;
+ background-position: 10px -51px !important;
}
#login_form_login, #reset_form_login {
- background-position: 10px 11px !important;
+ background-position: 10px 11px !important;
}
-#login_form_password,#reset_form_password,#reset_form_password_bis,
-#login_form_login,#reset_form_login {
- font-size: 20px;
- width: 97%;
- padding: 3px;
- margin-right: 6px;
+#login_form_password, #reset_form_password, #reset_form_password_bis,
+#login_form_login, #reset_form_login {
+ font-size: 20px;
+ width: 97%;
+ padding: 3px;
+ margin-right: 6px;
}
#login #login_error {
- background-color: #ffebe8;
- border-color: #c00;
+ background-color: #ffebe8;
+ border-color: #c00;
}
#login form input.submit {
- background-color: #e5e5e5;
+ background-color: #e5e5e5;
}
#login form input.submit:hover {
- background-color: #eee;
+ background-color: #eee;
}
.login #login_error {
- background-color: #ffffe0;
- border-color: #e6db55;
+ background-color: #ffffe0;
+ border-color: #e6db55;
}
.login #nav a {
- color: #777;
+ color: #777;
}
+
.login #piwik a {
- color: #CDCDCD;
+ color: #CDCDCD;
}
body.login {
- border-top-color: #464646;
+ border-top-color: #464646;
}
#login form input {
- color: #555;
+ color: #555;
}
a {
- text-decoration: none;
+ text-decoration: none;
}
#logo {
- margin: 100px auto 0 auto;
- width: 240px;
- position: relative;
+ margin: 100px auto 0 auto;
+ width: 240px;
+ position: relative;
}
#logo .description a {
- font:16px/16px 'Patrick Hand';
- color:#666666;
- right: auto;
- text-decoration: none;
+ font: 16px/16px 'Patrick Hand';
+ color: #666666;
+ right: auto;
+ text-decoration: none;
}
#logo .description {
- position: absolute;
- left: -40px !important;
- top: -30px !important;
- -webkit-transform:rotate(-6deg);
- -moz-transform:rotate(-6deg);
- -ms-transform:rotate(-6deg);
- -o-transform:rotate(-6deg);
+ position: absolute;
+ left: -40px !important;
+ top: -30px !important;
+ -webkit-transform: rotate(-6deg);
+ -moz-transform: rotate(-6deg);
+ -ms-transform: rotate(-6deg);
+ -o-transform: rotate(-6deg);
}
#logo .description .arrow {
- background:url(../../../themes/default/images/affix-arrow.png);
- width:50px;
- height:68px;
- position:absolute;
- left:-35px;
+ background: url(../../../themes/default/images/affix-arrow.png);
+ width: 50px;
+ height: 68px;
+ position: absolute;
+ left: -35px;
}
#logo img {
- border:0;
- vertical-align: bottom;
- width: 260px;
+ border: 0;
+ vertical-align: bottom;
+ width: 260px;
}
#logo .h1 {
- font-family: Georgia, "Times New Roman", Times, serif;
- font-weight: normal;
- color: #136F8B;
- font-size: 45pt;
- text-transform: none;
+ font-family: Georgia, "Times New Roman", Times, serif;
+ font-weight: normal;
+ color: #136F8B;
+ font-size: 45pt;
+ text-transform: none;
}
.loadingPiwik {
- float: left;
- margin-left: 16px;
+ float: left;
+ margin-left: 16px;
}
/* IE < 9 will use this */
-html.old-ie .ie-hide {
- display: none;
+html.old-ie .ie-hide {
+ display: none;
}
diff --git a/plugins/Login/templates/login.js b/plugins/Login/templates/login.js
index 28171b47ab..5458942fef 100755
--- a/plugins/Login/templates/login.js
+++ b/plugins/Login/templates/login.js
@@ -4,104 +4,97 @@
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*/
-(function($) {
-
-$(document).ready(function() {
- var switchForm = function(fromFormId, toFormId, message, callback) {
- var fromLoginInputId = '#'+fromFormId+'_login',
- toLoginInputId = '#'+toFormId+'_login',
- toPasswordInputId = '#'+toFormId+'_password',
- fromLoginNavId = '#'+fromFormId+'_nav',
- toLoginNavId = '#'+toFormId+'_nav';
-
- if ($(toLoginInputId).val() === '')
- {
- $(toLoginInputId).val($(fromLoginInputId).val());
- }
-
- // hide the bottom portion of the login screen & show the password reset bits
- $('#'+fromFormId+',#message_container').fadeOut(500, function() {
- // show lost password instructions
- $('#message_container').html(message);
-
- $(fromLoginNavId).hide();
- $(toLoginNavId).show();
- $('#'+toFormId+',#message_container').fadeIn(500, function() {
- // focus on login or password control based on whether a login exists
- if ($(toLoginInputId).val() === '')
- {
- $(toLoginInputId).focus();
- }
- else
- {
- $(toPasswordInputId).focus();
- }
-
- if (callback)
- {
- callback();
- }
- });
- });
- };
-
- // 'lost your password?' on click
- $('#login_form_nav').click(function(e) {
- e.preventDefault();
- switchForm('login_form', 'reset_form', $('#lost_password_instructions').html());
- return false;
- });
-
- // 'cancel' on click
- $('#reset_form_nav,#alternate_reset_nav').click(function(e) {
- e.preventDefault();
- $('#alternate_reset_nav').hide();
- switchForm('reset_form', 'login_form', '');
- return false;
- });
-
- // password reset on submit
- $('#reset_form_submit').click(function(e) {
- e.preventDefault();
-
- var ajaxDone = function(response)
- {
- $('.loadingPiwik').hide();
-
- var isSuccess = response.indexOf('id="login_error"') === -1,
- fadeOutIds = '#message_container';
- if (isSuccess)
- {
- fadeOutIds += ',#reset_form,#reset_form_nav';
- }
-
- $(fadeOutIds).fadeOut(300, function() {
- if (isSuccess)
- {
- $('#alternate_reset_nav').show();
- }
-
- $('#message_container').html(response).fadeIn(300);
- });
- };
-
- $('.loadingPiwik').show();
-
- // perform reset password request
- $.ajax({
- type: 'POST',
- url: 'index.php',
- dataType: 'html',
- async: true,
- error: function() { ajaxDone('<div id="login_error"><strong>HTTP Error</strong></div>'); },
- success: ajaxDone, // Callback when the request succeeds
- data: $('#reset_form').serialize()
- });
-
- return false;
- });
-
- $('#login_form_login').focus();
-});
+(function ($) {
+
+ $(document).ready(function () {
+ var switchForm = function (fromFormId, toFormId, message, callback) {
+ var fromLoginInputId = '#' + fromFormId + '_login',
+ toLoginInputId = '#' + toFormId + '_login',
+ toPasswordInputId = '#' + toFormId + '_password',
+ fromLoginNavId = '#' + fromFormId + '_nav',
+ toLoginNavId = '#' + toFormId + '_nav';
+
+ if ($(toLoginInputId).val() === '') {
+ $(toLoginInputId).val($(fromLoginInputId).val());
+ }
+
+ // hide the bottom portion of the login screen & show the password reset bits
+ $('#' + fromFormId + ',#message_container').fadeOut(500, function () {
+ // show lost password instructions
+ $('#message_container').html(message);
+
+ $(fromLoginNavId).hide();
+ $(toLoginNavId).show();
+ $('#' + toFormId + ',#message_container').fadeIn(500, function () {
+ // focus on login or password control based on whether a login exists
+ if ($(toLoginInputId).val() === '') {
+ $(toLoginInputId).focus();
+ }
+ else {
+ $(toPasswordInputId).focus();
+ }
+
+ if (callback) {
+ callback();
+ }
+ });
+ });
+ };
+
+ // 'lost your password?' on click
+ $('#login_form_nav').click(function (e) {
+ e.preventDefault();
+ switchForm('login_form', 'reset_form', $('#lost_password_instructions').html());
+ return false;
+ });
+
+ // 'cancel' on click
+ $('#reset_form_nav,#alternate_reset_nav').click(function (e) {
+ e.preventDefault();
+ $('#alternate_reset_nav').hide();
+ switchForm('reset_form', 'login_form', '');
+ return false;
+ });
+
+ // password reset on submit
+ $('#reset_form_submit').click(function (e) {
+ e.preventDefault();
+
+ var ajaxDone = function (response) {
+ $('.loadingPiwik').hide();
+
+ var isSuccess = response.indexOf('id="login_error"') === -1,
+ fadeOutIds = '#message_container';
+ if (isSuccess) {
+ fadeOutIds += ',#reset_form,#reset_form_nav';
+ }
+
+ $(fadeOutIds).fadeOut(300, function () {
+ if (isSuccess) {
+ $('#alternate_reset_nav').show();
+ }
+
+ $('#message_container').html(response).fadeIn(300);
+ });
+ };
+
+ $('.loadingPiwik').show();
+
+ // perform reset password request
+ $.ajax({
+ type: 'POST',
+ url: 'index.php',
+ dataType: 'html',
+ async: true,
+ error: function () { ajaxDone('<div id="login_error"><strong>HTTP Error</strong></div>'); },
+ success: ajaxDone, // Callback when the request succeeds
+ data: $('#reset_form').serialize()
+ });
+
+ return false;
+ });
+
+ $('#login_form_login').focus();
+ });
}(jQuery));
diff --git a/plugins/Login/templates/login.tpl b/plugins/Login/templates/login.tpl
index 956f8d4bc8..ad85960ec5 100644
--- a/plugins/Login/templates/login.tpl
+++ b/plugins/Login/templates/login.tpl
@@ -2,84 +2,89 @@
<section id="login">
-{* untrusted host warning *}
-{if isset($isValidHost) && isset($invalidHostMessage) && !$isValidHost}
-<div id="login_error">
- <strong>{'General_Warning'|translate}:&nbsp;</strong>{$invalidHostMessage}
+ {* untrusted host warning *}
+ {if isset($isValidHost) && isset($invalidHostMessage) && !$isValidHost}
+ <div id="login_error">
+ <strong>{'General_Warning'|translate}:&nbsp;</strong>{$invalidHostMessage}
- <br><br>{$invalidHostMessageHowToFix}
- <br/><br/><a style="float:right" href="http://piwik.org/faq/troubleshooting/#faq_171" target="_blank">{'General_Help'|translate} <img style='vertical-align: bottom' src="themes/default/images/help_grey.png" /></a><br/>
+ <br><br>{$invalidHostMessageHowToFix}
+ <br/><br/><a style="float:right" href="http://piwik.org/faq/troubleshooting/#faq_171" target="_blank">{'General_Help'|translate} <img
+ style='vertical-align: bottom' src="themes/default/images/help_grey.png"/></a><br/>
-</div>
-{else}
-<div id="message_container">
- {if $form_data.errors}
- <div id="login_error">
- {foreach from=$form_data.errors item=data}
- <strong>{'General_Error'|translate}</strong>: {$data}<br />
- {/foreach}
- </div>
- {/if}
+ </div>
+ {else}
+ <div id="message_container">
+ {if $form_data.errors}
+ <div id="login_error">
+ {foreach from=$form_data.errors item=data}
+ <strong>{'General_Error'|translate}</strong>
+ : {$data}
+ <br/>
+ {/foreach}
+ </div>
+ {/if}
- {if $AccessErrorString}
- <div id="login_error"><strong>{'General_Error'|translate}</strong>: {$AccessErrorString}<br /></div>
- {/if}
+ {if $AccessErrorString}
+ <div id="login_error"><strong>{'General_Error'|translate}</strong>: {$AccessErrorString}<br/></div>
+ {/if}
- {if $infoMessage}
- <p class="message">{$infoMessage}</p>
- {/if}
-</div>
+ {if $infoMessage}
+ <p class="message">{$infoMessage}</p>
+ {/if}
+ </div>
+ <form {$form_data.attributes}>
+ <h1>{'Login_LogIn'|translate}</h1>
+ <fieldset class="inputs">
+ <input type="text" name="form_login" id="login_form_login" class="input" value="" size="20" tabindex="10"
+ placeholder="{'General_Username'|translate}" autofocus="autofocus"/>
+ <input type="password" name="form_password" id="login_form_password" class="input" value="" size="20" tabindex="20"
+ placeholder="{'Login_Password'|translate}"/>
+ <input type="hidden" name="form_nonce" id="login_form_nonce" value="{$nonce}"/>
+ </fieldset>
-<form {$form_data.attributes}>
- <h1>{'Login_LogIn'|translate}</h1>
- <fieldset class="inputs">
- <input type="text" name="form_login" id="login_form_login" class="input" value="" size="20" tabindex="10" placeholder="{'General_Username'|translate}" autofocus="autofocus" />
- <input type="password" name="form_password" id="login_form_password" class="input" value="" size="20" tabindex="20" placeholder="{'Login_Password'|translate}" />
- <input type="hidden" name="form_nonce" id="login_form_nonce" value="{$nonce}" />
- </fieldset>
+ <fieldset class="actions">
+ <input name="form_rememberme" type="checkbox" id="login_form_rememberme" value="1" tabindex="90"
+ {if $form_data.form_rememberme.value}checked="checked" {/if}/>
+ <label for="login_form_rememberme">{'Login_RememberMe'|translate}</label>
+ <input class="submit" id='login_form_submit' type="submit" value="{'Login_LogIn'|translate}" tabindex="100"/>
+ </fieldset>
+ </form>
+ <form id="reset_form" style="display:none;">
+ <fieldset class="inputs">
+ <input type="text" name="form_login" id="reset_form_login" class="input" value="" size="20" tabindex="10"
+ placeholder="{'Login_LoginOrEmail'|translate}"/>
+ <input type="hidden" name="form_nonce" id="reset_form_nonce" value="{$nonce}"/>
- <fieldset class="actions">
- <input name="form_rememberme" type="checkbox" id="login_form_rememberme" value="1" tabindex="90" {if $form_data.form_rememberme.value}checked="checked" {/if}/>
- <label for="login_form_rememberme">{'Login_RememberMe'|translate}</label>
- <input class="submit" id='login_form_submit' type="submit" value="{'Login_LogIn'|translate}" tabindex="100" />
- </fieldset>
-</form>
+ <input type="password" name="form_password" id="reset_form_password" class="input" value="" size="20" tabindex="20"
+ placeholder="{'Login_Password'|translate}"/>
-<form id="reset_form" style="display:none;">
- <fieldset class="inputs">
- <input type="text" name="form_login" id="reset_form_login" class="input" value="" size="20" tabindex="10" placeholder="{'Login_LoginOrEmail'|translate}" />
- <input type="hidden" name="form_nonce" id="reset_form_nonce" value="{$nonce}" />
+ <input type="password" name="form_password_bis" id="reset_form_password_bis" class="input" value="" size="20" tabindex="30"
+ placeholder="{'Login_PasswordRepeat'|translate}"/>
+ </fieldset>
- <input type="password" name="form_password" id="reset_form_password" class="input" value="" size="20" tabindex="20" placeholder="{'Login_Password'|translate}" />
+ <fieldset class="actions">
+ <span class="loadingPiwik" style="display:none;"><img alt="Loading" src="themes/default/images/loading-blue.gif"/></span>
+ <input class="submit" id='reset_form_submit' type="submit" value="{'Login_ChangePassword'|translate}" tabindex="100"/>
+ </fieldset>
- <input type="password" name="form_password_bis" id="reset_form_password_bis" class="input" value="" size="20" tabindex="30" placeholder="{'Login_PasswordRepeat'|translate}" />
- </fieldset>
-
- <fieldset class="actions">
- <span class="loadingPiwik" style="display:none;"><img alt="Loading" src="themes/default/images/loading-blue.gif" /></span>
- <input class="submit" id='reset_form_submit' type="submit" value="{'Login_ChangePassword'|translate}" tabindex="100"/>
- </fieldset>
-
- <input type="hidden" name="module" value="Login"/>
- <input type="hidden" name="action" value="resetPassword"/>
-</form>
-
-<p id="nav">
-<a id="login_form_nav" href="#" title="{'Login_LostYourPassword'|translate}">{'Login_LostYourPassword'|translate}</a>
-<a id="alternate_reset_nav" href="#" style="display:none;" title="{'Login_LogIn'|translate}">{'Login_LogIn'|translate}</a>
-<a id="reset_form_nav" href="#" style="display:none;" title="{'Mobile_NavigationBack'|translate}">{'General_Cancel'|translate}</a>
-</p>
-{if isset($smarty.capture.poweredByPiwik)}
- <p id="piwik">
- {$smarty.capture.poweredByPiwik}
- </p>
-{/if}
-
-<div id="lost_password_instructions" style="display:none;">
- <p class="message">{'Login_ResetPasswordInstructions'|translate}</p>
-</div>
-{/if}
+ <input type="hidden" name="module" value="Login"/>
+ <input type="hidden" name="action" value="resetPassword"/>
+ </form>
+ <p id="nav">
+ <a id="login_form_nav" href="#" title="{'Login_LostYourPassword'|translate}">{'Login_LostYourPassword'|translate}</a>
+ <a id="alternate_reset_nav" href="#" style="display:none;" title="{'Login_LogIn'|translate}">{'Login_LogIn'|translate}</a>
+ <a id="reset_form_nav" href="#" style="display:none;" title="{'Mobile_NavigationBack'|translate}">{'General_Cancel'|translate}</a>
+ </p>
+ {if isset($smarty.capture.poweredByPiwik)}
+ <p id="piwik">
+ {$smarty.capture.poweredByPiwik}
+ </p>
+ {/if}
+ <div id="lost_password_instructions" style="display:none;">
+ <p class="message">{'Login_ResetPasswordInstructions'|translate}</p>
+ </div>
+ {/if}
</section>
</body>
</html>
diff --git a/plugins/Login/templates/message.tpl b/plugins/Login/templates/message.tpl
index 7b85147d8f..ff2e9d21e3 100755
--- a/plugins/Login/templates/message.tpl
+++ b/plugins/Login/templates/message.tpl
@@ -1,11 +1,13 @@
{if isset($infoMessage)}
-<p class="message">{$infoMessage}</p>
+ <p class="message">{$infoMessage}</p>
{/if}
{if isset($formErrors)}
-<p id="login_error">
- {foreach from=$formErrors item=data}
- <strong>{'General_Error'|translate}</strong>: {$data}<br />
- {/foreach}
-</p>
+ <p id="login_error">
+ {foreach from=$formErrors item=data}
+ <strong>{'General_Error'|translate}</strong>
+ : {$data}
+ <br/>
+ {/foreach}
+ </p>
{/if}