Passed
Pull Request — 1.11.x (#5763)
by Angel Fernando Quiroz
21:22 queued 12:43
created

AzureSyncUsergroupsCommand   A

Complexity

Total Complexity 17

Size/Duplication

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