Skip to content

Commit

Permalink
Merge pull request #22 from FrendsPlatform/issue-15
Browse files Browse the repository at this point in the history
SMTP.SendEmail - Add OAuth support
  • Loading branch information
Svenskapojkarna authored Dec 21, 2023
2 parents bcb2906 + efe942c commit 8262eda
Show file tree
Hide file tree
Showing 9 changed files with 219 additions and 95 deletions.
15 changes: 15 additions & 0 deletions Frends.SMTP.SendEmail/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,20 @@
# Changelog

## [1.2.0] - 2023-12-21
### Changed
- Changed Task to use MailKit library instead of deprecated System.Net.Mail.
- Changed the Task to create a temp file from the AttachmentFromString. The temp file will be removed afterwards.

### Added
- Added OAuth2 support.
- New parameters:
- SecureSocket
- UseOAuth2
- Token

### Removed
- Removed UseWindowsAuthentication because it's not supported with the new library.

## [1.1.0] - 2023-11-29
### Fixed
- [Breaking] Fixed issue with the attachments can't be given as expression by adding AttachmentOptions class.
Expand Down
32 changes: 16 additions & 16 deletions Frends.SMTP.SendEmail/Frends.Smtp.SendEmail.Tests/SendEmailTests.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using NUnit.Framework;
using System;
using System.IO;
using System.Threading.Tasks;
using Frends.SMTP.SendEmail.Definitions;

namespace Frends.SMTP.SendEmail.Tests;
Expand All @@ -15,8 +16,6 @@ public class SendEmailTests
private static readonly string TOEMAILADDRESS = Environment.GetEnvironmentVariable("Frends_SMTP_Email");
private static readonly string FROMEMAILADDRESS = Environment.GetEnvironmentVariable("Frends_SMTP_Email");
private const int PORT = 587;
private const bool USESSL = true;
private const bool USEWINDOWSAUTHENTICATION = false;
// ************************************************************************************************************


Expand Down Expand Up @@ -75,11 +74,12 @@ public void EmailTestSetup()
Password = PASSWORD,
SMTPServer = SMTPADDRESS,
Port = PORT,
UseSsl = USESSL,
UseWindowsAuthentication = USEWINDOWSAUTHENTICATION,
UseOAuth2 = false,
SecureSocket = SecureSocketOption.None
};

}

[TearDown]
public void EmailTestTearDown()
{
Expand All @@ -88,17 +88,17 @@ public void EmailTestTearDown()
}

[Test]
public void SendEmailWithPlainText()
public async Task SendEmailWithPlainText()
{
var input = _input;
input.Subject = "Email test - PlainText";

var result = SMTP.SendEmail(input, null, _options, default);
var result = await SMTP.SendEmail(input, null, _options, default);
Assert.IsTrue(result.EmailSent);
}

[Test]
public void SendEmailWithFileAttachment()
public async Task SendEmailWithFileAttachment()
{
var input = _input;
input.Subject = "Email test - FileAttachment";
Expand All @@ -114,12 +114,12 @@ public void SendEmailWithFileAttachment()

var Attachments = new AttachmentOptions { Attachments = new Attachment[] { attachment } };

var result = SMTP.SendEmail(input, Attachments, _options, default);
var result = await SMTP.SendEmail(input, Attachments, _options, default);
Assert.IsTrue(result.EmailSent);
}

[Test]
public void SendEmailWithStringAttachment()
public async Task SendEmailWithStringAttachment()
{
var input = _input;
input.Subject = "Email test - AttachmentFromString";
Expand All @@ -131,12 +131,12 @@ public void SendEmailWithStringAttachment()
};
var Attachments = new AttachmentOptions { Attachments = new Attachment[] { attachment } };

var result = SMTP.SendEmail(input, Attachments, _options, default);
var result = await SMTP.SendEmail(input, Attachments, _options, default);
Assert.IsTrue(result.EmailSent);
}

[Test]
public void TrySendingEmailWithNoFileAttachmentFound()
public async Task TrySendingEmailWithNoFileAttachmentFound()
{
var input = _input;
input.Subject = "Email test";
Expand All @@ -151,12 +151,12 @@ public void TrySendingEmailWithNoFileAttachmentFound()

var Attachments = new AttachmentOptions { Attachments = new Attachment[] { attachment } };

var result = SMTP.SendEmail(input, Attachments, _options, default);
var result = await SMTP.SendEmail(input, Attachments, _options, default);
Assert.IsFalse(result.EmailSent);
}

