mirror of
https://github.com/moodle/moodle.git
synced 2025-04-21 16:32:18 +02:00
MDL-58219 googledocs: Update to new model for controlledlinks
Part of MDL-58220
This commit is contained in:
parent
141ee541ca
commit
72643dc688
@ -123,15 +123,6 @@ class rest extends \core\oauth2\rest {
|
||||
],
|
||||
'response' => 'json'
|
||||
],
|
||||
'list_permissions' => [
|
||||
'endpoint' => 'https://www.googleapis.com/drive/v3/files/{fileid}/permissions',
|
||||
'method' => 'get',
|
||||
'args' => [
|
||||
'fileid' => PARAM_RAW,
|
||||
'fields' => PARAM_RAW
|
||||
],
|
||||
'response' => 'json'
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@ -42,9 +42,9 @@ $string['supportedreturntypes'] = 'Supported files';
|
||||
$string['defaultreturntype'] = 'Default return type';
|
||||
$string['fileoptions'] = 'The types and defaults for returned files is configurable here. Note that all files linked externally will be updated so that the owner is the Moodle system account.';
|
||||
$string['owner'] = 'Owned by: {$a}';
|
||||
$string['cachedef_folder'] = 'Google File IDs for folders in the system account';
|
||||
|
||||
// Deprecated since Moodle 3.3.
|
||||
$string['oauthinfo'] = '<p>To use this plugin, you must register your site with Google, as described in the documentation <a href="{$a->docsurl}">Google OAuth 2.0 setup</a>.</p><p>As part of the registration process, you will need to enter the following URL as \'Authorized Redirect URIs\':</p><p>{$a->callbackurl}</p><p>Once registered, you will be provided with a client ID and secret which can be used to configure all Google Drive and Picasa plugins.</p><p>Please also note that you will have to enable the service \'Drive API\'.</p>';
|
||||
$string['secret'] = 'Secret';
|
||||
$string['clientid'] = 'Client ID';
|
||||
$string['cachedef_folder'] = 'Google File IDs for folders in the system account';
|
||||
|
@ -317,8 +317,7 @@ class repository_googledocs extends repository {
|
||||
'id' => $gfile->id,
|
||||
'name' => $gfile->name,
|
||||
'exportformat' => 'download',
|
||||
'link' => $link,
|
||||
'claimed' => false
|
||||
'link' => $link
|
||||
]);
|
||||
$title = $gfile->name;
|
||||
} else {
|
||||
@ -366,8 +365,7 @@ class repository_googledocs extends repository {
|
||||
'id' => $gfile->id,
|
||||
'exportformat' => $exporttype,
|
||||
'link' => $link,
|
||||
'name' => $gfile->name,
|
||||
'claimed' => false
|
||||
'name' => $gfile->name
|
||||
]);
|
||||
}
|
||||
// Adds the file to the file list. Using the itemId along with the name as key
|
||||
@ -553,7 +551,7 @@ class repository_googledocs extends repository {
|
||||
$storedfile->get_filepath(),
|
||||
$storedfile->get_filename());
|
||||
|
||||
if (!empty($source->claimed) && $info->is_writable()) {
|
||||
if ($info->is_writable()) {
|
||||
// Add the current user as an OAuth writer.
|
||||
$systemauth = \core\oauth2\api::get_system_oauth_client($this->issuer);
|
||||
|
||||
@ -594,90 +592,6 @@ class repository_googledocs extends repository {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update an external file so only Moodle has write access to it.
|
||||
* This function must be implemented by all repositories supporting FILE_CONTROLLED_LINK return types.
|
||||
*
|
||||
* Throw exceptions on error and the transaction will be rolled back
|
||||
* (because it is called on an entire filearea at a time).
|
||||
*
|
||||
* @param stored_file $file
|
||||
*/
|
||||
public function prevent_changes_to_external_file(stored_file $file) {
|
||||
global $DB;
|
||||
|
||||
// Copy the file (will make it owned by moodle system account).
|
||||
// Update the sharing settings on the file.
|
||||
// Prevent editors from sharing the file.
|
||||
$source = json_decode($file->get_reference());
|
||||
|
||||
$systemauth = \core\oauth2\api::get_system_oauth_client($this->issuer);
|
||||
|
||||
if ($systemauth === false) {
|
||||
$details = 'Cannot connect as system user';
|
||||
throw new repository_exception('errorwhilecommunicatingwith', 'repository', '', $details);
|
||||
}
|
||||
$systemservice = new repository_googledocs\rest($systemauth);
|
||||
|
||||
// Copy the file so we get a snapshot file owned by Moodle.
|
||||
$newsource = $this->copy_file($systemservice, $source->id, $source->name);
|
||||
|
||||
// Set the sharing options.
|
||||
$this->set_file_sharing_anyone_with_link_can_read($systemservice, $newsource->id);
|
||||
$this->prevent_writers_from_sharing_file($systemservice, $newsource->id);
|
||||
// Delete the original file from the Moodle account. This only deletes it for us (not the original owner).
|
||||
|
||||
$summary = $this->get_file_summary($systemservice, $source->id);
|
||||
if (!empty($summary->parents[0])) {
|
||||
$myparent = $summary->parents[0];
|
||||
$this->remove_file_parent($systemservice, $source->id, $myparent);
|
||||
}
|
||||
// We need to change the source on the existing file now to point to the new id.
|
||||
$source->id = $newsource->id;
|
||||
$source->link = isset($newsource->webViewLink) ? $newsource->webViewLink : '';
|
||||
if (empty($source->link)) {
|
||||
$source->link = isset($newsource->webContentLink) ? $newsource->webContentLink : '';
|
||||
}
|
||||
$source->claimed = true;
|
||||
$reference = json_encode($source);
|
||||
$file->set_source($reference);
|
||||
|
||||
// We need to update the reference in the file_reference table.
|
||||
$refid = $file->get_referencefileid();
|
||||
$newref = (object) [
|
||||
'id' => $refid,
|
||||
'reference' => $reference,
|
||||
'referencehash' => sha1($reference)
|
||||
];
|
||||
$DB->update_record('files_reference', $newref);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Grant write access and redirect to an edit link for the file.
|
||||
*
|
||||
* @param stored_file $storedfile the file that contains the reference
|
||||
*/
|
||||
public function edit_external_file($storedfile) {
|
||||
// Grant writer access to this file.
|
||||
|
||||
// Redirect to the file.
|
||||
$this->send_file($storedfile);
|
||||
}
|
||||
|
||||
/**
|
||||
* List the permissions on a file.
|
||||
*
|
||||
* @param \repository_googledocs\rest $client Authenticated client.
|
||||
* @param string $fileid The id of the file.
|
||||
* @return array
|
||||
*/
|
||||
protected function list_file_permissions(\repository_googledocs\rest $client, $fileid) {
|
||||
$fields = "permissions(id,type,emailAddress,role,allowFileDiscovery,displayName)";
|
||||
return $client->call('list_permissions', ['fileid' => $fileid]);
|
||||
}
|
||||
|
||||
/**
|
||||
* See if a folder exists within a folder
|
||||
*
|
||||
@ -721,23 +635,6 @@ class repository_googledocs extends repository {
|
||||
return $created->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get capabilities for a file.
|
||||
*
|
||||
* @param \repository_googledocs\rest $client Authenticated client.
|
||||
* @param string $fileid The file we are checking.
|
||||
*
|
||||
* @return stdClass The file info with capabilities.
|
||||
*/
|
||||
protected function get_file_capabilities(\repository_googledocs\rest $client, $fileid) {
|
||||
$fields = "id,capabilities,writersCanShare";
|
||||
$params = [
|
||||
'fileid' => $fileid,
|
||||
'fields' => $fields
|
||||
];
|
||||
return $client->call('get', $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get simple file info for humans.
|
||||
*
|
||||
@ -755,30 +652,6 @@ class repository_googledocs extends repository {
|
||||
return $client->call('get', $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update file owner.
|
||||
*
|
||||
* @param \repository_googledocs\rest $client Authenticated client.
|
||||
* @param string $fileid The file we are updating.
|
||||
* @param string $owneremail
|
||||
*
|
||||
* @return boolean Did it work?
|
||||
*/
|
||||
protected function update_file_owner(\repository_googledocs\rest $client, $fileid, $owneremail) {
|
||||
$updateowner = [
|
||||
'emailAddress' => $owneremail,
|
||||
'role' => 'owner',
|
||||
'type' => 'user'
|
||||
];
|
||||
$params = ['fileid' => $fileid, 'transferOwnership' => 'true'];
|
||||
try {
|
||||
$response = $client->call('create_permission', $params, json_encode($updateowner));
|
||||
} catch (\core\oauth2\rest_exception $re) {
|
||||
return false;
|
||||
}
|
||||
return !empty($response->id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy a file and return the new file details. A side effect of the copy
|
||||
* is that the owner will be the account authenticated with this oauth client.
|
||||
@ -808,23 +681,6 @@ class repository_googledocs extends repository {
|
||||
return $fileinfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a file (for the current user).
|
||||
*
|
||||
* @param \repository_googledocs\rest $client Authenticated client.
|
||||
* @param string $fileid The file we are deleting.
|
||||
* @return boolean
|
||||
*/
|
||||
protected function delete_file(\repository_googledocs\rest $client, $fileid) {
|
||||
$params = ['fileid' => $fileid];
|
||||
$response = $client->call('delete', $params, ' ');
|
||||
if (empty($response->id)) {
|
||||
$details = 'Cannot delete file: ' . $fileid;
|
||||
throw new repository_exception('errorwhilecommunicatingwith', 'repository', '', $details);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a writer to the permissions on the file (temporary).
|
||||
*
|
||||
@ -898,27 +754,6 @@ class repository_googledocs extends repository {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove parent
|
||||
*
|
||||
* @param \repository_googledocs\rest $client Authenticated client.
|
||||
* @param string $fileid The file we are updating.
|
||||
* @param string $folderid The id of the folder we are removing
|
||||
* @return boolean
|
||||
*/
|
||||
protected function remove_file_parent(\repository_googledocs\rest $client, $fileid, $folderid) {
|
||||
// Set the parent.
|
||||
$params = [
|
||||
'fileid' => $fileid, 'removeParents' => $folderid
|
||||
];
|
||||
$response = $client->call('update', $params, ' ');
|
||||
if (empty($response->id)) {
|
||||
$details = 'Cannot remove the file parent: ' . $fileid . ', ' . $folderid;
|
||||
throw new repository_exception('errorwhilecommunicatingwith', 'repository', '', $details);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prevent writers from sharing.
|
||||
*
|
||||
@ -971,9 +806,12 @@ class repository_googledocs extends repository {
|
||||
* @param string $reference this reference is generated by
|
||||
* repository::get_file_reference()
|
||||
* @param context $context the target context for this new file.
|
||||
* @return string $modifiedreference (final one before saving to DB)
|
||||
* @param string $component the target component for this new file.
|
||||
* @param string $filearea the target filearea for this new file.
|
||||
* @param string $itemid the target itemid for this new file.
|
||||
* @return string updated reference (final one before it's saved to db).
|
||||
*/
|
||||
public function reference_file_selected($reference, $context) {
|
||||
public function reference_file_selected($reference, $context, $component, $filearea, $itemid) {
|
||||
// What we need to do here is transfer ownership to the system user (or copy)
|
||||
// then set the permissions so anyone with the share link can view,
|
||||
// finally update the reference to contain the share link if it was not
|
||||
@ -1000,21 +838,6 @@ class repository_googledocs extends repository {
|
||||
$userservice = new repository_googledocs\rest($userauth);
|
||||
$systemservice = new repository_googledocs\rest($systemauth);
|
||||
|
||||
// Get the list of existing permissions so we can see if the owner is already the system account,
|
||||
// and whether we need to update the link sharing options.
|
||||
$permissions = $this->list_file_permissions($userservice, $source->id);
|
||||
|
||||
$readshareupdaterequired = true;
|
||||
$ownerupdaterequired = true;
|
||||
foreach ($permissions->permissions as $permission) {
|
||||
if ($permission->id == 'anyoneWithLink' &&
|
||||
$permission->type == 'anyone' &&
|
||||
$permission->role == 'reader' &&
|
||||
$permission->allowFileDiscovery == false) {
|
||||
$readshareupdaterequired = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Add Moodle as writer.
|
||||
$this->add_writer_to_file($userservice, $source->id, $systemuseremail);
|
||||
|
||||
@ -1024,12 +847,22 @@ class repository_googledocs extends repository {
|
||||
$cache = cache::make('repository_googledocs', 'folder');
|
||||
$parentid = 'root';
|
||||
$fullpath = 'root';
|
||||
$allfolders = [];
|
||||
foreach ($contextlist as $context) {
|
||||
// Make sure a folder exists here.
|
||||
$foldername = $context->get_context_name();
|
||||
$foldername = clean_param($context->get_context_name(), PARAM_PATH);
|
||||
$allfolders[] = $foldername;
|
||||
}
|
||||
|
||||
$allfolders[] = clean_param($component, PARAM_PATH);
|
||||
$allfolders[] = clean_param($filearea, PARAM_PATH);
|
||||
$allfolders[] = clean_param($itemid, PARAM_PATH);
|
||||
|
||||
foreach ($allfolders as $foldername) {
|
||||
// Make sure a folder exists here.
|
||||
$fullpath .= '/' . $foldername;
|
||||
|
||||
$folderid = $cache->get('fullpath');
|
||||
$folderid = $cache->get($fullpath);
|
||||
if (empty($folderid)) {
|
||||
$folderid = $this->folder_exists_in_folder($systemservice, $foldername, $parentid);
|
||||
}
|
||||
@ -1043,13 +876,22 @@ class repository_googledocs extends repository {
|
||||
}
|
||||
}
|
||||
|
||||
$this->move_file_from_root_to_folder($systemservice, $source->id, $parentid);
|
||||
// Copy the file so we get a snapshot file owned by Moodle.
|
||||
$newsource = $this->copy_file($systemservice, $source->id, $source->name);
|
||||
// Move the copied file to the correct folder.
|
||||
$this->move_file_from_root_to_folder($systemservice, $newsource->id, $parentid);
|
||||
|
||||
if ($readshareupdaterequired) {
|
||||
$this->set_file_sharing_anyone_with_link_can_read($systemservice, $source->id);
|
||||
// Set the sharing options.
|
||||
$this->set_file_sharing_anyone_with_link_can_read($systemservice, $newsource->id);
|
||||
$this->prevent_writers_from_sharing_file($systemservice, $newsource->id);
|
||||
|
||||
$source->id = $newsource->id;
|
||||
$source->link = isset($newsource->webViewLink) ? $newsource->webViewLink : '';
|
||||
if (empty($source->link)) {
|
||||
$source->link = isset($newsource->webContentLink) ? $newsource->webContentLink : '';
|
||||
}
|
||||
$reference = json_encode($source);
|
||||
|
||||
// We did not update the reference at all.
|
||||
return $reference;
|
||||
}
|
||||
|
||||
@ -1183,6 +1025,9 @@ class repository_googledocs extends repository {
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function repository_googledocs_oauth2_system_scopes() {
|
||||
return 'https://www.googleapis.com/auth/drive';
|
||||
function repository_googledocs_oauth2_system_scopes(\core\oauth2\issuer $issuer) {
|
||||
if ($issuer->get('id') == get_config('googledocs', 'issuerid')) {
|
||||
return 'https://www.googleapis.com/auth/drive';
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user