From 2f35a33f4f87710606e83d9c357db63249c38bfa Mon Sep 17 00:00:00 2001 From: themoox Date: Mon, 5 Oct 2020 17:06:04 -0400 Subject: [PATCH] Allow config to specify a tenant id for non-multi-tenant applications (#1085) * Allow config to specify a tenant id for non-multi-tenant applications * Add instructions on how to find your O365 tenant identifier for National Cloud deployments. Co-authored-by: Ryan Brown Co-authored-by: abraunegg --- config | 1 + docs/USAGE.md | 1 + docs/national-cloud-deployments.md | 24 +++++++++++++++++++++- src/config.d | 2 ++ src/onedrive.d | 32 +++++++++++++++++++----------- src/sync.d | 4 ++-- 6 files changed, 49 insertions(+), 15 deletions(-) diff --git a/config b/config index bb3176ea..bafbd739 100644 --- a/config +++ b/config @@ -38,4 +38,5 @@ # resync = "false" # bypass_data_preservation = "false" # azure_ad_endpoint = "" +# azure_tenant_id = "common" # sync_business_shared_folders = "false" diff --git a/docs/USAGE.md b/docs/USAGE.md index bb94d63d..7dce21c8 100644 --- a/docs/USAGE.md +++ b/docs/USAGE.md @@ -298,6 +298,7 @@ The default configuration file is listed below: # resync = "false" # bypass_data_preservation = "false" # azure_ad_endpoint = "" +# azure_tenant_id = "common" # sync_business_shared_folders = "false" ``` diff --git a/docs/national-cloud-deployments.md b/docs/national-cloud-deployments.md index 2edec13c..5ce093da 100644 --- a/docs/national-cloud-deployments.md +++ b/docs/national-cloud-deployments.md @@ -51,6 +51,11 @@ A valid entry for the response URI should be one of: * https://login.microsoftonline.de/common/oauth2/nativeclient (Microsoft Cloud Germany) * https://login.chinacloudapi.cn/common/oauth2/nativeclient (Azure and Office 365 operated by 21Vianet in China) +For a single-tenant application, it may be necessary to use your specific tenant id instead of "common": +* https://login.microsoftonline.us/example.onmicrosoft.us/oauth2/nativeclient (Microsoft Cloud for US Government) +* https://login.microsoftonline.de/example.onmicrosoft.de/oauth2/nativeclient (Microsoft Cloud Germany) +* https://login.chinacloudapi.cn/example.onmicrosoft.cn/oauth2/nativeclient (Azure and Office 365 operated by 21Vianet in China) + ## Step 4: Configure the onedrive client to use new application registration Update to your 'onedrive' configuration file (`~/.config/onedrive/config`) the following: ```text @@ -64,7 +69,7 @@ This will reconfigure the client to use the new application registration you hav application_id = "22c49a0d-d21c-4792-aed1-8f163c982546" ``` -## Step 5: Confgure the onedrive client to use the specific Microsoft Azure deployment +## Step 5: Configure the onedrive client to use the specific Microsoft Azure deployment Update to your 'onedrive' configuration file (`~/.config/onedrive/config`) the following: ```text azure_ad_endpoint = "insert valid entry here" @@ -83,6 +88,23 @@ This will configure your client to use the correct Azure AD and Graph endpoints azure_ad_endpoint = "USL4" ``` +If the Microsoft Azure deployment does not support multi-tenant applications, update to your 'onedrive' configuration file (`~/.config/onedrive/config`) the following: +```text +azure_tenant_id = "insert valid entry here" +``` + +This will configure your client to use the specified tenant id in its Azure AD and Graph endpoint URIs, instead of "common". +The tenant id may be the GUID Directory ID (formatted "00000000-0000-0000-0000-000000000000"), or the fully qualified tenant name (e.g. "example.onmicrosoft.us"). +The GUID Directory ID may be located in the Azure administation page as per [https://docs.microsoft.com/en-us/onedrive/find-your-office-365-tenant-id](https://docs.microsoft.com/en-us/onedrive/find-your-office-365-tenant-id). Note that you may need to go to your national-deployment-specific administration page, rather than following the links within that document. +The tenant name may be obtained by following the PowerShell instructions on [https://docs.microsoft.com/en-us/onedrive/find-your-office-365-tenant-id](https://docs.microsoft.com/en-us/onedrive/find-your-office-365-tenant-id); it is shown as the "TenantDomain" upon completion of the "Connect-AzureAD" command. + +**Example:** +```text +azure_tenant_id = "example.onmicrosoft.us" +# or +azure_tenant_id = "0c4be462-a1ab-499b-99e0-da08ce52a2cc" +``` + ## Step 6: Authenticate the client Run the application without any additional command switches. diff --git a/src/config.d b/src/config.d index 263b714a..63f8184a 100644 --- a/src/config.d +++ b/src/config.d @@ -102,6 +102,8 @@ final class Config // AD Endpoint: https://login.chinacloudapi.cn // Graph Endpoint: https://microsoftgraph.chinacloudapi.cn stringValues["azure_ad_endpoint"] = ""; + // Support single-tenant applications that are not able to use the "common" multiplexer + stringValues["azure_tenant_id"] = "common"; // Allow enable / disable of the syncing of OneDrive Business Shared Folders via configuration file boolValues["sync_business_shared_folders"] = false; diff --git a/src/onedrive.d b/src/onedrive.d index e4c62f42..a07166fc 100644 --- a/src/onedrive.d +++ b/src/onedrive.d @@ -138,6 +138,14 @@ final class OneDriveApi .debugResponse = true; } + // Configure tenant id value, if 'azure_tenant_id' is configured, + // otherwise use the "common" multiplexer + string tenantId = "common"; + if (cfg.getValueString("azure_tenant_id") != "") { + // Use the value entered by the user + tenantId = cfg.getValueString("azure_tenant_id"); + } + // Configure Azure AD endpoints if 'azure_ad_endpoint' is configured string azureConfigValue = cfg.getValueString("azure_ad_endpoint"); switch(azureConfigValue) { @@ -147,9 +155,9 @@ final class OneDriveApi case "USL4": log.log("Configuring Azure AD for US Government Endpoints"); // Authentication - authUrl = usl4AuthEndpoint ~ "/common/oauth2/v2.0/authorize"; - redirectUrl = usl4AuthEndpoint ~ "/common/oauth2/nativeclient"; - tokenUrl = usl4AuthEndpoint ~ "/common/oauth2/v2.0/token"; + authUrl = usl4AuthEndpoint ~ "/" ~ tenantId ~ "/oauth2/v2.0/authorize"; + redirectUrl = usl4AuthEndpoint ~ "/" ~ tenantId ~ "/oauth2/nativeclient"; + tokenUrl = usl4AuthEndpoint ~ "/" ~ tenantId ~ "/oauth2/v2.0/token"; // Drive Queries driveUrl = usl4GraphEndpoint ~ "/v1.0/me/drive"; driveByIdUrl = usl4GraphEndpoint ~ "/v1.0/drives/"; @@ -165,9 +173,9 @@ final class OneDriveApi case "USL5": log.log("Configuring Azure AD for US Government Endpoints (DOD)"); // Authentication - authUrl = usl5AuthEndpoint ~ "/common/oauth2/v2.0/authorize"; - redirectUrl = usl5AuthEndpoint ~ "/common/oauth2/nativeclient"; - tokenUrl = usl5AuthEndpoint ~ "/common/oauth2/v2.0/token"; + authUrl = usl5AuthEndpoint ~ "/" ~ tenantId ~ "/oauth2/v2.0/authorize"; + redirectUrl = usl5AuthEndpoint ~ "/" ~ tenantId ~ "/oauth2/nativeclient"; + tokenUrl = usl5AuthEndpoint ~ "/" ~ tenantId ~ "/oauth2/v2.0/token"; // Drive Queries driveUrl = usl5GraphEndpoint ~ "/v1.0/me/drive"; driveByIdUrl = usl5GraphEndpoint ~ "/v1.0/drives/"; @@ -183,9 +191,9 @@ final class OneDriveApi case "DE": log.log("Configuring Azure AD Germany"); // Authentication - authUrl = deAuthEndpoint ~ "/common/oauth2/v2.0/authorize"; - redirectUrl = deAuthEndpoint ~ "/common/oauth2/nativeclient"; - tokenUrl = deAuthEndpoint ~ "/common/oauth2/v2.0/token"; + authUrl = deAuthEndpoint ~ "/" ~ tenantId ~ "/oauth2/v2.0/authorize"; + redirectUrl = deAuthEndpoint ~ "/" ~ tenantId ~ "/oauth2/nativeclient"; + tokenUrl = deAuthEndpoint ~ "/" ~ tenantId ~ "/oauth2/v2.0/token"; // Drive Queries driveUrl = deGraphEndpoint ~ "/v1.0/me/drive"; driveByIdUrl = deGraphEndpoint ~ "/v1.0/drives/"; @@ -201,9 +209,9 @@ final class OneDriveApi case "CN": log.log("Configuring AD China operated by 21Vianet"); // Authentication - authUrl = cnAuthEndpoint ~ "/common/oauth2/v2.0/authorize"; - redirectUrl = cnAuthEndpoint ~ "/common/oauth2/nativeclient"; - tokenUrl = cnAuthEndpoint ~ "/common/oauth2/v2.0/token"; + authUrl = cnAuthEndpoint ~ "/" ~ tenantId ~ "/oauth2/v2.0/authorize"; + redirectUrl = cnAuthEndpoint ~ "/" ~ tenantId ~ "/oauth2/nativeclient"; + tokenUrl = cnAuthEndpoint ~ "/" ~ tenantId ~ "/oauth2/v2.0/token"; // Drive Queries driveUrl = cnGraphEndpoint ~ "/v1.0/me/drive"; driveByIdUrl = cnGraphEndpoint ~ "/v1.0/drives/"; diff --git a/src/sync.d b/src/sync.d index e91e3f6a..f1539d18 100644 --- a/src/sync.d +++ b/src/sync.d @@ -1245,7 +1245,7 @@ final class SyncEngine long deltaChanges = 0; // What query do we use? - // National Cloud Deployments (US and DE) do not support /delta as a query + // Some National Cloud Deployments (US and DE) do not support /delta as a query // https://docs.microsoft.com/en-us/graph/deployments#supported-features // Are we running against a National Cloud Deployments that does not support /delta if ((nationalCloudDeployment) || ((driveId!= defaultDriveId) && (syncBusinessFolders))) { @@ -5914,4 +5914,4 @@ final class SyncEngine log.error("ERROR: onedrive.getSharedWithMe call returned an invalid JSON Object"); } } -} \ No newline at end of file +}