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

AzureSyncUsergroupsCommand::getAzureGroups()   A

Complexity

Conditions 5
Paths 5

Size

Total Lines 36
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Importance

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