diff --git a/application/controllers/NotificationController.php b/application/controllers/NotificationController.php index 97fa0f4d..cef254ab 100644 --- a/application/controllers/NotificationController.php +++ b/application/controllers/NotificationController.php @@ -2,6 +2,7 @@ namespace Icinga\Module\Director\Controllers; +use Icinga\Exception\NotFoundError; use Icinga\Module\Director\Web\Controller\ObjectController; use Icinga\Module\Director\Objects\IcingaHost; use Icinga\Module\Director\Objects\IcingaNotification; @@ -80,6 +81,10 @@ class NotificationController extends ObjectController } } + if (! $this->allowsObject($this->object)) { + throw new NotFoundError('No such object available'); + } + return $this->object; } } diff --git a/application/controllers/ServiceController.php b/application/controllers/ServiceController.php index c0a6182c..4782e5e1 100644 --- a/application/controllers/ServiceController.php +++ b/application/controllers/ServiceController.php @@ -49,14 +49,6 @@ class ServiceController extends ObjectController $this->host = $this->getOptionalRelatedObjectFromParams('host', 'host'); $this->set = $this->getOptionalRelatedObjectFromParams('service_set', 'set'); parent::init(); - if ($this->object) { - if ($this->host === null) { - $this->host = $this->loadOptionalRelatedObject($this->object, 'host'); - } - if ($this->set === null) { - $this->set = $this->loadOptionalRelatedObject($this->object, 'service_set'); - } - } $this->addOptionalHostTabs(); $this->addOptionalSetTabs(); } @@ -77,6 +69,20 @@ class ServiceController extends ObjectController return null; } + protected function loadOptionalObject(): void + { + parent::loadOptionalObject(); + + if ($this->object) { + if ($this->host === null) { + $this->host = $this->loadOptionalRelatedObject($this->object, 'host'); + } + if ($this->set === null) { + $this->set = $this->loadOptionalRelatedObject($this->object, 'service_set'); + } + } + } + protected function loadOptionalRelatedObject(IcingaObject $object, $relation) { $key = $object->getUnresolvedRelated($relation); diff --git a/application/controllers/ServicesetController.php b/application/controllers/ServicesetController.php index 684d2fc8..716eb2b2 100644 --- a/application/controllers/ServicesetController.php +++ b/application/controllers/ServicesetController.php @@ -3,6 +3,7 @@ namespace Icinga\Module\Director\Controllers; use Icinga\Data\Filter\Filter; +use Icinga\Exception\NotFoundError; use Icinga\Module\Director\Forms\IcingaServiceSetForm; use Icinga\Module\Director\Objects\IcingaHost; use Icinga\Module\Director\Objects\IcingaServiceSet; @@ -136,6 +137,10 @@ class ServicesetController extends ObjectController } } + if (! $this->allowsObject($this->object)) { + throw new NotFoundError('No such object available'); + } + return $this->object; } } diff --git a/library/Director/Restriction/FilterByNameRestriction.php b/library/Director/Restriction/FilterByNameRestriction.php index aef28c4e..d1bea1c4 100644 --- a/library/Director/Restriction/FilterByNameRestriction.php +++ b/library/Director/Restriction/FilterByNameRestriction.php @@ -5,6 +5,7 @@ namespace Icinga\Module\Director\Restriction; use gipfl\IcingaWeb2\Zf1\Db\FilterRenderer; use Icinga\Authentication\Auth; use Icinga\Data\Filter\Filter; +use Icinga\Data\Filter\FilterEqual; use Icinga\Module\Director\Db; use Icinga\Module\Director\Objects\IcingaObject; use Zend_Db_Select as ZfSelect; @@ -30,7 +31,11 @@ class FilterByNameRestriction extends ObjectRestriction protected function setNameForType($type) { - $this->name = "director/{$type}/filter-by-name"; + if ($type === 'service_set') { + $this->name = "director/{$type}/filter-by-name"; + } else { + $this->name = "director/{$type}/apply/filter-by-name"; + } } public function allows(IcingaObject $object) @@ -39,9 +44,9 @@ class FilterByNameRestriction extends ObjectRestriction return true; } - return $this->getFilter()->matches([ + return $this->getFilter()->matches( (object) ['object_name' => $object->getObjectName()] - ]); + ); } public function getFilter() diff --git a/library/Director/Web/Controller/Extension/ObjectRestrictions.php b/library/Director/Web/Controller/Extension/ObjectRestrictions.php index bedb3f18..fa56f023 100644 --- a/library/Director/Web/Controller/Extension/ObjectRestrictions.php +++ b/library/Director/Web/Controller/Extension/ObjectRestrictions.php @@ -5,6 +5,7 @@ namespace Icinga\Module\Director\Web\Controller\Extension; use Icinga\Authentication\Auth; use Icinga\Module\Director\Db; use Icinga\Module\Director\Objects\IcingaObject; +use Icinga\Module\Director\Restriction\FilterByNameRestriction; use Icinga\Module\Director\Restriction\HostgroupRestriction; use Icinga\Module\Director\Restriction\ObjectRestriction; @@ -13,6 +14,9 @@ trait ObjectRestrictions /** @var ObjectRestriction[] */ private $objectRestrictions; + /** @var IcingaObject */ + private $dummyRestrictedObject; + /** * @return ObjectRestriction[] */ @@ -30,13 +34,27 @@ trait ObjectRestrictions */ protected function loadObjectRestrictions(Db $db, Auth $auth) { - return [ - new HostgroupRestriction($db, $auth) - ]; + $objectType = $this->dummyRestrictedObject->getShortTableName(); + if ( + ($objectType === 'service' && $this->dummyRestrictedObject->isApplyRule()) + || $objectType === 'notification' + || $objectType === 'service_set' + || $objectType === 'scheduled_downtime' + ) { + if ($objectType === 'scheduled_downtime') { + $objectType = 'scheduled-downtime'; + } + + return [new FilterByNameRestriction($db, $auth, $objectType)]; + } + + // If the object is host or host group load HostgroupRestriction + return [new HostgroupRestriction($db, $auth)]; } public function allowsObject(IcingaObject $object) { + $this->dummyRestrictedObject = $object; foreach ($this->getObjectRestrictions() as $restriction) { if (! $restriction->allows($object)) { return false; diff --git a/library/Director/Web/Controller/ObjectsController.php b/library/Director/Web/Controller/ObjectsController.php index 5b3c8879..1440ef45 100644 --- a/library/Director/Web/Controller/ObjectsController.php +++ b/library/Director/Web/Controller/ObjectsController.php @@ -17,6 +17,7 @@ use Icinga\Module\Director\Objects\IcingaService; use Icinga\Module\Director\RestApi\IcingaObjectsHandler; use Icinga\Module\Director\Web\ActionBar\ObjectsActionBar; use Icinga\Module\Director\Web\ActionBar\TemplateActionBar; +use Icinga\Module\Director\Web\Controller\Extension\ObjectRestrictions; use Icinga\Module\Director\Web\Form\FormLoader; use Icinga\Module\Director\Web\Table\ApplyRulesTable; use Icinga\Module\Director\Web\Table\ObjectSetTable; @@ -33,6 +34,7 @@ use Ramsey\Uuid\Uuid; abstract class ObjectsController extends ActionController { use BranchHelper; + use ObjectRestrictions; protected $isApified = true; @@ -75,9 +77,13 @@ abstract class ObjectsController extends ActionController $table = $this->getTable(); if ( $request->getControllerName() === 'services' - && $host = $this->params->get('host') + && $hostName = $this->params->get('host') ) { - $host = IcingaHost::load($host, $this->db()); + $host = IcingaHost::load($hostName, $this->db()); + if (! $this->allowsObject($host)) { + throw new NotFoundError(sprintf('Failed to load %s "%s"', $host->getTableName(), $hostName)); + } + $table->getQuery()->where('o.host_id = ?', $host->get('id')); } diff --git a/library/Director/Web/Table/ObjectsTable.php b/library/Director/Web/Table/ObjectsTable.php index 4ad11661..00332bdf 100644 --- a/library/Director/Web/Table/ObjectsTable.php +++ b/library/Director/Web/Table/ObjectsTable.php @@ -226,11 +226,14 @@ class ObjectsTable extends ZfQueryBasedTable { /** @var Db $db */ $db = $this->connection(); + $dummyObject = $this->getDummyObject(); + $type = $dummyObject->getShortTableName(); - return [ - new HostgroupRestriction($db, $this->auth), - new FilterByNameRestriction($db, $this->auth, $this->getDummyObject()->getShortTableName()) - ]; + if ($dummyObject->isApplyRule()) { + return [new FilterByNameRestriction($db, $this->auth, $type)]; + } else { + return [new HostgroupRestriction($db, $this->auth)]; + } } /**