From 6a34afe36da23734de813560669069527011000a Mon Sep 17 00:00:00 2001 From: Stanislas Date: Wed, 11 Dec 2024 16:01:10 +0100 Subject: [PATCH] Fix(Core): Add entities_id and is_recursive fields to correctly filter data from the API (#858) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Fix(Core): check UPDATE / VIEW right from API * fix CS * check for access entity and prevent purge from API * fix purge * fix * move back to CommonDBTM * remove useless data * fix CS * another try * Move to CommonDBChild * fix * fix * move to sql instead of object * fix * fix CS * Update inc/abstractcontainerinstance.class.php Co-authored-by: Johan Cwiklinski * revert * can't attach because of 'itemtype' fk field * add check Co-authored-by: Cédric Anne * add check Co-authored-by: Cédric Anne * Adapt changelog --------- Co-authored-by: Johan Cwiklinski Co-authored-by: Cédric Anne --- CHANGELOG.md | 6 ++ inc/abstractcontainerinstance.class.php | 50 ++++++++++- templates/container.class.tpl | 113 +++++++++++++++++++++++- 3 files changed, 166 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d8310ce1..8b554804 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). +## [UNRELAESE] + +### Fixed + +- Fix `container` to prevent calls from `API` returning full container data + ## [1.21.15] - 2024-10-09 ### Fixed diff --git a/inc/abstractcontainerinstance.class.php b/inc/abstractcontainerinstance.class.php index 28cc8a2e..87ebcbd5 100644 --- a/inc/abstractcontainerinstance.class.php +++ b/inc/abstractcontainerinstance.class.php @@ -28,8 +28,56 @@ * ------------------------------------------------------------------------- */ -abstract class PluginFieldsAbstractContainerInstance extends CommonDBTM +abstract class PluginFieldsAbstractContainerInstance extends CommonDBChild { + public static $itemtype = 'itemtype'; + public static $items_id = 'items_id'; + + public static $mustBeAttached = false; + + /** + * This function relies on the static property `static::$plugins_forward_entity`, + * which should be populated using the following method (from setup): + * + * Plugin::registerClass( + * PluginFields, + * ['forwardentityfrom' => ] + * ); + * + * However, the order in which plugins are loaded can affect the behavior. + * For example, if a container is defined on a `GenericObject` itemtype and + * the `fields` plugin initializes before the `genericobject` plugin, the + * `itemtype` for the container will not yet exist, leading to potential issues. + * + * Modification of this function to meet specific requirements. + */ + public function addNeededInfoToInput($input) + { + if ($this->tryEntityForwarding()) { + $completeinput = array_merge($this->fields, $input); + if ( + $itemToGetEntity = static::getItemFromArray( + static::$itemtype, + static::$items_id, + $completeinput, + ) + ) { + if ( + ($itemToGetEntity instanceof CommonDBTM) + ) { + if ($itemToGetEntity->isEntityAssign()) { + $input['entities_id'] = $itemToGetEntity->getEntityID(); + } + + if ($itemToGetEntity->maybeRecursive()) { + $input['is_recursive'] = intval($itemToGetEntity->isRecursive()); + } + } + } + } + return $input; + } + public static function getSpecificValueToSelect($field, $name = '', $values = '', array $options = []) { if (!is_array($values)) { diff --git a/templates/container.class.tpl b/templates/container.class.tpl index 5c30a90f..97159ae9 100644 --- a/templates/container.class.tpl +++ b/templates/container.class.tpl @@ -13,6 +13,7 @@ class %%CLASSNAME%% extends PluginFieldsAbstractContainerInstance $obj = new self(); $table = $obj->getTable(); + $migration = new PluginFieldsMigration(0); // create Table if (!$DB->tableExists($table)) { @@ -32,10 +33,8 @@ class %%CLASSNAME%% extends PluginFieldsAbstractContainerInstance $result = $DB->query("SHOW COLUMNS FROM `$table`"); if ($result && $DB->numrows($result) > 0) { $changed = false; - $migration = new PluginFieldsMigration(0); while ($data = $DB->fetchAssoc($result)) { if (str_starts_with($data['Field'], 'itemtype_') && $data['Null'] !== 'YES') { - Toolbox::logDebug($data); $migration->changeField($table, $data['Field'], $data['Field'], "varchar(100) DEFAULT NULL"); $changed = true; } @@ -45,6 +44,116 @@ class %%CLASSNAME%% extends PluginFieldsAbstractContainerInstance } } } + + /** + * Adds the 'entities_id' field to the database table and migrates existing data. + * + * This block ensures that the 'entities_id' field is created and populated if it + * associated item type requires entity assignment + */ + if (getItemForItemtype("%%ITEMTYPE%%")->isEntityAssign() && !$DB->fieldExists($table, 'entities_id')) { + $migration->addField($table, 'entities_id', 'fkey', ['after' => 'plugin_fields_containers_id']); + $migration->addKey($table, 'entities_id'); + $migration->executeMigration(); + + // migrate data + $query = $DB->buildUpdate( + $table, + ['entities_id' => new QueryParam()], + ['id' => new QueryParam()] + ); + $stmt = $DB->prepare($query); + + //load all entries + $data = $DB->request( + [ + 'SELECT' => '*', + 'FROM' => $table, + ] + ); + + foreach ($data as $fields) { + //load related item + $related_item = $DB->request( + [ + 'SELECT' => '*', + 'FROM' => getTableForItemType($fields['itemtype']), + 'WHERE' => [ + 'id' => $fields['items_id'], + ] + ] + )->current(); + + if ($related_item === null) { + continue; + } + + //update if needed + if ($fields['entities_id'] != $related_item['entities_id']) { + $stmt->bind_param( + 'ii', + $related_item['entities_id'], + $fields['id'] + ); + $stmt->execute(); + } + } + } + + /** + * Adds the 'is_recursive' field to the database table and migrates existing data. + * + * This block ensures that the 'is_recursive' field is created and populated if it + * associated item type requires recursive assignment + */ + if (getItemForItemtype("%%ITEMTYPE%%")->maybeRecursive() && !$DB->fieldExists($table, 'is_recursive')) { + $migration->addField($table, 'is_recursive', 'bool', ['after' => 'entities_id']); + $migration->addKey($table, 'is_recursive'); + $migration->executeMigration(); + + //migrate data + $query = $DB->buildUpdate( + $table, + ['is_recursive' => new QueryParam()], + ['id' => new QueryParam()] + ); + $stmt = $DB->prepare($query); + + //load all entries + $data = $DB->request( + [ + 'SELECT' => '*', + 'FROM' => $table, + ] + ); + + foreach ($data as $fields) { + //load related item + $related_item = $DB->request( + [ + 'SELECT' => '*', + 'FROM' => getTableForItemType($fields['itemtype']), + 'WHERE' => [ + 'id' => $fields['items_id'], + ] + ] + )->current(); + + if ($related_item === null) { + continue; + } + + //update if needed + if ($fields['is_recursive'] != $related_item['is_recursive']) { + $stmt->bind_param( + 'ii', + $related_item['is_recursive'], + $fields['id'] + ); + $stmt->execute(); + } + } + } } static function uninstall() {