Skip to content

Commit

Permalink
Use an enum and implement migration from EnableSsl per datalust#89
Browse files Browse the repository at this point in the history
  • Loading branch information
MattMofDoom committed Oct 16, 2021
1 parent 98e6047 commit 2700698
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 42 deletions.
3 changes: 2 additions & 1 deletion src/Seq.App.EmailPlus/DirectMailGateway.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using DnsClient;
using DnsClient.Protocol;
using MailKit.Net.Smtp;
using MailKit.Security;
using MimeKit;

namespace Seq.App.EmailPlus
Expand Down Expand Up @@ -166,7 +167,7 @@ private static async Task<MailResult> TryDeliver(string server, SmtpOptions opti
return new MailResult {Success = false, LastServer = server, Type = deliveryType};
try
{
await Client.ConnectAsync(server, options.Port, options.SocketOptions);
await Client.ConnectAsync(server, options.Port, (SecureSocketOptions)options.SocketOptions);
if (options.RequiresAuthentication)
await Client.AuthenticateAsync(options.Username, options.Password);

Expand Down
14 changes: 5 additions & 9 deletions src/Seq.App.EmailPlus/EmailApp.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ internal EmailApp(IMailGateway mailGateway, IClock clock)
Host,
DeliverUsingDns != null && (bool) DeliverUsingDns,
port,
SmtpOptions.GetSocketOptions(port, EnableSsl, UseTlsWhenAvailable),
SmtpOptions.GetSocketOptions(port, EnableSsl, EnableTls),
Username,
Password));
// ReSharper restore ExpressionIsAlwaysNull ConditionIsAlwaysTrueOrFalse
Expand Down Expand Up @@ -116,18 +116,14 @@ public EmailApp()
"The port on the SMTP server machine to send mail to. Leave this blank to use the standard port (25).")]
public int? Port { get; set; }

[SeqAppSetting(
IsOptional = true,
DisplayName = "Require TLS",
HelpText = "Check this box to require that the server supports SSL/TLS for sending messages. If the port used is 465," +
"implicit SSL will ALWAYS be enabled; otherwise, the STARTTLS extension will be used if Require TLS is enabled. If this is disabled, Use Optional TLS If Available can be configured to allow TLS to be used when offered.")]
//EnableSSL has been retired but is preserved for migration purposes
public bool? EnableSsl { get; set; }

[SeqAppSetting(
IsOptional = true,
DisplayName = "Use Optional TLS if available",
HelpText = "If Enable SSL is disabled but the host supports TLS, allow Seq to negotiate using TLS. This has no effect if Enable SSL is enabled.")]
public bool? UseTlsWhenAvailable { get; set; }
DisplayName = "Require TLS",
HelpText = "Check this box to require that the server supports SSL/TLS for sending messages. If the port used is 465, StartTls (implicit TLS) will ALWAYS be used.")]
public TlsOptions? EnableTls { get; set; }

[SeqAppSetting(
IsOptional = true,
Expand Down
7 changes: 5 additions & 2 deletions src/Seq.App.EmailPlus/Seq.App.EmailPlus.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -14,21 +14,24 @@
<TreatWarningsAsErrors>True</TreatWarningsAsErrors>
<TreatSpecificWarningsAsErrors />
<PackageLicenseFile>LICENSE</PackageLicenseFile>
<PackageId>Seq.App.EmailPlus</PackageId>
<!--<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>-->
</PropertyGroup>

<ItemGroup>
<PackageReference Include="DnsClient" Version="1.5.0" />
<PackageReference Include="MailKit" Version="2.14.0" />
<PackageReference Include="MailKit" Version="2.15.0" />
<PackageReference Include="Seq.Apps" Version="5.1.0" />
<PackageReference Include="Serilog" Version="2.10.0" />
<PackageReference Include="Handlebars.Net" Version="2.0.9" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.1" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
</ItemGroup>

<ItemGroup>
<None Include="./icon.png" Pack="true" Visible="false" PackagePath="" />
<None Include="../../LICENSE" Pack="true" PackagePath="" />
<None Include="./obj/publish/**/*" Exclude="./obj/publish/Seq.App.EmailPlus.dll;./obj/publish/Seq.Apps.dll;./obj/publish/Serilog.dll" Pack="true" PackagePath="lib/$(TargetFramework)" />
<!--<None Include="$(OutDir)/**/*;" Exclude="$(OutDir)/$(MSBuildProjectName).dll;$(OutDir)/Seq.Apps.dll;$(OutDir)/Serilog.dll" Pack="true" PackagePath="lib/$(TargetFramework)" />-->
</ItemGroup>

</Project>
34 changes: 17 additions & 17 deletions src/Seq.App.EmailPlus/SmtpOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ public class SmtpOptions
public string Username { get; set; } = string.Empty;
public string Password { get; set; } = string.Empty;
public bool RequiresAuthentication => !string.IsNullOrEmpty(Username) && !string.IsNullOrEmpty(Password);
public SecureSocketOptions SocketOptions { get; set; }
public TlsOptions SocketOptions { get; set; }

public SmtpOptions(string host, bool dnsDelivery, int port, SecureSocketOptions socketOptions, string username = null, string password = null)
public SmtpOptions(string host, bool dnsDelivery, int port, TlsOptions socketOptions, string username = null, string password = null)
{
Host = GetServerList(host).ToList();
DnsDelivery = dnsDelivery;
Expand All @@ -33,24 +33,24 @@ IEnumerable<string> GetServerList(string hostName)
return new List<string>();
}

public static SecureSocketOptions GetSocketOptions(int port, bool? enableSsl, bool? useTlsWhenAvailable)
public static TlsOptions GetSocketOptions(int port, bool? enableSsl, TlsOptions? enableTls)
{
if (enableSsl == null) return SecureSocketOptions.Auto;
switch (enableSsl)
if (enableSsl == null && enableTls == null) return TlsOptions.Auto;

switch (enableTls)
{
case true when port == 465: //Implicit TLS
return SecureSocketOptions.SslOnConnect;
case true:
return SecureSocketOptions.StartTls;
case false when port == 465: //Implicit TLS
return SecureSocketOptions.SslOnConnect;
case false when useTlsWhenAvailable != null && !(bool) useTlsWhenAvailable:
return SecureSocketOptions.None;
case false when useTlsWhenAvailable != null && (bool) useTlsWhenAvailable:
return SecureSocketOptions.StartTlsWhenAvailable;
case null when (bool)enableSsl && port == 465: //Implicit TLS
case TlsOptions.None when port == 465:
case TlsOptions.Auto when port == 465:
case TlsOptions.StartTlsWhenAvailable when port == 465:
return TlsOptions.SslOnConnect;
case null when (bool)enableSsl:
return TlsOptions.StartTls; //Explicit TLS
case null:
return TlsOptions.Auto;
default:
return (TlsOptions)enableTls;
}

return SecureSocketOptions.Auto;
}
}
}
29 changes: 29 additions & 0 deletions src/Seq.App.EmailPlus/TlsOptions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using MailKit.Security;

