diff options
author | Alexander Tkachev | 2019-07-16 14:12:45 +0700 |
---|---|---|
committer | Matan Bareket | 2019-07-30 14:51:41 -0400 |
commit | edbea10c2e5606daec18c148c8b103649d1011c5 (patch) | |
tree | 0579a22dd3ce399c28a8a2d6ab93e7a80f5fc3a3 /backends/cloud | |
parent | e8669f693c6adbb33f515d9a4ce9d1079756e2e8 (diff) | |
download | scummvm-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.
Diffstat (limited to 'backends/cloud')
-rw-r--r-- | backends/cloud/onedrive/onedrivecreatedirectoryrequest.cpp | 2 | ||||
-rw-r--r-- | backends/cloud/onedrive/onedrivelistdirectoryrequest.cpp | 6 | ||||
-rw-r--r-- | backends/cloud/onedrive/onedrivestorage.cpp | 15 | ||||
-rw-r--r-- | backends/cloud/onedrive/onedrivetokenrefresher.cpp | 26 | ||||
-rw-r--r-- | backends/cloud/onedrive/onedrivetokenrefresher.h | 1 | ||||
-rw-r--r-- | backends/cloud/onedrive/onedriveuploadrequest.cpp | 4 | ||||
-rw-r--r-- | backends/cloud/savessyncrequest.cpp | 21 |
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 } } |