Skip to content

Commit 8d9ecf3

Browse files
committed
Apply relevant restrictions on REST url endpoints
The following url end points should apply relevant restrictions to filter out objects and show correct HTTP status code: - icingaweb2/director/service, if the host name is left out of the query (Example: icingaweb2/director/service?name=service-name) - icingaweb2/directore/notification - icingaweb2/director/serviceset - icingaweb2/director/scheduled-downtime
1 parent 2e1cac6 commit 8d9ecf3

File tree

7 files changed

+70
-20
lines changed

7 files changed

+70
-20
lines changed

application/controllers/NotificationController.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace Icinga\Module\Director\Controllers;
44

5+
use Icinga\Exception\NotFoundError;
56
use Icinga\Module\Director\Web\Controller\ObjectController;
67
use Icinga\Module\Director\Objects\IcingaHost;
78
use Icinga\Module\Director\Objects\IcingaNotification;
@@ -80,6 +81,10 @@ protected function loadObject()
8081
}
8182
}
8283

84+
if (! $this->allowsObject($this->object)) {
85+
throw new NotFoundError('No such object available');
86+
}
87+
8388
return $this->object;
8489
}
8590
}

application/controllers/ServiceController.php

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -48,14 +48,6 @@ public function init()
4848
$this->host = $this->getOptionalRelatedObjectFromParams('host', 'host');
4949
$this->set = $this->getOptionalRelatedObjectFromParams('service_set', 'set');
5050
parent::init();
51-
if ($this->object) {
52-
if ($this->host === null) {
53-
$this->host = $this->loadOptionalRelatedObject($this->object, 'host');
54-
}
55-
if ($this->set === null) {
56-
$this->set = $this->loadOptionalRelatedObject($this->object, 'service_set');
57-
}
58-
}
5951
$this->addOptionalHostTabs();
6052
$this->addOptionalSetTabs();
6153
}
@@ -76,6 +68,20 @@ protected function getOptionalRelatedObjectFromParams($type, $parameter)
7668
return null;
7769
}
7870

71+
protected function loadOptionalObject(): void
72+
{
73+
parent::loadOptionalObject();
74+
75+
if ($this->object) {
76+
if ($this->host === null) {
77+
$this->host = $this->loadOptionalRelatedObject($this->object, 'host');
78+
}
79+
if ($this->set === null) {
80+
$this->set = $this->loadOptionalRelatedObject($this->object, 'service_set');
81+
}
82+
}
83+
}
84+
7985
protected function loadOptionalRelatedObject(IcingaObject $object, $relation)
8086
{
8187
$key = $object->getUnresolvedRelated($relation);

application/controllers/ServicesetController.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace Icinga\Module\Director\Controllers;
44

55
use Icinga\Data\Filter\Filter;
6+
use Icinga\Exception\NotFoundError;
67
use Icinga\Module\Director\Forms\IcingaServiceSetForm;
78
use Icinga\Module\Director\Objects\IcingaHost;
89
use Icinga\Module\Director\Objects\IcingaServiceSet;
@@ -136,6 +137,10 @@ protected function loadObject()
136137
}
137138
}
138139

140+
if (! $this->allowsObject($this->object)) {
141+
throw new NotFoundError('No such object available');
142+
}
143+
139144
return $this->object;
140145
}
141146
}

library/Director/Restriction/FilterByNameRestriction.php

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use gipfl\IcingaWeb2\Zf1\Db\FilterRenderer;
66
use Icinga\Authentication\Auth;
77
use Icinga\Data\Filter\Filter;
8+
use Icinga\Data\Filter\FilterEqual;
89
use Icinga\Module\Director\Db;
910
use Icinga\Module\Director\Objects\IcingaObject;
1011
use Zend_Db_Select as ZfSelect;
@@ -30,7 +31,11 @@ protected function setType($type)
3031

3132
protected function setNameForType($type)
3233
{
33-
$this->name = "director/${type}/filter-by-name";
34+
if ($type === 'service_set') {
35+
$this->name = "director/{$type}/filter-by-name";
36+
} else {
37+
$this->name = "director/{$type}/apply/filter-by-name";
38+
}
3439
}
3540

3641
public function allows(IcingaObject $object)
@@ -39,9 +44,9 @@ public function allows(IcingaObject $object)
3944
return true;
4045
}
4146

42-
return $this->getFilter()->matches([
47+
return $this->getFilter()->matches(
4348
(object) ['object_name' => $object->getObjectName()]
44-
]);
49+
);
4550
}
4651

4752
public function getFilter()

