mirror of
https://github.com/Combodo/iTop.git
synced 2026-04-23 10:38:45 +02:00
WIP
This commit is contained in:
@@ -34,7 +34,9 @@
|
||||
*/
|
||||
class ObjectResult
|
||||
{
|
||||
public $code;
|
||||
use SanitizeTrait;
|
||||
|
||||
public $code;
|
||||
public $message;
|
||||
public $class;
|
||||
public $key;
|
||||
@@ -125,16 +127,16 @@ class ObjectResult
|
||||
|
||||
public function SanitizeContent()
|
||||
{
|
||||
foreach($this->fields as $sAttCode => $value)
|
||||
foreach($this->fields as $sFieldAttCode => $fieldValue)
|
||||
{
|
||||
try{
|
||||
$oAttDef = MetaModel::GetAttributeDef($this->class, $sAttCode);
|
||||
$oAttDef = MetaModel::GetAttributeDef($this->class, $sFieldAttCode);
|
||||
} catch (Exception $e) { // for special cases like ID
|
||||
continue;
|
||||
}
|
||||
if ($oAttDef instanceof iAttributeNoGroupBy) // iAttributeNoGroupBy is equivalent to sensitive attribute
|
||||
{
|
||||
$this->fields[$sAttCode] = '******';
|
||||
$this->SanitizeFieldIfSensitive($this->fields, $sFieldAttCode, $fieldValue, $oAttDef);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -275,7 +277,8 @@ class RestDelete
|
||||
*/
|
||||
class CoreServices implements iRestServiceProvider, iRestInputSanitizer
|
||||
{
|
||||
/**
|
||||
use SanitizeTrait;
|
||||
/**
|
||||
* Enumerate services delivered by this class
|
||||
*
|
||||
* @param string $sVersion The version (e.g. 1.0) supported by the services
|
||||
@@ -707,12 +710,9 @@ class CoreServices implements iRestServiceProvider, iRestInputSanitizer
|
||||
default :
|
||||
$sClass = $aJsonData['class'];
|
||||
if (isset($aJsonData['fields'])) {
|
||||
foreach ($aJsonData['fields'] as $sAttCode => $value) {
|
||||
$oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode);
|
||||
if ($oAttDef instanceof iAttributeNoGroupBy) // iAttributeNoGroupBy is equivalent to sensitive attribute
|
||||
{
|
||||
$aJsonData['fields'][$sAttCode] = '*****';
|
||||
}
|
||||
foreach ($aJsonData['fields'] as $sFieldAttCode => $fieldValue) {
|
||||
$oAttDef = MetaModel::GetAttributeDef($sClass, $sFieldAttCode);
|
||||
$this->SanitizeFieldIfSensitive($aJsonData['fields'], $sFieldAttCode, $fieldValue, $oAttDef);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -858,3 +858,51 @@ class CoreServices implements iRestServiceProvider, iRestInputSanitizer
|
||||
return $iLimit * max(0, $iPage - 1);
|
||||
}
|
||||
}
|
||||
|
||||
trait SanitizeTrait
|
||||
{
|
||||
/**
|
||||
* Sanitize a field if it is sensitive.
|
||||
*
|
||||
* @param array $fields The fields array
|
||||
* @param string $sFieldAttCode The attribute code
|
||||
* @param mixed $oAttDef The attribute definition
|
||||
*/
|
||||
private function SanitizeFieldIfSensitive(array &$fields, string $sFieldAttCode, $fieldValue, $oAttDef): void
|
||||
{
|
||||
if ($oAttDef instanceof iAttributeNoGroupBy) // iAttributeNoGroupBy is equivalent to sensitive attribute
|
||||
{
|
||||
$fields[$sFieldAttCode] = '*****';
|
||||
}
|
||||
if ($oAttDef instanceof AttributeLinkedSet) { // for 1-n relations
|
||||
foreach ($fieldValue as $i => $aLnkValues) {
|
||||
foreach ($aLnkValues as $sLnkAttCode => $sLnkValue) {
|
||||
$oLnkAttDef = MetaModel::GetAttributeDef($oAttDef->GetLinkedClass(), $sLnkAttCode);
|
||||
if ($oLnkAttDef instanceof iAttributeNoGroupBy) // iAttributeNoGroupBy is equivalent to sensitive attribute
|
||||
{
|
||||
$fields[$sFieldAttCode][$i][$sLnkAttCode] = '*****';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($oAttDef instanceof AttributeLinkedSetIndirect) { // for n-n relations
|
||||
foreach ($fieldValue as $i => $aLnkValues) {
|
||||
foreach ($aLnkValues as $sLnkAttCode => $sLnkValue) {
|
||||
$oLnkAttDef = MetaModel::GetAttributeDef($oAttDef->GetLinkedClass(), $sLnkAttCode);
|
||||
if ($oLnkAttDef instanceof iAttributeNoGroupBy) // iAttributeNoGroupBy is equivalent to sensitive attribute
|
||||
{
|
||||
$fields[$sFieldAttCode][$i][$sLnkAttCode] = '*****';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// for external key
|
||||
if ($oAttDef instanceof AttributeExternalKey) {
|
||||
$oExtKeyAttDef = MetaModel::GetAttributeDef($oAttDef->GetTargetClass(), $oAttDef->GetCode());
|
||||
if ($oExtKeyAttDef instanceof iAttributeNoGroupBy) // iAttributeNoGroupBy is equivalent to sensitive attribute
|
||||
{
|
||||
$fields[$sFieldAttCode] = '*****';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,15 +6,6 @@
|
||||
<field id="encrypted_string" xsi:type="AttributeEncryptedString" _delta="define">
|
||||
<sql>encrypted_string</sql>
|
||||
</field>
|
||||
|
||||
<class id="lnkGroupToCI" _created_in="itop-config-mgmt">
|
||||
<fields>
|
||||
<field id="password" xsi:type="AttributeExternalField" _delta="define">
|
||||
<extkey_attcode>group_id</extkey_attcode>
|
||||
<target_attcode>password</target_attcode>
|
||||
</field>
|
||||
</fields>
|
||||
</class>
|
||||
</fields>
|
||||
</class>
|
||||
</classes>
|
||||
|
||||
@@ -42,7 +42,7 @@ class RestServicesSanitizeOutputTest extends iTopCustomDatamodelTestCase
|
||||
$oRestResultWithObject = new \RestResultWithObjects();
|
||||
$oRestResultWithObject->AddObject(0, "ok", $oGroup, ['Group' => ['encrypted_string']]);
|
||||
$oRestResultWithObject->SanitizeContent();
|
||||
$this->assertEquals('{"objects":{"Group::-1":{"code":0,"message":"ok","class":"Group","key":-1,"fields":{"encrypted_string":"******"}}},"code":0,"message":null}', json_encode($oRestResultWithObject));
|
||||
$this->assertEquals('{"objects":{"Group::-1":{"code":0,"message":"ok","class":"Group","key":-1,"fields":{"encrypted_string":"*****"}}},"code":0,"message":null}', json_encode($oRestResultWithObject));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -119,22 +119,22 @@ class RestServicesTest extends ItopDataTestCase
|
||||
'core/update' => [
|
||||
'core/update',
|
||||
['comment' => 'Update user', 'class' => 'UserLocal', 'key' => ['login' => 'my_example'], 'output_fields' => 'password', 'fields' => ['password' => 'opkB!req57']],
|
||||
'{"objects":{"UserLocal::-1":{"code":0,"message":"ok","class":"UserLocal","key":-1,"fields":{"login":"","password":"******"}}},"code":0,"message":null}'
|
||||
'{"objects":{"UserLocal::-1":{"code":0,"message":"ok","class":"UserLocal","key":-1,"fields":{"login":"","password":"*****"}}},"code":0,"message":null}'
|
||||
],
|
||||
'core/create' => [
|
||||
'core/create',
|
||||
['comment' => 'Create user', 'class' => 'UserLocal', 'fields' => ['password' => 'Azertyuiiop*12', 'login' => 'toto', 'profile_list' => [1]]],
|
||||
'{"objects":{"UserLocal::-1":{"code":0,"message":"ok","class":"UserLocal","key":-1,"fields":{"login":"","password":"******"}}},"code":0,"message":null}'
|
||||
'{"objects":{"UserLocal::-1":{"code":0,"message":"ok","class":"UserLocal","key":-1,"fields":{"login":"","password":"*****"}}},"code":0,"message":null}'
|
||||
],
|
||||
'core/get' => [
|
||||
'core/get',
|
||||
['comment' => 'Get user', 'class' => 'UserLocal', 'key' => ['login' => 'my_example'], 'output_fields' => 'first_name, password'],
|
||||
'{"objects":{"UserLocal::-1":{"code":0,"message":"ok","class":"UserLocal","key":-1,"fields":{"login":"","password":"******"}}},"code":0,"message":null}'
|
||||
'{"objects":{"UserLocal::-1":{"code":0,"message":"ok","class":"UserLocal","key":-1,"fields":{"login":"","password":"*****"}}},"code":0,"message":null}'
|
||||
],
|
||||
'core/check_credentials' => [
|
||||
'core/check_credentials',
|
||||
['user' => 'admin', 'password' => 'admin'],
|
||||
'{"objects":{"UserLocal::-1":{"code":0,"message":"ok","class":"UserLocal","key":-1,"fields":{"login":"","password":"******"}}},"code":0,"message":null}' ],
|
||||
'{"objects":{"UserLocal::-1":{"code":0,"message":"ok","class":"UserLocal","key":-1,"fields":{"login":"","password":"*****"}}},"code":0,"message":null}' ],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user