From 55563b1235b491c31fd619bbb0ceb3478629179f Mon Sep 17 00:00:00 2001 From: Sebastian Holzer Date: Mon, 3 Jun 2024 12:40:04 +0200 Subject: [PATCH 1/6] Updated Target Framework from 4.5 to 4.8.0 --- Mail2Bug/App.config | 76 +++++++++++----------- Mail2Bug/Mail2Bug.csproj | 7 +- Mail2BugUnitTests/Mail2BugUnitTests.csproj | 7 +- Mail2BugUnitTests/app.config | 20 +++--- Tools/DpapiTool/App.config | 20 +++--- Tools/DpapiTool/DpapiTool.csproj | 4 +- 6 files changed, 68 insertions(+), 66 deletions(-) diff --git a/Mail2Bug/App.config b/Mail2Bug/App.config index 375f9cf..7e6bb9e 100644 --- a/Mail2Bug/App.config +++ b/Mail2Bug/App.config @@ -1,49 +1,49 @@ - + - + - - - - - - - - - - + + + + + + + + + + - + - + - - + + - - + + - - + + - - + + @@ -51,25 +51,25 @@ - - - + + + - - - - - + + + + + - - - - - - - + + + + + + + - \ No newline at end of file + diff --git a/Mail2Bug/Mail2Bug.csproj b/Mail2Bug/Mail2Bug.csproj index 22bbdc2..e0bc581 100644 --- a/Mail2Bug/Mail2Bug.csproj +++ b/Mail2Bug/Mail2Bug.csproj @@ -1,5 +1,5 @@  - + Debug @@ -9,12 +9,13 @@ Properties Mail2Bug Mail2Bug - v4.5 + v4.8 512 ..\ true + AnyCPU @@ -378,4 +379,4 @@ --> - + \ No newline at end of file diff --git a/Mail2BugUnitTests/Mail2BugUnitTests.csproj b/Mail2BugUnitTests/Mail2BugUnitTests.csproj index 9af2262..36668be 100644 --- a/Mail2BugUnitTests/Mail2BugUnitTests.csproj +++ b/Mail2BugUnitTests/Mail2BugUnitTests.csproj @@ -1,5 +1,5 @@  - + Debug AnyCPU @@ -8,7 +8,7 @@ Properties Mail2BugUnitTests Mail2BugUnitTests - v4.5 + v4.8 512 {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 10.0 @@ -18,6 +18,7 @@ UnitTest ..\ true + true @@ -170,4 +171,4 @@ --> - + \ No newline at end of file diff --git a/Mail2BugUnitTests/app.config b/Mail2BugUnitTests/app.config index 3e11088..8ba66b7 100644 --- a/Mail2BugUnitTests/app.config +++ b/Mail2BugUnitTests/app.config @@ -1,23 +1,23 @@ - + - - + + - - + + - - + + - - + + - \ No newline at end of file + diff --git a/Tools/DpapiTool/App.config b/Tools/DpapiTool/App.config index f9d4b5e..28f3a0b 100644 --- a/Tools/DpapiTool/App.config +++ b/Tools/DpapiTool/App.config @@ -1,25 +1,25 @@ - + - + - - + + - - + + - - + + - - + + diff --git a/Tools/DpapiTool/DpapiTool.csproj b/Tools/DpapiTool/DpapiTool.csproj index 757f1d3..34e91fb 100644 --- a/Tools/DpapiTool/DpapiTool.csproj +++ b/Tools/DpapiTool/DpapiTool.csproj @@ -1,5 +1,5 @@  - + Debug @@ -9,7 +9,7 @@ Properties DpapiTool DpapiTool - v4.5 + v4.8 512 ..\..\ true From 2cf0691bd3844c7f582efe70ede420548c72ba3a Mon Sep 17 00:00:00 2001 From: Sebastian Holzer Date: Tue, 4 Jun 2024 09:59:54 +0200 Subject: [PATCH 2/6] Added basic OAuth classes --- Mail2Bug/Config.cs | 9 +++ Mail2Bug/Email/EWS/EWSConnectionManger.cs | 6 +- Mail2Bug/Helpers/EWSOAuthHelper.cs | 74 +++++++++++++++++++++++ Mail2Bug/Mail2Bug.csproj | 1 + 4 files changed, 89 insertions(+), 1 deletion(-) create mode 100644 Mail2Bug/Helpers/EWSOAuthHelper.cs diff --git a/Mail2Bug/Config.cs b/Mail2Bug/Config.cs index 515e9d4..1edec41 100644 --- a/Mail2Bug/Config.cs +++ b/Mail2Bug/Config.cs @@ -28,6 +28,14 @@ public class KeyVaultSecret public string ApplicationSecretEnvironmentVariableName { get; set; } } + public class OAuthSecret + { + public string TenantID { get; set; } + public string ClientID { get; set; } + public string ClientSecret { get; set; } + public string UserAgentName { get; set; } + } + public class TfsServerConfig { // The TFS collection URL to connect to. e.g: @@ -202,6 +210,7 @@ public enum MailboxServiceType public string EWSUsername { get; set; } public string EWSPasswordFile { get; set; } public KeyVaultSecret EWSKeyVaultSecret { get; set; } + public OAuthSecret EWSOAuthSecret { get; set; } #endregion diff --git a/Mail2Bug/Email/EWS/EWSConnectionManger.cs b/Mail2Bug/Email/EWS/EWSConnectionManger.cs index 2769ef0..f99c5ca 100644 --- a/Mail2Bug/Email/EWS/EWSConnectionManger.cs +++ b/Mail2Bug/Email/EWS/EWSConnectionManger.cs @@ -1,7 +1,12 @@ using System; using System.Collections.Generic; +using System.IO; +using System.Net.Cache; +using System.Net; +using System.Text; using log4net; using Microsoft.Exchange.WebServices.Data; +using Newtonsoft.Json.Linq; namespace Mail2Bug.Email.EWS { @@ -108,7 +113,6 @@ static private EWSConnection ConnectToEWS(Credentials credentials, bool useConve }; } - private readonly Dictionary, EWSConnection> _cachedConnections; private readonly bool _enableConnectionCaching; diff --git a/Mail2Bug/Helpers/EWSOAuthHelper.cs b/Mail2Bug/Helpers/EWSOAuthHelper.cs new file mode 100644 index 0000000..d5b0ae8 --- /dev/null +++ b/Mail2Bug/Helpers/EWSOAuthHelper.cs @@ -0,0 +1,74 @@ +using Microsoft.Exchange.WebServices.Data; +using Newtonsoft.Json.Linq; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net.Cache; +using System.Net; +using System.Text; +using System.Threading.Tasks; + +namespace Mail2Bug.Helpers +{ + public class EWSOAuthHelper + { + private const string TenantID = "[Your Tenant ID]"; + private const string ClientID = "[Your Client ID]"; + private const string ClientSecret = "[Your Secret ID]"; + + private const string AgentName = "My Agent Name"; + + public static ExchangeService OAuthConnectPost() + { + string LoginURL = String.Format("https://login.microsoftonline.com/{0}/oauth2/v2.0/token", TenantID); + + var LogValues = new Dictionary + { + { "grant_type", "client_credentials" }, + { "client_id", ClientID }, + { "client_secret", ClientSecret }, + { "scope", "https://graph.microsoft.com/.default" } + }; + string postData = ""; + foreach (var v in LogValues) + { + postData += (String.IsNullOrWhiteSpace(postData) ? "" : "&") + v.Key + "=" + v.Value; + } + var data = Encoding.ASCII.GetBytes(postData); + + ServicePointManager.ServerCertificateValidationCallback = delegate { return true; }; + ServicePointManager.Expect100Continue = true; + ServicePointManager.DefaultConnectionLimit = 9999; + ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls + | SecurityProtocolType.Tls11 + | SecurityProtocolType.Tls12 + | SecurityProtocolType.Ssl3; + + HttpWebRequest request = (HttpWebRequest)WebRequest.Create(LoginURL); + request.Method = "POST"; + request.ContentType = "application/x-www-form-urlencoded"; + request.Accept = "*/*"; + request.UserAgent = AgentName; + request.CachePolicy = new RequestCachePolicy(RequestCacheLevel.NoCacheNoStore); + request.ContentLength = data.Length; + using (var stream = request.GetRequestStream()) + { + stream.Write(data, 0, data.Length); + } + + using (var response = (HttpWebResponse)request.GetResponse()) + using (Stream stream = response.GetResponseStream()) + using (var reader = new StreamReader(stream)) + { + var json = reader.ReadToEnd(); + var aToken = JObject.Parse(json)["access_token"].ToString(); + + var ewsClient = new ExchangeService(); + ewsClient.Url = new Uri("https://outlook.office365.com/EWS/Exchange.asmx"); + ewsClient.Credentials = new OAuthCredentials(aToken); + return ewsClient; + } + } + } +} diff --git a/Mail2Bug/Mail2Bug.csproj b/Mail2Bug/Mail2Bug.csproj index e0bc581..627dbb5 100644 --- a/Mail2Bug/Mail2Bug.csproj +++ b/Mail2Bug/Mail2Bug.csproj @@ -319,6 +319,7 @@ + From 542493c3f38cdc2c475d04b53e00c12673824f55 Mon Sep 17 00:00:00 2001 From: Sebastian Holzer Date: Tue, 4 Jun 2024 10:00:40 +0200 Subject: [PATCH 3/6] added deploy config --- .gitignore | 1 + Documentation/query.wiq | 2 +- deploy/Configuration/Dibit8_Query.wiq | 1 + deploy/Configuration/Dibit8_ReplyTemplate.htm | 58 +++ .../FullyAnnotatedConfigReference.xml | 329 ++++++++++++++++++ .../Mail2BugConfigDibitDevOps.xml | 76 ++++ 6 files changed, 466 insertions(+), 1 deletion(-) create mode 100644 deploy/Configuration/Dibit8_Query.wiq create mode 100644 deploy/Configuration/Dibit8_ReplyTemplate.htm create mode 100644 deploy/Configuration/FullyAnnotatedConfigReference.xml create mode 100644 deploy/Configuration/Mail2BugConfigDibitDevOps.xml diff --git a/.gitignore b/.gitignore index 7b742e8..f6fe0b5 100644 --- a/.gitignore +++ b/.gitignore @@ -95,3 +95,4 @@ Thumbs.db /packages/ *.nupkg +deploy/Configuration/bugsAtDibit.bin diff --git a/Documentation/query.wiq b/Documentation/query.wiq index 070f88a..248b247 100644 --- a/Documentation/query.wiq +++ b/Documentation/query.wiq @@ -1 +1 @@ -http://tfsServer.madeUpDomain.com:8080/tfs/somethingHelloWorldProjectSELECT [System.Id], [System.Title] FROM WorkItems WHERE [System.WorkItemType] <> '' AND ([System.CreatedBy] = 'mail2bug user') AND [System.ChangedDate] > @today - 60 ORDER BY [System.Id] +http://tfsServer.madeUpDomain.com:8080/tfs/somethingHelloWorldProjectSELECT [System.Id], [System.Title] FROM WorkItems WHERE [System.WorkItemType] <> '' AND ([System.CreatedBy] = 'Dibit Support') AND [System.ChangedDate] > @today - 60 ORDER BY [System.Id] diff --git a/deploy/Configuration/Dibit8_Query.wiq b/deploy/Configuration/Dibit8_Query.wiq new file mode 100644 index 0000000..5fba7ca --- /dev/null +++ b/deploy/Configuration/Dibit8_Query.wiq @@ -0,0 +1 @@ +https://devops.dibit.at/Dibit8%20Team/Dibit8Dibit8SELECT [System.Id], [System.Title] FROM WorkItems WHERE [System.WorkItemType] <> '' AND ([System.CreatedBy] = 'Dibit Support') AND [System.ChangedDate] > @today - 60 ORDER BY [System.Id] diff --git a/deploy/Configuration/Dibit8_ReplyTemplate.htm b/deploy/Configuration/Dibit8_ReplyTemplate.htm new file mode 100644 index 0000000..3e75c9b --- /dev/null +++ b/deploy/Configuration/Dibit8_ReplyTemplate.htm @@ -0,0 +1,58 @@ + + + + Dibit8 Support + + + + + + + + + + + +
+ +
[TFSProject] · [TFSWorkItemTemplate]
+ +

[_ID]

+

[_TITLE]

+

[_OWNER:Unassigned]

+

[Software Version:Dibit8]

+ + +
+

+ The above work item is used to track this issue. + New messages in this conversation will be automatically added to the work item as long as [Mail2BugAlias] is a recipient. +

+

Reply to this mail to add more information to the work item.

+
+
  +
  + + diff --git a/deploy/Configuration/FullyAnnotatedConfigReference.xml b/deploy/Configuration/FullyAnnotatedConfigReference.xml new file mode 100644 index 0000000..6b3ab7e --- /dev/null +++ b/deploy/Configuration/FullyAnnotatedConfigReference.xml @@ -0,0 +1,329 @@ + + + + + + + + + + + + + http://tfsServer.madeUpDomain.com:8080/tfs/something + + + false + + + mail2bug + + + .\Resources\mail2bug.bin + + + mail2bug + + + .\Resources\mail2bug.bin + + + + + + + + + HelloWorldProject + + + Bug + + + .\Resources\Query.wiq + + + false + + + Assigned To + + + + + + + ConversationID + + + + + + + + + + + + + + + + + + + + + + + + + Iteration 40 + + + + + true + + + true + + + true + + + false + + + + + + + + EWSByRecipients + + + Completed + Error + + + mail2bug@domain.com + + + mail2bug@domain.com + + + mail2bug@domain.com + + + .\Resources\mail2bug.bin + + + + + true + + + true + + + true + + + .\Resources\ReplyTemplateExample.htm + + + .*(bug|work item)\s*#*\s*(?<id>\d+) + !!!(bug|work item)\s*#*\s*(?<id>\d+) + ###\s*(?<fieldName>[^:]*):\s*(?<value>.*) + + + + diff --git a/deploy/Configuration/Mail2BugConfigDibitDevOps.xml b/deploy/Configuration/Mail2BugConfigDibitDevOps.xml new file mode 100644 index 0000000..8b5c5db --- /dev/null +++ b/deploy/Configuration/Mail2BugConfigDibitDevOps.xml @@ -0,0 +1,76 @@ + + + + + + https://devops.dibit.at/Dibit8%20Team + Dibit8 + Bug Report + + .\Configuration\Dibit8_Query.wiq + false + Assigned To + + + + ConversationID + + + + + + + + + + + true + + + + EWSByRecipients + bugs@dibit.at;support@dibit.at + + + bugs@dibit.at + + + bugs@dibit.at + + + .\Configuration\bugsAtDibit.bin + + + true + + true + true + + + .\Configuration\Dibit8_ReplyTemplate.htm + + + .*(bug|work item)\s*#\s*(?<id>\d+) + !!!(bug|work item)\s*#\s*(?<id>\d+) + ###\s*(?<fieldName>[^:]*):\s*(?<value>.*) + + + + From 12ae5a8dc4e7cdc1a1cfe2e15719f3ef2ade9ac4 Mon Sep 17 00:00:00 2001 From: Sebastian Holzer Date: Tue, 4 Jun 2024 10:13:51 +0200 Subject: [PATCH 4/6] Upgraded Microsoft.Exchange.WebServices nuget package; added OAuth authentication support; still to be tested/reviewed --- Mail2Bug/Config.cs | 6 ++++++ Mail2Bug/Email/EWS/EWSConnectionManger.cs | 18 ++++++++++++++---- Mail2Bug/Email/MailboxManagerFactory.cs | 3 ++- Mail2Bug/Helpers/EWSOAuthHelper.cs | 1 + Mail2Bug/Mail2Bug.csproj | 8 +++++--- Mail2Bug/packages.config | 2 +- 6 files changed, 29 insertions(+), 9 deletions(-) diff --git a/Mail2Bug/Config.cs b/Mail2Bug/Config.cs index 1edec41..c5d7493 100644 --- a/Mail2Bug/Config.cs +++ b/Mail2Bug/Config.cs @@ -201,6 +201,11 @@ public enum MailboxServiceType EWSByFolder, EWSByRecipients } + public enum AuthenticationMode + { + OAuth, + Basic + } public MailboxServiceType ServiceType { get; set; } @@ -211,6 +216,7 @@ public enum MailboxServiceType public string EWSPasswordFile { get; set; } public KeyVaultSecret EWSKeyVaultSecret { get; set; } public OAuthSecret EWSOAuthSecret { get; set; } + public AuthenticationMode EWSAuthenticationMode { get; set; } #endregion diff --git a/Mail2Bug/Email/EWS/EWSConnectionManger.cs b/Mail2Bug/Email/EWS/EWSConnectionManger.cs index f99c5ca..edae41e 100644 --- a/Mail2Bug/Email/EWS/EWSConnectionManger.cs +++ b/Mail2Bug/Email/EWS/EWSConnectionManger.cs @@ -7,6 +7,7 @@ using log4net; using Microsoft.Exchange.WebServices.Data; using Newtonsoft.Json.Linq; +using Mail2Bug.Helpers; namespace Mail2Bug.Email.EWS { @@ -27,6 +28,7 @@ public struct Credentials public string EmailAddress; public string UserName; public string Password; + public Config.OAuthSecret OAuthCredentials; } public struct EWSConnection @@ -87,11 +89,19 @@ static private Tuple GetKeyFromCredentials(Credential static private EWSConnection ConnectToEWS(Credentials credentials, bool useConversationGuidOnly) { Logger.DebugFormat("Initializing FolderMailboxManager for email adderss {0}", credentials.EmailAddress); - var exchangeService = new ExchangeService(ExchangeVersion.Exchange2010_SP1) + ExchangeService exchangeService; + if (credentials.OAuthCredentials != null) { - Credentials = new WebCredentials(credentials.UserName, credentials.Password), - Timeout = 60000 - }; + exchangeService = EWSOAuthHelper.OAuthConnectPost(); + } + else + { + exchangeService = new ExchangeService(ExchangeVersion.Exchange2010_SP1) + { + Credentials = new WebCredentials(credentials.UserName, credentials.Password), + Timeout = 60000 + }; + } exchangeService.AutodiscoverUrl( credentials.EmailAddress, diff --git a/Mail2Bug/Email/MailboxManagerFactory.cs b/Mail2Bug/Email/MailboxManagerFactory.cs index fcc86cf..9a20778 100644 --- a/Mail2Bug/Email/MailboxManagerFactory.cs +++ b/Mail2Bug/Email/MailboxManagerFactory.cs @@ -25,7 +25,8 @@ public IMailboxManager CreateMailboxManager(Config.EmailSettings emailSettings) { EmailAddress = emailSettings.EWSMailboxAddress, UserName = emailSettings.EWSUsername, - Password = password + Password = password, + OAuthCredentials = emailSettings.EWSAuthenticationMode == Config.EmailSettings.AuthenticationMode.OAuth ? emailSettings.EWSOAuthSecret : null, }; var exchangeService = _connectionManger.GetConnection(credentials, emailSettings.UseConversationGuidOnly); diff --git a/Mail2Bug/Helpers/EWSOAuthHelper.cs b/Mail2Bug/Helpers/EWSOAuthHelper.cs index d5b0ae8..a985a38 100644 --- a/Mail2Bug/Helpers/EWSOAuthHelper.cs +++ b/Mail2Bug/Helpers/EWSOAuthHelper.cs @@ -67,6 +67,7 @@ public static ExchangeService OAuthConnectPost() var ewsClient = new ExchangeService(); ewsClient.Url = new Uri("https://outlook.office365.com/EWS/Exchange.asmx"); ewsClient.Credentials = new OAuthCredentials(aToken); + ewsClient.Timeout = 60000; return ewsClient; } } diff --git a/Mail2Bug/Mail2Bug.csproj b/Mail2Bug/Mail2Bug.csproj index 627dbb5..522d3f3 100644 --- a/Mail2Bug/Mail2Bug.csproj +++ b/Mail2Bug/Mail2Bug.csproj @@ -59,9 +59,11 @@ ..\packages\Microsoft.Azure.KeyVault.1.0.0\lib\net45\Microsoft.Azure.KeyVault.dll True - - False - ..\packages\Microsoft.Exchange.WebServices.1.2\lib\Microsoft.Exchange.WebServices.dll + + ..\packages\Microsoft.Exchange.WebServices.2.2\lib\40\Microsoft.Exchange.WebServices.dll + + + ..\packages\Microsoft.Exchange.WebServices.2.2\lib\40\Microsoft.Exchange.WebServices.Auth.dll ..\packages\Microsoft.IdentityModel.Clients.ActiveDirectory.2.16.204221202\lib\net45\Microsoft.IdentityModel.Clients.ActiveDirectory.dll diff --git a/Mail2Bug/packages.config b/Mail2Bug/packages.config index 1dfc183..849ce6f 100644 --- a/Mail2Bug/packages.config +++ b/Mail2Bug/packages.config @@ -11,7 +11,7 @@ - + From 0c776bdff0c89f52890bc43113a44b0f1dc7bafc Mon Sep 17 00:00:00 2001 From: Sebastian Holzer Date: Tue, 4 Jun 2024 15:39:52 +0200 Subject: [PATCH 5/6] Finished OAuth implementation; --- Mail2Bug/App.config | 2 +- Mail2Bug/Email/EWS/EWSConnectionManger.cs | 2 +- Mail2Bug/Helpers/EWSOAuthHelper.cs | 21 +++++++++------------ 3 files changed, 11 insertions(+), 14 deletions(-) diff --git a/Mail2Bug/App.config b/Mail2Bug/App.config index 7e6bb9e..5a3e28e 100644 --- a/Mail2Bug/App.config +++ b/Mail2Bug/App.config @@ -7,7 +7,7 @@ - + diff --git a/Mail2Bug/Email/EWS/EWSConnectionManger.cs b/Mail2Bug/Email/EWS/EWSConnectionManger.cs index edae41e..793c086 100644 --- a/Mail2Bug/Email/EWS/EWSConnectionManger.cs +++ b/Mail2Bug/Email/EWS/EWSConnectionManger.cs @@ -92,7 +92,7 @@ static private EWSConnection ConnectToEWS(Credentials credentials, bool useConve ExchangeService exchangeService; if (credentials.OAuthCredentials != null) { - exchangeService = EWSOAuthHelper.OAuthConnectPost(); + exchangeService = EWSOAuthHelper.OAuthConnectPost(credentials.OAuthCredentials, credentials.EmailAddress); } else { diff --git a/Mail2Bug/Helpers/EWSOAuthHelper.cs b/Mail2Bug/Helpers/EWSOAuthHelper.cs index a985a38..4a177ac 100644 --- a/Mail2Bug/Helpers/EWSOAuthHelper.cs +++ b/Mail2Bug/Helpers/EWSOAuthHelper.cs @@ -13,22 +13,16 @@ namespace Mail2Bug.Helpers { public class EWSOAuthHelper { - private const string TenantID = "[Your Tenant ID]"; - private const string ClientID = "[Your Client ID]"; - private const string ClientSecret = "[Your Secret ID]"; - - private const string AgentName = "My Agent Name"; - - public static ExchangeService OAuthConnectPost() + public static ExchangeService OAuthConnectPost(Config.OAuthSecret oAuthCredentials, string emailAddress) { - string LoginURL = String.Format("https://login.microsoftonline.com/{0}/oauth2/v2.0/token", TenantID); + string LoginURL = String.Format("https://login.microsoftonline.com/{0}/oauth2/v2.0/token", oAuthCredentials.TenantID); var LogValues = new Dictionary { { "grant_type", "client_credentials" }, - { "client_id", ClientID }, - { "client_secret", ClientSecret }, - { "scope", "https://graph.microsoft.com/.default" } + { "client_id", oAuthCredentials.ClientID }, + { "client_secret", oAuthCredentials.ClientSecret }, + { "scope", "https://outlook.office365.com/.default" } }; string postData = ""; foreach (var v in LogValues) @@ -49,7 +43,7 @@ public static ExchangeService OAuthConnectPost() request.Method = "POST"; request.ContentType = "application/x-www-form-urlencoded"; request.Accept = "*/*"; - request.UserAgent = AgentName; + request.UserAgent = oAuthCredentials.UserAgentName; request.CachePolicy = new RequestCachePolicy(RequestCacheLevel.NoCacheNoStore); request.ContentLength = data.Length; using (var stream = request.GetRequestStream()) @@ -67,6 +61,9 @@ public static ExchangeService OAuthConnectPost() var ewsClient = new ExchangeService(); ewsClient.Url = new Uri("https://outlook.office365.com/EWS/Exchange.asmx"); ewsClient.Credentials = new OAuthCredentials(aToken); + //Impersonate and include x-anchormailbox headers are required! + ewsClient.ImpersonatedUserId = new ImpersonatedUserId(ConnectingIdType.SmtpAddress, emailAddress); + ewsClient.HttpHeaders.Add("X-AnchorMailbox", emailAddress); ewsClient.Timeout = 60000; return ewsClient; } From bf99d7821261919fae61a1211098c4cedb596acd Mon Sep 17 00:00:00 2001 From: Sebastian Holzer Date: Wed, 5 Jun 2024 07:12:44 +0200 Subject: [PATCH 6/6] Client Secret string for the Exchange application is now stored in an encrypted file rather than plaintext in the config, must be generated with DPAPI; --- .../FullyAnnotatedConfigReference.xml | 7 +++++-- Documentation/Mail2BugConfigExample.xml | 10 +++++++--- Mail2Bug/Config.cs | 2 +- Mail2Bug/Email/EWS/EWSConnectionManger.cs | 19 ++++++++++++++++++- Mail2Bug/Email/MailboxManagerFactory.cs | 5 ++++- Mail2Bug/Helpers/EWSOAuthHelper.cs | 3 ++- 6 files changed, 37 insertions(+), 9 deletions(-) diff --git a/Documentation/FullyAnnotatedConfigReference.xml b/Documentation/FullyAnnotatedConfigReference.xml index 9d6021c..96abd7c 100644 --- a/Documentation/FullyAnnotatedConfigReference.xml +++ b/Documentation/FullyAnnotatedConfigReference.xml @@ -309,8 +309,11 @@ 00000000-0000-0000-0000-000000000000 00000000-0000-0000-0000-000000000000 - - k5r933EbGAQHjTzzNwii71JtRMb0rxI09htsJqMF + + .\Resources\mail2bugAppClientSecret.bin Mail2Bug/1.0.0.0 diff --git a/Documentation/Mail2BugConfigExample.xml b/Documentation/Mail2BugConfigExample.xml index c698586..7c20b35 100644 --- a/Documentation/Mail2BugConfigExample.xml +++ b/Documentation/Mail2BugConfigExample.xml @@ -58,12 +58,16 @@ The application will impersonate the EWSUsername and get access to that application. Make sure to allow the application to access the EWSUsername and allow impersonating it. If you want to use Basic Authentication, omit this element! Warning: You must still setup the EWSPasswordFile and EWSUsername to log in in Azure Devops/TFS. --> - + .\Resources\mail2bugAppClientSecret.bin Mail2Bug/1.0.0.0 - --> + true diff --git a/Mail2Bug/Config.cs b/Mail2Bug/Config.cs index 1edec41..e97f192 100644 --- a/Mail2Bug/Config.cs +++ b/Mail2Bug/Config.cs @@ -32,7 +32,7 @@ public class OAuthSecret { public string TenantID { get; set; } public string ClientID { get; set; } - public string ClientSecret { get; set; } + public string ClientSecretFile { get; set; } public string UserAgentName { get; set; } } diff --git a/Mail2Bug/Email/EWS/EWSConnectionManger.cs b/Mail2Bug/Email/EWS/EWSConnectionManger.cs index 9f3539a..04aa348 100644 --- a/Mail2Bug/Email/EWS/EWSConnectionManger.cs +++ b/Mail2Bug/Email/EWS/EWSConnectionManger.cs @@ -28,7 +28,24 @@ public struct Credentials public string EmailAddress; public string UserName; public string Password; - public Config.OAuthSecret OAuthCredentials; + public CredentialsOAuth OAuthCredentials; + } + + public class CredentialsOAuth + { + public CredentialsOAuth() { } + public CredentialsOAuth(Config.EmailSettings emailSettings, string clientSecret) + { + TenantID = emailSettings.EWSOAuthSecret.TenantID; + ClientID = emailSettings.EWSOAuthSecret.ClientID; + ClientSecret = clientSecret; + UserAgentName = emailSettings.EWSOAuthSecret.UserAgentName; + } + + public string TenantID { get; set; } + public string ClientID { get; set; } + public string ClientSecret { get; set; } + public string UserAgentName { get; set; } } public struct EWSConnection diff --git a/Mail2Bug/Email/MailboxManagerFactory.cs b/Mail2Bug/Email/MailboxManagerFactory.cs index f360a76..9e6a98d 100644 --- a/Mail2Bug/Email/MailboxManagerFactory.cs +++ b/Mail2Bug/Email/MailboxManagerFactory.cs @@ -21,12 +21,15 @@ public IMailboxManager CreateMailboxManager(Config.EmailSettings emailSettings) { var credentialsHelper = new Helpers.CredentialsHelper(); string password = credentialsHelper.GetPassword(emailSettings.EWSPasswordFile, emailSettings.EncryptionScope, emailSettings.EWSKeyVaultSecret); + string clientSecret = emailSettings.EWSOAuthSecret != null + ? credentialsHelper.GetPassword(emailSettings.EWSOAuthSecret.ClientSecretFile, emailSettings.EncryptionScope, emailSettings.EWSKeyVaultSecret) + : null; var credentials = new EWSConnectionManger.Credentials { EmailAddress = emailSettings.EWSMailboxAddress, UserName = emailSettings.EWSUsername, Password = password, - OAuthCredentials = emailSettings.EWSOAuthSecret, + OAuthCredentials = emailSettings.EWSOAuthSecret != null ? new EWSConnectionManger.CredentialsOAuth(emailSettings, clientSecret) : null, }; var exchangeService = _connectionManger.GetConnection(credentials, emailSettings.UseConversationGuidOnly); diff --git a/Mail2Bug/Helpers/EWSOAuthHelper.cs b/Mail2Bug/Helpers/EWSOAuthHelper.cs index 4a177ac..deb475f 100644 --- a/Mail2Bug/Helpers/EWSOAuthHelper.cs +++ b/Mail2Bug/Helpers/EWSOAuthHelper.cs @@ -8,12 +8,13 @@ using System.Net; using System.Text; using System.Threading.Tasks; +using Mail2Bug.Email.EWS; namespace Mail2Bug.Helpers { public class EWSOAuthHelper { - public static ExchangeService OAuthConnectPost(Config.OAuthSecret oAuthCredentials, string emailAddress) + public static ExchangeService OAuthConnectPost(EWSConnectionManger.CredentialsOAuth oAuthCredentials, string emailAddress) { string LoginURL = String.Format("https://login.microsoftonline.com/{0}/oauth2/v2.0/token", oAuthCredentials.TenantID);