Commit 43b7dc31 authored by lpsolit%gmail.com's avatar lpsolit%gmail.com

Bug 405946: Some emails are not sent in the language chosen by the addressee -…

Bug 405946: Some emails are not sent in the language chosen by the addressee - Patch by Fré©ric Buclin <LpSolit@gmail.com> r=wurblzap a=LpSolit
parent 0e4b8f78
......@@ -3024,7 +3024,6 @@ sub RemoveVotes {
if (scalar(@list)) {
foreach my $ref (@list) {
my ($name, $userid, $oldvotes, $votesperuser, $maxvotesperbug) = (@$ref);
my $s;
$maxvotesperbug = min($votesperuser, $maxvotesperbug);
......@@ -3038,23 +3037,13 @@ sub RemoveVotes {
my $removedvotes = $oldvotes - $newvotes;
$s = ($oldvotes == 1) ? "" : "s";
my $oldvotestext = "You had $oldvotes vote$s on this bug.";
$s = ($removedvotes == 1) ? "" : "s";
my $removedvotestext = "You had $removedvotes vote$s removed from this bug.";
my $newvotestext;
if ($newvotes) {
$dbh->do("UPDATE votes SET vote_count = ? " .
"WHERE bug_id = ? AND who = ?",
undef, ($newvotes, $id, $userid));
$s = $newvotes == 1 ? "" : "s";
$newvotestext = "You still have $newvotes vote$s on this bug."
} else {
$dbh->do("DELETE FROM votes WHERE bug_id = ? AND who = ?",
undef, ($id, $userid));
$newvotestext = "You have no more votes remaining on this bug.";
}
# Notice that we did not make sure that the user fit within the $votesperuser
......@@ -3065,7 +3054,6 @@ sub RemoveVotes {
# Now lets send the e-mail to alert the user to the fact that their votes have
# been reduced or removed.
my $vars = {
'to' => $name . Bugzilla->params->{'emailsuffix'},
'bugid' => $id,
'reason' => $reason,
......@@ -3073,19 +3061,17 @@ sub RemoveVotes {
'votesremoved' => $removedvotes,
'votesold' => $oldvotes,
'votesnew' => $newvotes,
'votesremovedtext' => $removedvotestext,
'votesoldtext' => $oldvotestext,
'votesnewtext' => $newvotestext,
'count' => $removedvotes . "\n " . $newvotestext
};
my $voter = new Bugzilla::User($userid);
my $template = Bugzilla->template_inner($voter->settings->{'lang'}->{'value'});
my $msg;
my $template = Bugzilla->template;
$template->process("email/votes-removed.txt.tmpl", $vars, \$msg);
push(@messages, $msg);
}
Bugzilla->template_inner("");
my $votes = $dbh->selectrow_array("SELECT SUM(vote_count) " .
"FROM votes WHERE bug_id = ?",
undef, $id) || 0;
......
......@@ -1063,56 +1063,54 @@ or deleted.
sub notify {
my ($flag, $bug, $attachment) = @_;
my $template = Bugzilla->template;
# There is nobody to notify.
return unless ($flag->{'addressee'} || $flag->type->cc_list);
my $attachment_is_private = $attachment ? $attachment->isprivate : undef;
# If the target bug is restricted to one or more groups, then we need
# to make sure we don't send email about it to unauthorized users
# on the request type's CC: list, so we have to trawl the list for users
# not in those groups or email addresses that don't have an account.
my @bug_in_groups = grep {$_->{'ison'} || $_->{'mandatory'}} @{$bug->groups};
my $attachment_is_private = $attachment ? $attachment->isprivate : undef;
if (scalar(@bug_in_groups) || $attachment_is_private) {
my @new_cc_list;
foreach my $cc (split(/[, ]+/, $flag->type->cc_list)) {
my $ccuser = new Bugzilla::User({ name => $cc }) || next;
next if (scalar(@bug_in_groups) && !$ccuser->can_see_bug($bug->bug_id));
next if $attachment_is_private
&& Bugzilla->params->{"insidergroup"}
&& !$ccuser->in_group(Bugzilla->params->{"insidergroup"});
push(@new_cc_list, $cc);
}
$flag->type->{'cc_list'} = join(", ", @new_cc_list);
my %recipients;
foreach my $cc (split(/[, ]+/, $flag->type->cc_list)) {
my $ccuser = new Bugzilla::User({ name => $cc });
next if (scalar(@bug_in_groups) && (!$ccuser || !$ccuser->can_see_bug($bug->bug_id)));
next if $attachment_is_private && (!$ccuser || !$ccuser->is_insider);
# Prevent duplicated entries due to case sensitivity.
$cc = $ccuser ? $ccuser->email : $cc;
$recipients{$cc} = $ccuser;
}
# If there is nobody left to notify, return.
return unless ($flag->{'addressee'} || $flag->type->cc_list);
my @recipients = split(/[, ]+/, $flag->type->cc_list);
# Only notify if the addressee is allowed to receive the email.
if ($flag->{'addressee'} && $flag->{'addressee'}->email_enabled) {
push @recipients, $flag->{'addressee'}->email;
$recipients{$flag->{'addressee'}->email} = $flag->{'addressee'};
}
# Process and send notification for each recipient
foreach my $to (@recipients)
{
next unless $to;
# Process and send notification for each recipient.
# If there are users in the CC list who don't have an account,
# use the default language for email notifications.
my $default_lang;
if (grep { !$_ } values %recipients) {
my $default_user = new Bugzilla::User();
$default_lang = $default_user->settings->{'lang'}->{'value'};
}
foreach my $to (keys %recipients) {
my $vars = { 'flag' => $flag,
'to' => $to,
'bug' => $bug,
'attachment' => $attachment};
my $lang = $recipients{$to} ?
$recipients{$to}->settings->{'lang'}->{'value'} : $default_lang;
my $template = Bugzilla->template_inner($lang);
my $message;
my $rv = $template->process("request/email.txt.tmpl", $vars, \$message);
if (!$rv) {
Bugzilla->cgi->header();
ThrowTemplateError($template->error());
}
$template->process("request/email.txt.tmpl", $vars, \$message)
|| ThrowTemplateError($template->error());
Bugzilla->template_inner("");
MessageToMTA($message);
}
}
......
......@@ -34,6 +34,7 @@ use Bugzilla::Constants;
use Bugzilla::Error;
use Bugzilla::Mailer;
use Bugzilla::Util;
use Bugzilla::User;
use Date::Format;
use Date::Parse;
......@@ -80,20 +81,24 @@ sub issue_new_user_account_token {
$template->process('account/email/request-new.txt.tmpl', $vars, \$message)
|| ThrowTemplateError($template->error());
# In 99% of cases, the user getting the confirmation email is the same one
# who made the request, and so it is reasonable to send the email in the same
# language used to view the "Create a New Account" page (we cannot use his
# user prefs as the user has no account yet!).
MessageToMTA($message);
}
sub IssueEmailChangeToken {
my ($userid, $old_email, $new_email) = @_;
my ($user, $old_email, $new_email) = @_;
my $email_suffix = Bugzilla->params->{'emailsuffix'};
my ($token, $token_ts) = _create_token($userid, 'emailold', $old_email . ":" . $new_email);
my ($token, $token_ts) = _create_token($user->id, 'emailold', $old_email . ":" . $new_email);
my $newtoken = _create_token($userid, 'emailnew', $old_email . ":" . $new_email);
my $newtoken = _create_token($user->id, 'emailnew', $old_email . ":" . $new_email);
# Mail the user the token along with instructions for using it.
my $template = Bugzilla->template;
my $template = Bugzilla->template_inner($user->settings->{'lang'}->{'value'});
my $vars = {};
$vars->{'oldemailaddress'} = $old_email . $email_suffix;
......@@ -118,38 +123,34 @@ sub IssueEmailChangeToken {
$template->process("account/email/change-new.txt.tmpl", $vars, \$message)
|| ThrowTemplateError($template->error());
Bugzilla->template_inner("");
MessageToMTA($message);
}
# Generates a random token, adds it to the tokens table, and sends it
# to the user with instructions for using it to change their password.
sub IssuePasswordToken {
my $loginname = shift;
my $user = shift;
my $dbh = Bugzilla->dbh;
my $template = Bugzilla->template;
my $vars = {};
# Retrieve the user's ID from the database.
trick_taint($loginname);
my ($userid, $too_soon) =
$dbh->selectrow_array('SELECT profiles.userid, tokens.issuedate
FROM profiles
LEFT JOIN tokens
ON tokens.userid = profiles.userid
AND tokens.tokentype = ?
AND tokens.issuedate > NOW() - ' .
$dbh->sql_interval(10, 'MINUTE') . '
WHERE ' . $dbh->sql_istrcmp('login_name', '?'),
undef, ('password', $loginname));
my $too_soon =
$dbh->selectrow_array('SELECT 1 FROM tokens
WHERE userid = ?
AND tokentype = ?
AND issuedate > NOW() - ' .
$dbh->sql_interval(10, 'MINUTE'),
undef, ($user->id, 'password'));
ThrowUserError('too_soon_for_new_token', {'type' => 'password'}) if $too_soon;
my ($token, $token_ts) = _create_token($userid, 'password', $::ENV{'REMOTE_ADDR'});
my ($token, $token_ts) = _create_token($user->id, 'password', $::ENV{'REMOTE_ADDR'});
# Mail the user the token along with instructions for using it.
$vars->{'token'} = $token;
$vars->{'emailaddress'} = $loginname . Bugzilla->params->{'emailsuffix'};
my $template = Bugzilla->template_inner($user->settings->{'lang'}->{'value'});
my $vars = {};
$vars->{'token'} = $token;
$vars->{'emailaddress'} = $user->email;
$vars->{'max_token_age'} = MAX_TOKEN_AGE;
$vars->{'token_ts'} = $token_ts;
......@@ -158,6 +159,7 @@ sub IssuePasswordToken {
$vars, \$message)
|| ThrowTemplateError($template->error());
Bugzilla->template_inner("");
MessageToMTA($message);
}
......@@ -205,31 +207,28 @@ sub GenerateUniqueToken {
return $token;
}
# Cancels a previously issued token and notifies the system administrator.
# Cancels a previously issued token and notifies the user.
# This should only happen when the user accidentally makes a token request
# or when a malicious hacker makes a token request on behalf of a user.
sub Cancel {
my ($token, $cancelaction, $vars) = @_;
my $dbh = Bugzilla->dbh;
my $template = Bugzilla->template;
$vars ||= {};
# Get information about the token being canceled.
trick_taint($token);
my ($issuedate, $tokentype, $eventdata, $loginname) =
my ($issuedate, $tokentype, $eventdata, $userid) =
$dbh->selectrow_array('SELECT ' . $dbh->sql_date_format('issuedate') . ',
tokentype, eventdata, login_name
tokentype, eventdata, userid
FROM tokens
LEFT JOIN profiles
ON tokens.userid = profiles.userid
WHERE token = ?',
undef, $token);
# If we are cancelling the creation of a new user account, then there
# If we are canceling the creation of a new user account, then there
# is no entry in the 'profiles' table.
$loginname ||= $eventdata;
$vars->{'emailaddress'} = $loginname . Bugzilla->params->{'emailsuffix'};
$vars->{'maintainer'} = Bugzilla->params->{'maintainer'};
my $user = new Bugzilla::User($userid);
$vars->{'emailaddress'} = $userid ? $user->email : $eventdata;
$vars->{'remoteaddress'} = $::ENV{'REMOTE_ADDR'};
$vars->{'token'} = $token;
$vars->{'tokentype'} = $tokentype;
......@@ -238,11 +237,13 @@ sub Cancel {
$vars->{'cancelaction'} = $cancelaction;
# Notify the user via email about the cancellation.
my $template = Bugzilla->template_inner($user->settings->{'lang'}->{'value'});
my $message;
$template->process("account/cancel-token.txt.tmpl", $vars, \$message)
|| ThrowTemplateError($template->error());
Bugzilla->template_inner("");
MessageToMTA($message);
# Delete the token from the database.
......@@ -391,8 +392,8 @@ Bugzilla::Token - Provides different routines to manage tokens.
use Bugzilla::Token;
Bugzilla::Token::issue_new_user_account_token($login_name);
Bugzilla::Token::IssueEmailChangeToken($user_id, $old_email, $new_email);
Bugzilla::Token::IssuePasswordToken($login_name);
Bugzilla::Token::IssueEmailChangeToken($user, $old_email, $new_email);
Bugzilla::Token::IssuePasswordToken($user);
Bugzilla::Token::DeletePasswordTokens($user_id, $reason);
Bugzilla::Token::Cancel($token, $cancelaction, $vars);
......@@ -422,26 +423,26 @@ Bugzilla::Token - Provides different routines to manage tokens.
Returns: Nothing. It throws an error if the same user made the same
request in the last few minutes.
=item C<sub IssueEmailChangeToken($user_id, $old_email, $new_email)>
=item C<sub IssueEmailChangeToken($user, $old_email, $new_email)>
Description: Sends two distinct tokens per email to the old and new email
addresses to confirm the email address change for the given
user ID. These tokens remain valid for the next MAX_TOKEN_AGE days.
user. These tokens remain valid for the next MAX_TOKEN_AGE days.
Params: $user_id - The user ID of the user account requesting a new
email address.
Params: $user - User object of the user requesting a new
email address.
$old_email - The current (old) email address of the user.
$new_email - The new email address of the user.
Returns: Nothing.
=item C<IssuePasswordToken($login_name)>
=item C<IssuePasswordToken($user)>
Description: Sends a token per email to the given login name. This token
Description: Sends a token per email to the given user. This token
can be used to change the password (e.g. in case the user
cannot remember his password and wishes to enter a new one).
Params: $login_name - The login name of the user requesting a new password.
Params: $user - User object of the user requesting a new password.
Returns: Nothing. It throws an error if the same user made the same
request in the last few minutes.
......
......@@ -939,10 +939,7 @@ if ($action eq 'update') {
my ($who, $id) = (@$vote);
# If some votes are removed, RemoveVotes() returns a list
# of messages to send to voters.
my $msgs =
RemoveVotes($id, $who, "The rules for voting on this product " .
"has changed;\nyou had too many votes " .
"for a single bug.");
my $msgs = RemoveVotes($id, $who, 'votes_too_many_per_bug');
foreach my $msg (@$msgs) {
MessageToMTA($msg);
}
......@@ -991,11 +988,7 @@ if ($action eq 'update') {
foreach my $bug_id (@$bug_ids) {
# RemoveVotes() returns a list of messages to send
# in case some voters had too many votes.
my $msgs =
RemoveVotes($bug_id, $who, "The rules for voting on this " .
"product has changed; you had " .
"too many\ntotal votes, so all " .
"votes have been removed.");
my $msgs = RemoveVotes($bug_id, $who, 'votes_too_many_per_user');
foreach my $msg (@$msgs) {
MessageToMTA($msg);
}
......
......@@ -560,9 +560,7 @@ foreach my $bug (@bug_objects) {
# If some votes have been removed, RemoveVotes() returns
# a list of messages to send to voters.
# We delay the sending of these messages till tables are unlocked.
$msgs = RemoveVotes($bug->id, 0,
"This bug has been moved to a different product");
$msgs = RemoveVotes($bug->id, 0, 'votes_bug_moved');
CheckIfVotedConfirmed($bug->id, Bugzilla->user->id);
}
......
......@@ -158,11 +158,11 @@ elsif ($action eq 'begin-sudo') {
# Go ahead and send out the message now
my $message;
$template->process('email/sudo.txt.tmpl',
{ reason => $reason },
\$message);
my $mail_template = Bugzilla->template_inner($target_user->settings->{'lang'}->{'value'});
$mail_template->process('email/sudo.txt.tmpl', { reason => $reason }, \$message);
Bugzilla->template_inner("");
MessageToMTA($message);
$vars->{'message'} = 'sudo_started';
$vars->{'target'} = $target_user->login;
$target = 'global/message.html.tmpl';
......
......@@ -69,7 +69,15 @@ my $user = Bugzilla->login(LOGIN_REQUIRED);
my $cgi = Bugzilla->cgi;
my $dbh = Bugzilla->dbh;
my $template = Bugzilla->template;
# If the result of the sanity check is sent per email, then we have to
# take the user prefs into account rather than querying the web browser.
my $template;
if (Bugzilla->usage_mode == USAGE_MODE_CMDLINE) {
$template = Bugzilla->template_inner($user->settings->{'lang'}->{'value'});
}
else {
$template = Bugzilla->template;
}
my $vars = {};
print $cgi->header() unless Bugzilla->usage_mode == USAGE_MODE_CMDLINE;
......
......@@ -32,7 +32,7 @@ If you did not request this, it could be either an honest
mistake or someone attempting to break into your [% terms.Bugzilla %] account.
Take a look at the information below and forward this email
to [% maintainer %] if you suspect foul play.
to [% Param('maintainer') %] if you suspect foul play.
Token: [% token %]
Token Type: [% tokentype %]
......
......@@ -27,11 +27,28 @@ X-Bugzilla-Type: voteremoved
Some or all of your votes have been removed from [% terms.bug %] [%+ bugid %].
[% votesoldtext %]
You had [% votesold FILTER html %] [%+ IF votesold == 1 %]vote[% ELSE %]votes[% END
%] on this [% terms.bug %], but [% votesremoved FILTER html %] have been removed.
[% votesnewtext %]
[% IF votesnew %]
You still have [% votesnew FILTER html %] [%+ IF votesnew == 1 %]vote[% ELSE %]votes[% END %] on this [% terms.bug %].
[% ELSE %]
You have no more votes remaining on this [% terms.bug %].
[% END %]
Reason:
[% IF reason == "votes_bug_moved" %]
This [% terms.bug %] has been moved to a different product.
[% ELSIF reason == "votes_too_many_per_bug" %]
The rules for voting on this product has changed;
you had too many votes for a single [% terms.bug %].
[% ELSIF reason == "votes_too_many_per_user" %]
The rules for voting on this product has changed; you had
too many total votes, so all votes have been removed.
[% END %]
Reason: [% reason %]
[% urlbase %]show_bug.cgi?id=[% bugid %]
......
......@@ -76,11 +76,6 @@
that login name.
[% END %]
[% ELSIF error == "account_does_not_exist" %]
[% title = "Account Does Not Exist" %]
<code>[% email FILTER html %]</code> is not a valid [% terms.Bugzilla %]
account.
[% ELSIF error == "alias_has_comma_or_space" %]
[% title = "Invalid Characters In Alias" %]
The alias you entered, <em>[% alias FILTER html %]</em>,
......
......@@ -101,11 +101,10 @@ if ($cgi->param('t')) {
# If the user is requesting a password change, make sure they submitted
# their login name and it exists in the database, and that the DB module is in
# the list of allowed verification methods.
my $login_name;
my $user_account;
if ( $::action eq 'reqpw' ) {
$login_name = $cgi->param('loginname');
defined $login_name
|| ThrowUserError("login_needed_for_password_change");
my $login_name = $cgi->param('loginname')
|| ThrowUserError("login_needed_for_password_change");
# check verification methods
unless (Bugzilla->user->authorizer->can_change_password) {
......@@ -115,10 +114,7 @@ if ( $::action eq 'reqpw' ) {
validate_email_syntax($login_name)
|| ThrowUserError('illegal_email_address', {addr => $login_name});
my ($user_id) = $dbh->selectrow_array('SELECT userid FROM profiles WHERE ' .
$dbh->sql_istrcmp('login_name', '?'),
undef, $login_name);
$user_id || ThrowUserError("account_does_not_exist", {'email' => $login_name});
$user_account = Bugzilla::User->check($login_name);
}
# If the user is changing their password, make sure they submitted a new
......@@ -142,7 +138,7 @@ if ( $::action eq 'chgpw' ) {
# that variable and runs the appropriate code.
if ($::action eq 'reqpw') {
requestChangePassword($login_name);
requestChangePassword($user_account);
} elsif ($::action eq 'cfmpw') {
confirmChangePassword();
} elsif ($::action eq 'cxlpw') {
......@@ -175,8 +171,8 @@ exit;
################################################################################
sub requestChangePassword {
my ($login_name) = @_;
Bugzilla::Token::IssuePasswordToken($login_name);
my ($user) = @_;
Bugzilla::Token::IssuePasswordToken($user);
$vars->{'message'} = "password_change_request";
......
......@@ -138,7 +138,7 @@ sub SaveAccount {
is_available_username($new_login_name)
|| ThrowUserError("account_exists", {email => $new_login_name});
Bugzilla::Token::IssueEmailChangeToken($user->id, $old_login_name,
Bugzilla::Token::IssueEmailChangeToken($user, $old_login_name,
$new_login_name);
$vars->{'email_changes_saved'} = 1;
......
......@@ -353,10 +353,11 @@ while (my $event = get_next_event) {
#
sub mail {
my $args = shift;
my $addressee = $args->{recipient};
# Don't send mail to someone whose bugmail notification is disabled.
return if $addressee->email_disabled;
# Don't send mail to someone on the nomail list.
return if $args->{recipient}->email_disabled;
my $template = Bugzilla->template_inner($addressee->settings->{'lang'}->{'value'});
my $msg = ''; # it's a temporary variable to hold the template output
$args->{'alternatives'} ||= [];
......@@ -387,6 +388,7 @@ sub mail {
$template->process("whine/multipart-mime.txt.tmpl", $args, \$msg)
or die($template->error());
Bugzilla->template_inner("");
MessageToMTA($msg);
delete $args->{'boundary'};
......
......@@ -85,9 +85,11 @@ foreach my $email (sort (keys %bugs)) {
$vars->{'bugs'} = \@bugs;
my $msg;
my $template = Bugzilla->template;
$template->process("email/whine.txt.tmpl", $vars, \$msg);
my $template = Bugzilla->template_inner($user->settings->{'lang'}->{'value'});
$template->process("email/whine.txt.tmpl", $vars, \$msg)
or die($template->error());
Bugzilla->template_inner("");
MessageToMTA($msg);
print "$email " . join(" ", @{$bugs{$email}}) . "\n";
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment