diff --git a/core/attributedef.class.inc.php b/core/attributedef.class.inc.php index 57681870e..181075f5f 100644 --- a/core/attributedef.class.inc.php +++ b/core/attributedef.class.inc.php @@ -4272,43 +4272,6 @@ class AttributeEncryptedString extends AttributeString implements iAttributeNoGr { const SEARCH_WIDGET_TYPE = self::SEARCH_WIDGET_TYPE_RAW; - static $sKey = null; // Encryption key used for all encrypted fields - static $sLibrary = null; // Encryption library used for all encrypted fields - - public function __construct($sCode, $aParams) - { - parent::__construct($sCode, $aParams); - if (self::$sKey == null) - { - self::$sKey = MetaModel::GetConfig()->GetEncryptionKey(); - } - if (self::$sLibrary == null) - { - self::$sLibrary = MetaModel::GetConfig()->GetEncryptionLibrary(); - } - } - - /** - * When the attribute definitions are stored in APC cache: - * 1) The static class variable $sKey is NOT serialized - * 2) The object's constructor is NOT called upon wakeup - * 3) mcrypt may crash the server if passed an empty key !! - * - * So let's restore the key (if needed) when waking up - **/ - public function __wakeup() - { - if (self::$sKey == null) - { - self::$sKey = MetaModel::GetConfig()->GetEncryptionKey(); - } - if (self::$sLibrary == null) - { - self::$sLibrary = MetaModel::GetConfig()->GetEncryptionLibrary(); - } - } - - protected function GetSQLCol($bFullSpec = false) { return "TINYBLOB"; @@ -4347,8 +4310,8 @@ class AttributeEncryptedString extends AttributeString implements iAttributeNoGr */ public function FromSQLToValue($aCols, $sPrefix = '') { - $oSimpleCrypt = new SimpleCrypt(self::$sLibrary); - $sValue = $oSimpleCrypt->Decrypt(self::$sKey, $aCols[$sPrefix]); + $oSimpleCrypt = new SimpleCrypt(MetaModel::GetConfig()->GetEncryptionLibrary()); + $sValue = $oSimpleCrypt->Decrypt(MetaModel::GetConfig()->GetEncryptionKey(), $aCols[$sPrefix]); return $sValue; } @@ -4363,8 +4326,8 @@ class AttributeEncryptedString extends AttributeString implements iAttributeNoGr */ public function GetSQLValues($value) { - $oSimpleCrypt = new SimpleCrypt(self::$sLibrary); - $encryptedValue = $oSimpleCrypt->Encrypt(self::$sKey, $value); + $oSimpleCrypt = new SimpleCrypt(MetaModel::GetConfig()->GetEncryptionLibrary()); + $encryptedValue = $oSimpleCrypt->Encrypt(MetaModel::GetConfig()->GetEncryptionKey(), $value); $aValues = array(); $aValues[$this->Get("sql")] = $encryptedValue; @@ -11315,6 +11278,10 @@ class AttributeEnumSet extends AttributeSet } return $aValues; } + public function Equals($val1, $val2) + { + return $val1->Equals($val2); + } } diff --git a/core/ormset.class.inc.php b/core/ormset.class.inc.php index 71d0f8914..139207c78 100644 --- a/core/ormset.class.inc.php +++ b/core/ormset.class.inc.php @@ -385,7 +385,7 @@ class ormSet */ public function Equals(ormSet $other) { - return implode(', ', $this->GetValue()) === implode(', ', $other->GetValue()); + return implode(', ', $this->GetValues()) === implode(', ', $other->GetValues()); } /** diff --git a/core/simplegraph.class.inc.php b/core/simplegraph.class.inc.php index c889106ec..614ab031e 100644 --- a/core/simplegraph.class.inc.php +++ b/core/simplegraph.class.inc.php @@ -537,7 +537,7 @@ EOF } else { - throw new Exception('graphviz not found (executable path: '.$sDotExecutable.')'); + throw new Exception('graphviz not found'); } return $sHtml; } @@ -592,7 +592,7 @@ EOF } else { - throw new Exception('graphviz not found (executable path: '.$sDotExecutable.')'); + throw new Exception('graphviz not found'); } return $sHtml; } diff --git a/setup/unattended-install/unattended-install.php b/setup/unattended-install/unattended-install.php index fdf1ca5e0..2ac9eafb7 100644 --- a/setup/unattended-install/unattended-install.php +++ b/setup/unattended-install/unattended-install.php @@ -25,7 +25,9 @@ EOF; exit(-1); } ///////////////////////////////////////////////// -if (! utils::IsModeCLI()) + +$sCleanName = strtolower(trim(PHP_SAPI)); +if ($sCleanName !== 'cli') { echo "Mode CLI only"; exit(-1); diff --git a/tests/php-unit-tests/src/BaseTestCase/ItopDataTestCase.php b/tests/php-unit-tests/src/BaseTestCase/ItopDataTestCase.php index 3ff845b10..525583097 100644 --- a/tests/php-unit-tests/src/BaseTestCase/ItopDataTestCase.php +++ b/tests/php-unit-tests/src/BaseTestCase/ItopDataTestCase.php @@ -129,6 +129,13 @@ abstract class ItopDataTestCase extends ItopTestCase { $this->CreateTestOrganization(); } + + $oConfig = MetaModel::GetConfig(); + if ($oConfig->GetEncryptionLibrary() != DEFAULT_ENCRYPTION_LIB + && $oConfig->GetEncryptionKey() == DEFAULT_ENCRYPTION_KEY) { + // Config file is corrupted, let's fix it + $oConfig->SetEncryptionKey("6eb9d9afa3ee0fbcebe622a33bf57aaeafb7c37998fd24c403c2522c2d60117f"); + } } /** diff --git a/tests/php-unit-tests/unitary-tests/core/querybuilderexpressions/Delta/all-attributes.xml b/tests/php-unit-tests/unitary-tests/core/querybuilderexpressions/Delta/all-attributes.xml new file mode 100644 index 000000000..994618cfe --- /dev/null +++ b/tests/php-unit-tests/unitary-tests/core/querybuilderexpressions/Delta/all-attributes.xml @@ -0,0 +1,608 @@ + + + + + cmdbAbstractObject + + bizmodel,searchable + true + testabstract + + + + + + + + + + + + + + + name + + false + + all + + + + open + terminated + + meta_enum + open + all + + + status + + + + + + + + + + + + + + + + + TestAbstract + + bizmodel,searchable + false + testobject + + + + + + + false + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + org_id + + + false + Organization + DEL_AUTO + all + + + parent_id + + + true + DEL_AUTO + all + + + caselog + + true + all + + + date + 2010-05-26 + true + all + + + date_time + 2000-01-01 00:00:00 + true + all + + + deadline + 2028-05-26 00:00:00 + true + all + + + decimal + 1.01 + false + 8 + 2 + all + + + duration + 180 + false + all + + + email + test@combodo.com + false + + all + + + encrypted + 1234pwd + false + + all + + + password + + false + + + + onewaypassword + + false + + + + enum + + yes + no + + no + false + radio_horizontal + + all + + + enumset + + + low + + + high + + + large + + + tall + + + thin + + + long + + + short + + + small + + + big + + + true + + all + + + file + true + + + html + + true + + + 200 + all + + + + true + 128 + 128 + 128 + 128 + all + + + integer + 7 + false + all + + + ip_address + 15.28.255.1 + false + + all + + + percentage + 50 + false + + all + + + phone + +33 666333000 + false + + all + + + status + + new + investigation + cancel + done + + new + false + + + all + + + + investigation + + + + true + all + + + stopwatch + started + + + tagset + true + + + all + + + text + + true + + + 30 + all + + + long_text + + true + + + 50 + all + + + url + http://www.combodo.com + false + + _blank + all + + + oql + + true + + + boolean + + true + + + + + + + TestAbstract + + bizmodel,searchable + false + subobject + + + + + + + + + + + + + + + + + + + + + false + true + + + + + + testobject_id + + + false + TestObject + DEL_AUTO + all + + + + testobject_id + name + + + testobject_id + meta_enum + + + testobject_id + org_id + + + testobject_id + parent_id + + + testobject_id + caselog + + + testobject_id + date + + + testobject_id + date_time + + + testobject_id + deadline + + + testobject_id + decimal + + + testobject_id + duration + + + testobject_id + email + + + testobject_id + encrypted + + + testobject_id + password + + + testobject_id + onewaypassword + + + testobject_id + enum + + + testobject_id + enumset + + + testobject_id + file + + + testobject_id + html + + + testobject_id + image + + + testobject_id + integer + + + testobject_id + ip_address + + + testobject_id + percentage + + + testobject_id + phone + + + testobject_id + status + + + testobject_id + stopwatch + + + testobject_id + stopwatch_started + + + testobject_id + tagset + + + testobject_id + text + + + testobject_id + long_text + + + testobject_id + url + + + testobject_id + oql + + + testobject_id + boolean + + + + + + + \ No newline at end of file diff --git a/tests/php-unit-tests/unitary-tests/core/querybuilderexpressions/QueryBuilderExpressionsTest.php b/tests/php-unit-tests/unitary-tests/core/querybuilderexpressions/QueryBuilderExpressionsTest.php new file mode 100644 index 000000000..3f3af0e0e --- /dev/null +++ b/tests/php-unit-tests/unitary-tests/core/querybuilderexpressions/QueryBuilderExpressionsTest.php @@ -0,0 +1,197 @@ + 'tagA', + 'label' => 'Tag A', + 'description' => 'Tag known as "A"' + ]); + $oTagA->DBInsert(); + + $sTargetClass = 'TestObject'; + $aValues = [ + 'name' => [ + 'value' => 'Tadam!', + 'type' => 'php:integer', + ], + 'org_id' => [ + 'value' => $this->getTestOrgId(), + 'type' => 'php:integer', + ], + 'parent_id' => [ + 'value' => 0, + 'type' => 'php:integer', + ], + 'caselog' => [ + 'value' => '{"items":[{"message":"Hi folks!"}]}', + 'type' => 'ormCaseLog', + ], + 'date' => [ + 'value' => '2023-10-04', + 'type' => 'php:string', + ], + 'date_time' => [ + 'value' => '2023-10-04 17:11:54', + 'type' => 'php:string', + ], + 'deadline' => [ + 'value' => '2023-10-04 17:11:54', + 'type' => 'php:string', + ], + 'decimal' => [ + 'value' => '123456.78', + 'type' => 'php:string', + ], + 'duration' => [ + 'value' => 3660, // One hour and one minute + 'type' => 'php:integer', + ], + 'email' => [ + 'value' => 'john.foo@company.com', + 'type' => 'php:string', + ], + 'encrypted' => [ + 'value' => 'secret...inDB!', + 'type' => 'php:string', + ], + 'password' => [ + 'value' => 'abc123', + 'type' => 'php:string', + ], + 'onewaypassword' => [ + 'value' => 'az"e(t-yè', + 'type' => 'php:string', + ], + 'enum' => [ + 'value' => 'yes', + 'type' => 'php:string', + ], + 'enumset' => [ + 'value' => 'low|high', + 'type' => 'php:string', + ], + 'file' => [ + 'value' => '{"data":"blahblah","mimetype":"text/plain","filename":"trash.txt", "downloads_count":0}', + 'type' => 'ormDocument', + ], + 'html' => [ + 'value' => '

Hello world!

', + 'type' => 'php:string', + ], + 'image' => [ + 'value' => '{"data":"notanimage-sowhat?","mimetype":"image/png","filename":"trash.png", "downloads_count":0}', + 'type' => 'ormDocument', + ], + 'integer' => [ + 'value' => 123, + 'type' => 'php:integer', + ], + 'ip_address' => [ + 'value' => '192.158.1.38', + 'type' => 'php:string', + ], + 'percentage' => [ + 'value' => 49.3, + 'type' => 'php:double', + ], + 'phone' => [ + 'value' => '+33476123456', + 'type' => 'php:string', + ], + 'status' => [ + 'value' => 'investigation', + 'type' => 'php:string', + ], + 'stopwatch' => [ + 'value' => null, + 'type' => 'ormStopWatch', + ], + 'tagset' => [ + 'value' => 'tagA', + 'type' => 'php:string', + ], + 'text' => [ + 'value' => 'Hello world!', + 'type' => 'php:string', + ], + 'long_text' => [ + 'value' => 'Hello world!', + 'type' => 'php:string', + ], + 'url' => [ + 'value' => 'http://www.combodo.com/void', + 'type' => 'php:string', + ], + 'oql' => [ + 'value' => 'SELECT Organization', + 'type' => 'php:string', + ], + 'boolean' => [ + 'value' => true, + 'type' => 'php:boolean', + ], + ]; + + $aValuesToSet = []; + foreach ($aValues as $sAttCode => $aValueData) { + if (substr($aValueData['type'], 0, 4) == 'php:') { + $aValuesToSet[$sAttCode] = $aValueData['value']; + } else { + $oAttDef = \MetaModel::GetAttributeDef($sTargetClass, $sAttCode); + $oJSONObject = is_null($aValueData['value']) ? null : json_decode($aValueData['value'], false); + $aValuesToSet[$sAttCode] = $oAttDef->FromJSONToValue($oJSONObject); + } + } + + + // Test that I can write without any error (such as malformed SQL query, that would throw an exception) + $oObject = \MetaModel::NewObject($sTargetClass, $aValuesToSet); + $oObject->DBInsert(); + + // Test that I can read without any error (such as malformed SQL query, that would throw an exception) + $iTestObject = $oObject->GetKey(); + $oObjectFromDB = \MetaModel::GetObject($sTargetClass, $iTestObject); + + // Test that each value matches the original value + foreach ($aValues as $sAttCode => $aValueData) { + $oAttDef = \MetaModel::GetAttributeDef($sTargetClass, $sAttCode); + static::assertTrue($oAttDef->Equals( + $oObject->Get($sAttCode), + $oObjectFromDB->Get($sAttCode) + ), "Value of attribute '$sAttCode' has been altered after DB write + read"); + } + + // Create an indirection + $oSubObject = \MetaModel::NewObject('SubObject', [ + 'name' => 'subobject for '.$iTestObject, + 'testobject_id' => $iTestObject + ]); + $oSubObject->DBInsert(); + + // Test that it can be read from the DB + $iSubObject = $oSubObject->GetKey(); + $oSubObjectFromDB = \MetaModel::GetObject('SubObject', $iSubObject); + + // Test that each external field value matches the original value + foreach ($aValues as $sAttCode => $aValueData) { + $sExtFieldAttCode = '_'.$sAttCode; + $oAttDef = \MetaModel::GetAttributeDef($sTargetClass, $sAttCode); + static::assertTrue($oAttDef->Equals($oObject->Get($sAttCode), $oSubObjectFromDB->Get($sExtFieldAttCode)), "Value of attribute '$sAttCode' not correctly read as an external key"); + } + } +} \ No newline at end of file