SSL Handshake Prompt for IMAP (#381)

* Fix an incorrect namespace for copy auth url request.

* Implemented SSL handshake process for testing imap configuration.

* Implemented SSL handshake process for testing imap configuration.

* Replace certificate PathIcon with WinoFontIcon in XAML.
This commit is contained in:
Burak Kaan Köse
2024-09-14 21:51:43 +02:00
committed by GitHub
parent cad9250cb7
commit 56bfbeca58
24 changed files with 473 additions and 113 deletions

View File

@@ -1,21 +1,18 @@
using System;
using Wino.Core.Domain.Models.AutoDiscovery;
using Wino.Core.Domain.Models.AutoDiscovery;
namespace Wino.Core.Domain.Exceptions
{
public class ImapConnectionFailedPackage
{
public ImapConnectionFailedPackage(Exception error, string protocolLog, AutoDiscoverySettings settings)
public ImapConnectionFailedPackage(string errorMessage, string protocolLog, AutoDiscoverySettings settings)
{
Error = error;
ErrorMessage = errorMessage;
ProtocolLog = protocolLog;
Settings = settings;
}
public AutoDiscoverySettings Settings { get; }
public Exception Error { get; }
public string ErrorMessage { get; set; }
public string ProtocolLog { get; }
public string GetErrorMessage() => Error.InnerException == null ? Error.Message : Error.InnerException.Message;
}
}

View File

@@ -0,0 +1,17 @@
namespace Wino.Core.Domain.Exceptions
{
public class ImapTestSSLCertificateException : System.Exception
{
public ImapTestSSLCertificateException(string issuer, string expirationDateString, string validFromDateString)
{
Issuer = issuer;
ExpirationDateString = expirationDateString;
ValidFromDateString = validFromDateString;
}
public string Issuer { get; set; }
public string ExpirationDateString { get; set; }
public string ValidFromDateString { get; set; }
}
}

View File

@@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
namespace Wino.Core.Domain.Extensions
{
public static class ExceptionExtensions
{
public static IEnumerable<Exception> GetInnerExceptions(this Exception ex)
{
if (ex == null)
{
throw new ArgumentNullException("ex");
}
var innerException = ex;
do
{
yield return innerException;
innerException = innerException.InnerException;
}
while (innerException != null);
}
}
}

View File

@@ -5,6 +5,6 @@ namespace Wino.Core.Domain.Interfaces
{
public interface IImapTestService
{
Task TestImapConnectionAsync(CustomServerInformation serverInformation);
Task TestImapConnectionAsync(CustomServerInformation serverInformation, bool allowSSLHandShake);
}
}

View File

@@ -0,0 +1,48 @@
using System;
using System.Linq;
using System.Text.Json.Serialization;
using Wino.Core.Domain.Extensions;
namespace Wino.Core.Domain.Models.Connectivity
{
/// <summary>
/// Contains validation of the IMAP server connectivity during account setup.
/// </summary>
public class ImapConnectivityTestResults
{
[JsonConstructor]
protected ImapConnectivityTestResults() { }
public bool IsSuccess { get; set; }
public bool IsCertificateUIRequired { get; set; }
public string FailedReason { get; set; }
public string FailureProtocolLog { get; set; }
public static ImapConnectivityTestResults Success() => new ImapConnectivityTestResults() { IsSuccess = true };
public static ImapConnectivityTestResults Failure(Exception ex, string failureProtocolLog) => new ImapConnectivityTestResults()
{
FailedReason = string.Join(Environment.NewLine, ex.GetInnerExceptions().Select(e => e.Message)),
FailureProtocolLog = failureProtocolLog
};
public static ImapConnectivityTestResults CertificateUIRequired(string issuer,
string expirationString,
string validFromString)
{
return new ImapConnectivityTestResults()
{
IsSuccess = false,
IsCertificateUIRequired = true,
CertificateIssuer = issuer,
CertificateExpirationDateString = expirationString,
CertificateValidFromDateString = validFromString
};
}
public string CertificateIssuer { get; set; }
public string CertificateValidFromDateString { get; set; }
public string CertificateExpirationDateString { get; set; }
}
}

View File

@@ -34,6 +34,8 @@
"BasicIMAPSetupDialog_Title": "IMAP Account",
"Buttons_AddAccount": "Add Account",
"Buttons_AddNewAlias": "Add New Alias",
"Buttons_Allow": "Allow",
"Buttons_Deny": "Deny",
"Buttons_SyncAliases": "Synchronize Aliases",
"Buttons_ApplyTheme": "Apply Theme",
"Buttons_Browse": "Browse",
@@ -221,6 +223,14 @@
"IMAPSetupDialog_UsernamePlaceholder": "johndoe, johndoe@fabrikam.com, domain/johndoe",
"IMAPSetupDialog_ConnectionFailedTitle": "Connection Failed",
"IMAPSetupDialog_ConnectionFailedMessage": "IMAP connection failed.",
"IMAPSetupDialog_CertificateAllowanceRequired_Row0": "This server is requesting a SSL handshake to continue. Please confirm the certificate details below.",
"IMAPSetupDialog_CertificateAllowanceRequired_Row1": "Allow the handshake to continue setting up your account.",
"IMAPSetupDialog_CertificateIssuer": "Issuer",
"IMAPSetupDialog_CertificateSubject": "Subject",
"IMAPSetupDialog_CertificateValidFrom": "Valid from",
"IMAPSetupDialog_CertificateValidTo": "Valid to",
"IMAPSetupDialog_CertificateDenied": "User didn't authorize the handshake with the certificate.",
"IMAPSetupDialog_CertificateView": "View Certificate",
"ImageRenderingDisabled": "Image rendering is disabled for this message.",
"InfoBarAction_Enable": "Enable",
"InfoBarMessage_SynchronizationDisabledFolder": "This folder is disabled for synchronization.",

View File

@@ -193,6 +193,16 @@ namespace Wino.Core.Domain
/// </summary>
public static string Buttons_AddNewAlias => Resources.GetTranslatedString(@"Buttons_AddNewAlias");
/// <summary>
/// Allow
/// </summary>
public static string Buttons_Allow => Resources.GetTranslatedString(@"Buttons_Allow");
/// <summary>
/// Deny
/// </summary>
public static string Buttons_Deny => Resources.GetTranslatedString(@"Buttons_Deny");
/// <summary>
/// Synchronize Aliases
/// </summary>
@@ -1128,6 +1138,46 @@ namespace Wino.Core.Domain
/// </summary>
public static string IMAPSetupDialog_ConnectionFailedMessage => Resources.GetTranslatedString(@"IMAPSetupDialog_ConnectionFailedMessage");
/// <summary>
/// This server is requesting a SSL handshake to continue. Please confirm the certificate details below.
/// </summary>
public static string IMAPSetupDialog_CertificateAllowanceRequired_Row0 => Resources.GetTranslatedString(@"IMAPSetupDialog_CertificateAllowanceRequired_Row0");
/// <summary>
/// Allow the handshake to continue setting up your account.
/// </summary>
public static string IMAPSetupDialog_CertificateAllowanceRequired_Row1 => Resources.GetTranslatedString(@"IMAPSetupDialog_CertificateAllowanceRequired_Row1");
/// <summary>
/// Issuer
/// </summary>
public static string IMAPSetupDialog_CertificateIssuer => Resources.GetTranslatedString(@"IMAPSetupDialog_CertificateIssuer");
/// <summary>
/// Subject
/// </summary>
public static string IMAPSetupDialog_CertificateSubject => Resources.GetTranslatedString(@"IMAPSetupDialog_CertificateSubject");
/// <summary>
/// Valid from
/// </summary>
public static string IMAPSetupDialog_CertificateValidFrom => Resources.GetTranslatedString(@"IMAPSetupDialog_CertificateValidFrom");
/// <summary>
/// Valid to
/// </summary>
public static string IMAPSetupDialog_CertificateValidTo => Resources.GetTranslatedString(@"IMAPSetupDialog_CertificateValidTo");
/// <summary>
/// User didn't authorize the handshake with the certificate.
/// </summary>
public static string IMAPSetupDialog_CertificateDenied => Resources.GetTranslatedString(@"IMAPSetupDialog_CertificateDenied");
/// <summary>
/// View Certificate
/// </summary>
public static string IMAPSetupDialog_CertificateView => Resources.GetTranslatedString(@"IMAPSetupDialog_CertificateView");
/// <summary>
/// Image rendering is disabled for this message.
/// </summary>