summaryrefslogtreecommitdiffstats
path: root/Bugzilla/Mailer.pm
diff options
context:
space:
mode:
authorByron Jones <glob@mozilla.com>2014-10-31 08:20:42 +0100
committerByron Jones <glob@mozilla.com>2014-10-31 08:20:42 +0100
commit908480c98aa48a9d1caf09ee00f3cfe0863afec2 (patch)
treea15dc741c3fe821865291a0789fda1607d2a67a4 /Bugzilla/Mailer.pm
parentf1fda7c8b9cf4646374cc708c14942e5feed82d1 (diff)
downloadbugzilla-908480c98aa48a9d1caf09ee00f3cfe0863afec2.tar.gz
bugzilla-908480c98aa48a9d1caf09ee00f3cfe0863afec2.tar.xz
Bug 1062739: add the ability for administrators to limit the number of emails sent to a user per minute and hour
r=dylan,a=glob
Diffstat (limited to 'Bugzilla/Mailer.pm')
-rw-r--r--Bugzilla/Mailer.pm53
1 files changed, 51 insertions, 2 deletions
diff --git a/Bugzilla/Mailer.pm b/Bugzilla/Mailer.pm
index 4447d4046..389b6f69e 100644
--- a/Bugzilla/Mailer.pm
+++ b/Bugzilla/Mailer.pm
@@ -41,6 +41,8 @@ sub MessageToMTA {
return;
}
+ my $dbh = Bugzilla->dbh;
+
my $email;
if (ref $msg) {
$email = $msg;
@@ -58,14 +60,50 @@ sub MessageToMTA {
# email immediately, in case the transaction is rolled back. Instead we
# insert it into the mail_staging table, and bz_commit_transaction calls
# send_staged_mail() after the transaction is committed.
- if (! $send_now && Bugzilla->dbh->bz_in_transaction()) {
+ if (! $send_now && $dbh->bz_in_transaction()) {
# The e-mail string may contain tainted values.
my $string = $email->as_string;
trick_taint($string);
- Bugzilla->dbh->do("INSERT INTO mail_staging (message) VALUES(?)", undef, $string);
+ $dbh->do("INSERT INTO mail_staging (message) VALUES(?)", undef, $string);
return;
}
+ # 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.
#
@@ -181,6 +219,17 @@ sub MessageToMTA {
ThrowCodeError('mail_send_error', { msg => $@->message, mail => $email });
}
}
+
+ # 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