From 4d2e6d2d8709da9168af824c36458dd5857b08a8 Mon Sep 17 00:00:00 2001 From: "Alexander A. Klimov" Date: Thu, 20 Oct 2016 18:28:19 +0200 Subject: [PATCH 1/4] Make hooks respect module permissions refs #12396 --- library/Icinga/Application/Modules/Module.php | 26 +++++++++++-------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/library/Icinga/Application/Modules/Module.php b/library/Icinga/Application/Modules/Module.php index de40266e1..555127228 100644 --- a/library/Icinga/Application/Modules/Module.php +++ b/library/Icinga/Application/Modules/Module.php @@ -4,6 +4,7 @@ namespace Icinga\Application\Modules; use Exception; +use Icinga\Authentication\Auth; use Zend_Controller_Router_Route; use Zend_Controller_Router_Route_Abstract; use Zend_Controller_Router_Route_Regex; @@ -1282,19 +1283,22 @@ class Module */ protected function provideHook($name, $implementation = null, $key = null) { - if ($implementation === null) { - $implementation = $name; + if (Auth::getInstance()->hasPermission('module/' . $this->name)) { + if ($implementation === null) { + $implementation = $name; + } + + if (strpos($implementation, '\\') === false) { + $class = $this->getNamespace() + . '\\ProvidedHook\\' + . $this->slashesToNamespace($implementation); + } else { + $class = $implementation; + } + + Hook::register($name, $class, $class); } - if (strpos($implementation, '\\') === false) { - $class = $this->getNamespace() - . '\\ProvidedHook\\' - . $this->slashesToNamespace($implementation); - } else { - $class = $implementation; - } - - Hook::register($name, $class, $class); return $this; } From 1cd2cfbdc944901b9379bbd1e1d53f8dbafc46fa Mon Sep 17 00:00:00 2001 From: "Alexander A. Klimov" Date: Thu, 20 Oct 2016 18:28:19 +0200 Subject: [PATCH 2/4] Revert "Make hooks respect module permissions" This reverts commit 4d2e6d2d8709da9168af824c36458dd5857b08a8. --- library/Icinga/Application/Modules/Module.php | 26 ++++++++----------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/library/Icinga/Application/Modules/Module.php b/library/Icinga/Application/Modules/Module.php index 555127228..de40266e1 100644 --- a/library/Icinga/Application/Modules/Module.php +++ b/library/Icinga/Application/Modules/Module.php @@ -4,7 +4,6 @@ namespace Icinga\Application\Modules; use Exception; -use Icinga\Authentication\Auth; use Zend_Controller_Router_Route; use Zend_Controller_Router_Route_Abstract; use Zend_Controller_Router_Route_Regex; @@ -1283,22 +1282,19 @@ class Module */ protected function provideHook($name, $implementation = null, $key = null) { - if (Auth::getInstance()->hasPermission('module/' . $this->name)) { - if ($implementation === null) { - $implementation = $name; - } - - if (strpos($implementation, '\\') === false) { - $class = $this->getNamespace() - . '\\ProvidedHook\\' - . $this->slashesToNamespace($implementation); - } else { - $class = $implementation; - } - - Hook::register($name, $class, $class); + if ($implementation === null) { + $implementation = $name; } + if (strpos($implementation, '\\') === false) { + $class = $this->getNamespace() + . '\\ProvidedHook\\' + . $this->slashesToNamespace($implementation); + } else { + $class = $implementation; + } + + Hook::register($name, $class, $class); return $this; } From 5bce7dc9b86e30068cc55e762f259772412081fd Mon Sep 17 00:00:00 2001 From: Johannes Meyer Date: Fri, 11 Nov 2016 16:15:16 +0100 Subject: [PATCH 3/4] Hook: Check a user's module permission before providing it's hook instances refs #12396 --- library/Icinga/Application/Hook.php | 59 ++++++++++++++++++++++++++--- 1 file changed, 53 insertions(+), 6 deletions(-) diff --git a/library/Icinga/Application/Hook.php b/library/Icinga/Application/Hook.php index b397be65a..33761a342 100644 --- a/library/Icinga/Application/Hook.php +++ b/library/Icinga/Application/Hook.php @@ -4,7 +4,8 @@ namespace Icinga\Application; use Exception; -use Icinga\Application\Logger; +use Icinga\Authentication\Auth; +use Icinga\Application\Modules\Manager; use Icinga\Exception\ProgrammingError; /** @@ -148,6 +149,46 @@ class Hook ); } + /** + * Extract the Icinga module name from a given namespaced class name + * + * Does no validation, prefix must have been checked before + * + * Shameless copy of ClassLoader::extractModuleName() + * + * @param string $class The hook's class path + * + * @return string + */ + protected static function extractModuleName($class) + { + return lcfirst( + substr( + $class, + ClassLoader::MODULE_PREFIX_LENGTH, + strpos( + $class, + ClassLoader::NAMESPACE_SEPARATOR, + ClassLoader::MODULE_PREFIX_LENGTH + 1 + ) - ClassLoader::MODULE_PREFIX_LENGTH + ) + ); + } + + /** + * Return whether the user has the permission to access the module which provides the given hook + * + * @param string $class The hook's class path + * + * @return bool + */ + protected static function hasPermission($class) + { + return Auth::getInstance()->hasPermission( + Manager::MODULE_PERMISSION_NS . self::extractModuleName($class) + ); + } + /** * Test for a valid class name * @@ -213,17 +254,19 @@ class Hook public static function all($name) { $name = self::normalizeHookName($name); - if (!self::has($name)) { + if (! self::has($name)) { return array(); } foreach (self::$hooks[$name] as $key => $hook) { - if (self::createInstance($name, $key) === null) { - return array(); + if (self::hasPermission($key)) { + if (self::createInstance($name, $key) === null) { + return array(); + } } } - return self::$instances[$name]; + return isset(self::$instances[$name]) ? self::$instances[$name] : array(); } /** @@ -238,7 +281,11 @@ class Hook $name = self::normalizeHookName($name); if (self::has($name)) { - return self::createInstance($name, key(self::$hooks[$name])); + foreach (self::$hooks[$name] as $key => $hook) { + if (self::hasPermission($key)) { + return self::createInstance($name, $key); + } + } } } From f1a1f411922f993e53780f5b5f3b17fc425814b1 Mon Sep 17 00:00:00 2001 From: Johannes Meyer Date: Fri, 11 Nov 2016 16:15:59 +0100 Subject: [PATCH 4/4] Module: Drop deprecated method registerHook and arg $key of method provideHook --- library/Icinga/Application/Modules/Module.php | 20 +------------------ 1 file changed, 1 insertion(+), 19 deletions(-) diff --git a/library/Icinga/Application/Modules/Module.php b/library/Icinga/Application/Modules/Module.php index de40266e1..b5eafbdb0 100644 --- a/library/Icinga/Application/Modules/Module.php +++ b/library/Icinga/Application/Modules/Module.php @@ -1242,22 +1242,6 @@ class Module return $this->includeScript($this->configScript); } - /** - * Register a hook - * - * @param string $name Name of the hook - * @param string $class Class of the hook w/ namespace - * @param string $key - * - * @return $this - * - * @deprecated Deprecated in favor of {@link provideHook()}. Will be removed in version 2.2.0 - */ - protected function registerHook($name, $class, $key = null) - { - return $this->provideHook($name, $class, $key); - } - protected function slashesToNamespace($class) { $list = explode('/', $class); @@ -1275,12 +1259,10 @@ class Module * @param string $implementation [optional] Fully qualified name of the class providing the hook implementation. * Defaults to the module's ProvidedHook namespace plus the hook's name for the * class name. Web 2's namespace separator is \\ (double backslash) at the moment - * @param string $key No-op arg for compatibility reasons. This argument is deprecated and will be - * removed in version 2.2.0 * * @return $this */ - protected function provideHook($name, $implementation = null, $key = null) + protected function provideHook($name, $implementation = null) { if ($implementation === null) { $implementation = $name;