aboutsummaryrefslogtreecommitdiff
path: root/backends/cloud/onedrive/onedrivetokenrefresher.cpp
diff options
context:
space:
mode:
authorAlexander Tkachev2016-05-26 21:40:01 +0600
committerAlexander Tkachev2016-08-24 16:07:55 +0600
commit8f6bcdf55da97db98384c2a8cb9dcdf34232ac35 (patch)
treea1ec4f773c2891cf432f05af2461ca161959a017 /backends/cloud/onedrive/onedrivetokenrefresher.cpp
parentb246c17850687e7b15b644b761fbfe835ffc1c32 (diff)
downloadscummvm-rg350-8f6bcdf55da97db98384c2a8cb9dcdf34232ac35.tar.gz
scummvm-rg350-8f6bcdf55da97db98384c2a8cb9dcdf34232ac35.tar.bz2
scummvm-rg350-8f6bcdf55da97db98384c2a8cb9dcdf34232ac35.zip
CLOUD: Add OneDriveTokenRefresher
OneDriveTokenRefresher is a CurlJsonRequest replacement for OneDriveStorage methods. It behaves very similarly, but checks received JSON before passing it to user. If it contains "error" key, it attempts to refresh the token through OneDriveStorage, and then restarts the original request, so user won't notice that there ever was an error.
Diffstat (limited to 'backends/cloud/onedrive/onedrivetokenrefresher.cpp')
-rw-r--r--backends/cloud/onedrive/onedrivetokenrefresher.cpp124
1 files changed, 124 insertions, 0 deletions
diff --git a/backends/cloud/onedrive/onedrivetokenrefresher.cpp b/backends/cloud/onedrive/onedrivetokenrefresher.cpp
new file mode 100644
index 0000000000..5e72717740
--- /dev/null
+++ b/backends/cloud/onedrive/onedrivetokenrefresher.cpp
@@ -0,0 +1,124 @@
+/* ScummVM - Graphic Adventure Engine
+*
+* ScummVM is the legal property of its developers, whose names
+* are too numerous to list here. Please refer to the COPYRIGHT
+* file distributed with this source distribution.
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* as published by the Free Software Foundation; either version 2
+* of the License, or (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*/
+#define FORBIDDEN_SYMBOL_ALLOW_ALL
+
+#include "backends/cloud/onedrive/onedrivetokenrefresher.h"
+#include "backends/cloud/onedrive/onedrivestorage.h"
+#include "backends/networking/curl/connectionmanager.h"
+#include "backends/networking/curl/curljsonrequest.h"
+#include "common/config-manager.h"
+#include "common/debug.h"
+#include "common/json.h"
+#include <curl/curl.h>
+
+namespace Cloud {
+namespace OneDrive {
+
+OneDriveTokenRefresher::OneDriveTokenRefresher(OneDriveStorage *parent, Networking::JsonCallback callback, const char *url):
+ CurlJsonRequest(0, url),
+ _parentStorage(parent),
+ _innerRequest(
+ new CurlJsonRequest(
+ new Common::Callback<OneDriveTokenRefresher, Networking::RequestJsonPair>(this, &OneDriveTokenRefresher::innerRequestCallback),
+ url
+ )
+ ), _jsonCallback(callback), _retryId(-1), _started(false) {}
+
+OneDriveTokenRefresher::~OneDriveTokenRefresher() {}
+
+void OneDriveTokenRefresher::innerRequestCallback(Networking::RequestJsonPair pair) {
+ if (!pair.value) {
+ //notify user of failure
+ warning("OneDriveTokenRefresher: got NULL instead of JSON");
+ ConnMan.getRequestInfo(_id).state = Networking::FINISHED;
+ if (_jsonCallback) (*_jsonCallback)(Networking::RequestJsonPair(_id, 0));
+ return;
+ }
+
+ Common::JSONObject result = pair.value->asObject();
+ if (result.contains("error")) {
+ //new token needed => request token & then retry original request
+ ConnMan.getRequestInfo(pair.id).state = Networking::PAUSED;
+ _retryId = pair.id;
+ delete pair.value;
+ _parentStorage->getAccessToken(new Common::Callback<OneDriveTokenRefresher, Storage::RequestBoolPair>(this, &OneDriveTokenRefresher::tokenRefreshed));
+ return;
+ }
+
+ //notify user of success
+ ConnMan.getRequestInfo(_id).state = Networking::FINISHED;
+ if (_jsonCallback) (*_jsonCallback)(Networking::RequestJsonPair(_id, pair.value));
+}
+
+void OneDriveTokenRefresher::tokenRefreshed(Storage::RequestBoolPair pair) {
+ if (!pair.value) {
+ //failed to refresh token, notify user with NULL in original callback
+ warning("OneDriveTokenRefresher: failed to refresh token");
+ ConnMan.getRequestInfo(_id).state = Networking::FINISHED;
+ if (_jsonCallback) (*_jsonCallback)(Networking::RequestJsonPair(_id, 0));
+ return;
+ }
+
+ //successfully received refreshed token, can restart the original request now
+ Networking::RequestInfo &info = ConnMan.getRequestInfo(_retryId);
+ info.state = Networking::RETRY;
+ info.retryInSeconds = 1;
+
+ //update headers: first change header with token, then pass those to request
+ for (uint32 i = 0; i < _headers.size(); ++i) {
+ if (_headers[i].contains("Authorization: bearer ")) {
+ _headers[i] = "Authorization: bearer " + _parentStorage->accessToken();
+ }
+ }
+ CurlJsonRequest *retryRequest = (CurlJsonRequest *)info.request;
+ if (retryRequest) retryRequest->setHeaders(_headers);
+}
+
+void OneDriveTokenRefresher::handle() {
+ if (!_started) {
+ for (uint32 i = 0; i < _headers.size(); ++i)
+ _innerRequest->addHeader(_headers[i]);
+ _started = true;
+ ConnMan.addRequest(_innerRequest);
+ }
+}
+
+void OneDriveTokenRefresher::restart() {
+ //can't restart as all headers were passed to _innerRequest which is probably dead now
+ warning("OneDriveTokenRefresher: cannot be restarted");
+ ConnMan.getRequestInfo(_id).state = Networking::FINISHED;
+ if (_jsonCallback) (*_jsonCallback)(Networking::RequestJsonPair(_id, 0));
+}
+
+Networking::NetworkReadStream *OneDriveTokenRefresher::execute() {
+ if (!_started) {
+ for (uint32 i = 0; i < _headers.size(); ++i)
+ _innerRequest->addHeader(_headers[i]);
+ _started = true;
+ } else {
+ warning("OneDriveTokenRefresher: inner Request is already started");
+ }
+ return _innerRequest->execute();
+}
+
+} //end of namespace OneDrive
+} //end of namespace Cloud