Merge branch 'bugfix/hooks-don-t-respect-module-permissions-12396'

fixes #12396
This commit is contained in:
Johannes Meyer 2016-11-14 09:46:08 +01:00
commit 7d98025d7d
2 changed files with 54 additions and 25 deletions

View File

@ -4,7 +4,8 @@
namespace Icinga\Application; namespace Icinga\Application;
use Exception; use Exception;
use Icinga\Application\Logger; use Icinga\Authentication\Auth;
use Icinga\Application\Modules\Manager;
use Icinga\Exception\ProgrammingError; 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 * Test for a valid class name
* *
@ -213,17 +254,19 @@ class Hook
public static function all($name) public static function all($name)
{ {
$name = self::normalizeHookName($name); $name = self::normalizeHookName($name);
if (!self::has($name)) { if (! self::has($name)) {
return array(); return array();
} }
foreach (self::$hooks[$name] as $key => $hook) { foreach (self::$hooks[$name] as $key => $hook) {
if (self::hasPermission($key)) {
if (self::createInstance($name, $key) === null) { if (self::createInstance($name, $key) === null) {
return array(); 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); $name = self::normalizeHookName($name);
if (self::has($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);
}
}
} }
} }

View File

@ -1242,22 +1242,6 @@ class Module
return $this->includeScript($this->configScript); 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) protected function slashesToNamespace($class)
{ {
$list = explode('/', $class); $list = explode('/', $class);
@ -1275,12 +1259,10 @@ class Module
* @param string $implementation [optional] Fully qualified name of the class providing the hook implementation. * @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 * 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 * 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 * @return $this
*/ */
protected function provideHook($name, $implementation = null, $key = null) protected function provideHook($name, $implementation = null)
{ {
if ($implementation === null) { if ($implementation === null) {
$implementation = $name; $implementation = $name;