From c1301a04b6f0be1e7da3e7a44f4399285ce37930 Mon Sep 17 00:00:00 2001 From: mattab <matthieu.aubry@gmail.com> Date: Tue, 7 Jan 2014 17:45:32 +1300 Subject: [PATCH] Adding new option to completely disable the Plugins enable/disable/uninstall features: enable_plugins_admin is 1 by default. --- config/global.ini.php | 21 ++-- lang/en.json | 1 + plugins/CorePluginsAdmin/Controller.php | 107 ++++++++++++------ plugins/CorePluginsAdmin/CorePluginsAdmin.php | 5 + .../CorePluginsAdmin/templates/macros.twig | 8 +- .../CorePluginsAdmin/templates/plugins.twig | 10 +- .../CorePluginsAdmin/templates/themes.twig | 6 +- 7 files changed, 110 insertions(+), 48 deletions(-) diff --git a/config/global.ini.php b/config/global.ini.php index d315d31c33..794f9dc0a2 100644 --- a/config/global.ini.php +++ b/config/global.ini.php @@ -348,13 +348,6 @@ overlay_following_pages_limit = 300 ; With this option, you can disable the framed mode of the Overlay plugin. Use it if your website contains a framebuster. overlay_disable_framed_mode = 0 -; By setting this option to 0, you can disable the Piwik marketplace. This is useful to prevent giving the Super user -; the access to disk and install custom PHP code (Piwik plugins). -enable_marketplace = 1 - -; By setting this option to 0, you can prevent Super User from editing the Geolocation settings. -enable_geolocation_admin = 1 - ; If php is running in a chroot environment, when trying to import CSV files with createTableFromCSVFile(), ; Mysql will try to load the chrooted path (which is imcomplete). To prevent an error, here you can specify the ; absolute path to the chroot environment. eg. '/path/to/piwik/chrooted/' @@ -364,6 +357,20 @@ absolute_chroot_path = ; This may for example be useful when doing Mysql AWS replication enable_load_data_infile = 1 +; By setting this option to 0, you can disable the Piwik marketplace. This is useful to prevent giving the Super user +; the access to disk and install custom PHP code (Piwik plugins). +enable_marketplace = 1 + +; By setting this option to 0: +; - links to Enable/Disable/Uninstall plugins will be hidden and disabled +; - links to Uninstall themes will be disabled (but user can still enable/disable themes) +; - as well as disabling plugins admin actions (such as "Upload new plugin"), setting this to 1 will have same effect as setting enable_marketplace=1 +enable_plugins_admin = 1 + +; By setting this option to 0, you can prevent Super User from editing the Geolocation settings. +enable_geolocation_admin = 1 + + [Tracker] ; Piwik uses first party cookies by default. If set to 1, ; the visit ID cookie will be set on the Piwik server domain as well diff --git a/lang/en.json b/lang/en.json index 3a73f8eaac..474d5a1244 100644 --- a/lang/en.json +++ b/lang/en.json @@ -716,6 +716,7 @@ "ThemesManagement": "Manage Themes", "MainDescription": "Plugins extend and expand the functionality of Piwik. Once a plugin is installed, you may activate it or deactivate it here.", "ThemesDescription": "Themes can change the appearance of Piwik user interface,\n and provide a completely new visual experience to enjoy your analytics reports.", + "DoMoreContactPiwikAdmins": "To install a new plugin or a new theme, please get in touch with your Piwik admins.", "Theme": "Theme", "Version": "Version", "Status": "Status", diff --git a/plugins/CorePluginsAdmin/Controller.php b/plugins/CorePluginsAdmin/Controller.php index 1d269193e6..b4a06f2ffa 100644 --- a/plugins/CorePluginsAdmin/Controller.php +++ b/plugins/CorePluginsAdmin/Controller.php @@ -43,6 +43,7 @@ class Controller extends Plugin\ControllerAdmin static::dieIfMarketplaceIsDisabled(); $pluginName = $this->initPluginModification($nonceName); + $this->dieIfPluginAdminDisabledAndIsPlugin($pluginName); $view = $this->configureView('@CorePluginsAdmin/' . $template); @@ -84,6 +85,7 @@ class Controller extends Plugin\ControllerAdmin public function uploadPlugin() { + static::dieIfPluginsAdminIsDisabled(); Piwik::checkUserIsSuperUser(); $nonce = Common::getRequestVar('nonce', null, 'string'); @@ -152,7 +154,19 @@ class Controller extends Plugin\ControllerAdmin private function dieIfMarketplaceIsDisabled() { if (!CorePluginsAdmin::isMarketplaceEnabled()) { - throw new \Exception('The Marketplace is disabled. Enable the Marketplace by changing the config entry "enable_marketplace" to 1.'); + throw new \Exception('The Marketplace feature has been disabled. + You may enable the Marketplace by changing the config entry "enable_marketplace" to 1. + Please contact your Piwik admins with your request so they can assist.'); + } + + $this->dieIfPluginsAdminIsDisabled(); + } + + private function dieIfPluginsAdminIsDisabled() + { + if (!CorePluginsAdmin::isPluginsAdminEnabled()) { + throw new \Exception('Enabling, disabling and uninstalling plugins has been disabled by Piwik admins. + Please contact your Piwik admins with your request so they can assist you.'); } } @@ -193,7 +207,7 @@ class Controller extends Plugin\ControllerAdmin return $view->render(); } - function extend() + public function extend() { static::dieIfMarketplaceIsDisabled(); @@ -222,6 +236,7 @@ class Controller extends Plugin\ControllerAdmin $view->pluginNamesHavingSettings = $this->getPluginNamesHavingSettingsForCurrentUser(); $view->isMarketplaceEnabled = CorePluginsAdmin::isMarketplaceEnabled(); + $view->isPluginsAdminEnabled = CorePluginsAdmin::isPluginsAdminEnabled(); $view->pluginsHavingUpdate = array(); $view->marketplacePluginNames = array(); @@ -239,13 +254,13 @@ class Controller extends Plugin\ControllerAdmin return $view; } - function plugins() + public function plugins() { $view = $this->createPluginsOrThemesView('plugins', $themesOnly = false); return $view->render(); } - function themes() + public function themes() { $view = $this->createPluginsOrThemesView('themes', $themesOnly = true); return $view->render(); @@ -366,39 +381,10 @@ class Controller extends Plugin\ControllerAdmin return $view->render(); } - public function deactivate($redirectAfter = true) - { - $pluginName = $this->initPluginModification(static::DEACTIVATE_NONCE); - \Piwik\Plugin\Manager::getInstance()->deactivatePlugin($pluginName); - $this->redirectAfterModification($redirectAfter); - } - - protected function redirectAfterModification($redirectAfter) - { - if ($redirectAfter) { - Url::redirectToReferrer(); - } - } - - protected function initPluginModification($nonceName) - { - Piwik::checkUserIsSuperUser(); - - $nonce = Common::getRequestVar('nonce', null, 'string'); - - if (!Nonce::verifyNonce($nonceName, $nonce)) { - throw new \Exception(Piwik::translate('General_ExceptionNonceMismatch')); - } - - Nonce::discardNonce($nonceName); - - $pluginName = Common::getRequestVar('pluginName', null, 'string'); - return $pluginName; - } - public function activate($redirectAfter = true) { $pluginName = $this->initPluginModification(static::ACTIVATE_NONCE); + $this->dieIfPluginAdminDisabledAndIsPlugin($pluginName); \Piwik\Plugin\Manager::getInstance()->activatePlugin($pluginName); @@ -413,8 +399,8 @@ class Controller extends Plugin\ControllerAdmin $message = Piwik::translate('CorePluginsAdmin_SuccessfullyActicated', array($pluginName)); if (SettingsManager::hasPluginSettingsForCurrentUser($pluginName)) { $target = sprintf('<a href="index.php%s#%s">', - Url::getCurrentQueryStringWithParametersModified(array('module' => 'CoreAdminHome', 'action' => 'pluginSettings')), - $pluginName); + Url::getCurrentQueryStringWithParametersModified(array('module' => 'CoreAdminHome', 'action' => 'pluginSettings')), + $pluginName); $message .= ' ' . Piwik::translate('CorePluginsAdmin_ChangeSettingsPossible', array($target, '</a>')); } @@ -428,9 +414,20 @@ class Controller extends Plugin\ControllerAdmin } } + public function deactivate($redirectAfter = true) + { + $pluginName = $this->initPluginModification(static::DEACTIVATE_NONCE); + $this->dieIfPluginAdminDisabledAndIsPlugin($pluginName); + + \Piwik\Plugin\Manager::getInstance()->deactivatePlugin($pluginName); + $this->redirectAfterModification($redirectAfter); + } + public function uninstall($redirectAfter = true) { $pluginName = $this->initPluginModification(static::UNINSTALL_NONCE); + // Uninstall is disabled in all cases (even for themes) - we do not use dieIfPluginAdminDisabledAndIsPlugin + $this->dieIfPluginsAdminIsDisabled(); $uninstalled = \Piwik\Plugin\Manager::getInstance()->uninstallPlugin($pluginName); @@ -448,9 +445,47 @@ class Controller extends Plugin\ControllerAdmin $this->redirectAfterModification($redirectAfter); } + protected function initPluginModification($nonceName) + { + Piwik::checkUserIsSuperUser(); + + $nonce = Common::getRequestVar('nonce', null, 'string'); + + if (!Nonce::verifyNonce($nonceName, $nonce)) { + throw new \Exception(Piwik::translate('General_ExceptionNonceMismatch')); + } + + Nonce::discardNonce($nonceName); + + $pluginName = Common::getRequestVar('pluginName', null, 'string'); + + return $pluginName; + } + + protected function redirectAfterModification($redirectAfter) + { + if ($redirectAfter) { + Url::redirectToReferrer(); + } + } + private function getPluginNamesHavingSettingsForCurrentUser() { return array_keys(SettingsManager::getPluginSettingsForCurrentUser()); } + protected function dieIfPluginAdminDisabledAndIsPlugin($pluginName) + { + $isTheme = false; + try { + $plugin = Plugin\Manager::getInstance()->loadPlugin($pluginName); + $isTheme = $plugin->isTheme(); + } catch (\Exception $e) { + echo $e->getMessage(); + } + if (!$isTheme) { + $this->dieIfPluginsAdminIsDisabled(); + } + } + } diff --git a/plugins/CorePluginsAdmin/CorePluginsAdmin.php b/plugins/CorePluginsAdmin/CorePluginsAdmin.php index 89a1357b82..cc71dad90d 100644 --- a/plugins/CorePluginsAdmin/CorePluginsAdmin.php +++ b/plugins/CorePluginsAdmin/CorePluginsAdmin.php @@ -100,6 +100,11 @@ class CorePluginsAdmin extends \Piwik\Plugin return (bool) Config::getInstance()->General['enable_marketplace']; } + public static function isPluginsAdminEnabled() + { + return (bool) Config::getInstance()->General['enable_plugins_admin']; + } + public function getJsFiles(&$jsFiles) { $jsFiles[] = "plugins/CoreHome/javascripts/popover.js"; diff --git a/plugins/CorePluginsAdmin/templates/macros.twig b/plugins/CorePluginsAdmin/templates/macros.twig index 07d64473a1..15fe28328e 100644 --- a/plugins/CorePluginsAdmin/templates/macros.twig +++ b/plugins/CorePluginsAdmin/templates/macros.twig @@ -88,7 +88,7 @@ {% endmacro %} -{% macro tablePlugins(pluginsInfo, pluginNamesHavingSettings, activateNonce, deactivateNonce, uninstallNonce, isTheme, marketplacePluginNames) %} +{% macro tablePlugins(pluginsInfo, pluginNamesHavingSettings, activateNonce, deactivateNonce, uninstallNonce, isTheme, marketplacePluginNames, displayAdminLinks) %} <div id="confirmUninstallPlugin" class="ui-confirm"> @@ -105,7 +105,9 @@ <th>{% if isTheme %}{{ 'CorePluginsAdmin_Theme'|translate }}{% else %}{{ 'General_Plugin'|translate }}{% endif %}</th> <th>{{ 'General_Description'|translate }}</th> <th class="status">{{ 'CorePluginsAdmin_Status'|translate }}</th> + {% if displayAdminLinks %} <th class="action-links">{{ 'General_Action'|translate }}</th> + {% endif %} </tr> </thead> <tbody id="plugins"> @@ -161,12 +163,13 @@ {{ 'CorePluginsAdmin_Active'|translate }} {% else %} {{ 'CorePluginsAdmin_Inactive'|translate }} - {% if plugin.uninstallable %} <br/> - <a data-pluginName="{{ name|escape('html_attr') }}" class="uninstall" href='index.php?module=CorePluginsAdmin&action=uninstall&pluginName={{ name }}&nonce={{ uninstallNonce }}'>{{ 'CorePluginsAdmin_ActionUninstall'|translate }}</a>{% endif %} + {% if plugin.uninstallable and displayAdminLinks %} <br/> - <a data-pluginName="{{ name|escape('html_attr') }}" class="uninstall" href='index.php?module=CorePluginsAdmin&action=uninstall&pluginName={{ name }}&nonce={{ uninstallNonce }}'>{{ 'CorePluginsAdmin_ActionUninstall'|translate }}</a>{% endif %} {% endif %} {%- endif %} </td> + {% if displayAdminLinks %} <td class="togl action-links" {% if isZeitgeist %}style="border-left-width:0px;"{% endif %}> {% if not isZeitgeist -%} @@ -182,6 +185,7 @@ {%- endif %} </td> + {% endif %} </tr> {% endif %} {% endfor %} diff --git a/plugins/CorePluginsAdmin/templates/plugins.twig b/plugins/CorePluginsAdmin/templates/plugins.twig index 37cade2ec4..18732a7a5f 100644 --- a/plugins/CorePluginsAdmin/templates/plugins.twig +++ b/plugins/CorePluginsAdmin/templates/plugins.twig @@ -15,11 +15,17 @@ <h2>{{ 'CorePluginsAdmin_PluginsManagement'|translate }}</h2> - <p>{{ 'CorePluginsAdmin_MainDescription'|translate }}</p> + <p>{{ 'CorePluginsAdmin_MainDescription'|translate }} + + {% if not isPluginsAdminEnabled %} + <br/>{{ 'CorePluginsAdmin_DoMoreContactPiwikAdmins'|translate }} + {% endif %} + + </p> {{ plugins.pluginsFilter(false, isMarketplaceEnabled) }} - {{ plugins.tablePlugins(pluginsInfo, pluginNamesHavingSettings, activateNonce, deactivateNonce, uninstallNonce, false, marketplacePluginNames) }} + {{ plugins.tablePlugins(pluginsInfo, pluginNamesHavingSettings, activateNonce, deactivateNonce, uninstallNonce, false, marketplacePluginNames, isPluginsAdminEnabled) }} </div> {% endblock %} \ No newline at end of file diff --git a/plugins/CorePluginsAdmin/templates/themes.twig b/plugins/CorePluginsAdmin/templates/themes.twig index 7fafac6c10..0930e48ca3 100644 --- a/plugins/CorePluginsAdmin/templates/themes.twig +++ b/plugins/CorePluginsAdmin/templates/themes.twig @@ -19,11 +19,15 @@ {% if otherUsersCount > 0 %} <br/> {{ 'CorePluginsAdmin_InfoThemeIsUsedByOtherUsersAsWell'|translate(otherUsersCount, themeEnabled) }} {% endif %} + {% if not isPluginsAdminEnabled %} + <br/>{{ 'CorePluginsAdmin_DoMoreContactPiwikAdmins'|translate }} + {% endif %} + </p> {{ plugins.pluginsFilter(true, isMarketplaceEnabled) }} - {{ plugins.tablePlugins(pluginsInfo, pluginNamesHavingSettings, activateNonce, deactivateNonce, uninstallNonce, true, marketplacePluginNames) }} + {{ plugins.tablePlugins(pluginsInfo, pluginNamesHavingSettings, activateNonce, deactivateNonce, uninstallNonce, true, marketplacePluginNames, true ) }} </div> {% endblock %} -- GitLab