namespace Seq.App.EmailPlus
{
public enum TlsOptions
{
/// <summary>
/// None
/// </summary>
None = SecureSocketOptions.None,
/// <summary>
/// Auto
/// </summary>
Auto = SecureSocketOptions.Auto,
/// <summary>
/// Implicit TLS
/// </summary>
SslOnConnect = SecureSocketOptions.SslOnConnect,
/// <summary>
/// Explicit TLS
/// </summary>
StartTls = SecureSocketOptions.StartTls,
/// <summary>
/// Optional TLS
/// </summary>
StartTlsWhenAvailable = SecureSocketOptions.StartTlsWhenAvailable

}
}
26 changes: 13 additions & 13 deletions test/Seq.App.EmailPlus.Tests/EmailAppTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -231,19 +231,19 @@ public async Task ToAddressesCanBeCommaSeparated()
}

[Theory]
[InlineData(25, null, null, SecureSocketOptions.Auto)]
[InlineData(25, true, false, SecureSocketOptions.StartTls)]
[InlineData(25, false, false, SecureSocketOptions.None)]
[InlineData(25, false, true, SecureSocketOptions.StartTlsWhenAvailable)]
[InlineData(587, true, false, SecureSocketOptions.StartTls)]
[InlineData(587, false, false, SecureSocketOptions.None)]
[InlineData(587, false, true, SecureSocketOptions.StartTlsWhenAvailable)]
[InlineData(465, true, false, SecureSocketOptions.SslOnConnect)]
[InlineData(465, false, false, SecureSocketOptions.SslOnConnect)]
[InlineData(465, false, true, SecureSocketOptions.SslOnConnect)]
public void CorrectSecureSocketOptionsAreChosenForPort(int port, bool? enableSsl, bool? optionalTls, SecureSocketOptions expected)
{
Assert.Equal(expected, SmtpOptions.GetSocketOptions(port, enableSsl, optionalTls));
[InlineData(25, null, null, TlsOptions.Auto)]
[InlineData(25, true, null, TlsOptions.StartTls)]
[InlineData(25, false, TlsOptions.None, TlsOptions.None)]
[InlineData(25, false, TlsOptions.StartTlsWhenAvailable, TlsOptions.StartTlsWhenAvailable)]
[InlineData(587, true, TlsOptions.StartTls, TlsOptions.StartTls)]
[InlineData(587, false, TlsOptions.None, TlsOptions.None)]
[InlineData(587, false, TlsOptions.StartTlsWhenAvailable, TlsOptions.StartTlsWhenAvailable)]
[InlineData(465, true, TlsOptions.None, TlsOptions.SslOnConnect)]
[InlineData(465, false, TlsOptions.Auto, TlsOptions.SslOnConnect)]
[InlineData(465, false, TlsOptions.SslOnConnect, TlsOptions.SslOnConnect)]
public void CorrectSecureSocketOptionsAreChosenForPort(int port, bool? enableSsl, TlsOptions? enableTls, TlsOptions expected)
{
Assert.Equal(expected, SmtpOptions.GetSocketOptions(port, enableSsl, enableTls));
}
}
}

0 comments on commit 2700698

Please sign in to comment.