diff --git a/src/NzbDrone.Core/Notifications/Email/Email.cs b/src/NzbDrone.Core/Notifications/Email/Email.cs index ada554a2d..56b58b7ad 100644 --- a/src/NzbDrone.Core/Notifications/Email/Email.cs +++ b/src/NzbDrone.Core/Notifications/Email/Email.cs @@ -1,34 +1,145 @@ +using System; using System.Collections.Generic; +using System.Linq; using FluentValidation.Results; +using MailKit.Net.Smtp; +using MailKit.Security; +using MimeKit; +using NLog; using NzbDrone.Common.Extensions; namespace NzbDrone.Core.Notifications.Email { public class Email : NotificationBase { - private readonly IEmailService _emailService; + private readonly Logger _logger; public override string Name => "Email"; - public Email(IEmailService emailService) + public Email(Logger logger) { - _emailService = emailService; + _logger = logger; } public override string Link => null; public override void OnHealthIssue(HealthCheck.HealthCheck message) { - _emailService.SendEmail(Settings, HEALTH_ISSUE_TITLE_BRANDED, message.Message); + SendEmail(Settings, HEALTH_ISSUE_TITLE_BRANDED, message.Message); } public override ValidationResult Test() { var failures = new List(); - failures.AddIfNotNull(_emailService.Test(Settings)); + failures.AddIfNotNull(Test(Settings)); return new ValidationResult(failures); } + + public ValidationFailure Test(EmailSettings settings) + { + const string body = "Success! You have properly configured your email notification settings"; + + try + { + SendEmail(settings, "Prowlarr - Test Notification", body); + } + catch (Exception ex) + { + _logger.Error(ex, "Unable to send test email"); + return new ValidationFailure("Server", "Unable to send test email"); + } + + return null; + } + + private void SendEmail(EmailSettings settings, string subject, string body, bool htmlBody = false) + { + var email = new MimeMessage(); + + email.From.Add(ParseAddress("From", settings.From)); + email.To.AddRange(settings.To.Select(x => ParseAddress("To", x))); + email.Cc.AddRange(settings.CC.Select(x => ParseAddress("CC", x))); + email.Bcc.AddRange(settings.Bcc.Select(x => ParseAddress("BCC", x))); + + email.Subject = subject; + email.Body = new TextPart(htmlBody ? "html" : "plain") + { + Text = body + }; + + _logger.Debug("Sending email Subject: {0}", subject); + + try + { + Send(email, settings); + _logger.Debug("Email sent. Subject: {0}", subject); + } + catch (Exception ex) + { + _logger.Error("Error sending email. Subject: {0}", email.Subject); + _logger.Debug(ex, ex.Message); + throw; + } + + _logger.Debug("Finished sending email. Subject: {0}", email.Subject); + } + + private void Send(MimeMessage email, EmailSettings settings) + { + using (var client = new SmtpClient()) + { + client.Timeout = 10000; + + var serverOption = SecureSocketOptions.Auto; + + if (settings.RequireEncryption) + { + if (settings.Port == 465) + { + serverOption = SecureSocketOptions.SslOnConnect; + } + else + { + serverOption = SecureSocketOptions.StartTls; + } + } + + _logger.Debug("Connecting to mail server"); + + client.Connect(settings.Server, settings.Port, serverOption); + + if (!string.IsNullOrWhiteSpace(settings.Username)) + { + _logger.Debug("Authenticating to mail server"); + + client.Authenticate(settings.Username, settings.Password); + } + + _logger.Debug("Sending to mail server"); + + client.Send(email); + + _logger.Debug("Sent to mail server, disconnecting"); + + client.Disconnect(true); + + _logger.Debug("Disconnecting from mail server"); + } + } + + private MailboxAddress ParseAddress(string type, string address) + { + try + { + return MailboxAddress.Parse(address); + } + catch (Exception ex) + { + _logger.Error(ex, "{0} email address '{1}' invalid", type, address); + throw; + } + } } } diff --git a/src/NzbDrone.Core/Notifications/Email/EmailService.cs b/src/NzbDrone.Core/Notifications/Email/EmailService.cs deleted file mode 100644 index f6e41658e..000000000 --- a/src/NzbDrone.Core/Notifications/Email/EmailService.cs +++ /dev/null @@ -1,100 +0,0 @@ -using System; -using System.Linq; -using FluentValidation.Results; -using MailKit.Net.Smtp; -using MailKit.Security; -using MimeKit; -using NLog; - -namespace NzbDrone.Core.Notifications.Email -{ - public interface IEmailService - { - void SendEmail(EmailSettings settings, string subject, string body, bool htmlBody = false); - ValidationFailure Test(EmailSettings settings); - } - - public class EmailService : IEmailService - { - private readonly Logger _logger; - - public EmailService(Logger logger) - { - _logger = logger; - } - - public void SendEmail(EmailSettings settings, string subject, string body, bool htmlBody = false) - { - var email = new MimeMessage(); - email.From.Add(MailboxAddress.Parse(settings.From)); - - settings.To.ToList().ForEach(x => email.To.Add(MailboxAddress.Parse(x))); - settings.CC.ToList().ForEach(x => email.Cc.Add(MailboxAddress.Parse(x))); - settings.Bcc.ToList().ForEach(x => email.Bcc.Add(MailboxAddress.Parse(x))); - - email.Subject = subject; - email.Body = new TextPart(htmlBody ? "html" : "plain") - { - Text = body - }; - - try - { - Send(email, settings); - } - catch (Exception ex) - { - _logger.Error("Error sending email. Subject: {0}", email.Subject); - _logger.Debug(ex, ex.Message); - throw; - } - } - - private void Send(MimeMessage email, EmailSettings settings) - { - using (var client = new SmtpClient()) - { - var serverOption = SecureSocketOptions.Auto; - - if (settings.RequireEncryption) - { - if (settings.Port == 465) - { - serverOption = SecureSocketOptions.SslOnConnect; - } - else - { - serverOption = SecureSocketOptions.StartTls; - } - } - - client.Connect(settings.Server, settings.Port, serverOption); - - if (!string.IsNullOrWhiteSpace(settings.Username)) - { - client.Authenticate(settings.Username, settings.Password); - } - - client.Send(email); - client.Disconnect(true); - } - } - - public ValidationFailure Test(EmailSettings settings) - { - const string body = "Success! You have properly configured your email notification settings"; - - try - { - SendEmail(settings, "Prowlarr - Test Notification", body); - } - catch (Exception ex) - { - _logger.Error(ex, "Unable to send test email: " + ex.Message); - return new ValidationFailure("Server", "Unable to send test email"); - } - - return null; - } - } -} diff --git a/src/NzbDrone.Core/Notifications/Email/EmailSettings.cs b/src/NzbDrone.Core/Notifications/Email/EmailSettings.cs index 83a9a263e..1cc716c5d 100644 --- a/src/NzbDrone.Core/Notifications/Email/EmailSettings.cs +++ b/src/NzbDrone.Core/Notifications/Email/EmailSettings.cs @@ -58,13 +58,13 @@ namespace NzbDrone.Core.Notifications.Email [FieldDefinition(5, Label = "From Address")] public string From { get; set; } - [FieldDefinition(6, Label = "Recipient Address(es)", HelpText = "Comma seperated list of email recipients")] + [FieldDefinition(6, Label = "Recipient Address(es)", HelpText = "Comma separated list of email recipients")] public IEnumerable To { get; set; } - [FieldDefinition(7, Label = "CC Address(es)", HelpText = "Comma seperated list of email cc recipients", Advanced = true)] + [FieldDefinition(7, Label = "CC Address(es)", HelpText = "Comma separated list of email cc recipients", Advanced = true)] public IEnumerable CC { get; set; } - [FieldDefinition(8, Label = "BCC Address(es)", HelpText = "Comma seperated list of email bcc recipients", Advanced = true)] + [FieldDefinition(8, Label = "BCC Address(es)", HelpText = "Comma separated list of email bcc recipients", Advanced = true)] public IEnumerable Bcc { get; set; } public NzbDroneValidationResult Validate()