commit
d2467fee16
|
@ -95,6 +95,7 @@ class ConfigController extends Controller
|
|||
*/
|
||||
public function modulesAction()
|
||||
{
|
||||
$this->assertPermission('config/modules');
|
||||
// Overwrite tabs created in init
|
||||
// @TODO(el): This seems not natural to me. Module configuration should have its own controller.
|
||||
$this->view->tabs = Widget::create('tabs')
|
||||
|
@ -120,6 +121,7 @@ class ConfigController extends Controller
|
|||
|
||||
public function moduleAction()
|
||||
{
|
||||
$this->assertPermission('config/modules');
|
||||
$app = Icinga::app();
|
||||
$manager = $app->getModuleManager();
|
||||
$name = $this->getParam('name');
|
||||
|
|
|
@ -12,7 +12,9 @@ class SearchController extends ActionController
|
|||
{
|
||||
public function indexAction()
|
||||
{
|
||||
$this->view->dashboard = SearchDashboard::search($this->params->get('q'));
|
||||
$searchDashboard = new SearchDashboard();
|
||||
$searchDashboard->setUser($this->Auth()->getUser());
|
||||
$this->view->dashboard = $searchDashboard->search($this->params->get('q'));
|
||||
|
||||
// NOTE: This renders the dashboard twice. Remove this once we can catch exceptions thrown in view scripts.
|
||||
$this->view->dashboard->render();
|
||||
|
|
|
@ -63,24 +63,34 @@ class RoleForm extends ConfigForm
|
|||
public function init()
|
||||
{
|
||||
$helper = new Zend_Form_Element('bogus');
|
||||
foreach (Icinga::app()->getModuleManager()->getLoadedModules() as $module) {
|
||||
$mm = Icinga::app()->getModuleManager();
|
||||
foreach ($mm->listInstalledModules() as $moduleName) {
|
||||
$modulePermission = $mm::MODULE_PERMISSION_NS . $moduleName;
|
||||
$this->providedPermissions[$modulePermission] = sprintf(
|
||||
$this->translate('Allow access to module %s') . ' (%s)',
|
||||
$moduleName,
|
||||
$modulePermission
|
||||
);
|
||||
|
||||
$module = $mm->getModule($moduleName, false);
|
||||
foreach ($module->getProvidedPermissions() as $permission) {
|
||||
/** @var object $permission */
|
||||
$this->providedPermissions[$permission->name] = $permission->description . ' (' . $permission->name . ')';
|
||||
$this->providedPermissions[$permission->name] = $permission->description
|
||||
. ' (' . $permission->name . ')';
|
||||
}
|
||||
foreach ($module->getProvidedRestrictions() as $restriction) {
|
||||
/** @var object $restriction */
|
||||
$name = $helper->filterName($restriction->name); // Zend only permits alphanumerics, the underscore,
|
||||
// the circumflex and any ASCII character in range
|
||||
// \x7f to \xff (127 to 255)
|
||||
// Zend only permits alphanumerics, the underscore, the circumflex and any ASCII character in range
|
||||
// \x7f to \xff (127 to 255)
|
||||
$name = $helper->filterName($restriction->name);
|
||||
while (isset($this->providedRestrictions[$name])) {
|
||||
// Because Zend_Form_Element::filterName() replaces any not permitted character with the empty
|
||||
// string we may have duplicate names, e.g. 're/striction' and 'restriction'
|
||||
$name .= '_';
|
||||
}
|
||||
$this->providedRestrictions[$name] = array(
|
||||
'description' => $restriction->description,
|
||||
'name' => $restriction->name
|
||||
'description' => $restriction->description,
|
||||
'name' => $restriction->name
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
<?php
|
||||
use Icinga\Web\Widget\SearchDashboard;
|
||||
?>
|
||||
|
||||
<? if (SearchDashboard::search('dummy')->getPane('search')->hasDashlets()): ?>
|
||||
use Icinga\Web\Widget\SearchDashboard;
|
||||
|
||||
$searchDashboard = new SearchDashboard();
|
||||
$searchDashboard->setUser($this->Auth()->getUser());
|
||||
|
||||
if ($searchDashboard->search('dummy')->getPane('search')->hasDashlets()): ?>
|
||||
<form action="<?= $this->href('search') ?>" method="get" role="search">
|
||||
<input
|
||||
type="text" name="q" id="search" class="search" placeholder="<?= $this->translate('Search') ?> …"
|
||||
|
@ -13,4 +16,4 @@ use Icinga\Web\Widget\SearchDashboard;
|
|||
<nav>
|
||||
<h1 id="navigation" class="sr-only"><?= t('Navigation'); ?></h1>
|
||||
<?= $menuRenderer; ?>
|
||||
</nav>
|
||||
</nav>
|
||||
|
|
|
@ -290,3 +290,9 @@ The first release candidate of Icinga Web 2 introduces the following non-backwar
|
|||
the [EPEL repository](http://fedoraproject.org/wiki/EPEL). Before, Zend was installed as Icinga Web 2 vendor library
|
||||
through the package `icingaweb2-vendor-zend`. After upgrading, please make sure to remove the package
|
||||
`icingaweb2-vendor-zend`.
|
||||
|
||||
* Icinga Web 2 version 2.0.0 requires permissions for accessing modules. Those permissions are automatically generated
|
||||
for each installed module in the format `module/<moduleName>`. Administrators have to grant the module permissions to
|
||||
users and/or user groups in the roles configuration for permitting access to specific modules.
|
||||
In addition, restrictions provided by modules are now configurable for each installed module too. Before,
|
||||
a module had to be enabled before having the possibility to configure restrictions.
|
||||
|
|
|
@ -3,9 +3,9 @@
|
|||
Access control is a vital part of configuring Icinga Web 2 in a secure way.
|
||||
It is important that not every user that has access to Icinga Web 2 is able
|
||||
to do any action or to see any host and service. For example, it is useful to allow
|
||||
only a small group of administrators to change the Icinga Web 2 configuration,
|
||||
to prevent misconfiguration or security breaches. Another important use case is
|
||||
creating groups of users which can only see the fraction of the monitoring
|
||||
only a small group of administrators to change the Icinga Web 2 configuration,
|
||||
to prevent misconfiguration or security breaches. Another important use case is
|
||||
creating groups of users which can only see the fraction of the monitoring
|
||||
environment they are in charge of.
|
||||
|
||||
This chapter will describe how to do the security configuration of Icinga Web 2
|
||||
|
@ -13,16 +13,16 @@ and how to apply permissions and restrictions to users or groups of users.
|
|||
|
||||
## Basics
|
||||
|
||||
Icinga Web 2 access control is done by defining **roles** that associate permissions
|
||||
and restrictions with **users** and **groups**. There are two general kinds of
|
||||
Icinga Web 2 access control is done by defining **roles** that associate permissions
|
||||
and restrictions with **users** and **groups**. There are two general kinds of
|
||||
things to which access can be managed: actions and objects.
|
||||
|
||||
|
||||
### Actions
|
||||
|
||||
Actions are all the things an Icinga Web 2 user can do, like changing a certain configuration,
|
||||
changing permissions or sending a command to the Icinga instance through the
|
||||
<a href="http://docs.icinga.org/icinga2/latest/doc/module/icinga2/toc#!/icinga2/latest/doc/module/icinga2/chapter/getting-started#setting-up-external-command-pipe">Command Pipe</a>
|
||||
changing permissions or sending a command to the Icinga instance through the
|
||||
<a href="http://docs.icinga.org/icinga2/latest/doc/module/icinga2/toc#!/icinga2/latest/doc/module/icinga2/chapter/getting-started#setting-up-external-command-pipe">Command Pipe</a>
|
||||
in the monitoring module. All actions must be be **allowed explicitly** using permissions.
|
||||
|
||||
A permission is a simple list of identifiers of actions a user is
|
||||
|
@ -43,7 +43,7 @@ in greater detail in the section [Restrictions](#restrictions).
|
|||
Anyone who can **login** to Icinga Web 2 is considered a user and can be referenced to by the
|
||||
**user name** used during login.
|
||||
For example, there might be user called **jdoe** authenticated
|
||||
using Active Directory, and a user **icingaadmin** that is authenticated using a MySQL-Database as backend.
|
||||
using Active Directory, and a user **icingaadmin** that is authenticated using a MySQL-Database as backend.
|
||||
In the configuration, both can be referenced to by using their user names **icingaadmin** or **jdoe**.
|
||||
|
||||
Icinga Web 2 users and groups are not configured by a configuration file, but provided by
|
||||
|
@ -87,7 +87,7 @@ users have access to all configuration options, or another role **support**
|
|||
could define that a list of users or groups is restricted to see only hosts and services
|
||||
that match a specific query.
|
||||
|
||||
The actual permission of a certain user will be determined by merging the permissions
|
||||
The actual permission of a certain user will be determined by merging the permissions
|
||||
and restrictions of the user itself and all the groups the user is member of. Permissions can
|
||||
be simply added up, while restrictions follow a slighty more complex pattern, that is described
|
||||
in the section [Stacking Filters](#stacking-filters).
|
||||
|
@ -126,12 +126,12 @@ Each role is defined as a section, with the name of the role as section name. Th
|
|||
attributes can be defined for each role in a default Icinga Web 2 installation:
|
||||
|
||||
|
||||
Directive | Description
|
||||
Directive | Description
|
||||
---------------------------|-----------------------------------------------------------------------------
|
||||
users | A comma-separated list of user **user names** that are affected by this role
|
||||
groups | A comma-separated list of **group names** that are affected by this role
|
||||
permissions | A comma-separated list of **permissions** granted by this role
|
||||
monitoring/filter/objects | A **filter expression** that restricts the access to services and hosts
|
||||
users | A comma-separated list of user **user names** that are affected by this role
|
||||
groups | A comma-separated list of **group names** that are affected by this role
|
||||
permissions | A comma-separated list of **permissions** granted by this role
|
||||
monitoring/filter/objects | A **filter expression** that restricts the access to services and hosts
|
||||
|
||||
|
||||
|
||||
|
@ -149,35 +149,39 @@ are in the namespace `config/modules`
|
|||
The permission `config/*` would grant permission to all configuration actions,
|
||||
while just specifying a wildcard `*` would give permission for all actions.
|
||||
|
||||
Access to modules is restricted to users who have the related module permission granted. Icinga Web 2 provides
|
||||
a module permission in the format `module/<moduleName>` for each installed module.
|
||||
|
||||
When multiple roles assign permissions to the same user (either directly or indirectly
|
||||
through a group) all permissions can simply be added together to get the users actual permission set.
|
||||
through a group) all permissions are added together to get the users actual permission set.
|
||||
|
||||
#### Global permissions
|
||||
### Global Permissions
|
||||
|
||||
Name | Permits
|
||||
-------------------------------------|-----------------------------------------------------------------
|
||||
* | Allow everything, including module-specific permissions
|
||||
config/* | Allow all configuration actions
|
||||
config/modules | Allow enabling or disabling modules
|
||||
Name | Permits
|
||||
--------------- ----|--------------------------------------------------------
|
||||
* | Allow everything, including module-specific permissions
|
||||
config/* | Allow all configuration actions
|
||||
config/modules | Allow enabling or disabling modules
|
||||
module/<moduleName> | Allow access to module <moduleName>
|
||||
|
||||
|
||||
#### Monitoring module permissions
|
||||
### Monitoring Module Permissions
|
||||
|
||||
The built-in monitoring module defines an additional set of permissions, that
|
||||
is described in detail in [monitoring module documentation](/icingaweb2/doc/module/doc/chapter/monitoring-security#monitoring-security).
|
||||
is described in detail in the [monitoring module documentation](/icingaweb2/doc/module/doc/chapter/monitoring-security#monitoring-security).
|
||||
|
||||
|
||||
## <a id="restrictions"></a> Restrictions
|
||||
|
||||
Restrictions can be used to define what a user or group can see by specifying
|
||||
a filter expression that applies to a defined set of data. By default, when no
|
||||
restrictions are defined, a user will be able to see every information that is available.
|
||||
a filter expression that applies to a defined set of data. By default, when no
|
||||
restrictions are defined, a user will be able to see every information that is available.
|
||||
|
||||
A restrictions is always specified for a certain **filter directive**, that defines what
|
||||
data the filter is applied to. The **filter directive** is a simple identifier, that was
|
||||
defined in an Icinga Web 2 module. The only filter directive that is available
|
||||
in a default installation, is the `monitoring/filter/objects` directive, defined by the monitoring module,
|
||||
that can be used to apply filter to hosts and services. This directive was previously
|
||||
that can be used to apply filter to hosts and services. This directive was previously
|
||||
mentioned in the section [Syntax](#syntax).
|
||||
|
||||
### Filter Expressions
|
||||
|
@ -251,7 +255,7 @@ Notice that because of the behavior of two stacking filters, a user that is memb
|
|||
#### Example 2: Hostgroups
|
||||
|
||||
[unix-server]
|
||||
groups = "unix-admins"
|
||||
groups = "unix-admins"
|
||||
monitoring/filter/objects = "(hostgroup_name=bsd-servers|hostgroup_name=linux-servers)"
|
||||
|
||||
This role allows all members of the group unix-admins to see hosts and services
|
||||
|
|
|
@ -24,6 +24,13 @@ use Icinga\Exception\NotReadableError;
|
|||
*/
|
||||
class Manager
|
||||
{
|
||||
/**
|
||||
* Namespace for module permissions
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const MODULE_PERMISSION_NS = 'module/';
|
||||
|
||||
/**
|
||||
* Array of all installed module's base directories
|
||||
*
|
||||
|
@ -401,22 +408,25 @@ class Manager
|
|||
}
|
||||
|
||||
/**
|
||||
* Return the module instance of the given module when it is loaded
|
||||
* Get a module
|
||||
*
|
||||
* @param string $name The module name to return
|
||||
* @param string $name Name of the module
|
||||
* @param bool $assertLoaded Whether or not to throw an exception if the module hasn't been loaded
|
||||
*
|
||||
* @return Module
|
||||
* @throws ProgrammingError When the module hasn't been loaded
|
||||
* @throws ProgrammingError If the module hasn't been loaded
|
||||
*/
|
||||
public function getModule($name)
|
||||
public function getModule($name, $assertLoaded = true)
|
||||
{
|
||||
if (!$this->hasLoaded($name)) {
|
||||
throw new ProgrammingError(
|
||||
'Cannot access module %s as it hasn\'t been loaded',
|
||||
$name
|
||||
);
|
||||
if ($this->hasLoaded($name)) {
|
||||
return $this->loadedModules[$name];
|
||||
} elseif (! (bool) $assertLoaded) {
|
||||
return new Module($this->app, $name, $this->getModuleDir($name));
|
||||
}
|
||||
return $this->loadedModules[$name];
|
||||
throw new ProgrammingError(
|
||||
'Can\'t access module %s because it hasn\'t been loaded',
|
||||
$name
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -102,7 +102,7 @@ class Module
|
|||
/**
|
||||
* Module metadata (version...)
|
||||
*
|
||||
* @var stdClass
|
||||
* @var object
|
||||
*/
|
||||
private $metadata;
|
||||
|
||||
|
@ -113,6 +113,13 @@ class Module
|
|||
*/
|
||||
private $triedToLaunchConfigScript = false;
|
||||
|
||||
/**
|
||||
* Whether the module's namespaces have been registered on our autoloader
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $registeredAutoloader = false;
|
||||
|
||||
/**
|
||||
* Whether this module has been registered
|
||||
*
|
||||
|
@ -199,87 +206,6 @@ class Module
|
|||
*/
|
||||
protected $userGroupBackends = array();
|
||||
|
||||
/**
|
||||
* Provide a search URL
|
||||
*
|
||||
* @param string $title
|
||||
* @param string $url
|
||||
* @param int $priority
|
||||
*/
|
||||
public function provideSearchUrl($title, $url, $priority = 0)
|
||||
{
|
||||
$searchUrl = (object) array(
|
||||
'title' => (string) $title,
|
||||
'url' => (string) $url,
|
||||
'priority' => (int) $priority
|
||||
);
|
||||
|
||||
$this->searchUrls[] = $searchUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return this module's search urls
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getSearchUrls()
|
||||
{
|
||||
$this->launchConfigScript();
|
||||
return $this->searchUrls;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all Menu Items
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getPaneItems()
|
||||
{
|
||||
$this->launchConfigScript();
|
||||
return $this->paneItems;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a pane to dashboard
|
||||
*
|
||||
* @param $name
|
||||
* @return Pane
|
||||
*/
|
||||
protected function dashboard($name)
|
||||
{
|
||||
$this->paneItems[$name] = new Pane($name);
|
||||
return $this->paneItems[$name];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all Menu Items
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getMenuItems()
|
||||
{
|
||||
$this->launchConfigScript();
|
||||
return $this->menuItems;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a menu Section to the Sidebar menu
|
||||
*
|
||||
* @param $name
|
||||
* @param array $properties
|
||||
* @return mixed
|
||||
*/
|
||||
protected function menuSection($name, array $properties = array())
|
||||
{
|
||||
if (array_key_exists($name, $this->menuItems)) {
|
||||
$this->menuItems[$name]->setProperties($properties);
|
||||
} else {
|
||||
$this->menuItems[$name] = new Menu($name, new ConfigObject($properties));
|
||||
}
|
||||
|
||||
return $this->menuItems[$name];
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new module object
|
||||
*
|
||||
|
@ -304,6 +230,91 @@ class Module
|
|||
$this->metadataFile = $basedir . '/module.info';
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide a search URL
|
||||
*
|
||||
* @param string $title
|
||||
* @param string $url
|
||||
* @param int $priority
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function provideSearchUrl($title, $url, $priority = 0)
|
||||
{
|
||||
$this->searchUrls[] = (object) array(
|
||||
'title' => (string) $title,
|
||||
'url' => (string) $url,
|
||||
'priority' => (int) $priority
|
||||
);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get this module's search urls
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getSearchUrls()
|
||||
{
|
||||
$this->launchConfigScript();
|
||||
return $this->searchUrls;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all pane items
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getPaneItems()
|
||||
{
|
||||
$this->launchConfigScript();
|
||||
return $this->paneItems;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a pane to dashboard
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
* @return Pane
|
||||
*/
|
||||
protected function dashboard($name)
|
||||
{
|
||||
$this->paneItems[$name] = new Pane($name);
|
||||
return $this->paneItems[$name];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all menu items
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getMenuItems()
|
||||
{
|
||||
$this->launchConfigScript();
|
||||
return $this->menuItems;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add or get a menu section
|
||||
*
|
||||
* @param string $name
|
||||
* @param array $properties
|
||||
*
|
||||
* @return Menu
|
||||
*/
|
||||
protected function menuSection($name, array $properties = array())
|
||||
{
|
||||
if (array_key_exists($name, $this->menuItems)) {
|
||||
$this->menuItems[$name]->setProperties($properties);
|
||||
} else {
|
||||
$this->menuItems[$name] = new Menu($name, new ConfigObject($properties));
|
||||
}
|
||||
|
||||
return $this->menuItems[$name];
|
||||
}
|
||||
|
||||
/**
|
||||
* Register module
|
||||
*
|
||||
|
@ -327,16 +338,16 @@ class Module
|
|||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->registerWebIntegration();
|
||||
$this->registered = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether this module has been registered
|
||||
* Get whether this module has been registered
|
||||
*
|
||||
* @return bool
|
||||
* @return bool
|
||||
*/
|
||||
public function isRegistered()
|
||||
{
|
||||
|
@ -346,9 +357,9 @@ class Module
|
|||
/**
|
||||
* Test for an enabled module by name
|
||||
*
|
||||
* @param string $name
|
||||
* @param string $name
|
||||
*
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
public static function exists($name)
|
||||
{
|
||||
|
@ -356,7 +367,7 @@ class Module
|
|||
}
|
||||
|
||||
/**
|
||||
* Get module by name
|
||||
* Get a module by name
|
||||
*
|
||||
* @param string $name
|
||||
* @param bool $autoload
|
||||
|
@ -418,7 +429,7 @@ class Module
|
|||
}
|
||||
|
||||
/**
|
||||
* Getter for module name
|
||||
* Get the module name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
|
@ -428,7 +439,7 @@ class Module
|
|||
}
|
||||
|
||||
/**
|
||||
* Getter for module version
|
||||
* Get the module version
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
|
@ -438,7 +449,7 @@ class Module
|
|||
}
|
||||
|
||||
/**
|
||||
* Get module description
|
||||
* Get the module description
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
|
@ -448,7 +459,7 @@ class Module
|
|||
}
|
||||
|
||||
/**
|
||||
* Get module title (short description)
|
||||
* Get the module title (short description)
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
|
@ -458,9 +469,9 @@ class Module
|
|||
}
|
||||
|
||||
/**
|
||||
* Getter for module version
|
||||
* Get the module dependencies
|
||||
*
|
||||
* @return Array
|
||||
* @return array
|
||||
*/
|
||||
public function getDependencies()
|
||||
{
|
||||
|
@ -555,7 +566,7 @@ class Module
|
|||
}
|
||||
|
||||
/**
|
||||
* Getter for css file name
|
||||
* Get the module's CSS directory
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
|
@ -565,17 +576,7 @@ class Module
|
|||
}
|
||||
|
||||
/**
|
||||
* Getter for base directory
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getBaseDir()
|
||||
{
|
||||
return $this->basedir;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the controller directory
|
||||
* Get the module's controller directory
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
|
@ -585,7 +586,17 @@ class Module
|
|||
}
|
||||
|
||||
/**
|
||||
* Getter for library directory
|
||||
* Get the module's base directory
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getBaseDir()
|
||||
{
|
||||
return $this->basedir;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the module's library directory
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
|
@ -595,7 +606,7 @@ class Module
|
|||
}
|
||||
|
||||
/**
|
||||
* Getter for configuration directory
|
||||
* Get the module's configuration directory
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
|
@ -605,7 +616,7 @@ class Module
|
|||
}
|
||||
|
||||
/**
|
||||
* Getter for form directory
|
||||
* Get the module's form directory
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
|
@ -615,11 +626,11 @@ class Module
|
|||
}
|
||||
|
||||
/**
|
||||
* Getter for module config object
|
||||
* Get the module config
|
||||
*
|
||||
* @param string $file
|
||||
* @param string $file
|
||||
*
|
||||
* @return Config
|
||||
* @return Config
|
||||
*/
|
||||
public function getConfig($file = 'config')
|
||||
{
|
||||
|
@ -627,9 +638,7 @@ class Module
|
|||
}
|
||||
|
||||
/**
|
||||
* Retrieve provided permissions
|
||||
*
|
||||
* @param string $name Permission name
|
||||
* Get provided permissions
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
|
@ -640,9 +649,8 @@ class Module
|
|||
}
|
||||
|
||||
/**
|
||||
* Retrieve provided restrictions
|
||||
* Get provided restrictions
|
||||
*
|
||||
* @param string $name Restriction name
|
||||
* @return array
|
||||
*/
|
||||
public function getProvidedRestrictions()
|
||||
|
@ -652,24 +660,11 @@ class Module
|
|||
}
|
||||
|
||||
/**
|
||||
* Whether the given permission name is supported
|
||||
* Whether the module provides the given restriction
|
||||
*
|
||||
* @param string $name Permission name
|
||||
* @param string $name Restriction name
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function providesPermission($name)
|
||||
{
|
||||
$this->launchConfigScript();
|
||||
return array_key_exists($name, $this->permissionList);
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the given restriction name is supported
|
||||
*
|
||||
* @param string $name Restriction name
|
||||
*
|
||||
* @return bool
|
||||
* @return bool
|
||||
*/
|
||||
public function providesRestriction($name)
|
||||
{
|
||||
|
@ -678,9 +673,22 @@ class Module
|
|||
}
|
||||
|
||||
/**
|
||||
* Retrieve this modules configuration tabs
|
||||
* Whether the module provides the given permission
|
||||
*
|
||||
* @return Icinga\Web\Widget\Tabs
|
||||
* @param string $name Permission name
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function providesPermission($name)
|
||||
{
|
||||
$this->launchConfigScript();
|
||||
return array_key_exists($name, $this->permissionList);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the module configuration tabs
|
||||
*
|
||||
* @return \Icinga\Web\Widget\Tabs
|
||||
*/
|
||||
public function getConfigTabs()
|
||||
{
|
||||
|
@ -698,9 +706,9 @@ class Module
|
|||
}
|
||||
|
||||
/**
|
||||
* Whether this module provides a setup wizard
|
||||
* Whether the module provides a setup wizard
|
||||
*
|
||||
* @return bool
|
||||
* @return bool
|
||||
*/
|
||||
public function providesSetupWizard()
|
||||
{
|
||||
|
@ -714,9 +722,9 @@ class Module
|
|||
}
|
||||
|
||||
/**
|
||||
* Return this module's setup wizard
|
||||
* Get the module's setup wizard
|
||||
*
|
||||
* @return SetupWizard
|
||||
* @return SetupWizard
|
||||
*/
|
||||
public function getSetupWizard()
|
||||
{
|
||||
|
@ -724,9 +732,9 @@ class Module
|
|||
}
|
||||
|
||||
/**
|
||||
* Return this module's user backends
|
||||
* Get the module's user backends
|
||||
*
|
||||
* @return array
|
||||
* @return array
|
||||
*/
|
||||
public function getUserBackends()
|
||||
{
|
||||
|
@ -735,9 +743,9 @@ class Module
|
|||
}
|
||||
|
||||
/**
|
||||
* Return this module's user group backends
|
||||
* Get the module's user group backends
|
||||
*
|
||||
* @return array
|
||||
* @return array
|
||||
*/
|
||||
public function getUserGroupBackends()
|
||||
{
|
||||
|
@ -748,10 +756,10 @@ class Module
|
|||
/**
|
||||
* Provide a named permission
|
||||
*
|
||||
* @param string $name Unique permission name
|
||||
* @param string $name Permission description
|
||||
* @param string $name Unique permission name
|
||||
* @param string $description Permission description
|
||||
*
|
||||
* @return void
|
||||
* @throws IcingaException If the permission is already provided
|
||||
*/
|
||||
protected function providePermission($name, $description)
|
||||
{
|
||||
|
@ -770,10 +778,10 @@ class Module
|
|||
/**
|
||||
* Provide a named restriction
|
||||
*
|
||||
* @param string $name Unique restriction name
|
||||
* @param string $description Restriction description
|
||||
* @param string $name Unique restriction name
|
||||
* @param string $description Restriction description
|
||||
*
|
||||
* @return void
|
||||
* @throws IcingaException If the restriction is already provided
|
||||
*/
|
||||
protected function provideRestriction($name, $description)
|
||||
{
|
||||
|
@ -792,15 +800,16 @@ class Module
|
|||
/**
|
||||
* Provide a module config tab
|
||||
*
|
||||
* @param string $name Unique tab name
|
||||
* @param string $config Tab config
|
||||
* @param string $name Unique tab name
|
||||
* @param array $config Tab config
|
||||
*
|
||||
* @return $this
|
||||
* @return $this
|
||||
* @throws ProgrammingError If $config lacks the key 'url'
|
||||
*/
|
||||
protected function provideConfigTab($name, $config = array())
|
||||
{
|
||||
if (! array_key_exists('url', $config)) {
|
||||
throw new ProgrammingError('A module config tab MUST provide and "url"');
|
||||
throw new ProgrammingError('A module config tab MUST provide a "url"');
|
||||
}
|
||||
$config['url'] = $this->getName() . '/' . ltrim($config['url'], '/');
|
||||
$this->configTabs[$name] = $config;
|
||||
|
@ -810,7 +819,7 @@ class Module
|
|||
/**
|
||||
* Provide a setup wizard
|
||||
*
|
||||
* @param string $className The name of the class
|
||||
* @param string $className The name of the class
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
|
@ -823,8 +832,8 @@ class Module
|
|||
/**
|
||||
* Provide a user backend capable of authenticating users
|
||||
*
|
||||
* @param string $identifier The identifier of the new backend type
|
||||
* @param string $className The name of the class
|
||||
* @param string $identifier The identifier of the new backend type
|
||||
* @param string $className The name of the class
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
|
@ -837,8 +846,8 @@ class Module
|
|||
/**
|
||||
* Provide a user group backend
|
||||
*
|
||||
* @param string $identifier The identifier of the new backend type
|
||||
* @param string $className The name of the class
|
||||
* @param string $identifier The identifier of the new backend type
|
||||
* @param string $className The name of the class
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
|
@ -849,12 +858,16 @@ class Module
|
|||
}
|
||||
|
||||
/**
|
||||
* Register new namespaces on the autoloader
|
||||
* Register module namespaces on the autoloader
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
protected function registerAutoloader()
|
||||
{
|
||||
if ($this->registeredAutoloader) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
$moduleName = ucfirst($this->getName());
|
||||
|
||||
$moduleLibraryDir = $this->getLibDir(). '/'. $moduleName;
|
||||
|
@ -867,6 +880,8 @@ class Module
|
|||
$this->app->getLoader()->registerNamespace('Icinga\\Module\\' . $moduleName. '\\Forms', $moduleFormDir);
|
||||
}
|
||||
|
||||
$this->registeredAutoloader = true;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
@ -884,7 +899,7 @@ class Module
|
|||
}
|
||||
|
||||
/**
|
||||
* return bool Whether this module has translations
|
||||
* Get whether the module has translations
|
||||
*/
|
||||
public function hasLocales()
|
||||
{
|
||||
|
@ -894,7 +909,7 @@ class Module
|
|||
/**
|
||||
* List all available locales
|
||||
*
|
||||
* return array Locale list
|
||||
* @return array Locale list
|
||||
*/
|
||||
public function listLocales()
|
||||
{
|
||||
|
@ -941,10 +956,9 @@ class Module
|
|||
}
|
||||
|
||||
/**
|
||||
* Add routes for static content and any route added via addRoute() to the route chain
|
||||
* Add routes for static content and any route added via {@link addRoute()} to the route chain
|
||||
*
|
||||
* @return $this
|
||||
* @see addRoute()
|
||||
* @return $this
|
||||
*/
|
||||
protected function registerRoutes()
|
||||
{
|
||||
|
@ -993,14 +1007,14 @@ class Module
|
|||
/**
|
||||
* Include a php script if it is readable
|
||||
*
|
||||
* @param string $file File to include
|
||||
* @param string $file File to include
|
||||
*
|
||||
* @return $this
|
||||
* @return $this
|
||||
*/
|
||||
protected function includeScript($file)
|
||||
{
|
||||
if (file_exists($file) && is_readable($file) === true) {
|
||||
include($file);
|
||||
if (file_exists($file) && is_readable($file)) {
|
||||
include $file;
|
||||
}
|
||||
|
||||
return $this;
|
||||
|
@ -1008,28 +1022,27 @@ class Module
|
|||
|
||||
/**
|
||||
* Run module config script
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
protected function launchConfigScript()
|
||||
{
|
||||
if ($this->triedToLaunchConfigScript || !$this->registered) {
|
||||
return;
|
||||
if ($this->triedToLaunchConfigScript) {
|
||||
return $this;
|
||||
}
|
||||
$this->triedToLaunchConfigScript = true;
|
||||
if (! file_exists($this->configScript)
|
||||
|| ! is_readable($this->configScript)) {
|
||||
return;
|
||||
}
|
||||
include($this->configScript);
|
||||
$this->registerAutoloader();
|
||||
return $this->includeScript($this->configScript);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register hook
|
||||
*
|
||||
* @param string $name
|
||||
* @param string $class
|
||||
* @param string $key
|
||||
* @param string $name
|
||||
* @param string $class
|
||||
* @param string $key
|
||||
*
|
||||
* @return $this
|
||||
* @return $this
|
||||
*/
|
||||
protected function registerHook($name, $class, $key = null)
|
||||
{
|
||||
|
@ -1058,12 +1071,8 @@ class Module
|
|||
}
|
||||
|
||||
/**
|
||||
* Translate a string with the global mt()
|
||||
*
|
||||
* @param $string
|
||||
* @param null $context
|
||||
*
|
||||
* @return mixed|string
|
||||
* (non-PHPDoc)
|
||||
* @see Translator::translate() For the function documentation.
|
||||
*/
|
||||
protected function translate($string, $context = null)
|
||||
{
|
||||
|
|
|
@ -4,17 +4,19 @@
|
|||
namespace Icinga\Exception;
|
||||
|
||||
use Exception;
|
||||
use ReflectionClass;
|
||||
|
||||
class IcingaException extends Exception
|
||||
{
|
||||
/**
|
||||
* @param string $message format string for vsprintf()
|
||||
* Any futher args: args for vsprintf()
|
||||
* @see vsprintf
|
||||
* Create a new exception
|
||||
*
|
||||
* If there is at least one exception, the last one will be also used for the exception chaining.
|
||||
* @param string $message Exception message or exception format string
|
||||
* @param mixed ...$arg Format string argument
|
||||
*
|
||||
* If there is at least one exception, the last one will be used for exception chaining.
|
||||
*/
|
||||
public function __construct($message = '')
|
||||
public function __construct($message)
|
||||
{
|
||||
$args = array_slice(func_get_args(), 1);
|
||||
$exc = null;
|
||||
|
@ -26,6 +28,19 @@ class IcingaException extends Exception
|
|||
parent::__construct(vsprintf($message, $args), 0, $exc);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the exception from an array of arguments
|
||||
*
|
||||
* @param array $args
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
public static function create(array $args)
|
||||
{
|
||||
$e = new ReflectionClass(get_called_class());
|
||||
return $e->newInstanceArgs($args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the given exception formatted as one-liner
|
||||
*
|
||||
|
|
|
@ -53,13 +53,14 @@ class Controller extends ModuleActionController
|
|||
/**
|
||||
* Immediately respond w/ HTTP 404
|
||||
*
|
||||
* @param $message
|
||||
* @param string $message Exception message or exception format string
|
||||
* @param mixed ...$arg Format string argument
|
||||
*
|
||||
* @throws HttpNotFoundException
|
||||
*/
|
||||
public function httpNotFound($message)
|
||||
{
|
||||
throw new HttpNotFoundException($message);
|
||||
throw HttpNotFoundException::create(func_get_args());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -155,7 +155,7 @@ class ActionController extends Zend_Controller_Action
|
|||
*/
|
||||
public function assertPermission($permission)
|
||||
{
|
||||
if (! $this->Auth()->hasPermission($permission)) {
|
||||
if ($this->requiresAuthentication && ! $this->Auth()->hasPermission($permission)) {
|
||||
throw new SecurityException('No permission for %s', $permission);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ namespace Icinga\Web\Controller;
|
|||
|
||||
use Icinga\Application\Config;
|
||||
use Icinga\Application\Icinga;
|
||||
use Icinga\Application\Modules\Manager;
|
||||
|
||||
/**
|
||||
* Base class for module action controllers
|
||||
|
@ -34,6 +35,9 @@ class ModuleActionController extends ActionController
|
|||
$this->_helper->layout()->moduleName = $this->moduleName;
|
||||
$this->view->translationDomain = $this->moduleName;
|
||||
$this->moduleInit();
|
||||
if ($this->getFrontController()->getDefaultModule() !== $this->moduleName) {
|
||||
$this->assertPermission(Manager::MODULE_PERMISSION_NS . $this->moduleName);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -206,13 +206,14 @@ class Menu implements RecursiveIterator
|
|||
*/
|
||||
public static function load()
|
||||
{
|
||||
/** @var $menu \Icinga\Web\Menu */
|
||||
$menu = new static('menu');
|
||||
$menu->addMainMenuItems();
|
||||
$auth = Manager::getInstance();
|
||||
$manager = Icinga::app()->getModuleManager();
|
||||
foreach ($manager->getLoadedModules() as $module) {
|
||||
/** @var $module \Icinga\Application\Modules\Module */
|
||||
$menu->mergeSubMenus($module->getMenuItems());
|
||||
if ($auth->hasPermission($manager::MODULE_PERMISSION_NS . $module->getName())) {
|
||||
$menu->mergeSubMenus($module->getMenuItems());
|
||||
}
|
||||
}
|
||||
return $menu->order();
|
||||
}
|
||||
|
|
|
@ -70,13 +70,13 @@ class Dashboard extends AbstractWidget
|
|||
{
|
||||
$manager = Icinga::app()->getModuleManager();
|
||||
foreach ($manager->getLoadedModules() as $module) {
|
||||
/** @var $module \Icinga\Application\Modules\Module */
|
||||
$this->mergePanes($module->getPaneItems());
|
||||
if ($this->getUser()->can($manager::MODULE_PERMISSION_NS . $module->getName())) {
|
||||
$this->mergePanes($module->getPaneItems());
|
||||
}
|
||||
|
||||
}
|
||||
if ($this->user !== null) {
|
||||
$this->loadUserDashboards();
|
||||
}
|
||||
|
||||
$this->loadUserDashboards();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
@ -90,11 +90,11 @@ class Dashboard extends AbstractWidget
|
|||
{
|
||||
$output = array();
|
||||
foreach ($this->panes as $pane) {
|
||||
if ($pane->isUserWidget() === true) {
|
||||
if ($pane->isUserWidget()) {
|
||||
$output[$pane->getName()] = $pane->toArray();
|
||||
}
|
||||
foreach ($pane->getDashlets() as $dashlet) {
|
||||
if ($dashlet->isUserWidget() === true) {
|
||||
if ($dashlet->isUserWidget()) {
|
||||
$output[$pane->getName() . '.' . $dashlet->getTitle()] = $dashlet->toArray();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,6 +12,11 @@ use Icinga\Web\Url;
|
|||
*/
|
||||
class SearchDashboard extends Dashboard
|
||||
{
|
||||
/**
|
||||
* Name for the search pane
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const SEARCH_PANE = 'search';
|
||||
|
||||
/**
|
||||
|
@ -19,13 +24,39 @@ class SearchDashboard extends Dashboard
|
|||
*
|
||||
* @param string $searchString
|
||||
*
|
||||
* @return Dashboard|SearchDashboard
|
||||
* @return $this
|
||||
*/
|
||||
public static function search($searchString = '')
|
||||
public function search($searchString = '')
|
||||
{
|
||||
$dashboard = new static('searchDashboard');
|
||||
$dashboard->loadSearchDashlets($searchString);
|
||||
return $dashboard;
|
||||
$pane = $this->createPane(self::SEARCH_PANE)->getPane(self::SEARCH_PANE)->setTitle(t('Search'));
|
||||
$this->activate(self::SEARCH_PANE);
|
||||
|
||||
$manager = Icinga::app()->getModuleManager();
|
||||
$searchUrls = array();
|
||||
|
||||
foreach ($manager->getLoadedModules() as $module) {
|
||||
if ($this->getUser()->can($manager::MODULE_PERMISSION_NS . $module->getName())) {
|
||||
$moduleSearchUrls = $module->getSearchUrls();
|
||||
if (! empty($moduleSearchUrls)) {
|
||||
if ($searchString === '') {
|
||||
$pane->add(t('Ready to search'), 'search/hint');
|
||||
return $this;
|
||||
}
|
||||
$searchUrls = array_merge($searchUrls, $moduleSearchUrls);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
usort($searchUrls, array($this, 'compareSearchUrls'));
|
||||
|
||||
foreach (array_reverse($searchUrls) as $searchUrl) {
|
||||
$pane->addDashlet(
|
||||
$searchUrl->title . ': ' . $searchString,
|
||||
Url::fromPath($searchUrl->url, array('q' => $searchString))
|
||||
);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -43,40 +74,6 @@ class SearchDashboard extends Dashboard
|
|||
return parent::render();
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads search dashlets
|
||||
*
|
||||
* @param string $searchString
|
||||
*/
|
||||
protected function loadSearchDashlets($searchString)
|
||||
{
|
||||
$pane = $this->createPane(self::SEARCH_PANE)->getPane(self::SEARCH_PANE)->setTitle(t('Search'));
|
||||
$this->activate(self::SEARCH_PANE);
|
||||
|
||||
$manager = Icinga::app()->getModuleManager();
|
||||
$searchUrls = array();
|
||||
|
||||
foreach ($manager->getLoadedModules() as $module) {
|
||||
$moduleSearchUrls = $module->getSearchUrls();
|
||||
if (! empty($moduleSearchUrls)) {
|
||||
if ($searchString === '') {
|
||||
$pane->add(t('Ready to search'), 'search/hint');
|
||||
return;
|
||||
}
|
||||
$searchUrls = array_merge($searchUrls, $moduleSearchUrls);
|
||||
}
|
||||
}
|
||||
|
||||
usort($searchUrls, array($this, 'compareSearchUrls'));
|
||||
|
||||
foreach (array_reverse($searchUrls) as $searchUrl) {
|
||||
$pane->addDashlet(
|
||||
$searchUrl->title . ': ' . $searchString,
|
||||
Url::fromPath($searchUrl->url, array('q' => $searchString))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare search URLs based on their priority
|
||||
*
|
||||
|
|
|
@ -38,17 +38,11 @@ class Doc_IcingawebController extends DocController
|
|||
/**
|
||||
* View a chapter of Icinga Web 2's documentation
|
||||
*
|
||||
* @throws Zend_Controller_Action_Exception If the required parameter 'chapterId' is missing
|
||||
* @throws \Icinga\Exception\MissingParameterException If the required parameter 'chapter' is missing
|
||||
*/
|
||||
public function chapterAction()
|
||||
{
|
||||
$chapter = $this->getParam('chapter');
|
||||
if ($chapter === null) {
|
||||
throw new Zend_Controller_Action_Exception(
|
||||
sprintf($this->translate('Missing parameter %s'), 'chapter'),
|
||||
404
|
||||
);
|
||||
}
|
||||
$chapter = $this->params->getRequired('chapter');
|
||||
$this->renderChapter(
|
||||
$this->getPath(),
|
||||
$chapter,
|
||||
|
|
|
@ -10,16 +10,15 @@ class Doc_ModuleController extends DocController
|
|||
/**
|
||||
* Get the path to a module documentation
|
||||
*
|
||||
* @param string $module The name of the module
|
||||
* @param string $default The default path
|
||||
* @param bool $suppressErrors Whether to not throw an exception if the module documentation is not
|
||||
* available
|
||||
* @param string $module The name of the module
|
||||
* @param string $default The default path
|
||||
* @param bool $suppressErrors Whether to not throw an exception if the module documentation is not available
|
||||
*
|
||||
* @return string|null Path to the documentation or null if the module documentation is not
|
||||
* available and errors are suppressed
|
||||
* @return string|null Path to the documentation or null if the module documentation is not available
|
||||
* and errors are suppressed
|
||||
*
|
||||
* @throws Zend_Controller_Action_Exception If the module documentation is not available and errors are not
|
||||
* suppressed
|
||||
* @throws \Icinga\Exception\Http\HttpNotFoundException If the module documentation is not available and errors
|
||||
* are not suppressed
|
||||
*/
|
||||
protected function getPath($module, $default, $suppressErrors = false)
|
||||
{
|
||||
|
@ -35,10 +34,7 @@ class Doc_ModuleController extends DocController
|
|||
if ($suppressErrors) {
|
||||
return null;
|
||||
}
|
||||
throw new Zend_Controller_Action_Exception(
|
||||
sprintf($this->translate('Documentation for module \'%s\' is not available'), $module),
|
||||
404
|
||||
);
|
||||
$this->httpNotFound($this->translate('Documentation for module \'%s\' is not available'), $module);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -48,55 +44,41 @@ class Doc_ModuleController extends DocController
|
|||
{
|
||||
$moduleManager = Icinga::app()->getModuleManager();
|
||||
$modules = array();
|
||||
foreach ($moduleManager->listEnabledModules() as $module) {
|
||||
foreach ($moduleManager->listInstalledModules() as $module) {
|
||||
$path = $this->getPath($module, $moduleManager->getModuleDir($module, '/doc'), true);
|
||||
if ($path !== null) {
|
||||
$modules[] = $moduleManager->getModule($module);
|
||||
$modules[] = $moduleManager->getModule($module, false);
|
||||
}
|
||||
}
|
||||
$this->view->modules = $modules;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert that the given module is enabled
|
||||
* Assert that the given module is installed
|
||||
*
|
||||
* @param $moduleName
|
||||
* @param string $moduleName
|
||||
*
|
||||
* @throws Zend_Controller_Action_Exception If the required parameter 'moduleName' is empty or either if the
|
||||
* given module is neither installed nor enabled
|
||||
* @throws \Icinga\Exception\Http\HttpNotFoundException If the given module is not installed
|
||||
*/
|
||||
protected function assertModuleEnabled($moduleName)
|
||||
protected function assertModuleInstalled($moduleName)
|
||||
{
|
||||
if (empty($moduleName)) {
|
||||
throw new Zend_Controller_Action_Exception(
|
||||
sprintf($this->translate('Missing parameter \'%s\''), 'moduleName'),
|
||||
404
|
||||
);
|
||||
}
|
||||
$moduleManager = Icinga::app()->getModuleManager();
|
||||
if (! $moduleManager->hasInstalled($moduleName)) {
|
||||
throw new Zend_Controller_Action_Exception(
|
||||
sprintf($this->translate('Module \'%s\' is not installed'), $moduleName),
|
||||
404
|
||||
);
|
||||
}
|
||||
if (! $moduleManager->hasEnabled($moduleName)) {
|
||||
throw new Zend_Controller_Action_Exception(
|
||||
sprintf($this->translate('Module \'%s\' is not enabled'), $moduleName),
|
||||
404
|
||||
);
|
||||
$this->httpNotFound($this->translate('Module \'%s\' is not installed'), $moduleName);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* View the toc of a module's documentation
|
||||
*
|
||||
* @see assertModuleEnabled()
|
||||
* @throws \Icinga\Exception\MissingParameterException If the required parameter 'moduleName' is empty
|
||||
* @throws \Icinga\Exception\Http\HttpNotFoundException If the given module is not installed
|
||||
* @see assertModuleInstalled()
|
||||
*/
|
||||
public function tocAction()
|
||||
{
|
||||
$module = $this->getParam('moduleName');
|
||||
$this->assertModuleEnabled($module);
|
||||
$module = $this->params->getRequired('moduleName');
|
||||
$this->assertModuleInstalled($module);
|
||||
$this->view->moduleName = $module;
|
||||
try {
|
||||
$this->renderToc(
|
||||
|
@ -106,28 +88,23 @@ class Doc_ModuleController extends DocController
|
|||
array('moduleName' => $module)
|
||||
);
|
||||
} catch (DocException $e) {
|
||||
throw new Zend_Controller_Action_Exception($e->getMessage(), 404);
|
||||
$this->httpNotFound($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* View a chapter of a module's documentation
|
||||
*
|
||||
* @throws Zend_Controller_Action_Exception If the required parameter 'chapterId' is missing or if an error in
|
||||
* the documentation module's library occurs
|
||||
* @see assertModuleEnabled()
|
||||
* @throws \Icinga\Exception\MissingParameterException If one of the required parameters 'moduleName' and
|
||||
* 'chapter' is empty
|
||||
* @throws \Icinga\Exception\Http\HttpNotFoundException If the given module is not installed
|
||||
* @see assertModuleInstalled()
|
||||
*/
|
||||
public function chapterAction()
|
||||
{
|
||||
$module = $this->getParam('moduleName');
|
||||
$this->assertModuleEnabled($module);
|
||||
$chapter = $this->getParam('chapter');
|
||||
if ($chapter === null) {
|
||||
throw new Zend_Controller_Action_Exception(
|
||||
sprintf($this->translate('Missing parameter %s'), 'chapter'),
|
||||
404
|
||||
);
|
||||
}
|
||||
$module = $this->params->getRequired('moduleName');
|
||||
$this->assertModuleInstalled($module);
|
||||
$chapter = $this->params->getRequired('chapter');
|
||||
$this->view->moduleName = $module;
|
||||
try {
|
||||
$this->renderChapter(
|
||||
|
@ -137,19 +114,21 @@ class Doc_ModuleController extends DocController
|
|||
array('moduleName' => $module)
|
||||
);
|
||||
} catch (DocException $e) {
|
||||
throw new Zend_Controller_Action_Exception($e->getMessage(), 404);
|
||||
$this->httpNotFound($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* View a module's documentation as PDF
|
||||
*
|
||||
* @see assertModuleEnabled()
|
||||
* @throws \Icinga\Exception\MissingParameterException If the required parameter 'moduleName' is empty
|
||||
* @throws \Icinga\Exception\Http\HttpNotFoundException If the given module is not installed
|
||||
* @see assertModuleInstalled()
|
||||
*/
|
||||
public function pdfAction()
|
||||
{
|
||||
$module = $this->getParam('moduleName');
|
||||
$this->assertModuleEnabled($module);
|
||||
$module = $this->params->getRequired('moduleName');
|
||||
$this->assertModuleInstalled($module);
|
||||
$this->renderPdf(
|
||||
$this->getPath($module, Icinga::app()->getModuleManager()->getModuleDir($module, '/doc')),
|
||||
$module,
|
||||
|
|
|
@ -92,9 +92,6 @@ class Doc_SearchController extends DocController
|
|||
return $path;
|
||||
}
|
||||
}
|
||||
throw new Zend_Controller_Action_Exception(
|
||||
$this->translate('Documentation for Icinga Web 2 is not available'),
|
||||
404
|
||||
);
|
||||
$this->httpNotFound($this->translate('Documentation for Icinga Web 2 is not available'));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
$this->translate('Module documentations'),
|
||||
'doc/module/',
|
||||
null,
|
||||
array('title' => $this->translate('List all modifications for which documentation is available'))
|
||||
array('title' => $this->translate('List all modules for which documentation is available'))
|
||||
); ?></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
</div>
|
||||
<div class="content">
|
||||
<ul>
|
||||
<?php foreach ($modules as $module): ?>
|
||||
<?php foreach ($modules as $module): /** @var \Icinga\Application\Modules\Module $module */ ?>
|
||||
<li><?= $this->qlink(
|
||||
$module->getTitle(),
|
||||
'doc/module/toc',
|
||||
|
|
|
@ -8,11 +8,11 @@ namespace Tests\Icinga\Web;
|
|||
require_once realpath(dirname(__FILE__) . '/../../../../bootstrap.php');
|
||||
|
||||
use Mockery;
|
||||
use Icinga\Application\Icinga;
|
||||
use Icinga\Test\BaseTestCase;
|
||||
use Icinga\User;
|
||||
use Icinga\Web\Widget\Dashboard;
|
||||
use Icinga\Web\Widget\Dashboard\Pane;
|
||||
use Icinga\Web\Widget\Dashboard\Dashlet;
|
||||
use Icinga\Test\BaseTestCase;
|
||||
|
||||
class DashletWithMockedView extends Dashlet
|
||||
{
|
||||
|
@ -52,6 +52,7 @@ class DashboardTest extends BaseTestCase
|
|||
$moduleMock->shouldReceive('getPaneItems')->andReturn(array(
|
||||
'test-pane' => new Pane('Test Pane')
|
||||
));
|
||||
$moduleMock->shouldReceive('getName')->andReturn('test');
|
||||
|
||||
$moduleManagerMock = Mockery::mock('Icinga\Application\Modules\Manager');
|
||||
$moduleManagerMock->shouldReceive('getLoadedModules')->andReturn(array(
|
||||
|
@ -130,7 +131,10 @@ class DashboardTest extends BaseTestCase
|
|||
*/
|
||||
public function testLoadPaneItemsProvidedByEnabledModules()
|
||||
{
|
||||
$user = new User('test');
|
||||
$user->setPermissions(array('*' => '*'));
|
||||
$dashboard = new Dashboard();
|
||||
$dashboard->setUser($user);
|
||||
$dashboard->load();
|
||||
|
||||
$this->assertCount(
|
||||
|
|
|
@ -5,6 +5,7 @@ namespace Tests\Icinga\Web;
|
|||
|
||||
use Mockery;
|
||||
use Icinga\Test\BaseTestCase;
|
||||
use Icinga\User;
|
||||
use Icinga\Web\Widget\SearchDashboard;
|
||||
|
||||
class SearchDashboardTest extends BaseTestCase
|
||||
|
@ -19,6 +20,7 @@ class SearchDashboardTest extends BaseTestCase
|
|||
$moduleMock->shouldReceive('getSearchUrls')->andReturn(array(
|
||||
$searchUrl
|
||||
));
|
||||
$moduleMock->shouldReceive('getName')->andReturn('test');
|
||||
|
||||
$moduleManagerMock = Mockery::mock('Icinga\Application\Modules\Manager');
|
||||
$moduleManagerMock->shouldReceive('getLoadedModules')->andReturn(array(
|
||||
|
@ -34,14 +36,22 @@ class SearchDashboardTest extends BaseTestCase
|
|||
*/
|
||||
public function testWhetherRenderThrowsAnExceptionWhenHasNoDashlets()
|
||||
{
|
||||
$dashboard = SearchDashboard::search('pending');
|
||||
$user = new User('test');
|
||||
$user->setPermissions(array('*' => '*'));
|
||||
$dashboard = new SearchDashboard();
|
||||
$dashboard->setUser($user);
|
||||
$dashboard = $dashboard->search('pending');
|
||||
$dashboard->getPane('search')->removeDashlets();
|
||||
$dashboard->render();
|
||||
}
|
||||
|
||||
public function testWhetherSearchLoadsSearchDashletsFromModules()
|
||||
{
|
||||
$dashboard = SearchDashboard::search('pending');
|
||||
$user = new User('test');
|
||||
$user->setPermissions(array('*' => '*'));
|
||||
$dashboard = new SearchDashboard();
|
||||
$dashboard->setUser($user);
|
||||
$dashboard = $dashboard->search('pending');
|
||||
|
||||
$result = $dashboard->getPane('search')->hasDashlet('Hosts: pending');
|
||||
|
||||
|
@ -50,7 +60,11 @@ class SearchDashboardTest extends BaseTestCase
|
|||
|
||||
public function testWhetherSearchProvidesHintWhenSearchStringIsEmpty()
|
||||
{
|
||||
$dashboard = SearchDashboard::search();
|
||||
$user = new User('test');
|
||||
$user->setPermissions(array('*' => '*'));
|
||||
$dashboard = new SearchDashboard();
|
||||
$dashboard->setUser($user);
|
||||
$dashboard = $dashboard->search();
|
||||
|
||||
$result = $dashboard->getPane('search')->hasDashlet('Ready to search');
|
||||
|
||||
|
|
Loading…
Reference in New Issue