Passed
Pull Request — 1.11.x (#5763)
by Angel Fernando Quiroz
13:34
created

AzureSyncUsergroupsCommand   A

Complexity

Total Complexity 17

Size/Duplication

Total Lines 135
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 17
eloc 72
c 1
b 0
f 0
dl 0
loc 135
rs 10

3 Methods

Rating   Name   Duplication   Size   Complexity  
A getAzureGroups() 0 34 5
B __invoke() 0 45 7
A getAzureGroupMembers() 0 36 5
1
<?php
2
3
/* For license terms, see /license.txt */
4
5
use League\OAuth2\Client\Token\AccessTokenInterface;
6
7
class AzureSyncUsergroupsCommand extends AzureCommand
8
{
9
    /**
10
     * @return Generator<int, string>
11
     * @throws Exception
12
     */
13
    public function __invoke(): Generator
14
    {
15
        yield 'Synchronizing groups from Azure.';
16
17
        $token = $this->provider->getAccessToken(
18
            'client_credentials',
19
            ['resource' => $this->provider->resource]
20
        );
21
22
        foreach ($this->getAzureGroups($token) as $azureGroupInfo) {
23
            $usergroup = new UserGroup();
24
25
            if ($usergroup->usergroup_exists($azureGroupInfo['displayName'])) {
26
                $groupId = $usergroup->getIdByName($azureGroupInfo['displayName']);
27
28
                if ($groupId) {
29
                    $usergroup->subscribe_users_to_usergroup($groupId, []);
30
31
                    yield sprintf('Class exists, all users unsubscribed: %s', $azureGroupInfo['displayName']);
32
                }
33
            } else {
34
                $groupId = $usergroup->save([
35
                    'name' => $azureGroupInfo['displayName'],
36
                    'description' => $azureGroupInfo['description'],
37
                ]);
38
39
                if ($groupId) {
40
                    yield sprintf('Class created: %s', $azureGroupInfo['displayName']);
41
                }
42
            }
43
44
            $newGroupMembers = [];
45
46
            foreach ($this->getAzureGroupMembers($token, $azureGroupInfo['id']) as $azureGroupMember) {
47
                if ($userId = $this->plugin->getUserIdByVerificationOrder($azureGroupMember, 'id')) {
48
                    $newGroupMembers[] = $userId;
49
                }
50
            }
51
52
            $usergroup->subscribe_users_to_usergroup($groupId, $newGroupMembers);
53
54
            yield sprintf(
55
                'User IDs subscribed in class %s: %s',
56
                $azureGroupInfo['displayName'],
57
                implode(', ', $newGroupMembers)
58
            );
59
        }
60
    }
61
62
    /**
63
     * @return Generator<int, array<string, string>>
64
     * @throws Exception
65
     */
66
    private function getAzureGroups(AccessTokenInterface $token): Generator
67
    {
68
        $groupFields = [
69
            'id',
70
            'displayName',
71
            'description',
72
        ];
73
74
        $query = sprintf(
75
            '$top=%d&$select=%s',
76
            AzureActiveDirectory::API_PAGE_SIZE,
77
            implode(',', $groupFields)
78
        );
79
80
        do {
81
            try {
82
                $azureGroupsRequest = $this->provider->request('get', "groups?$query", $token);
83
            } catch (Exception $e) {
84
                throw new Exception('Exception when requesting groups from Azure: '.$e->getMessage());
85
            }
86
87
            $azureGroupsInfo = $azureGroupsRequest['value'] ?? [];
88
89
            foreach ($azureGroupsInfo as $azureGroupInfo) {
90
                yield $azureGroupInfo;
91
            }
92
93
            $hasNextLink = false;
94
95
            if (!empty($azureGroupsRequest['@odata.nextLink'])) {
96
                $hasNextLink = true;
97
                $query = parse_url($azureGroupsRequest['@odata.nextLink'], PHP_URL_QUERY);
98
            }
99
        } while($hasNextLink);
100
    }
101
102
    /**
103
     * @return Generator<int, array<string, string>>
104
     * @throws Exception
105
     */
106
    private function getAzureGroupMembers(AccessTokenInterface $token, string $groupObjectId): Generator
107
    {
108
        $userFields = [
109
            'mail',
110
            'mailNickname',
111
            'id'
112
        ];
113
        $query = sprintf(
114
            '$top=%d&$select=%s',
115
            AzureActiveDirectory::API_PAGE_SIZE,
116
            implode(',', $userFields)
117
        );
118
        $hasNextLink = false;
119
120
        do {
121
            try {
122
                $azureGroupMembersRequest = $this->provider->request(
123
                    'get',
124
                    "groups/$groupObjectId/members?$query",
125
                    $token
126
                );
127
            } catch (Exception $e) {
128
                throw new Exception('Exception when requesting group members from Azure: '.$e->getMessage());
129
            }
130
131
            $azureGroupMembers = $azureGroupMembersRequest['value'] ?? [];
132
133
            foreach ($azureGroupMembers as $azureGroupMember) {
134
                yield $azureGroupMember;
135
            }
136
137
            if (!empty($azureGroupMembersRequest['@odata.nextLink'])) {
138
                $hasNextLink = true;
139
                $query = parse_url($azureGroupMembersRequest['@odata.nextLink'], PHP_URL_QUERY);
140
            }
141
        } while ($hasNextLink);
142
    }
143
}
144