You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
685 lines
22 KiB
685 lines
22 KiB
<?php
|
|
/*
|
|
** Zabbix
|
|
** Copyright (C) 2001-2023 Zabbix SIA
|
|
**
|
|
** This program is free software; you can redistribute it and/or modify
|
|
** it under the terms of the GNU General Public License as published by
|
|
** the Free Software Foundation; either version 2 of the License, or
|
|
** (at your option) any later version.
|
|
**
|
|
** This program is distributed in the hope that it will be useful,
|
|
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
** GNU General Public License for more details.
|
|
**
|
|
** You should have received a copy of the GNU General Public License
|
|
** along with this program; if not, write to the Free Software
|
|
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
**/
|
|
|
|
|
|
namespace SCIM\services;
|
|
|
|
use API as APIRPC;
|
|
use APIException;
|
|
use CAuthenticationHelper;
|
|
use CApiInputValidator;
|
|
use CProvisioning;
|
|
use DB;
|
|
use SCIM\ScimApiService;
|
|
|
|
class Group extends ScimApiService {
|
|
|
|
public const SCIM_SCHEMA = 'urn:ietf:params:scim:schemas:core:2.0:Group';
|
|
|
|
/**
|
|
* Return all groups information.
|
|
* When filter 'id' or 'displayName' is defined will return information for single group.
|
|
* If group not found, for filter 'id', will return ZBX_API_ERROR_NO_ENTITY error.
|
|
*
|
|
* @param array $options
|
|
* @param string $options['id'] (optional) SCIM group id.
|
|
* @param string $options['displayName'] (optional) SCIM group display name.
|
|
*
|
|
* @return array Array of groups data when no filters are defined. Single group data for defined filter.
|
|
*/
|
|
public function get(array $options = []): array {
|
|
$this->validateGet($options);
|
|
|
|
if (array_key_exists('id', $options)) {
|
|
$db_scim_group = DB::select('scim_group', [
|
|
'output' => ['name'],
|
|
'scim_groupids' => $options['id']
|
|
]);
|
|
|
|
if (!$db_scim_group) {
|
|
self::exception(ZBX_API_ERROR_NO_ENTITY, 'No permissions to referred object or it does not exist!');
|
|
}
|
|
|
|
$users = $this->getUsersByGroupIds([$options['id']]);
|
|
|
|
return [
|
|
'id' => $options['id'],
|
|
'displayName' => $db_scim_group[0]['name'],
|
|
'users' => $users[$options['id']]
|
|
];
|
|
}
|
|
|
|
if (array_key_exists('displayName', $options)) {
|
|
$db_scim_group = DB::select('scim_group', [
|
|
'output' => ['name', 'scim_groupid'],
|
|
'filter' => ['name' => $options['displayName']]
|
|
]);
|
|
|
|
if (!$db_scim_group) {
|
|
return [];
|
|
}
|
|
|
|
$users = $this->getUsersByGroupIds([$db_scim_group[0]['scim_groupid']]);
|
|
|
|
return [
|
|
'id' => $db_scim_group[0]['scim_groupid'],
|
|
'displayName' => $db_scim_group[0]['name'],
|
|
'users' => $users
|
|
];
|
|
}
|
|
|
|
$db_scim_groups = DB::select('scim_group', [
|
|
'output' => ['name'],
|
|
'preservekeys' => true
|
|
]);
|
|
|
|
if ($db_scim_groups) {
|
|
$groups_users = $this->getUsersByGroupIds(array_keys($db_scim_groups));
|
|
|
|
foreach ($groups_users as $groupid => $users) {
|
|
$db_scim_groups[$groupid]['users'] = $users;
|
|
}
|
|
}
|
|
|
|
return $db_scim_groups;
|
|
}
|
|
|
|
/**
|
|
* @param array $options
|
|
*
|
|
* @throws APIException if input is invalid.
|
|
*/
|
|
private function validateGet(array &$options): void {
|
|
$api_input_rules = ['type' => API_OBJECT, 'fields' => [
|
|
'displayName' => ['type' => API_STRING_UTF8],
|
|
'id' => ['type' => API_ID],
|
|
'startIndex' => ['type' => API_INT32, 'default' => 1],
|
|
'count' => ['type' => API_INT32, 'default' => 100]
|
|
]];
|
|
|
|
if (!CApiInputValidator::validate($api_input_rules, $options, '/', $error)) {
|
|
self::exception(ZBX_API_ERROR_PARAMETERS, $error);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Create group, assign users to new group when 'members' is passed in request.
|
|
*
|
|
* @param array $options
|
|
* @param string $options['displayName'] SCIM group name.
|
|
* @param array $options['members'] Array with SCIM group members.
|
|
* @param string $options['members'][]['value'] Userid.
|
|
*
|
|
* @return array Array with data for created group.
|
|
*/
|
|
public function post(array $options): array {
|
|
$this->validatePost($options);
|
|
|
|
$db_scim_groups = DB::select('scim_group', [
|
|
'output' => ['scim_groupid'],
|
|
'filter' => ['name' => $options['displayName']]
|
|
]);
|
|
|
|
if ($db_scim_groups) {
|
|
$options['id'] = $db_scim_groups[0]['scim_groupid'];
|
|
|
|
return $this->put($options);
|
|
}
|
|
|
|
[$scim_groupid] = DB::insert('scim_group', [['name' => $options['displayName']]]);
|
|
|
|
if (!$scim_groupid) {
|
|
self::exception(ZBX_API_ERROR_INTERNAL, 'Cannot create group '.$options['displayName'].'.');
|
|
}
|
|
|
|
$group = [
|
|
'id' => $scim_groupid,
|
|
'displayName' => $options['displayName'],
|
|
'users' => []
|
|
];
|
|
|
|
if (array_key_exists('members', $options) && $options['members'] != []) {
|
|
$userdirectoryid = CAuthenticationHelper::getSamlUserdirectoryidForScim();
|
|
$scim_group_members = array_column($options['members'], 'value');
|
|
$group['users'] = $this->verifyUserids($scim_group_members, $userdirectoryid);
|
|
|
|
foreach ($scim_group_members as $memberid) {
|
|
$user_group = DB::insert('user_scim_group', [[
|
|
'userid' => $memberid,
|
|
'scim_groupid' => $scim_groupid
|
|
]]);
|
|
|
|
if (!$user_group) {
|
|
self::exception(ZBX_API_ERROR_INTERNAL,
|
|
'Cannot add user '.$memberid.' to group '.$options['displayName'].'.'
|
|
);
|
|
}
|
|
|
|
$this->updateProvisionedUserGroups($memberid, $userdirectoryid);
|
|
}
|
|
}
|
|
|
|
return $group;
|
|
}
|
|
|
|
/**
|
|
* @param array $options
|
|
*
|
|
* @throws APIException if input is invalid.
|
|
*/
|
|
private function validatePost(array $options): void {
|
|
$api_input_rules = ['type' => API_OBJECT, 'flags' => API_REQUIRED | API_ALLOW_UNEXPECTED, 'fields' => [
|
|
'schemas' => ['type' => API_STRINGS_UTF8, 'flags' => API_REQUIRED | API_NOT_EMPTY],
|
|
'displayName' => ['type' => API_STRING_UTF8, 'flags' => API_REQUIRED | API_NOT_EMPTY],
|
|
'members' => ['type' => API_OBJECTS, 'fields' => [
|
|
'display' => ['type' => API_STRING_UTF8, 'flags' => API_REQUIRED | API_NOT_EMPTY],
|
|
'value' => ['type' => API_ID, 'flags' => API_REQUIRED]
|
|
]]
|
|
]];
|
|
|
|
if (!CApiInputValidator::validate($api_input_rules, $options, '/', $error)) {
|
|
self::exception(ZBX_API_ERROR_PARAMETERS, $error);
|
|
}
|
|
|
|
if (!in_array(self::SCIM_SCHEMA, $options['schemas'], true)) {
|
|
self::exception(ZBX_API_ERROR_PARAMETERS, 'Incorrect schema was sent in the request.');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Receives new information on the SCIM group and its members. Updates 'user_scim_group' table, updates users'
|
|
* user groups mapping based on the remaining SCIM groups and SAML settings.
|
|
*
|
|
* @param array $options
|
|
* @param string $options['id'] SCIM group id.
|
|
* @param array $options['members'] Array with SCIM group members.
|
|
* @param string $options['members'][]['value'] Userid.
|
|
*
|
|
* @return array Array with data for updated group.
|
|
*/
|
|
public function put(array $options): array {
|
|
$this->validatePut($options);
|
|
|
|
$db_scim_groups = DB::select('scim_group', [
|
|
'output' => ['name'],
|
|
'scim_groupids' => $options['id']
|
|
]);
|
|
|
|
if (!$db_scim_groups) {
|
|
self::exception(ZBX_API_ERROR_NO_ENTITY, 'No permissions to referred object or it does not exist!');
|
|
}
|
|
$db_scim_group = $db_scim_groups[0];
|
|
|
|
if ($options['displayName'] !== $db_scim_group['name']) {
|
|
$scim_groupid = DB::update('scim_group', [
|
|
'values' => ['name' => $options['displayName']],
|
|
'where' => ['scim_groupid' => $options['id']]
|
|
]);
|
|
|
|
if (!$scim_groupid) {
|
|
self::exception(ZBX_API_ERROR_INTERNAL,
|
|
'Cannot update group '.$db_scim_group['name'].' to group '.$options['displayName'].'.'
|
|
);
|
|
}
|
|
|
|
$db_scim_group['name'] = $options['displayName'];
|
|
}
|
|
|
|
$userdirectoryid = CAuthenticationHelper::getSamlUserdirectoryidForScim();
|
|
$scim_group_members = array_column($options['members'], 'value');
|
|
$this->verifyUserids($scim_group_members, $userdirectoryid);
|
|
|
|
$db_scim_group_members = DB::select('user_scim_group', [
|
|
'output' => ['userid'],
|
|
'filter' => ['scim_groupid' => $options['id']]
|
|
]);
|
|
|
|
$users_to_add = array_diff($scim_group_members, array_column($db_scim_group_members, 'userid'));
|
|
$users_to_remove = array_diff(array_column($db_scim_group_members, 'userid'), $scim_group_members);
|
|
|
|
if($users_to_add) {
|
|
foreach ($users_to_add as $userid) {
|
|
$scim_user_group = DB::insert('user_scim_group', [[
|
|
'userid' => $userid,
|
|
'scim_groupid' => $options['id']
|
|
]]);
|
|
|
|
if (!$scim_user_group) {
|
|
self::exception(ZBX_API_ERROR_INTERNAL,
|
|
'Cannot add user '.$userid.' to group '.$options['displayName'].'.'
|
|
);
|
|
}
|
|
|
|
$this->updateProvisionedUserGroups($userid, $userdirectoryid);
|
|
}
|
|
}
|
|
|
|
if ($users_to_remove) {
|
|
DB::delete('user_scim_group', [
|
|
'userid' => array_values($users_to_remove),
|
|
'scim_groupid' => $options['id']
|
|
]);
|
|
|
|
foreach ($users_to_remove as $userid) {
|
|
$this->updateProvisionedUserGroups($userid, $userdirectoryid);
|
|
}
|
|
}
|
|
|
|
$db_users = APIRPC::User()->get([
|
|
'output' => ['userid', 'username'],
|
|
'userids' => $scim_group_members,
|
|
'filter' => ['userdirectoryid' => $userdirectoryid]
|
|
]);
|
|
|
|
return [
|
|
'id' => $options['id'],
|
|
'displayName' => $db_scim_group['name'],
|
|
'users' => $db_users
|
|
];
|
|
}
|
|
|
|
/**
|
|
* @param array $options
|
|
*
|
|
* @throws APIException if input is invalid.
|
|
*/
|
|
private function validatePut($options) {
|
|
$api_input_rules = ['type' => API_OBJECT, 'flags' => API_REQUIRED | API_ALLOW_UNEXPECTED, 'fields' => [
|
|
'schemas' => ['type' => API_STRINGS_UTF8, 'flags' => API_REQUIRED | API_NOT_EMPTY],
|
|
'id' => ['type' => API_ID, 'flags' => API_REQUIRED],
|
|
'displayName' => ['type' => API_STRING_UTF8, 'flags' => API_REQUIRED | API_NOT_EMPTY],
|
|
'members' => ['type' => API_OBJECTS, 'flags' => API_REQUIRED, 'fields' => [
|
|
'display' => ['type' => API_STRING_UTF8, 'flags' => API_REQUIRED | API_NOT_EMPTY],
|
|
'value' => ['type' => API_ID, 'flags' => API_REQUIRED]
|
|
]]
|
|
]];
|
|
|
|
if (!CApiInputValidator::validate($api_input_rules, $options, '/', $error)) {
|
|
self::exception(ZBX_API_ERROR_PARAMETERS, $error);
|
|
}
|
|
|
|
if (!in_array(self::SCIM_SCHEMA, $options['schemas'], true)) {
|
|
self::exception(ZBX_API_ERROR_PARAMETERS, 'Incorrect schema was sent in the request.');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Receives new information on the SCIM group members. Updates 'user_scim_group' table, updates users'
|
|
* user groups mapping based on the remaining SCIM groups and SAML settings.
|
|
*
|
|
* @param array $options
|
|
* @param string $options['id'] SCIM group id.
|
|
* @param array $options['Operations'] List of operations that need to be performed.
|
|
* @param string $options['Operations'][]['op'] Operation that needs to be performed -'add',
|
|
* 'replace', 'remove'.
|
|
* @param string $options['Operations'][]['path'] On what operation should be performed, filters are
|
|
* not supported, only 'members' path is supported.
|
|
* @param array $options['Operations'][]['value'] Array of values on which operation should be
|
|
* performed. If operation is 'remove' this can be
|
|
* omitted, in this case all members should be removed.
|
|
* @param string $options['Operations'][]['value'][]['value'] User id on which operation should be performed.
|
|
*
|
|
* @return array Array with data for updated group.
|
|
*
|
|
* @throws APIException
|
|
*/
|
|
public function patch(array $options): array {
|
|
$this->validatePatch($options);
|
|
|
|
$db_scim_groups = DB::select('scim_group', [
|
|
'output' => ['name'],
|
|
'scim_groupids' => $options['id']
|
|
]);
|
|
|
|
if (!$db_scim_groups) {
|
|
self::exception(ZBX_API_ERROR_NO_ENTITY, 'No permissions to referred object or it does not exist!');
|
|
}
|
|
|
|
$db_users = [];
|
|
$db_users_delete = [];
|
|
$new_userids = [];
|
|
$del_userids = [];
|
|
$do_replace = false;
|
|
$userdirectoryid = CAuthenticationHelper::getSamlUserdirectoryidForScim();
|
|
|
|
foreach ($options['Operations'] as $operation) {
|
|
if ($operation['path'] === 'displayName') {
|
|
$scim_groupid = DB::update('scim_group', [
|
|
'values' => ['name' => $operation['value']],
|
|
'where' => ['scim_groupid' => $options['id']]
|
|
]);
|
|
|
|
if (!$scim_groupid) {
|
|
self::exception(ZBX_API_ERROR_INTERNAL,
|
|
'Cannot update group '.$db_scim_groups[0]['name'].' to group '.$operation['value'].'.'
|
|
);
|
|
}
|
|
|
|
$db_scim_groups[0]['name'] = $operation['value'];
|
|
}
|
|
else if ($operation['path'] === 'members') {
|
|
switch ($operation['op']) {
|
|
case 'add':
|
|
$new_userids = array_merge($new_userids, array_column($operation['value'], 'value'));
|
|
|
|
break;
|
|
|
|
case 'remove':
|
|
if (!$do_replace) {
|
|
if (array_key_exists('value', $operation)) {
|
|
$del_userids = array_merge($del_userids, array_column($operation['value'], 'value'));
|
|
}
|
|
|
|
if (!$del_userids) {
|
|
// Empty 'value' array for 'remove' operation should act as 'replace' operation.
|
|
$do_replace = true;
|
|
}
|
|
}
|
|
|
|
break;
|
|
|
|
case 'replace':
|
|
$new_userids = array_merge($new_userids, array_column($operation['value'], 'value'));
|
|
$do_replace = true;
|
|
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if ($new_userids || $del_userids) {
|
|
$new_userids = array_diff($new_userids, $del_userids);
|
|
|
|
if (!$do_replace && $new_userids) {
|
|
$db_userids = DB::select('user_scim_group', [
|
|
'output' => ['userid'],
|
|
'filter' => ['scim_groupid' => $options['id']]
|
|
]);
|
|
$new_userids = array_diff($new_userids, array_column($db_userids, 'userid'));
|
|
}
|
|
|
|
$db_users = $this->verifyUserids($new_userids, $userdirectoryid);
|
|
$db_users_delete = $this->verifyUserids($del_userids, $userdirectoryid);
|
|
}
|
|
|
|
if ($do_replace) {
|
|
DB::delete('user_scim_group', ['scim_groupid' => $options['id']]);
|
|
}
|
|
else if ($del_userids) {
|
|
DB::delete('user_scim_group', ['userid' => $del_userids, 'scim_groupid' => $options['id']]);
|
|
}
|
|
|
|
if ($new_userids) {
|
|
$values = [];
|
|
|
|
foreach ($new_userids as $userid) {
|
|
$values[] = [
|
|
'userid' => $userid,
|
|
'scim_groupid' => $options['id']
|
|
];
|
|
}
|
|
|
|
DB::insertBatch('user_scim_group', $values);
|
|
}
|
|
|
|
foreach (array_column(array_merge($db_users, $db_users_delete), 'userid') as $db_userid) {
|
|
$this->updateProvisionedUserGroups($db_userid, $userdirectoryid);
|
|
}
|
|
|
|
return [
|
|
'id' => $options['id'],
|
|
'displayName' => $db_scim_groups[0]['name'],
|
|
'users' => $db_users
|
|
];
|
|
}
|
|
|
|
/**
|
|
* @param array $options
|
|
*
|
|
* @throws APIException if input is invalid.
|
|
*/
|
|
private function validatePatch(array &$options): void {
|
|
$api_input_rules = ['type' => API_OBJECT, 'flags' => API_REQUIRED | API_ALLOW_UNEXPECTED, 'fields' => [
|
|
'id' => ['type' => API_ID, 'flags' => API_REQUIRED],
|
|
'schemas' => ['type' => API_STRINGS_UTF8, 'flags' => API_REQUIRED | API_NOT_EMPTY],
|
|
'Operations' => ['type' => API_OBJECTS, 'flags' => API_REQUIRED | API_NOT_EMPTY | API_ALLOW_UNEXPECTED, 'fields' => [
|
|
'path' => ['type' => API_STRING_UTF8, 'flags' => API_REQUIRED, 'in' => implode(',', ['members', 'externalId', 'displayName'])],
|
|
'op' => ['type' => API_MULTIPLE, 'rules' => [
|
|
['if' => ['field' => 'path', 'in' => 'displayName'], 'type' => API_STRING_UTF8, 'flags' => API_REQUIRED, 'in' => implode(',', ['replace', 'Replace'])],
|
|
['else' => true, 'type' => API_STRING_UTF8, 'flags' => API_REQUIRED, 'in' => implode(',', ['add', 'remove', 'replace', 'Add', 'Remove', 'Replace'])]
|
|
]],
|
|
'value' => ['type' => API_MULTIPLE, 'rules' => [
|
|
['if' => ['field' => 'path', 'in' => 'members'], 'type' => API_OBJECTS, 'flags' => API_NOT_EMPTY, 'fields' => [
|
|
'value' => ['type' => API_ID]
|
|
]],
|
|
['else' => true, 'type' => API_STRING_UTF8, 'flags' => API_NOT_EMPTY]
|
|
]]
|
|
]]
|
|
]];
|
|
|
|
if (!CApiInputValidator::validate($api_input_rules, $options, '/', $error)) {
|
|
self::exception(ZBX_API_ERROR_PARAMETERS, $error);
|
|
}
|
|
|
|
if (!in_array(ScimApiService::SCIM_PATCH_SCHEMA, $options['schemas'], true)) {
|
|
self::exception(ZBX_API_ERROR_PARAMETERS, 'Incorrect schema was sent in the request.');
|
|
}
|
|
|
|
foreach ($options['Operations'] as &$operation) {
|
|
$operation['op'] = strtolower($operation['op']);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Deletes SCIM group from 'scim_group' table. Deletes the users that belong to this group from 'user_scim_group'
|
|
* table. Updates users' user groups mapping based on the remaining SCIM groups and SAML settings.
|
|
*
|
|
* @param array $options
|
|
* @param string $options['id] SCIM group to be deleted.
|
|
*
|
|
* @return array Deleted group id.
|
|
*/
|
|
public function delete(array $options): array {
|
|
$this->validateDelete($options);
|
|
|
|
$db_scim_group_members = DB::select('user_scim_group', [
|
|
'output' => ['userid'],
|
|
'filter' => ['scim_groupid' => $options['id']]
|
|
]);
|
|
|
|
DB::delete('scim_group', ['scim_groupid' => $options['id']]);
|
|
|
|
foreach (array_column($db_scim_group_members, 'userid') as $userid) {
|
|
$this->updateProvisionedUserGroups($userid, CAuthenticationHelper::getSamlUserdirectoryidForScim());
|
|
}
|
|
|
|
return [$options['id']];
|
|
}
|
|
|
|
/**
|
|
* @param array $options
|
|
*
|
|
* @throws APIException if the input is invalid.
|
|
*/
|
|
private function validateDelete(array $options): void {
|
|
$api_input_rules = ['type' => API_OBJECT, 'flags' => API_REQUIRED, 'fields' => [
|
|
'id' => ['type' => API_ID, 'flags' => API_REQUIRED]
|
|
]];
|
|
|
|
if (!CApiInputValidator::validate($api_input_rules, $options, '/', $error)) {
|
|
self::exception(ZBX_API_ERROR_PARAMETERS, $error);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Based on SCIM group id, returns all the users that are included in this group.
|
|
*
|
|
* @param array $groupids SCIM groups' IDs.
|
|
*
|
|
* @return array Returns array where each group has its own array of users. Groupid is key, userid is key.
|
|
* [<groupid>][<userid>]['userid']
|
|
* [<groupid>][<userid>]['username']
|
|
*/
|
|
private function getUsersByGroupIds(array $groupids): array {
|
|
$db_scim_groups_members = DB::select('user_scim_group', [
|
|
'output' => ['userid', 'scim_groupid'],
|
|
'filter' => ['scim_groupid' => $groupids]
|
|
]);
|
|
|
|
if (!$db_scim_groups_members) {
|
|
return array_fill_keys($groupids, []);
|
|
}
|
|
|
|
$users = APIRPC::User()->get([
|
|
'output' => ['userid', 'username'],
|
|
'userids' => array_column($db_scim_groups_members, 'userid'),
|
|
'preservekeys' => true
|
|
]);
|
|
|
|
$users_groups = array_fill_keys($groupids, []);
|
|
foreach ($groupids as $groupid) {
|
|
foreach ($db_scim_groups_members as $scim_group_member) {
|
|
if ($scim_group_member['scim_groupid'] == $groupid) {
|
|
$users_groups[$groupid][$scim_group_member['userid']] = $users[$scim_group_member['userid']];
|
|
}
|
|
}
|
|
}
|
|
|
|
return $users_groups;
|
|
}
|
|
|
|
/**
|
|
* Checks what kind of SCIM groups user belongs to, checks the mapping of the groups in SAML settings and updates
|
|
* user's user group and role based on this mapping.
|
|
*
|
|
* @param string $userid
|
|
* @param array $userdirectoryid
|
|
*
|
|
* @return void
|
|
*/
|
|
private function updateProvisionedUserGroups(string $userid, string $userdirectoryid): void {
|
|
$provisioning = CProvisioning::forUserDirectoryId($userdirectoryid);
|
|
|
|
$user_scim_groupids = DB::select('user_scim_group', [
|
|
'output' => ['scim_groupid'],
|
|
'filter' => ['userid' => $userid]
|
|
]);
|
|
|
|
$user_scim_group_names = DB::select('scim_group', [
|
|
'output' => ['name'],
|
|
'scim_groupids' => array_column($user_scim_groupids, 'scim_groupid')
|
|
]);
|
|
|
|
$group_rights = $provisioning->getUserGroupsAndRole(array_column($user_scim_group_names, 'name'));
|
|
|
|
APIRPC::User()->updateProvisionedUser([
|
|
'userid' => $userid,
|
|
'roleid' => $group_rights['roleid'],
|
|
'usrgrps' => $group_rights['usrgrps']
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* Verifies if provided users exist in the database.
|
|
*
|
|
* @param array $userids User ids.
|
|
* @param string $userdirectoryid User directory id to which users belong to.
|
|
*
|
|
* @return array Returns array with users' id and username.
|
|
*
|
|
* @throws APIException
|
|
*/
|
|
private function verifyUserids(array $userids, string $userdirectoryid): array {
|
|
$users = APIRPC::User()->get([
|
|
'output' => ['userid', 'username'],
|
|
'userids' => $userids,
|
|
'filter' => ['userdirectoryid' => $userdirectoryid]
|
|
]);
|
|
|
|
if (count($users) !== count($userids)) {
|
|
self::exception(ZBX_API_ERROR_NO_ENTITY, 'No permissions to referred object or it does not exist!');
|
|
}
|
|
|
|
return $users;
|
|
}
|
|
|
|
/**
|
|
* Add user to specified list of SAML/SCIM groups. Creates new entries in 'scim_group' if group do not exists.
|
|
* Remove user to scim group relation from 'user_scim_group' when no groups supplied but
|
|
* do not removes scim_groups entry if user were last related to group user.
|
|
*
|
|
* @param array $saml_group_names Array of strings with SAML/SCIM groups names.
|
|
* @param int $userid User id.
|
|
*/
|
|
public static function createScimGroupsFromSamlAttributes(array $saml_group_names, string $userid): void {
|
|
if (!$saml_group_names) {
|
|
DB::delete('user_scim_group', ['userid' => $userid]);
|
|
|
|
return;
|
|
}
|
|
|
|
$db_scim_groups = DB::select('scim_group', [
|
|
'output' => ['scim_groupid', 'name'],
|
|
'filter' => ['name' => $saml_group_names],
|
|
'preservekeys' => true
|
|
]);
|
|
|
|
$groups_to_add = array_diff($saml_group_names, array_column($db_scim_groups, 'name'));
|
|
$scim_groupids = array_column($db_scim_groups, 'scim_groupid');
|
|
|
|
if ($groups_to_add) {
|
|
$insert = [];
|
|
|
|
foreach ($groups_to_add as $group_to_add) {
|
|
$insert[] = ['name' => $group_to_add];
|
|
}
|
|
|
|
$db_newids = DB::insert('scim_group', $insert, true);
|
|
$scim_groupids = array_merge($scim_groupids, $db_newids);
|
|
}
|
|
|
|
$db_users_scim_groupids = DB::select('user_scim_group', [
|
|
'output' => ['scim_groupid'],
|
|
'filter' => ['userid' => $userid]
|
|
]);
|
|
$db_users_scim_groupids = array_column($db_users_scim_groupids, 'scim_groupid');
|
|
$user_scim_groupids_delete = array_diff($db_users_scim_groupids, $scim_groupids);
|
|
$user_scim_groupids_add = [];
|
|
|
|
foreach(array_diff($scim_groupids, $db_users_scim_groupids) as $scim_groupid) {
|
|
$user_scim_groupids_add[] = [
|
|
'userid' => $userid,
|
|
'scim_groupid' => $scim_groupid
|
|
];
|
|
}
|
|
|
|
if ($user_scim_groupids_add) {
|
|
DB::insert('user_scim_group', $user_scim_groupids_add);
|
|
}
|
|
|
|
if ($user_scim_groupids_delete) {
|
|
DB::delete('user_scim_group', [
|
|
'userid' => $userid,
|
|
'scim_groupid' => $user_scim_groupids_delete
|
|
]);
|
|
}
|
|
}
|
|
}
|