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

pull/5763/head
Angel Fernando Quiroz Campos 1 year ago
parent 22afc8eab5
commit ca32e13288
No known key found for this signature in database
GPG Key ID: B284841AE3E562CD
  1. 2
      plugin/azure_active_directory/src/AzureActiveDirectory.php
  2. 23
      plugin/azure_active_directory/src/AzureCommand.php
  3. 116
      plugin/azure_active_directory/src/AzureSyncUsersCommand.php
  4. 85
      plugin/azure_active_directory/src/scripts/sync_users.php

@ -36,6 +36,8 @@ class AzureActiveDirectory extends Plugin
public const EXTRA_FIELD_AZURE_ID = 'azure_id';
public const EXTRA_FIELD_AZURE_UID = 'azure_uid';
public const API_PAGE_SIZE = 100;
/**
* AzureActiveDirectory constructor.
*/

@ -0,0 +1,23 @@
<?php
/* For license terms, see /license.txt */
use TheNetworg\OAuth2\Client\Provider\Azure;
class AzureCommand
{
/**
* @var AzureActiveDirectory
*/
protected $plugin;
/**
* @var Azure
*/
protected $provider;
public function __construct()
{
$this->plugin = AzureActiveDirectory::create();
$this->provider = $this->plugin->getProviderForApiGraph();
}
}

@ -0,0 +1,116 @@
<?php
/* For license terms, see /license.txt */
use League\OAuth2\Client\Token\AccessTokenInterface;
class AzureSyncUsersCommand extends AzureCommand
{
/**
* @return Generator<int, string>
* @throws Exception
*/
public function __invoke(): Generator
{
yield 'Synchronizing users from Azure.';
$token = $this->provider->getAccessToken(
'client_credentials',
['resource' => $this->provider->resource]
);
$existingUsers = [];
foreach ($this->getAzureUsers($token) as $azureUserInfo) {
try {
$userId = $this->plugin->registerUser(
$token,
$this->provider,
$azureUserInfo,
'users/' . $azureUserInfo['id'] . '/memberOf',
'id',
'id'
);
} catch (Exception $e) {
yield $e->getMessage();
continue;
}
$existingUsers[] = $userId;
$userInfo = api_get_user_info($userId);
yield sprintf('User info: %s', serialize($userInfo));
}
if ('true' === $this->plugin->get(AzureActiveDirectory::SETTING_DEACTIVATE_NONEXISTING_USERS)) {
yield '----------------';
yield 'Trying deactivate non-existing users in Azure';
$users = UserManager::getRepository()->findByAuthSource('azure');
$userIdList = array_map(
function ($user) {
return $user->getId();
},
$users
);
$nonExistingUsers = array_diff($userIdList, $existingUsers);
UserManager::deactivate_users($nonExistingUsers);
yield sprintf(
'Deactivated users IDs: %s',
implode(', ', $nonExistingUsers)
);
}
}
/**
* @return Generator<int, array<string, string>>
* @throws Exception
*/
private function getAzureUsers(AccessTokenInterface $token): Generator
{
$userFields = [
'givenName',
'surname',
'mail',
'userPrincipalName',
'businessPhones',
'mobilePhone',
'accountEnabled',
'mailNickname',
'id'
];
$query = sprintf(
'$top=%d&$select=%s',
AzureActiveDirectory::API_PAGE_SIZE,
implode(',', $userFields)
);
do {
try {
$azureUsersRequest = $this->provider->request('get', "users?$query", $token);
} catch (Exception $e) {
throw new Exception('Exception when requesting users from Azure: '.$e->getMessage());
}
$azureUsersInfo = $azureUsersRequest['value'] ?? [];
foreach ($azureUsersInfo as $azureUserInfo) {
yield $azureUserInfo;
}
$hasNextLink = false;
if (!empty($azureUsersRequest['@odata.nextLink'])) {
$hasNextLink = true;
$query = parse_url($azureUsersRequest['@odata.nextLink'], PHP_URL_QUERY);
}
} while ($hasNextLink);
}
}

@ -1,91 +1,18 @@
<?php
/* For license terms, see /license.txt */
require __DIR__ . '/../../../../main/inc/global.inc.php';
require __DIR__.'/../../../../main/inc/global.inc.php';
if (PHP_SAPI !== 'cli') {
exit('Run this script through the command line or comment this line in the code');
}
$plugin = AzureActiveDirectory::create();
$provider = $plugin->getProviderForApiGraph();
echo 'Synchronizing users from Azure.'.PHP_EOL;
$command = new AzureSyncUsersCommand();
try {
$token = $provider->getAccessToken(
'client_credentials',
['resource' => $provider->resource]
);
$userFields = [
'givenName',
'surname',
'mail',
'userPrincipalName',
'businessPhones',
'mobilePhone',
'accountEnabled',
'mailNickname',
'id'
];
$azureUsersInfo = $provider->get(
'users?$select='.implode(',', $userFields),
$token
);
} catch (Exception $e) {
printf("%s - %s".PHP_EOL, time(), $e->getMessage());
die;
}
printf("%s - Number of users obtained %d".PHP_EOL, time(), count($azureUsersInfo));
$existingUsers = [];
/** @var array $user */
foreach ($azureUsersInfo as $azureUserInfo) {
try {
$userId = $plugin->registerUser(
$token,
$provider,
$azureUserInfo,
'users/' . $azureUserInfo['id'] . '/memberOf',
'id',
'id'
);
$existingUsers[] = $userId;
$userInfo = api_get_user_info($userId);
printf("%s - UserInfo %s".PHP_EOL, time(), serialize($userInfo));
} catch (Exception $e) {
printf("%s - %s".PHP_EOL, time(), $e->getMessage());
continue;
foreach ($command() as $str) {
printf("%d - %s".PHP_EOL, time(), $str);
}
}
if ('true' === $plugin->get(AzureActiveDirectory::SETTING_DEACTIVATE_NONEXISTING_USERS)) {
echo '----------------'.PHP_EOL;
printf('Trying deactivate non-existing users in Azure.'.PHP_EOL, time());
$users = UserManager::getRepository()->findByAuthSource('azure');
$userIdList = array_map(
function ($user) {
return $user->getId();
},
$users
);
$nonExistingUsers = array_diff($userIdList, $existingUsers);
UserManager::deactivate_users($nonExistingUsers);
printf(
"%d - Deactivated users IDs: %s".PHP_EOL,
time(),
implode(', ', $nonExistingUsers)
);
} catch (Exception $e) {
printf('%s - Exception: %s'.PHP_EOL, time(), $e->getMessage());
}

Loading…
Cancel
Save