From d90493cf2f1f435b060f3ae01600f05f801f24a8 Mon Sep 17 00:00:00 2001 From: "v.shishlov" Date: Sun, 29 Aug 2021 18:28:47 +0300 Subject: [PATCH] add ssl 1.2 --- CPE.sln | 14 +++- .../CPE.App.Api.Test/CPE.App.Api.Test.csproj | 81 +++++++++++++++++++ .../Properties/AssemblyInfo.cs | 20 +++++ .../StatementControllerTest.cs | 23 ++++++ CPE/CPE.App/CPE.App.Api.Test/app.config | 43 ++++++++++ CPE/CPE.App/CPE.App.Api.Test/packages.config | 7 ++ CPE/CPE.App/CPE.App.Api/CPE.App.Api.csproj | 1 + .../CPE.App.Api/Helpers/SendEmailHelper.cs | 13 +-- .../CPE.App.Api/Helpers/TinCanHelper.cs | 48 ++++++++--- CPE/CPE.App/CPE.App.Api/Web.config | 77 +++++++----------- CPE/CPE.App/CPE.App.Api/log4net.config | 4 +- CPE/CPE.App/CPE.App.Web/CPE.App.Web.csproj | 2 + .../Controllers/IndexController.cs | 19 ++++- .../CPE.App.Web/Helpers/SendEmailHelper.cs | 27 +++++++ 14 files changed, 312 insertions(+), 67 deletions(-) create mode 100644 CPE/CPE.App/CPE.App.Api.Test/CPE.App.Api.Test.csproj create mode 100644 CPE/CPE.App/CPE.App.Api.Test/Properties/AssemblyInfo.cs create mode 100644 CPE/CPE.App/CPE.App.Api.Test/StatementControllerTest.cs create mode 100644 CPE/CPE.App/CPE.App.Api.Test/app.config create mode 100644 CPE/CPE.App/CPE.App.Api.Test/packages.config create mode 100644 CPE/CPE.App/CPE.App.Web/Helpers/SendEmailHelper.cs diff --git a/CPE.sln b/CPE.sln index eeffbfe..7009806 100644 --- a/CPE.sln +++ b/CPE.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 14 -VisualStudioVersion = 14.0.24720.0 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.31624.102 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CPE.App.Api", "CPE\CPE.App\CPE.App.Api\CPE.App.Api.csproj", "{6E4AE2DF-5EA5-431B-BB49-193F11171206}" EndProject @@ -26,6 +26,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CPE.App.NotifyService", "CP EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CPE.App.NotifyConsole", "CPE\CPE.App\CPE.App.NotifyConsole\CPE.App.NotifyConsole.csproj", "{A71359A1-3731-436D-83E9-5EF779E4BF47}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CPE.App.Api.Test", "CPE\CPE.App\CPE.App.Api.Test\CPE.App.Api.Test.csproj", "{097E31AB-E16C-4D32-839A-539F93973D35}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -59,6 +61,10 @@ Global {A71359A1-3731-436D-83E9-5EF779E4BF47}.Debug|Any CPU.Build.0 = Debug|Any CPU {A71359A1-3731-436D-83E9-5EF779E4BF47}.Release|Any CPU.ActiveCfg = Release|Any CPU {A71359A1-3731-436D-83E9-5EF779E4BF47}.Release|Any CPU.Build.0 = Release|Any CPU + {097E31AB-E16C-4D32-839A-539F93973D35}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {097E31AB-E16C-4D32-839A-539F93973D35}.Debug|Any CPU.Build.0 = Debug|Any CPU + {097E31AB-E16C-4D32-839A-539F93973D35}.Release|Any CPU.ActiveCfg = Release|Any CPU + {097E31AB-E16C-4D32-839A-539F93973D35}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -70,5 +76,9 @@ Global {3161F348-B6C7-4B00-BC03-74B67A7949A1} = {76CEA54F-65A1-413F-A08C-CF3A029897B6} {165A20D7-30C3-4CAB-8BC1-D4C23219B633} = {76CEA54F-65A1-413F-A08C-CF3A029897B6} {A71359A1-3731-436D-83E9-5EF779E4BF47} = {76CEA54F-65A1-413F-A08C-CF3A029897B6} + {097E31AB-E16C-4D32-839A-539F93973D35} = {76CEA54F-65A1-413F-A08C-CF3A029897B6} + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {FBF87F62-852B-4BEF-AB03-1E1602B43317} EndGlobalSection EndGlobal diff --git a/CPE/CPE.App/CPE.App.Api.Test/CPE.App.Api.Test.csproj b/CPE/CPE.App/CPE.App.Api.Test/CPE.App.Api.Test.csproj new file mode 100644 index 0000000..82101b5 --- /dev/null +++ b/CPE/CPE.App/CPE.App.Api.Test/CPE.App.Api.Test.csproj @@ -0,0 +1,81 @@ + + + + + + Debug + AnyCPU + {097E31AB-E16C-4D32-839A-539F93973D35} + Library + Properties + CPE.App.Api.Test + CPE.App.Api.Test + v4.5.2 + 512 + {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + 15.0 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + $(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages + False + UnitTest + + + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\..\..\packages\MSTest.TestFramework.2.1.2\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.dll + + + ..\..\..\packages\MSTest.TestFramework.2.1.2\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.dll + + + ..\..\..\packages\Newtonsoft.Json.6.0.4\lib\net45\Newtonsoft.Json.dll + + + ..\..\..\packages\Shouldly.2.8.2\lib\net451\Shouldly.dll + + + + + + + + + + + + + + + {6E4AE2DF-5EA5-431B-BB49-193F11171206} + CPE.App.Api + + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + \ No newline at end of file diff --git a/CPE/CPE.App/CPE.App.Api.Test/Properties/AssemblyInfo.cs b/CPE/CPE.App/CPE.App.Api.Test/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..2938e77 --- /dev/null +++ b/CPE/CPE.App/CPE.App.Api.Test/Properties/AssemblyInfo.cs @@ -0,0 +1,20 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +[assembly: AssemblyTitle("CPE.App.Api.Test")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("CPE.App.Api.Test")] +[assembly: AssemblyCopyright("Copyright © 2021")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +[assembly: ComVisible(false)] + +[assembly: Guid("097e31ab-e16c-4d32-839a-539f93973d35")] + +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/CPE/CPE.App/CPE.App.Api.Test/StatementControllerTest.cs b/CPE/CPE.App/CPE.App.Api.Test/StatementControllerTest.cs new file mode 100644 index 0000000..26d04c8 --- /dev/null +++ b/CPE/CPE.App/CPE.App.Api.Test/StatementControllerTest.cs @@ -0,0 +1,23 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System; +using CPE.App.Api.Helpers; +using CPE.App.Api.Models; +using Newtonsoft.Json; +using Shouldly; + +namespace CPE.App.Api.Test +{ + [TestClass] + public class StatementControllerTest + { + [TestMethod] + public void HandleStatementTest() + { + var tincanObject = + "{\"id\":null,\"actor\":{\"name\":\"Patricia Berry\",\"mbox\":\"mailto:pberry@cpeincmail.com\"},\"verb\":{\"id\":\"http://adlnet.gov/expapi/verbs/passed\"},\"result\":{\"score\":{\"scaled\":1,\"raw\":0,\"min\":0,\"max\":0},\"success\":true,\"completion\":false},\"timestamp\":\"08/28/2021 16:38:19\",\"version\":null,\"object\":{\"id\":\"https://learning.elucidat.com/course/611ecf21dbbae-611fca09461e2\",\"definition\":{\"name\":{\"en-US\":\"Ethics for Hawaii CPAs \"}}}}"; + TinCanStatementModel statement = JsonConvert.DeserializeObject(tincanObject); + var done = TinCanHelper.HandleStatement(statement); + done.ShouldBe(true); + } + } +} diff --git a/CPE/CPE.App/CPE.App.Api.Test/app.config b/CPE/CPE.App/CPE.App.Api.Test/app.config new file mode 100644 index 0000000..08545f7 --- /dev/null +++ b/CPE/CPE.App/CPE.App.Api.Test/app.config @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/CPE/CPE.App/CPE.App.Api.Test/packages.config b/CPE/CPE.App/CPE.App.Api.Test/packages.config new file mode 100644 index 0000000..eab5efc --- /dev/null +++ b/CPE/CPE.App/CPE.App.Api.Test/packages.config @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/CPE/CPE.App/CPE.App.Api/CPE.App.Api.csproj b/CPE/CPE.App/CPE.App.Api/CPE.App.Api.csproj index 37c6913..77179e4 100644 --- a/CPE/CPE.App/CPE.App.Api/CPE.App.Api.csproj +++ b/CPE/CPE.App/CPE.App.Api/CPE.App.Api.csproj @@ -319,6 +319,7 @@ + diff --git a/CPE/CPE.App/CPE.App.Api/Helpers/SendEmailHelper.cs b/CPE/CPE.App/CPE.App.Api/Helpers/SendEmailHelper.cs index ee506b2..ec69d3f 100644 --- a/CPE/CPE.App/CPE.App.Api/Helpers/SendEmailHelper.cs +++ b/CPE/CPE.App/CPE.App.Api/Helpers/SendEmailHelper.cs @@ -1,9 +1,5 @@ using System; -using System.Collections.Generic; using System.Configuration; -using System.Linq; -using System.Web; -using System.IO; using CPE.App.Web.Models; using System.Net.Mail; using CPE.App.Api.Models; @@ -15,9 +11,16 @@ namespace CPE.App.Api.Helpers { public static bool SendCertificateEmail(PurchasedCourse course) { + var courseEmail = course.Email; + var emailTest = ConfigurationManager.AppSettings["EmailTest"]; + if (!string.IsNullOrWhiteSpace(emailTest)) + { + courseEmail = emailTest; + } + //elucidat cert email var cDate = course.CertificateDate.Value.ToString("yyyyMMdd"); - MailMessage mail = new MailMessage(ConfigurationManager.AppSettings["EmailSender"], course.Email); + MailMessage mail = new MailMessage(ConfigurationManager.AppSettings["EmailSender"], courseEmail); SmtpClient client = new SmtpClient(); client.Port = 25; client.DeliveryMethod = SmtpDeliveryMethod.Network; diff --git a/CPE/CPE.App/CPE.App.Api/Helpers/TinCanHelper.cs b/CPE/CPE.App/CPE.App.Api/Helpers/TinCanHelper.cs index 7e7a0e7..9629fc7 100644 --- a/CPE/CPE.App/CPE.App.Api/Helpers/TinCanHelper.cs +++ b/CPE/CPE.App/CPE.App.Api/Helpers/TinCanHelper.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.Linq; using System.Web; +using Newtonsoft.Json; namespace CPE.App.Api.Helpers { @@ -13,10 +14,10 @@ namespace CPE.App.Api.Helpers { // statement.Verb.Id=http://adlnet.gov/expapi/verbs/answered // statement.Verb.Id=http://adlnet.gov/expapi/verbs/experienced - + var dtNow = DateTime.UtcNow.ToString("yyyyMMdd_HHmmss"); if (statement.Verb.Id.IndexOf("passed")>-1) { - Utilities.LogWrapper.Info("[TinCanHelper][HandleStatement] {0} statement.Verb.Id={1}", DateTime.UtcNow.ToString("yyyyMMdd_HHmmss"), statement.Verb.Id); + Utilities.LogWrapper.Info("[TinCanHelper][HandleStatement] {0} statement.Verb.Id={1}. statement={2}", dtNow, statement.Verb.Id, JsonConvert.SerializeObject(statement)); //parse statement to db variables var email = statement.Actor.Mbox.Substring(7); @@ -24,15 +25,40 @@ namespace CPE.App.Api.Helpers var lname = statement.Actor.Name.Substring(statement.Actor.Name.LastIndexOf(" ") + 1); var courseUrl = statement.Object.Id.Substring(statement.Object.Id.LastIndexOf("/") + 1); var courseName = statement.Object.Definition.Name.EnUs; + bool done; //cpe has test data with multiple, currently valid purchases of the same course for one user, which causes problems but is not a real-world problem. //elucidat tracks all users globally by email address so a tincan statement won't identify a specific purchase here //unless we create unique email addy (e.g. email+ticket@mail.com) when originally logging them in to content - var course = BaseController.Database.PurchasedCourses.FirstOrDefault(c => c.Email == email && c.ContentUrl == courseUrl && c.CertificateDate == null); + var course = BaseController.Database.PurchasedCourses.FirstOrDefault(c => + c.Email == email && c.ContentUrl == courseUrl && c.CertificateDate == null); if (course == null) { - Utilities.LogWrapper.Info("[TinCanHelper][HandleStatement] {0} no action, cert already earned email={1} courseName={2}", DateTime.UtcNow.ToString("yyyyMMdd_HHmmss"), email, courseName); + Utilities.LogWrapper.Info("[TinCanHelper][HandleStatement] {0} no action 1, cert already earned email={1} courseName={2}", dtNow, email, courseName); //no action, cert already earned + //try + //{ + // course = BaseController.Database.PurchasedCourses.FirstOrDefault(c => c.Email == email && c.ContentUrl == courseUrl && c.CertificateDate!=null); + // if (course == null) + // { + // Utilities.LogWrapper.Info("[TinCanHelper][HandleStatement] {0} no action, course == null, select courseName={1} from db with CertificateDate.", dtNow, courseName); + // } + + // Utilities.LogWrapper.Info("[TinCanHelper][HandleStatement] {0} no action, select courseName={1} from db with CertificateDate. course={2}", dtNow, courseName, JsonConvert.SerializeObject(course)); + + // done = SendEmailHelper.SendCertificateEmail(course); + + // Utilities.LogWrapper.Info("[TinCanHelper][HandleStatement] {0} no action, send courseName={1} from db to email={2} successfully", dtNow, courseName, email); + //} + //catch (Exception exception) + //{ + // var innerException = ""; + // if (exception.InnerException != null) innerException = exception.InnerException.ToString(); + // Utilities.LogWrapper.Info("[TinCanHelper][HandleStatement] {0} email={1} courseName={2} exception={3}", dtNow, email, courseName, exception.ToString()+ innerException); + //} + + //Utilities.LogWrapper.Info("[TinCanHelper][HandleStatement] {0} cert sent email={1} courseName={2}", dtNow, email, courseName); + return true; } @@ -43,12 +69,12 @@ namespace CPE.App.Api.Helpers } catch (Exception exception) { - Utilities.LogWrapper.Error("[TinCanHelper][HandleStatement] {0} email={1} courseName={2} exception={3}", DateTime.UtcNow.ToString("yyyyMMdd_HHmmss"), email, courseName, exception.ToString()); + Utilities.LogWrapper.Error("[TinCanHelper][HandleStatement] {0} email={1} courseName={2} exception={3}", dtNow, email, courseName, exception.ToString()); } - var done = SendEmailHelper.SendCertificateEmail(course); + done = SendEmailHelper.SendCertificateEmail(course); - Utilities.LogWrapper.Info("[TinCanHelper][HandleStatement] {0} cert sent email={1} courseName={2}", DateTime.UtcNow.ToString("yyyyMMdd_HHmmss"), email, courseName); + Utilities.LogWrapper.Info("[TinCanHelper][HandleStatement] {0} cert sent email={1} courseName={2}", dtNow, email, courseName); //umm why am i not returning done here? return true; @@ -57,7 +83,7 @@ namespace CPE.App.Api.Helpers if (statement.Verb.Id.IndexOf("failed") > -1) { - Utilities.LogWrapper.Info("[TinCanHelper][HandleStatement] {0} statement.Verb.Id={1}", DateTime.UtcNow.ToString("yyyyMMdd_HHmmss"), statement.Verb.Id); + Utilities.LogWrapper.Info("[TinCanHelper][HandleStatement] {0} statement.Verb.Id={1}. statement={2}", dtNow, statement.Verb.Id, JsonConvert.SerializeObject(statement)); //parse statement to db variables var email = statement.Actor.Mbox.Substring(7); @@ -76,7 +102,7 @@ namespace CPE.App.Api.Helpers return true; } - Utilities.LogWrapper.Info("[TinCanHelper][HandleStatement] {0} course.Ticket={1}", DateTime.UtcNow.ToString("yyyyMMdd_HHmmss"), course.Ticket); + Utilities.LogWrapper.Info("[TinCanHelper][HandleStatement] {0} course.Ticket={1}", dtNow, course.Ticket); if (!course.FailedAttempts.HasValue) { @@ -89,10 +115,10 @@ namespace CPE.App.Api.Helpers } catch (Exception exception) { - Utilities.LogWrapper.Error("[TinCanHelper][HandleStatement] {0} email={1} courseName={2} exception={3}", DateTime.UtcNow.ToString("yyyyMMdd_HHmmss"), email, courseName, exception.ToString()); + Utilities.LogWrapper.Error("[TinCanHelper][HandleStatement] {0} email={1} courseName={2} exception={3}", dtNow, email, courseName, exception.ToString()); } - Utilities.LogWrapper.Info("[TinCanHelper][HandleStatement] {0} failure recorded email={1} courseName={2}", DateTime.UtcNow.ToString("yyyyMMdd_HHmmss"), email, courseName); + Utilities.LogWrapper.Info("[TinCanHelper][HandleStatement] {0} failure recorded email={1} courseName={2}", dtNow, email, courseName); return true; } diff --git a/CPE/CPE.App/CPE.App.Api/Web.config b/CPE/CPE.App/CPE.App.Api/Web.config index 60d407d..8dc71cb 100644 --- a/CPE/CPE.App/CPE.App.Api/Web.config +++ b/CPE/CPE.App/CPE.App.Api/Web.config @@ -1,47 +1,39 @@ - + - +
- -
-
-
-
- + - - - - - + + + + + + + - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + - - - - - - - - - + + - + - + + @@ -152,5 +138,4 @@ - - + diff --git a/CPE/CPE.App/CPE.App.Api/log4net.config b/CPE/CPE.App/CPE.App.Api/log4net.config index c2cb045..b0a26e4 100644 --- a/CPE/CPE.App/CPE.App.Api/log4net.config +++ b/CPE/CPE.App/CPE.App.Api/log4net.config @@ -2,7 +2,7 @@ - + @@ -17,7 +17,7 @@ - + diff --git a/CPE/CPE.App/CPE.App.Web/CPE.App.Web.csproj b/CPE/CPE.App/CPE.App.Web/CPE.App.Web.csproj index 7312f94..bd180d3 100644 --- a/CPE/CPE.App/CPE.App.Web/CPE.App.Web.csproj +++ b/CPE/CPE.App/CPE.App.Web/CPE.App.Web.csproj @@ -29,6 +29,7 @@ ..\..\..\ true ..\..\..\packages\WebGrease.1.5.2\lib + true @@ -212,6 +213,7 @@ + diff --git a/CPE/CPE.App/CPE.App.Web/Controllers/IndexController.cs b/CPE/CPE.App/CPE.App.Web/Controllers/IndexController.cs index 227a3c1..813d055 100644 --- a/CPE/CPE.App/CPE.App.Web/Controllers/IndexController.cs +++ b/CPE/CPE.App/CPE.App.Web/Controllers/IndexController.cs @@ -406,7 +406,7 @@ namespace CPE.App.Web.Controllers { public ActionResult Email() { var email = new MailMessage { To = { - "tallen@intesolv.com" + "sophia@sophicsystems.com" }, Subject = "[CPE] Email Test", Body = "Email test has been received.", @@ -417,6 +417,23 @@ namespace CPE.App.Web.Controllers { return Redirect("/"); } + public ActionResult SendCerificateEmail(string email, string url, string key) + { + if (key != "q1w2e3") return Content("Bad key"); + var course = Database.PurchasedCourses + .Where(c => c.Email == email && c.ContentUrl == url) + .OrderByDescending(c => c.CertificateDate).FirstOrDefault(); + + var done = SendEmailHelperWeb.SendCertificateEmail(course); + + var s = url.Split('-'); + var courseName = Database.CourseDetails + .FirstOrDefault(c => c.ReleaseCode == s[1])?.Name; + + Utilities.LogWrapper.Info("[TinCanHelper][HandleStatement] {0} cert sent email={1} courseName={2}", DateTime.UtcNow.ToString("yyyyMMdd_HHmmss"), email, courseName); + + return Content("Certificate send successfully"); + } [HttpPost] public ActionResult Admin(string login, string passcode) { diff --git a/CPE/CPE.App/CPE.App.Web/Helpers/SendEmailHelper.cs b/CPE/CPE.App/CPE.App.Web/Helpers/SendEmailHelper.cs new file mode 100644 index 0000000..93128b5 --- /dev/null +++ b/CPE/CPE.App/CPE.App.Web/Helpers/SendEmailHelper.cs @@ -0,0 +1,27 @@ +using System.Configuration; +using CPE.App.Web.Models; +using System.Net.Mail; + +namespace CPE.App.Web.Helpers +{ + public class SendEmailHelperWeb + { + public static bool SendCertificateEmail(PurchasedCourse course) + { + //elucidat cert email + var cDate = course.CertificateDate.Value.ToString("yyyyMMdd"); + MailMessage mail = new MailMessage(ConfigurationManager.AppSettings["EmailSender"], course.Email); + SmtpClient client = new SmtpClient(); + client.Port = 25; + client.DeliveryMethod = SmtpDeliveryMethod.Network; + client.UseDefaultCredentials = false; + client.Host = "localhost"; + mail.Subject = ConfigurationManager.AppSettings["EmailSubject"]; + string mailBodyText = CPE.Utilities.Email.RenderEmail(course.ContentUrl, course.CertificateDate, course.Ticket); + mail.Body = mailBodyText; + mail.IsBodyHtml = true; + client.Send(mail); + return true; + } + } +} \ No newline at end of file -- 2.20.1