From 9ee18c2f3656f9779635de0592cf48258091f600 Mon Sep 17 00:00:00 2001 From: jbostoen <6421683+jbostoen@users.noreply.github.com> Date: Fri, 25 Apr 2025 14:46:33 +0200 Subject: [PATCH 1/3] Add helper method to create an ObjectResult from a DBObject. (#706) Author: Jeffrey Bostoen --- core/restservices.class.inc.php | 75 +++++++++++++++++++++------------ 1 file changed, 47 insertions(+), 28 deletions(-) diff --git a/core/restservices.class.inc.php b/core/restservices.class.inc.php index 88d563d81..42899b975 100644 --- a/core/restservices.class.inc.php +++ b/core/restservices.class.inc.php @@ -76,6 +76,52 @@ class ObjectResult $this->fields = array(); } + /** + * Creates an ObjectResult from a DBObject. + * + * @param DBObject $oObj The object. + * @param array|null $aFieldSpec An array of class => attribute codes (Cf. RestUtils::GetFieldList). List of the attributes to be reported. + * @param boolean $bExtendedOutput Output all of the link set attributes ? + * @param integer $iCode An error code (RestResult::OK is no issue has been found) + * @param string $sMessage Description of the error if any, an empty string otherwise + * + * @return ObjectResult + */ + public static function FromDBObject(DBObject $oObj, ?array $aFieldSpec = null, $bExtendedOutput = false, $iCode = 0, $sMessage = '') : ObjectResult { + + $oObjRes = new ObjectResult($oObj::class, $oObj->GetKey()); + $oObjRes->code = $iCode; + $oObjRes->message = $sMessage; + + $aFields = null; + if (!is_null($aFieldSpec)) + { + // Enum all classes in the hierarchy, starting with the current one + foreach (MetaModel::EnumParentClasses($oObj::class, ENUM_PARENT_CLASSES_ALL, false) as $sRefClass) + { + if (array_key_exists($sRefClass, $aFieldSpec)) + { + $aFields = $aFieldSpec[$sRefClass]; + break; + } + } + } + if (is_null($aFields)) + { + // No fieldspec given, or not found... + $aFields = array('id', 'friendlyname'); + } + + foreach ($aFields as $sAttCode) + { + $oObjRes->AddField($oObj, $sAttCode, $bExtendedOutput); + } + + return $oObjRes; + + } + + /** * Helper to make an output value for a given attribute * @@ -204,34 +250,7 @@ class RestResultWithObjects extends RestResult */ public function AddObject($iCode, $sMessage, $oObject, $aFieldSpec = null, $bExtendedOutput = false) { - $sClass = get_class($oObject); - $oObjRes = new ObjectResult($sClass, $oObject->GetKey()); - $oObjRes->code = $iCode; - $oObjRes->message = $sMessage; - - $aFields = null; - if (!is_null($aFieldSpec)) - { - // Enum all classes in the hierarchy, starting with the current one - foreach (MetaModel::EnumParentClasses($sClass, ENUM_PARENT_CLASSES_ALL, false) as $sRefClass) - { - if (array_key_exists($sRefClass, $aFieldSpec)) - { - $aFields = $aFieldSpec[$sRefClass]; - break; - } - } - } - if (is_null($aFields)) - { - // No fieldspec given, or not found... - $aFields = array('id', 'friendlyname'); - } - - foreach ($aFields as $sAttCode) - { - $oObjRes->AddField($oObject, $sAttCode, $bExtendedOutput); - } + $oObjRes = ObjectResult::FromDBObject($oObject, $aFieldSpec, $bExtendedOutput, $iCode, $sMessage); $sObjKey = get_class($oObject).'::'.$oObject->GetKey(); $this->objects[$sObjKey] = $oObjRes; From 544c4ae888a343447564dcc6a866caed5285d819 Mon Sep 17 00:00:00 2001 From: jf-cbd Date: Tue, 13 May 2025 16:05:39 +0200 Subject: [PATCH 2/3] =?UTF-8?q?N=C2=B08379=20-=20fix=20backup=20issue?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../2.x/itop-backup/dbrestore.class.inc.php | 9 +------ datamodels/2.x/itop-backup/status.php | 10 +------ setup/backup.class.inc.php | 26 +++++++++++-------- setup/setuputils.class.inc.php | 17 ++++++------ 4 files changed, 25 insertions(+), 37 deletions(-) diff --git a/datamodels/2.x/itop-backup/dbrestore.class.inc.php b/datamodels/2.x/itop-backup/dbrestore.class.inc.php index d274047fa..34944710b 100644 --- a/datamodels/2.x/itop-backup/dbrestore.class.inc.php +++ b/datamodels/2.x/itop-backup/dbrestore.class.inc.php @@ -53,14 +53,7 @@ class DBRestore extends DBBackup $sUser = self::EscapeShellArg($this->sDBUser); $sPwd = self::EscapeShellArg($this->sDBPwd); $sDBName = self::EscapeShellArg($this->sDBName); - if (empty($this->sMySQLBinDir)) - { - $sMySQLExe = 'mysql'; - } - else - { - $sMySQLExe = '"'.$this->sMySQLBinDir.'/mysql"'; - } + $sMySQLExe = DBBackup::MakeSafeMySQLCommand($this->sMySQLBinDir, 'mysql'); if (is_null($this->iDBPort)) { $sPortOption = ''; diff --git a/datamodels/2.x/itop-backup/status.php b/datamodels/2.x/itop-backup/status.php index feeeb9b1b..6f11a2d52 100644 --- a/datamodels/2.x/itop-backup/status.php +++ b/datamodels/2.x/itop-backup/status.php @@ -56,15 +56,7 @@ try // $sMySQLBinDir = MetaModel::GetConfig()->GetModuleSetting('itop-backup', 'mysql_bindir', ''); $sMySQLBinDir = utils::ReadParam('mysql_bindir', $sMySQLBinDir, true); - if (empty($sMySQLBinDir)) - { - $sMySQLDump = 'mysqldump'; - } - else - { - //echo 'Info - Found mysql_bindir: '.$sMySQLBinDir; - $sMySQLDump = '"'.$sMySQLBinDir.'/mysqldump"'; - } + $sMySQLDump = DBBackup::MakeSafeMySQLCommand($sMySQLBinDir, 'mysqldump'); $sCommand = "$sMySQLDump -V 2>&1"; $aOutput = array(); diff --git a/setup/backup.class.inc.php b/setup/backup.class.inc.php index d03650edc..e534bec17 100644 --- a/setup/backup.class.inc.php +++ b/setup/backup.class.inc.php @@ -104,6 +104,8 @@ class DBBackup /** @var string */ protected $sDBName; /** @var string */ + protected $sMySQLBinDir = ''; + /** @var string */ protected $sDBSubName; /** @@ -131,7 +133,6 @@ class DBBackup $this->sDBSubName = $oConfig->get('db_subname'); } - protected $sMySQLBinDir = ''; /** * Create a normalized backup name, depending on the current date/time and Database @@ -299,8 +300,9 @@ class DBBackup } $this->LogInfo("Starting backup of $this->sDBHost/$this->sDBName(suffix:'$this->sDBSubName')"); + $sMySQLBinDir = utils::ReadParam('mysql_bindir', $this->sMySQLBinDir, true); - $sMySQLDump = $this->GetMysqldumpCommand(); + $sMySQLDump = $this->MakeSafeMySQLCommand($sMySQLBinDir, 'mysqldump'); // Store the results in a temporary file $sTmpFileName = self::EscapeShellArg($sBackupFileName); @@ -557,20 +559,22 @@ EOF; /** * @return string the command to launch mysqldump (without its params) + * @throws \BackupException */ - private function GetMysqldumpCommand() + public static function MakeSafeMySQLCommand(string $sMySQLBinDir, string $sCmd) { - $sMySQLBinDir = utils::ReadParam('mysql_bindir', $this->sMySQLBinDir, true); - if (empty($sMySQLBinDir)) - { - $sMysqldumpCommand = 'mysqldump'; + if (empty($sMySQLBinDir)) { + $sMySQLCommand = $sCmd; } - else - { - $sMysqldumpCommand = '"'.$sMySQLBinDir.'/mysqldump"'; + else { + $sMySQLBinDir = escapeshellcmd($sMySQLBinDir); + $sMySQLCommand = '"'.$sMySQLBinDir.'/$sCmd"'; + if (!file_exists($sMySQLCommand)) { + throw new BackupException("$sCmd not found in $sMySQLBinDir"); + } } - return $sMysqldumpCommand; + return $sMySQLCommand; } } diff --git a/setup/setuputils.class.inc.php b/setup/setuputils.class.inc.php index 93fcece77..9386085a7 100644 --- a/setup/setuputils.class.inc.php +++ b/setup/setuputils.class.inc.php @@ -484,16 +484,15 @@ class SetupUtils { $sMySQLBinDir = MetaModel::GetConfig()->GetModuleSetting('itop-backup', 'mysql_bindir', ''); } - - if (empty($sMySQLBinDir)) - { - $sMySQLDump = 'mysqldump'; - } - else - { - SetupPage::log('Info - Found mysql_bindir: '.$sMySQLBinDir); - $sMySQLDump = '"'.$sMySQLBinDir.'/mysqldump"'; + try { + $sMySQLDump = DBBackup::MakeSafeMySQLCommand($sMySQLBinDir, 'mysqldump'); + } catch (Exception $e) { + $aResult[] = new CheckResult(CheckResult::ERROR, $e->getMessage()); + return $aResult; } + if (!empty($sMySQLBinDir)) { + SetupPage::log('Info - Found mysql_bindir: '.$sMySQLBinDir); + } $sCommand = "$sMySQLDump -V 2>&1"; $aOutput = array(); From f5ddbbbe0e2de69f485c732f3672abcb34708207 Mon Sep 17 00:00:00 2001 From: jf-cbd <121934370+jf-cbd@users.noreply.github.com> Date: Tue, 13 May 2025 16:59:43 +0200 Subject: [PATCH 3/3] Rollback typing parameter --- setup/backup.class.inc.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/backup.class.inc.php b/setup/backup.class.inc.php index f0f222814..424578973 100644 --- a/setup/backup.class.inc.php +++ b/setup/backup.class.inc.php @@ -628,7 +628,7 @@ EOF; * @return string the command to launch mysqldump (without its params) * @throws \BackupException */ - public static function MakeSafeMySQLCommand(string $sMySQLBinDir, string $sCmd) + public static function MakeSafeMySQLCommand($sMySQLBinDir, string $sCmd) { if (empty($sMySQLBinDir)) { $sMySQLCommand = $sCmd;