parent
							
								
									22afc8eab5
								
							
						
					
					
						commit
						ca32e13288
					
				@ -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…
					
					
				
		Reference in new issue