ResidualVM logo ResidualVM website - Forums - Contact us BuildBot - Doxygen - Wiki curved edge

onedrivestorage.cpp

Go to the documentation of this file.
00001 /* ScummVM - Graphic Adventure Engine
00002  *
00003  * ScummVM is the legal property of its developers, whose names
00004  * are too numerous to list here. Please refer to the COPYRIGHT
00005  * file distributed with this source distribution.
00006  *
00007  * This program is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU General Public License
00009  * as published by the Free Software Foundation; either version 2
00010  * of the License, or (at your option) any later version.
00011  *
00012  * This program is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00020  *
00021  */
00022 
00023 #define FORBIDDEN_SYMBOL_ALLOW_ALL
00024 
00025 #include <curl/curl.h>
00026 #include "backends/cloud/onedrive/onedrivestorage.h"
00027 #include "backends/cloud/cloudmanager.h"
00028 #include "backends/cloud/onedrive/onedrivecreatedirectoryrequest.h"
00029 #include "backends/cloud/onedrive/onedrivetokenrefresher.h"
00030 #include "backends/cloud/onedrive/onedrivelistdirectoryrequest.h"
00031 #include "backends/cloud/onedrive/onedriveuploadrequest.h"
00032 #include "backends/networking/curl/connectionmanager.h"
00033 #include "backends/networking/curl/curljsonrequest.h"
00034 #include "backends/networking/curl/networkreadstream.h"
00035 #include "common/config-manager.h"
00036 #include "common/debug.h"
00037 #include "common/json.h"
00038 
00039 namespace Cloud {
00040 namespace OneDrive {
00041 
00042 #define ONEDRIVE_API_SPECIAL_APPROOT_ID "https://graph.microsoft.com/v1.0/drive/special/approot:/"
00043 #define ONEDRIVE_API_SPECIAL_APPROOT "https://graph.microsoft.com/v1.0/drive/special/approot"
00044 
00045 OneDriveStorage::OneDriveStorage(Common::String token, Common::String refreshToken, bool enabled):
00046     BaseStorage(token, refreshToken, enabled) {}
00047 
00048 OneDriveStorage::OneDriveStorage(Common::String code, Networking::ErrorCallback cb) {
00049     getAccessToken(code, cb);
00050 }
00051 
00052 OneDriveStorage::~OneDriveStorage() {}
00053 
00054 Common::String OneDriveStorage::cloudProvider() { return "onedrive"; }
00055 
00056 uint32 OneDriveStorage::storageIndex() { return kStorageOneDriveId; }
00057 
00058 bool OneDriveStorage::needsRefreshToken() { return true; }
00059 
00060 bool OneDriveStorage::canReuseRefreshToken() { return false; }
00061 
00062 void OneDriveStorage::saveConfig(Common::String keyPrefix) {
00063     ConfMan.set(keyPrefix + "access_token", _token, ConfMan.kCloudDomain);
00064     ConfMan.set(keyPrefix + "refresh_token", _refreshToken, ConfMan.kCloudDomain);
00065     saveIsEnabledFlag(keyPrefix);
00066 }
00067 
00068 Common::String OneDriveStorage::name() const {
00069     return "OneDrive";
00070 }
00071 
00072 void OneDriveStorage::infoInnerCallback(StorageInfoCallback outerCallback, Networking::JsonResponse response) {
00073     Common::JSONValue *json = response.value;
00074     if (!json) {
00075         warning("OneDriveStorage::infoInnerCallback: NULL passed instead of JSON");
00076         delete outerCallback;
00077         return;
00078     }
00079 
00080     if (!Networking::CurlJsonRequest::jsonIsObject(json, "OneDriveStorage::infoInnerCallback")) {
00081         delete json;
00082         delete outerCallback;
00083         return;
00084     }
00085 
00086     Common::JSONObject jsonInfo = json->asObject();
00087 
00088     Common::String uid, displayName, email;
00089     uint64 quotaUsed = 0, quotaAllocated = 26843545600LL; // 25 GB, because I actually don't know any way to find out the real one
00090 
00091     if (Networking::CurlJsonRequest::jsonContainsObject(jsonInfo, "createdBy", "OneDriveStorage::infoInnerCallback")) {
00092         Common::JSONObject createdBy = jsonInfo.getVal("createdBy")->asObject();
00093         if (Networking::CurlJsonRequest::jsonContainsObject(createdBy, "user", "OneDriveStorage::infoInnerCallback")) {
00094             Common::JSONObject user = createdBy.getVal("user")->asObject();
00095             if (Networking::CurlJsonRequest::jsonContainsString(user, "id", "OneDriveStorage::infoInnerCallback"))
00096                 uid = user.getVal("id")->asString();
00097             if (Networking::CurlJsonRequest::jsonContainsString(user, "displayName", "OneDriveStorage::infoInnerCallback"))
00098                 displayName = user.getVal("displayName")->asString();
00099         }
00100     }
00101 
00102     if (Networking::CurlJsonRequest::jsonContainsIntegerNumber(jsonInfo, "size", "OneDriveStorage::infoInnerCallback")) {
00103         quotaUsed = jsonInfo.getVal("size")->asIntegerNumber();
00104     }
00105 
00106     Common::String username = email;
00107     if (username == "")
00108         username = displayName;
00109     if (username == "")
00110         username = uid;
00111     CloudMan.setStorageUsername(kStorageOneDriveId, username);
00112 
00113     if (outerCallback) {
00114         (*outerCallback)(StorageInfoResponse(nullptr, StorageInfo(uid, displayName, email, quotaUsed, quotaAllocated)));
00115         delete outerCallback;
00116     }
00117 
00118     delete json;
00119 }
00120 
00121 void OneDriveStorage::fileInfoCallback(Networking::NetworkReadStreamCallback outerCallback, Networking::JsonResponse response) {
00122     Common::JSONValue *json = response.value;
00123     if (!json) {
00124         warning("OneDriveStorage::fileInfoCallback: NULL passed instead of JSON");
00125         if (outerCallback)
00126             (*outerCallback)(Networking::NetworkReadStreamResponse(response.request, nullptr));
00127         delete outerCallback;
00128         return;
00129     }
00130 
00131     if (!Networking::CurlJsonRequest::jsonIsObject(json, "OneDriveStorage::fileInfoCallback")) {
00132         if (outerCallback)
00133             (*outerCallback)(Networking::NetworkReadStreamResponse(response.request, nullptr));
00134         delete json;
00135         delete outerCallback;
00136         return;
00137     }
00138 
00139     Common::JSONObject result = response.value->asObject();
00140     if (!Networking::CurlJsonRequest::jsonContainsString(result, "@microsoft.graph.downloadUrl", "OneDriveStorage::fileInfoCallback")) {
00141         warning("OneDriveStorage: downloadUrl not found in passed JSON");
00142         debug(9, "%s", response.value->stringify().c_str());
00143         if (outerCallback)
00144             (*outerCallback)(Networking::NetworkReadStreamResponse(response.request, nullptr));
00145         delete json;
00146         delete outerCallback;
00147         return;
00148     }
00149 
00150     const char *url = result.getVal("@microsoft.graph.downloadUrl")->asString().c_str();
00151     if (outerCallback)
00152         (*outerCallback)(Networking::NetworkReadStreamResponse(
00153             response.request,
00154             new Networking::NetworkReadStream(url, nullptr, "")
00155         ));
00156 
00157     delete json;
00158     delete outerCallback;
00159 }
00160 
00161 Networking::Request *OneDriveStorage::listDirectory(Common::String path, ListDirectoryCallback callback, Networking::ErrorCallback errorCallback, bool recursive) {
00162     debug(9, "OneDrive: `ls \"%s\"`", path.c_str());
00163     return addRequest(new OneDriveListDirectoryRequest(this, path, callback, errorCallback, recursive));
00164 }
00165 
00166 Networking::Request *OneDriveStorage::upload(Common::String path, Common::SeekableReadStream *contents, UploadCallback callback, Networking::ErrorCallback errorCallback) {
00167     debug(9, "OneDrive: `upload \"%s\"`", path.c_str());
00168     return addRequest(new OneDriveUploadRequest(this, path, contents, callback, errorCallback));
00169 }
00170 
00171 Networking::Request *OneDriveStorage::streamFileById(Common::String path, Networking::NetworkReadStreamCallback outerCallback, Networking::ErrorCallback errorCallback) {
00172     debug(9, "OneDrive: `download \"%s\"`", path.c_str());
00173     Common::String url = ONEDRIVE_API_SPECIAL_APPROOT_ID + ConnMan.urlEncode(path);
00174     Networking::JsonCallback innerCallback = new Common::CallbackBridge<OneDriveStorage, Networking::NetworkReadStreamResponse, Networking::JsonResponse>(this, &OneDriveStorage::fileInfoCallback, outerCallback);
00175     Networking::CurlJsonRequest *request = new OneDriveTokenRefresher(this, innerCallback, errorCallback, url.c_str());
00176     request->addHeader("Authorization: bearer " + _token);
00177     return addRequest(request);
00178 }
00179 
00180 Networking::Request *OneDriveStorage::createDirectory(Common::String path, BoolCallback callback, Networking::ErrorCallback errorCallback) {
00181     debug(9, "OneDrive: `mkdir \"%s\"`", path.c_str());
00182     if (!errorCallback)
00183         errorCallback = getErrorPrintingCallback();
00184     return addRequest(new OneDriveCreateDirectoryRequest(this, path, callback, errorCallback));
00185 }
00186 
00187 Networking::Request *OneDriveStorage::info(StorageInfoCallback callback, Networking::ErrorCallback errorCallback) {
00188     debug(9, "OneDrive: `info`");
00189     Networking::JsonCallback innerCallback = new Common::CallbackBridge<OneDriveStorage, StorageInfoResponse, Networking::JsonResponse>(this, &OneDriveStorage::infoInnerCallback, callback);
00190     Networking::CurlJsonRequest *request = new OneDriveTokenRefresher(this, innerCallback, errorCallback, ONEDRIVE_API_SPECIAL_APPROOT);
00191     request->addHeader("Authorization: bearer " + _token);
00192     return addRequest(request);
00193 }
00194 
00195 Common::String OneDriveStorage::savesDirectoryPath() { return "saves/"; }
00196 
00197 OneDriveStorage *OneDriveStorage::loadFromConfig(Common::String keyPrefix) {
00198     if (!ConfMan.hasKey(keyPrefix + "access_token", ConfMan.kCloudDomain)) {
00199         warning("OneDriveStorage: no access_token found");
00200         return nullptr;
00201     }
00202 
00203     if (!ConfMan.hasKey(keyPrefix + "refresh_token", ConfMan.kCloudDomain)) {
00204         warning("OneDriveStorage: no refresh_token found");
00205         return nullptr;
00206     }
00207 
00208     Common::String accessToken = ConfMan.get(keyPrefix + "access_token", ConfMan.kCloudDomain);
00209     Common::String refreshToken = ConfMan.get(keyPrefix + "refresh_token", ConfMan.kCloudDomain);
00210     return new OneDriveStorage(accessToken, refreshToken, loadIsEnabledFlag(keyPrefix));
00211 }
00212 
00213 void OneDriveStorage::removeFromConfig(Common::String keyPrefix) {
00214     ConfMan.removeKey(keyPrefix + "access_token", ConfMan.kCloudDomain);
00215     ConfMan.removeKey(keyPrefix + "refresh_token", ConfMan.kCloudDomain);
00216     removeIsEnabledFlag(keyPrefix);
00217 }
00218 
00219 } // End of namespace OneDrive
00220 } // End of namespace Cloud


Generated on Sat Apr 4 2020 05:00:25 for ResidualVM by doxygen 1.7.1
curved edge   curved edge