library/Director/Web/Controller/Extension/ObjectRestrictions.php

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use Icinga\Authentication\Auth;
66
use Icinga\Module\Director\Db;
77
use Icinga\Module\Director\Objects\IcingaObject;
8+
use Icinga\Module\Director\Restriction\FilterByNameRestriction;
89
use Icinga\Module\Director\Restriction\HostgroupRestriction;
910
use Icinga\Module\Director\Restriction\ObjectRestriction;
1011

@@ -13,6 +14,9 @@ trait ObjectRestrictions
1314
/** @var ObjectRestriction[] */
1415
private $objectRestrictions;
1516

17+
/** @var IcingaObject */
18+
private $dummyRestrictedObject;
19+
1620
/**
1721
* @return ObjectRestriction[]
1822
*/
@@ -30,13 +34,27 @@ public function getObjectRestrictions()
3034
*/
3135
protected function loadObjectRestrictions(Db $db, Auth $auth)
3236
{
33-
return [
34-
new HostgroupRestriction($db, $auth)
35-
];
37+
$objectType = $this->dummyRestrictedObject->getShortTableName();
38+
if (
39+
($objectType === 'service' && $this->dummyRestrictedObject->isApplyRule())
40+
|| $objectType === 'notification'
41+
|| $objectType === 'service_set'
42+
|| $objectType === 'scheduled_downtime'
43+
) {
44+
if ($objectType === 'scheduled_downtime') {
45+
$objectType = 'scheduled-downtime';
46+
}
47+
48+
return [new FilterByNameRestriction($db, $auth, $objectType)];
49+
}
50+
51+
// If the object is host or host group load HostgroupRestriction
52+
return [new HostgroupRestriction($db, $auth)];
3653
}
3754

3855
public function allowsObject(IcingaObject $object)
3956
{
57+
$this->dummyRestrictedObject = $object;
4058
foreach ($this->getObjectRestrictions() as $restriction) {
4159
if (! $restriction->allows($object)) {
4260
return false;

library/Director/Web/Controller/ObjectsController.php

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
use Icinga\Module\Director\RestApi\IcingaObjectsHandler;
1717
use Icinga\Module\Director\Web\ActionBar\ObjectsActionBar;
1818
use Icinga\Module\Director\Web\ActionBar\TemplateActionBar;
19+
use Icinga\Module\Director\Web\Controller\Extension\ObjectRestrictions;
1920
use Icinga\Module\Director\Web\Form\FormLoader;
2021
use Icinga\Module\Director\Web\Table\ApplyRulesTable;
2122
use Icinga\Module\Director\Web\Table\ObjectSetTable;
@@ -32,6 +33,7 @@
3233
abstract class ObjectsController extends ActionController
3334
{
3435
use BranchHelper;
36+
use ObjectRestrictions;
3537

3638
protected $isApified = true;
3739

@@ -73,9 +75,13 @@ protected function apiRequestHandler()
7375
$request = $this->getRequest();
7476
$table = $this->getTable();
7577
if ($request->getControllerName() === 'services'
76-
&& $host = $this->params->get('host')
78+
&& $hostName = $this->params->get('host')
7779
) {
78-
$host = IcingaHost::load($host, $this->db());
80+
$host = IcingaHost::load($hostName, $this->db());
81+
if (! $this->allowsObject($host)) {
82+
throw new NotFoundError(sprintf('Failed to load %s "%s"', $host->getTableName(), $hostName));
83+
}
84+
7985
$table->getQuery()->where('o.host_id = ?', $host->get('id'));
8086
}
8187

library/Director/Web/Table/ObjectsTable.php

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -229,10 +229,14 @@ protected function loadRestrictions()
229229
$db = $this->connection();
230230
$auth = $this->getAuth();
231231

232-
return [
233-
new HostgroupRestriction($db, $auth),
234-
new FilterByNameRestriction($db, $auth, $this->getDummyObject()->getShortTableName())
235-
];
232+
$dummyObject = $this->getDummyObject();
233+
$type = $dummyObject->getShortTableName();
234+
235+
if ($dummyObject->isApplyRule()) {
236+
return [new FilterByNameRestriction($db, $auth, $type)];
237+
} else {
238+
return [new HostgroupRestriction($db, $auth)];
239+
}
236240
}
237241

238242
/**
@@ -298,6 +302,7 @@ protected function prepareQuery()
298302
$query->order('object_name')->limit(100);
299303
} else {
300304
$this->applyObjectTypeFilter($query);
305+
$this->applyRestrictions($query);
301306
$query->order('o.object_name')->limit(100);
302307
}
303308

0 commit comments

Comments
 (0)