Merge commit from fork

Apply relevant restrictions on REST url endpoints
This commit is contained in:
Ravi Kumar Kempapura Srinivasa 2025-03-26 11:19:54 +01:00 committed by GitHub
commit a99a998540
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 68 additions and 20 deletions

View File

@ -2,6 +2,7 @@
namespace Icinga\Module\Director\Controllers; namespace Icinga\Module\Director\Controllers;
use Icinga\Exception\NotFoundError;
use Icinga\Module\Director\Web\Controller\ObjectController; use Icinga\Module\Director\Web\Controller\ObjectController;
use Icinga\Module\Director\Objects\IcingaHost; use Icinga\Module\Director\Objects\IcingaHost;
use Icinga\Module\Director\Objects\IcingaNotification; 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; return $this->object;
} }
} }

View File

@ -49,14 +49,6 @@ class ServiceController extends ObjectController
$this->host = $this->getOptionalRelatedObjectFromParams('host', 'host'); $this->host = $this->getOptionalRelatedObjectFromParams('host', 'host');
$this->set = $this->getOptionalRelatedObjectFromParams('service_set', 'set'); $this->set = $this->getOptionalRelatedObjectFromParams('service_set', 'set');
parent::init(); 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->addOptionalHostTabs();
$this->addOptionalSetTabs(); $this->addOptionalSetTabs();
} }
@ -77,6 +69,20 @@ class ServiceController extends ObjectController
return null; 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) protected function loadOptionalRelatedObject(IcingaObject $object, $relation)
{ {
$key = $object->getUnresolvedRelated($relation); $key = $object->getUnresolvedRelated($relation);

View File

@ -3,6 +3,7 @@
namespace Icinga\Module\Director\Controllers; namespace Icinga\Module\Director\Controllers;
use Icinga\Data\Filter\Filter; use Icinga\Data\Filter\Filter;
use Icinga\Exception\NotFoundError;
use Icinga\Module\Director\Forms\IcingaServiceSetForm; use Icinga\Module\Director\Forms\IcingaServiceSetForm;
use Icinga\Module\Director\Objects\IcingaHost; use Icinga\Module\Director\Objects\IcingaHost;
use Icinga\Module\Director\Objects\IcingaServiceSet; 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; return $this->object;
} }
} }

View File

@ -5,6 +5,7 @@ namespace Icinga\Module\Director\Restriction;
use gipfl\IcingaWeb2\Zf1\Db\FilterRenderer; use gipfl\IcingaWeb2\Zf1\Db\FilterRenderer;
use Icinga\Authentication\Auth; use Icinga\Authentication\Auth;
use Icinga\Data\Filter\Filter; use Icinga\Data\Filter\Filter;
use Icinga\Data\Filter\FilterEqual;
use Icinga\Module\Director\Db; use Icinga\Module\Director\Db;
use Icinga\Module\Director\Objects\IcingaObject; use Icinga\Module\Director\Objects\IcingaObject;
use Zend_Db_Select as ZfSelect; use Zend_Db_Select as ZfSelect;
@ -30,7 +31,11 @@ class FilterByNameRestriction extends ObjectRestriction
protected function setNameForType($type) 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) public function allows(IcingaObject $object)
@ -39,9 +44,9 @@ class FilterByNameRestriction extends ObjectRestriction
return true; return true;
} }
return $this->getFilter()->matches([ return $this->getFilter()->matches(
(object) ['object_name' => $object->getObjectName()] (object) ['object_name' => $object->getObjectName()]
]); );
} }
public function getFilter() public function getFilter()

View File

@ -5,6 +5,7 @@ namespace Icinga\Module\Director\Web\Controller\Extension;
use Icinga\Authentication\Auth; use Icinga\Authentication\Auth;
use Icinga\Module\Director\Db; use Icinga\Module\Director\Db;
use Icinga\Module\Director\Objects\IcingaObject; use Icinga\Module\Director\Objects\IcingaObject;
use Icinga\Module\Director\Restriction\FilterByNameRestriction;
use Icinga\Module\Director\Restriction\HostgroupRestriction; use Icinga\Module\Director\Restriction\HostgroupRestriction;
use Icinga\Module\Director\Restriction\ObjectRestriction; use Icinga\Module\Director\Restriction\ObjectRestriction;
@ -13,6 +14,9 @@ trait ObjectRestrictions
/** @var ObjectRestriction[] */ /** @var ObjectRestriction[] */
private $objectRestrictions; private $objectRestrictions;
/** @var IcingaObject */
private $dummyRestrictedObject;
/** /**
* @return ObjectRestriction[] * @return ObjectRestriction[]
*/ */
@ -30,13 +34,27 @@ trait ObjectRestrictions
*/ */
protected function loadObjectRestrictions(Db $db, Auth $auth) protected function loadObjectRestrictions(Db $db, Auth $auth)
{ {
return [ $objectType = $this->dummyRestrictedObject->getShortTableName();
new HostgroupRestriction($db, $auth) 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) public function allowsObject(IcingaObject $object)
{ {
$this->dummyRestrictedObject = $object;
foreach ($this->getObjectRestrictions() as $restriction) { foreach ($this->getObjectRestrictions() as $restriction) {
if (! $restriction->allows($object)) { if (! $restriction->allows($object)) {
return false; return false;

View File

@ -17,6 +17,7 @@ use Icinga\Module\Director\Objects\IcingaService;
use Icinga\Module\Director\RestApi\IcingaObjectsHandler; use Icinga\Module\Director\RestApi\IcingaObjectsHandler;
use Icinga\Module\Director\Web\ActionBar\ObjectsActionBar; use Icinga\Module\Director\Web\ActionBar\ObjectsActionBar;
use Icinga\Module\Director\Web\ActionBar\TemplateActionBar; 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\Form\FormLoader;
use Icinga\Module\Director\Web\Table\ApplyRulesTable; use Icinga\Module\Director\Web\Table\ApplyRulesTable;
use Icinga\Module\Director\Web\Table\ObjectSetTable; use Icinga\Module\Director\Web\Table\ObjectSetTable;
@ -33,6 +34,7 @@ use Ramsey\Uuid\Uuid;
abstract class ObjectsController extends ActionController abstract class ObjectsController extends ActionController
{ {
use BranchHelper; use BranchHelper;
use ObjectRestrictions;
protected $isApified = true; protected $isApified = true;
@ -75,9 +77,13 @@ abstract class ObjectsController extends ActionController
$table = $this->getTable(); $table = $this->getTable();
if ( if (
$request->getControllerName() === 'services' $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')); $table->getQuery()->where('o.host_id = ?', $host->get('id'));
} }

View File

@ -226,11 +226,14 @@ class ObjectsTable extends ZfQueryBasedTable
{ {
/** @var Db $db */ /** @var Db $db */
$db = $this->connection(); $db = $this->connection();
$dummyObject = $this->getDummyObject();
$type = $dummyObject->getShortTableName();
return [ if ($dummyObject->isApplyRule()) {
new HostgroupRestriction($db, $this->auth), return [new FilterByNameRestriction($db, $this->auth, $type)];
new FilterByNameRestriction($db, $this->auth, $this->getDummyObject()->getShortTableName()) } else {
]; return [new HostgroupRestriction($db, $this->auth)];
}
} }
/** /**