]> git.ipfire.org Git - thirdparty/bugzilla.git/commitdiff
Bug 297646: Write helper functions for Bugzilla::Token.pm
authorbugzilla%glob.com.au <>
Fri, 1 Jul 2005 09:55:11 +0000 (09:55 +0000)
committerbugzilla%glob.com.au <>
Fri, 1 Jul 2005 09:55:11 +0000 (09:55 +0000)
Patch by Byron Jones <bugzilla@glob.com.au> r=LpSolit,a=justdave

Bugzilla/Token.pm

index 7e77a6835b68176b9b965812d329758be4c16284..0149feff9eb9773e41e039dac857fd3796819d5a 100644 (file)
@@ -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;