public async Task <IOperationResult <ConfirmationRequestData> > ProcessConfigurationChangeRequest( string vaultIp, string vaultPort, string vaultToken) { if (_lastConfigurationChangeRequestAt.HasValue && _lastConfigurationChangeRequestAt.Value.AddMinutes(MINUTES_BETWEEN_CONFIGURATION_CHANGE_REQUESTS) > DateTime.Now) { return(OperationResult.UserError <ConfirmationRequestData>($"Please, wait. The interval between configuration requests is: {MINUTES_BETWEEN_CONFIGURATION_CHANGE_REQUESTS}")); } else { _lastConfigurationChangeRequestAt = DateTime.Now; } return(await OperationResult .Try(() => CreateVaultClient(vaultIp, vaultPort, vaultToken)) .BindAsync(async(x) => await ReadConfiguration(x)) .Bind(candidateProtectedConfiguration => { // A new configuration has been read. We set it as a candidate. _candidateProtectedConfiguration = candidateProtectedConfiguration; // The email is stored in protected form. If it's been set already, we use the current one, otherwise the candidate one var requestFields = new[] { ConfigurationKey.AdminEmail, ConfigurationKey.SmtpHost, ConfigurationKey.SmtpPort, ConfigurationKey.MailingAccountLogin, ConfigurationKey.MailingAccountPassword }; var actingProtectedConfiguration = _currentProtectedConfiguration.Keys.Intersect(requestFields).Count() == requestFields.Length ? _currentProtectedConfiguration : _candidateProtectedConfiguration; // Generate and set the confirmation code parameters var confirmationCode = Guid.NewGuid().ToString(); _confirmationCodeProtected = _dataProtector.Protect(confirmationCode); _confirmationCodeIssuedAt = DateTime.Now; var requestData = new ConfirmationRequestData { ConfirmationCode = confirmationCode, AdminEmail = _dataProtector.Unprotect(actingProtectedConfiguration[ConfigurationKey.AdminEmail]), SmtpHost = _dataProtector.Unprotect(actingProtectedConfiguration[ConfigurationKey.SmtpHost]), SmtpPort = _dataProtector.Unprotect(actingProtectedConfiguration[ConfigurationKey.SmtpPort]), MailingAccountLogin = _dataProtector.Unprotect(actingProtectedConfiguration[ConfigurationKey.MailingAccountLogin]), MailingAccountPassword = _dataProtector.Unprotect(actingProtectedConfiguration[ConfigurationKey.MailingAccountPassword]), }; return OperationResult.Success(requestData); })); }
public IOperationResult SendConfirmCode(ConfirmationRequestData data) { return(OperationResult.Try(() => { if (string.IsNullOrEmpty(data.AdminEmail) || string.IsNullOrEmpty(data.SmtpHost) || string.IsNullOrEmpty(data.SmtpPort) || string.IsNullOrEmpty(data.MailingAccountLogin) || string.IsNullOrEmpty(data.SmtpPort)) { return OperationResult.Failure(new Exception("One of necessary configuration parameters is empty")); } var message = new MimeMessage(); message.From.Add(new MailboxAddress("Quiz", data.MailingAccountLogin)); message.To.Add(new MailboxAddress("Quiz", data.AdminEmail)); message.Subject = "An attempt to change configuration"; var confirmUrl = string.Format("{0}://{1}/Configuration/Confirm?confirmCode={2}", _contextAccessor.HttpContext.Request.Scheme, _contextAccessor.HttpContext.Request.Host, data.ConfirmationCode); message.Body = new TextPart(MimeKit.Text.TextFormat.Html) { Text = $"To confirm new configuration visit <a href='{confirmUrl}'>this link</a>" }; using (var client = new SmtpClient()) { client.ServerCertificateValidationCallback = (s, c, h, e) => true; client.Connect(data.SmtpHost, int.Parse(data.SmtpPort), SecureSocketOptions.SslOnConnect); client.Authenticate(data.MailingAccountLogin, data.MailingAccountPassword); client.Send(message); client.Disconnect(true); return OperationResult.Success(); } })); }