Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

User inventory rule #16972

Merged
merged 10 commits into from May 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/Inventory/Asset/InventoryAsset.php
Expand Up @@ -430,6 +430,10 @@ public function isNew(): bool
protected function handleInput(\stdClass $value, ?CommonDBTM $item = null): array
{
$input = ['_auto' => 1];
if (property_exists($value, '_inventory_users')) {
$input = ['_inventory_users' => $value->_inventory_users];
}

$locks = [];

if ($item !== null) {
Expand Down
7 changes: 7 additions & 0 deletions src/Inventory/Asset/MainAsset.php
Expand Up @@ -276,6 +276,7 @@ protected function prepareForUsers($val)

// * USERS
$cnt = 0;
$_inventory_users = [];
if (isset($this->extra_data['users'])) {
if (count($this->extra_data['users']) > 0) {
$user_temp = '';
Expand All @@ -295,6 +296,8 @@ protected function prepareForUsers($val)
$user .= "@" . $a_users->domain;
}
}
$_inventory_users[] = $user;

if ($cnt == 0) {
if (property_exists($a_users, 'login')) {
// Search on domain
Expand Down Expand Up @@ -347,6 +350,10 @@ protected function prepareForUsers($val)
$val->contact = $user_temp ?? '';
}
}

if (!empty($_inventory_users)) {
$val->_inventory_users = $_inventory_users;
}
}

protected function prepareForBios($val)
Expand Down
79 changes: 70 additions & 9 deletions src/RuleAsset.php
Expand Up @@ -158,6 +158,19 @@ public function getCriterias()
Rule::PATTERN_DATE_IS_NOT_EQUAL,
];

$criterias['_inventory_users']['name'] = __('User from inventory');
$criterias['_inventory_users']['allow_condition'] = [
Rule::REGEX_MATCH,
Rule::REGEX_NOT_MATCH,
Rule::PATTERN_EXISTS,
Rule::PATTERN_DOES_NOT_EXISTS,
Rule::PATTERN_BEGIN,
Rule::PATTERN_END,
Rule::PATTERN_IS_EMPTY,
Rule::PATTERN_CONTAIN,
Rule::PATTERN_NOT_CONTAIN
];

return $criterias;
}

Expand Down Expand Up @@ -206,6 +219,22 @@ public function getActions()
$actions['otherserial']['type'] = 'text';
$actions['otherserial']['force_actions'] = ['regex_result'];

$actions['_affect_user_by_name_and_regex']['name'] = __('Assign user from name');
$actions['_affect_user_by_name_and_regex']['type'] = 'text';
$actions['_affect_user_by_name_and_regex']['force_actions'] = ['regex_result'];

$actions['_affect_user_by_email_and_regex']['name'] = __('Assign user from email');
$actions['_affect_user_by_email_and_regex']['type'] = 'text';
$actions['_affect_user_by_email_and_regex']['force_actions'] = ['regex_result'];

$actions['_affect_user_by_registration_number_and_regex']['name'] = __('Assign user from registration number');
$actions['_affect_user_by_registration_number_and_regex']['type'] = 'text';
$actions['_affect_user_by_registration_number_and_regex']['force_actions'] = ['regex_result'];

$actions['_affect_user_by_sync_field_and_regex']['name'] = __('Assign user from sync field');
$actions['_affect_user_by_sync_field_and_regex']['type'] = 'text';
$actions['_affect_user_by_sync_field_and_regex']['force_actions'] = ['regex_result'];

return $actions;
}

