From 3891b63a1eb52076337885487f251a10580a4a85 Mon Sep 17 00:00:00 2001 From: Frédéric Buclin Date: Wed, 27 Apr 2016 18:50:13 +0200 Subject: Bug 218917 - Allow the login name to be different from the email address Original patch by Gervase Markham r=gerv a=dkl --- Bugzilla/Token.pm | 39 ++++++++++++++++++++++++++------------- 1 file changed, 26 insertions(+), 13 deletions(-) (limited to 'Bugzilla/Token.pm') diff --git a/Bugzilla/Token.pm b/Bugzilla/Token.pm index b6f07468e..4f522bda9 100644 --- a/Bugzilla/Token.pm +++ b/Bugzilla/Token.pm @@ -89,30 +89,32 @@ sub check_auth_delegation_token { # Creates and sends a token to create a new user account. # It assumes that the login has the correct format and is not already in use. sub issue_new_user_account_token { - my $login_name = shift; + my ($login, $email) = @_; my $dbh = Bugzilla->dbh; my $template = Bugzilla->template; my $vars = {}; - # Is there already a pending request for this login name? If yes, do not throw + # Is there already a pending request for this email? If yes, do not throw # an error because the user may have lost their email with the token inside. # But to prevent using this way to mailbomb an email address, make sure # the last request is old enough before sending a new email (default: 10 minutes). + my $regexp = "^$email:"; my $pending_requests = $dbh->selectrow_array( 'SELECT COUNT(*) FROM tokens WHERE tokentype = ? - AND ' . $dbh->sql_istrcmp('eventdata', '?') . ' + AND ' . $dbh->sql_regexp('eventdata', $dbh->quote($regexp)) . ' AND issuedate > ' . $dbh->sql_date_math('NOW()', '-', ACCOUNT_CHANGE_INTERVAL, 'MINUTE'), - undef, ('account', $login_name)); + undef, 'account'); ThrowUserError('too_soon_for_new_token', {'type' => 'account'}) if $pending_requests; - my ($token, $token_ts) = _create_token(undef, 'account', $login_name); + my ($token, $token_ts) = _create_token(undef, 'account', "$email:$login"); - $vars->{'email'} = $login_name . Bugzilla->params->{'emailsuffix'}; + $vars->{'login'} = $login; + $vars->{'email'} = $email; $vars->{'expiration_ts'} = ctime($token_ts + MAX_TOKEN_AGE * 86400); $vars->{'token'} = $token; @@ -131,15 +133,15 @@ sub IssueEmailChangeToken { my $new_email = shift; my $user = Bugzilla->user; - my ($token, $token_ts) = _create_token($user->id, 'emailold', $user->login . ":$new_email"); - my $newtoken = _create_token($user->id, 'emailnew', $user->login . ":$new_email"); + my ($token, $token_ts) = _create_token($user->id, 'emailold', $user->email . ":$new_email"); + my $newtoken = _create_token($user->id, 'emailnew', $user->email . ":$new_email"); # Mail the user the token along with instructions for using it. my $template = Bugzilla->template_inner($user->setting('lang')); my $vars = {}; - $vars->{'newemailaddress'} = $new_email . Bugzilla->params->{'emailsuffix'}; + $vars->{'newemailaddress'} = $new_email; $vars->{'expiration_ts'} = ctime($token_ts + MAX_TOKEN_AGE * 86400); # First send an email to the new address. If this one doesn't exist, @@ -335,7 +337,17 @@ sub Cancel { # is no entry in the 'profiles' table. my $user = new Bugzilla::User($userid); - $vars->{'emailaddress'} = $userid ? $user->email : $eventdata; + if ($userid) { + $vars->{'emailaddress'} = $user->email; + $vars->{'login'} = $user->login; + } + else { + # Be careful! Some logins may contain ":" in them. + my ($email, $login) = split(':', $eventdata, 2); + $vars->{'emailaddress'} = $email; + $vars->{'login'} = $login; + } + $vars->{'remoteaddress'} = remote_ip(); $vars->{'token'} = $token; $vars->{'tokentype'} = $tokentype; @@ -511,7 +523,7 @@ Bugzilla::Token - Provides different routines to manage tokens. use Bugzilla::Token; - Bugzilla::Token::issue_new_user_account_token($login_name); + Bugzilla::Token::issue_new_user_account_token($login, $email); Bugzilla::Token::IssueEmailChangeToken($user, $new_email); Bugzilla::Token::IssuePasswordToken($user); Bugzilla::Token::DeletePasswordTokens($user_id, $reason); @@ -539,14 +551,15 @@ Bugzilla::Token - Provides different routines to manage tokens. Returns: The token. -=item C +=item C Description: Creates and sends a token per email to the email address requesting a new user account. It doesn't check whether the user account already exists. The user will have to use this token to confirm the creation of their user account. - Params: $login_name - The new login name requested by the user. + Params: $login - The new login name requested by the user. + $email - The email address to be associated with the account. Returns: Nothing. It throws an error if the same user made the same request in the last few minutes. -- cgit v1.2.3-24-g4f1b