Plugin: Azure: Refactor to get paginated results when syncing user groups - refs BT#21930

pull/5763/head
Angel Fernando Quiroz Campos 1 year ago
parent ca32e13288
commit 091a9d29af
No known key found for this signature in database
GPG Key ID: B284841AE3E562CD
  1. 143
      plugin/azure_active_directory/src/AzureSyncUsergroupsCommand.php
  2. 91
      plugin/azure_active_directory/src/scripts/sync_usergroups.php

@ -0,0 +1,143 @@
<?php
/* For license terms, see /license.txt */
use League\OAuth2\Client\Token\AccessTokenInterface;
class AzureSyncUsergroupsCommand extends AzureCommand
{
/**
* @return Generator<int, string>
* @throws Exception
*/
public function __invoke(): Generator
{
yield 'Synchronizing groups from Azure.';
$token = $this->provider->getAccessToken(
'client_credentials',
['resource' => $this->provider->resource]
);
foreach ($this->getAzureGroups($token) as $azureGroupInfo) {
$usergroup = new UserGroup();
if ($usergroup->usergroup_exists($azureGroupInfo['displayName'])) {
$groupId = $usergroup->getIdByName($azureGroupInfo['displayName']);
if ($groupId) {
$usergroup->subscribe_users_to_usergroup($groupId, []);
yield sprintf('Class exists, all users unsubscribed: %s', $azureGroupInfo['displayName']);
}
} else {
$groupId = $usergroup->save([
'name' => $azureGroupInfo['displayName'],
'description' => $azureGroupInfo['description'],
]);
if ($groupId) {
yield sprintf('Class created: %s', $azureGroupInfo['displayName']);
}
}
$newGroupMembers = [];
foreach ($this->getAzureGroupMembers($token, $azureGroupInfo['id']) as $azureGroupMember) {
if ($userId = $this->plugin->getUserIdByVerificationOrder($azureGroupMember, 'id')) {
$newGroupMembers[] = $userId;
}
}
$usergroup->subscribe_users_to_usergroup($groupId, $newGroupMembers);
yield sprintf(
'User IDs subscribed in class %s: %s',
$azureGroupInfo['displayName'],
implode(', ', $newGroupMembers)
);
}
}
/**
* @return Generator<int, array<string, string>>
* @throws Exception
*/
private function getAzureGroups(AccessTokenInterface $token): Generator
{
$groupFields = [
'id',
'displayName',
'description',
];
$query = sprintf(
'$top=%d&$select=%s',
AzureActiveDirectory::API_PAGE_SIZE,
implode(',', $groupFields)
);
do {
try {
$azureGroupsRequest = $this->provider->request('get', "groups?$query", $token);
} catch (Exception $e) {
throw new Exception('Exception when requesting groups from Azure: '.$e->getMessage());
}
$azureGroupsInfo = $azureGroupsRequest['value'] ?? [];
foreach ($azureGroupsInfo as $azureGroupInfo) {
yield $azureGroupInfo;
}
$hasNextLink = false;
if (!empty($azureGroupsRequest['@odata.nextLink'])) {
$hasNextLink = true;
$query = parse_url($azureGroupsRequest['@odata.nextLink'], PHP_URL_QUERY);
}
} while($hasNextLink);
}
/**
* @return Generator<int, array<string, string>>
* @throws Exception
*/
private function getAzureGroupMembers(AccessTokenInterface $token, string $groupObjectId): Generator
{
$userFields = [
'mail',
'mailNickname',
'id'
];
$query = sprintf(
'$top=%d&$select=%s',
AzureActiveDirectory::API_PAGE_SIZE,
implode(',', $userFields)
);
$hasNextLink = false;
do {
try {
$azureGroupMembersRequest = $this->provider->request(
'get',
"groups/$groupObjectId/members?$query",
$token
);
} catch (Exception $e) {
throw new Exception('Exception when requesting group members from Azure: '.$e->getMessage());
}
$azureGroupMembers = $azureGroupMembersRequest['value'] ?? [];
foreach ($azureGroupMembers as $azureGroupMember) {
yield $azureGroupMember;
}
if (!empty($azureGroupMembersRequest['@odata.nextLink'])) {
$hasNextLink = true;
$query = parse_url($azureGroupMembersRequest['@odata.nextLink'], PHP_URL_QUERY);
}
} while ($hasNextLink);
}
}

@ -1,97 +1,18 @@
<?php <?php
/* For license terms, see /license.txt */ /* For license terms, see /license.txt */
require __DIR__ . '/../../../../main/inc/global.inc.php'; require __DIR__.'/../../../../main/inc/global.inc.php';
if (PHP_SAPI !== 'cli') { if (PHP_SAPI !== 'cli') {
exit('Run this script through the command line or comment this line in the code'); exit('Run this script through the command line or comment this line in the code');
} }
$plugin = AzureActiveDirectory::create(); $command = new AzureSyncUsergroupsCommand();
$provider = $plugin->getProviderForApiGraph();
echo 'Synchronizing groups from Azure.'.PHP_EOL;
try { try {
$token = $provider->getAccessToken( foreach ($command() as $str) {
'client_credentials', printf("%d - %s".PHP_EOL, time(), $str);
['resource' => $provider->resource]
);
$groupFields = [
'id',
'displayName',
'description',
];
$azureGroupsInfo = $provider->get(
'groups?$select='.implode(',', $groupFields),
$token
);
} catch (Exception $e) {
printf("%s - %s".PHP_EOL, time(), $e->getMessage());
die;
}
printf("%s - Number of groups obtained %d".PHP_EOL, time(), count($azureGroupsInfo));
/** @var array<string, string> $azureGroupInfo */
foreach ($azureGroupsInfo as $azureGroupInfo) {
$usergroup = new UserGroup();
$exists = $usergroup->usergroup_exists($azureGroupInfo['displayName']);
if (!$exists) {
$groupId = $usergroup->save([
'name' => $azureGroupInfo['displayName'],
'description' => $azureGroupInfo['description'],
]);
if ($groupId) {
printf('%d - Class created: %s'.PHP_EOL, time(), $azureGroupInfo['displayName']);
}
} else {
$groupId = $usergroup->getIdByName($azureGroupInfo['displayName']);
if ($groupId) {
$usergroup->subscribe_users_to_usergroup($groupId, []);
printf('%d - Class exists, all users unsubscribed: %s'.PHP_EOL, time(), $azureGroupInfo['displayName']);
}
}
try {
$userFields = [
'mail',
'mailNickname',
'id'
];
$azureGroupMembers = $provider->get(
sprintf('groups/%s/members?$select=%s', $azureGroupInfo['id'], implode(',', $userFields)),
$token
);
} catch (Exception $e) {
printf("%s - %s".PHP_EOL, time(), $e->getMessage());
continue;
} }
} catch (Exception $e) {
$newGroupMembers = []; printf('%s - Exception: %s'.PHP_EOL, time(), $e->getMessage());
foreach ($azureGroupMembers as $azureGroupMember) {
$userId = $plugin->getUserIdByVerificationOrder($azureGroupMember, 'id');
if ($userId) {
$newGroupMembers[] = $userId;
}
}
$usergroup->subscribe_users_to_usergroup($groupId, $newGroupMembers);
printf(
'%d - User IDs subscribed in class %s: %s'.PHP_EOL,
time(),
$azureGroupInfo['displayName'],
implode(', ', $newGroupMembers)
);
} }

Loading…
Cancel
Save