From: bugzilla%glob.com.au <> Date: Fri, 1 Jul 2005 09:55:11 +0000 (+0000) Subject: Bug 297646: Write helper functions for Bugzilla::Token.pm X-Git-Tag: bugzilla-2.18.2~7 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=14dbfc8c23f6c3a66c541a6d9f1fb129b0398f9d;p=thirdparty%2Fbugzilla.git Bug 297646: Write helper functions for Bugzilla::Token.pm Patch by Byron Jones r=LpSolit,a=justdave --- diff --git a/Bugzilla/Token.pm b/Bugzilla/Token.pm index 7e77a6835b..0149feff9e 100644 --- a/Bugzilla/Token.pm +++ b/Bugzilla/Token.pm @@ -32,8 +32,10 @@ package Bugzilla::Token; use Bugzilla::Config; use Bugzilla::Error; use Bugzilla::BugMail; +use Bugzilla::Util; use Date::Format; +use Date::Parse; # This module requires that its caller have said "require CGI.pl" to import # relevant functions from that script and its companion globals.pl. @@ -46,33 +48,15 @@ use Date::Format; my $maxtokenage = 3; ################################################################################ -# Functions +# Public Functions ################################################################################ sub IssueEmailChangeToken { my ($userid, $old_email, $new_email) = @_; - my $token_ts = time(); - my $issuedate = time2str("%Y-%m-%d %H:%M", $token_ts); + my ($token, $token_ts) = _create_token($userid, 'emailold', $old_email . ":" . $new_email); - # Generate a unique token and insert it into the tokens table. - # We have to lock the tokens table before generating the token, - # since the database must be queried for token uniqueness. - &::SendSQL("LOCK TABLES tokens WRITE"); - my $token = GenerateUniqueToken(); - my $quotedtoken = &::SqlQuote($token); - my $quoted_emails = &::SqlQuote($old_email . ":" . $new_email); - &::SendSQL("INSERT INTO tokens ( userid , issuedate , token , - tokentype , eventdata ) - VALUES ( $userid , '$issuedate' , $quotedtoken , - 'emailold' , $quoted_emails )"); - my $newtoken = GenerateUniqueToken(); - $quotedtoken = &::SqlQuote($newtoken); - &::SendSQL("INSERT INTO tokens ( userid , issuedate , token , - tokentype , eventdata ) - VALUES ( $userid , '$issuedate' , $quotedtoken , - 'emailnew' , $quoted_emails )"); - &::SendSQL("UNLOCK TABLES"); + my $newtoken = _create_token($userid, 'emailnew', $old_email . ":" . $new_email); # Mail the user the token along with instructions for using it. @@ -124,18 +108,8 @@ sub IssuePasswordToken { ThrowUserError('too_soon_for_new_token'); }; - my $token_ts = time(); - - # Generate a unique token and insert it into the tokens table. - # We have to lock the tokens table before generating the token, - # since the database must be queried for token uniqueness. - &::SendSQL("LOCK TABLES tokens WRITE"); - my $token = GenerateUniqueToken(); - my $quotedtoken = &::SqlQuote($token); - my $quotedipaddr = &::SqlQuote($::ENV{'REMOTE_ADDR'}); - &::SendSQL("INSERT INTO tokens ( userid , issuedate , token , tokentype , eventdata ) - VALUES ( $userid , NOW() , $quotedtoken , 'password' , $quotedipaddr )"); - &::SendSQL("UNLOCK TABLES"); + # Generate a unique token + my ($token, $token_ts) = _create_token($userid, 'password', $::ENV{'REMOTE_ADDR'}); # Mail the user the token along with instructions for using it. @@ -156,6 +130,13 @@ sub IssuePasswordToken { Bugzilla::BugMail::MessageToMTA($message, $vars->{'emailaddress'}); } +sub IssueSessionToken { + # Generates a random token, adds it to the tokens table, and returns + # the token to the caller. + + my $data = shift; + return _create_token(Bugzilla->user->id, 'session', $data); +} sub CleanTokenTable { &::SendSQL("LOCK TABLES tokens WRITE"); @@ -164,7 +145,6 @@ sub CleanTokenTable { &::SendSQL("UNLOCK TABLES"); } - sub GenerateUniqueToken { # Generates a unique random token. Uses &GenerateRandomPassword # for the tokens themselves and checks uniqueness by searching for @@ -174,20 +154,21 @@ sub GenerateUniqueToken { my $token; my $duplicate = 1; my $tries = 0; - while ($duplicate) { + my $dbh = Bugzilla->dbh; + my $sth = $dbh->prepare("SELECT userid FROM tokens WHERE token = ?"); + + while ($duplicate) { ++$tries; if ($tries > 100) { ThrowCodeError("token_generation_error"); } - $token = &::GenerateRandomPassword(); - &::SendSQL("SELECT userid FROM tokens WHERE token = " . &::SqlQuote($token)); - $duplicate = &::FetchSQLData(); + $sth->execute($token); + $duplicate = $sth->fetchrow_array; } return $token; - } @@ -232,9 +213,7 @@ sub Cancel { Bugzilla::BugMail::MessageToMTA($message, $vars->{'emailaddress'}); # Delete the token from the database. - &::SendSQL("LOCK TABLES tokens WRITE"); - &::SendSQL("DELETE FROM tokens WHERE token = $quotedtoken"); - &::SendSQL("UNLOCK TABLES"); + DeleteToken($token); } sub DeletePasswordTokens { @@ -263,5 +242,63 @@ sub HasEmailChangeToken { return $token; } +sub GetTokenData($) { + # Returns the userid, issuedate and eventdata for the specified token + + my ($token) = @_; + return unless defined $token; + trick_taint($token); + + my $dbh = Bugzilla->dbh; + return $dbh->selectrow_array( + "SELECT userid, issuedate, eventdata + FROM tokens + WHERE token = ?", undef, $token); +} + +sub DeleteToken($) { + # Deletes specified token + + my ($token) = @_; + return unless defined $token; + trick_taint($token); + + my $dbh = Bugzilla->dbh; + $dbh->do("LOCK TABLES tokens WRITE"); + $dbh->do("DELETE FROM tokens WHERE token = ?", undef, $token); + $dbh->do("UNLOCK TABLES"); +} + +################################################################################ +# Internal Functions +################################################################################ + +sub _create_token($$$) { + # Generates a unique token and inserts it into the database + # Returns the token and the token timestamp + my ($userid, $tokentype, $eventdata) = @_; + + detaint_natural($userid); + trick_taint($tokentype); + trick_taint($eventdata); + + my $dbh = Bugzilla->dbh; + $dbh->do("LOCK TABLES tokens WRITE"); + + my $token = GenerateUniqueToken(); + + $dbh->do("INSERT INTO tokens (userid, issuedate, token, tokentype, eventdata) + VALUES (?, NOW(), ?, ?, ?)", undef, ($userid, $token, $tokentype, $eventdata)); + + $dbh->do("UNLOCK TABLES"); + + if (wantarray) { + my (undef, $token_ts, undef) = GetTokenData($token); + $token_ts = str2time($token_ts); + return ($token, $token_ts); + } else { + return $token; + } +} 1;