From 88a78237b01bae66786f9c32f30b936240ea6f58 Mon Sep 17 00:00:00 2001 From: Robin McCorkell Date: Wed, 12 Aug 2015 22:09:20 +0100 Subject: [PATCH] Migrate Google external storage to new API --- .../ajax/{google.php => oauth2.php} | 1 + apps/files_external/appinfo/app.php | 14 -- apps/files_external/appinfo/application.php | 4 + apps/files_external/appinfo/routes.php | 4 +- apps/files_external/js/google.js | 131 ------------------ apps/files_external/js/oauth2.js | 95 +++++++++++++ .../files_external/lib/auth/oauth2/oauth2.php | 51 +++++++ apps/files_external/lib/backend/google.php | 48 +++++++ 8 files changed, 201 insertions(+), 147 deletions(-) rename apps/files_external/ajax/{google.php => oauth2.php} (98%) delete mode 100644 apps/files_external/js/google.js create mode 100644 apps/files_external/js/oauth2.js create mode 100644 apps/files_external/lib/auth/oauth2/oauth2.php create mode 100644 apps/files_external/lib/backend/google.php diff --git a/apps/files_external/ajax/google.php b/apps/files_external/ajax/oauth2.php similarity index 98% rename from apps/files_external/ajax/google.php rename to apps/files_external/ajax/oauth2.php index acaf1b0b27..0a202e3ddc 100644 --- a/apps/files_external/ajax/google.php +++ b/apps/files_external/ajax/oauth2.php @@ -33,6 +33,7 @@ OCP\JSON::checkLoggedIn(); OCP\JSON::callCheck(); $l = \OC::$server->getL10N('files_external'); +// FIXME: currently hard-coded to Google Drive if (isset($_POST['client_id']) && isset($_POST['client_secret']) && isset($_POST['redirect'])) { $client = new Google_Client(); $client->setClientId((string)$_POST['client_id']); diff --git a/apps/files_external/appinfo/app.php b/apps/files_external/appinfo/app.php index 14edfe3538..9db4b0a633 100644 --- a/apps/files_external/appinfo/app.php +++ b/apps/files_external/appinfo/app.php @@ -70,20 +70,6 @@ if (OCP\Config::getAppValue('files_external', 'allow_user_mounting', 'yes') == ' OCP\Util::connectHook('OC_Filesystem', 'post_initMountPoints', '\OC_Mount_Config', 'initMountPointsHook'); OCP\Util::connectHook('OC_User', 'post_login', 'OC\Files\Storage\SMB_OC', 'login'); -OC_Mount_Config::registerBackend('\OC\Files\Storage\Google', [ - 'backend' => 'Google Drive', - 'priority' => 100, - 'configuration' => [ - 'configured' => '#configured', - 'client_id' => (string)$l->t('Client ID'), - 'client_secret' => '*'.$l->t('Client secret'), - 'token' => '#token', - ], - 'custom' => 'google', - 'has_dependencies' => true, -]); - - OC_Mount_Config::registerBackend('\OC\Files\Storage\Swift', [ 'backend' => (string)$l->t('OpenStack Object Storage'), 'priority' => 100, diff --git a/apps/files_external/appinfo/application.php b/apps/files_external/appinfo/application.php index 4a9a7a6b82..1e43c73740 100644 --- a/apps/files_external/appinfo/application.php +++ b/apps/files_external/appinfo/application.php @@ -67,6 +67,7 @@ class Application extends App { $container->query('OCA\Files_External\Lib\Backend\SFTP'), $container->query('OCA\Files_External\Lib\Backend\AmazonS3'), $container->query('OCA\Files_External\Lib\Backend\Dropbox'), + $container->query('OCA\Files_External\Lib\Backend\Google'), ]); if (!\OC_Util::runningOnWindows()) { @@ -97,6 +98,9 @@ class Application extends App { // AuthMechanism::SCHEME_OAUTH1 mechanisms $container->query('OCA\Files_External\Lib\Auth\OAuth1\OAuth1'), + // AuthMechanism::SCHEME_OAUTH2 mechanisms + $container->query('OCA\Files_External\Lib\Auth\OAuth2\OAuth2'), + // Specialized mechanisms $container->query('OCA\Files_External\Lib\Auth\AmazonS3\AccessKey'), ]); diff --git a/apps/files_external/appinfo/routes.php b/apps/files_external/appinfo/routes.php index ccc50cbd0f..5d7018c347 100644 --- a/apps/files_external/appinfo/routes.php +++ b/apps/files_external/appinfo/routes.php @@ -48,8 +48,8 @@ namespace OCA\Files_External\AppInfo; $this->create('files_external_oauth1', 'ajax/oauth1.php') ->actionInclude('files_external/ajax/oauth1.php'); -$this->create('files_external_google', 'ajax/google.php') - ->actionInclude('files_external/ajax/google.php'); +$this->create('files_external_oauth2', 'ajax/oauth2.php') + ->actionInclude('files_external/ajax/oauth2.php'); $this->create('files_external_list_applicable', '/applicable') diff --git a/apps/files_external/js/google.js b/apps/files_external/js/google.js deleted file mode 100644 index 648538f802..0000000000 --- a/apps/files_external/js/google.js +++ /dev/null @@ -1,131 +0,0 @@ -$(document).ready(function() { - - $('#externalStorage tbody tr.\\\\OC\\\\Files\\\\Storage\\\\Google').each(function() { - var configured = $(this).find('[data-parameter="configured"]'); - if ($(configured).val() == 'true') { - $(this).find('.configuration input').attr('disabled', 'disabled'); - $(this).find('.configuration').append($('').attr('id', 'access') - .text(t('files_external', 'Access granted'))); - } else { - var client_id = $(this).find('.configuration [data-parameter="client_id"]').val(); - var client_secret = $(this).find('.configuration [data-parameter="client_secret"]') - .val(); - if (client_id != '' && client_secret != '') { - var params = {}; - window.location.href.replace(/[?&]+([^=&]+)=([^&]*)/gi, function(m, key, value) { - params[key] = value; - }); - if (params['code'] !== undefined) { - var tr = $(this); - var token = $(this).find('.configuration [data-parameter="token"]'); - var statusSpan = $(tr).find('.status span'); - statusSpan.removeClass(); - statusSpan.addClass('waiting'); - $.post(OC.filePath('files_external', 'ajax', 'google.php'), - { - step: 2, - client_id: client_id, - client_secret: client_secret, - redirect: location.protocol + '//' + location.host + location.pathname, - code: params['code'], - }, function(result) { - if (result && result.status == 'success') { - $(token).val(result.data.token); - $(configured).val('true'); - OCA.External.Settings.mountConfig.saveStorageConfig(tr, function(status) { - if (status) { - $(tr).find('.configuration input').attr('disabled', 'disabled'); - $(tr).find('.configuration').append($('') - .attr('id', 'access') - .text(t('files_external', 'Access granted'))); - } - }); - } else { - OC.dialogs.alert(result.data.message, - t('files_external', 'Error configuring Google Drive storage') - ); - } - } - ); - } - } else { - onGoogleInputsChange($(this)); - } - } - }); - - $('#externalStorage').on('paste', 'tbody tr.\\\\OC\\\\Files\\\\Storage\\\\Google td', - function() { - var tr = $(this).parent(); - setTimeout(function() { - onGoogleInputsChange(tr); - }, 20); - } - ); - - $('#externalStorage').on('keyup', 'tbody tr.\\\\OC\\\\Files\\\\Storage\\\\Google td', - function() { - onGoogleInputsChange($(this).parent()); - } - ); - - $('#externalStorage').on('change', 'tbody tr.\\\\OC\\\\Files\\\\Storage\\\\Google .chzn-select' - , function() { - onGoogleInputsChange($(this).parent().parent()); - } - ); - - function onGoogleInputsChange(tr) { - if ($(tr).find('[data-parameter="configured"]').val() != 'true') { - var config = $(tr).find('.configuration'); - if ($(tr).find('.mountPoint input').val() != '' - && $(config).find('[data-parameter="client_id"]').val() != '' - && $(config).find('[data-parameter="client_secret"]').val() != '' - && ($(tr).find('.chzn-select').length == 0 - || $(tr).find('.chzn-select').val() != null)) - { - if ($(tr).find('.google').length == 0) { - $(config).append($(document.createElement('input')).addClass('button google') - .attr('type', 'button') - .attr('value', t('files_external', 'Grant access'))); - } else { - $(tr).find('.google').show(); - } - } else if ($(tr).find('.google').length > 0) { - $(tr).find('.google').hide(); - } - } - } - - $('#externalStorage').on('click', '.google', function(event) { - event.preventDefault(); - var tr = $(this).parent().parent(); - var configured = $(this).parent().find('[data-parameter="configured"]'); - var client_id = $(this).parent().find('[data-parameter="client_id"]').val(); - var client_secret = $(this).parent().find('[data-parameter="client_secret"]').val(); - if (client_id != '' && client_secret != '') { - var token = $(this).parent().find('[data-parameter="token"]'); - $.post(OC.filePath('files_external', 'ajax', 'google.php'), - { - step: 1, - client_id: client_id, - client_secret: client_secret, - redirect: location.protocol + '//' + location.host + location.pathname, - }, function(result) { - if (result && result.status == 'success') { - $(configured).val('false'); - $(token).val('false'); - OCA.External.Settings.mountConfig.saveStorageConfig(tr, function(status) { - window.location = result.data.url; - }); - } else { - OC.dialogs.alert(result.data.message, - t('files_external', 'Error configuring Google Drive storage') - ); - } - } - ); - } - }); - -}); diff --git a/apps/files_external/js/oauth2.js b/apps/files_external/js/oauth2.js new file mode 100644 index 0000000000..8494143742 --- /dev/null +++ b/apps/files_external/js/oauth2.js @@ -0,0 +1,95 @@ +$(document).ready(function() { + + OCA.External.Settings.mountConfig.whenSelectAuthMechanism(function($tr, authMechanism, scheme) { + if (authMechanism === 'oauth2::oauth2') { + var config = $tr.find('.configuration'); + config.append($(document.createElement('input')) + .addClass('button auth-param') + .attr('type', 'button') + .attr('value', t('files_external', 'Grant access')) + .attr('name', 'oauth2_grant') + ); + + var configured = $tr.find('[data-parameter="configured"]'); + if ($(configured).val() == 'true') { + $tr.find('.configuration input').attr('disabled', 'disabled'); + $tr.find('.configuration').append($('').attr('id', 'access') + .text(t('files_external', 'Access granted'))); + } else { + var client_id = $tr.find('.configuration [data-parameter="client_id"]').val(); + var client_secret = $tr.find('.configuration [data-parameter="client_secret"]') + .val(); + if (client_id != '' && client_secret != '') { + var params = {}; + window.location.href.replace(/[?&]+([^=&]+)=([^&]*)/gi, function(m, key, value) { + params[key] = value; + }); + if (params['code'] !== undefined) { + var token = $tr.find('.configuration [data-parameter="token"]'); + var statusSpan = $tr.find('.status span'); + statusSpan.removeClass(); + statusSpan.addClass('waiting'); + $.post(OC.filePath('files_external', 'ajax', 'oauth2.php'), + { + step: 2, + client_id: client_id, + client_secret: client_secret, + redirect: location.protocol + '//' + location.host + location.pathname, + code: params['code'], + }, function(result) { + if (result && result.status == 'success') { + $(token).val(result.data.token); + $(configured).val('true'); + OCA.External.Settings.mountConfig.saveStorageConfig($tr, function(status) { + if (status) { + $tr.find('.configuration input').attr('disabled', 'disabled'); + $tr.find('.configuration').append($('') + .attr('id', 'access') + .text(t('files_external', 'Access granted'))); + } + }); + } else { + OC.dialogs.alert(result.data.message, + t('files_external', 'Error configuring OAuth2') + ); + } + } + ); + } + } + } + } + }); + + $('#externalStorage').on('click', '[name="oauth2_grant"]', function(event) { + event.preventDefault(); + var tr = $(this).parent().parent(); + var configured = $(this).parent().find('[data-parameter="configured"]'); + var client_id = $(this).parent().find('[data-parameter="client_id"]').val(); + var client_secret = $(this).parent().find('[data-parameter="client_secret"]').val(); + if (client_id != '' && client_secret != '') { + var token = $(this).parent().find('[data-parameter="token"]'); + $.post(OC.filePath('files_external', 'ajax', 'oauth2.php'), + { + step: 1, + client_id: client_id, + client_secret: client_secret, + redirect: location.protocol + '//' + location.host + location.pathname, + }, function(result) { + if (result && result.status == 'success') { + $(configured).val('false'); + $(token).val('false'); + OCA.External.Settings.mountConfig.saveStorageConfig(tr, function(status) { + window.location = result.data.url; + }); + } else { + OC.dialogs.alert(result.data.message, + t('files_external', 'Error configuring OAuth2') + ); + } + } + ); + } + }); + +}); diff --git a/apps/files_external/lib/auth/oauth2/oauth2.php b/apps/files_external/lib/auth/oauth2/oauth2.php new file mode 100644 index 0000000000..73faa85a44 --- /dev/null +++ b/apps/files_external/lib/auth/oauth2/oauth2.php @@ -0,0 +1,51 @@ + + * + * @copyright Copyright (c) 2015, ownCloud, Inc. + * @license AGPL-3.0 + * + * This code is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License, version 3, + * along with this program. If not, see + * + */ + +namespace OCA\Files_External\Lib\Auth\OAuth2; + +use \OCP\IL10N; +use \OCA\Files_External\Lib\DefinitionParameter; +use \OCA\Files_External\Lib\Auth\AuthMechanism; + +/** + * OAuth2 authentication + */ +class OAuth2 extends AuthMechanism { + + public function __construct(IL10N $l) { + $this + ->setIdentifier('oauth2::oauth2') + ->setScheme(self::SCHEME_OAUTH2) + ->setText($l->t('OAuth2')) + ->addParameters([ + (new DefinitionParameter('configured', 'configured')) + ->setType(DefinitionParameter::VALUE_HIDDEN), + (new DefinitionParameter('client_id', $l->t('Client ID'))), + (new DefinitionParameter('client_secret', $l->t('Client secret'))) + ->setType(DefinitionParameter::VALUE_PASSWORD), + (new DefinitionParameter('token', 'token')) + ->setType(DefinitionParameter::VALUE_HIDDEN), + ]) + ->setCustomJs('oauth2') + ; + } + +} diff --git a/apps/files_external/lib/backend/google.php b/apps/files_external/lib/backend/google.php new file mode 100644 index 0000000000..b46b2f653a --- /dev/null +++ b/apps/files_external/lib/backend/google.php @@ -0,0 +1,48 @@ + + * + * @copyright Copyright (c) 2015, ownCloud, Inc. + * @license AGPL-3.0 + * + * This code is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License, version 3, + * along with this program. If not, see + * + */ + +namespace OCA\Files_External\Lib\Backend; + +use \OCP\IL10N; +use \OCA\Files_External\Lib\Backend\Backend; +use \OCA\Files_External\Lib\DefinitionParameter; +use \OCA\Files_External\Lib\Auth\AuthMechanism; +use \OCA\Files_External\Service\BackendService; +use \OCA\Files_External\Lib\Auth\OAuth2\OAuth2; + +class Google extends Backend { + + public function __construct(IL10N $l, OAuth2 $legacyAuth) { + $this + ->setIdentifier('googledrive') + ->addIdentifierAlias('\OC\Files\Storage\Google') // legacy compat + ->setStorageClass('\OC\Files\Storage\Google') + ->setText($l->t('Google Drive')) + ->addParameters([ + // all parameters handled in OAuth2 mechanism + ]) + ->setDependencyCheck('\OC\Files\Storage\Google::checkDependencies') + ->addAuthScheme(AuthMechanism::SCHEME_OAUTH2) + ->setLegacyAuthMechanism($legacyAuth) + ; + } + +}