From 0ee0e2d537e6217278e75ec59c216936896bf6cb Mon Sep 17 00:00:00 2001 From: Alexander Tkachev Date: Mon, 15 Jul 2019 21:06:00 +0700 Subject: CLOUD: Update GoogleDriveStorage and BoxStorage to auth via cloud.scummvm.org --- backends/cloud/box/boxstorage.cpp | 77 ++------- backends/cloud/box/boxstorage.h | 25 +-- backends/cloud/box/boxtokenrefresher.cpp | 4 +- backends/cloud/googledrive/googledrivestorage.cpp | 71 ++------- backends/cloud/googledrive/googledrivestorage.h | 25 +-- .../googledrive/googledrivetokenrefresher.cpp | 2 +- backends/cloud/id/idstorage.cpp | 5 + backends/cloud/id/idstorage.h | 6 +- gui/storagewizarddialog.cpp | 172 ++------------------- gui/storagewizarddialog.h | 26 +--- 10 files changed, 77 insertions(+), 336 deletions(-) diff --git a/backends/cloud/box/boxstorage.cpp b/backends/cloud/box/boxstorage.cpp index 2671a77a5e..df81773855 100644 --- a/backends/cloud/box/boxstorage.cpp +++ b/backends/cloud/box/boxstorage.cpp @@ -42,50 +42,25 @@ namespace Cloud { namespace Box { -#define BOX_OAUTH2_TOKEN "https://api.box.com/oauth2/token" #define BOX_API_FOLDERS "https://api.box.com/2.0/folders" #define BOX_API_FILES_CONTENT "https://api.box.com/2.0/files/%s/content" #define BOX_API_USERS_ME "https://api.box.com/2.0/users/me" -char *BoxStorage::KEY = nullptr; //can't use CloudConfig there yet, loading it on instance creation/auth -char *BoxStorage::SECRET = nullptr; - -void BoxStorage::loadKeyAndSecret() { -#ifdef ENABLE_RELEASE - KEY = RELEASE_BOX_KEY; - SECRET = RELEASE_BOX_SECRET; -#else - Common::String k = ConfMan.get("BOX_KEY", ConfMan.kCloudDomain); - KEY = new char[k.size() + 1]; - memcpy(KEY, k.c_str(), k.size()); - KEY[k.size()] = 0; - - k = ConfMan.get("BOX_SECRET", ConfMan.kCloudDomain); - SECRET = new char[k.size() + 1]; - memcpy(SECRET, k.c_str(), k.size()); - SECRET[k.size()] = 0; -#endif -} - BoxStorage::BoxStorage(Common::String token, Common::String refreshToken): - _token(token), _refreshToken(refreshToken) {} + IdStorage(token, refreshToken) {} BoxStorage::BoxStorage(Common::String code) { - getAccessToken( - new Common::Callback(this, &BoxStorage::codeFlowComplete), - new Common::Callback(this, &BoxStorage::codeFlowFailed), - code - ); + getAccessToken(code); } BoxStorage::~BoxStorage() {} -void BoxStorage::getAccessToken(BoolCallback callback, Networking::ErrorCallback errorCallback, Common::String code) { - if (!KEY || !SECRET) - loadKeyAndSecret(); - bool codeFlow = (code != ""); +Common::String BoxStorage::cloudProvider() { return "box"; } - if (!codeFlow && _refreshToken == "") { +uint32 BoxStorage::storageIndex() { return kStorageBoxId; } + +void BoxStorage::refreshAccessToken(BoolCallback callback, Networking::ErrorCallback errorCallback) { + if (_refreshToken == "") { warning("BoxStorage: no refresh token available to get new access token."); if (callback) (*callback)(BoolResponse(nullptr, false)); return; @@ -95,23 +70,8 @@ void BoxStorage::getAccessToken(BoolCallback callback, Networking::ErrorCallback if (errorCallback == nullptr) errorCallback = getErrorPrintingCallback(); - Networking::CurlJsonRequest *request = new Networking::CurlJsonRequest(innerCallback, errorCallback, BOX_OAUTH2_TOKEN); - if (codeFlow) { - request->addPostField("grant_type=authorization_code"); - request->addPostField("code=" + code); - } else { - request->addPostField("grant_type=refresh_token"); - request->addPostField("refresh_token=" + _refreshToken); - } - request->addPostField("client_id=" + Common::String(KEY)); - request->addPostField("client_secret=" + Common::String(SECRET)); - /* - if (Cloud::CloudManager::couldUseLocalServer()) { - request->addPostField("&redirect_uri=http%3A%2F%2Flocalhost%3A12345"); - } else { - request->addPostField("&redirect_uri=https%3A%2F%2Fwww.scummvm.org/c/code"); - } - */ + Common::String url = "https://cloud.scummvm.org/box/refresh/" + _refreshToken; // TODO: subject to change + Networking::CurlJsonRequest *request = new Networking::CurlJsonRequest(innerCallback, errorCallback, url); addRequest(request); } @@ -151,23 +111,6 @@ void BoxStorage::tokenRefreshed(BoolCallback callback, Networking::JsonResponse delete callback; } -void BoxStorage::codeFlowComplete(BoolResponse response) { - if (!response.value) { - warning("BoxStorage: failed to get access token through code flow"); - CloudMan.removeStorage(this); - return; - } - - CloudMan.replaceStorage(this, kStorageBoxId); - ConfMan.flushToDisk(); -} - -void BoxStorage::codeFlowFailed(Networking::ErrorResponse error) { - debug(9, "BoxStorage: code flow failed (%s, %ld):", (error.failed ? "failed" : "interrupted"), error.httpResponseCode); - debug(9, "%s", error.response.c_str()); - CloudMan.removeStorage(this); -} - void BoxStorage::saveConfig(Common::String keyPrefix) { ConfMan.set(keyPrefix + "access_token", _token, ConfMan.kCloudDomain); ConfMan.set(keyPrefix + "refresh_token", _refreshToken, ConfMan.kCloudDomain); @@ -321,8 +264,6 @@ Networking::Request *BoxStorage::info(StorageInfoCallback callback, Networking:: Common::String BoxStorage::savesDirectoryPath() { return "scummvm/saves/"; } BoxStorage *BoxStorage::loadFromConfig(Common::String keyPrefix) { - loadKeyAndSecret(); - if (!ConfMan.hasKey(keyPrefix + "access_token", ConfMan.kCloudDomain)) { warning("BoxStorage: no access_token found"); return nullptr; diff --git a/backends/cloud/box/boxstorage.h b/backends/cloud/box/boxstorage.h index a641669b2a..e22624a20c 100644 --- a/backends/cloud/box/boxstorage.h +++ b/backends/cloud/box/boxstorage.h @@ -30,23 +30,27 @@ namespace Cloud { namespace Box { class BoxStorage: public Id::IdStorage { - static char *KEY, *SECRET; - - static void loadKeyAndSecret(); - - Common::String _token, _refreshToken; - /** This private constructor is called from loadFromConfig(). */ BoxStorage(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 createDirectoryInnerCallback(BoolCallback outerCallback, Networking::JsonResponse response); + +protected: + /** + * @return "box" + */ + virtual Common::String cloudProvider(); + + /** + * @return kStorageBoxId + */ + virtual uint32 storageIndex(); + public: /** This constructor uses OAuth code flow to get tokens. */ BoxStorage(Common::String code); @@ -101,11 +105,10 @@ public: virtual Common::String getRootDirectoryId(); /** - * 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/box/boxtokenrefresher.cpp b/backends/cloud/box/boxtokenrefresher.cpp index 5f7ad1d611..19cdd92667 100644 --- a/backends/cloud/box/boxtokenrefresher.cpp +++ b/backends/cloud/box/boxtokenrefresher.cpp @@ -99,7 +99,7 @@ void BoxTokenRefresher::finishJson(Common::JSONValue *json) { pause(); delete json; - _parentStorage->getAccessToken(new Common::Callback(this, &BoxTokenRefresher::tokenRefreshed)); + _parentStorage->refreshAccessToken(new Common::Callback(this, &BoxTokenRefresher::tokenRefreshed)); return; } } @@ -111,7 +111,7 @@ void BoxTokenRefresher::finishJson(Common::JSONValue *json) { void BoxTokenRefresher::finishError(Networking::ErrorResponse error) { if (error.httpResponseCode == 401) { // invalid_token pause(); - _parentStorage->getAccessToken(new Common::Callback(this, &BoxTokenRefresher::tokenRefreshed)); + _parentStorage->refreshAccessToken(new Common::Callback(this, &BoxTokenRefresher::tokenRefreshed)); return; } diff --git a/backends/cloud/googledrive/googledrivestorage.cpp b/backends/cloud/googledrive/googledrivestorage.cpp index 51799eb384..bd4f2cb8d3 100644 --- a/backends/cloud/googledrive/googledrivestorage.cpp +++ b/backends/cloud/googledrive/googledrivestorage.cpp @@ -43,49 +43,25 @@ namespace Cloud { namespace GoogleDrive { -#define GOOGLEDRIVE_OAUTH2_TOKEN "https://accounts.google.com/o/oauth2/token" #define GOOGLEDRIVE_API_FILES_ALT_MEDIA "https://www.googleapis.com/drive/v3/files/%s?alt=media" #define GOOGLEDRIVE_API_FILES "https://www.googleapis.com/drive/v3/files" #define GOOGLEDRIVE_API_ABOUT "https://www.googleapis.com/drive/v3/about?fields=storageQuota,user" -char *GoogleDriveStorage::KEY = nullptr; //can't use CloudConfig there yet, loading it on instance creation/auth -char *GoogleDriveStorage::SECRET = nullptr; - -void GoogleDriveStorage::loadKeyAndSecret() { -#ifdef ENABLE_RELEASE - KEY = RELEASE_GOOGLE_DRIVE_KEY; - SECRET = RELEASE_GOOGLE_DRIVE_SECRET; -#else - Common::String k = ConfMan.get("GOOGLE_DRIVE_KEY", ConfMan.kCloudDomain); - KEY = new char[k.size() + 1]; - memcpy(KEY, k.c_str(), k.size()); - KEY[k.size()] = 0; - - k = ConfMan.get("GOOGLE_DRIVE_SECRET", ConfMan.kCloudDomain); - SECRET = new char[k.size() + 1]; - memcpy(SECRET, k.c_str(), k.size()); - SECRET[k.size()] = 0; -#endif -} - GoogleDriveStorage::GoogleDriveStorage(Common::String token, Common::String refreshToken): - _token(token), _refreshToken(refreshToken) {} + IdStorage(token, refreshToken) {} GoogleDriveStorage::GoogleDriveStorage(Common::String code) { - getAccessToken( - new Common::Callback(this, &GoogleDriveStorage::codeFlowComplete), - new Common::Callback(this, &GoogleDriveStorage::codeFlowFailed), - code - ); + getAccessToken(code); } GoogleDriveStorage::~GoogleDriveStorage() {} -void GoogleDriveStorage::getAccessToken(BoolCallback callback, Networking::ErrorCallback errorCallback, Common::String code) { - if (!KEY || !SECRET) loadKeyAndSecret(); - bool codeFlow = (code != ""); +Common::String GoogleDriveStorage::cloudProvider() { return "gdrive"; } - if (!codeFlow && _refreshToken == "") { +uint32 GoogleDriveStorage::storageIndex() { return kStorageGoogleDriveId; } + +void GoogleDriveStorage::refreshAccessToken(BoolCallback callback, Networking::ErrorCallback errorCallback) { + if (_refreshToken == "") { warning("GoogleDriveStorage: no refresh token available to get new access token."); if (callback) (*callback)(BoolResponse(nullptr, false)); @@ -95,17 +71,9 @@ void GoogleDriveStorage::getAccessToken(BoolCallback callback, Networking::Error Networking::JsonCallback innerCallback = new Common::CallbackBridge(this, &GoogleDriveStorage::tokenRefreshed, callback); if (errorCallback == nullptr) errorCallback = getErrorPrintingCallback(); - Networking::CurlJsonRequest *request = new Networking::CurlJsonRequest(innerCallback, errorCallback, GOOGLEDRIVE_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/gdrive/refresh/" + _refreshToken; // TODO: subject to change + Networking::CurlJsonRequest *request = new Networking::CurlJsonRequest(innerCallback, errorCallback, url); addRequest(request); } @@ -147,23 +115,6 @@ void GoogleDriveStorage::tokenRefreshed(BoolCallback callback, Networking::JsonR delete callback; } -void GoogleDriveStorage::codeFlowComplete(BoolResponse response) { - if (!response.value) { - warning("GoogleDriveStorage: failed to get access token through code flow"); - CloudMan.removeStorage(this); - return; - } - - CloudMan.replaceStorage(this, kStorageGoogleDriveId); - ConfMan.flushToDisk(); -} - -void GoogleDriveStorage::codeFlowFailed(Networking::ErrorResponse error) { - debug(9, "GoogleDriveStorage: code flow failed (%s, %ld):", (error.failed ? "failed" : "interrupted"), error.httpResponseCode); - debug(9, "%s", error.response.c_str()); - CloudMan.removeStorage(this); -} - void GoogleDriveStorage::saveConfig(Common::String keyPrefix) { ConfMan.set(keyPrefix + "access_token", _token, ConfMan.kCloudDomain); ConfMan.set(keyPrefix + "refresh_token", _refreshToken, ConfMan.kCloudDomain); @@ -320,8 +271,6 @@ Networking::Request *GoogleDriveStorage::info(StorageInfoCallback callback, Netw Common::String GoogleDriveStorage::savesDirectoryPath() { return "scummvm/saves/"; } GoogleDriveStorage *GoogleDriveStorage::loadFromConfig(Common::String keyPrefix) { - loadKeyAndSecret(); - if (!ConfMan.hasKey(keyPrefix + "access_token", ConfMan.kCloudDomain)) { warning("GoogleDriveStorage: no access_token found"); return nullptr; diff --git a/backends/cloud/googledrive/googledrivestorage.h b/backends/cloud/googledrive/googledrivestorage.h index d0585bc403..30bc9ab3f5 100644 --- a/backends/cloud/googledrive/googledrivestorage.h +++ b/backends/cloud/googledrive/googledrivestorage.h @@ -30,18 +30,10 @@ namespace Cloud { namespace GoogleDrive { class GoogleDriveStorage: public Id::IdStorage { - static char *KEY, *SECRET; - - static void loadKeyAndSecret(); - - Common::String _token, _refreshToken; - /** This private constructor is called from loadFromConfig(). */ GoogleDriveStorage(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); @@ -50,6 +42,18 @@ class GoogleDriveStorage: public Id::IdStorage { void createDirectoryInnerCallback(BoolCallback outerCallback, Networking::JsonResponse json); void printInfo(StorageInfoResponse response); + +protected: + /** + * @return "gdrive" + */ + virtual Common::String cloudProvider(); + + /** + * @return kStorageGoogleDriveId + */ + virtual uint32 storageIndex(); + public: /** This constructor uses OAuth code flow to get tokens. */ GoogleDriveStorage(Common::String code); @@ -103,11 +107,10 @@ public: virtual Common::String getRootDirectoryId(); /** - * 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/googledrive/googledrivetokenrefresher.cpp b/backends/cloud/googledrive/googledrivetokenrefresher.cpp index a32a7fcbed..f28f73a788 100644 --- a/backends/cloud/googledrive/googledrivetokenrefresher.cpp +++ b/backends/cloud/googledrive/googledrivetokenrefresher.cpp @@ -100,7 +100,7 @@ void GoogleDriveTokenRefresher::finishJson(Common::JSONValue *json) { pause(); delete json; - _parentStorage->getAccessToken(new Common::Callback(this, &GoogleDriveTokenRefresher::tokenRefreshed)); + _parentStorage->refreshAccessToken(new Common::Callback(this, &GoogleDriveTokenRefresher::tokenRefreshed)); return; } } diff --git a/backends/cloud/id/idstorage.cpp b/backends/cloud/id/idstorage.cpp index 44427ac4d2..dd8805ea9b 100644 --- a/backends/cloud/id/idstorage.cpp +++ b/backends/cloud/id/idstorage.cpp @@ -33,6 +33,11 @@ namespace Cloud { namespace Id { +IdStorage::IdStorage() {} + +IdStorage::IdStorage(Common::String token, Common::String refreshToken): + BaseStorage(token, refreshToken) {} + IdStorage::~IdStorage() {} void IdStorage::printFiles(FileArrayResponse response) { diff --git a/backends/cloud/id/idstorage.h b/backends/cloud/id/idstorage.h index 946a792b42..35a320284e 100644 --- a/backends/cloud/id/idstorage.h +++ b/backends/cloud/id/idstorage.h @@ -23,7 +23,7 @@ #ifndef BACKENDS_CLOUD_ID_IDSTORAGE_H #define BACKENDS_CLOUD_ID_IDSTORAGE_H -#include "backends/cloud/storage.h" +#include "backends/cloud/basestorage.h" #include "backends/networking/curl/curljsonrequest.h" /* @@ -43,7 +43,7 @@ namespace Cloud { namespace Id { -class IdStorage: public Cloud::Storage { +class IdStorage: public Cloud::BaseStorage { protected: void printFiles(FileArrayResponse response); void printBool(BoolResponse response); @@ -52,6 +52,8 @@ protected: ListDirectoryCallback getPrintFilesCallback(); public: + IdStorage(); + IdStorage(Common::String token, Common::String refreshToken); virtual ~IdStorage(); /** Public Cloud API comes down there. */ diff --git a/gui/storagewizarddialog.cpp b/gui/storagewizarddialog.cpp index b5b4b6fee6..b01d4422b8 100644 --- a/gui/storagewizarddialog.cpp +++ b/gui/storagewizarddialog.cpp @@ -60,8 +60,7 @@ StorageWizardDialog::StorageWizardDialog(uint32 storageId): _returnLine1 = new StaticTextWidget(container, "GlobalOptions_Cloud_ConnectionWizard_Container.ReturnLine1", _("Obtain the code from the storage, enter it")); _returnLine2 = new StaticTextWidget(container, "GlobalOptions_Cloud_ConnectionWizard_Container.ReturnLine2", _("in the following field and press 'Connect':")); - for (uint32 i = 0; i < CODE_FIELDS; ++i) - _codeWidget[i] = new EditTextWidget(container, "GlobalOptions_Cloud_ConnectionWizard_Container.CodeBox" + Common::String::format("%d", i+1), "", 0, kCodeBoxCmd); + _codeWidget = new EditTextWidget(container, "GlobalOptions_Cloud_ConnectionWizard_Container.CodeBox1", "", 0, kCodeBoxCmd); _messageWidget = new StaticTextWidget(container, "GlobalOptions_Cloud_ConnectionWizard_Container.MessageLine", ""); // Buttons @@ -121,7 +120,6 @@ void StorageWizardDialog::open() { if (doClose) { close(); - return; } } } @@ -133,67 +131,10 @@ void StorageWizardDialog::close() { void StorageWizardDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) { switch (cmd) { case kCodeBoxCmd: { - Common::String code, message; - - if (_storageId == Cloud::kStorageDropboxId || _storageId == Cloud::kStorageOneDriveId) { - // new handling - code = _codeWidget[0]->getEditString(); - - bool ok = (code.size() > 0); - message = ""; // (ok ? _("All OK!") : ""); - - _connectWidget->setEnabled(ok); - _messageWidget->setLabel(message); - return; - } - - uint32 correctFields = 0; - for (uint32 i = 0; i < CODE_FIELDS; ++i) { - Common::String subcode = _codeWidget[i]->getEditString(); - if (subcode.size() == 0) { - ++correctFields; - continue; - } - bool correct = correctChecksum(subcode); - if (correct) { - code += subcode; - code.deleteLastChar(); - ++correctFields; - } else { - if (i == correctFields) { //first incorrect field - message += Common::String::format("#%d", i + 1); - } else { - message += Common::String::format(", #%d", i + 1); - } - } - } - - if (message.size() > 0) { - Common::String messageTemplate; - if (CODE_FIELDS - correctFields == 1) - messageTemplate = _("Field %s has a mistake in it."); - else - messageTemplate = _("Fields %s have mistakes in them."); - message = Common::String::format(messageTemplate.c_str(), message.c_str()); - } - - bool ok = false; - if (correctFields == CODE_FIELDS && code.size() > 0) { - //the last 3 chars must be an encoded crc16 - if (code.size() > 3) { - uint32 size = code.size(); - uint32 gotcrc = decodeHashchar(code[size - 3]) | (decodeHashchar(code[size - 2]) << 6) | (decodeHashchar(code[size - 1]) << 12); - code.erase(size - 3); - uint32 crc = crc16(code); - ok = (crc == gotcrc); - } - if (ok) - message = _("All OK!"); - else - message = _("Invalid code"); - } + Common::String code = _codeWidget->getEditString(); + bool ok = (code.size() > 0); _connectWidget->setEnabled(ok); - _messageWidget->setLabel(message); + _messageWidget->setLabel(""); break; } case kOpenUrlCmd: { @@ -206,21 +147,8 @@ void StorageWizardDialog::handleCommand(CommandSender *sender, uint32 cmd, uint3 case kPasteCodeCmd: { if (g_system->hasTextInClipboard()) { Common::String message = g_system->getTextFromClipboard(); - for (uint32 i = 0; i < CODE_FIELDS; ++i) { - if (message.empty()) break; - Common::String subcode = ""; - for (uint32 j = 0; j < message.size(); ++j) { - if (message[j] == ' ') { - message.erase(0, j+1); - break; - } - subcode += message[j]; - if (j+1 == message.size()) { - message = ""; - break; - } - } - _codeWidget[i]->setEditString(subcode); + if (!message.empty()) { + _codeWidget->setEditString(message); } handleCommand(sender, kCodeBoxCmd, data); g_gui.scheduleTopDialogRedraw(); @@ -228,32 +156,13 @@ void StorageWizardDialog::handleCommand(CommandSender *sender, uint32 cmd, uint3 break; } case kConnectCmd: { - if (_storageId == Cloud::kStorageDropboxId || _storageId == Cloud::kStorageOneDriveId) { - // new handling - Common::String code = _codeWidget[0]->getEditString(); - if (code.size() == 0) - return; - - CloudMan.connectStorage(_storageId, code); - setResult(1); - close(); + Common::String code = _codeWidget->getEditString(); + if (code.size() == 0) return; - } - Common::String code; - for (uint32 i = 0; i < CODE_FIELDS; ++i) { - Common::String subcode = _codeWidget[i]->getEditString(); - if (subcode.size() == 0) - continue; - code += subcode; - code.deleteLastChar(); - } - if (code.size() > 3) { - code.erase(code.size() - 3); - CloudMan.connectStorage(_storageId, code); - setResult(1); - close(); - } + CloudMan.connectStorage(_storageId, code); + setResult(1); + close(); break; } #ifdef USE_SDL_NET @@ -286,11 +195,9 @@ void StorageWizardDialog::containerWidgetsReflow() { if (_urlLineWidget) _urlLineWidget->setVisible(true); if (_returnLine1) _returnLine1->setVisible(true); if (_returnLine2) _returnLine2->setVisible(true); - - bool showFields = true; // TODO: remove this const - for (uint32 i = 0; i < CODE_FIELDS; ++i) - _codeWidget[i]->setVisible(showFields && ((_storageId != Cloud::kStorageDropboxId && _storageId != Cloud::kStorageOneDriveId) || i < 1)); // show only one field for Dropbox - _messageWidget->setVisible(showFields); + + _codeWidget->setVisible(true); + _messageWidget->setVisible(true); // left column / first bottom row if (_picture) { @@ -301,62 +208,17 @@ void StorageWizardDialog::containerWidgetsReflow() { _openUrlWidget->setVisible(visible); } if (_pasteCodeWidget) { - bool visible = showFields && g_system->hasFeature(OSystem::kFeatureClipboardSupport); + bool visible = g_system->hasFeature(OSystem::kFeatureClipboardSupport); _pasteCodeWidget->setVisible(visible); } // bottom row if (_cancelWidget) _cancelWidget->setVisible(true); - if (_connectWidget) { - _connectWidget->setVisible(showFields); - } + if (_connectWidget) _connectWidget->setVisible(true); } Common::String StorageWizardDialog::getUrl() const { - Common::String url = "https://www.scummvm.org/c/"; - switch (_storageId) { - case Cloud::kStorageDropboxId: - case Cloud::kStorageOneDriveId: - url = "https://cloud.scummvm.org/"; - break; - case Cloud::kStorageGoogleDriveId: - url += "gd"; - break; - case Cloud::kStorageBoxId: - url += "bx"; - break; - } - - return url; -} - -int StorageWizardDialog::decodeHashchar(char c) { - const char HASHCHARS[65] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ?!"; - for (uint32 i = 0; i < 64; ++i) - if (c == HASHCHARS[i]) - return i; - return -1; -} - -bool StorageWizardDialog::correctChecksum(Common::String s) { - if (s.size() == 0) - return false; //no last char - int providedChecksum = decodeHashchar(s.lastChar()); - int calculatedChecksum = 0x2A; //any initial value would do, but it must equal to the one used on the page where these checksums were generated - for (uint32 i = 0; i < s.size()-1; ++i) { - calculatedChecksum = calculatedChecksum ^ s[i]; - } - return providedChecksum == (calculatedChecksum % 64); -} - -uint32 StorageWizardDialog::crc16(Common::String s) { //"CRC16_CCITT_FALSE" - uint32 crc = 0xFFFF, x; - for (uint32 i = 0; i < s.size(); ++i) { - x = ((crc >> 8) ^ s[i]) & 0xFF; - x ^= x >> 4; - crc = ((crc << 8) ^ (x << 12) ^ (x << 5) ^ x) & 0xFFFF; - } - return crc; + return "https://cloud.scummvm.org/"; } } // End of namespace GUI diff --git a/gui/storagewizarddialog.h b/gui/storagewizarddialog.h index 61bc8ac873..ede37505ee 100644 --- a/gui/storagewizarddialog.h +++ b/gui/storagewizarddialog.h @@ -41,7 +41,6 @@ enum StorageWizardDialogCommands { #endif class StorageWizardDialog : public Dialog { - static const uint32 CODE_FIELDS = 8; uint32 _storageId; StaticTextWidget *_headlineWidget; @@ -49,7 +48,7 @@ class StorageWizardDialog : public Dialog { StaticTextWidget *_urlLineWidget; StaticTextWidget *_returnLine1; StaticTextWidget *_returnLine2; - EditTextWidget *_codeWidget[CODE_FIELDS]; + EditTextWidget *_codeWidget; StaticTextWidget *_messageWidget; GraphicsWidget *_picture; @@ -70,29 +69,6 @@ class StorageWizardDialog : public Dialog { /** Return short scummvm.org URL for user to navigate to. */ Common::String getUrl() const; - /** - * Return the value corresponding to the given character. - * - * There is a value corresponding to each of 64 selected - * printable characters (0-9, A-Z, a-z, ? and !). - * - * When given another character, -1 is returned. - */ - int decodeHashchar(char c); - - /** - * Return whether checksum is correct. - * - * The last character of the string is treated as - * the checksum of all the others (decoded with - * decodeHashchar()). - * - * Checksum = (c[0] ^ c[1] ^ ...) % 64 - */ - bool correctChecksum(Common::String s); - - /** The "CRC16_CCITT_FALSE" CRC-16 algorithm. */ - uint32 crc16(Common::String s); public: StorageWizardDialog(uint32 storageId); -- cgit v1.2.3