From cb114a086e9d68706f326adcc30b149fb06170d1 Mon Sep 17 00:00:00 2001 From: Koosha Khajeh Moogahi Date: Fri, 18 May 2012 16:36:12 +0200 Subject: Bug 752303: It is no longer possible to cancel an email address change when this one has already been confirmed r/a=LpSolit --- Bugzilla/Install.pm | 2 +- Bugzilla/User.pm | 32 +++++++++++++++++++++----------- token.cgi | 19 +++++-------------- 3 files changed, 27 insertions(+), 26 deletions(-) diff --git a/Bugzilla/Install.pm b/Bugzilla/Install.pm index 6c7f72fc4..cffcc704b 100644 --- a/Bugzilla/Install.pm +++ b/Bugzilla/Install.pm @@ -319,7 +319,7 @@ sub create_admin { print get_text('install_admin_get_email') . ' '; $login = ; chomp $login; - eval { Bugzilla::User->check_login_name_for_creation($login); }; + eval { Bugzilla::User->check_login_name($login); }; if ($@) { say $@; undef $login; diff --git a/Bugzilla/User.pm b/Bugzilla/User.pm index 9e4ecb8fb..7ce66aa8f 100644 --- a/Bugzilla/User.pm +++ b/Bugzilla/User.pm @@ -88,7 +88,7 @@ use constant VALIDATORS => { cryptpassword => \&_check_password, disable_mail => \&_check_disable_mail, disabledtext => \&_check_disabledtext, - login_name => \&check_login_name_for_creation, + login_name => \&check_login_name, realname => \&_check_realname, extern_id => \&_check_extern_id, is_enabled => \&_check_is_enabled, @@ -150,20 +150,25 @@ sub super_user { sub update { my $self = shift; + my $options = shift; + my $changes = $self->SUPER::update(@_); my $dbh = Bugzilla->dbh; if (exists $changes->{login_name}) { - # If we changed the login, silently delete any tokens. - $dbh->do('DELETE FROM tokens WHERE userid = ?', undef, $self->id); + # Delete all the tokens related to the userid + $dbh->do('DELETE FROM tokens WHERE userid = ?', undef, $self->id) + unless $options->{keep_tokens}; # And rederive regex groups $self->derive_regexp_groups(); } # Logout the user if necessary. Bugzilla->logout_user($self) - if (exists $changes->{login_name} || exists $changes->{disabledtext} - || exists $changes->{cryptpassword}); + if (!$options->{keep_session} + && (exists $changes->{login_name} + || exists $changes->{disabledtext} + || exists $changes->{cryptpassword})); # XXX Can update profiles_activity here as soon as it understands # field names like login_name. @@ -196,7 +201,7 @@ sub _check_extern_id { # This is public since createaccount.cgi needs to use it before issuing # a token for account creation. -sub check_login_name_for_creation { +sub check_login_name { my ($invocant, $name) = @_; $name = trim($name); $name || ThrowUserError('user_login_required'); @@ -204,7 +209,9 @@ sub check_login_name_for_creation { # Check the name if it's a new user, or if we're changing the name. if (!ref($invocant) || $invocant->login ne $name) { - is_available_username($name) + my @params = ($name); + push(@params, $invocant->login) if ref($invocant); + is_available_username(@params) || ThrowUserError('account_exists', { email => $name }); } @@ -1952,8 +1959,8 @@ sub is_available_username { # was unsafe and required weird escaping; using substring to pull out # the new/old email addresses and sql_position() to find the delimiter (':') # is cleaner/safer - my $eventdata = $dbh->selectrow_array( - "SELECT eventdata + my ($tokentype, $eventdata) = $dbh->selectrow_array( + "SELECT tokentype, eventdata FROM tokens WHERE (tokentype = 'emailold' AND SUBSTRING(eventdata, 1, (" . @@ -1965,7 +1972,10 @@ sub is_available_username { if ($eventdata) { # Allow thru owner of token - if($old_username && ($eventdata eq "$old_username:$username")) { + if ($old_username + && (($tokentype eq 'emailnew' && $eventdata eq "$old_username:$username") + || ($tokentype eq 'emailold' && $eventdata eq "$username:$old_username"))) + { return 1; } return 0; @@ -1988,7 +1998,7 @@ sub check_account_creation_enabled { sub check_and_send_account_creation_confirmation { my ($self, $login) = @_; - $login = $self->check_login_name_for_creation($login); + $login = $self->check_login_name($login); my $creation_regexp = Bugzilla->params->{'createemailregexp'}; if ($login !~ /$creation_regexp/i) { diff --git a/token.cgi b/token.cgi index 5f647edb3..9a6a0de88 100755 --- a/token.cgi +++ b/token.cgi @@ -193,7 +193,6 @@ sub confirmChangeEmail { sub changeEmail { my ($userid, $eventdata, $token) = @_; my $dbh = Bugzilla->dbh; - my ($old_email, $new_email) = split(/:/,$eventdata); # Check the user entered the correct old email address @@ -208,21 +207,15 @@ sub changeEmail { ThrowUserError("account_exists", { email => $new_email } ); } - # Update the user's login name in the profiles table and delete the token - # from the tokens table. $dbh->bz_start_transaction(); - $dbh->do(q{UPDATE profiles - SET login_name = ? - WHERE userid = ?}, - undef, ($new_email, $userid)); + my $user = Bugzilla::User->check({ id => $userid }); + # Update the user's login name in the profiles table. + $user->set_login($new_email); + $user->update({ keep_session => 1, keep_tokens => 1 }); delete_token($token); $dbh->do(q{DELETE FROM tokens WHERE userid = ? AND tokentype = 'emailnew'}, undef, $userid); - # The email address has been changed, so we need to rederive the groups - my $user = new Bugzilla::User($userid); - $user->derive_regexp_groups; - $dbh->bz_commit_transaction(); # Return HTTP response headers. @@ -250,9 +243,7 @@ sub cancelChangeEmail { # check to see if it has been altered if ($user->login ne $old_email) { $user->set_login($old_email); - $user->update(); - # email has changed, so rederive groups - $user->derive_regexp_groups; + $user->update({ keep_session => 1 }); $vars->{'message'} = "email_change_canceled_reinstated"; } -- cgit v1.2.3-24-g4f1b