aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Tkachev2019-07-16 14:12:45 +0700
committerMatan Bareket2019-07-30 14:51:41 -0400
commitedbea10c2e5606daec18c148c8b103649d1011c5 (patch)
tree0579a22dd3ce399c28a8a2d6ab93e7a80f5fc3a3
parente8669f693c6adbb33f515d9a4ce9d1079756e2e8 (diff)
downloadscummvm-rg350-edbea10c2e5606daec18c148c8b103649d1011c5.tar.gz
scummvm-rg350-edbea10c2e5606daec18c148c8b103649d1011c5.tar.bz2
scummvm-rg350-edbea10c2e5606daec18c148c8b103649d1011c5.zip
CLOUD: Fix OneDriveStorage API interaction
Something changed and old API endpoint "api.onedrive.com" now does not work. The other one, "graph.microsoft.com", does, but there were some other changes in JSON it returns. These changes are also in this commit.
-rw-r--r--backends/cloud/onedrive/onedrivecreatedirectoryrequest.cpp2
-rw-r--r--backends/cloud/onedrive/onedrivelistdirectoryrequest.cpp6
-rw-r--r--backends/cloud/onedrive/onedrivestorage.cpp15
-rw-r--r--backends/cloud/onedrive/onedrivetokenrefresher.cpp26
-rw-r--r--backends/cloud/onedrive/onedrivetokenrefresher.h1
-rw-r--r--backends/cloud/onedrive/onedriveuploadrequest.cpp4
-rw-r--r--backends/cloud/savessyncrequest.cpp21
7 files changed, 61 insertions, 14 deletions
diff --git a/backends/cloud/onedrive/onedrivecreatedirectoryrequest.cpp b/backends/cloud/onedrive/onedrivecreatedirectoryrequest.cpp
index 74cf3208e3..f7e995f332 100644
--- a/backends/cloud/onedrive/onedrivecreatedirectoryrequest.cpp
+++ b/backends/cloud/onedrive/onedrivecreatedirectoryrequest.cpp
@@ -31,7 +31,7 @@
namespace Cloud {
namespace OneDrive {
-#define ONEDRIVE_API_SPECIAL_APPROOT "https://api.onedrive.com/v1.0/drive/special/approot"
+#define ONEDRIVE_API_SPECIAL_APPROOT "https://graph.microsoft.com/v1.0/drive/special/approot"
OneDriveCreateDirectoryRequest::OneDriveCreateDirectoryRequest(OneDriveStorage *storage, Common::String path, Storage::BoolCallback cb, Networking::ErrorCallback ecb):
Networking::Request(nullptr, ecb), _storage(storage), _path(path), _boolCallback(cb),
diff --git a/backends/cloud/onedrive/onedrivelistdirectoryrequest.cpp b/backends/cloud/onedrive/onedrivelistdirectoryrequest.cpp
index 953845d343..f16097680b 100644
--- a/backends/cloud/onedrive/onedrivelistdirectoryrequest.cpp
+++ b/backends/cloud/onedrive/onedrivelistdirectoryrequest.cpp
@@ -31,7 +31,8 @@
namespace Cloud {
namespace OneDrive {
-#define ONEDRIVE_API_SPECIAL_APPROOT_CHILDREN "https://api.onedrive.com/v1.0/drive/special/approot:/%s:/children"
+#define ONEDRIVE_API_SPECIAL_APPROOT_CHILDREN "https://graph.microsoft.com/v1.0/drive/special/approot:/%s:/children"
+#define ONEDRIVE_API_SPECIAL_APPROOT_CHILDREN_ROOT_ITSELF "https://graph.microsoft.com/v1.0/drive/special/approot/children"
OneDriveListDirectoryRequest::OneDriveListDirectoryRequest(OneDriveStorage *storage, Common::String path, Storage::ListDirectoryCallback cb, Networking::ErrorCallback ecb, bool recursive):
Networking::Request(nullptr, ecb),
@@ -77,6 +78,7 @@ void OneDriveListDirectoryRequest::listNextDirectory() {
Common::String dir = _currentDirectory;
dir.deleteLastChar();
Common::String url = Common::String::format(ONEDRIVE_API_SPECIAL_APPROOT_CHILDREN, ConnMan.urlEncode(dir).c_str());
+ if (dir == "") url = Common::String(ONEDRIVE_API_SPECIAL_APPROOT_CHILDREN_ROOT_ITSELF);
makeRequest(url);
}
@@ -84,7 +86,7 @@ void OneDriveListDirectoryRequest::makeRequest(Common::String url) {
Networking::JsonCallback callback = new Common::Callback<OneDriveListDirectoryRequest, Networking::JsonResponse>(this, &OneDriveListDirectoryRequest::listedDirectoryCallback);
Networking::ErrorCallback failureCallback = new Common::Callback<OneDriveListDirectoryRequest, Networking::ErrorResponse>(this, &OneDriveListDirectoryRequest::listedDirectoryErrorCallback);
Networking::CurlJsonRequest *request = new OneDriveTokenRefresher(_storage, callback, failureCallback, url.c_str());
- request->addHeader("Authorization: Bearer " + _storage->accessToken());
+ request->addHeader("Authorization: bearer " + _storage->accessToken());
_workingRequest = ConnMan.addRequest(request);
}
diff --git a/backends/cloud/onedrive/onedrivestorage.cpp b/backends/cloud/onedrive/onedrivestorage.cpp
index fbaa675085..48c3a10d82 100644
--- a/backends/cloud/onedrive/onedrivestorage.cpp
+++ b/backends/cloud/onedrive/onedrivestorage.cpp
@@ -39,8 +39,8 @@
namespace Cloud {
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"
+#define ONEDRIVE_API_SPECIAL_APPROOT_ID "https://graph.microsoft.com/v1.0/drive/special/approot:/"
+#define ONEDRIVE_API_SPECIAL_APPROOT "https://graph.microsoft.com/v1.0/drive/special/approot"
OneDriveStorage::OneDriveStorage(Common::String token, Common::String refreshToken):
BaseStorage(token, refreshToken) {}
@@ -136,7 +136,7 @@ void OneDriveStorage::fileInfoCallback(Networking::NetworkReadStreamCallback out
}
Common::JSONObject result = response.value->asObject();
- if (!Networking::CurlJsonRequest::jsonContainsString(result, "@content.downloadUrl", "OneDriveStorage::fileInfoCallback")) {
+ if (!Networking::CurlJsonRequest::jsonContainsString(result, "@microsoft.graph.downloadUrl", "OneDriveStorage::fileInfoCallback")) {
warning("OneDriveStorage: downloadUrl not found in passed JSON");
debug(9, "%s", response.value->stringify().c_str());
if (outerCallback)
@@ -146,7 +146,7 @@ void OneDriveStorage::fileInfoCallback(Networking::NetworkReadStreamCallback out
return;
}
- const char *url = result.getVal("@content.downloadUrl")->asString().c_str();
+ const char *url = result.getVal("@microsoft.graph.downloadUrl")->asString().c_str();
if (outerCallback)
(*outerCallback)(Networking::NetworkReadStreamResponse(
response.request,
@@ -158,28 +158,33 @@ void OneDriveStorage::fileInfoCallback(Networking::NetworkReadStreamCallback out
}
Networking::Request *OneDriveStorage::listDirectory(Common::String path, ListDirectoryCallback callback, Networking::ErrorCallback errorCallback, bool recursive) {
+ debug(9, "OneDrive: `ls \"%s\"`", path.c_str());
return addRequest(new OneDriveListDirectoryRequest(this, path, callback, errorCallback, recursive));
}
Networking::Request *OneDriveStorage::upload(Common::String path, Common::SeekableReadStream *contents, UploadCallback callback, Networking::ErrorCallback errorCallback) {
+ debug(9, "OneDrive: `upload \"%s\"`", path.c_str());
return addRequest(new OneDriveUploadRequest(this, path, contents, callback, errorCallback));
}
Networking::Request *OneDriveStorage::streamFileById(Common::String path, Networking::NetworkReadStreamCallback outerCallback, Networking::ErrorCallback errorCallback) {
+ debug(9, "OneDrive: `download \"%s\"`", path.c_str());
Common::String url = ONEDRIVE_API_SPECIAL_APPROOT_ID + ConnMan.urlEncode(path);
Networking::JsonCallback innerCallback = new Common::CallbackBridge<OneDriveStorage, Networking::NetworkReadStreamResponse, Networking::JsonResponse>(this, &OneDriveStorage::fileInfoCallback, outerCallback);
Networking::CurlJsonRequest *request = new OneDriveTokenRefresher(this, innerCallback, errorCallback, url.c_str());
- request->addHeader("Authorization: Bearer " + _token);
+ request->addHeader("Authorization: bearer " + _token);
return addRequest(request);
}
Networking::Request *OneDriveStorage::createDirectory(Common::String path, BoolCallback callback, Networking::ErrorCallback errorCallback) {
+ debug(9, "OneDrive: `mkdir \"%s\"`", path.c_str());
if (!errorCallback)
errorCallback = getErrorPrintingCallback();
return addRequest(new OneDriveCreateDirectoryRequest(this, path, callback, errorCallback));
}
Networking::Request *OneDriveStorage::info(StorageInfoCallback callback, Networking::ErrorCallback errorCallback) {
+ debug(9, "OneDrive: `info`");
Networking::JsonCallback innerCallback = new Common::CallbackBridge<OneDriveStorage, StorageInfoResponse, Networking::JsonResponse>(this, &OneDriveStorage::infoInnerCallback, callback);
Networking::CurlJsonRequest *request = new OneDriveTokenRefresher(this, innerCallback, errorCallback, ONEDRIVE_API_SPECIAL_APPROOT);
request->addHeader("Authorization: bearer " + _token);
diff --git a/backends/cloud/onedrive/onedrivetokenrefresher.cpp b/backends/cloud/onedrive/onedrivetokenrefresher.cpp
index 1404f76ba0..d17e352159 100644
--- a/backends/cloud/onedrive/onedrivetokenrefresher.cpp
+++ b/backends/cloud/onedrive/onedrivetokenrefresher.cpp
@@ -94,7 +94,7 @@ void OneDriveTokenRefresher::finishJson(Common::JSONValue *json) {
irrecoverable = false;
}
- if (code == "unauthenticated")
+ if (code == "unauthenticated" || code == "InvalidAuthenticationToken")
irrecoverable = false;
if (irrecoverable) {
@@ -114,6 +114,30 @@ void OneDriveTokenRefresher::finishJson(Common::JSONValue *json) {
CurlJsonRequest::finishJson(json);
}
+void OneDriveTokenRefresher::finishError(Networking::ErrorResponse error) {
+ bool irrecoverable = error.interrupted || error.failed;
+ if (error.failed) {
+ Common::JSONValue *value = Common::JSON::parse(error.response.c_str());
+
+ //somehow OneDrive returns JSON with '.' in unexpected places, try fixing it
+ if (!value) {
+ Common::String fixedResponse = error.response;
+ for (uint32 i = 0; i < fixedResponse.size(); ++i) {
+ if (fixedResponse[i] == '.')
+ fixedResponse.replace(i, 1, " ");
+ }
+ value = Common::JSON::parse(fixedResponse.c_str());
+ }
+
+ if (value) {
+ finishJson(value);
+ return;
+ }
+ }
+
+ Request::finishError(error); //call closest base class's method
+}
+
void OneDriveTokenRefresher::setHeaders(Common::Array<Common::String> &headers) {
_headers = headers;
curl_slist_free_all(_headersList);
diff --git a/backends/cloud/onedrive/onedrivetokenrefresher.h b/backends/cloud/onedrive/onedrivetokenrefresher.h
index d190bc4666..b4473798cd 100644
--- a/backends/cloud/onedrive/onedrivetokenrefresher.h
+++ b/backends/cloud/onedrive/onedrivetokenrefresher.h
@@ -38,6 +38,7 @@ class OneDriveTokenRefresher: public Networking::CurlJsonRequest {
void tokenRefreshed(Storage::BoolResponse response);
virtual void finishJson(Common::JSONValue *json);
+ virtual void finishError(Networking::ErrorResponse error);
public:
OneDriveTokenRefresher(OneDriveStorage *parent, Networking::JsonCallback callback, Networking::ErrorCallback ecb, const char *url);
virtual ~OneDriveTokenRefresher();
diff --git a/backends/cloud/onedrive/onedriveuploadrequest.cpp b/backends/cloud/onedrive/onedriveuploadrequest.cpp
index ebf387fca2..85e0525069 100644
--- a/backends/cloud/onedrive/onedriveuploadrequest.cpp
+++ b/backends/cloud/onedrive/onedriveuploadrequest.cpp
@@ -33,8 +33,8 @@
namespace Cloud {
namespace OneDrive {
-#define ONEDRIVE_API_SPECIAL_APPROOT_UPLOAD "https://api.onedrive.com/v1.0/drive/special/approot:/%s:/upload.createSession"
-#define ONEDRIVE_API_SPECIAL_APPROOT_CONTENT "https://api.onedrive.com/v1.0/drive/special/approot:/%s:/content"
+#define ONEDRIVE_API_SPECIAL_APPROOT_UPLOAD "https://graph.microsoft.com/v1.0/drive/special/approot:/%s:/upload.createSession"
+#define ONEDRIVE_API_SPECIAL_APPROOT_CONTENT "https://graph.microsoft.com/v1.0/drive/special/approot:/%s:/content"
OneDriveUploadRequest::OneDriveUploadRequest(OneDriveStorage *storage, Common::String path, Common::SeekableReadStream *contents, Storage::UploadCallback callback, Networking::ErrorCallback ecb):
Networking::Request(nullptr, ecb), _storage(storage), _savePath(path), _contentsStream(contents), _uploadCallback(callback),
diff --git a/backends/cloud/savessyncrequest.cpp b/backends/cloud/savessyncrequest.cpp
index f9b16b355b..00cc814a50 100644
--- a/backends/cloud/savessyncrequest.cpp
+++ b/backends/cloud/savessyncrequest.cpp
@@ -126,11 +126,11 @@ void SavesSyncRequest::directoryListedCallback(Storage::ListDirectoryResponse re
_filesToUpload.push_back(i->_key);
}
- debug(9, "\nSavesSyncRequest: download files:");
+ debug(9, (_filesToDownload.size() > 0 ? "\nSavesSyncRequest: download files:" : "\nSavesSyncRequest: nothing to download"));
for (uint32 i = 0; i < _filesToDownload.size(); ++i) {
debug(9, "%s", _filesToDownload[i].name().c_str());
}
- debug(9, "\nSavesSyncRequest: upload files:");
+ debug(9, (_filesToUpload.size() > 0 ? "\nSavesSyncRequest: upload files:" : "\nSavesSyncRequest: nothing to upload"));
for (uint32 i = 0; i < _filesToUpload.size(); ++i) {
debug(9, "%s", _filesToUpload[i].c_str());
}
@@ -145,9 +145,22 @@ void SavesSyncRequest::directoryListedErrorCallback(Networking::ErrorResponse er
if (_ignoreCallback)
return;
+ if (error.failed) debug(9, "%s", error.response.c_str());
+
bool irrecoverable = error.interrupted || error.failed;
if (error.failed) {
Common::JSONValue *value = Common::JSON::parse(error.response.c_str());
+
+ // somehow OneDrive returns JSON with '.' in unexpected places, try fixing it
+ if (!value) {
+ Common::String fixedResponse = error.response;
+ for (uint32 i = 0; i < fixedResponse.size(); ++i) {
+ if (fixedResponse[i] == '.')
+ fixedResponse.replace(i, 1, " ");
+ }
+ value = Common::JSON::parse(fixedResponse.c_str());
+ }
+
if (value) {
if (value->isObject()) {
Common::JSONObject object = value->asObject();
@@ -174,11 +187,13 @@ void SavesSyncRequest::directoryListedErrorCallback(Networking::ErrorResponse er
delete value;
}
- //Google Drive and Box-related ScummVM-based error
+ //Google Drive, Box and OneDrive-related ScummVM-based error
if (error.response.contains("subdirectory not found")) {
irrecoverable = false; //base "/ScummVM/" folder not found
} else if (error.response.contains("no such file found in its parent directory")) {
irrecoverable = false; //"Saves" folder within "/ScummVM/" not found
+ } else if (error.response.contains("itemNotFound") && error.response.contains("Item does not exist")) {
+ irrecoverable = false; //"saves" folder within application folder is not found
}
}