From 8333cce498a0c600ff42e58d644f9dad7a10068b Mon Sep 17 00:00:00 2001 From: Alexander Tkachev Date: Mon, 15 Jul 2019 20:13:02 +0700 Subject: CLOUD: Update OneDriveStorage to work via cloud.scummvm.org --- backends/cloud/basestorage.cpp | 1 + backends/cloud/onedrive/onedrivestorage.cpp | 84 ++++------------------ backends/cloud/onedrive/onedrivestorage.h | 31 ++++---- backends/cloud/onedrive/onedrivetokenrefresher.cpp | 2 +- gui/storagewizarddialog.cpp | 10 ++- 5 files changed, 35 insertions(+), 93 deletions(-) diff --git a/backends/cloud/basestorage.cpp b/backends/cloud/basestorage.cpp index 9b31b4cad3..b71f7f6b15 100644 --- a/backends/cloud/basestorage.cpp +++ b/backends/cloud/basestorage.cpp @@ -87,6 +87,7 @@ void BaseStorage::codeFlowComplete(Networking::JsonResponse response) { debug(9, "%s", json->stringify(true).c_str()); CloudMan.removeStorage(this); } else { + debug(9, "%s", json->stringify(true).c_str()); // TODO: remove before commit _token = result.getVal("access_token")->asString(); CloudMan.replaceStorage(this, storageIndex()); ConfMan.flushToDisk(); diff --git a/backends/cloud/onedrive/onedrivestorage.cpp b/backends/cloud/onedrive/onedrivestorage.cpp index af8c70f845..09d7a819d8 100644 --- a/backends/cloud/onedrive/onedrivestorage.cpp +++ b/backends/cloud/onedrive/onedrivestorage.cpp @@ -43,49 +43,24 @@ namespace Cloud { namespace OneDrive { -#define ONEDRIVE_OAUTH2_TOKEN "https://login.live.com/oauth20_token.srf" #define ONEDRIVE_API_SPECIAL_APPROOT_ID "https://api.onedrive.com/v1.0/drive/special/approot:/" #define ONEDRIVE_API_SPECIAL_APPROOT "https://api.onedrive.com/v1.0/drive/special/approot" -char *OneDriveStorage::KEY = nullptr; //can't use CloudConfig there yet, loading it on instance creation/auth -char *OneDriveStorage::SECRET = nullptr; - -void OneDriveStorage::loadKeyAndSecret() { -#ifdef ENABLE_RELEASE - KEY = RELEASE_ONEDRIVE_KEY; - SECRET = RELEASE_ONEDRIVE_SECRET; -#else - Common::String k = ConfMan.get("ONEDRIVE_KEY", ConfMan.kCloudDomain); - KEY = new char[k.size() + 1]; - memcpy(KEY, k.c_str(), k.size()); - KEY[k.size()] = 0; - - k = ConfMan.get("ONEDRIVE_SECRET", ConfMan.kCloudDomain); - SECRET = new char[k.size() + 1]; - memcpy(SECRET, k.c_str(), k.size()); - SECRET[k.size()] = 0; -#endif -} - -OneDriveStorage::OneDriveStorage(Common::String token, Common::String uid, Common::String refreshToken): - _token(token), _uid(uid), _refreshToken(refreshToken) {} +OneDriveStorage::OneDriveStorage(Common::String token, Common::String refreshToken): + BaseStorage(token, refreshToken) {} OneDriveStorage::OneDriveStorage(Common::String code) { - getAccessToken( - new Common::Callback(this, &OneDriveStorage::codeFlowComplete), - new Common::Callback(this, &OneDriveStorage::codeFlowFailed), - code - ); + getAccessToken(code); } OneDriveStorage::~OneDriveStorage() {} -void OneDriveStorage::getAccessToken(BoolCallback callback, Networking::ErrorCallback errorCallback, Common::String code) { - if (!KEY || !SECRET) - loadKeyAndSecret(); - bool codeFlow = (code != ""); +Common::String OneDriveStorage::cloudProvider() { return "onedrive"; } - if (!codeFlow && _refreshToken == "") { +uint32 OneDriveStorage::storageIndex() { return kStorageOneDriveId; } + +void OneDriveStorage::refreshAccessToken(BoolCallback callback, Networking::ErrorCallback errorCallback) { + if (_refreshToken == "") { warning("OneDriveStorage: no refresh token available to get new access token."); if (callback) (*callback)(BoolResponse(nullptr, false)); @@ -95,17 +70,9 @@ void OneDriveStorage::getAccessToken(BoolCallback callback, Networking::ErrorCal Networking::JsonCallback innerCallback = new Common::CallbackBridge(this, &OneDriveStorage::tokenRefreshed, callback); if (errorCallback == nullptr) errorCallback = getErrorPrintingCallback(); - Networking::CurlJsonRequest *request = new Networking::CurlJsonRequest(innerCallback, errorCallback, ONEDRIVE_OAUTH2_TOKEN); - if (codeFlow) { - request->addPostField("code=" + code); - request->addPostField("grant_type=authorization_code"); - } else { - request->addPostField("refresh_token=" + _refreshToken); - request->addPostField("grant_type=refresh_token"); - } - request->addPostField("client_id=" + Common::String(KEY)); - request->addPostField("client_secret=" + Common::String(SECRET)); - request->addPostField("&redirect_uri=https%3A%2F%2Fwww.scummvm.org/c/code"); + + Common::String url = "https://cloud.scummvm.org/onedrive/refresh/" + _refreshToken; // TODO: subject to change + Networking::CurlJsonRequest *request = new Networking::CurlJsonRequest(innerCallback, errorCallback, url); addRequest(request); } @@ -137,7 +104,6 @@ void OneDriveStorage::tokenRefreshed(BoolCallback callback, Networking::JsonResp (*callback)(BoolResponse(nullptr, false)); } else { _token = result.getVal("access_token")->asString(); - _uid = result.getVal("user_id")->asString(); _refreshToken = result.getVal("refresh_token")->asString(); CloudMan.save(); //ask CloudManager to save our new refreshToken if (callback) @@ -147,26 +113,8 @@ void OneDriveStorage::tokenRefreshed(BoolCallback callback, Networking::JsonResp delete callback; } -void OneDriveStorage::codeFlowComplete(BoolResponse response) { - if (!response.value) { - warning("OneDriveStorage: failed to get access token through code flow"); - CloudMan.removeStorage(this); - return; - } - - CloudMan.replaceStorage(this, kStorageOneDriveId); - ConfMan.flushToDisk(); -} - -void OneDriveStorage::codeFlowFailed(Networking::ErrorResponse error) { - debug(9, "OneDriveStorage: code flow failed (%s, %ld):", (error.failed ? "failed" : "interrupted"), error.httpResponseCode); - debug(9, "%s", error.response.c_str()); - CloudMan.removeStorage(this); -} - void OneDriveStorage::saveConfig(Common::String keyPrefix) { ConfMan.set(keyPrefix + "access_token", _token, ConfMan.kCloudDomain); - ConfMan.set(keyPrefix + "user_id", _uid, ConfMan.kCloudDomain); ConfMan.set(keyPrefix + "refresh_token", _refreshToken, ConfMan.kCloudDomain); } @@ -295,27 +243,19 @@ Networking::Request *OneDriveStorage::info(StorageInfoCallback callback, Network Common::String OneDriveStorage::savesDirectoryPath() { return "saves/"; } OneDriveStorage *OneDriveStorage::loadFromConfig(Common::String keyPrefix) { - loadKeyAndSecret(); - if (!ConfMan.hasKey(keyPrefix + "access_token", ConfMan.kCloudDomain)) { warning("OneDriveStorage: no access_token found"); return nullptr; } - if (!ConfMan.hasKey(keyPrefix + "user_id", ConfMan.kCloudDomain)) { - warning("OneDriveStorage: no user_id found"); - return nullptr; - } - if (!ConfMan.hasKey(keyPrefix + "refresh_token", ConfMan.kCloudDomain)) { warning("OneDriveStorage: no refresh_token found"); return nullptr; } Common::String accessToken = ConfMan.get(keyPrefix + "access_token", ConfMan.kCloudDomain); - Common::String userId = ConfMan.get(keyPrefix + "user_id", ConfMan.kCloudDomain); Common::String refreshToken = ConfMan.get(keyPrefix + "refresh_token", ConfMan.kCloudDomain); - return new OneDriveStorage(accessToken, userId, refreshToken); + return new OneDriveStorage(accessToken, refreshToken); } } // End of namespace OneDrive diff --git a/backends/cloud/onedrive/onedrivestorage.h b/backends/cloud/onedrive/onedrivestorage.h index 5d24eb2c2e..2dab86e24b 100644 --- a/backends/cloud/onedrive/onedrivestorage.h +++ b/backends/cloud/onedrive/onedrivestorage.h @@ -23,30 +23,34 @@ #ifndef BACKENDS_CLOUD_ONEDRIVE_ONEDRIVESTORAGE_H #define BACKENDS_CLOUD_ONEDRIVE_ONEDRIVESTORAGE_H -#include "backends/cloud/storage.h" +#include "backends/cloud/basestorage.h" #include "backends/networking/curl/curljsonrequest.h" namespace Cloud { namespace OneDrive { -class OneDriveStorage: public Cloud::Storage { - static char *KEY, *SECRET; - - static void loadKeyAndSecret(); - - Common::String _token, _uid, _refreshToken; - +class OneDriveStorage: public Cloud::BaseStorage { /** This private constructor is called from loadFromConfig(). */ - OneDriveStorage(Common::String token, Common::String uid, Common::String refreshToken); + OneDriveStorage(Common::String token, Common::String refreshToken); void tokenRefreshed(BoolCallback callback, Networking::JsonResponse response); - void codeFlowComplete(BoolResponse response); - void codeFlowFailed(Networking::ErrorResponse error); /** Constructs StorageInfo based on JSON response from cloud. */ void infoInnerCallback(StorageInfoCallback outerCallback, Networking::JsonResponse json); void fileInfoCallback(Networking::NetworkReadStreamCallback outerCallback, Networking::JsonResponse response); + +protected: + /** + * @return "onedrive" + */ + virtual Common::String cloudProvider(); + + /** + * @return kStorageOneDriveId + */ + virtual uint32 storageIndex(); + public: /** This constructor uses OAuth code flow to get tokens. */ OneDriveStorage(Common::String code); @@ -98,11 +102,10 @@ public: static OneDriveStorage *loadFromConfig(Common::String keyPrefix); /** - * Gets new access_token. If passed is "", refresh_token is used. - * Use "" in order to refresh token and pass a callback, so you could + * Gets new access_token. Pass a callback, so you could * continue your work when new token is available. */ - void getAccessToken(BoolCallback callback, Networking::ErrorCallback errorCallback = nullptr, Common::String code = ""); + void refreshAccessToken(BoolCallback callback, Networking::ErrorCallback errorCallback = nullptr); Common::String accessToken() const { return _token; } }; diff --git a/backends/cloud/onedrive/onedrivetokenrefresher.cpp b/backends/cloud/onedrive/onedrivetokenrefresher.cpp index be6de40258..1404f76ba0 100644 --- a/backends/cloud/onedrive/onedrivetokenrefresher.cpp +++ b/backends/cloud/onedrive/onedrivetokenrefresher.cpp @@ -105,7 +105,7 @@ void OneDriveTokenRefresher::finishJson(Common::JSONValue *json) { pause(); delete json; - _parentStorage->getAccessToken(new Common::Callback(this, &OneDriveTokenRefresher::tokenRefreshed)); + _parentStorage->refreshAccessToken(new Common::Callback(this, &OneDriveTokenRefresher::tokenRefreshed)); return; } } diff --git a/gui/storagewizarddialog.cpp b/gui/storagewizarddialog.cpp index 0a50f8e812..b5b4b6fee6 100644 --- a/gui/storagewizarddialog.cpp +++ b/gui/storagewizarddialog.cpp @@ -135,7 +135,7 @@ void StorageWizardDialog::handleCommand(CommandSender *sender, uint32 cmd, uint3 case kCodeBoxCmd: { Common::String code, message; - if (_storageId == Cloud::kStorageDropboxId) { + if (_storageId == Cloud::kStorageDropboxId || _storageId == Cloud::kStorageOneDriveId) { // new handling code = _codeWidget[0]->getEditString(); @@ -228,7 +228,7 @@ void StorageWizardDialog::handleCommand(CommandSender *sender, uint32 cmd, uint3 break; } case kConnectCmd: { - if (_storageId == Cloud::kStorageDropboxId) { + if (_storageId == Cloud::kStorageDropboxId || _storageId == Cloud::kStorageOneDriveId) { // new handling Common::String code = _codeWidget[0]->getEditString(); if (code.size() == 0) @@ -289,7 +289,7 @@ void StorageWizardDialog::containerWidgetsReflow() { bool showFields = true; // TODO: remove this const for (uint32 i = 0; i < CODE_FIELDS; ++i) - _codeWidget[i]->setVisible(showFields && (_storageId != Cloud::kStorageDropboxId || i < 1)); // show only one field for Dropbox + _codeWidget[i]->setVisible(showFields && ((_storageId != Cloud::kStorageDropboxId && _storageId != Cloud::kStorageOneDriveId) || i < 1)); // show only one field for Dropbox _messageWidget->setVisible(showFields); // left column / first bottom row @@ -316,10 +316,8 @@ Common::String StorageWizardDialog::getUrl() const { Common::String url = "https://www.scummvm.org/c/"; switch (_storageId) { case Cloud::kStorageDropboxId: - url = "https://cloud.scummvm.org/"; - break; case Cloud::kStorageOneDriveId: - url += "od"; + url = "https://cloud.scummvm.org/"; break; case Cloud::kStorageGoogleDriveId: url += "gd"; -- cgit v1.2.3