private async Task SendMail(EmailTypes emailType, SendGridMessage message, int userId)
        {
            if (message.To.Length != 1)
            {
                throw new LogReadyException(LogTag.UnsupportedUsageOfSendMail, new { userId, emailType });
            }

            var toEmail = message.To.First().Address;

            if (toEmail.EndsWith("@test.com") && toEmail.EndsWith("@fake.fake"))
            {
                return;
            }

            QuotaValidationResult result = _quotaValidator.ValidateQuota(emailType, message, userId);

            if (result.IsValid)
            {
                await _sgTransport.DeliverAsync(message);

                await _sgLogger.LogEmailToDisk(emailType, message.To.First().Address, message.Subject, message.Html ?? message.Text, userId);
            }
            else
            {
                await SendQuotaExceedNotification(result, emailType, message, userId);
            }
        }
Example #2
0
        private QuotaValidationResult ValidateMessageNotification(SendGridMessage message, int userId)
        {
            string emailAddress = message.To.First().Address;

            PrepareCountersIfNeeded(emailAddress, userId);

            EmailCountersStorage.TotalByEmail[emailAddress] += 1;
            EmailCountersStorage.Total += 1;

            QuotaValidationResult totalByEmailResult = CheckTotalByEmail(emailAddress);

            if (totalByEmailResult.IsValid == false)
            {
                return(totalByEmailResult);
            }

            QuotaValidationResult totalResult = CheckTotal();

            if (totalResult.IsValid == false)
            {
                return(totalResult);
            }

            return(QuotaValidationResult.Success);
        }
Example #3
0
 private QuotaValidationResult CheckTotal()
 {
     if (EmailCountersStorage.Total > EmailsTotalQuota)
     {
         var quotaExceedData = QuotaExceedData.Create(EmailQuotaType.TotalSentEmails, EmailsTotalQuota, EmailCountersStorage.Total);
         return(QuotaValidationResult.GetValidationExccedResult(quotaExceedData));
     }
     return(QuotaValidationResult.Success);
 }
        private async Task SendQuotaExceedNotification(QuotaValidationResult quotaExceededResult, EmailTypes emailType, SendGridMessage message, int userId)
        {
            //Andriy: Send email notification only if quota exceeded first time.
            if (quotaExceededResult.ExceedData.Value == quotaExceededResult.ExceedData.Quota + 1)
            {
                var notificationMessage = new SendGridMessage
                {
                    From    = new MailAddress(HellolingoEmailAddresses.Default, "HL"),
                    To      = new[] { new MailAddress(HellolingoEmailAddresses.Admin) },
                    Subject = $"{emailType} quota exceeded",
                };

                string template         = @"
				<style>
				  body { font: 12px arial; }
				  table { border-collapse: collapse; font-size: 13px;}
				  td { border: solid lightgrey 1px; padding: 2px 5px; }
				  td:nth-child(2) { font-weight: bold }
				  .everyone { font-weight:bold; color: green }
				  .ephemeral { font-weight:bold; color: orange }
				  .sender { font-weight:bold; color: red }
				  .button { 
					padding: 8px; border-radius: 8px;
					color: black; text-decoration: none;
					line-height: 36px;
				  }
				  .button-green { background-color: green; border: solid 3px green }
				  .button-red { background-color: red; border: solid 3px red }
				</style>

				<h3>Emails quota exceeded</h3>
				<table>
				  <tr><td>When</td><td>#When#</td></tr>
				  <tr><td>Email type</td><td>#EmailType#</td></tr>
                  <tr><td>Quota type</td><td>#QuotaType#</td></tr>
                  <tr><td>Quota value</td><td>#QuotaValue#</td></tr>
                  <tr><td>Email address</td><td>#EmailAddress#</td></tr>
                  <tr><td>Email subject</td><td>#EmailSubject#</td></tr>
				</table>
                <h4>Email body</h4>
                <div>#EmailBody#</div>";
                string notificationHtml = template.Replace("#When#", DateTime.Now.ToString(DateTimeFormat))
                                          .Replace("#EmailType#", emailType.ToString())
                                          .Replace("#QuotaType#", quotaExceededResult.ExceedData.QuotaType.ToString())
                                          .Replace("#QuotaValue#", quotaExceededResult.ExceedData.Quota.ToString())
                                          .Replace("#EmailAddress#", message.To.First().Address)
                                          .Replace("#EmailSubject#", message.Subject)
                                          .Replace("#EmailBody#", message.Html ?? message.Text);


                notificationMessage.Html = notificationHtml;
                await _sgTransport.DeliverAsync(notificationMessage);
            }
            await _sgLogger.LogQuotaExceedEmailToDisk(emailType, message.To.FirstOrDefault()?.Address, message.Subject, message.Html ?? message.Text, userId);
        }