[Test]
public void TrySendingEmailWithNoCcAndBcc()
public async Task TrySendingEmailWithNoCcAndBcc()
{
var input = _input2;
input.Subject = "Email test";
Expand All @@ -171,7 +171,7 @@ public void TrySendingEmailWithNoCcAndBcc()

var Attachments = new AttachmentOptions { Attachments = new Attachment[] { attachment } };

var result = SMTP.SendEmail(input, Attachments, _options, default);
var result = await SMTP.SendEmail(input, Attachments, _options, default);
Assert.IsFalse(result.EmailSent);
}

Expand All @@ -191,7 +191,7 @@ public void TrySendingEmailWithNoFileAttachmentFoundException()

var Attachments = new AttachmentOptions { Attachments = new Attachment[] { attachment } };

Assert.Throws<FileNotFoundException>(() => SMTP.SendEmail(input, Attachments, _options, default));

var ex = Assert.ThrowsAsync<FileNotFoundException>(async () => await SMTP.SendEmail(input, Attachments, _options, default));
Assert.AreEqual(@$"The given filepath '{attachment.FilePath}' had no matching files", ex.Message);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,31 +11,36 @@ public class Attachment
/// <summary>
/// Chooses if the attachment file is created from a string or copied from disk.
/// </summary>
/// <example>AttachmentType.FileAttachment</example>
public AttachmentType AttachmentType { get; set; }

/// <summary>
/// Attachment from string.
/// </summary>
/// <example>AttachmentFromString { "Test file content", "testFile.txt" }</example>
[UIHint(nameof(AttachmentType), "", AttachmentType.AttachmentFromString)]
public AttachmentFromString StringAttachment { get; set; }

/// <summary>
/// Attachment file's path. Uses Directory.GetFiles(string, string) as a pattern matching technique. See https://msdn.microsoft.com/en-us/library/wz42302f(v=vs.110).aspx.
/// Exception: If the path ends in a directory, all files in that folder are added as attachments.
/// </summary>
/// <example>C:\path\to\file.txt</example>
[DefaultValue("")]
[UIHint(nameof(AttachmentType), "", AttachmentType.FileAttachment)]
public string FilePath { get; set; }

/// <summary>
/// If set true and no files match the given path, an exception is thrown.
/// </summary>
/// <example>true</example>
[UIHint(nameof(AttachmentType), "", AttachmentType.FileAttachment)]
public bool ThrowExceptionIfAttachmentNotFound { get; set; }

/// <summary>
/// If set true and no files match the given path, email will be sent nevertheless.
/// </summary>
/// <example>true</example>
[UIHint(nameof(AttachmentType), "", AttachmentType.FileAttachment)]
public bool SendIfNoAttachmentsFound { get; set; }
}
Expand Down
11 changes: 10 additions & 1 deletion Frends.SMTP.SendEmail/Frends.Smtp.SendEmail/Definitions/Input.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;

namespace Frends.SMTP.SendEmail.Definitions;

Expand All @@ -11,48 +12,55 @@ public class Input
/// Recipient addresses separated by ',' or ';'
/// </summary>
/// <example>jane.doe@somedomain.com</example>
[DisplayFormat(DataFormatString = "Text")]
[DefaultValue("jane.doe@somedomain.com")]
public string To { get; set; }

/// <summary>
/// Cc recipient addresses separated by ',' or ';'
/// </summary>
/// <example>jane.doe@somedomain.com</example>
[DisplayFormat(DataFormatString = "Text")]
[DefaultValue("jane.doe@somedomain.com")]
public string Cc { get; set; }

/// <summary>
/// Bcc recipient addresses separated by ',' or ';'
/// </summary>
/// <example>jane.doe@somedomain.com</example>
[DisplayFormat(DataFormatString = "Text")]
[DefaultValue("jane.doe@somedomain.com")]
public string Bcc { get; set; }

/// <summary>
/// Sender address.
/// </summary>
/// <example>jane.doe@somedomain.com</example>
[DisplayFormat(DataFormatString = "Text")]
[DefaultValue("john.doe@somedomain.com")]
public string From { get; set; }

/// <summary>
/// Name of the sender.
/// </summary>
/// <example>Jane Doe</example>
[DisplayFormat(DataFormatString = "Text")]
[DefaultValue("")]
public string SenderName { get; set; }

/// <summary>
/// Email message's subject.
/// </summary>
/// <example>Hello Jane</example>
[DisplayFormat(DataFormatString = "Text")]
[DefaultValue("Hello Jane")]
public string Subject { get; set; }

