Commit 65e2e0e8 authored by lpsolit%gmail.com's avatar lpsolit%gmail.com

Bug 300551: Eliminate deprecated Bugzilla::DB routines from User.pm and Token.pm…

Bug 300551: Eliminate deprecated Bugzilla::DB routines from User.pm and Token.pm - Patch by Frédéric Buclin <LpSolit@gmail.com> r=wicked a=justdave
parent f4ec7d28
...@@ -88,36 +88,32 @@ sub IssueEmailChangeToken { ...@@ -88,36 +88,32 @@ sub IssueEmailChangeToken {
Bugzilla::BugMail::MessageToMTA($message); Bugzilla::BugMail::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 { sub IssuePasswordToken {
# Generates a random token, adds it to the tokens table, and sends it my $loginname = shift;
# to the user with instructions for using it to change their password.
my ($loginname) = @_;
my $dbh = Bugzilla->dbh; my $dbh = Bugzilla->dbh;
my $template = Bugzilla->template;
my $vars = {};
# Retrieve the user's ID from the database. # Retrieve the user's ID from the database.
my $quotedloginname = &::SqlQuote($loginname); trick_taint($loginname);
&::SendSQL("SELECT profiles.userid, tokens.issuedate FROM profiles my ($userid, $too_soon) =
LEFT JOIN tokens $dbh->selectrow_array('SELECT profiles.userid, tokens.issuedate
ON tokens.userid = profiles.userid FROM profiles
AND tokens.tokentype = 'password' LEFT JOIN tokens
AND tokens.issuedate > NOW() - " . ON tokens.userid = profiles.userid
$dbh->sql_interval(10, 'MINUTE') . " AND tokens.tokentype = ?
WHERE " . $dbh->sql_istrcmp('login_name', $quotedloginname)); AND tokens.issuedate > NOW() - ' .
my ($userid, $toosoon) = &::FetchSQLData(); $dbh->sql_interval(10, 'MINUTE') . '
WHERE ' . $dbh->sql_istrcmp('login_name', '?'),
if ($toosoon) { undef, ('password', $loginname));
ThrowUserError('too_soon_for_new_token');
}; ThrowUserError('too_soon_for_new_token') if $too_soon;
my ($token, $token_ts) = _create_token($userid, 'password', $::ENV{'REMOTE_ADDR'}); my ($token, $token_ts) = _create_token($userid, 'password', $::ENV{'REMOTE_ADDR'});
# Mail the user the token along with instructions for using it. # Mail the user the token along with instructions for using it.
my $template = Bugzilla->template;
my $vars = {};
$vars->{'token'} = $token; $vars->{'token'} = $token;
$vars->{'emailaddress'} = $loginname . Param('emailsuffix'); $vars->{'emailaddress'} = $loginname . Param('emailsuffix');
...@@ -143,9 +139,10 @@ sub IssueSessionToken { ...@@ -143,9 +139,10 @@ sub IssueSessionToken {
sub CleanTokenTable { sub CleanTokenTable {
my $dbh = Bugzilla->dbh; my $dbh = Bugzilla->dbh;
$dbh->bz_lock_tables('tokens WRITE'); $dbh->bz_lock_tables('tokens WRITE');
&::SendSQL("DELETE FROM tokens WHERE " . $dbh->do('DELETE FROM tokens
$dbh->sql_to_days('NOW()') . " - " . WHERE ' . $dbh->sql_to_days('NOW()') . ' - ' .
$dbh->sql_to_days('issuedate') . " >= " . $maxtokenage); $dbh->sql_to_days('issuedate') . ' >= ?',
undef, $maxtokenage);
$dbh->bz_unlock_tables(); $dbh->bz_unlock_tables();
} }
...@@ -154,9 +151,8 @@ sub GenerateUniqueToken { ...@@ -154,9 +151,8 @@ sub GenerateUniqueToken {
# for the tokens themselves and checks uniqueness by searching for # for the tokens themselves and checks uniqueness by searching for
# the token in the "tokens" table. Gives up if it can't come up # the token in the "tokens" table. Gives up if it can't come up
# with a token after about one hundred tries. # with a token after about one hundred tries.
my ($table, $column) = @_; my ($table, $column) = @_;
my $token; my $token;
my $duplicate = 1; my $duplicate = 1;
my $tries = 0; my $tries = 0;
...@@ -175,30 +171,27 @@ sub GenerateUniqueToken { ...@@ -175,30 +171,27 @@ sub GenerateUniqueToken {
$sth->execute($token); $sth->execute($token);
$duplicate = $sth->fetchrow_array; $duplicate = $sth->fetchrow_array;
} }
return $token; return $token;
} }
# Cancels a previously issued token and notifies the system administrator.
# 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 { sub Cancel {
# Cancels a previously issued token and notifies the system administrator.
# 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.
my ($token, $cancelaction, $vars) = @_; my ($token, $cancelaction, $vars) = @_;
my $dbh = Bugzilla->dbh; my $dbh = Bugzilla->dbh;
$vars ||= {}; $vars ||= {};
# Quote the token for inclusion in SQL statements.
my $quotedtoken = &::SqlQuote($token);
# Get information about the token being cancelled. # Get information about the token being cancelled.
&::SendSQL("SELECT " . $dbh->sql_date_format('issuedate') . ", trick_taint($token);
tokentype , eventdata , login_name , realname my ($issuedate, $tokentype, $eventdata, $loginname, $realname) =
FROM tokens, profiles $dbh->selectrow_array('SELECT ' . $dbh->sql_date_format('issuedate') . ',
WHERE tokens.userid = profiles.userid tokentype , eventdata , login_name , realname
AND token = $quotedtoken"); FROM tokens
my ($issuedate, $tokentype, $eventdata, $loginname, $realname) = &::FetchSQLData(); INNER JOIN profiles
ON tokens.userid = profiles.userid
WHERE token = ?',
undef, $token);
# Get the email address of the Bugzilla maintainer. # Get the email address of the Bugzilla maintainer.
my $maintainer = Param('maintainer'); my $maintainer = Param('maintainer');
...@@ -228,53 +221,53 @@ sub Cancel { ...@@ -228,53 +221,53 @@ sub Cancel {
sub DeletePasswordTokens { sub DeletePasswordTokens {
my ($userid, $reason) = @_; my ($userid, $reason) = @_;
my $dbh = Bugzilla->dbh; my $dbh = Bugzilla->dbh;
my $sth = $dbh->prepare("SELECT token " .
"FROM tokens " . detaint_natural($userid);
"WHERE userid=? AND tokentype='password'"); my $tokens = $dbh->selectcol_arrayref('SELECT token FROM tokens
$sth->execute($userid); WHERE userid = ? AND tokentype = ?',
while (my $token = $sth->fetchrow_array) { undef, ($userid, 'password'));
foreach my $token (@$tokens) {
Bugzilla::Token::Cancel($token, $reason); Bugzilla::Token::Cancel($token, $reason);
} }
} }
# Returns an email change token if the user has one.
sub HasEmailChangeToken { sub HasEmailChangeToken {
# Returns an email change token if the user has one. my $userid = shift;
my ($userid) = @_;
my $dbh = Bugzilla->dbh; my $dbh = Bugzilla->dbh;
&::SendSQL("SELECT token FROM tokens WHERE userid = $userid " .
"AND (tokentype = 'emailnew' OR tokentype = 'emailold') " . my $token = $dbh->selectrow_array('SELECT token FROM tokens
$dbh->sql_limit(1)); WHERE userid = ?
my ($token) = &::FetchSQLData(); AND (tokentype = ? OR tokentype = ?) ' .
$dbh->sql_limit(1),
undef, ($userid, 'emailnew', 'emailold'));
return $token; return $token;
} }
# Returns the userid, issuedate and eventdata for the specified token
sub GetTokenData { sub GetTokenData {
# Returns the userid, issuedate and eventdata for the specified token
my ($token) = @_; my ($token) = @_;
my $dbh = Bugzilla->dbh;
return unless defined $token; return unless defined $token;
trick_taint($token); trick_taint($token);
my $dbh = Bugzilla->dbh;
return $dbh->selectrow_array( return $dbh->selectrow_array(
"SELECT userid, " . $dbh->sql_date_format('issuedate') . ", eventdata "SELECT userid, " . $dbh->sql_date_format('issuedate') . ", eventdata
FROM tokens FROM tokens
WHERE token = ?", undef, $token); WHERE token = ?", undef, $token);
} }
# Deletes specified token
sub DeleteToken { sub DeleteToken {
# Deletes specified token
my ($token) = @_; my ($token) = @_;
my $dbh = Bugzilla->dbh;
return unless defined $token; return unless defined $token;
trick_taint($token); trick_taint($token);
my $dbh = Bugzilla->dbh;
$dbh->bz_lock_tables('tokens WRITE'); $dbh->bz_lock_tables('tokens WRITE');
$dbh->do("DELETE FROM tokens WHERE token = ?", undef, $token); $dbh->do("DELETE FROM tokens WHERE token = ?", undef, $token);
$dbh->bz_unlock_tables(); $dbh->bz_unlock_tables();
...@@ -284,16 +277,16 @@ sub DeleteToken { ...@@ -284,16 +277,16 @@ sub DeleteToken {
# Internal Functions # Internal Functions
################################################################################ ################################################################################
# Generates a unique token and inserts it into the database
# Returns the token and the token timestamp
sub _create_token { sub _create_token {
# Generates a unique token and inserts it into the database
# Returns the token and the token timestamp
my ($userid, $tokentype, $eventdata) = @_; my ($userid, $tokentype, $eventdata) = @_;
my $dbh = Bugzilla->dbh;
detaint_natural($userid); detaint_natural($userid);
trick_taint($tokentype); trick_taint($tokentype);
trick_taint($eventdata); trick_taint($eventdata);
my $dbh = Bugzilla->dbh;
$dbh->bz_lock_tables('tokens WRITE'); $dbh->bz_lock_tables('tokens WRITE');
my $token = GenerateUniqueToken(); my $token = GenerateUniqueToken();
......
...@@ -129,19 +129,11 @@ sub _create { ...@@ -129,19 +129,11 @@ sub _create {
my $dbh = Bugzilla->dbh; my $dbh = Bugzilla->dbh;
my ($id, my ($id, $login, $name, $disabledtext, $mybugslink) =
$login, $dbh->selectrow_array(qq{SELECT userid, login_name, realname,
$name, disabledtext, mybugslink
$disabledtext, FROM profiles WHERE $cond},
$mybugslink) = $dbh->selectrow_array(qq{SELECT userid, undef, $val);
login_name,
realname,
disabledtext,
mybugslink
FROM profiles
WHERE $cond},
undef,
$val);
return undef unless defined $id; return undef unless defined $id;
...@@ -675,12 +667,8 @@ sub derive_regexp_groups { ...@@ -675,12 +667,8 @@ sub derive_regexp_groups {
} }
} }
$dbh->do(q{UPDATE profiles $dbh->do(q{UPDATE profiles SET refreshed_when = ? WHERE userid = ?},
SET refreshed_when = ? undef, ($time, $id));
WHERE userid=?},
undef,
$time,
$id);
} }
sub product_responsibilities { sub product_responsibilities {
...@@ -751,9 +739,10 @@ sub match { ...@@ -751,9 +739,10 @@ sub match {
# $str contains the string to match, while $limit contains the # $str contains the string to match, while $limit contains the
# maximum number of records to retrieve. # maximum number of records to retrieve.
my ($str, $limit, $exclude_disabled) = @_; my ($str, $limit, $exclude_disabled) = @_;
my $user = Bugzilla->user;
my @users = (); my $dbh = Bugzilla->dbh;
my @users = ();
return \@users if $str =~ /^\s*$/; return \@users if $str =~ /^\s*$/;
# The search order is wildcards, then exact match, then substring search. # The search order is wildcards, then exact match, then substring search.
...@@ -762,97 +751,77 @@ sub match { ...@@ -762,97 +751,77 @@ sub match {
# ones following it will not execute. # ones following it will not execute.
# first try wildcards # first try wildcards
my $wildstr = $str; my $wildstr = $str;
my $user = Bugzilla->user;
my $dbh = Bugzilla->dbh;
if ($wildstr =~ s/\*/\%/g && # don't do wildcards if no '*' in the string if ($wildstr =~ s/\*/\%/g && # don't do wildcards if no '*' in the string
Param('usermatchmode') ne 'off') { # or if we only want exact matches Param('usermatchmode') ne 'off') { # or if we only want exact matches
# Build the query. # Build the query.
my $sqlstr = &::SqlQuote($wildstr); trick_taint($wildstr);
my $query = "SELECT DISTINCT userid, realname, login_name, " . my $query = "SELECT DISTINCT login_name FROM profiles ";
"LENGTH(login_name) AS namelength " . if (Param('usevisibilitygroups')) {
"FROM profiles "; $query .= "INNER JOIN user_group_map
if (&::Param('usevisibilitygroups')) { ON user_group_map.user_id = profiles.userid ";
$query .= ", user_group_map ";
} }
$query .= "WHERE (" $query .= "WHERE ("
. $dbh->sql_istrcmp('login_name', $sqlstr, "LIKE") . " OR " . . $dbh->sql_istrcmp('login_name', '?', "LIKE") . " OR " .
$dbh->sql_istrcmp('realname', $sqlstr, "LIKE") . ") "; $dbh->sql_istrcmp('realname', '?', "LIKE") . ") ";
if (&::Param('usevisibilitygroups')) { if (Param('usevisibilitygroups')) {
$query .= "AND user_group_map.user_id = userid " . $query .= "AND isbless = 0 " .
"AND isbless = 0 " .
"AND group_id IN(" . "AND group_id IN(" .
join(', ', (-1, @{$user->visible_groups_inherited})) . join(', ', (-1, @{$user->visible_groups_inherited})) . ") ";
")";
} }
$query .= " AND disabledtext = '' " if $exclude_disabled; $query .= " AND disabledtext = '' " if $exclude_disabled;
$query .= "ORDER BY namelength "; $query .= " ORDER BY login_name ";
$query .= $dbh->sql_limit($limit) if $limit; $query .= $dbh->sql_limit($limit) if $limit;
# Execute the query, retrieve the results, and make them into # Execute the query, retrieve the results, and make them into
# User objects. # User objects.
my $user_logins = $dbh->selectcol_arrayref($query, undef, ($wildstr, $wildstr));
&::PushGlobalSQLState(); foreach my $login_name (@$user_logins) {
&::SendSQL($query); push(@users, Bugzilla::User->new_from_login($login_name));
push(@users, new Bugzilla::User(&::FetchSQLData())) while &::MoreSQLData(); }
&::PopGlobalSQLState();
} }
else { # try an exact match else { # try an exact match
my $sqlstr = &::SqlQuote($str);
my $query = "SELECT userid, realname, login_name " .
"FROM profiles " .
"WHERE " . $dbh->sql_istrcmp('login_name', $sqlstr);
# Exact matches don't care if a user is disabled. # Exact matches don't care if a user is disabled.
trick_taint($str);
my $user_id = $dbh->selectrow_array('SELECT userid FROM profiles
WHERE ' . $dbh->sql_istrcmp('login_name', '?'),
undef, $str);
&::PushGlobalSQLState(); push(@users, new Bugzilla::User($user_id)) if $user_id;
&::SendSQL($query);
push(@users, new Bugzilla::User(&::FetchSQLData())) if &::MoreSQLData();
&::PopGlobalSQLState();
} }
# then try substring search # then try substring search
if ((scalar(@users) == 0) if ((scalar(@users) == 0)
&& (&::Param('usermatchmode') eq 'search') && (Param('usermatchmode') eq 'search')
&& (length($str) >= 3)) && (length($str) >= 3))
{ {
$str = lc($str);
trick_taint($str);
my $sqlstr = &::SqlQuote(lc($str)); my $query = "SELECT DISTINCT login_name FROM profiles ";
if (Param('usevisibilitygroups')) {
my $query = "SELECT DISTINCT userid, realname, login_name, " . $query .= "INNER JOIN user_group_map
"LENGTH(login_name) AS namelength " . ON user_group_map.user_id = profiles.userid ";
"FROM profiles";
if (&::Param('usevisibilitygroups')) {
$query .= ", user_group_map";
} }
$query .= " WHERE (" . $query .= " WHERE (" .
$dbh->sql_position($sqlstr, 'LOWER(login_name)') . " > 0" . $dbh->sql_position('?', 'LOWER(login_name)') . " > 0" . " OR " .
" OR " . $dbh->sql_position('?', 'LOWER(realname)') . " > 0) ";
$dbh->sql_position($sqlstr, 'LOWER(realname)') . " > 0)"; if (Param('usevisibilitygroups')) {
if (&::Param('usevisibilitygroups')) { $query .= " AND isbless = 0" .
$query .= " AND user_group_map.user_id = userid" .
" AND isbless = 0" .
" AND group_id IN(" . " AND group_id IN(" .
join(', ', (-1, @{$user->visible_groups_inherited})) . ")"; join(', ', (-1, @{$user->visible_groups_inherited})) . ") ";
} }
$query .= " AND disabledtext = ''" if $exclude_disabled; $query .= " AND disabledtext = '' " if $exclude_disabled;
$query .= " ORDER BY namelength"; $query .= " ORDER BY login_name ";
$query .= " " . $dbh->sql_limit($limit) if $limit; $query .= $dbh->sql_limit($limit) if $limit;
&::PushGlobalSQLState();
&::SendSQL($query);
push(@users, new Bugzilla::User(&::FetchSQLData())) while &::MoreSQLData();
&::PopGlobalSQLState();
}
# order @users by alpha
@users = sort { uc($a->login) cmp uc($b->login) } @users;
my $user_logins = $dbh->selectcol_arrayref($query, undef, ($str, $str));
foreach my $login_name (@$user_logins) {
push(@users, Bugzilla::User->new_from_login($login_name));
}
}
return \@users; return \@users;
} }
...@@ -1203,10 +1172,10 @@ sub wants_bug_mail { ...@@ -1203,10 +1172,10 @@ sub wants_bug_mail {
# need one piece of information, and doing so (as of 2004-11-23) slows # need one piece of information, and doing so (as of 2004-11-23) slows
# down bugmail sending by a factor of 2. If Bug creation was more # down bugmail sending by a factor of 2. If Bug creation was more
# lazy, this might not be so bad. # lazy, this might not be so bad.
my $bug_status = $dbh->selectrow_array("SELECT bug_status my $bug_status = $dbh->selectrow_array('SELECT bug_status
FROM bugs FROM bugs WHERE bug_id = ?',
WHERE bug_id = $bug_id"); undef, $bug_id);
if ($bug_status eq "UNCONFIRMED") { if ($bug_status eq "UNCONFIRMED") {
$wants_mail &= $self->wants_mail([EVT_UNCONFIRMED], $relationship); $wants_mail &= $self->wants_mail([EVT_UNCONFIRMED], $relationship);
} }
...@@ -1237,13 +1206,14 @@ sub wants_mail { ...@@ -1237,13 +1206,14 @@ sub wants_mail {
} }
my $wants_mail = my $wants_mail =
$dbh->selectrow_array("SELECT 1 $dbh->selectrow_array('SELECT 1
FROM email_setting FROM email_setting
WHERE user_id = $self->{'id'} WHERE user_id = ?
AND relationship = $relationship AND relationship = ?
AND event IN (" . join(",", @$events) . ") AND event IN (' . join(',', @$events) . ') ' .
LIMIT 1"); $dbh->sql_limit(1),
undef, ($self->{'id'}, $relationship));
return defined($wants_mail) ? 1 : 0; return defined($wants_mail) ? 1 : 0;
} }
...@@ -1271,7 +1241,7 @@ sub get_userlist { ...@@ -1271,7 +1241,7 @@ sub get_userlist {
$query .= " 1 "; $query .= " 1 ";
} }
$query .= "FROM profiles "; $query .= "FROM profiles ";
if (&::Param('usevisibilitygroups')) { if (Param('usevisibilitygroups')) {
$query .= "LEFT JOIN user_group_map " . $query .= "LEFT JOIN user_group_map " .
"ON user_group_map.user_id = userid AND isbless = 0 " . "ON user_group_map.user_id = userid AND isbless = 0 " .
"AND group_id IN(" . "AND group_id IN(" .
...@@ -1334,16 +1304,14 @@ sub insert_new_user { ...@@ -1334,16 +1304,14 @@ sub insert_new_user {
next if ($event == EVT_CHANGED_BY_ME); next if ($event == EVT_CHANGED_BY_ME);
next if (($event == EVT_CC) && ($rel != REL_REPORTER)); next if (($event == EVT_CC) && ($rel != REL_REPORTER));
$dbh->do("INSERT INTO email_setting " . $dbh->do('INSERT INTO email_setting (user_id, relationship, event)
"(user_id, relationship, event) " . VALUES (?, ?, ?)', undef, ($userid, $rel, $event));
"VALUES ($userid, $rel, $event)"); }
}
} }
foreach my $event (GLOBAL_EVENTS) { foreach my $event (GLOBAL_EVENTS) {
$dbh->do("INSERT INTO email_setting " . $dbh->do('INSERT INTO email_setting (user_id, relationship, event)
"(user_id, relationship, event) " . VALUES (?, ?, ?)', undef, ($userid, REL_ANY, $event));
"VALUES ($userid, " . REL_ANY . ", $event)");
} }
my $user = new Bugzilla::User($userid); my $user = new Bugzilla::User($userid);
......
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