diff --git a/application/forms/Dashboard/DashletForm.php b/application/forms/Dashboard/DashletForm.php index 68e07225a..ecfacb3d4 100644 --- a/application/forms/Dashboard/DashletForm.php +++ b/application/forms/Dashboard/DashletForm.php @@ -8,6 +8,7 @@ use Icinga\Application\Logger; use Icinga\Web\Dashboard\Common\BaseDashboard; use Icinga\Web\Dashboard\Dashboard; use Icinga\Web\Dashboard\DashboardHome; +use Icinga\Util\DBUtils; use Icinga\Web\Notification; use Icinga\Web\Dashboard\Dashlet; use Icinga\Web\Dashboard\Pane; @@ -155,7 +156,7 @@ class DashletForm extends SetupNewDashboardForm protected function onSuccess() { - $conn = Dashboard::getConn(); + $conn = DBUtils::getConn(); $dashboard = $this->dashboard; $selectedHome = $this->getPopulatedValue('home'); @@ -263,10 +264,12 @@ class DashletForm extends SetupNewDashboardForm } $currentPane->setHome($currentHome); - // When the user wishes to create a new dashboard pane, we have to explicitly reset the dashboard panes - // of the original home, so that it isn't considered as we want to move the pane even though it isn't - // supposed to when the original home contains a dashboard with the same name - // @see DashboardHome::manageEntries() for details + /** + * When the user wishes to create a new dashboard pane, we have to explicitly reset the dashboard panes + * of the original home, so that it isn't considered as we want to move the pane even though it isn't + * supposed to when the original home contains a dashboard with the same name + * {@see DashboardHome::manageEntry()} for details + */ $selectedPane = $this->getPopulatedValue('pane'); if ((! $selectedPane || $selectedPane === self::CREATE_NEW_PANE) && ! $currentHome->hasEntry($currentPane->getName())) { diff --git a/application/forms/Dashboard/HomePaneForm.php b/application/forms/Dashboard/HomePaneForm.php index 1da1fa972..85ddffcbf 100644 --- a/application/forms/Dashboard/HomePaneForm.php +++ b/application/forms/Dashboard/HomePaneForm.php @@ -7,6 +7,7 @@ namespace Icinga\Forms\Dashboard; use Icinga\Application\Logger; use Icinga\Web\Dashboard\Common\BaseDashboard; use Icinga\Web\Dashboard\DashboardHome; +use Icinga\Util\DBUtils; use Icinga\Web\Notification; use Icinga\Web\Dashboard\Dashboard; use ipl\Web\Url; @@ -115,7 +116,7 @@ class HomePaneForm extends BaseDashboardForm $orgHome->setEntries([]); } - $conn = Dashboard::getConn(); + $conn = DBUtils::getConn(); $conn->beginTransaction(); try { diff --git a/application/forms/Dashboard/NewHomePaneForm.php b/application/forms/Dashboard/NewHomePaneForm.php index f686c61d3..221d38b09 100644 --- a/application/forms/Dashboard/NewHomePaneForm.php +++ b/application/forms/Dashboard/NewHomePaneForm.php @@ -7,6 +7,7 @@ namespace Icinga\Forms\Dashboard; use Icinga\Web\Dashboard\Dashboard; use Icinga\Web\Dashboard\DashboardHome; use Icinga\Web\Dashboard\Pane; +use Icinga\Util\DBUtils; use Icinga\Web\Notification; use ipl\Web\Url; @@ -78,7 +79,7 @@ class NewHomePaneForm extends BaseDashboardForm protected function onSuccess() { $requestUrl = Url::fromRequest(); - $conn = Dashboard::getConn(); + $conn = DBUtils::getConn(); if ($requestUrl->getPath() === Dashboard::BASE_ROUTE . '/new-pane') { $selectedHome = $this->getPopulatedValue('home'); diff --git a/application/forms/Dashboard/SetupNewDashboardForm.php b/application/forms/Dashboard/SetupNewDashboardForm.php index 0d25411da..b23df4251 100644 --- a/application/forms/Dashboard/SetupNewDashboardForm.php +++ b/application/forms/Dashboard/SetupNewDashboardForm.php @@ -2,12 +2,14 @@ namespace Icinga\Forms\Dashboard; +use Icinga\Application\Modules; use Icinga\Web\Dashboard\Dashboard; use Icinga\Web\Dashboard\DashboardHome; use Icinga\Web\Dashboard\Dashlet; use Icinga\Web\Dashboard\ItemList\DashletListMultiSelect; use Icinga\Web\Dashboard\ItemList\EmptyDashlet; use Icinga\Web\Dashboard\Pane; +use Icinga\Util\DBUtils; use Icinga\Web\Notification; use ipl\Html\HtmlElement; use ipl\Html\Text; @@ -33,7 +35,7 @@ class SetupNewDashboardForm extends BaseDashboardForm parent::init(); if (empty(self::$moduleDashlets)) { - self::$moduleDashlets = Dashboard::getModuleDashlets(); + self::$moduleDashlets = Modules\DashletManager::getDashlets(); } $this->setRedirectUrl((string) Url::fromPath(Dashboard::BASE_ROUTE)); @@ -242,7 +244,7 @@ class SetupNewDashboardForm extends BaseDashboardForm protected function onSuccess() { if ($this->getPopulatedValue('submit')) { - $conn = Dashboard::getConn(); + $conn = DBUtils::getConn(); $pane = new Pane($this->getPopulatedValue('pane')); $home = $this->dashboard->getEntry(DashboardHome::DEFAULT_HOME); diff --git a/application/forms/Dashboard/WelcomeForm.php b/application/forms/Dashboard/WelcomeForm.php index e921187b2..3b40b5857 100644 --- a/application/forms/Dashboard/WelcomeForm.php +++ b/application/forms/Dashboard/WelcomeForm.php @@ -4,8 +4,10 @@ namespace Icinga\Forms\Dashboard; +use Icinga\Application\Modules; use Icinga\Web\Dashboard\Dashboard; use Icinga\Web\Dashboard\DashboardHome; +use Icinga\Util\DBUtils; use ipl\Html\Form; use ipl\Web\Url; @@ -36,20 +38,28 @@ class WelcomeForm extends Form 'data-no-icinga-ajax' => true ]); - $this->addElement('submit', 'btn_use_defaults', ['label' => t('Use System Defaults')]); + $shouldDisabled = empty(Modules\DashletManager::getSystemDefaults()); + $this->addElement('submit', 'btn_use_defaults', [ + 'label' => t('Use System Defaults'), + 'disabled' => $shouldDisabled ?: null, + 'title' => $shouldDisabled + ? t('It could not be found any system defaults on your system. Please make sure to enable' + .' either icingadb or monitoring module and try it later!') + : null + ]); } protected function onSuccess() { if ($this->getPopulatedValue('btn_use_defaults')) { $home = $this->dashboard->getEntry(DashboardHome::DEFAULT_HOME); - $conn = Dashboard::getConn(); + $conn = DBUtils::getConn(); $conn->beginTransaction(); try { // Default Home might have been disabled, so we have to update it first $this->dashboard->manageEntry($home); - $home->manageEntry($this->dashboard->getSystemDefaults(), null, true); + $home->manageEntry(Modules\DashletManager::getSystemDefaults(), null, true); $conn->commitTransaction(); } catch (\Exception $err) { diff --git a/library/Icinga/Web/Dashboard/Common/DashboardManager.php b/library/Icinga/Web/Dashboard/Common/DashboardManager.php index 594797d81..4b605ec88 100644 --- a/library/Icinga/Web/Dashboard/Common/DashboardManager.php +++ b/library/Icinga/Web/Dashboard/Common/DashboardManager.php @@ -11,7 +11,7 @@ use Icinga\Model; use Icinga\Web\Dashboard\Dashboard; use Icinga\Web\Dashboard\DashboardHome; use Icinga\Web\Dashboard\Pane; -use Icinga\Web\Dashboard\Util\DBUtils; +use Icinga\Util\DBUtils; use ipl\Stdlib\Filter; trait DashboardManager @@ -137,7 +137,7 @@ trait DashboardManager if ($home->getName() !== DashboardHome::DEFAULT_HOME) { DBUtils::getConn()->delete(DashboardHome::TABLE, ['id = ?' => $home->getUuid()]); } elseif (! $home->isDisabled()) { - DBUtils::getConn()->update(DashboardHome::TABLE, ['disabled' => 1], [ + DBUtils::getConn()->update(DashboardHome::TABLE, ['disabled' => DBUtils::bool2BoolEnum(true)], [ 'id = ?' => $home->getUuid() ]); } @@ -168,7 +168,7 @@ trait DashboardManager $conn->update(DashboardHome::TABLE, [ 'label' => $home->getTitle(), 'priority' => $home->getPriority(), - 'disabled' => 'n' + 'disabled' => DBUtils::bool2BoolEnum(false) ], ['id = ?' => $home->getUuid()]); } } diff --git a/library/Icinga/Web/Dashboard/Dashboard.php b/library/Icinga/Web/Dashboard/Dashboard.php index cd9038478..26cb62321 100644 --- a/library/Icinga/Web/Dashboard/Dashboard.php +++ b/library/Icinga/Web/Dashboard/Dashboard.php @@ -252,9 +252,8 @@ class Dashboard extends BaseHtmlElement implements DashboardEntry $this->addHtml(HtmlElement::create('p', null, $message)); $this->addHtml($this->welcomeForm); - //$this->addHtml($wrapper); } elseif (! $activeHome->hasEntries()) { - $this->addHtml(HtmlElement::create('h1', null, t('No dashboard added to this dashboard home'))); + $this->addHtml(HtmlElement::create('h1', null, t('No dashboard added to this dashboard home.'))); } else { $activePane = $this->getActivePane(); diff --git a/library/Icinga/Web/Dashboard/DashboardHome.php b/library/Icinga/Web/Dashboard/DashboardHome.php index 0c9110e4a..5848819fa 100644 --- a/library/Icinga/Web/Dashboard/DashboardHome.php +++ b/library/Icinga/Web/Dashboard/DashboardHome.php @@ -9,6 +9,7 @@ use Icinga\Model\Home; use Icinga\Web\Dashboard\Common\BaseDashboard; use Icinga\Web\Dashboard\Common\DashboardEntries; use Icinga\Web\Dashboard\Common\Sortable; +use Icinga\Web\Dashboard\Util\DBUtils; use ipl\Stdlib\Filter; use function ipl\Stdlib\get_php_type; @@ -67,7 +68,7 @@ class DashboardHome extends BaseDashboard implements Sortable ->setPriority($home->priority) ->setType($home->type) ->setUuid($home->id) - ->setDisabled((bool) $home->disabled); + ->setDisabled($home->disabled); return $self; } @@ -156,7 +157,7 @@ class DashboardHome extends BaseDashboard implements Sortable $pane = $pane instanceof Pane ? $pane : $this->getEntry($pane); $pane->removeEntries(); - Dashboard::getConn()->delete(Pane::TABLE, [ + DBUtils::getConn()->delete(Pane::TABLE, [ 'id = ?' => $pane->getUuid(), 'home_id = ?' => $this->getUuid() ]); @@ -167,10 +168,13 @@ class DashboardHome extends BaseDashboard implements Sortable public function loadDashboardEntries(string $name = '') { $this->setEntries([]); - $panes = \Icinga\Model\Pane::on(Dashboard::getConn())->utilize(self::TABLE); + $panes = \Icinga\Model\Pane::on(DBUtils::getConn())->utilize(self::TABLE); $panes ->filter(Filter::equal('home_id', $this->getUuid())) - ->filter(Filter::equal('username', Dashboard::getUser()->getUsername())); + ->filter(Filter::equal( + self::TABLE . '.icingaweb_dashboard_owner.id', + Dashboard::getUser()->getAdditional('id') + )); foreach ($panes as $pane) { $newPane = new Pane($pane->name); @@ -200,10 +204,10 @@ class DashboardHome extends BaseDashboard implements Sortable public function manageEntry($entry, BaseDashboard $origin = null, bool $manageRecursive = false) { $user = Dashboard::getUser(); - $conn = Dashboard::getConn(); + $conn = DBUtils::getConn(); $panes = is_array($entry) ? $entry : [$entry]; - // highest priority is 0, so count($entries) are all always lowest prio + 1 + // Highest priority is 0, so count($entries) are all always lowest prio + 1 $order = count($this->getEntries()); if ($origin && ! $origin instanceof DashboardHome) { @@ -223,7 +227,6 @@ class DashboardHome extends BaseDashboard implements Sortable 'home_id' => $this->getUuid(), 'name' => $pane->getName(), 'label' => $pane->getTitle(), - 'username' => $user->getUsername(), 'priority' => $order++ ]); } elseif (! $this->hasEntry($pane->getName()) || ! $origin || ! $origin->hasEntry($pane->getName())) { diff --git a/library/Icinga/Web/Dashboard/Dashlet.php b/library/Icinga/Web/Dashboard/Dashlet.php index bede56e0d..f3b0248c3 100644 --- a/library/Icinga/Web/Dashboard/Dashlet.php +++ b/library/Icinga/Web/Dashboard/Dashlet.php @@ -6,7 +6,6 @@ namespace Icinga\Web\Dashboard; use Icinga\Application\Icinga; use Icinga\Web\Dashboard\Common\BaseDashboard; -use Icinga\Web\Request; use Icinga\Web\Url; use ipl\Html\BaseHtmlElement; use ipl\Html\HtmlElement; @@ -80,9 +79,7 @@ class Dashlet extends BaseDashboard public function getUrl() { if ($this->url !== null && ! $this->url instanceof Url) { - if (Icinga::app()->isCli()) { - $this->url = Url::fromPath($this->url, [], new Request()); - } else { + if (! Icinga::app()->isCli()) { $this->url = Url::fromPath($this->url); } } @@ -252,12 +249,12 @@ class Dashlet extends BaseDashboard { $pane = $this->getPane(); return [ - 'id' => $this->getUuid(), - 'pane' => ! $stringify ? $pane : ($pane ? $pane->getName() : null), - 'name' => $this->getName(), - 'url' => $this->getUrl()->getRelativeUrl(), - 'label' => $this->getTitle(), - 'order' => $this->getPriority(), + 'id' => $this->getUuid(), + 'pane' => ! $stringify ? $pane : ($pane ? $pane->getName() : null), + 'name' => $this->getName(), + 'url' => $this->getUrl()->getRelativeUrl(), + 'label' => $this->getTitle(), + 'priority' => $this->getPriority(), ]; } } diff --git a/library/Icinga/Web/Dashboard/Pane.php b/library/Icinga/Web/Dashboard/Pane.php index c2498bea5..ce70a7a79 100644 --- a/library/Icinga/Web/Dashboard/Pane.php +++ b/library/Icinga/Web/Dashboard/Pane.php @@ -4,14 +4,15 @@ namespace Icinga\Web\Dashboard; +use Icinga\Application\Icinga; use Icinga\Web\Dashboard\Common\BaseDashboard; use Icinga\Exception\ProgrammingError; use Icinga\Exception\ConfigurationError; use Icinga\Model; use Icinga\Web\Dashboard\Common\DashboardEntries; use Icinga\Web\Dashboard\Common\Sortable; +use Icinga\Web\Dashboard\Util\DBUtils; use ipl\Stdlib\Filter; -use ipl\Web\Url; use function ipl\Stdlib\get_php_type; @@ -80,7 +81,7 @@ class Pane extends BaseDashboard implements Sortable $dashlet = $this->getEntry($dashlet); } - Dashboard::getConn()->delete(Dashlet::TABLE, [ + DBUtils::getConn()->delete(Dashlet::TABLE, [ 'id = ?' => $dashlet->getUuid(), 'dashboard_id = ?' => $this->getUuid() ]); @@ -90,13 +91,26 @@ class Pane extends BaseDashboard implements Sortable public function loadDashboardEntries(string $name = '') { - $dashlets = Model\Dashlet::on(Dashboard::getConn()) + $dashlets = Model\Dashlet::on(DBUtils::getConn()) ->utilize(self::TABLE) ->with('icingaweb_module_dashlet'); - $dashlets->filter(Filter::equal('dashboard_id', $this->getUuid())); + $dashlets + ->filter(Filter::equal('dashboard_id', $this->getUuid())) + // Module dashlets can be disabled due to permissions or the module is not loaded + ->filter(Filter::equal('icingaweb_module_dashlet.disabled', false)); $this->setEntries([]); + + $user = Dashboard::getUser(); + $mm = Icinga::app()->getModuleManager(); foreach ($dashlets as $dashlet) { + $module = $dashlet->icingaweb_module_dashlet->module; + if ($module && $mm->hasInstalled($module)) { + if (! $user->can($mm::MODULE_PERMISSION_NS . $module)) { + continue; + } + } + $newDashlet = new Dashlet($dashlet->name, $dashlet->url, $this); $newDashlet ->setPane($this) @@ -106,6 +120,9 @@ class Pane extends BaseDashboard implements Sortable ->setDescription($dashlet->icingaweb_module_dashlet->description); $this->addEntry($newDashlet); + if ($module && ! $mm->hasInstalled($module)) { + $this->removeEntry($newDashlet); + } } return $this; @@ -129,7 +146,7 @@ class Pane extends BaseDashboard implements Sortable $home = $this->getHome(); $user = Dashboard::getUser()->getUsername(); - $conn = Dashboard::getConn(); + $conn = DBUtils::getConn(); $dashlets = is_array($entry) ? $entry : [$entry]; // Highest priority is 0, so count($entries) are always lowest prio + 1 @@ -143,14 +160,17 @@ class Pane extends BaseDashboard implements Sortable break; } + $url = $dashlet->getUrl(); + $url = is_string($url) ?: $url->getRelativeUrl(); $uuid = Dashboard::getSHA1($user . $home->getName() . $this->getName() . $dashlet->getName()); + if (! $this->hasEntry($dashlet->getName()) && (! $origin || ! $origin->hasEntry($dashlet->getName()))) { $conn->insert(Dashlet::TABLE, [ 'id' => $uuid, 'dashboard_id' => $this->getUuid(), 'name' => $dashlet->getName(), 'label' => $dashlet->getTitle(), - 'url' => $dashlet->getUrl()->getRelativeUrl(), + 'url' => $url, 'priority' => $order++ ]); @@ -188,7 +208,7 @@ class Pane extends BaseDashboard implements Sortable 'id' => $uuid, 'dashboard_id' => $this->getUuid(), 'label' => $dashlet->getTitle(), - 'url' => $dashlet->getUrl()->getRelativeUrl(), + 'url' => $url, 'priority' => $dashlet->getPriority() ], $filterCondition); } else { diff --git a/library/Icinga/Web/Menu.php b/library/Icinga/Web/Menu.php index c0af398fe..0be9dc88f 100644 --- a/library/Icinga/Web/Menu.php +++ b/library/Icinga/Web/Menu.php @@ -4,9 +4,9 @@ namespace Icinga\Web; use Icinga\Application\Logger; -use Icinga\Authentication\Auth; use Icinga\Model\Home; use Icinga\Web\Dashboard\DashboardHome; +use Icinga\Util\DBUtils; use Icinga\Web\Navigation\Navigation; use Icinga\Web\Dashboard\Dashboard; use ipl\Stdlib\Filter; @@ -121,7 +121,7 @@ class Menu extends Navigation ]); $this->addItem('user', [ 'cssClass' => 'user-nav-item', - 'label' => Auth::getInstance()->getUser()->getUsername(), + 'label' => Dashboard::getUser()->getUsername(), 'icon' => 'user', 'priority' => 900, 'children' => [ @@ -160,8 +160,8 @@ class Menu extends Navigation $dashboardHomes = []; try { - $homes = Home::on(Dashboard::getConn()); - $homes->filter(Filter::equal('username', Auth::getInstance()->getUser()->getUsername())); + $homes = Home::on(DBUtils::getConn()); + $homes->filter(Filter::equal('user_id', Dashboard::getUser()->getAdditional('id'))); foreach ($homes as $home) { if ($home->name === DashboardHome::DEFAULT_HOME) {