Skip to content

Commit

Permalink
Merge pull request #642 from ncstate-delta/zoom/scopes_check
Browse files Browse the repository at this point in the history
  • Loading branch information
smbader authored Mar 6, 2025
2 parents e211120 + d53713f commit eef119d
Show file tree
Hide file tree
Showing 6 changed files with 142 additions and 21 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ Optional functionality can be enabled by granting additional scopes:
- cloud_recording:read:list_user_recordings:admin
- cloud_recording:read:recording_settings:admin
- Tracking fields (zoom | defaulttrackingfields)
- Not yet supported by Zoom
- tracking_field:read:list_tracking_fields:admin
- Recycle licenses (zoom | utmost), (zoom | recycleonjoin), (zoom | protectedgroups)
- group:read:list_groups:admin
- user:read:list_users:admin
Expand Down
19 changes: 19 additions & 0 deletions classes/task/delete_meeting_recordings.php
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,25 @@ public function execute() {
return;
}

// Required scopes for deleting meeting recordings.
$requiredscopes = [
'classic' => [
'recording:read:admin',
],
'granular' => [
'cloud_recording:read:list_recording_files:admin',
],
];

// Checking for missing scopes.
$missingscopes = $service->check_scopes($requiredscopes);
if (!empty($missingscopes)) {
foreach ($missingscopes as $missingscope) {
mtrace('Missing scope: ' . $missingscope);
}
return;
}

// See if we cannot make anymore API calls.
$retryafter = get_config('zoom', 'retry-after');
if (!empty($retryafter) && time() < $retryafter) {
Expand Down
20 changes: 20 additions & 0 deletions classes/task/get_meeting_recordings.php
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,26 @@ public function execute() {
return;
}

// Required scopes for meeting recordings.
$requiredscopes = [
'classic' => [
'recording:read:admin',
],
'granular' => [
'cloud_recording:read:list_user_recordings:admin',
'cloud_recording:read:recording_settings:admin',
],
];

// Checking for missing scopes.
$missingscopes = $service->check_scopes($requiredscopes);
if (!empty($missingscopes)) {
foreach ($missingscopes as $missingscope) {
mtrace('Missing scope: ' . $missingscope);
}
return;
}

// See if we cannot make anymore API calls.
$retryafter = get_config('zoom', 'retry-after');
if (!empty($retryafter) && time() < $retryafter) {
Expand Down
37 changes: 37 additions & 0 deletions classes/task/update_meetings.php
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,43 @@ public function execute() {
return;
}

// Required scopes for reading meeting information.
$requiredscopes = [
'classic' => [
'meeting:read:admin',
],
'granular' => [
'meeting:read:meeting:admin',
],
];

// Checking for missing scopes.
$missingmeetingscopes = $service->check_scopes($requiredscopes);
foreach ($missingmeetingscopes as $missingscope) {
mtrace('Missing scope: ' . $missingscope);
}

// Required scopes for reading webinar information.
$requiredscopes = [
'classic' => [
'webinar:read:admin',
],
'granular' => [
'webinar:read:webinar:admin',
],
];

// Checking for missing scopes.
$missingwebinarscopes = $service->check_scopes($requiredscopes);
foreach ($missingwebinarscopes as $missingscope) {
mtrace('Missing scope: ' . $missingscope);
}

// Exit if we have neither meeting scopes nor webinar scopes.
if (!empty($missingmeetingscopes) && !empty($missingwebinarscopes)) {
return;
}

// Show trace message.
mtrace('Starting to process existing Zoom meeting activities ...');

Expand Down
19 changes: 19 additions & 0 deletions classes/task/update_tracking_fields.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,25 @@ public function execute() {
return;
}

// Required scopes for tracking fields.
$requiredscopes = [
'classic' => [
'tracking_fields:read:admin',
],
'granular' => [
'tracking_field:read:list_tracking_fields:admin',
],
];

// Checking for missing scopes.
$missingscopes = $service->check_scopes($requiredscopes);
if (!empty($missingscopes)) {
foreach ($missingscopes as $missingscope) {
mtrace('Missing scope: ' . $missingscope);
}
return;
}

// Show trace message.
mtrace('Starting to process existing Zoom tracking fields ...');

Expand Down
66 changes: 46 additions & 20 deletions classes/webservice.php
Original file line number Diff line number Diff line change
Expand Up @@ -1072,7 +1072,7 @@ public function list_tracking_fields() {
$response = null;
try {
// Classic: tracking_fields:read:admin.
// Granular: Not yet implemented by Zoom.
// Granular: tracking_field:read:list_tracking_fields:admin.
$response = $this->make_call('tracking_fields');
} catch (moodle_exception $error) {
debugging($error->getMessage());
Expand Down Expand Up @@ -1240,6 +1240,34 @@ public function has_scope($scopes) {
return !empty($matchingscopes);
}

/**
* Check for Zoom scopes
*
* @param string $requiredscopes Required Zoom scopes.
* @throws moodle_exception
* @return array missingscopes
*/
public function check_scopes($requiredscopes) {
if (!isset($this->scopes)) {
$this->get_access_token();
}

$scopetype = $this->get_scope_type($this->scopes);

$missingscopes = array_diff($requiredscopes[$scopetype], $this->scopes);
return $missingscopes;
}

/**
* Checks for the type of scope (classic or granular) of the user.
*
* @param array $scopes
* @return string scope type
*/
private function get_scope_type($scopes) {
return in_array('meeting:read:admin', $scopes, true) ? 'classic' : 'granular';
}

/**
* Stores token and expiration in cache, returns token from OAuth call.
*
Expand Down Expand Up @@ -1276,31 +1304,29 @@ private function oauth($cache) {

$scopes = explode(' ', $response->scope);

// Keep the scope information in memory.
$this->scopes = $scopes;

// Assume that we are using granular scopes.
$requiredscopes = [
'meeting:read:meeting:admin',
'meeting:read:invitation:admin',
'meeting:delete:meeting:admin',
'meeting:update:meeting:admin',
'meeting:write:meeting:admin',
'user:read:list_schedulers:admin',
'user:read:settings:admin',
'user:read:user:admin',
];

// Check if we received classic scopes.
if (in_array('meeting:read:admin', $scopes, true)) {
$requiredscopes = [
'granular' => [
'meeting:read:meeting:admin',
'meeting:read:invitation:admin',
'meeting:delete:meeting:admin',
'meeting:update:meeting:admin',
'meeting:write:meeting:admin',
'user:read:list_schedulers:admin',
'user:read:settings:admin',
'user:read:user:admin',
],
'classic' => [
'meeting:read:admin',
'meeting:write:admin',
'user:read:admin',
];
}

$missingscopes = array_diff($requiredscopes, $scopes);
],
];

// Keep the scope information in memory.
$this->scopes = $scopes;
$missingscopes = $this->check_scopes($requiredscopes);

if (!empty($missingscopes)) {
$missingscopes = implode(', ', $missingscopes);
Expand Down

0 comments on commit eef119d

Please sign in to comment.