using System.Net; using InABox.Core; using Microsoft.Exchange.WebServices.Data; namespace InABox.Mail { class ExchangeTraceListener : ITraceListener { public void Trace(string traceType, string traceMessage) { Logger.Send(LogType.Information, traceType, traceMessage); } } public class ExchangeMailer : CoreMailer { private ExchangeService Service; private ExchangeVersion Version = ExchangeVersion.Exchange2007_SP1; public IEnumerable Versions() { var results = new List(); var values = Enum.GetValues(typeof(ExchangeVersion)).Cast(); foreach (var value in values) results.Add(value.ToString()); return results; } protected override void Initialize() { ServicePointManager.ServerCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => true; Version = Enum.GetValues(typeof(ExchangeVersion)).Cast().Min(); } public override void Dispose() { if (Service != null) Service = null; } private static bool RedirectionUrlValidationCallback(string redirectionUrl) { // The default for the validation callback is to reject the URL. bool result = false; Uri redirectionUri = new Uri(redirectionUrl); // Validate the contents of the redirection URL. In this simple validation // callback, the redirection URL is considered valid if it is using HTTPS // to encrypt the authentication credentials. if (redirectionUri.Scheme == "https") { result = true; } return result; } protected override bool DoConnect() { try { Service = new ExchangeService(Version); Service.Timeout = 10000; Service.TraceListener = new ExchangeTraceListener(); Service.TraceFlags = TraceFlags.All; Service.TraceEnabled = true; if (String.IsNullOrWhiteSpace(MailboxDomain)) { if (String.IsNullOrWhiteSpace(MailboxUserName)) Service.UseDefaultCredentials = true; else { Service.Credentials = new WebCredentials(MailboxUserName, MailboxPassword); if (String.IsNullOrWhiteSpace(MailboxHost)) Service.AutodiscoverUrl(MailboxUserName,RedirectionUrlValidationCallback); else Service.Url = new Uri($"https://{MailboxHost}:{(MailboxPort == 0 ? 443 : MailboxPort)}/EWS/Exchange.asmx"); var folder = Folder.Bind(Service, WellKnownFolderName.Inbox).ConfigureAwait(true); } } else { Service.Credentials = new WebCredentials(MailboxUserName, MailboxPassword, MailboxDomain); Service.Url = new Uri(string.Format("https://{0}:{1}/EWS/Exchange.asmx", MailboxHost, MailboxPort == 0 ? 443 : MailboxPort)); } return true; } catch (Exception err) { Service = null; return false; } } protected override bool GetIsConnected() { return Service != null; } protected override bool DoSendMessage(ExchangeMailMessage message) { var result = false; if (IsConnected) { var email = new EmailMessage(Service); if (message.To != null) email.ToRecipients.AddRange(message.To.Select(x => new EmailAddress(x))); if (message.CC != null) email.CcRecipients.AddRange(message.CC.Select(x => new EmailAddress(x))); if (message.BCC != null) email.BccRecipients.AddRange(message.BCC.Select(x => new EmailAddress(x))); email.Subject = message.Subject; email.Body = new MessageBody(BodyType.Text, message.Body); email.SendAndSaveCopy(); result = true; } return result; } protected override ExchangeMailFolder DoFindFolder(ExchangeMailFolder parent, string name) { FindFoldersResults results = null; if (parent == null) results = Service.FindFolders(WellKnownFolderName.Inbox, new FolderView(int.MaxValue)).Result; else results = Service.FindFolders(parent.Folder.Id, new FolderView(int.MaxValue)).Result; var result = results.FirstOrDefault(x => x.DisplayName.Equals(name)); return new ExchangeMailFolder(result); } protected override ExchangeMailFolder GetInbox() { var folder = Folder.Bind(Service, WellKnownFolderName.Inbox).Result; return new ExchangeMailFolder(folder); } protected override ExchangeMailFolder GetSentItems() { var folder = Folder.Bind(Service, WellKnownFolderName.SentItems).Result; return new ExchangeMailFolder(folder); } protected override ExchangeMailMessage DoGetMessage(ExchangeMailFolder folder, string id) { throw new NotImplementedException(); } protected override IEnumerable DoGetMessages(ExchangeMailFolder folder) { var parent = folder != null ? folder.Folder : Service.FindFolders(WellKnownFolderName.Inbox, new FolderView(1)).Result.FirstOrDefault(); if (parent != null) { FindItemsResults items = parent.FindItems(new ItemView(int.MaxValue)).Result; var results = new List(); foreach (var item in items) try { var message = EmailMessage.Bind(Service, item.Id).Result; results.Add(new ExchangeMailMessage(message)); } catch (Exception e) { } return results; } return null; } protected override IEnumerable DoListMessages(ExchangeMailFolder folder, int min = 0, int max = int.MaxValue) { throw new NotImplementedException(); } protected override ExchangeMailMessage DoCreateMessage() { var email = new EmailMessage(Service); return new ExchangeMailMessage(email); } protected override bool DoMoveMessage(ExchangeMailMessage message, ExchangeMailFolder to) { if (message != null && to != null) { message.Message.Move(to.Folder.Id); return true; } return false; } protected override bool DoSaveDraft(ExchangeMailMessage message) { message.Message.Save(WellKnownFolderName.Drafts); return true; } } } // internal class ExchangeVersion // { // }