aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--backends/cloud/basestorage.cpp125
-rw-r--r--backends/cloud/basestorage.h14
-rw-r--r--backends/cloud/box/boxstorage.cpp52
-rw-r--r--backends/cloud/box/boxstorage.h10
-rw-r--r--backends/cloud/dropbox/dropboxstorage.cpp2
-rw-r--r--backends/cloud/dropbox/dropboxstorage.h2
-rw-r--r--backends/cloud/googledrive/googledrivestorage.cpp55
-rw-r--r--backends/cloud/googledrive/googledrivestorage.h10
-rw-r--r--backends/cloud/onedrive/onedrivestorage.cpp56
-rw-r--r--backends/cloud/onedrive/onedrivestorage.h10
10 files changed, 145 insertions, 191 deletions
diff --git a/backends/cloud/basestorage.cpp b/backends/cloud/basestorage.cpp
index b71f7f6b15..035098fb47 100644
--- a/backends/cloud/basestorage.cpp
+++ b/backends/cloud/basestorage.cpp
@@ -41,7 +41,7 @@ void BaseStorage::getAccessToken(Common::String code) {
Networking::JsonCallback callback = new Common::Callback<BaseStorage, Networking::JsonResponse>(this, &BaseStorage::codeFlowComplete);
Networking::ErrorCallback errorCallback = new Common::Callback<BaseStorage, Networking::ErrorResponse>(this, &BaseStorage::codeFlowFailed);
- Common::String url = Common::String::format("https://cloud.scummvm.org/%s/%s", cloudProvider().c_str(), code.c_str());
+ Common::String url = Common::String::format("https://cloud.scummvm.org/%s/token/%s", cloudProvider().c_str(), code.c_str());
Networking::CurlJsonRequest *request = new Networking::CurlJsonRequest(callback, errorCallback, url);
addRequest(request);
@@ -82,16 +82,32 @@ void BaseStorage::codeFlowComplete(Networking::JsonResponse response) {
return;
}
- if (!Networking::CurlJsonRequest::jsonContainsString(result, "access_token", "BaseStorage::codeFlowComplete")) {
- warning("BaseStorage: bad response, no 'access_token' attribute passed");
+ if (!Networking::CurlJsonRequest::jsonContainsObject(result, "oauth", "BaseStorage::codeFlowComplete")) {
+ warning("BaseStorage: bad response, no 'oauth' attribute passed");
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();
+ delete json;
+ return;
+ }
+
+ Common::JSONObject oauth = result.getVal("oauth")->asObject();
+ bool requiresRefreshToken = needsRefreshToken();
+ if (!Networking::CurlJsonRequest::jsonContainsString(oauth, "access_token", "BaseStorage::codeFlowComplete") ||
+ !Networking::CurlJsonRequest::jsonContainsString(oauth, "refresh_token", "BaseStorage::codeFlowComplete", !requiresRefreshToken)) {
+ warning("BaseStorage: bad response, no 'access_token' or 'refresh_token' attribute passed");
+ debug(9, "%s", json->stringify(true).c_str());
+ CloudMan.removeStorage(this);
+ delete json;
+ return;
+ }
+
+ debug(9, "%s", json->stringify(true).c_str()); // TODO: remove before commit
+ _token = oauth.getVal("access_token")->asString();
+ if (requiresRefreshToken) {
+ _refreshToken = oauth.getVal("refresh_token")->asString();
}
+ CloudMan.replaceStorage(this, storageIndex());
+ ConfMan.flushToDisk();
delete json;
}
@@ -102,4 +118,97 @@ void BaseStorage::codeFlowFailed(Networking::ErrorResponse error) {
CloudMan.removeStorage(this);
}
+void BaseStorage::refreshAccessToken(BoolCallback callback, Networking::ErrorCallback errorCallback) {
+ if (_refreshToken == "") {
+ warning("BaseStorage: no refresh token available to get new access token.");
+ if (callback) (*callback)(BoolResponse(nullptr, false));
+ return;
+ }
+
+ Networking::JsonCallback innerCallback = new Common::CallbackBridge<BaseStorage, BoolResponse, Networking::JsonResponse>(this, &BaseStorage::tokenRefreshed, callback);
+ if (errorCallback == nullptr)
+ errorCallback = getErrorPrintingCallback();
+
+ Common::String url = Common::String::format("https://cloud.scummvm.org/%s/refresh?code=%s", cloudProvider().c_str(), _refreshToken.c_str());
+ Networking::CurlJsonRequest *request = new Networking::CurlJsonRequest(innerCallback, errorCallback, url);
+ addRequest(request);
+}
+
+void BaseStorage::tokenRefreshed(BoolCallback callback, Networking::JsonResponse response) {
+ Common::JSONValue *json = response.value;
+ if (json == nullptr) {
+ debug(9, "BaseStorage::tokenRefreshed: got NULL instead of JSON!");
+ if (callback)
+ (*callback)(BoolResponse(nullptr, false));
+ delete callback;
+ return;
+ }
+
+ if (!json->isObject()) {
+ debug(9, "BaseStorage::tokenRefreshed: passed JSON is not an object!");
+ if (callback)
+ (*callback)(BoolResponse(nullptr, false));
+ delete json;
+ delete callback;
+ return;
+ }
+
+ Common::JSONObject result = json->asObject();
+ if (!Networking::CurlJsonRequest::jsonContainsAttribute(result, "error", "BaseStorage::tokenRefreshed")) {
+ warning("BaseStorage: bad response, no 'error' attribute passed");
+ debug(9, "%s", json->stringify(true).c_str());
+ if (callback)
+ (*callback)(BoolResponse(nullptr, false));
+ delete json;
+ delete callback;
+ return;
+ }
+
+ if (result.getVal("error")->asBool()) {
+ Common::String errorMessage = "{error: true}, message is missing";
+ if (Networking::CurlJsonRequest::jsonContainsString(result, "message", "BaseStorage::tokenRefreshed")) {
+ errorMessage = result.getVal("message")->asString();
+ }
+ warning("BaseStorage: response says error occurred: %s", errorMessage.c_str());
+ if (callback)
+ (*callback)(BoolResponse(nullptr, false));
+ delete json;
+ delete callback;
+ return;
+ }
+
+ if (!Networking::CurlJsonRequest::jsonContainsObject(result, "oauth", "BaseStorage::tokenRefreshed")) {
+ warning("BaseStorage: bad response, no 'oauth' attribute passed");
+ debug(9, "%s", json->stringify(true).c_str());
+ if (callback)
+ (*callback)(BoolResponse(nullptr, false));
+ delete json;
+ delete callback;
+ return;
+ }
+
+ Common::JSONObject oauth = result.getVal("oauth")->asObject();
+ bool requiresRefreshToken = needsRefreshToken(); // TODO: it seems Google Drive might not send new refresh token, and still accept old one
+ if (!Networking::CurlJsonRequest::jsonContainsString(oauth, "access_token", "BaseStorage::tokenRefreshed") ||
+ !Networking::CurlJsonRequest::jsonContainsString(oauth, "refresh_token", "BaseStorage::tokenRefreshed", !requiresRefreshToken)) {
+ warning("BaseStorage: bad response, no 'access_token' or 'refresh_token' attribute passed");
+ debug(9, "%s", json->stringify(true).c_str());
+ if (callback)
+ (*callback)(BoolResponse(nullptr, false));
+ delete json;
+ delete callback;
+ return;
+ }
+
+ _token = oauth.getVal("access_token")->asString();
+ if (requiresRefreshToken) {
+ _refreshToken = oauth.getVal("refresh_token")->asString();
+ }
+ CloudMan.save(); //ask CloudManager to save our new access_token and refresh_token
+ if (callback)
+ (*callback)(BoolResponse(nullptr, true));
+ delete json;
+ delete callback;
+}
+
} // End of namespace Cloud
diff --git a/backends/cloud/basestorage.h b/backends/cloud/basestorage.h
index cca6e1bb48..4b3b497d0d 100644
--- a/backends/cloud/basestorage.h
+++ b/backends/cloud/basestorage.h
@@ -64,10 +64,24 @@ protected:
*/
virtual uint32 storageIndex() = 0;
+ /**
+ * Return whether storage needs refresh_token to work.
+ */
+ virtual bool needsRefreshToken() = 0;
+
+private:
+ void tokenRefreshed(BoolCallback callback, Networking::JsonResponse response);
+
public:
BaseStorage();
BaseStorage(Common::String token, Common::String refreshToken);
virtual ~BaseStorage();
+
+ /**
+ * Gets new access_token. Pass a callback, so you could
+ * continue your work when new token is available.
+ */
+ virtual void refreshAccessToken(BoolCallback callback, Networking::ErrorCallback errorCallback = nullptr);
};
} // End of namespace Cloud
diff --git a/backends/cloud/box/boxstorage.cpp b/backends/cloud/box/boxstorage.cpp
index d743e9546e..42e902902d 100644
--- a/backends/cloud/box/boxstorage.cpp
+++ b/backends/cloud/box/boxstorage.cpp
@@ -55,57 +55,7 @@ Common::String BoxStorage::cloudProvider() { return "box"; }
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;
- }
-
- Networking::JsonCallback innerCallback = new Common::CallbackBridge<BoxStorage, BoolResponse, Networking::JsonResponse>(this, &BoxStorage::tokenRefreshed, callback);
- if (errorCallback == nullptr)
- errorCallback = getErrorPrintingCallback();
-
- 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);
-}
-
-void BoxStorage::tokenRefreshed(BoolCallback callback, Networking::JsonResponse response) {
- Common::JSONValue *json = response.value;
- if (!json) {
- warning("BoxStorage: got NULL instead of JSON");
- if (callback)
- (*callback)(BoolResponse(nullptr, false));
- delete callback;
- return;
- }
-
- if (!Networking::CurlJsonRequest::jsonIsObject(json, "BoxStorage")) {
- if (callback)
- (*callback)(BoolResponse(nullptr, false));
- delete json;
- delete callback;
- return;
- }
-
- Common::JSONObject result = json->asObject();
- if (!Networking::CurlJsonRequest::jsonContainsString(result, "access_token", "BoxStorage") ||
- !Networking::CurlJsonRequest::jsonContainsString(result, "refresh_token", "BoxStorage")) {
- warning("BoxStorage: bad response, no token passed");
- debug(9, "%s", json->stringify().c_str());
- if (callback)
- (*callback)(BoolResponse(nullptr, false));
- } else {
- _token = result.getVal("access_token")->asString();
- _refreshToken = result.getVal("refresh_token")->asString();
- CloudMan.save(); //ask CloudManager to save our new refreshToken
- if (callback)
- (*callback)(BoolResponse(nullptr, true));
- }
- delete json;
- delete callback;
-}
+bool BoxStorage::needsRefreshToken() { return true; }
void BoxStorage::saveConfig(Common::String keyPrefix) {
ConfMan.set(keyPrefix + "access_token", _token, ConfMan.kCloudDomain);
diff --git a/backends/cloud/box/boxstorage.h b/backends/cloud/box/boxstorage.h
index e22624a20c..a6ceb522ad 100644
--- a/backends/cloud/box/boxstorage.h
+++ b/backends/cloud/box/boxstorage.h
@@ -33,8 +33,6 @@ class BoxStorage: public Id::IdStorage {
/** This private constructor is called from loadFromConfig(). */
BoxStorage(Common::String token, Common::String refreshToken);
- void tokenRefreshed(BoolCallback callback, Networking::JsonResponse response);
-
/** Constructs StorageInfo based on JSON response from cloud. */
void infoInnerCallback(StorageInfoCallback outerCallback, Networking::JsonResponse json);
@@ -51,6 +49,8 @@ protected:
*/
virtual uint32 storageIndex();
+ virtual bool needsRefreshToken();
+
public:
/** This constructor uses OAuth code flow to get tokens. */
BoxStorage(Common::String code);
@@ -104,12 +104,6 @@ public:
virtual Common::String getRootDirectoryId();
- /**
- * Gets new access_token. Pass a callback, so you could
- * continue your work when new token is available.
- */
- void refreshAccessToken(BoolCallback callback, Networking::ErrorCallback errorCallback = nullptr);
-
Common::String accessToken() const { return _token; }
};
diff --git a/backends/cloud/dropbox/dropboxstorage.cpp b/backends/cloud/dropbox/dropboxstorage.cpp
index 459f4dc67a..8941dff94a 100644
--- a/backends/cloud/dropbox/dropboxstorage.cpp
+++ b/backends/cloud/dropbox/dropboxstorage.cpp
@@ -52,6 +52,8 @@ Common::String DropboxStorage::cloudProvider() { return "dropbox"; }
uint32 DropboxStorage::storageIndex() { return kStorageDropboxId; }
+bool DropboxStorage::needsRefreshToken() { return false; }
+
void DropboxStorage::saveConfig(Common::String keyPrefix) {
ConfMan.set(keyPrefix + "access_token", _token, ConfMan.kCloudDomain);
}
diff --git a/backends/cloud/dropbox/dropboxstorage.h b/backends/cloud/dropbox/dropboxstorage.h
index b82e38e554..bd9f284f72 100644
--- a/backends/cloud/dropbox/dropboxstorage.h
+++ b/backends/cloud/dropbox/dropboxstorage.h
@@ -45,6 +45,8 @@ protected:
*/
virtual uint32 storageIndex();
+ virtual bool needsRefreshToken();
+
public:
/** This constructor uses OAuth code flow to get tokens. */
DropboxStorage(Common::String code);
diff --git a/backends/cloud/googledrive/googledrivestorage.cpp b/backends/cloud/googledrive/googledrivestorage.cpp
index a2f688a1e7..be81629cef 100644
--- a/backends/cloud/googledrive/googledrivestorage.cpp
+++ b/backends/cloud/googledrive/googledrivestorage.cpp
@@ -56,60 +56,7 @@ Common::String GoogleDriveStorage::cloudProvider() { return "gdrive"; }
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));
- return;
- }
-
- Networking::JsonCallback innerCallback = new Common::CallbackBridge<GoogleDriveStorage, BoolResponse, Networking::JsonResponse>(this, &GoogleDriveStorage::tokenRefreshed, callback);
- if (errorCallback == nullptr)
- errorCallback = getErrorPrintingCallback();
-
- 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);
-}
-
-void GoogleDriveStorage::tokenRefreshed(BoolCallback callback, Networking::JsonResponse response) {
- Common::JSONValue *json = response.value;
- if (!json) {
- warning("GoogleDriveStorage: got NULL instead of JSON");
- if (callback)
- (*callback)(BoolResponse(nullptr, false));
- delete callback;
- return;
- }
-
- if (!Networking::CurlJsonRequest::jsonIsObject(json, "GoogleDriveStorage")) {
- if (callback)
- (*callback)(BoolResponse(nullptr, false));
- delete json;
- delete callback;
- return;
- }
-
- Common::JSONObject result = json->asObject();
- if (!Networking::CurlJsonRequest::jsonContainsString(result, "access_token", "GoogleDriveStorage")) {
- warning("GoogleDriveStorage: bad response, no token passed");
- debug(9, "%s", json->stringify().c_str());
- if (callback)
- (*callback)(BoolResponse(nullptr, false));
- } else {
- _token = result.getVal("access_token")->asString();
- if (!Networking::CurlJsonRequest::jsonContainsString(result, "refresh_token", "GoogleDriveStorage"))
- warning("GoogleDriveStorage: no refresh_token passed");
- else
- _refreshToken = result.getVal("refresh_token")->asString();
- CloudMan.save(); //ask CloudManager to save our new refreshToken
- if (callback)
- (*callback)(BoolResponse(nullptr, true));
- }
- delete json;
- delete callback;
-}
+bool GoogleDriveStorage::needsRefreshToken() { return true; }
void GoogleDriveStorage::saveConfig(Common::String keyPrefix) {
ConfMan.set(keyPrefix + "access_token", _token, ConfMan.kCloudDomain);
diff --git a/backends/cloud/googledrive/googledrivestorage.h b/backends/cloud/googledrive/googledrivestorage.h
index 30bc9ab3f5..730e8e20c3 100644
--- a/backends/cloud/googledrive/googledrivestorage.h
+++ b/backends/cloud/googledrive/googledrivestorage.h
@@ -33,8 +33,6 @@ class GoogleDriveStorage: public Id::IdStorage {
/** This private constructor is called from loadFromConfig(). */
GoogleDriveStorage(Common::String token, Common::String refreshToken);
- void tokenRefreshed(BoolCallback callback, Networking::JsonResponse response);
-
/** Constructs StorageInfo based on JSON response from cloud. */
void infoInnerCallback(StorageInfoCallback outerCallback, Networking::JsonResponse json);
@@ -54,6 +52,8 @@ protected:
*/
virtual uint32 storageIndex();
+ virtual bool needsRefreshToken();
+
public:
/** This constructor uses OAuth code flow to get tokens. */
GoogleDriveStorage(Common::String code);
@@ -106,12 +106,6 @@ public:
virtual Common::String getRootDirectoryId();
- /**
- * Gets new access_token. Pass a callback, so you could
- * continue your work when new token is available.
- */
- void refreshAccessToken(BoolCallback callback, Networking::ErrorCallback errorCallback = nullptr);
-
Common::String accessToken() const { return _token; }
};
diff --git a/backends/cloud/onedrive/onedrivestorage.cpp b/backends/cloud/onedrive/onedrivestorage.cpp
index 779797aa21..8a2a8a5dae 100644
--- a/backends/cloud/onedrive/onedrivestorage.cpp
+++ b/backends/cloud/onedrive/onedrivestorage.cpp
@@ -42,7 +42,7 @@ namespace OneDrive {
#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"
-OneDriveStorage::OneDriveStorage(Common::String token, Common::String refreshToken):
+OneDriveStorage::OneDriveStorage(Common::String token, Common::String refreshToken):
BaseStorage(token, refreshToken) {}
OneDriveStorage::OneDriveStorage(Common::String code) {
@@ -55,59 +55,7 @@ Common::String OneDriveStorage::cloudProvider() { return "onedrive"; }
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));
- return;
- }
-
- Networking::JsonCallback innerCallback = new Common::CallbackBridge<OneDriveStorage, BoolResponse, Networking::JsonResponse>(this, &OneDriveStorage::tokenRefreshed, callback);
- if (errorCallback == nullptr)
- errorCallback = getErrorPrintingCallback();
-
- 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);
-}
-
-void OneDriveStorage::tokenRefreshed(BoolCallback callback, Networking::JsonResponse response) {
- Common::JSONValue *json = response.value;
- if (!json) {
- warning("OneDriveStorage: got NULL instead of JSON");
- if (callback)
- (*callback)(BoolResponse(nullptr, false));
- delete callback;
- return;
- }
-
- if (!Networking::CurlJsonRequest::jsonIsObject(json, "OneDriveStorage")) {
- if (callback)
- (*callback)(BoolResponse(nullptr, false));
- delete json;
- delete callback;
- return;
- }
-
- Common::JSONObject result = json->asObject();
- if (!Networking::CurlJsonRequest::jsonContainsString(result, "access_token", "OneDriveStorage") ||
- !Networking::CurlJsonRequest::jsonContainsString(result, "user_id", "OneDriveStorage") ||
- !Networking::CurlJsonRequest::jsonContainsString(result, "refresh_token", "OneDriveStorage")) {
- warning("OneDriveStorage: bad response, no token or user_id passed");
- debug(9, "%s", json->stringify().c_str());
- if (callback)
- (*callback)(BoolResponse(nullptr, false));
- } else {
- _token = result.getVal("access_token")->asString();
- _refreshToken = result.getVal("refresh_token")->asString();
- CloudMan.save(); //ask CloudManager to save our new refreshToken
- if (callback)
- (*callback)(BoolResponse(nullptr, true));
- }
- delete json;
- delete callback;
-}
+bool OneDriveStorage::needsRefreshToken() { return true; }
void OneDriveStorage::saveConfig(Common::String keyPrefix) {
ConfMan.set(keyPrefix + "access_token", _token, ConfMan.kCloudDomain);
diff --git a/backends/cloud/onedrive/onedrivestorage.h b/backends/cloud/onedrive/onedrivestorage.h
index 2dab86e24b..5059e0d5b0 100644
--- a/backends/cloud/onedrive/onedrivestorage.h
+++ b/backends/cloud/onedrive/onedrivestorage.h
@@ -33,8 +33,6 @@ class OneDriveStorage: public Cloud::BaseStorage {
/** This private constructor is called from loadFromConfig(). */
OneDriveStorage(Common::String token, Common::String refreshToken);
- void tokenRefreshed(BoolCallback callback, Networking::JsonResponse response);
-
/** Constructs StorageInfo based on JSON response from cloud. */
void infoInnerCallback(StorageInfoCallback outerCallback, Networking::JsonResponse json);
@@ -51,6 +49,8 @@ protected:
*/
virtual uint32 storageIndex();
+ virtual bool needsRefreshToken();
+
public:
/** This constructor uses OAuth code flow to get tokens. */
OneDriveStorage(Common::String code);
@@ -101,12 +101,6 @@ public:
*/
static OneDriveStorage *loadFromConfig(Common::String keyPrefix);
- /**
- * Gets new access_token. Pass a callback, so you could
- * continue your work when new token is available.
- */
- void refreshAccessToken(BoolCallback callback, Networking::ErrorCallback errorCallback = nullptr);
-
Common::String accessToken() const { return _token; }
};