Skip to content
This repository has been archived by the owner on Dec 13, 2022. It is now read-only.

fix(conf): prevent timeperiod to call itself via templates #7024

Merged
merged 4 commits into from
Dec 14, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions src/Centreon/Domain/Repository/TimePeriodRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -161,4 +161,34 @@ public function getChainByParant($id, &$result)

return $result;
}

/**
* Get an array of all time periods IDs that are related as templates
*
* @param int $id ID of time period
* @param array $result This parameter is used forward to data from the recursive method
* @return array
*/
public function getIncludeChainByParent($id, &$result)
{
$sql = 'SELECT t.timeperiod_include_id AS `id` '
. 'FROM timeperiod_include_relations AS t '
. 'WHERE t.timeperiod_include_id IS NOT NULL AND t.timeperiod_id = :id '
. 'GROUP BY t.timeperiod_include_id';

$stmt = $this->db->prepare($sql);
$stmt->bindValue(':id', $id, PDO::PARAM_INT);
$stmt->execute();

while ($row = $stmt->fetch()) {
$isExisting = array_key_exists($row['id'], $result);
$result[$row['id']] = $row['id'];

if (!$isExisting) {
$this->getIncludeChainByParent($row['id'], $result);
}
}

return $result;
}
}
66 changes: 47 additions & 19 deletions www/api/class/centreon_configuration_timeperiod.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@

class CentreonConfigurationTimeperiod extends CentreonConfigurationObjects
{

/**
* CentreonConfigurationTimeperiod constructor.
*/
Expand All @@ -48,47 +49,74 @@ public function __construct()
}

/**
* Get a list of time periods as a source of data for the select2 widget
*
* @throws RestBadRequestException If some parameter is missing will throw this exception
* @return array
* @throws RestBadRequestException
*/
public function getList()
jdelpierre marked this conversation as resolved.
Show resolved Hide resolved
{
$queryValues = array();
$queryWhere = $queryValues = [];

// Check for select2 'q' argument
if (isset($this->arguments['q'])) {
$queryValues['name'] = '%' . (string)$this->arguments['q'] . '%';
} else {
$queryValues['name'] = '%%';
$queryWhere[] = 'tp_name LIKE :name';
$queryValues['name'] = [
PDO::PARAM_STR => "%{$this->arguments['q']}%",
];
}

// exclude some values from the result
if (isset($this->arguments['exclude'])) {
$queryWhere[] = 'tp_id <> :exclude';
$queryValues['exclude'] = [
PDO::PARAM_INT => (int) $this->arguments['exclude'],
];
}

$queryTimePeriod = 'SELECT SQL_CALC_FOUND_ROWS DISTINCT tp_id, tp_name FROM timeperiod ' .
'WHERE tp_name LIKE :name ' .
'ORDER BY tp_name ';
($queryWhere ? 'WHERE ' . join(' AND ', $queryWhere) : '') .
' ORDER BY tp_name ';

if (isset($this->arguments['page_limit']) && isset($this->arguments['page'])) {
if (!is_numeric($this->arguments['page']) || !is_numeric($this->arguments['page_limit'])) {
throw new \RestBadRequestException('Error, limit must be numerical');
}

$offset = ($this->arguments['page'] - 1) * $this->arguments['page_limit'];

$queryTimePeriod .= 'LIMIT :offset, :limit';
$queryValues['offset'] = (int)$offset;
$queryValues['limit'] = (int)$this->arguments['page_limit'];

$queryValues['offset'] = [
PDO::PARAM_INT => (int) $offset,
];
$queryValues['limit'] = [
PDO::PARAM_INT => (int) $this->arguments['page_limit'],
];
}

$stmt = $this->pearDB->prepare($queryTimePeriod);
$stmt->bindParam(':name', $queryValues['name'], PDO::PARAM_STR);
if (isset($queryValues['offset'])) {
$stmt->bindParam(':offset', $queryValues["offset"], PDO::PARAM_INT);
$stmt->bindParam(':limit', $queryValues["limit"], PDO::PARAM_INT);

foreach ($queryValues as $bindId => $bindData) {
foreach ($bindData as $bindType => $bindValue) {
$stmt->bindValue($bindId, $bindValue, $bindType);
break;
}
}

$stmt->execute();
$timePeriodList = array();
$timePeriodList = [];

while ($data = $stmt->fetch()) {
$timePeriodList[] = array(
$timePeriodList[] = [
'id' => $data['tp_id'],
'text' => html_entity_decode($data['tp_name']),
);
];
}
return array(

return [
'items' => $timePeriodList,
'total' => $stmt->rowCount()
);
'total' => $stmt->rowCount(),
];
}
}
57 changes: 57 additions & 0 deletions www/include/configuration/configObject/timeperiod/DB-Func.php
Original file line number Diff line number Diff line change
Expand Up @@ -419,3 +419,60 @@ function getTimeperiodIdByName($name)
}
return $id;
}

/**
* Get chain of time periods via template relation
*
* @global \Pimple\Container $dependencyInjector
* @param array $tpIds List of selected time period as IDs
* @return array
*/
jdelpierre marked this conversation as resolved.
Show resolved Hide resolved
function getTimeperiodsFromTemplate(array $tpIds)
{
global $dependencyInjector;

$db = $dependencyInjector['centreon.db-manager'];

$result = [];

foreach ($tpIds as $tpId) {
$db->getRepository(Centreon\Domain\Repository\TimePeriodRepository::class)
->getIncludeChainByParent($tpId, $result);
}

return $result;
}

/**
* Validator prevent loops via template
*
* @global \HTML_QuickFormCustom $form Access to the form object
* @param array $value List of selected time period as IDs
* @return bool
*/
jdelpierre marked this conversation as resolved.
Show resolved Hide resolved
function testTemplateLoop($value)
{
// skip check if template field is empty
if (!$value) {
return true;
}

global $form;

$data = $form->getSubmitValues();

// skip check if timeperiod is new
if (!$data['tp_id']) {
return true;
} elseif (in_array($data['tp_id'], $value)) {
// try to skip heavy check of templates

return false;
} elseif (in_array($data['tp_id'], getTimeperiodsFromTemplate($value))) {
// get list of all timeperiods related via templates

return false;
}

return true;
}
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,9 @@
$eTemplate = '<table><tr><td><div class="ams">{label_2}</div>{unselected}</td><td align="center">{add}<br /><br />'
. '<br />{remove}</td><td><div class="ams">{label_3}</div>{selected}</td></tr></table>';

$timeAvRoute = './include/common/webServices/rest/internal.php?object=centreon_configuration_timeperiod&action=list';
$timeAvRoute = './include/common/webServices/rest/internal.php?object=centreon_configuration_timeperiod&action=list' .
($tp_id ? "&exclude={$tp_id}" : '') // exclude this timeperiod from list
;
$attrTimeperiods = array(
'datasourceOrigin' => 'ajax',
'availableDatasetRoute' => $timeAvRoute,
Expand Down Expand Up @@ -200,6 +202,12 @@ function myReplace()
$form->addRule('tp_friday', _('Error in hour definition'), 'format');
$form->addRule('tp_saturday', _('Error in hour definition'), 'format');

/*
* Check for template loops
*/
$form->registerRule('templateLoop', 'callback', 'testTemplateLoop');
$form->addRule('tp_include', _('The selected template has the same time period as a template'), 'templateLoop');

$form->setRequiredNote("<font style='color: red;'>*</font>&nbsp;" . _("Required fields"));

/*
Expand Down