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:
Diffstat (limited to 'plugins/Login/Controller.php')
-rw-r--r--plugins/Login/Controller.php257
1 files changed, 151 insertions, 106 deletions
diff --git a/plugins/Login/Controller.php b/plugins/Login/Controller.php
index 98b0dd23e9..08c657827a 100644
--- a/plugins/Login/Controller.php
+++ b/plugins/Login/Controller.php
@@ -1,4 +1,5 @@
<?php
+
/**
* Matomo - free/libre analytics platform
*
@@ -6,6 +7,7 @@
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*
*/
+
namespace Piwik\Plugins\Login;
use Exception;
@@ -13,12 +15,14 @@ use Piwik\Auth\Password;
use Piwik\Common;
use Piwik\Config;
use Piwik\Container\StaticContainer;
+use Piwik\Date;
use Piwik\Log;
use Piwik\Nonce;
use Piwik\Piwik;
use Piwik\Plugins\CoreAdminHome\Emails\UserAcceptInvitationEmail;
use Piwik\Plugins\CoreAdminHome\Emails\UserDeclinedInvitationEmail;
use Piwik\Plugins\Login\Security\BruteForceDetection;
+use Piwik\Plugins\PrivacyManager\SystemSettings;
use Piwik\Plugins\UsersManager\Model as UsersModel;
use Piwik\Plugins\UsersManager\UsersManager;
use Piwik\QuickForm2;
@@ -70,19 +74,19 @@ class Controller extends \Piwik\Plugin\ControllerAdmin
* Constructor.
*
* @param PasswordResetter $passwordResetter
- * @param AuthInterface $auth
+ * @param \Piwik\Auth $auth
* @param SessionInitializer $sessionInitializer
* @param PasswordVerifier $passwordVerify
* @param BruteForceDetection $bruteForceDetection
* @param SystemSettings $systemSettings
*/
public function __construct(
- $passwordResetter = null,
- $auth = null,
- $sessionInitializer = null,
- $passwordVerify = null,
- $bruteForceDetection = null,
- $systemSettings = null
+ $passwordResetter = null,
+ $auth = null,
+ $sessionInitializer = null,
+ $passwordVerify = null,
+ $bruteForceDetection = null,
+ $systemSettings = null
) {
parent::__construct();
@@ -122,7 +126,7 @@ class Controller extends \Piwik\Plugin\ControllerAdmin
*
* @return string
*/
- function index()
+ public function index()
{
return $this->login();
}
@@ -135,7 +139,7 @@ class Controller extends \Piwik\Plugin\ControllerAdmin
* @return string
* @internal param string $currentUrl Current URL
*/
- function login($messageNoAccess = null, $infoMessage = false)
+ public function login($messageNoAccess = null, $infoMessage = false)
{
$form = new FormLogin();
if ($form->validate()) {
@@ -231,20 +235,20 @@ class Controller extends \Piwik\Plugin\ControllerAdmin
}
}
- return $this->renderTemplate('@Login/confirmPassword', array(
+ return $this->renderTemplate('@Login/confirmPassword', [
'nonce' => Nonce::getNonce($nonceKey),
'AccessErrorString' => $messageNoAccess,
'loginPlugin' => Piwik::getLoginPluginName(),
- ));
+ ]);
}
/**
* Form-less login
- * @see how to use it on http://piwik.org/faq/how-to/#faq_30
+ * @see how to use it on https://matomo.org/faq/how-to/faq_30
* @throws Exception
* @return void
*/
- function logme()
+ public function logme()
{
if (Config::getInstance()->General['login_allow_logme'] == 0) {
throw new Exception('This functionality has been disabled in config');
@@ -254,8 +258,9 @@ class Controller extends \Piwik\Plugin\ControllerAdmin
$login = Common::getRequestVar('login', null, 'string');
if (Piwik::hasTheUserSuperUserAccess($login)) {
- throw new Exception(Piwik::translate('Login_ExceptionInvalidSuperUserAccessAuthenticationMethod',
- array("logme")));
+ throw new Exception(
+ Piwik::translate('Login_ExceptionInvalidSuperUserAccessAuthenticationMethod', ["logme"])
+ );
}
$currentUrl = 'index.php';
@@ -274,10 +279,10 @@ class Controller extends \Piwik\Plugin\ControllerAdmin
{
Piwik::checkUserHasSuperUserAccess();
- return $this->renderTemplate('bruteForceLog', array(
+ return $this->renderTemplate('bruteForceLog', [
'blockedIps' => $this->bruteForceDetection->getCurrentlyBlockedIps(),
'blacklistedIps' => $this->systemSettings->blacklistedBruteForceIps->getValue()
- ));
+ ]);
}
/**
@@ -289,14 +294,14 @@ class Controller extends \Piwik\Plugin\ControllerAdmin
public function ajaxNoAccess($errorMessage)
{
return sprintf(
- '<div class="alert alert-danger">
+ '<div class="alert alert-danger">
<p><strong>%s:</strong> %s</p>
<p><a href="%s">%s</a></p>
</div>',
- Piwik::translate('General_Error'),
- htmlentities($errorMessage, Common::HTML_ENCODING_QUOTE_STYLE, 'UTF-8', $doubleEncode = false),
- 'index.php?module=' . Piwik::getLoginPluginName(),
- Piwik::translate('Login_LogIn')
+ Piwik::translate('General_Error'),
+ htmlentities($errorMessage, Common::HTML_ENCODING_QUOTE_STYLE, 'UTF-8', $doubleEncode = false),
+ 'index.php?module=' . Piwik::getLoginPluginName(),
+ Piwik::translate('Login_LogIn')
);
}
@@ -345,7 +350,8 @@ class Controller extends \Piwik\Plugin\ControllerAdmin
$currentHost = explode(':', $currentHost, 2)[0];
// we only redirect to a trusted host
- if (!empty($host) && !empty($currentHost) && $host == $currentHost && Url::isValidHost($host)
+ if (
+ !empty($host) && !empty($currentHost) && $host == $currentHost && Url::isValidHost($host)
) {
$urlToRedirect = $redirect;
}
@@ -362,9 +368,8 @@ class Controller extends \Piwik\Plugin\ControllerAdmin
/**
* Reset password action. Stores new password as hash and sends email
* to confirm use.
- *
*/
- function resetPassword()
+ public function resetPassword()
{
$infoMessage = null;
$formErrors = null;
@@ -379,7 +384,7 @@ class Controller extends \Piwik\Plugin\ControllerAdmin
$infoMessage = Piwik::translate('Login_ConfirmationLinkSent');
}
} else {
- $formErrors = array($errorMessage);
+ $formErrors = [$errorMessage];
}
} else {
// if invalid, display error
@@ -410,7 +415,7 @@ class Controller extends \Piwik\Plugin\ControllerAdmin
} catch (Exception $ex) {
Log::debug($ex);
- return array($ex->getMessage());
+ return [$ex->getMessage()];
}
return null;
@@ -444,15 +449,21 @@ class Controller extends \Piwik\Plugin\ControllerAdmin
return $this->login($errorMessage);
}
- if (!empty($_POST['nonce'])
- && !empty($_POST['mtmpasswordconfirm'])
- && !empty($resetToken)
- && !empty($login)
- && !empty($passwordHash)
- && empty($errorMessage)) {
+ if (
+ !empty($_POST['nonce'])
+ && !empty($_POST['mtmpasswordconfirm'])
+ && !empty($resetToken)
+ && !empty($login)
+ && !empty($passwordHash)
+ && empty($errorMessage)
+ ) {
Nonce::checkNonce(self::NONCE_CONFIRMRESETPASSWORD, $_POST['nonce']);
- if ($this->passwordResetter->doesResetPasswordHashMatchesPassword($_POST['mtmpasswordconfirm'],
- $passwordHash)) {
+ if (
+ $this->passwordResetter->doesResetPasswordHashMatchesPassword(
+ $_POST['mtmpasswordconfirm'],
+ $passwordHash
+ )
+ ) {
$this->passwordResetter->setHashedPasswordForLogin($login, $passwordHash);
return $this->resetPasswordSuccess();
} else {
@@ -462,10 +473,10 @@ class Controller extends \Piwik\Plugin\ControllerAdmin
$nonce = Nonce::getNonce(self::NONCE_CONFIRMRESETPASSWORD);
- return $this->renderTemplateAs('confirmResetPassword', array(
+ return $this->renderTemplateAs('confirmResetPassword', [
'nonce' => $nonce,
'errorMessage' => $errorMessage
- ), 'basic');
+ ], 'basic');
}
/**
@@ -475,7 +486,7 @@ class Controller extends \Piwik\Plugin\ControllerAdmin
*/
public function resetPasswordSuccess()
{
- $_POST = array(); // prevent showing error message username and password is missing
+ $_POST = []; // prevent showing error message username and password is missing
return $this->login($errorMessage = null, $infoMessage = Piwik::translate('Login_PasswordChanged'));
}
@@ -499,7 +510,7 @@ class Controller extends \Piwik\Plugin\ControllerAdmin
*/
public function logout()
{
- Piwik::postEvent('Login.logout', array(Piwik::getCurrentUserLogin()));
+ Piwik::postEvent('Login.logout', [Piwik::getCurrentUserLogin()]);
self::clearSession();
@@ -524,79 +535,99 @@ class Controller extends \Piwik\Plugin\ControllerAdmin
$token = Common::getRequestVar('token', null, 'string');
$form = Common::getRequestVar('invitation_form', false, 'string');
- //check token is valid
- $user = $model->getUserByTokenAuth($token);
- if ($user['invite_status'] !== 'pending') {
- throw new Exception(Piwik::translate('Login_InvalidOrExpiredToken'));
- }
+ $settings = new SystemSettings();
+ $termsAndConditionUrl = $settings->termsAndConditionUrl->getValue();
+ $privacyPolicyUrl = $settings->privacyPolicyUrl->getValue();
+ $user = $model->getUserByInviteToken($token);
- //if user not match the invite user
+ // if no user matches the invite token
if (!$user) {
throw new Exception(Piwik::translate('Login_InvalidUsernameEmail'));
}
- //if form is blank
+ if (!empty($user['invite_expired_at']) && Date::factory($user['invite_expired_at'])->isEarlier(Date::now())) {
+ throw new Exception(Piwik::translate('Login_InvalidOrExpiredToken'));
+ }
+
+ // if form was sent
if (!empty($form)) {
$error = null;
$password = Common::getRequestVar('password', false, 'string');
$passwordConfirmation = Common::getRequestVar('passwordConfirmation', false, 'string');
- $terms = Common::getRequestVar('terms', false, 'string');
+ $conditionCheck = Common::getRequestVar('conditionCheck', false, 'string');
+
if (!$password) {
$error = Piwik::translate('Login_PasswordRequired');
}
- //not accept terms
- if (!$terms) {
- $error = Piwik::translate('Login_TermsRequired');
+ // check if terms accepted and privacy
+ if (!$conditionCheck && ($privacyPolicyUrl || $termsAndConditionUrl)) {
+ if ($privacyPolicyUrl && $termsAndConditionUrl) {
+ $error = Piwik::translate('Login_AcceptPrivacyPolicyAndTermsAndCondition');
+ } elseif ($privacyPolicyUrl) {
+ $error = Piwik::translate('Login_AcceptPrivacyPolicy');
+ } elseif ($termsAndConditionUrl) {
+ $error = Piwik::translate('Login_AcceptTermsAndCondition');
+ }
}
- //valid password
+ // validate password
if (!UsersManager::isValidPasswordString($password)) {
- $error = Piwik::translate('UsersManager_ExceptionInvalidPassword',
- array(UsersManager::PASSWORD_MIN_LENGTH));
+ $error = Piwik::translate('UsersManager_ExceptionInvalidPassword', [UsersManager::PASSWORD_MIN_LENGTH]);
}
- //confirm matching password
+
+ // confirm matching passwords
if ($password !== $passwordConfirmation) {
$error = Piwik::translate('Login_PasswordsDoNotMatch');
}
if (!$error) {
$password = UsersManager::getPasswordHash($password);
- $passwordInfo = $passwordHelper->info($password);
-
- if (!isset($passwordInfo['algo']) || 0 >= $passwordInfo['algo']) {
- // password may have already been fully hashed
- $password = $passwordHelper->hash($password);
+ $password = $passwordHelper->hash($password);
+
+ // update pending user to active user
+ $model->updateUserFields(
+ $user['login'],
+ [
+ 'password' => $password,
+ 'invite_token' => null,
+ 'invite_accept_at' => Date::now()->getDatetime(),
+ 'invite_expired_at' => null,
+ ]
+ );
+
+ // send e-mail to inviter
+ if (!empty($user['invited_by'])) {
+ $invitedBy = $model->getUser($user['invited_by']);
+ if ($invitedBy) {
+ $mail = StaticContainer::getContainer()->make(UserAcceptInvitationEmail::class, [
+ 'login' => $user['invited_by'],
+ 'emailAddress' => $invitedBy['email'],
+ 'userLogin' => $user['login'],
+ ]);
+ $mail->safeSend();
+ }
}
- //update pending user to active user
- $model->updateUserFields($user['login'], ['password' => $password, 'invite_status' => 'accept']);
- $sessionInitializer = new SessionInitializer();
- $auth = StaticContainer::get('Piwik\Auth');
- $auth->setTokenAuth(null); // ensure authenticated through password
- $auth->setLogin($user['login']);
- $auth->setPassword($passwordConfirmation);
- $sessionInitializer->initSession($auth);
-
- //send Admin Email
- try {
- $mail = StaticContainer::getContainer()->make(UserAcceptInvitationEmail::class, array(
- 'login' => $user['login'],
- 'emailAddress' => $user['email'],
- 'userLogin' => $user['login'],
- ));
- $mail->safeSend();
- } catch (\Exception $e) {
-
- }
+ /**
+ * Triggered after a user accepted an invite
+ *
+ * @param string $userLogin The invited user's login.
+ * @param string $email The invited user's e-mail.
+ * @param string $inviterLogin The login of the user, who invited this user
+ */
+ Piwik::postEvent('UsersManager.inviteUser.accepted', [$user['login'], $user['email'], $user['invited_by']]);
- $this->redirectToIndex('CoreHome', 'index');
+ $this->authenticateAndRedirect($user['login'], $passwordConfirmation);
}
+
$view->AccessErrorString = $error;
}
+
$view->user = $user;
+ $view->termsAndCondition = $termsAndConditionUrl;
+ $view->privacyPolicyUrl = $privacyPolicyUrl;
$view->token = $token;
- $view->declined = false;
$this->configureView($view);
self::setHostValidationVariablesView($view);
return $view->render();
@@ -609,42 +640,56 @@ class Controller extends \Piwik\Plugin\ControllerAdmin
$token = Common::getRequestVar('token', null, 'string');
$form = Common::getRequestVar('invitation_form', false, 'string');
- $user = $model->getUserByTokenAuth($token);
- if ($user['invite_status'] !== 'pending') {
+ $user = $model->getUserByInviteToken($token);
+
+ // if no user matches the invite token
+ if (!$user) {
throw new Exception(Piwik::translate('Login_InvalidOrExpiredToken'));
}
- //if user not match the invite user
- if (!$user) {
- throw new Exception(Piwik::translate('Login_InvalidUsernameEmail'));
+
+ if (!empty($user['invite_expired_at']) && Date::factory($user['invite_expired_at'])->isEarlier(Date::now())) {
+ throw new Exception(Piwik::translate('Login_InvalidOrExpiredToken'));
}
- if ($form) {
- $model->deleteAllTokensForUser($user['login']);
- $model->updateUserFields($user['login'], ['invite_status' => 'decline']);
- $this->redirectToIndex('Login', 'index');
+ $view = new View('@Login/invitationDecline');
- }
+ if ($form) {
+ // remove user
+ try {
+ $model->deleteUser($user['login']);
+ } catch (\Exception $e) {
+ // deleting the user triggers an event, which might call methods that require a user to be logged in
+ // as those operations might not be needed for a pending user, we simply ignore any errors here
+ }
- $view = new View('@Login/invitation');
- $view->declined = true;
- $view->token = $token;
+ // send e-mail to inviter
+ if (!empty($user['invited_by'])) {
+ $invitedBy = $model->getUser($user['invited_by']);
+ if ($invitedBy) {
+ $mail = StaticContainer::getContainer()->make(UserDeclinedInvitationEmail::class, [
+ 'login' => $user['invited_by'],
+ 'emailAddress' => $invitedBy['email'],
+ 'userLogin' => $user['login'],
+ ]);
+ $mail->safeSend();
+ }
+ }
- //send Admin Email
- try {
- $mail = StaticContainer::getContainer()->make(UserDeclinedInvitationEmail::class, array(
- 'login' => $user['login'],
- 'emailAddress' => $user['email'],
- 'userLogin' => $user['login'],
- ));
- $mail->safeSend();
- } catch (\Exception $e) {
+ $view = new View('@Login/invitationDeclineSuccess');
+ /**
+ * Triggered after a user accepted an invite
+ *
+ * @param string $userLogin The invited user's login.
+ * @param string $email The invited user's e-mail.
+ * @param string $inviterLogin The login of the user, who invited this user
+ */
+ Piwik::postEvent('UsersManager.inviteUser.declined', [$user['login'], $user['email'], $user['invited_by']]);
}
+
+ $view->token = $token;
$this->configureView($view);
self::setHostValidationVariablesView($view);
return $view->render();
-
-
}
-
}