Skip to content

Commit

Permalink
refs #4565 migrate config super user to database
Browse files Browse the repository at this point in the history
  • Loading branch information
tsteur committed Jan 27, 2014
1 parent 56bddb5 commit 80f254d
Show file tree
Hide file tree
Showing 33 changed files with 666 additions and 615 deletions.
5 changes: 1 addition & 4 deletions config/global.ini.php
Expand Up @@ -33,10 +33,6 @@
port = 3306
adapter = PDO_MYSQL

[superuser]
login =
password =

[log]
; possible values for log: screen, database, file
log_writers[] = screen
Expand Down Expand Up @@ -585,6 +581,7 @@
Plugins_Tracker[] = Goals
Plugins_Tracker[] = PrivacyManager
Plugins_Tracker[] = UserCountry
Plugins_Tracker[] = Login

[APISettings]
; Any key/value pair can be added in this section, they will be available via the REST call
Expand Down
44 changes: 29 additions & 15 deletions core/Access.php
Expand Up @@ -11,6 +11,7 @@
namespace Piwik;

use Piwik\Db;
use Piwik\Plugins\UsersManager\API as APIUsersManager;

/**
* Singleton that manages user access to Piwik resources.
Expand Down Expand Up @@ -213,7 +214,7 @@ protected function reloadAccessSuperUser()
}
$this->idsitesByAccess['superuser'] = $allSitesId;

$this->setConfigUserLoginIfCurrentUserHasNotSuperUserAccess();
$this->setAnySuperUserLoginIfCurrentUserHasNotSuperUserAccess();

Piwik::postTestEvent('Access.loadingSuperUserAccess', array(&$this->idsitesByAccess, &$this->login));

Expand Down Expand Up @@ -284,24 +285,37 @@ public function getTokenAuth()
return $this->token_auth;
}

/**
* @see Access::getConfigSuperUserLogin()
* @deprecated deprecated since version 2.0.4
*/
public function getSuperUserLogin()
static public function getAnyUserHavingSuperUserAccess()
{
try {
$superUsers = APIUsersManager::getInstance()->getUsersHavingSuperUserAccess();
} catch (\Exception $e) {
return;
}

$firstSuperUser = array_shift($superUsers);

return $firstSuperUser;
}

public function getAnySuperUserAccessLogin()
{
return $this->getConfigSuperUserLogin();
$anySuperUser = $this->getAnyUserHavingSuperUserAccess();

if (empty($anySuperUser)) {
return;
}

return $anySuperUser['login'];
}

/**
* Returns the super user's login.
*
* @return string
* @see Access::getAnySuperUserAccessLogin()
* @deprecated deprecated since version 2.0.4
*/
public function getConfigSuperUserLogin()
public function getSuperUserLogin()
{
$superuser = Config::getInstance()->superuser;
return $superuser['login'];
return $this->getAnySuperUserAccessLogin();
}

/**
Expand Down Expand Up @@ -460,10 +474,10 @@ protected function getIdSites($idSites)
return $idSites;
}

private function setConfigUserLoginIfCurrentUserHasNotSuperUserAccess()
private function setAnySuperUserLoginIfCurrentUserHasNotSuperUserAccess()
{
if (!Piwik::hasTheUserSuperUserAccess($this->login)) {
$this->login = $this->getConfigSuperUserLogin();
$this->login = $this->getAnySuperUserAccessLogin();
}
}
}
Expand Down
25 changes: 25 additions & 0 deletions core/Auth.php
Expand Up @@ -37,6 +37,21 @@ public function authenticate();
* Authenticates the user and initializes the session.
*/
public function initSession($login, $md5Password, $rememberMe);

/**
* Accessor to set authentication token. If set, you can authenticate the tokenAuth by calling the authenticate()
* method afterwards.
*
* @param string $token_auth authentication token
*/
public function setTokenAuth($token_auth);

/**
* Accessor to set login name
*
* @param string $login user login
*/
public function setLogin($login);
}

/**
Expand Down Expand Up @@ -117,6 +132,16 @@ public function getCode()
return $this->code;
}

/**
* Returns true if the user has Super User access, false otherwise.
*
* @return bool
*/
public function hasSuperUserAccess()
{
return $this->getCode() == self::SUCCESS_SUPERUSER_AUTH_CODE;
}

