GetOptional("is_null_allowed", false); } // Facilitate things: allow the user to Set the value from a string or from an ormPassword (already encrypted) public function MakeRealValue($proposedValue, $oHostObj) { $oPassword = $proposedValue; if (is_object($oPassword)) { $oPassword = clone $proposedValue; } else { $oPassword = new ormPassword('', ''); $oPassword->SetPassword($proposedValue); } return $oPassword; } public function GetSQLExpressions($sPrefix = '') { if ($sPrefix == '') { $sPrefix = $this->GetCode(); // Warning: AttributeOneWayPassword does not have any sql property so code = sql ! } $aColumns = []; // Note: to optimize things, the existence of the attribute is determined by the existence of one column with an empty suffix $aColumns[''] = $sPrefix.'_hash'; $aColumns['_salt'] = $sPrefix.'_salt'; return $aColumns; } public function FromSQLToValue($aCols, $sPrefix = '') { if (!array_key_exists($sPrefix, $aCols)) { $sAvailable = implode(', ', array_keys($aCols)); throw new MissingColumnException("Missing column '$sPrefix' from {$sAvailable}"); } $hashed = isset($aCols[$sPrefix]) ? $aCols[$sPrefix] : ''; if (!array_key_exists($sPrefix.'_salt', $aCols)) { $sAvailable = implode(', ', array_keys($aCols)); throw new MissingColumnException("Missing column '".$sPrefix."_salt' from {$sAvailable}"); } $sSalt = isset($aCols[$sPrefix.'_salt']) ? $aCols[$sPrefix.'_salt'] : ''; $value = new ormPassword($hashed, $sSalt); return $value; } public function GetSQLValues($value) { // #@# Optimization: do not load blobs anytime // As per mySQL doc, selecting blob columns will prevent mySQL from // using memory in case a temporary table has to be created // (temporary tables created on disk) // We will have to remove the blobs from the list of attributes when doing the select // then the use of Get() should finalize the load if ($value instanceof ormPassword) { $aValues = []; $aValues[$this->GetCode().'_hash'] = $value->GetHash(); $aValues[$this->GetCode().'_salt'] = $value->GetSalt(); } else { $aValues = []; $aValues[$this->GetCode().'_hash'] = ''; $aValues[$this->GetCode().'_salt'] = ''; } return $aValues; } public function GetSQLColumns($bFullSpec = false) { $aColumns = []; $aColumns[$this->GetCode().'_hash'] = 'TINYBLOB'; $aColumns[$this->GetCode().'_salt'] = 'TINYBLOB'; return $aColumns; } public function GetImportColumns() { $aColumns = []; $aColumns[$this->GetCode()] = 'TINYTEXT'.CMDBSource::GetSqlStringColumnDefinition(); return $aColumns; } public function FromImportToValue($aCols, $sPrefix = '') { if (!isset($aCols[$sPrefix])) { $sAvailable = implode(', ', array_keys($aCols)); throw new MissingColumnException("Missing column '$sPrefix' from {$sAvailable}"); } $sClearPwd = $aCols[$sPrefix]; $oPassword = new ormPassword('', ''); $oPassword->SetPassword($sClearPwd); return $oPassword; } public function GetBasicFilterOperators() { return []; } public function GetBasicFilterLooseOperator() { return '='; } public function GetBasicFilterSQLExpr($sOpCode, $value) { return 'true'; } public function GetAsHTML($value, $oHostObject = null, $bLocalize = true) { if (is_object($value)) { return $value->GetAsHTML(); } return ''; } public function GetAsCSV( $sValue, $sSeparator = ',', $sTextQualifier = '"', $oHostObject = null, $bLocalize = true, $bConvertToPlainText = false ) { return ''; // Not exportable in CSV } public function GetAsXML($value, $oHostObject = null, $bLocalize = true) { return ''; // Not exportable in XML } public function GetValueLabel($sValue, $oHostObj = null) { // Don't display anything in "group by" reports return '*****'; } /** * @inheritDoc */ public function HasAValue($proposedValue): bool { // Protection against wrong value type if (false === ($proposedValue instanceof ormPassword)) { // On object creation, the attribute value is "" instead of an ormPassword... if (is_string($proposedValue)) { return utils::IsNotNullOrEmptyString($proposedValue); } return parent::HasAValue($proposedValue); } return $proposedValue->IsEmpty() === false; } protected function GetChangeRecordAdditionalData(CMDBChangeOp $oMyChangeOp, DBObject $oObject, $original, $value): void { if (is_null($original)) { $original = ''; } $oMyChangeOp->Set("prev_pwd", $original); } protected function GetChangeRecordClassName(): string { return CMDBChangeOpSetAttributeOneWayPassword::class; } }