/// <summary>
/// Body of the message.
/// </summary>
/// <exmaple>You've got mail!</exmaple>
/// <example>You've got mail!</example>
[DisplayFormat(DataFormatString = "Text")]
[DefaultValue("You've got mail!")]
public string Message { get; set; }

Expand All @@ -67,6 +75,7 @@ public class Input
/// Encoding of message body and subject. Use following table's name column for other options. https://msdn.microsoft.com/en-us/library/system.text.encoding(v=vs.110).aspx#Anchor_5
/// </summary>
/// <example>utf-8</example>
[DisplayFormat(DataFormatString = "Text")]
[DefaultValue("utf-8")]
public string MessageEncoding { get; set; }

Expand Down
30 changes: 20 additions & 10 deletions Frends.SMTP.SendEmail/Frends.Smtp.SendEmail/Definitions/Options.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ public class Options
/// SMTP server address.
/// </summary>
/// <example>smtp.somedomain.com</example>
[DisplayFormat(DataFormatString = "Text")]
[DefaultValue("smtp.somedomain.com")]
public string SMTPServer { get; set; }

Expand All @@ -23,25 +24,34 @@ public class Options
public int Port { get; set; }

/// <summary>
/// Set this true if SMTP expects to be connected using SSL.
/// Choose the SecureSocketOption to use, default is Auto
/// </summary>
/// <exmaple>true</exmaple>
[DefaultValue("false")]
public bool UseSsl { get; set; }
/// <example>SecureSocketOption.None</example>
[DefaultValue(SecureSocketOption.Auto)]
public SecureSocketOption SecureSocket { get; set; }

/// <summary>
/// Set this true if you want to use windows authentication to authenticate to SMTP server.
/// Set this true if SMTP server expectes OAuth token.
/// </summary>
/// <example>false</example>
[DefaultValue("true")]
public bool UseWindowsAuthentication { get; set; }
/// <example>true</example>
[DefaultValue(false)]
public bool UseOAuth2 { get; set; }

/// <summary>
/// Token to be used when using OAuth2.
/// </summary>
/// <example>cec4ce4f98e4f68e4vc89v1489v4987s4erv8794...</example>
[DisplayFormat(DataFormatString = "Text")]
[UIHint(nameof(UseOAuth2), "", true)]
[PasswordPropertyText]
public string Token { get; set; }

/// <summary>
/// Use this username to log in to the SMTP server
/// </summary>
/// <example>testuser</example>
[DisplayFormat(DataFormatString = "Text")]
[DefaultValue("")]
[UIHint(nameof(UseWindowsAuthentication), "", false)]
public string UserName { get; set; }

/// <summary>
Expand All @@ -50,6 +60,6 @@ public class Options
/// <example>Password123</example>
[PasswordPropertyText(true)]
[DefaultValue("")]
[UIHint(nameof(UseWindowsAuthentication), "", false)]
[UIHint(nameof(UseOAuth2), "", false)]
public string Password { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
namespace Frends.SMTP.SendEmail.Definitions;

/// <summary>
/// Secure Socket Options.
/// </summary>
public enum SecureSocketOption
{
/// <summary>
/// No SSL or TLS encryption should be used.
/// </summary>
None,
/// <summary>
/// Allow the IMailService to decide which SSL or TLS options to use (default).
/// If the server does not support SSL or TLS, then the connection will continue without any encryption.
/// </summary>
Auto,
/// <summary>
/// The connection should use SSL or TLS encryption immediately.
/// </summary>
SslOnConnect,
/// <summary>
/// Elevates the connection to use TLS encryption immediately after reading the greeting and capabilities of
/// the server. If the server does not support the STARTTLS extension, then the connection will fail and a
/// NotSupportedException will be thrown.
/// </summary>
StartTls,
/// <summary>
/// Elevates the connection to use TLS encryption immediately after reading the greeting and capabilities of
/// the server, but only if the server supports the STARTTLS extension.
/// </summary>
StartTlsWhenAvailable
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@

<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Version>1.1.0</Version>
<Version>1.2.0</Version>
<LangVersion>latest</LangVersion>
<Authors>Frends</Authors>
<Company>Frends</Company>
Expand All @@ -24,6 +23,7 @@
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" />
<PackageReference Include="MailKit" Version="4.3.0" />
</ItemGroup>

<ItemGroup>
Expand Down
Loading

0 comments on commit 8262eda

Please sign in to comment.