/**
* Returns true if this result was successfully authentication.
*
Expand Down
25 changes: 24 additions & 1 deletion core/Config.php
Expand Up @@ -370,7 +370,10 @@ public function &__get($name)
: $this->configLocal[$name];
}

if ($section === null) {
if ($section === null && $name = 'superuser') {
$user = $this->getConfigSuperUserForBackwardCompatibility();
return $user;
} else if ($section === null) {
throw new Exception("Error while trying to read a specific config file entry <strong>'$name'</strong> from your configuration files.</b>If you just completed a Piwik upgrade, please check that the file config/global.ini.php was overwritten by the latest Piwik version.");
}

Expand All @@ -381,6 +384,26 @@ public function &__get($name)
return $tmp;
}

/**
* @deprecated since version 2.0.4
*/
public function getConfigSuperUserForBackwardCompatibility()
{
try {
$db = Db::get();
$user = $db->fetchRow("SELECT login, email, password
FROM " . Common::prefixTable("user") . "
WHERE superuser_access = 1
ORDER BY date_registered ASC LIMIT 1");

if (!empty($user)) {
return $user;
}
} catch (Exception $e) {}

return array();
}

public function getFromGlobalConfig($name)
{
if (isset($this->configGlobal[$name])) {
Expand Down
10 changes: 6 additions & 4 deletions core/CronArchive.php
Expand Up @@ -832,10 +832,12 @@ private function initWebsiteIds()

private function initTokenAuth()
{
$login = Piwik::getConfigSuperUserLogin();
$md5Password = Config::getInstance()->superuser['password'];
$this->token_auth = md5($login . $md5Password);
$this->login = $login;
$superUser = Db::get()->fetchRow("SELECT login, token_auth
FROM " . Common::prefixTable("user") . "
WHERE superuser_access = 1
ORDER BY date_registered ASC");
$this->login = $superUser['login'];
$this->token_auth = $superUser['token_auth'];
}

private function initPiwikHost()
Expand Down
66 changes: 28 additions & 38 deletions core/Piwik.php
Expand Up @@ -215,43 +215,38 @@ static public function getRandomTitle()
*/
static public function getCurrentUserEmail()
{
if (!Piwik::isUserIsConfigSuperUser()) {
$user = APIUsersManager::getInstance()->getUser(Piwik::getCurrentUserLogin());
return $user['email'];
}
return self::getConfigSuperUserEmail();
$user = APIUsersManager::getInstance()->getUser(Piwik::getCurrentUserLogin());
return $user['email'];
}

/**
* Returns the super user's username.
*
* @return string
* @api
*/
static public function getConfigSuperUserLogin()
{
return Access::getInstance()->getConfigSuperUserLogin();
}

/**
* @see Piwik::getConfigSuperUserLogin()
* @deprecated deprecated since version 2.0.4
*/
static public function getSuperUserLogin()
{
return self::getConfigSuperUserLogin();
return Access::getInstance()->getSuperUserLogin();
}

/**
* Returns the super user's email address.
* Get a list of all email addresses having Super User access.
*
* @return string
* @api
* @return array
*/
static public function getConfigSuperUserEmail()
static public function getAllSuperUserAccessEmailAddresses()
{
$superuser = Config::getInstance()->superuser;
return $superuser['email'];
$emails = array();

try {
$superUsers = APIUsersManager::getInstance()->getUsersHavingSuperUserAccess();
} catch (\Exception $e) {
return $emails;
}

foreach ($superUsers as $superUser) {
$emails[] = $superUser['email'];
}

return $emails;
}

/**
Expand Down Expand Up @@ -332,8 +327,7 @@ static public function checkUserHasSuperUserAccessOrIsTheUser($theUser)
}

/**
* Check whether the given user has superuser access. Note: This method will return false if current user
* has not superuser access.
* Check whether the given user has superuser access.
*
* @param string $theUser A username.
* @return bool
Expand All @@ -345,18 +339,19 @@ static public function hasTheUserSuperUserAccess($theUser)
return false;
}

if (Piwik::getConfigSuperUserLogin() === $theUser) {
return true;
}

try {
$superUserLogins = APIUsersManager::getInstance()->getUsersLoginHavingSuperUserAccess();
$superUsers = APIUsersManager::getInstance()->getUsersHavingSuperUserAccess();
} catch (\Exception $e) {
// not allowed to request user logins
return false;
}

return in_array($theUser, $superUserLogins);
foreach ($superUsers as $superUser) {
if ($theUser === $superUser['login']) {
return true;
}
}

return false;
}

/**
Expand Down Expand Up @@ -384,11 +379,6 @@ static public function hasUserSuperUserAccess()
}
}

static public function isUserIsConfigSuperUser()
{
return self::hasUserSuperUserAccess() && self::getCurrentUserLogin() === self::getConfigSuperUserLogin();
}

/**
* Returns true if the current user is the special **anonymous** user or not.
*
Expand Down
13 changes: 11 additions & 2 deletions core/Plugin/Controller.php
Expand Up @@ -589,7 +589,7 @@ public static function setHostValidationVariablesView($view)

$emailSubject = rawurlencode(Piwik::translate('CoreHome_InjectedHostEmailSubject', $invalidHost));
$emailBody = rawurlencode(Piwik::translate('CoreHome_InjectedHostEmailBody'));
$superUserEmail = Piwik::getConfigSuperUserEmail();
$superUserEmail = implode(',', Piwik::getAllSuperUserAccessEmailAddresses());

$mailToUrl = "mailto:$superUserEmail?subject=$emailSubject&body=$emailBody";
$mailLinkStart = "<a href=\"$mailToUrl\">";
Expand Down Expand Up @@ -622,6 +622,14 @@ public static function setHostValidationVariablesView($view)
$validHost,
'</a>'
));
} else if (Piwik::isUserIsAnonymous()) {
$view->invalidHostMessage = $warningStart . ' '
. Piwik::translate('CoreHome_InjectedHostNonSuperUserWarning', array(
"<br/><a href=\"$validUrl\">",
'</a>',
'<span style="display:none">',
'</span>'
));
} else {
$view->invalidHostMessage = $warningStart . ' '
. Piwik::translate('CoreHome_InjectedHostNonSuperUserWarning', array(
Expand Down Expand Up @@ -734,7 +742,8 @@ public function redirectToIndex($moduleToRedirect, $actionToRedirect, $websiteId
if (!empty($currentLogin)
&& $currentLogin != 'anonymous'
) {
$errorMessage = sprintf(Piwik::translate('CoreHome_NoPrivilegesAskPiwikAdmin'), $currentLogin, "<br/><a href='mailto:" . Piwik::getConfigSuperUserEmail() . "?subject=Access to Piwik for user $currentLogin'>", "</a>");
$emails = implode(',', Piwik::getAllSuperUserAccessEmailAddresses());
$errorMessage = sprintf(Piwik::translate('CoreHome_NoPrivilegesAskPiwikAdmin'), $currentLogin, "<br/><a href='mailto:" . $emails . "?subject=Access to Piwik for user $currentLogin'>", "</a>");
$errorMessage .= "<br /><br />&nbsp;&nbsp;&nbsp;<b><a href='index.php?module=" . Registry::get('auth')->getName() . "&amp;action=logout'>&rsaquo; " . Piwik::translate('General_Logout') . "</a></b><br />";
Piwik_ExitWithMessage($errorMessage, false, true);
}
Expand Down
3 changes: 3 additions & 0 deletions core/Plugin/Manager.php
Expand Up @@ -911,6 +911,9 @@ protected function isTrackerPlugin(Plugin $plugin)
if (strpos($name, self::TRACKER_EVENT_PREFIX) === 0) {
return true;
}
if ($name === 'Request.initAuthenticationObject') {
return true;
}
}
return false;
}
Expand Down
4 changes: 2 additions & 2 deletions core/SettingsPiwik.php
Expand Up @@ -20,15 +20,15 @@
class SettingsPiwik
{
/**
* Get salt from [superuser] section
* Get salt from [General] section
*
* @return string
*/
public static function getSalt()
{
static $salt = null;
if (is_null($salt)) {
$salt = @Config::getInstance()->superuser['salt'];
$salt = @Config::getInstance()->General['salt'];
}
return $salt;
}
Expand Down

0 comments on commit 80f254d

Please sign in to comment.