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:
-rwxr-xr-xconfig/global.ini.php6
-rw-r--r--config/global.php2
-rw-r--r--core/Application/Kernel/PluginList.php4
-rw-r--r--core/Config.php4
-rw-r--r--core/Config/IniFileChain.php17
-rw-r--r--core/Plugin.php4
-rw-r--r--core/SettingsPiwik.php3
-rw-r--r--plugins/CoreAdminHome/CustomLogo.php10
-rw-r--r--plugins/CorePluginsAdmin/templates/macros.twig2
-rw-r--r--plugins/SitesManager/API.php3
-rw-r--r--plugins/SitesManager/Controller.php1
-rw-r--r--plugins/SitesManager/Menu.php2
-rw-r--r--plugins/SitesManager/SitesManager.php14
-rw-r--r--plugins/UsersManager/API.php6
-rw-r--r--plugins/UsersManager/Controller.php18
-rw-r--r--plugins/UsersManager/Menu.php2
-rw-r--r--plugins/UsersManager/UsersManager.php15
-rw-r--r--plugins/UsersManager/templates/userSettings.twig4
18 files changed, 103 insertions, 14 deletions
diff --git a/config/global.ini.php b/config/global.ini.php
index e874b68b66..ba088da242 100755
--- a/config/global.ini.php
+++ b/config/global.ini.php
@@ -674,6 +674,12 @@ enable_load_data_infile = 1
; - links to Uninstall themes will be disabled (but user can still enable/disable themes)
enable_plugins_admin = 1
+; By setting this option to 0 the users management will be disabled
+enable_users_admin = 1
+
+; By setting this option to 0 the websites management will be disabled
+enable_sites_admin = 1
+
; By setting this option to 1, it will be possible for Super Users to upload Matomo plugin ZIP archives directly in Matomo Administration.
; Enabling this opens a remote code execution vulnerability where
; an attacker who gained Super User access could execute custom PHP code in a Matomo plugin.
diff --git a/config/global.php b/config/global.php
index e83091c882..187e6aae78 100644
--- a/config/global.php
+++ b/config/global.php
@@ -10,6 +10,8 @@ return array(
'path.root' => PIWIK_USER_PATH,
+ 'path.misc.user' => 'misc/user/',
+
'path.tmp' => function (ContainerInterface $c) {
$root = $c->get('path.root');
diff --git a/core/Application/Kernel/PluginList.php b/core/Application/Kernel/PluginList.php
index 14d2591b73..dbab86e3bd 100644
--- a/core/Application/Kernel/PluginList.php
+++ b/core/Application/Kernel/PluginList.php
@@ -65,7 +65,9 @@ class PluginList
public function getActivatedPlugins()
{
$section = $this->settings->getSection('Plugins');
- return @$section['Plugins'] ?: array();
+ $plugins = @$section['Plugins'] ?: array();
+
+ return $plugins;
}
/**
diff --git a/core/Config.php b/core/Config.php
index 7a24ca4038..916b43b6dd 100644
--- a/core/Config.php
+++ b/core/Config.php
@@ -138,6 +138,10 @@ class Config
*/
public static function getLocalConfigPath()
{
+ if (!empty($GLOBALS['CONFIG_INI_PATH_RESOLVER']) && is_callable($GLOBALS['CONFIG_INI_PATH_RESOLVER'])) {
+ return call_user_func($GLOBALS['CONFIG_INI_PATH_RESOLVER']);
+ }
+
$path = self::getByDomainConfigPath();
if ($path) {
return $path;
diff --git a/core/Config/IniFileChain.php b/core/Config/IniFileChain.php
index 94ef276d58..c10930b1d4 100644
--- a/core/Config/IniFileChain.php
+++ b/core/Config/IniFileChain.php
@@ -11,6 +11,7 @@ use Piwik\Common;
use Piwik\Ini\IniReader;
use Piwik\Ini\IniReadingException;
use Piwik\Ini\IniWriter;
+use Piwik\Piwik;
/**
* Manages a list of INI files where the settings in each INI file merge with or override the
@@ -510,6 +511,22 @@ class IniFileChain
private function dumpSettings($values, $header)
{
+ /**
+ * Triggered before a config is being written / saved on the local file system.
+ *
+ * A plugin can listen to it and modify which settings will be saved on the file system. This allows you
+ * to prevent saving config values that a plugin sets on demand. Say you configure the database password in the
+ * config on demand in your plugin, then you could prevent that the password is saved in the actual config file
+ * by listening to this event like this:
+ *
+ * **Example**
+ * function doNotSaveDbPassword (&$values) {
+ * unset($values['database']['password']);
+ * }
+ *
+ * @param array &$values Config values that will be saved
+ */
+ Piwik::postEvent('Config.beforeSave', array(&$values));
$values = $this->encodeValues($values);
$writer = new IniWriter();
diff --git a/core/Plugin.php b/core/Plugin.php
index ac38b72e20..a3187bf70f 100644
--- a/core/Plugin.php
+++ b/core/Plugin.php
@@ -13,6 +13,8 @@ use Piwik\Plugin\Dependency;
use Piwik\Plugin\Manager;
use Piwik\Plugin\MetadataLoader;
+if (!class_exists('Piwik\Plugin')) {
+
/**
* Base class of all Plugin Descriptor classes.
*
@@ -593,3 +595,5 @@ class Plugin
return $dependency;
}
}
+}
+
diff --git a/core/SettingsPiwik.php b/core/SettingsPiwik.php
index 1f8e8b203b..9be5fdf119 100644
--- a/core/SettingsPiwik.php
+++ b/core/SettingsPiwik.php
@@ -10,6 +10,7 @@ namespace Piwik;
use Exception;
use Piwik\Cache as PiwikCache;
+use Piwik\Container\StaticContainer;
/**
* Contains helper methods that can be used to get common Piwik settings.
@@ -354,7 +355,7 @@ class SettingsPiwik
*/
public static function rewriteMiscUserPathWithInstanceId($path)
{
- $tmp = 'misc/user/';
+ $tmp = StaticContainer::get('path.misc.user');
$path = self::rewritePathAppendPiwikInstanceId($path, $tmp);
return $path;
}
diff --git a/plugins/CoreAdminHome/CustomLogo.php b/plugins/CoreAdminHome/CustomLogo.php
index ba2ce811d9..1c1368a1f5 100644
--- a/plugins/CoreAdminHome/CustomLogo.php
+++ b/plugins/CoreAdminHome/CustomLogo.php
@@ -9,6 +9,7 @@
namespace Piwik\Plugins\CoreAdminHome;
use Piwik\Config;
+use Piwik\Container\StaticContainer;
use Piwik\Filesystem;
use Piwik\Option;
use Piwik\Piwik;
@@ -136,22 +137,22 @@ class CustomLogo
public static function getPathUserLogo()
{
- return static::rewritePath('misc/user/logo.png');
+ return static::rewritePath(StaticContainer::get('path.misc.user') . 'logo.png');
}
public static function getPathUserFavicon()
{
- return static::rewritePath('misc/user/favicon.png');
+ return static::rewritePath(StaticContainer::get('path.misc.user') . 'favicon.png');
}
public static function getPathUserSvgLogo()
{
- return static::rewritePath('misc/user/logo.svg');
+ return static::rewritePath(StaticContainer::get('path.misc.user') . 'logo.svg');
}
public static function getPathUserLogoSmall()
{
- return static::rewritePath('misc/user/logo-header.png');
+ return static::rewritePath(StaticContainer::get('path.misc.user') . 'logo-header.png');
}
protected static function rewritePath($path)
@@ -288,3 +289,4 @@ class CustomLogo
}
}
+
diff --git a/plugins/CorePluginsAdmin/templates/macros.twig b/plugins/CorePluginsAdmin/templates/macros.twig
index 13c7a41ec9..9c753c77d6 100644
--- a/plugins/CorePluginsAdmin/templates/macros.twig
+++ b/plugins/CorePluginsAdmin/templates/macros.twig
@@ -282,6 +282,7 @@
</tbody>
</table>
+ {% if displayAdminLinks %}
<div class="tableActionBar">
{% if isTheme %}
<a href="{{ linkTo({'action':'browseThemes', 'sort': ''}) }}"><span class="icon-add"></span> {{ 'CorePluginsAdmin_InstallNewThemes'|translate }}</a>
@@ -289,6 +290,7 @@
<a href="{{ linkTo({'action':'browsePlugins', 'sort': ''}) }}"><span class="icon-add"></span> {{ 'CorePluginsAdmin_InstallNewPlugins'|translate }}</a>
{% endif %}
</div>
+ {% endif %}
<div class="footer-message">
{% set pluginsAlwaysActivated %}
diff --git a/plugins/SitesManager/API.php b/plugins/SitesManager/API.php
index b8da10cf39..909d694f23 100644
--- a/plugins/SitesManager/API.php
+++ b/plugins/SitesManager/API.php
@@ -615,6 +615,7 @@ class API extends \Piwik\Plugin\API
$excludeUnknownUrls = null)
{
Piwik::checkUserHasSuperUserAccess();
+ SitesManager::dieIfSitesAdminIsDisabled();
$this->checkName($siteName);
@@ -795,6 +796,7 @@ class API extends \Piwik\Plugin\API
public function deleteSite($idSite)
{
Piwik::checkUserHasSuperUserAccess();
+ SitesManager::dieIfSitesAdminIsDisabled();
$idSites = $this->getSitesId();
if (!in_array($idSite, $idSites)) {
@@ -1255,6 +1257,7 @@ class API extends \Piwik\Plugin\API
$excludeUnknownUrls = null)
{
Piwik::checkUserHasAdminAccess($idSite);
+ SitesManager::dieIfSitesAdminIsDisabled();
$idSites = $this->getSitesId();
diff --git a/plugins/SitesManager/Controller.php b/plugins/SitesManager/Controller.php
index 2d6c4a7824..da66d3a248 100644
--- a/plugins/SitesManager/Controller.php
+++ b/plugins/SitesManager/Controller.php
@@ -33,6 +33,7 @@ class Controller extends \Piwik\Plugin\ControllerAdmin
public function index()
{
Piwik::checkUserHasSomeAdminAccess();
+ SitesManager::dieIfSitesAdminIsDisabled();
return $this->renderTemplate('index');
}
diff --git a/plugins/SitesManager/Menu.php b/plugins/SitesManager/Menu.php
index d37353cada..f8b94dc97a 100644
--- a/plugins/SitesManager/Menu.php
+++ b/plugins/SitesManager/Menu.php
@@ -28,7 +28,7 @@ class Menu extends \Piwik\Plugin\Menu
$menu->addMeasurableItem('General_Settings', $this->urlForAction('globalSettings'), $order = 11);
}
- if (Piwik::isUserHasSomeAdminAccess()) {
+ if (Piwik::isUserHasSomeAdminAccess() && SitesManager::isSitesAdminEnabled()) {
$menu->addMeasurableItem('SitesManager_MenuManage', $this->urlForAction('index'), $order = 10);
$type = $this->getFirstTypeIfOnlyOneIsInUse();
diff --git a/plugins/SitesManager/SitesManager.php b/plugins/SitesManager/SitesManager.php
index 751c599f3a..23b7108c7b 100644
--- a/plugins/SitesManager/SitesManager.php
+++ b/plugins/SitesManager/SitesManager.php
@@ -11,6 +11,7 @@ namespace Piwik\Plugins\SitesManager;
use Piwik\Access;
use Piwik\API\Request;
use Piwik\Common;
+use Piwik\Config;
use Piwik\Container\StaticContainer;
use Piwik\Exception\UnexpectedWebsiteFoundException;
use Piwik\Option;
@@ -47,6 +48,19 @@ class SitesManager extends \Piwik\Plugin
);
}
+ public static function isSitesAdminEnabled()
+ {
+ return (bool) Config::getInstance()->General['enable_sites_admin'];
+ }
+
+ public static function dieIfSitesAdminIsDisabled()
+ {
+ Piwik::checkUserIsNotAnonymous();
+ if (!self::isSitesAdminEnabled()) {
+ throw new \Exception('Creating, updating, and deleting sites has been disabled.');
+ }
+ }
+
public function addSystemSummaryItems(&$systemSummary)
{
$websites = Request::processRequest('SitesManager.getAllSites', array('filter_limit' => '-1'));
diff --git a/plugins/UsersManager/API.php b/plugins/UsersManager/API.php
index fac5b6178d..d2614f581d 100644
--- a/plugins/UsersManager/API.php
+++ b/plugins/UsersManager/API.php
@@ -651,6 +651,7 @@ class API extends \Piwik\Plugin\API
public function addUser($userLogin, $password, $email, $alias = false, $_isPasswordHashed = false, $initialIdSite = null)
{
Piwik::checkUserHasSomeAdminAccess();
+ UsersManager::dieIfUsersAdminIsDisabled();
if (!Piwik::hasUserSuperUserAccess()) {
if (empty($initialIdSite)) {
@@ -709,6 +710,7 @@ class API extends \Piwik\Plugin\API
{
Piwik::checkUserHasSuperUserAccess();
$this->checkUserIsNotAnonymous($userLogin);
+ UsersManager::dieIfUsersAdminIsDisabled();
$requirePasswordConfirmation = self::$SET_SUPERUSER_ACCESS_REQUIRE_PASSWORD_CONFIRMATION;
self::$SET_SUPERUSER_ACCESS_REQUIRE_PASSWORD_CONFIRMATION = true;
@@ -874,6 +876,7 @@ class API extends \Piwik\Plugin\API
$isEmailNotificationOnInConfig = Config::getInstance()->General['enable_update_users_email'];
Piwik::checkUserHasSuperUserAccessOrIsTheUser($userLogin);
+ UsersManager::dieIfUsersAdminIsDisabled();
$this->checkUserIsNotAnonymous($userLogin);
$this->checkUserExists($userLogin);
@@ -957,6 +960,7 @@ class API extends \Piwik\Plugin\API
public function deleteUser($userLogin)
{
Piwik::checkUserHasSuperUserAccess();
+ UsersManager::dieIfUsersAdminIsDisabled();
$this->checkUserIsNotAnonymous($userLogin);
$this->checkUserExist($userLogin);
@@ -1049,6 +1053,8 @@ class API extends \Piwik\Plugin\API
*/
public function setUserAccess($userLogin, $access, $idSites)
{
+ UsersManager::dieIfUsersAdminIsDisabled();
+
if ($access != 'noaccess') {
$this->checkAccessType($access);
}
diff --git a/plugins/UsersManager/Controller.php b/plugins/UsersManager/Controller.php
index a9e2ffcf5b..3d67327469 100644
--- a/plugins/UsersManager/Controller.php
+++ b/plugins/UsersManager/Controller.php
@@ -15,6 +15,7 @@ use Piwik\Common;
use Piwik\Container\StaticContainer;
use Piwik\Option;
use Piwik\Piwik;
+use Piwik\Plugin;
use Piwik\Plugin\ControllerAdmin;
use Piwik\Plugins\LanguagesManager\API as APILanguagesManager;
use Piwik\Plugins\LanguagesManager\LanguagesManager;
@@ -53,6 +54,7 @@ class Controller extends ControllerAdmin
{
Piwik::checkUserIsNotAnonymous();
Piwik::checkUserHasSomeAdminAccess();
+ UsersManager::dieIfUsersAdminIsDisabled();
$view = new View('@UsersManager/index');
@@ -183,6 +185,7 @@ class Controller extends ControllerAdmin
$view->userEmail = $user['email'];
$view->userTokenAuth = Piwik::getCurrentUserTokenAuth();
$view->ignoreSalt = $this->getIgnoreCookieSalt();
+ $view->isUsersAdminEnabled = UsersManager::isUsersAdminEnabled();
$newsletterSignupOptionKey = NewsletterSignup::NEWSLETTER_SIGNUP_OPTION . $userLogin;
$view->showNewsletterSignup = Option::get($newsletterSignupOptionKey) === false
@@ -210,11 +213,14 @@ class Controller extends ControllerAdmin
$view->defaultReportSiteName = Site::getNameFor($defaultReport);
}
- $view->defaultReportOptions = array(
- array('key' => 'MultiSites', 'value' => Piwik::translate('General_AllWebsitesDashboard')),
- array('key' => $reportOptionsValue, 'value' => Piwik::translate('General_DashboardForASpecificWebsite')),
- );
+ $defaultReportOptions = array();
+ if (Plugin\Manager::getInstance()->isPluginActivated('MultiSites')) {
+ $defaultReportOptions[] = array('key' => 'MultiSites', 'value' => Piwik::translate('General_AllWebsitesDashboard'));
+ }
+ $defaultReportOptions[] = array('key' => $reportOptionsValue, 'value' => Piwik::translate('General_DashboardForASpecificWebsite'));
+
+ $view->defaultReportOptions = $defaultReportOptions;
$view->defaultDate = $this->getDefaultDateForUser($userLogin);
$view->availableDefaultDates = $this->getDefaultDates();
@@ -383,7 +389,9 @@ class Controller extends ControllerAdmin
Piwik::checkUserHasSuperUserAccessOrIsTheUser($userLogin);
- $this->processPasswordChange($userLogin);
+ if (UsersManager::isUsersAdminEnabled()) {
+ $this->processPasswordChange($userLogin);
+ }
LanguagesManager::setLanguageForSession($language);
diff --git a/plugins/UsersManager/Menu.php b/plugins/UsersManager/Menu.php
index 77fc8ced04..7945480d4e 100644
--- a/plugins/UsersManager/Menu.php
+++ b/plugins/UsersManager/Menu.php
@@ -15,7 +15,7 @@ class Menu extends \Piwik\Plugin\Menu
{
public function configureAdminMenu(MenuAdmin $menu)
{
- if (Piwik::isUserHasSomeAdminAccess()) {
+ if (Piwik::isUserHasSomeAdminAccess() && UsersManager::isUsersAdminEnabled()) {
$menu->addSystemItem('UsersManager_MenuUsers', $this->urlForAction('index'), $order = 15);
}
diff --git a/plugins/UsersManager/UsersManager.php b/plugins/UsersManager/UsersManager.php
index 7e3f6de428..ede90bea93 100644
--- a/plugins/UsersManager/UsersManager.php
+++ b/plugins/UsersManager/UsersManager.php
@@ -14,9 +14,11 @@ use Piwik\Access\Role\Write;
use Piwik\API\Request;
use Piwik\Auth\Password;
use Piwik\Common;
+use Piwik\Config;
use Piwik\Option;
use Piwik\Piwik;
use Piwik\Plugins\CoreHome\SystemSummary;
+use Piwik\Plugins\CorePluginsAdmin\CorePluginsAdmin;
use Piwik\SettingsPiwik;
/**
@@ -45,6 +47,19 @@ class UsersManager extends \Piwik\Plugin
);
}
+ public static function isUsersAdminEnabled()
+ {
+ return (bool) Config::getInstance()->General['enable_users_admin'];
+ }
+
+ public static function dieIfUsersAdminIsDisabled()
+ {
+ Piwik::checkUserIsNotAnonymous();
+ if (!self::isUsersAdminEnabled()) {
+ throw new \Exception('Creating, updating, and deleting users has been disabled.');
+ }
+ }
+
public function addSystemSummaryItems(&$systemSummary)
{
$userLogins = Request::processRequest('UsersManager.getUsersLogin', array('filter_limit' => '-1'));
diff --git a/plugins/UsersManager/templates/userSettings.twig b/plugins/UsersManager/templates/userSettings.twig
index 567cac4984..22c9a58ccb 100644
--- a/plugins/UsersManager/templates/userSettings.twig
+++ b/plugins/UsersManager/templates/userSettings.twig
@@ -20,6 +20,7 @@
inline-help="{{ 'UsersManager_YourUsernameCannotBeChanged'|translate|e('html_attr') }}">
</div>
+ {% if isUsersAdminEnabled %}
<div piwik-field uicontrol="text" name="email"
ng-model="personalSettings.email"
ng-change="personalSettings.requirePasswordConfirmation()"
@@ -27,6 +28,7 @@
data-title="{{ 'UsersManager_Email'|translate|e('html_attr') }}"
value="{{ userEmail }}">
</div>
+ {% endif %}
<div id="languageHelp" class="inline-help-node">
<a target="_blank" rel="noreferrer noopener" href="https://matomo.org/translations/">
@@ -72,7 +74,7 @@
value="{{ defaultDate }}" options="{{ availableDefaultDates|json_encode }}">
</div>
- {% if isValidHost is defined and isValidHost %}
+ {% if isValidHost is defined and isValidHost and isUsersAdminEnabled %}
<div piwik-field uicontrol="password" name="password" autocomplete="off"
ng-model="personalSettings.password"