Expand Down Expand Up @@ -246,16 +275,48 @@ public function executeActions($output, $params, array $input = [])
case "regex_result":
switch ($action->fields["field"]) {
case "_affect_user_by_regex":
case "_affect_user_by_name_and_regex":
foreach ($this->regex_results as $regex_result) {
$res = RuleAction::getRegexResultById(
$action->fields["value"],
$regex_result
);
if ($res != null) {
$user = User::getIdByName($res);
if ($user) {
$output['users_id'] = $user;
}
$res = RuleAction::getRegexResultById(
$action->fields["value"],
$regex_result
);
if ($res != null && $user = User::getIdByName($res)) {
$output['users_id'] = $user;
}
}
break;
case "_affect_user_by_email_and_regex":
foreach ($this->regex_results as $regex_result) {
$res = RuleAction::getRegexResultById(
$action->fields["value"],
$regex_result
);
$user = new User();
if ($res != null && $user->getFromDBbyEmail($res)) {
$output['users_id'] = $user->fields['id'];
}
}
break;
case "_affect_user_by_registration_number_and_regex":
foreach ($this->regex_results as $regex_result) {
$res = RuleAction::getRegexResultById(
$action->fields["value"],
$regex_result
);
if ($res != null && $user = User::getIdByField('registration_number', $res)) {
$output['users_id'] = $user;
}
}
break;
case "_affect_user_by_sync_field_and_regex":
foreach ($this->regex_results as $regex_result) {
$res = RuleAction::getRegexResultById(
$action->fields["value"],
$regex_result
);
if ($res != null && $user = User::getIdByField('sync_field', $res)) {
$output['users_id'] = $user;
}
}
break;
Expand Down
238 changes: 238 additions & 0 deletions tests/functional/Glpi/Inventory/Inventory.php
Expand Up @@ -44,6 +44,7 @@
use OperatingSystemServicePack;
use OperatingSystemVersion;
use RuleCriteria;
use UserEmail;
use wapmorgan\UnifiedArchive\UnifiedArchive;

class Inventory extends InventoryTestCase
Expand Down Expand Up @@ -7853,4 +7854,241 @@ public function testStatusIfInventoryOnAddUpdate()
$this->boolean($computer->getFromDB($agent['items_id']))->isTrue();
$this->integer($computer->fields['states_id'])->isIdenticalTo($states_id);
}

protected function getAssignUserByFieldAndRegexRules()
{
$glpi_id = \User::getIDByName('glpi');
$this->createItem(UserEmail::class, [
'users_id' => $glpi_id,
'is_default' => 1,
'email' => 'glpi@teclib.com'
]);
$normal_id = \User::getIDByName('normal');
$this->updateItem(\User::class, $normal_id, [
'registration_number' => 'normal1234567890',
]);
$test_id = \User::getIDByName('_test_user');
$this->updateItem(\User::class, $test_id, [
'realname' => '_test_user',
'authtype' => \Auth::EXTERNAL,
'sync_field' => '_test_user@toto'
]);
yield [
'rules_fields' => [
'name' => 'Assign user by name field',
'action' => '_affect_user_by_name_and_regex',
'value' => '#0i',
'condition' => \Rule::PATTERN_NOT_CONTAIN,
'pattern' => 'admin'
],
"xml_fields" => [
'name' => 'adminglp',
'domain' => 'TECLIB'
],
'result' => [
'users_id' => 0,
]
];
$contain_test_user = $this->createItem(\User::class, [
'name' => 'contain_test'
]);
yield [
'rules_fields' => [
'name' => 'Assign user by name field',
'action' => '_affect_user_by_name_and_regex',
'value' => '#0',
'condition' => \Rule::PATTERN_CONTAIN,
'pattern' => 'contain'
],
"xml_fields" => [
'name' => 'logcontain_test',
'domain' => 'TECLIB'
],
'result' => [
'users_id' => $contain_test_user->fields['id'],
]
];
$begin_test_user = $this->createItem(\User::class, [
'name' => 'begin_test'
]);
yield [
'rules_fields' => [
'name' => 'Assign user by name field',
'action' => '_affect_user_by_name_and_regex',
'value' => '#0',
'condition' => \Rule::PATTERN_BEGIN,
'pattern' => 'logbegin'
],
"xml_fields" => [
'name' => 'logbegin_test',
'domain' => 'TECLIB'
],
'result' => [
'users_id' => $begin_test_user->fields['id'],
]
];
$end_test_user = $this->createItem(\User::class, [
'name' => 'end_test'
]);
yield [
'rules_fields' => [
'name' => 'Assign user by name field',
'action' => '_affect_user_by_name_and_regex',
'value' => '#0',
'condition' => \Rule::PATTERN_END,
'pattern' => 'END'
],
"xml_fields" => [
'name' => 'logend_test',
'domain' => 'END'
],
'result' => [
'users_id' => $end_test_user->fields['id'],
]
];
yield [
'rules_fields' => [
'name' => 'Assign user by name',
'action' => '_affect_user_by_name_and_regex',
'value' => '#0h',
],
"xml_fields" => [
'name' => 'logtec',
'domain' => 'TECLIB'
],
'result' => [
'users_id' => \User::getIDByName('tech'),
]
];
yield [
'rules_fields' => [
'name' => 'Assign user by registration number',
'action' => '_affect_user_by_registration_number_and_regex',
'value' => '#0l1234567890',
],
"xml_fields" => [
'name' => 'lognorma',
'domain' => 'TECLIB'
],
'result' => [
'users_id' => $normal_id,
]
];
yield [
'rules_fields' => [
'name' => 'Assign user by email',
'action' => '_affect_user_by_email_and_regex',
'value' => '#0i@teclib.com',
],
"xml_fields" => [
'name' => 'logglp',
'domain' => 'TECLIB'
],
'result' => [
'users_id' => $glpi_id,
]
];
yield [
'rules_fields' => [
'name' => 'Assign user by sync field',
'action' => '_affect_user_by_sync_field_and_regex',
'value' => '#0r@toto',
],
"xml_fields" => [
'name' => 'log_test_use',
'domain' => 'TECLIB'
],
'result' => [
'users_id' => $test_id,
]
];
}

/**
* @dataProvider getAssignUserByFieldAndRegexRules
*/
public function testAssignUserByFieldAndRegex($rules_fields, $xml_fields, $result)
{
global $DB;

//create rule
$input_rule = [
'is_active' => 1,
'name' => $rules_fields['name'],
'match' => 'AND',
'sub_type' => 'RuleAsset',
'condition' => \RuleAsset::ONADD + \RuleAsset::ONUPDATE
];

$rule = new \Rule();
$rules_id = $rule->add($input_rule);
$this->integer($rules_id)->isGreaterThan(0);

if (isset($rules_fields['condition']) && isset($rules_fields['pattern'])) {
$input_criteria2 = [
'rules_id' => $rules_id,
'criteria' => '_inventory_users',
'condition' => $rules_fields['condition'],
'pattern' => $rules_fields['pattern'],
];
$rule_criteria2 = new \RuleCriteria();
$rule_criteria2_id = $rule_criteria2->add($input_criteria2);
$this->integer($rule_criteria2_id)->isGreaterThan(0);
}
//create criteria
$input_criteria = [
'rules_id' => $rules_id,
'criteria' => '_inventory_users',
'condition' => \Rule::REGEX_MATCH,
'pattern' => '/^log([^@]+)/'
];
$rule_criteria = new \RuleCriteria();
$rule_criteria_id = $rule_criteria->add($input_criteria);
$this->integer($rule_criteria_id)->isGreaterThan(0);

//create action
$input_action = [
'rules_id' => $rules_id,
'action_type' => 'regex_result',
'field' => $rules_fields['action'],
'value' => $rules_fields['value']
];
$rule_action = new \RuleAction();
$rule_action_id = $rule_action->add($input_action);
$this->integer($rule_action_id)->isGreaterThan(0);

$xml_source = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>
<REQUEST>
<CONTENT>
<HARDWARE>
<NAME>glpixps</NAME>
<UUID>25C1BB60-5BCB-11D9-B18F-5404A6A534C4</UUID>
</HARDWARE>
<BIOS>
<MSN>640HP72</MSN>
</BIOS>
<USERS>
<DOMAIN>" . $xml_fields['domain'] . "</DOMAIN>
<LOGIN>" . $xml_fields['name'] . "</LOGIN>
</USERS>
<VERSIONCLIENT>GLPI-Agent_v1.6.18</VERSIONCLIENT>
</CONTENT>
<DEVICEID>test_assign_user_by_field_and_regex</DEVICEID>
<QUERY>INVENTORY</QUERY>
</REQUEST>";

\SingletonRuleList::getInstance("RuleAsset", 0)->load = 0;
\SingletonRuleList::getInstance("RuleAsset", 0)->list = [];
$this->doInventory($xml_source, true);

//check created agent
$agents = $DB->request(['FROM' => \Agent::getTable(), "WHERE" => ['deviceid' => 'test_assign_user_by_field_and_regex']]);
$this->integer(count($agents))->isIdenticalTo(1);
$agent = $agents->current();

//check created computer
$computer = new \Computer();
$this->boolean($computer->getFromDB($agent['items_id']))->isTrue();
$this->integer($computer->fields['users_id'])->isIdenticalTo($result['users_id']);
}
}