Catch a 403 Forbidden exception when querying Sharepoint Library Names (#620)

* Catch a 403 Forbidden exception when attempting to query for an Office 365 Shared Library Name
* Validate that the returned response is a valid JSON object
* Update scopes as per https://github.com/OneDrive/onedrive-api-docs/issues/1119
* Update that if a 403 error is received, what is the right course of action to take
This commit is contained in:
abraunegg 2019-08-09 18:14:10 +10:00 committed by GitHub
parent 92c4c81bf8
commit 893e235151
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 86 additions and 23 deletions

View file

@ -166,7 +166,7 @@ final class OneDriveApi
{
import std.stdio, std.regex;
char[] response;
string url = authUrl ~ "?client_id=" ~ clientId ~ "&scope=files.readwrite%20files.readwrite.all%20offline_access&response_type=code&redirect_uri=" ~ redirectUrl;
string url = authUrl ~ "?client_id=" ~ clientId ~ "&scope=Files.ReadWrite%20Files.ReadWrite.all%20Sites.ReadWrite.All%20offline_access&response_type=code&redirect_uri=" ~ redirectUrl;
string authFilesString = cfg.getValueString("auth_files");
if (authFilesString == "") {
log.log("Authorize this app visiting:\n");
@ -702,9 +702,15 @@ final class OneDriveApi
case 400:
// Bad Request .. how should we act?
log.vlog("OneDrive returned a 'HTTP 400 - Bad Request' - gracefully handling error");
break;
break;
// Item not found
// 403 - Forbidden
case 403:
// OneDrive responded that the user is forbidden
log.vlog("OneDrive returned a 'HTTP 403 - Forbidden' - gracefully handling error");
break;
// 404 - Item not found
case 404:
// Item was not found - do not throw an exception
log.vlog("OneDrive returned a 'HTTP 404 - Item not found' - gracefully handling error");
@ -774,12 +780,19 @@ final class OneDriveApi
case 400:
// Bad Request .. how should we act?
log.vlog("OneDrive returned a 'HTTP 400 - Bad Request' - gracefully handling error");
break;
break;
// 403 - Forbidden
case 403:
// OneDrive responded that the user is forbidden
log.vlog("OneDrive returned a 'HTTP 403 - Forbidden' - gracefully handling error");
// Throw this as a specific exception so this is caught when performing sync.o365SiteSearch
throw new OneDriveException(http.statusLine.code, http.statusLine.reason, response);
// 412 - Precondition Failed
case 412:
log.vlog("OneDrive returned a 'HTTP 412 - Precondition Failed' - gracefully handling error");
// Throw this as a specific exception so this is caught when performing uploadLastModifiedTime
// Throw this as a specific exception so this is caught when performing sync.uploadLastModifiedTime
throw new OneDriveException(http.statusLine.code, http.statusLine.reason, response);
// Server side (OneDrive) Errors

View file

@ -2608,30 +2608,80 @@ final class SyncEngine
string drive_id;
string webUrl;
bool found = false;
JSONValue siteQuery = onedrive.o365SiteSearch(encodeComponent(o365SharedLibraryName));
JSONValue siteQuery;
log.log("Office 365 Library Name Query: ", o365SharedLibraryName);
foreach (searchResult; siteQuery["value"].array) {
// Need an 'exclusive' match here with o365SharedLibraryName as entered
log.vdebug("Found O365 Site: ", searchResult);
if (o365SharedLibraryName == searchResult["displayName"].str){
// 'displayName' matches search request
site_id = searchResult["id"].str;
webUrl = searchResult["webUrl"].str;
JSONValue siteDriveQuery = onedrive.o365SiteDrives(site_id);
foreach (driveResult; siteDriveQuery["value"].array) {
// Display results
found = true;
writeln("SiteName: ", searchResult["displayName"].str);
writeln("drive_id: ", driveResult["id"].str);
writeln("URL: ", webUrl);
}
try {
siteQuery = onedrive.o365SiteSearch(encodeComponent(o365SharedLibraryName));
} catch (OneDriveException e) {
log.error("ERROR: Query of OneDrive for Office 365 Library Name failed");
if (e.httpStatusCode == 403) {
// Forbidden - most likely authentication scope needs to be updated
log.error("ERROR: Authentication scope needs to be updated. Use --logout and re-authenticate client.");
return;
} else {
// display what the error is
auto errorArray = splitLines(e.msg);
log.error("Error Message: ", errorArray[0]);
// extract 'message' as the reason
JSONValue errorMessage = parseJSON(replace(e.msg, errorArray[0], ""));
log.error("Error Reason: ", errorMessage["error"]["message"].str);
return;
}
}
if(!found) {
writeln("ERROR: This site could not be found. Please check it's name and your permissions to access the site.");
// is siteQuery a valid JSON object & contain data we can use?
if ((siteQuery.type() == JSONType.object) && ("value" in siteQuery)) {
// valid JSON object
foreach (searchResult; siteQuery["value"].array) {
// Need an 'exclusive' match here with o365SharedLibraryName as entered
log.vdebug("Found O365 Site: ", searchResult);
if (o365SharedLibraryName == searchResult["displayName"].str){
// 'displayName' matches search request
site_id = searchResult["id"].str;
webUrl = searchResult["webUrl"].str;
JSONValue siteDriveQuery;
try {
siteDriveQuery = onedrive.o365SiteDrives(site_id);
} catch (OneDriveException e) {
log.error("ERROR: Query of OneDrive for Office Site ID failed");
auto errorArray = splitLines(e.msg);
log.error("Error Message: ", errorArray[0]);
// extract 'message' as the reason
JSONValue errorMessage = parseJSON(replace(e.msg, errorArray[0], ""));
log.error("Error Reason: ", errorMessage["error"]["message"].str);
return;
}
// is siteDriveQuery a valid JSON object & contain data we can use?
if ((siteDriveQuery.type() == JSONType.object) && ("value" in siteDriveQuery)) {
// valid JSON object
foreach (driveResult; siteDriveQuery["value"].array) {
// Display results
found = true;
writeln("SiteName: ", searchResult["displayName"].str);
writeln("drive_id: ", driveResult["id"].str);
writeln("URL: ", webUrl);
}
} else {
// not a valid JSON object
log.error("ERROR: There was an error performing this operation on OneDrive");
log.error("ERROR: Increase logging verbosity to assist determining why.");
return;
}
}
}
if(!found) {
log.error("ERROR: This site could not be found. Please check it's name and your permissions to access the site.");
}
} else {
// not a valid JSON object
log.error("ERROR: There was an error performing this operation on OneDrive");
log.error("ERROR: Increase logging verbosity to assist determining why.");
return;
}
}