ExchangeMailer.cs 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. using System.Net;
  2. using InABox.Core;
  3. using Microsoft.Exchange.WebServices.Data;
  4. namespace InABox.Mail
  5. {
  6. class ExchangeTraceListener : ITraceListener
  7. {
  8. public void Trace(string traceType, string traceMessage)
  9. {
  10. Logger.Send(LogType.Information, traceType, traceMessage);
  11. }
  12. }
  13. public class ExchangeMailer : CoreMailer<ExchangeMailFolder, ExchangeMailSummary, ExchangeMailMessage>
  14. {
  15. private ExchangeService? Service;
  16. private ExchangeVersion Version = ExchangeVersion.Exchange2007_SP1;
  17. public IEnumerable<string> Versions()
  18. {
  19. var results = new List<string>();
  20. var values = Enum.GetValues(typeof(ExchangeVersion)).Cast<ExchangeVersion>();
  21. foreach (var value in values)
  22. results.Add(value.ToString());
  23. return results;
  24. }
  25. protected override void Initialize()
  26. {
  27. ServicePointManager.ServerCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => true;
  28. Version = Enum.GetValues(typeof(ExchangeVersion)).Cast<ExchangeVersion>().Min();
  29. }
  30. public override void Dispose()
  31. {
  32. if (Service != null)
  33. Service = null;
  34. }
  35. private static bool RedirectionUrlValidationCallback(string redirectionUrl)
  36. {
  37. // The default for the validation callback is to reject the URL.
  38. bool result = false;
  39. Uri redirectionUri = new Uri(redirectionUrl);
  40. // Validate the contents of the redirection URL. In this simple validation
  41. // callback, the redirection URL is considered valid if it is using HTTPS
  42. // to encrypt the authentication credentials.
  43. if (redirectionUri.Scheme == "https")
  44. {
  45. result = true;
  46. }
  47. return result;
  48. }
  49. protected override bool DoConnect()
  50. {
  51. try
  52. {
  53. Service = new ExchangeService(Version);
  54. Service.Timeout = 10000;
  55. Service.TraceListener = new ExchangeTraceListener();
  56. Service.TraceFlags = TraceFlags.All;
  57. Service.TraceEnabled = true;
  58. if (String.IsNullOrWhiteSpace(MailboxDomain))
  59. {
  60. if (String.IsNullOrWhiteSpace(MailboxUserName))
  61. Service.UseDefaultCredentials = true;
  62. else
  63. {
  64. Service.Credentials = new WebCredentials(MailboxUserName, MailboxPassword);
  65. if (String.IsNullOrWhiteSpace(MailboxHost))
  66. Service.AutodiscoverUrl(MailboxUserName,RedirectionUrlValidationCallback);
  67. else
  68. Service.Url = new Uri($"https://{MailboxHost}:{(MailboxPort == 0 ? 443 : MailboxPort)}/EWS/Exchange.asmx");
  69. var folder = Folder.Bind(Service, WellKnownFolderName.Inbox).ConfigureAwait(true);
  70. }
  71. }
  72. else
  73. {
  74. Service.Credentials = new WebCredentials(MailboxUserName, MailboxPassword, MailboxDomain);
  75. if (MailboxHost.IsNullOrWhiteSpace())
  76. {
  77. Service.AutodiscoverUrl(MailboxUserName, RedirectionUrlValidationCallback);
  78. }
  79. else
  80. {
  81. Service.Url = new Uri(string.Format("https://{0}:{1}/EWS/Exchange.asmx", MailboxHost, MailboxPort == 0 ? 443 : MailboxPort));
  82. }
  83. }
  84. return true;
  85. }
  86. catch (Exception err)
  87. {
  88. CoreUtils.LogException("", err);
  89. Service = null;
  90. return false;
  91. }
  92. }
  93. protected override bool GetIsConnected()
  94. {
  95. return Service != null;
  96. }
  97. private ExchangeService GetService()
  98. {
  99. return Service ?? throw new Exception("Not Connected");
  100. }
  101. protected override bool DoSendMessage(ExchangeMailMessage message)
  102. {
  103. var result = false;
  104. if (IsConnected)
  105. {
  106. var email = new EmailMessage(Service);
  107. if (message.To != null)
  108. email.ToRecipients.AddRange(message.To.Select(x => new EmailAddress(x)));
  109. if (message.CC != null)
  110. email.CcRecipients.AddRange(message.CC.Select(x => new EmailAddress(x)));
  111. if (message.BCC != null)
  112. email.BccRecipients.AddRange(message.BCC.Select(x => new EmailAddress(x)));
  113. email.Subject = message.Subject;
  114. email.Body = new MessageBody(BodyType.Text, message.Body);
  115. email.SendAndSaveCopy().ContinueWith(MessageSent);
  116. result = true;
  117. }
  118. return result;
  119. }
  120. private void MessageSent(System.Threading.Tasks.Task task)
  121. {
  122. }
  123. protected override ExchangeMailFolder DoFindFolder(ExchangeMailFolder parent, string name)
  124. {
  125. FindFoldersResults results = null;
  126. if (parent == null)
  127. results = GetService().FindFolders(WellKnownFolderName.Inbox, new FolderView(int.MaxValue)).Result;
  128. else
  129. results = GetService().FindFolders(parent.Folder.Id, new FolderView(int.MaxValue)).Result;
  130. var result = results.FirstOrDefault(x => x.DisplayName.Equals(name));
  131. return new ExchangeMailFolder(result);
  132. }
  133. protected override ExchangeMailFolder GetInbox()
  134. {
  135. var folder = Folder.Bind(Service, WellKnownFolderName.Inbox).Result;
  136. return new ExchangeMailFolder(folder);
  137. }
  138. protected override ExchangeMailFolder GetSentItems()
  139. {
  140. var folder = Folder.Bind(Service, WellKnownFolderName.SentItems).Result;
  141. return new ExchangeMailFolder(folder);
  142. }
  143. protected override ExchangeMailMessage DoGetMessage(ExchangeMailFolder folder, string id)
  144. {
  145. throw new NotImplementedException();
  146. }
  147. protected override IEnumerable<ExchangeMailMessage> DoGetMessages(ExchangeMailFolder folder)
  148. {
  149. var parent = folder != null ? folder.Folder : GetService().FindFolders(WellKnownFolderName.Inbox, new FolderView(1)).Result.FirstOrDefault();
  150. if (parent != null)
  151. {
  152. FindItemsResults<Item> items = parent.FindItems(new ItemView(int.MaxValue)).Result;
  153. var results = new List<ExchangeMailMessage>();
  154. foreach (var item in items)
  155. try
  156. {
  157. var message = EmailMessage.Bind(Service, item.Id).Result;
  158. results.Add(new ExchangeMailMessage(message));
  159. }
  160. catch (Exception e)
  161. {
  162. CoreUtils.LogException("", e);
  163. }
  164. return results;
  165. }
  166. return null;
  167. }
  168. protected override IEnumerable<ExchangeMailSummary> DoListMessages(ExchangeMailFolder folder, int min = 0, int max = int.MaxValue)
  169. {
  170. throw new NotImplementedException();
  171. }
  172. protected override ExchangeMailMessage DoCreateMessage()
  173. {
  174. var email = new EmailMessage(Service);
  175. return new ExchangeMailMessage(email);
  176. }
  177. protected override bool DoMoveMessage(ExchangeMailMessage message, ExchangeMailFolder to)
  178. {
  179. if (message != null && to != null)
  180. {
  181. message.Message.Move(to.Folder.Id);
  182. return true;
  183. }
  184. return false;
  185. }
  186. protected override bool DoSaveDraft(ExchangeMailMessage message)
  187. {
  188. message.Message.Save(WellKnownFolderName.Drafts);
  189. return true;
  190. }
  191. }
  192. }
  193. // internal class ExchangeVersion
  194. // {
  195. // }