(domain.Identifier);
string remoteStorageRootPath = AppGroupSettings.Settings.Value.RemoteStorageRootPath;
if (domainSettings != null && !string.IsNullOrEmpty(domainSettings.RemoteStorageRootPath))
@@ -39,10 +52,7 @@ public VirtualEngine(NSFileProviderDomain domain)
remoteStorageRootPath = domainSettings.RemoteStorageRootPath;
}
- // set remote root storage item id.
- SetRemoteStorageRootItemId(Mapping.EncodePath(remoteStorageRootPath));
-
- Logger.LogMessage($"Engine started.");
+ return Mapping.EncodePath(remoteStorageRootPath);
}
///
diff --git a/macOS/WebDAVDrive/README.md b/macOS/WebDAVDrive/README.md
index 85f63a2..e4cd792 100644
--- a/macOS/WebDAVDrive/README.md
+++ b/macOS/WebDAVDrive/README.md
@@ -49,6 +49,14 @@
Now you can manage documents using Finder, command prompt or by any other means. You can find the new file system in the 'Locations' sections in Finder.
For the development and testing convenience, when installing the extension, it will automatically open an instance of Finder with a mounted file system as well as will launch a default web browser navigating to the WebDAV server URL specified in your appsettings.json:
+Packaging the Sample
+To create installer for testing purposes and install the sample to /Application folder follow this steps:
+
+- You need Mac Developer certificate to sign app and 3rd Party Mac Developer Installer certificate to sign pkg. To get them use this guide.
+- Start Release build.
+- Then open Release output folder and find WebDAV Drive signed.pkg and use this pkg to install the Sample on the same host.
+
+For production environment you need to create Group ID, App Identifies and Provisioning Profiles configuration as described in this article.
See also:
- macOS File Provider Extension Troubleshooting
diff --git a/macOS/WebDAVDrive/WebDAVCommon/AppSettings.cs b/macOS/WebDAVDrive/WebDAVCommon/AppSettings.cs
index 3cd8ec9..a191816 100644
--- a/macOS/WebDAVDrive/WebDAVCommon/AppSettings.cs
+++ b/macOS/WebDAVDrive/WebDAVCommon/AppSettings.cs
@@ -14,14 +14,9 @@ public class AppSettings : Settings
public string WebDAVClientLicense { get; set; }
///
- /// WebDAV server URL.
+ /// WebDAV server URLs.
///
- public string WebDAVServerUrl { get; set; }
-
- ///
- /// WebSocket server URL.
- ///
- public string WebSocketServerUrl { get; set; }
+ public List WebDAVServerURLs { get; set; } = new();
///
/// Automatic lock timout in milliseconds.
diff --git a/macOS/WebDAVDrive/WebDAVCommon/DomainSettings.cs b/macOS/WebDAVDrive/WebDAVCommon/DomainSettings.cs
deleted file mode 100644
index b1f9f36..0000000
--- a/macOS/WebDAVDrive/WebDAVCommon/DomainSettings.cs
+++ /dev/null
@@ -1,17 +0,0 @@
-using System;
-namespace WebDAVCommon
-{
- public class DomainSettings
- {
- ///
- /// WebDAV server URL.
- ///
- public string WebDAVServerUrl { get; set; } = string.Empty;
-
- ///
- /// WebSocket server URL.
- ///
- public string WebSocketServerUrl { get; set; } = string.Empty;
- }
-}
-
diff --git a/macOS/WebDAVDrive/WebDAVCommon/SecureStorage.cs b/macOS/WebDAVDrive/WebDAVCommon/SecureStorage.cs
index e0141e7..6ceab02 100644
--- a/macOS/WebDAVDrive/WebDAVCommon/SecureStorage.cs
+++ b/macOS/WebDAVDrive/WebDAVCommon/SecureStorage.cs
@@ -9,9 +9,6 @@ namespace WebDAVCommon
{
public class SecureStorage: SecureStorageBase
{
- public const string ExtensionIdentifier = "com.webdav.vfs.app";
- public const string ExtensionDisplayName = "IT Hit WebDAV Drive";
-
public SecureStorage(): base("65S3A9JQ35.group.com.webdav.vfs")
{
diff --git a/macOS/WebDAVDrive/WebDAVCommon/WebDavSessionUtils.cs b/macOS/WebDAVDrive/WebDAVCommon/WebDavSessionUtils.cs
index a94429b..6a93b0b 100644
--- a/macOS/WebDAVDrive/WebDAVCommon/WebDavSessionUtils.cs
+++ b/macOS/WebDAVDrive/WebDAVCommon/WebDavSessionUtils.cs
@@ -20,6 +20,17 @@ public static async Task GetWebDavSessionAsync()
{
webDavSession.Credentials = new NetworkCredential(await secureStorage.GetAsync("UserName"), await secureStorage.GetAsync("Password"));
}
+ else if (!string.IsNullOrEmpty(loginType) && loginType.Equals("Cookies"))
+ {
+ List cookies = await secureStorage.GetAsync>("Cookies");
+ if (cookies != null)
+ {
+ foreach (Cookie cookie in cookies)
+ {
+ webDavSession.CookieContainer.Add(cookie);
+ }
+ }
+ }
return webDavSession;
}
diff --git a/macOS/WebDAVDrive/WebDAVFileProviderExtension/VirtualEngine.cs b/macOS/WebDAVDrive/WebDAVFileProviderExtension/VirtualEngine.cs
index a70b695..c80a717 100644
--- a/macOS/WebDAVDrive/WebDAVFileProviderExtension/VirtualEngine.cs
+++ b/macOS/WebDAVDrive/WebDAVFileProviderExtension/VirtualEngine.cs
@@ -68,12 +68,8 @@ public VirtualEngine(NSFileProviderDomain domain)
SecureStorage = new SecureStorage();
- WebDAVServerUrl = AppGroupSettings.Settings.Value.WebDAVServerUrl;
- DomainSettings domainSettings = SecureStorage.GetAsync(domain.Identifier).Result;
- if (domainSettings != null && !string.IsNullOrEmpty(domainSettings.WebDAVServerUrl))
- {
- WebDAVServerUrl = domainSettings.WebDAVServerUrl;
- }
+ // Get WebDAV url from user settings.
+ WebDAVServerUrl = SecureStorage.GetAsync(domain.Identifier).Result;
InitWebDavSession();
@@ -133,11 +129,8 @@ public override async Task GetMenuCommandAsync(Guid menuGuid, IOpe
throw new NotImplementedException();
}
- ///
- /// Returns remote storage item id.
- ///
- ///
- public async Task GetRootStorageItemIdAsync()
+ ///
+ public override async Task GetRootStorageItemIdAsync()
{
Logger.LogMessage($"{nameof(VirtualEngine)}.{nameof(GetRootStorageItemIdAsync)}()");
try
@@ -152,7 +145,14 @@ public async Task GetRootStorageItemIdAsync()
// Challenge-responce auth: Basic, Digest, NTLM or Kerberos
case 401:
// Set login type to display sing in button in Finder.
- await SecureStorage.RequireAuthenticationAsync();
+ await SecureStorage.RequirePasswordAuthenticationAsync();
+ return null;
+ // 302 redirect to login page.
+ case 302:
+ Uri failedUri = httpException.Uri;
+ await SecureStorage.SetAsync("CookiesFailedUrl", failedUri.AbsoluteUri);
+ // Set login type to display sing in button in Finder.
+ await SecureStorage.RequireCookiesAuthenticationAsync();
return null;
}
return null;
@@ -180,8 +180,9 @@ protected override void Stop()
public override async Task IsAuthenticatedAsync()
{
Logger.LogMessage($"{nameof(IEngine)}.{nameof(IsAuthenticatedAsync)}()");
- string loginType = await SecureStorage.GetAsync("LoginType");
- return string.IsNullOrEmpty(loginType) || loginType != "RequireAuthentication";
+ string requireAuthentication = await SecureStorage.GetAsync("RequireAuthentication");
+
+ return string.IsNullOrEmpty(requireAuthentication);
}
}
}
diff --git a/macOS/WebDAVDrive/WebDAVFileProviderExtension/VirtualFileSystemItem.cs b/macOS/WebDAVDrive/WebDAVFileProviderExtension/VirtualFileSystemItem.cs
index 0156532..0c65186 100644
--- a/macOS/WebDAVDrive/WebDAVFileProviderExtension/VirtualFileSystemItem.cs
+++ b/macOS/WebDAVDrive/WebDAVFileProviderExtension/VirtualFileSystemItem.cs
@@ -172,26 +172,55 @@ public Task> GetPropertiesAsync(IOperati
protected async void HandleWebExceptions(Client.Exceptions.WebDavHttpException webDavHttpException, IResultContext resultContext)
{
+ Logger.LogError("HandleWebExceptions", ex: webDavHttpException);
+
switch (webDavHttpException.Status.Code)
{
// Challenge-responce auth: Basic, Digest, NTLM or Kerberos
case 401:
- if (Engine.WebDavSession.Credentials == null || !(Engine.WebDavSession.Credentials is NetworkCredential) ||
- (Engine.WebDavSession.Credentials as NetworkCredential).UserName != await Engine.SecureStorage.GetAsync("UserName"))
+ if ((Engine.WebDavSession.Credentials == null && !string.IsNullOrEmpty(await Engine.SecureStorage.GetAsync("UserName"))) ||
+ (Engine.WebDavSession.Credentials is NetworkCredential &&
+ (Engine.WebDavSession.Credentials as NetworkCredential).UserName != await Engine.SecureStorage.GetAsync("UserName")))
+ {
+ Engine.Logger.LogDebug("Reset WebDav session - password auth");
+
+ // Reset WebDavSession.
+ Engine.InitWebDavSession();
+ }
+ else
{
// Set login type to display sing in button in Finder.
- await Engine.SecureStorage.RequireAuthenticationAsync();
+ await Engine.SecureStorage.RequirePasswordAuthenticationAsync();
if (resultContext != null)
{
resultContext.ReportStatus(CloudFileStatus.STATUS_CLOUD_FILE_AUTHENTICATION_FAILED);
}
}
- else
+ break;
+
+ // 302 redirect to login page.
+ case 302:
+ Uri failedUri = webDavHttpException.Uri;
+ await Engine.SecureStorage.SetAsync("CookiesFailedUrl", failedUri.AbsoluteUri);
+
+
+ if (Engine.WebDavSession.CookieContainer.Count == 0)
{
+ Engine.Logger.LogDebug($"Reset WebDav session - cookies auth: {Engine.WebDavSession.CookieContainer.Count}");
+
// Reset WebDavSession.
Engine.InitWebDavSession();
}
+ else
+ {
+ // Set login type to display sing in button in Finder.
+ await Engine.SecureStorage.RequireCookiesAuthenticationAsync();
+ if (resultContext != null)
+ {
+ resultContext.ReportStatus(CloudFileStatus.STATUS_CLOUD_FILE_AUTHENTICATION_FAILED);
+ }
+ }
break;
}
}
diff --git a/macOS/WebDAVDrive/WebDAVFileProviderExtension/WebDAVFileProviderExtension.csproj b/macOS/WebDAVDrive/WebDAVFileProviderExtension/WebDAVFileProviderExtension.csproj
index 8d98543..9dd067a 100644
--- a/macOS/WebDAVDrive/WebDAVFileProviderExtension/WebDAVFileProviderExtension.csproj
+++ b/macOS/WebDAVDrive/WebDAVFileProviderExtension/WebDAVFileProviderExtension.csproj
@@ -76,7 +76,7 @@