Example #5
0
        private QuotaValidationResult CheckEmailValidationsTotal(string emailAddress)
        {
            int totalValidationsValue = EmailCountersStorage.EmailVerificationsTotal[emailAddress];

            if (totalValidationsValue > EmailValidationsTotalQuota)
            {
                var quotaExceedData = QuotaExceedData.Create(EmailQuotaType.EmailVerificationGlobally, EmailValidationsTotalQuota, totalValidationsValue);
                return(QuotaValidationResult.GetValidationExccedResult(quotaExceedData));
            }
            return(QuotaValidationResult.Success);
        }
Example #6
0
        private QuotaValidationResult CheckEmailValidationWithUserId(int userId)
        {
            int userValidationValue = EmailCountersStorage.EmailVerificationsByUserId[userId];

            if (userValidationValue > EmailValidationByUserIdQuota)
            {
                var quotaExceedData = QuotaExceedData.Create(EmailQuotaType.EmailVerificationByUserId, EmailValidationByUserIdQuota, userValidationValue);
                return(QuotaValidationResult.GetValidationExccedResult(quotaExceedData));
            }
            return(QuotaValidationResult.Success);
        }
Example #7
0
        private QuotaValidationResult CheckEmailValidationWithEmail(string emailAddress)
        {
            int emailValidationValue = EmailCountersStorage.EmailVerificationsByEmail[emailAddress];

            if (emailValidationValue > EmailValidationByEmailQuota)
            {
                var quotaExceedData = QuotaExceedData.Create(EmailQuotaType.EmailVerificationByEmail, EmailValidationByEmailQuota, emailValidationValue);
                return(QuotaValidationResult.GetValidationExccedResult(quotaExceedData));
            }
            return(QuotaValidationResult.Success);
        }
Example #8
0
        private QuotaValidationResult CheckTotalByEmail(string emailAddress)
        {
            int totalByEmailValue = EmailCountersStorage.TotalByEmail[emailAddress];

            if (totalByEmailValue > TotalByEmailQuota)
            {
                var quotaExceedData = QuotaExceedData.Create(EmailQuotaType.SameEmailAddress, TotalByEmailQuota, totalByEmailValue);
                return(QuotaValidationResult.GetValidationExccedResult(quotaExceedData));
            }
            return(QuotaValidationResult.Success);
        }
Example #9
0
        private QuotaValidationResult ValidateEmailVerificationMessage(SendGridMessage message, int userId)
        {
            string emailAddress = message.To.First().Address;

            PrepareCountersIfNeeded(emailAddress, userId);

            EmailCountersStorage.EmailVerificationsByEmail[emailAddress] += 1;
            EmailCountersStorage.EmailVerificationsByUserId[userId]      += 1;
            EmailCountersStorage.EmailVerificationsTotal[emailAddress]   += 1;
            EmailCountersStorage.TotalByEmail[emailAddress] += 1;
            EmailCountersStorage.Total += 1;

            QuotaValidationResult emailValidationByEmailResult = CheckEmailValidationWithEmail(emailAddress);

            if (emailValidationByEmailResult.IsValid == false)
            {
                return(emailValidationByEmailResult);
            }

            QuotaValidationResult emailValidationByUserIdResult = CheckEmailValidationWithUserId(userId);

            if (emailValidationByUserIdResult.IsValid == false)
            {
                return(emailValidationByUserIdResult);
            }

            QuotaValidationResult emailValidationTotalResult = CheckEmailValidationsTotal(emailAddress);

            if (emailValidationTotalResult.IsValid == false)
            {
                return(emailValidationTotalResult);
            }

            QuotaValidationResult totalByEmailResult = CheckTotalByEmail(emailAddress);

            if (totalByEmailResult.IsValid == false)
            {
                return(totalByEmailResult);
            }

            QuotaValidationResult totalResult = CheckTotal();

            if (totalResult.IsValid == false)
            {
                return(totalResult);
            }

            return(QuotaValidationResult.Success);
        }