CLOUD: Update OneDrive

Added JSON checks.

New jsonContainsObject() method added to CurlJsonRequest.
This commit is contained in:
Alexander Tkachev 2016-07-26 14:53:44 +06:00
parent d34b9b91ad
commit fc8e29d583
5 changed files with 83 additions and 22 deletions

View File

@ -93,7 +93,7 @@ void GoogleDriveStorage::getAccessToken(BoolCallback callback, Networking::Error
Networking::JsonCallback innerCallback = new Common::CallbackBridge<GoogleDriveStorage, BoolResponse, Networking::JsonResponse>(this, &GoogleDriveStorage::tokenRefreshed, callback);
if (errorCallback == nullptr)
errorCallback = getErrorPrintingCallback();
Networking::CurlJsonRequest *request = new Networking::CurlJsonRequest(innerCallback, errorCallback, GOOGLEDRIVE_OAUTH2_TOKEN); //TODO
Networking::CurlJsonRequest *request = new Networking::CurlJsonRequest(innerCallback, errorCallback, GOOGLEDRIVE_OAUTH2_TOKEN);
if (codeFlow) {
request->addPostField("code=" + code);
request->addPostField("grant_type=authorization_code");

View File

@ -101,12 +101,19 @@ void OneDriveCreateDirectoryRequest::responseCallback(Networking::JsonResponse r
if (rq && rq->getNetworkReadStream())
error.httpResponseCode = rq->getNetworkReadStream()->httpResponseCode();
if (!json) {
warning("OneDriveCreateDirectoryRequest: NULL passed instead of JSON");
if (json == nullptr) {
error.response = "Failed to parse JSON, null passed!";
finishError(error);
return;
}
if (!json->isObject()) {
error.response = "Passed JSON is not an object!";
finishError(error);
delete json;
return;
}
Common::JSONObject info = json->asObject();
if (info.contains("id")) {
finishCreation(true);

View File

@ -116,12 +116,24 @@ void OneDriveStorage::tokenRefreshed(BoolCallback callback, Networking::JsonResp
Common::JSONValue *json = response.value;
if (!json) {
warning("OneDriveStorage: got NULL instead of JSON");
if (callback) (*callback)(BoolResponse(nullptr, false));
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 (!result.contains("access_token") || !result.contains("user_id") || !result.contains("refresh_token")) {
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)
@ -135,6 +147,7 @@ void OneDriveStorage::tokenRefreshed(BoolCallback callback, Networking::JsonResp
(*callback)(BoolResponse(nullptr, true));
}
delete json;
delete callback;
}
void OneDriveStorage::codeFlowComplete(BoolResponse response) {
@ -168,7 +181,13 @@ Common::String OneDriveStorage::name() const {
void OneDriveStorage::infoInnerCallback(StorageInfoCallback outerCallback, Networking::JsonResponse response) {
Common::JSONValue *json = response.value;
if (!json) {
warning("OneDriveStorage: NULL passed instead of JSON");
warning("OneDriveStorage::infoInnerCallback: NULL passed instead of JSON");
delete outerCallback;
return;
}
if (!Networking::CurlJsonRequest::jsonIsObject(json, "OneDriveStorage::infoInnerCallback")) {
delete json;
delete outerCallback;
return;
}
@ -178,16 +197,18 @@ void OneDriveStorage::infoInnerCallback(StorageInfoCallback outerCallback, Netwo
Common::String uid, name, email;
uint64 quotaUsed = 0, quotaAllocated = 26843545600L; // 25 GB, because I actually don't know any way to find out the real one
if (info.contains("createdBy") && info.getVal("createdBy")->isObject()) {
if (Networking::CurlJsonRequest::jsonContainsObject(info, "createdBy", "OneDriveStorage::infoInnerCallback")) {
Common::JSONObject createdBy = info.getVal("createdBy")->asObject();
if (createdBy.contains("user") && createdBy.getVal("user")->isObject()) {
if (Networking::CurlJsonRequest::jsonContainsObject(createdBy, "user", "OneDriveStorage::infoInnerCallback")) {
Common::JSONObject user = createdBy.getVal("user")->asObject();
uid = user.getVal("id")->asString();
name = user.getVal("displayName")->asString();
if (Networking::CurlJsonRequest::jsonContainsString(user, "id", "OneDriveStorage::infoInnerCallback"))
uid = user.getVal("id")->asString();
if (Networking::CurlJsonRequest::jsonContainsString(user, "displayName", "OneDriveStorage::infoInnerCallback"))
name = user.getVal("displayName")->asString();
}
}
if (info.contains("size") && info.getVal("size")->isIntegerNumber()) {
if (Networking::CurlJsonRequest::jsonContainsIntegerNumber(info, "size", "OneDriveStorage::infoInnerCallback")) {
quotaUsed = info.getVal("size")->asIntegerNumber();
}
@ -207,28 +228,43 @@ void OneDriveStorage::infoInnerCallback(StorageInfoCallback outerCallback, Netwo
}
void OneDriveStorage::fileInfoCallback(Networking::NetworkReadStreamCallback outerCallback, Networking::JsonResponse response) {
if (!response.value) {
warning("OneDriveStorage::fileInfoCallback: NULL, not JSON");
Common::JSONValue *json = response.value;
if (!json) {
warning("OneDriveStorage::fileInfoCallback: NULL passed instead of JSON");
if (outerCallback)
(*outerCallback)(Networking::NetworkReadStreamResponse(response.request, nullptr));
delete outerCallback;
return;
}
if (!Networking::CurlJsonRequest::jsonIsObject(json, "OneDriveStorage::fileInfoCallback")) {
if (outerCallback)
(*outerCallback)(Networking::NetworkReadStreamResponse(response.request, nullptr));
delete json;
delete outerCallback;
return;
}
Common::JSONObject result = response.value->asObject();
if (result.contains("@content.downloadUrl")) {
const char *url = result.getVal("@content.downloadUrl")->asString().c_str();
if (outerCallback)
(*outerCallback)(Networking::NetworkReadStreamResponse(
response.request,
new Networking::NetworkReadStream(url, nullptr, "")
));
} else {
if (!Networking::CurlJsonRequest::jsonContainsString(result, "@content.downloadUrl", "OneDriveStorage::fileInfoCallback")) {
warning("OneDriveStorage: downloadUrl not found in passed JSON");
debug(9, "%s", response.value->stringify().c_str());
if (outerCallback)
(*outerCallback)(Networking::NetworkReadStreamResponse(response.request, nullptr));
delete json;
delete outerCallback;
return;
}
delete response.value;
const char *url = result.getVal("@content.downloadUrl")->asString().c_str();
if (outerCallback)
(*outerCallback)(Networking::NetworkReadStreamResponse(
response.request,
new Networking::NetworkReadStream(url, nullptr, "")
));
delete json;
delete outerCallback;
}
Networking::Request *OneDriveStorage::listDirectory(Common::String path, ListDirectoryCallback callback, Networking::ErrorCallback errorCallback, bool recursive) {

View File

@ -114,6 +114,23 @@ bool CurlJsonRequest::jsonIsObject(Common::JSONValue *item, const char *warningP
return false;
}
bool CurlJsonRequest::jsonContainsObject(Common::JSONObject &item, const char *key, const char *warningPrefix, bool isOptional) {
if (!item.contains(key)) {
if (isOptional) {
return true;
}
warning("%s: passed item misses the \"%s\" attribute!", warningPrefix, key);
return false;
}
if (item.getVal(key)->isObject()) return true;
warning("%s: passed item's \"%s\" attribute is not an object!", warningPrefix, key);
debug(9, "%s", item.getVal(key)->stringify(true).c_str());
return false;
}
bool CurlJsonRequest::jsonContainsString(Common::JSONObject &item, const char *key, const char *warningPrefix, bool isOptional) {
if (!item.contains(key)) {
if (isOptional) {

View File

@ -54,6 +54,7 @@ public:
virtual void restart();
static bool jsonIsObject(Common::JSONValue *item, const char *warningPrefix);
static bool jsonContainsObject(Common::JSONObject &item, const char *key, const char *warningPrefix, bool isOptional = false);
static bool jsonContainsString(Common::JSONObject &item, const char *key, const char *warningPrefix, bool isOptional = false);
static bool jsonContainsIntegerNumber(Common::JSONObject &item, const char *key, const char *warningPrefix, bool isOptional = false);
static bool jsonContainsArray(Common::JSONObject &item, const char *key, const char *warningPrefix, bool isOptional = false);