mirror of
https://github.com/Combodo/iTop.git
synced 2026-04-24 02:58:43 +02:00
WIP
This commit is contained in:
@@ -138,7 +138,14 @@ abstract class AttributeDefinition
|
|||||||
|
|
||||||
protected $aCSSClasses;
|
protected $aCSSClasses;
|
||||||
|
|
||||||
public function GetType()
|
private $bIsSensitive = false;
|
||||||
|
|
||||||
|
public function IsSensitive()
|
||||||
|
{
|
||||||
|
return $this->bIsSensitive;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function GetType()
|
||||||
{
|
{
|
||||||
return Dict::S('Core:'.get_class($this));
|
return Dict::S('Core:'.get_class($this));
|
||||||
}
|
}
|
||||||
@@ -3775,7 +3782,12 @@ class AttributeFinalClass extends AttributeString
|
|||||||
*/
|
*/
|
||||||
class AttributePassword extends AttributeString implements iAttributeNoGroupBy
|
class AttributePassword extends AttributeString implements iAttributeNoGroupBy
|
||||||
{
|
{
|
||||||
const SEARCH_WIDGET_TYPE = self::SEARCH_WIDGET_TYPE_RAW;
|
private $bIsSensitive = true;
|
||||||
|
public function IsSensitive()
|
||||||
|
{
|
||||||
|
return $this->bIsSensitive;
|
||||||
|
}
|
||||||
|
const SEARCH_WIDGET_TYPE = self::SEARCH_WIDGET_TYPE_RAW;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Useless constructor, but if not present PHP 7.4.0/7.4.1 is crashing :( (N°2329)
|
* Useless constructor, but if not present PHP 7.4.0/7.4.1 is crashing :( (N°2329)
|
||||||
@@ -3851,7 +3863,12 @@ class AttributePassword extends AttributeString implements iAttributeNoGroupBy
|
|||||||
*/
|
*/
|
||||||
class AttributeEncryptedString extends AttributeString implements iAttributeNoGroupBy
|
class AttributeEncryptedString extends AttributeString implements iAttributeNoGroupBy
|
||||||
{
|
{
|
||||||
const SEARCH_WIDGET_TYPE = self::SEARCH_WIDGET_TYPE_RAW;
|
private $bIsSensitive = true;
|
||||||
|
public function IsSensitive()
|
||||||
|
{
|
||||||
|
return $this->bIsSensitive;
|
||||||
|
}
|
||||||
|
const SEARCH_WIDGET_TYPE = self::SEARCH_WIDGET_TYPE_RAW;
|
||||||
|
|
||||||
static $sKey = null; // Encryption key used for all encrypted fields
|
static $sKey = null; // Encryption key used for all encrypted fields
|
||||||
static $sLibrary = null; // Encryption library used for all encrypted fields
|
static $sLibrary = null; // Encryption library used for all encrypted fields
|
||||||
@@ -9243,7 +9260,12 @@ class AttributeSubItem extends AttributeDefinition
|
|||||||
*/
|
*/
|
||||||
class AttributeOneWayPassword extends AttributeDefinition implements iAttributeNoGroupBy
|
class AttributeOneWayPassword extends AttributeDefinition implements iAttributeNoGroupBy
|
||||||
{
|
{
|
||||||
const SEARCH_WIDGET_TYPE = self::SEARCH_WIDGET_TYPE_RAW;
|
private $bIsSensitive = true;
|
||||||
|
public function IsSensitive()
|
||||||
|
{
|
||||||
|
return $this->bIsSensitive;
|
||||||
|
}
|
||||||
|
const SEARCH_WIDGET_TYPE = self::SEARCH_WIDGET_TYPE_RAW;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Useless constructor, but if not present PHP 7.4.0/7.4.1 is crashing :( (N°2329)
|
* Useless constructor, but if not present PHP 7.4.0/7.4.1 is crashing :( (N°2329)
|
||||||
|
|||||||
@@ -123,7 +123,7 @@ class ObjectResult
|
|||||||
$this->fields[$sAttCode] = $this->MakeResultValue($oObject, $sAttCode, $bExtendedOutput);
|
$this->fields[$sAttCode] = $this->MakeResultValue($oObject, $sAttCode, $bExtendedOutput);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function SanitizeContent()
|
/* public function SanitizeContent()
|
||||||
{
|
{
|
||||||
foreach($this->fields as $sAttCode => $value)
|
foreach($this->fields as $sAttCode => $value)
|
||||||
{
|
{
|
||||||
@@ -132,12 +132,12 @@ class ObjectResult
|
|||||||
} catch (Exception $e) { // for special cases like ID
|
} catch (Exception $e) { // for special cases like ID
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if ($oAttDef instanceof AttributeEncryptedString || $oAttDef instanceof AttributePassword || $oAttDef instanceof AttributeOneWayPassword)
|
if ($oAttDef->IsSensitive())
|
||||||
{
|
{
|
||||||
$this->fields[$sAttCode] = '******';
|
$this->fields[$sAttCode] = '******';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -198,7 +198,7 @@ class RestResultWithObjects extends RestResult
|
|||||||
$this->objects[$sObjKey] = $oObjRes;
|
$this->objects[$sObjKey] = $oObjRes;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function SanitizeContent()
|
/* public function SanitizeContent()
|
||||||
{
|
{
|
||||||
parent::SanitizeContent();
|
parent::SanitizeContent();
|
||||||
|
|
||||||
@@ -206,7 +206,7 @@ class RestResultWithObjects extends RestResult
|
|||||||
{
|
{
|
||||||
$oObjRes->SanitizeContent();
|
$oObjRes->SanitizeContent();
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
class RestResultWithRelations extends RestResultWithObjects
|
class RestResultWithRelations extends RestResultWithObjects
|
||||||
@@ -708,7 +708,8 @@ class CoreServices implements iRestServiceProvider, iRestInputSanitizer
|
|||||||
$sClass = $aJsonData['class'];
|
$sClass = $aJsonData['class'];
|
||||||
foreach ($aJsonData['fields'] as $sAttCode => $value) {
|
foreach ($aJsonData['fields'] as $sAttCode => $value) {
|
||||||
$oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode);
|
$oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode);
|
||||||
if ($oAttDef instanceof AttributeEncryptedString || $oAttDef instanceof AttributePassword || $oAttDef instanceof AttributeOneWayPassword) {
|
var_dump($oAttDef);
|
||||||
|
if ($oAttDef->IsSensitive()) {
|
||||||
$aJsonData['fields'][$sAttCode] = '*****';
|
$aJsonData['fields'][$sAttCode] = '*****';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,9 +24,12 @@ use CoreException;
|
|||||||
use CoreServices;
|
use CoreServices;
|
||||||
use CoreUnexpectedValue;
|
use CoreUnexpectedValue;
|
||||||
use SimpleGraphException;
|
use SimpleGraphException;
|
||||||
use UserLocal;
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @runTestsInSeparateProcesses
|
||||||
|
* @preserveGlobalState disabled
|
||||||
|
* @backupGlobals disabled
|
||||||
|
*/
|
||||||
class RestServicesTest extends ItopDataTestCase
|
class RestServicesTest extends ItopDataTestCase
|
||||||
{
|
{
|
||||||
public function setUp(): void
|
public function setUp(): void
|
||||||
@@ -34,8 +37,6 @@ class RestServicesTest extends ItopDataTestCase
|
|||||||
parent::setUp();
|
parent::setUp();
|
||||||
}
|
}
|
||||||
|
|
||||||
// provider
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return void
|
* @return void
|
||||||
* @dataProvider providerTestSanitizeJsonInput
|
* @dataProvider providerTestSanitizeJsonInput
|
||||||
@@ -47,47 +48,47 @@ class RestServicesTest extends ItopDataTestCase
|
|||||||
$this->assertEquals($sExpectedJsonDataSanitized, $sOutputJson);
|
$this->assertEquals($sExpectedJsonDataSanitized, $sOutputJson);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testCoreUpdateSanitization()
|
public function providerTestSanitizeJsonInput()
|
||||||
{
|
{
|
||||||
$sJsonData = <<<JSON
|
return [
|
||||||
{
|
'core/check_credentials' => [
|
||||||
"operation": "core/update",
|
'{"operation": "core/check_credentials", "user": "admin", "password": "admin"}',
|
||||||
"comment": "Update user",
|
'{
|
||||||
"class": "UserLocal",
|
"operation": "core/check_credentials",
|
||||||
"key":
|
"user": "admin",
|
||||||
{
|
"password": "*****"
|
||||||
"description": "The fridge is empty"
|
}'
|
||||||
},
|
],
|
||||||
"output_fields": "first_name, password",
|
'core/update' => [
|
||||||
"fields":
|
'{"operation": "core/update", "comment": "Update user", "class": "UserLocal", "key": {"id":1}, "output_fields": "first_name, password", "fields": {"password" : "123456"}}',
|
||||||
{
|
'{
|
||||||
"id": "1",
|
"operation": "core/update",
|
||||||
"password" : "123456"
|
"comment": "Update user",
|
||||||
}
|
"class": "UserLocal",
|
||||||
}
|
"key": {
|
||||||
JSON;
|
"id": 1
|
||||||
$sExpectedJsonDataSanitized = <<<JSON
|
},
|
||||||
{
|
"output_fields": "first_name, password",
|
||||||
"operation": "core/update",
|
"fields": {
|
||||||
"comment": "Update user",
|
"password": "*****"
|
||||||
"class": "UserLocal",
|
}
|
||||||
"key":
|
}'
|
||||||
{
|
],
|
||||||
"description": "My description"
|
'core/create' => [
|
||||||
},
|
'{"operation": "core/create", "comment": "Create user", "class": "UserLocal", "fields": {"first_name": "John", "last_name": "Doe", "email": "jd@example/com", "password" : "123456"}}',
|
||||||
"output_fields": "first_name, password",
|
'{
|
||||||
"fields":
|
"operation": "core/create",
|
||||||
{
|
"comment": "Create user",
|
||||||
"id": "1",
|
"class": "UserLocal",
|
||||||
"password" : "123456"
|
"fields": {
|
||||||
}
|
"first_name": "John",
|
||||||
}
|
"last_name": "Doe",
|
||||||
JSON;
|
"email": "jd@example/com",
|
||||||
|
"password": "*****"
|
||||||
$sOutputJson = $this->CallCoreRestApi_Internally($sJsonData);
|
}
|
||||||
$aJson = json_decode($sOutputJson, true);
|
}'
|
||||||
$this->assertEquals(0, $aJson['code'], $sOutputJson); // answer is still the same
|
],
|
||||||
$this->assertEquals($sExpectedJsonDataSanitized, $aJson['input_data'], $sOutputJson);
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -102,60 +103,55 @@ JSON;
|
|||||||
*/
|
*/
|
||||||
public function testSanitizeJsonOutput($sOperation, $aJsonData, $sExpectedJsonDataSanitized)
|
public function testSanitizeJsonOutput($sOperation, $aJsonData, $sExpectedJsonDataSanitized)
|
||||||
{
|
{
|
||||||
|
$this->CreateUser('my_example', '1', 'Azertyuiiop*12', 1);
|
||||||
$oRS = new CoreServices();
|
$oRS = new CoreServices();
|
||||||
$oUser = new UserLocal();
|
$oResult = $oRS->ExecOperation(1.3, $sOperation, json_decode(json_encode($aJsonData)));
|
||||||
$oUser->Set('password', "123456");
|
// delete every pattern like "::xxx"
|
||||||
$oRestResultWithObject = new \RestResultWithObjects();
|
$actualResult = json_encode($oResult);
|
||||||
$oRestResultWithObject->AddObject(0, "ok", $oUser, ['UserLocal' => ['login', 'password']]);
|
$sExpectedJsonDataSanitized = preg_replace('/::[0-9]+/', '', $sExpectedJsonDataSanitized);
|
||||||
$oRestResultWithObject->SanitizeContent();
|
$actualResult = preg_replace('/::[0-9]+/', '', $actualResult);
|
||||||
$this->assertEquals($sExpectedJsonDataSanitized, json_encode($oRestResultWithObject));
|
// convert both to arrays
|
||||||
}
|
$actualResult = json_decode($actualResult, true);
|
||||||
|
$sExpectedJsonDataSanitized = json_decode($sExpectedJsonDataSanitized, true);
|
||||||
|
$this->recursive_unset($actualResult, 'key');
|
||||||
|
$this->recursive_unset($sExpectedJsonDataSanitized, 'key');
|
||||||
|
|
||||||
public function providerTestSanitizeJsonInput()
|
|
||||||
{
|
$this->assertEquals($sExpectedJsonDataSanitized, $actualResult);
|
||||||
return [
|
|
||||||
'core/check_credentials' => [
|
|
||||||
'{"operation": "core/check_credentials", "user": "admin", "password": "admin"}',
|
|
||||||
'{
|
|
||||||
"operation": "core/check_credentials",
|
|
||||||
"user": "admin",
|
|
||||||
"password": "*****"
|
|
||||||
}'
|
|
||||||
],
|
|
||||||
'core/update' => [
|
|
||||||
'{"operation": "core/update", "comment": "Update user", "class": "UserLocal", "key": {"id":1}, "output_fields": "first_name, password", "fields": {"password" : "123456"}}',
|
|
||||||
'{"operation": "core/update", "comment": "Update user", "class": "UserLocal", "key": {"id":1}, "output_fields": "first_name, password", "fields": {"password" : "*****"}}'
|
|
||||||
],
|
|
||||||
'core/create' => [
|
|
||||||
'{"operation": "core/create", "comment": "Create user", "class": "UserLocal", "fields": {"first_name": "John", "last_name": "Doe", "email": "jd@example/com", "password" : "123456"}}',
|
|
||||||
'{"operation": "core/create", "comment": "Create user", "class": "UserLocal", "fields": {"first_name": "John", "last_name": "Doe", "email": "jd@example/com", "password" : "*****"}}',
|
|
||||||
],
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function providerTestSanitizeJsonOutput()
|
public function providerTestSanitizeJsonOutput()
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'core/check_credentials' => [
|
|
||||||
'core/check_credentials',
|
'core/update' => [
|
||||||
['user' => 'admin', 'password' => 'admin'],
|
'core/update',
|
||||||
'{"operation":"core/check_credentials","user":"admin","password":"*****"}'
|
['comment' => 'Update user', 'class' => 'UserLocal', 'key' => ['login' => 'my_example'], 'output_fields' => 'password', 'fields' => ['password' => 'opkB!req57']],
|
||||||
],
|
'{"objects":{"UserLocal::78":{"code":0,"message":"updated","class":"UserLocal","key":"78","fields":{"password":"*****"}}},"code":0,"message":null}'],
|
||||||
'core/update' => [
|
'core/create' => [
|
||||||
'core/update',
|
'core/create',
|
||||||
['comment' => 'Update user', 'class' => 'UserLocal', 'key' => ['description' => 'My description'], 'output_fields' => 'first_name, password', 'fields' => ['id' => '1', 'password' => '123456']],
|
['comment' => 'Create user', 'class' => 'UserLocal', 'fields' => ['password' => 'Azertyuiiop*12', 'login' => 'toto', 'profile_list' => [1]]],
|
||||||
'{"operation":"core/update","comment":"Update user","class":"UserLocal","key":{"description":"My description"},"output_fields":"first_name, password","fields":{"id":"1","password":"*****"}}'
|
'{"operation":"core/create","comment":"Create user","class":"UserLocal","fields":{"first_name":"John","last_name":"Doe","email":"jd@example/com","password":"*****"}}'
|
||||||
],
|
],
|
||||||
'core/create' => [
|
'core/get' => [
|
||||||
'core/create',
|
'core/get',
|
||||||
['comment' => 'Create user', 'class' => 'UserLocal', 'fields' => ['first_name' => 'John', 'last_name' => 'Doe', 'email' => 'jd@example/com', 'password' => '123456']],
|
['comment' => 'Get user', 'class' => 'UserLocal', 'key' => ['login' => 'my_example'], 'output_fields' => 'first_name, password'],
|
||||||
'{"operation":"core/create","comment":"Create user","class":"UserLocal","fields":{"first_name":"John","last_name":"Doe","email":"jd@example/com","password":"*****"}}'
|
'{"objects":{"UserLocal":{"code":0,"message":"","class":"UserLocal","key":"148","fields":{"first_name":"My first name","password":"*****"}}},"code":0,"message":"Found: 1"}'
|
||||||
],
|
],
|
||||||
'core/get' => [
|
'core/check_credentials' => [
|
||||||
'core/get',
|
'core/check_credentials',
|
||||||
['comment' => 'Get user', 'class' => 'UserLocal', 'key' => ['id' => '1'], 'output_fields' => 'first_name, password'],
|
['user' => 'admin', 'password' => 'admin'],
|
||||||
'{"operation":"core/get","comment":"Get user","class":"UserLocal","key":{"id":"1"},"output_fields":"first_name, password"}'
|
'{"code":0,"message":null,"authorized":true}'
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function recursive_unset(&$array, $unwanted_key) {
|
||||||
|
unset($array[$unwanted_key]);
|
||||||
|
foreach ($array as &$value) {
|
||||||
|
if (is_array($value)) {
|
||||||
|
$this->recursive_unset($value, $unwanted_key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user