Skip to content

Commit 3fcb201

Browse files
committed
Apply correct restrictions to 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 de8fe10 commit 3fcb201

File tree

7 files changed

+68
-20
lines changed

7 files changed

+68
-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
@@ -49,14 +49,6 @@ public function init()
4949
$this->host = $this->getOptionalRelatedObjectFromParams('host', 'host');
5050
$this->set = $this->getOptionalRelatedObjectFromParams('service_set', 'set');
5151
parent::init();
52-
if ($this->object) {
53-
if ($this->host === null) {
54-
$this->host = $this->loadOptionalRelatedObject($this->object, 'host');
55-
}
56-
if ($this->set === null) {
57-
$this->set = $this->loadOptionalRelatedObject($this->object, 'service_set');
58-
}
59-
}
6052
$this->addOptionalHostTabs();
6153
$this->addOptionalSetTabs();
6254
}
@@ -77,6 +69,20 @@ protected function getOptionalRelatedObjectFromParams($type, $parameter)
7769
return null;
7870
}
7971

72+
protected function loadOptionalObject(): void
73+
{
74+
parent::loadOptionalObject();
75+
76+
if ($this->object) {
77+
if ($this->host === null) {
78+
$this->host = $this->loadOptionalRelatedObject($this->object, 'host');
79+
}
80+
if ($this->set === null) {
81+
$this->set = $this->loadOptionalRelatedObject($this->object, 'service_set');
82+
}
83+
}
84+
}
85+
8086
protected function loadOptionalRelatedObject(IcingaObject $object, $relation)
8187
{
8288
$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
@@ -17,6 +17,7 @@
1717
use Icinga\Module\Director\RestApi\IcingaObjectsHandler;
1818
use Icinga\Module\Director\Web\ActionBar\ObjectsActionBar;
1919
use Icinga\Module\Director\Web\ActionBar\TemplateActionBar;
20+
use Icinga\Module\Director\Web\Controller\Extension\ObjectRestrictions;
2021
use Icinga\Module\Director\Web\Form\FormLoader;
2122
use Icinga\Module\Director\Web\Table\ApplyRulesTable;
2223
use Icinga\Module\Director\Web\Table\ObjectSetTable;
@@ -33,6 +34,7 @@
3334
abstract class ObjectsController extends ActionController
3435
{
3536
use BranchHelper;
37+
use ObjectRestrictions;
3638

3739
protected $isApified = true;
3840

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

library/Director/Web/Table/ObjectsTable.php

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -226,11 +226,14 @@ protected function loadRestrictions()
226226
{
227227
/** @var Db $db */
228228
$db = $this->connection();
229+
$dummyObject = $this->getDummyObject();
230+
$type = $dummyObject->getShortTableName();
229231

230-
return [
231-
new HostgroupRestriction($db, $this->auth),
232-
new FilterByNameRestriction($db, $this->auth, $this->getDummyObject()->getShortTableName())
233-
];
232+
if ($dummyObject->isApplyRule()) {
233+
return [new FilterByNameRestriction($db, $this->auth, $type)];
234+
} else {
235+
return [new HostgroupRestriction($db, $this->auth)];
236+
}
234237
}
235238

236239
/**

0 commit comments

Comments
 (0)