public override async Task <SendEmailResult> SendEmailAsync <TTemplate>(string emailAddress, string templateId, TTemplate parameters, bool test) { // convert the model's public properties to a dictionary var mergeParameters = parameters.GetPropertiesDictionary(); // prefix subject with environment name mergeParameters["Environment"] = SharedOptions.IsProduction() ? "" : $"[{SharedOptions.Environment}] "; // determine which client to use var client = test ? TestClient : ProductionClient; // send email var response = await client.SendEmailAsync( emailAddress, templateId, mergeParameters, Options.ClientReference); // get result var notification = await client.GetNotificationByIdAsync(response.id); return(new SendEmailResult { Status = notification.status, Server = "Gov Notify", ServerUsername = Options.ClientReference, EmailAddress = emailAddress, EmailSubject = notification.subject }); }
public PagedResult<EmployerRecord> LoadSearch(string searchText) { var lastSearchText = _Session["LastPrivateSearchText"] as string; var remoteTotal = _Session["LastPrivateSearchRemoteTotal"].ToInt32(); PagedResult<EmployerRecord> result = null; if (!SharedOptions.IsProduction() && _httpContextAccessor.HttpContext != null && _httpContextAccessor.HttpContext.Request.Query["fail"].ToBoolean()) { ClearSearch(); } else if (remoteTotal == -1 || string.IsNullOrWhiteSpace(lastSearchText) || searchText != lastSearchText) { ClearSearch(); } else { result = _Session.Get<PagedResult<EmployerRecord>>("LastPrivateSearchResults"); if (result == null) result = new PagedResult<EmployerRecord>(); } return result; }
private bool CheckPasswordBasedOnHashingAlgorithm(User user, string password) { switch (user.HashingAlgorithm) { case HashingAlgorithm.Unhashed: if (SharedOptions.IsProduction()) { break; } return(user.PasswordHash == password); case HashingAlgorithm.SHA512: return(user.PasswordHash == Crypto.GetSHA512Checksum(password)); case HashingAlgorithm.PBKDF2: return(user.PasswordHash == Crypto.GetPBKDF2(password, Convert.FromBase64String(user.Salt))); case HashingAlgorithm.PBKDF2AppliedToSHA512: return(user.PasswordHash == Crypto.GetPBKDF2(Crypto.GetSHA512Checksum(password), Convert.FromBase64String(user.Salt))); case HashingAlgorithm.Unknown: break; default: throw new InvalidEnumArgumentException($"Invalid enum argument: {user.HashingAlgorithm}"); } throw new InvalidOperationException($"Hashing algorithm should not be {user.HashingAlgorithm}"); }
public IEnumerable <Client> Get() { if ((_sharedOptions.IsProduction() || _sharedOptions.IsPreProduction()) && _sharedOptions.AuthSecret.EqualsI("secret", "", null)) { throw new Exception( "Invalid ClientSecret for IdentityServer. You must set 'AuthSecret' to a unique key"); } return(new[] { new Client { ClientName = "Modern Slavery reporting service", ClientId = "ModernSlaveryServiceWebsite", ClientSecrets = new List <Secret> { new Secret(_sharedOptions.AuthSecret.GetSHA256Checksum()) }, ClientUri = _sharedOptions.SiteAuthority, AllowedGrantTypes = GrantTypes.Implicit, AllowAccessTokensViaBrowser = true, RequireConsent = false, RedirectUris = new List <string> { _sharedOptions.SiteAuthority, _sharedOptions.SiteAuthority + "signin-oidc", _sharedOptions.SiteAuthority + "manage-organisations", _sharedOptions.DoneUrl }, PostLogoutRedirectUris = new List <string> { _sharedOptions.SiteAuthority, _sharedOptions.SiteAuthority + "signout-callback-oidc", _sharedOptions.SiteAuthority + "manage-organisations", _sharedOptions.SiteAuthority + "manage-account/complete-change-email", _sharedOptions.SiteAuthority + "manage-account/close-account-completed", _sharedOptions.DoneUrl }, AllowedScopes = new List <string> { IdentityServerConstants.StandardScopes.OpenId, IdentityServerConstants.StandardScopes.Profile, "roles" }, Properties = new Dictionary <string, string> { { "AutomaticRedirectAfterSignOut", "true" } } } }); }
public void Register(IDependencyBuilder builder) { if (string.IsNullOrWhiteSpace(_sharedOptions.GoogleAnalyticsAccountId)) { if (_sharedOptions.IsProduction()) { throw new ArgumentNullException(nameof(_sharedOptions.GoogleAnalyticsAccountId)); } builder.Autofac.RegisterType <FakeWebTracker>().As <IWebTracker>().SingleInstance(); return; } //Add a dedicated httpclient for Google Analytics tracking with exponential retry policy builder.Services.AddHttpClient <IWebTracker, GoogleAnalyticsTracker>(nameof(IWebTracker), client => { client.BaseAddress = GoogleAnalyticsTracker.BaseUri; client.DefaultRequestHeaders.Clear(); client.DefaultRequestHeaders.ConnectionClose = false; ServicePointManager.FindServicePoint(client.BaseAddress).ConnectionLeaseTimeout = 60 * 1000; }) .SetHandlerLifetime(TimeSpan.FromMinutes(10)) .AddPolicyHandler( //see https://developers.google.com/analytics/devguides/config/mgmt/v3/errors HttpPolicyExtensions .HandleTransientHttpError() .WaitAndRetryAsync(6, retryAttempt => TimeSpan.FromMilliseconds(new Random().Next(1, 1000)) + TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)))); //Register WebTracker builder.Autofac.RegisterType <GoogleAnalyticsTracker>() .As <IWebTracker>() .SingleInstance() .WithParameter( (p, ctx) => p.ParameterType == typeof(HttpClient), (p, ctx) => ctx.Resolve <IHttpClientFactory>().CreateClient(nameof(IWebTracker))) .WithParameter("trackingId", _sharedOptions.GoogleAnalyticsAccountId); }
public void DeleteAllTestRecords(DateTime?deadline = null) { if (SharedOptions.IsProduction()) { throw new Exception("Attempt to delete all test data from production environment"); } if (string.IsNullOrWhiteSpace(SharedOptions.TestPrefix)) { throw new ArgumentNullException(nameof(SharedOptions.TestPrefix)); } if (deadline == null || deadline.Value == DateTime.MinValue) { ExecuteSqlCommand( $"UPDATE UO SET AddressId=null FROM UserOrganisations UO WITH (ROWLOCK) JOIN organisations O ON O.OrganisationId=UO.OrganisationId where O.OrganisationName like '{SharedOptions.TestPrefix}%'"); ExecuteSqlCommand( $"UPDATE UO SET AddressId=null FROM UserOrganisations UO WITH (ROWLOCK) JOIN Users U ON U.UserId=UO.UserId where U.Firstname like '{SharedOptions.TestPrefix}%'"); ExecuteSqlCommand( $"UPDATE Organisations WITH (ROWLOCK) SET LatestAddressId=null, LatestRegistration_OrganisationId=null,LatestRegistration_UserId=null,LatestReturnId=null,LatestScopeId=null where OrganisationName like '{SharedOptions.TestPrefix}%'"); ExecuteSqlCommand($"DELETE Users WITH (ROWLOCK) where Firstname like '{SharedOptions.TestPrefix}%'"); ExecuteSqlCommand( $"DELETE Organisations WITH (ROWLOCK) where OrganisationName like '{SharedOptions.TestPrefix}%'"); } else { var dl = deadline.Value.ToString("yyyy-MM-dd HH:mm:ss"); ExecuteSqlCommand( $"UPDATE UO SET AddressId=null FROM UserOrganisations UO WITH (ROWLOCK) JOIN organisations O ON O.OrganisationId=UO.OrganisationId where O.OrganisationName like '{SharedOptions.TestPrefix}%' AND UO.Created<'{dl}'"); ExecuteSqlCommand( $"UPDATE UO SET AddressId=null FROM UserOrganisations UO WITH (ROWLOCK) JOIN Users U ON U.UserId=UO.UserId where U.Firstname like '{SharedOptions.TestPrefix}%' AND UO.Created<'{dl}'"); ExecuteSqlCommand( $"UPDATE Organisations WITH (ROWLOCK) SET LatestAddressId=null, LatestRegistration_OrganisationId=null,LatestRegistration_UserId=null,LatestReturnId=null,LatestScopeId=null where OrganisationName like '{SharedOptions.TestPrefix}%' AND Created<'{dl}'"); ExecuteSqlCommand( $"DELETE Users WITH (ROWLOCK) where Firstname like '{SharedOptions.TestPrefix}%' AND Created<'{dl}'"); ExecuteSqlCommand( $"DELETE Organisations WITH (ROWLOCK) where OrganisationName like '{SharedOptions.TestPrefix}%' AND Created<'{dl}'"); } }
public async void SendSuccessfulSubmissionEmail(string emailAddress, string organisationName, string submittedOrUpdated, string reportingPeriod, string reportLink) { var personalisation = new Dictionary <string, dynamic> { { "OrganisationName", organisationName }, { "SubmittedOrUpdated", submittedOrUpdated }, { "ReportingPeriod", reportingPeriod }, { "ReportLink", reportLink }, { "Environment", SharedOptions.IsProduction() ? "" : $"[{SharedOptions.Environment}] " } }; var notifyEmail = new SendEmailRequest { EmailAddress = emailAddress, TemplateId = EmailTemplates.SendSuccessfulSubmissionEmail, Personalisation = personalisation }; await AddEmailToQueue(notifyEmail); }
public override async Task <SendEmailResult> SendEmailAsync <TModel>(string emailAddress, string templateId, TModel model, bool test) { // convert the model's public properties to a dictionary var mergeParameters = model.GetPropertiesDictionary(); // prefix subject with environment name mergeParameters["Environment"] = SharedOptions.IsProduction() ? "" : $"[{SharedOptions.Environment}] "; // get template var emailTemplateInfo = EmailTemplateRepo.GetByTemplateId(templateId); var htmlContent = File.ReadAllText(emailTemplateInfo.FilePath); // parse html var parser = new HtmlParser(); var document = parser.ParseDocument(htmlContent); // remove the meta data comments from the document var templateMetaData = document.Descendents <IComment>().FirstOrDefault(); if (templateMetaData == null) { new NullReferenceException(nameof(templateMetaData)); } templateMetaData.Remove(); var messageSubject = emailTemplateInfo.EmailSubject; var messageHtml = document.ToHtml(); var messageText = document.Text(); // merge the template parameters foreach ((string name, object value) in mergeParameters) { messageSubject = messageSubject.Replace($"(({name}))", value.ToString()); messageHtml = messageHtml.Replace($"(({name}))", value.ToString()); } var smtpServer = string.IsNullOrWhiteSpace(Options.Server) ? Options.Server2 : Options.Server; var smtpServerPort = Options.Port <= 0 ? Options.Port2 : Options.Port; var smtpUsername = string.IsNullOrWhiteSpace(Options.Username) ? Options.Username2 : Options.Username; var smtpPassword = string.IsNullOrWhiteSpace(Options.Password) ? Options.Password2 : Options.Password; await Email.QuickSendAsync( messageSubject, Options.SenderEmail, Options.SenderName, Options.ReplyEmail, emailAddress, messageHtml, smtpServer, smtpUsername, smtpPassword, smtpServerPort, test : test); return(new SendEmailResult { Status = "sent", Server = $"{smtpServer}:{smtpServerPort}", ServerUsername = smtpUsername, EmailAddress = emailAddress, EmailSubject = messageSubject, EmailMessagePlainText = messageText }); }