From 4919a582465fb2e7e7bfd746156d5a543ba6398e Mon Sep 17 00:00:00 2001 From: abraunegg Date: Thu, 13 Sep 2018 08:41:46 +1000 Subject: [PATCH] Resolve File download fails if the file is marked as malware in OneDrive (Issue #153) (#155) * Gracefully handle the situation where OneDrive has marked a file as malware and will not provide the file for download --- src/onedrive.d | 4 ++-- src/sync.d | 39 ++++++++++++++++++++++++++++++++------- 2 files changed, 34 insertions(+), 9 deletions(-) diff --git a/src/onedrive.d b/src/onedrive.d index 296d7ffa..cf4f2ddf 100644 --- a/src/onedrive.d +++ b/src/onedrive.d @@ -206,13 +206,13 @@ final class OneDriveApi // Return the requested details of the specified id // https://docs.microsoft.com/en-us/onedrive/developer/rest-api/api/driveitem_get - JSONValue getFileSize(const(char)[] driveId, const(char)[] id) + JSONValue getFileDetails(const(char)[] driveId, const(char)[] id) { checkAccessTokenExpired(); const(char)[] url; // string driveByIdUrl = "https://graph.microsoft.com/v1.0/drives/"; url = driveByIdUrl ~ driveId ~ "/items/" ~ id; - url ~= "?select=size"; + url ~= "?select=size,malware"; return get(url); } diff --git a/src/sync.d b/src/sync.d index 67fb5742..a0e1021a 100644 --- a/src/sync.d +++ b/src/sync.d @@ -45,6 +45,11 @@ private bool changeHasParentReferenceId(const ref JSONValue item) return ("id" in item["parentReference"]) != null; } +private bool isMalware(const ref JSONValue item) +{ + return ("malware" in item) != null; +} + // construct an Item struct from a JSON driveItem private Item makeItem(const ref JSONValue driveItem) { @@ -147,6 +152,8 @@ final class SyncEngine private string accountType; // free space remaining at init() private long remainingFreeSpace; + // is file malware flag + private bool malwareDetected = false; this(Config cfg, OneDriveApi onedrive, ItemDatabase itemdb, SelectiveSync selectiveSync) { @@ -488,6 +495,9 @@ final class SyncEngine { Item item = makeItem(driveItem); + // Reset the malwareDetected flag for this item + malwareDetected = false; + if (isItemRoot(driveItem) || !item.parentId || isRoot) { item.parentId = null; // ensures that it has no parent item.driveId = driveId; // HACK: makeItem() cannot set the driveId property of the root @@ -574,11 +584,14 @@ final class SyncEngine applyNewItem(item, path); } - // save the item in the db - if (cached) { - itemdb.update(item); - } else { - itemdb.insert(item); + if (malwareDetected == false){ + // save the item in the db + // if the file was detected as malware and NOT downloaded, we dont want to falsify the DB as downloading it as otherwise the next pass will think it was deleted, thus delete the remote item + if (cached) { + itemdb.update(item); + } else { + itemdb.insert(item); + } } } @@ -649,8 +662,20 @@ final class SyncEngine { assert(item.type == ItemType.file); write("Downloading file ", path, " ... "); - JSONValue fileSizeDetails = onedrive.getFileSize(item.driveId, item.id); - auto fileSize = fileSizeDetails["size"].integer; + JSONValue fileDetails = onedrive.getFileDetails(item.driveId, item.id); + + // Issue #153 Debugging + //log.log("File Details: ", fileDetails); + + if (isMalware(fileDetails)){ + // OneDrive reports that this file is malware + log.error("ERROR: MALWARE DETECTED IN FILE - DOWNLOAD SKIPPED"); + // set global flag + malwareDetected = true; + return; + } + + auto fileSize = fileDetails["size"].integer; try { onedrive.downloadById(item.driveId, item.id, path, fileSize); } catch (OneDriveException e) {