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/UsersManager/API.php')
-rw-r--r--plugins/UsersManager/API.php122
1 files changed, 104 insertions, 18 deletions
diff --git a/plugins/UsersManager/API.php b/plugins/UsersManager/API.php
index c1f5965f96..ae9189e653 100644
--- a/plugins/UsersManager/API.php
+++ b/plugins/UsersManager/API.php
@@ -10,12 +10,14 @@ namespace Piwik\Plugins\UsersManager;
use Exception;
use Piwik\Access;
+use Piwik\Auth\Password;
use Piwik\Common;
use Piwik\Config;
use Piwik\Container\StaticContainer;
use Piwik\Date;
use Piwik\Option;
use Piwik\Piwik;
+use Piwik\SettingsPiwik;
use Piwik\Site;
use Piwik\Tracker\Cache;
@@ -41,6 +43,11 @@ class API extends \Piwik\Plugin\API
private $model;
/**
+ * @var Password
+ */
+ private $password;
+
+ /**
* @var UserAccessFilter
*/
private $userFilter;
@@ -50,10 +57,11 @@ class API extends \Piwik\Plugin\API
private static $instance = null;
- public function __construct(Model $model, UserAccessFilter $filter)
+ public function __construct(Model $model, UserAccessFilter $filter, Password $password)
{
$this->model = $model;
$this->userFilter = $filter;
+ $this->password = $password;
}
/**
@@ -208,6 +216,7 @@ class API extends \Piwik\Plugin\API
$users = $this->model->getUsers($logins);
$users = $this->userFilter->filterUsers($users);
+ $users = $this->enrichUsers($users);
// Non Super user can only access login & alias
if (!Piwik::hasUserSuperUserAccess()) {
@@ -355,7 +364,10 @@ class API extends \Piwik\Plugin\API
$user = $this->model->getUser($userLogin);
- return $this->userFilter->filterUser($user);
+ $user = $this->userFilter->filterUser($user);
+ $user = $this->enrichUser($user);
+
+ return $user;
}
/**
@@ -372,7 +384,10 @@ class API extends \Piwik\Plugin\API
$user = $this->model->getUserByEmail($userEmail);
- return $this->userFilter->filterUser($user);
+ $user = $this->userFilter->filterUser($user);
+ $user = $this->enrichUser($user);
+
+ return $user;
}
private function checkLogin($userLogin)
@@ -436,9 +451,9 @@ class API extends \Piwik\Plugin\API
$passwordTransformed = $password;
}
- $alias = $this->getCleanAlias($alias, $userLogin);
-
- $token_auth = $this->getTokenAuth($userLogin, $passwordTransformed);
+ $alias = $this->getCleanAlias($alias, $userLogin);
+ $passwordTransformed = $this->password->hash($passwordTransformed);
+ $token_auth = $this->createTokenAuth($userLogin);
$this->model->addUser($userLogin, $passwordTransformed, $email, $alias, $token_auth, Date::now()->getDatetime());
@@ -500,11 +515,7 @@ class API extends \Piwik\Plugin\API
Piwik::checkUserIsNotAnonymous();
$users = $this->model->getUsersHavingSuperUserAccess();
-
- foreach($users as &$user) {
- // remove token_auth in API response
- unset($user['token_auth']);
- }
+ $users = $this->enrichUsers($users);
// we do not filter these users by access and return them all since we need to print this information in the
// UI and they are allowed to see this.
@@ -512,11 +523,52 @@ class API extends \Piwik\Plugin\API
return $users;
}
+ private function enrichUsers($users)
+ {
+ if (!empty($users)) {
+ foreach ($users as $index => $user) {
+ $users[$index] = $this->enrichUser($user);
+ }
+ }
+ return $users;
+ }
+
+ private function enrichUser($user)
+ {
+ if (!empty($user)) {
+ unset($user['token_auth']);
+ }
+
+ return $user;
+ }
+
+ /**
+ * Regenerate the token_auth associated with a user.
+ *
+ * If the user currently logged in regenerates his own token, he will be logged out.
+ * His previous token will be rendered invalid.
+ *
+ * @param string $userLogin
+ * @throws Exception
+ */
+ public function regenerateTokenAuth($userLogin)
+ {
+ $this->checkUserIsNotAnonymous($userLogin);
+
+ Piwik::checkUserHasSuperUserAccessOrIsTheUser($userLogin);
+
+ $this->model->updateUserTokenAuth(
+ $userLogin,
+ $this->createTokenAuth($userLogin)
+ );
+ }
+
/**
* Updates a user in the database.
* Only login and password are required (case when we update the password).
- * When the password changes, the key token for this user will change, which could break
- * its API calls.
+ *
+ * If the password changes and the user has an old token_auth (legacy MD5 format) associated,
+ * the token will be regenerated. This could break a user's API calls.
*
* @see addUser() for all the parameters
*/
@@ -525,18 +577,30 @@ class API extends \Piwik\Plugin\API
{
Piwik::checkUserHasSuperUserAccessOrIsTheUser($userLogin);
$this->checkUserIsNotAnonymous($userLogin);
- $userInfo = $this->getUser($userLogin);
+ $this->checkUserExists($userLogin);
+
+ $userInfo = $this->model->getUser($userLogin);
+ $token_auth = $userInfo['token_auth'];
+
$passwordHasBeenUpdated = false;
if (empty($password)) {
$password = $userInfo['password'];
} else {
$password = Common::unsanitizeInputValue($password);
+
if (!$_isPasswordHashed) {
UsersManager::checkPassword($password);
$password = UsersManager::getPasswordHash($password);
}
+ $passwordInfo = $this->password->info($password);
+
+ if (!isset($passwordInfo['algo']) || 0 >= $passwordInfo['algo']) {
+ // password may have already been fully hashed
+ $password = $this->password->hash($password);
+ }
+
$passwordHasBeenUpdated = true;
}
@@ -552,8 +616,7 @@ class API extends \Piwik\Plugin\API
$this->checkEmail($email);
}
- $alias = $this->getCleanAlias($alias, $userLogin);
- $token_auth = $this->getTokenAuth($userLogin, $password);
+ $alias = $this->getCleanAlias($alias, $userLogin);
$this->model->updateUser($userLogin, $password, $email, $alias, $token_auth);
@@ -780,7 +843,20 @@ class API extends \Piwik\Plugin\API
}
/**
- * Generates a unique MD5 for the given login & password
+ * Generates a new random authentication token.
+ *
+ * @param string $userLogin Login
+ * @return string
+ */
+ public function createTokenAuth($userLogin)
+ {
+ return md5($userLogin . microtime(true) . Common::generateUniqId() . SettingsPiwik::getSalt());
+ }
+
+ /**
+ * Returns the user's API token.
+ *
+ * If the username/password combination is incorrect an invalid token will be returned.
*
* @param string $userLogin Login
* @param string $md5Password hashed string of the password (using current hash function; MD5-named for historical reasons)
@@ -790,6 +866,16 @@ class API extends \Piwik\Plugin\API
{
UsersManager::checkPasswordHash($md5Password, Piwik::translate('UsersManager_ExceptionPasswordMD5HashExpected'));
- return md5($userLogin . $md5Password);
+ $user = $this->model->getUser($userLogin);
+
+ if (!$this->password->verify($md5Password, $user['password'])) {
+ return md5($userLogin . microtime(true) . Common::generateUniqId());
+ }
+
+ if ($this->password->needsRehash($user['password'])) {
+ $this->updateUser($userLogin, $this->password->hash($md5Password));
+ }
+
+ return $user['token_auth'];
}
}