From 7dc675fedb5b2631a8bafd0fb691eac485eff0af Mon Sep 17 00:00:00 2001 From: Byron Jones Date: Tue, 4 Nov 2014 13:38:46 +0800 Subject: Bug 1092037: backport bug 1062739 to bmo (add the ability for administrators to limit the number of emails sent to a user per minute and hour) --- Bugzilla/Mailer.pm | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) (limited to 'Bugzilla/Mailer.pm') diff --git a/Bugzilla/Mailer.pm b/Bugzilla/Mailer.pm index 381422821..556500b1a 100644 --- a/Bugzilla/Mailer.pm +++ b/Bugzilla/Mailer.pm @@ -67,6 +67,8 @@ sub MessageToMTA { return; } + my $dbh = Bugzilla->dbh; + my $email; if (ref $msg) { $email = $msg; @@ -82,6 +84,42 @@ sub MessageToMTA { $email = new Email::MIME($msg); } + # Ensure that we are not sending emails too quickly to recipients. + if (Bugzilla->params->{use_mailer_queue} + && (EMAIL_LIMIT_PER_MINUTE || EMAIL_LIMIT_PER_HOUR)) + { + $dbh->do( + "DELETE FROM email_rates WHERE message_ts < " + . $dbh->sql_date_math('LOCALTIMESTAMP(0)', '-', '1', 'HOUR')); + + my $recipient = $email->header('To'); + + if (EMAIL_LIMIT_PER_MINUTE) { + my $minute_rate = $dbh->selectrow_array( + "SELECT COUNT(*) + FROM email_rates + WHERE recipient = ? AND message_ts >= " + . $dbh->sql_date_math('LOCALTIMESTAMP(0)', '-', '1', 'MINUTE'), + undef, + $recipient); + if ($minute_rate >= EMAIL_LIMIT_PER_MINUTE) { + die EMAIL_LIMIT_EXCEPTION; + } + } + if (EMAIL_LIMIT_PER_HOUR) { + my $hour_rate = $dbh->selectrow_array( + "SELECT COUNT(*) + FROM email_rates + WHERE recipient = ? AND message_ts >= " + . $dbh->sql_date_math('LOCALTIMESTAMP(0)', '-', '1', 'HOUR'), + undef, + $recipient); + if ($hour_rate >= EMAIL_LIMIT_PER_HOUR) { + die EMAIL_LIMIT_EXCEPTION; + } + } + } + # We add this header to uniquely identify all email that we # send as coming from this Bugzilla installation. # @@ -208,6 +246,17 @@ sub MessageToMTA { ThrowCodeError('mail_send_error', { msg => $retval, mail => $email }) if !$retval; } + + # insert into email_rates + if (Bugzilla->params->{use_mailer_queue} + && (EMAIL_LIMIT_PER_MINUTE || EMAIL_LIMIT_PER_HOUR)) + { + $dbh->do( + "INSERT INTO email_rates(recipient, message_ts) VALUES (?, LOCALTIMESTAMP(0))", + undef, + $email->header('To') + ); + } } # Builds header suitable for use as a threading marker in email notifications -- cgit v1.2.3-24-g4f1b