aboutsummaryrefslogtreecommitdiffstats
path: root/sanitycheck.cgi
diff options
context:
space:
mode:
authorlpsolit%gmail.com <>2006-12-27 04:17:25 +0000
committerlpsolit%gmail.com <>2006-12-27 04:17:25 +0000
commit618959cbc2196f6b2156c40cddf63bf550eb78d8 (patch)
treec7aca4fa058bfe4a7c6ca66e6457b1d71271053a /sanitycheck.cgi
parentf9f63fd6d55a88c4386dbcf732174b5ac2facec9 (diff)
downloadbugs-618959cbc2196f6b2156c40cddf63bf550eb78d8.tar
bugs-618959cbc2196f6b2156c40cddf63bf550eb78d8.tar.gz
bugs-618959cbc2196f6b2156c40cddf63bf550eb78d8.tar.bz2
bugs-618959cbc2196f6b2156c40cddf63bf550eb78d8.tar.xz
bugs-618959cbc2196f6b2156c40cddf63bf550eb78d8.zip
Bug 364780: The keyword cache cannot be fixed with editkeywords privs only - Patch by Frédéric Buclin <LpSolit@gmail.com> r/a=justdave
Diffstat (limited to 'sanitycheck.cgi')
-rwxr-xr-xsanitycheck.cgi283
1 files changed, 156 insertions, 127 deletions
diff --git a/sanitycheck.cgi b/sanitycheck.cgi
index 4b25fa038..bf8ba1980 100755
--- a/sanitycheck.cgi
+++ b/sanitycheck.cgi
@@ -22,6 +22,7 @@
# Matthew Tuck <matty@chariot.net.au>
# Max Kanat-Alexander <mkanat@bugzilla.org>
# Marc Schumann <wurblzap@gmail.com>
+# Frédéric Buclin <LpSolit@gmail.com>
use strict;
@@ -78,11 +79,13 @@ Bugzilla->login(LOGIN_REQUIRED);
my $cgi = Bugzilla->cgi;
my $dbh = Bugzilla->dbh;
my $template = Bugzilla->template;
+my $user = Bugzilla->user;
# Make sure the user is authorized to access sanitycheck.cgi.
# As this script can now alter the group_control_map table, we no longer
# let users with editbugs privs run it anymore.
-Bugzilla->user->in_group("editcomponents")
+$user->in_group("editcomponents")
+ || ($user->in_group('editkeywords') && defined $cgi->param('rebuildkeywordcache'))
|| ThrowUserError("auth_failure", {group => "editcomponents",
action => "run",
object => "sanity_check"});
@@ -94,6 +97,16 @@ my @row;
$template->put_header("Sanity Check");
###########################################################################
+# Users with 'editkeywords' privs only can only check keywords.
+###########################################################################
+unless ($user->in_group('editcomponents')) {
+ check_votes_or_keywords('keywords');
+ Status("Sanity check completed.");
+ $template->put_footer();
+ exit;
+}
+
+###########################################################################
# Fix vote cache
###########################################################################
@@ -602,164 +615,180 @@ sub AlertBadVoteCache {
Alert("Bad vote cache for bug " . BugLink($id));
}
-$sth = $dbh->prepare(q{SELECT bug_id, votes, keywords
- FROM bugs
- WHERE votes != 0
- OR keywords != ''});
-$sth->execute;
-
-my %votes;
-my %bugid;
-my %keyword;
+check_votes_or_keywords();
-while (my ($id, $v, $k) = $sth->fetchrow_array) {
- if ($v != 0) {
- $votes{$id} = $v;
- }
- if ($k) {
- $keyword{$id} = $k;
- }
-}
+sub check_votes_or_keywords {
+ my $check = shift || 'all';
-Status("Checking cached vote counts");
-$sth = $dbh->prepare(q{SELECT bug_id, SUM(vote_count)
- FROM votes }.
- $dbh->sql_group_by('bug_id'));
-$sth->execute;
+ my $dbh = Bugzilla->dbh;
+ my $sth = $dbh->prepare(q{SELECT bug_id, votes, keywords
+ FROM bugs
+ WHERE votes != 0 OR keywords != ''});
+ $sth->execute;
-my $offer_votecache_rebuild = 0;
+ my %votes;
+ my %keyword;
-while (my ($id, $v) = $sth->fetchrow_array) {
- if ($v <= 0) {
- Alert("Bad vote sum for bug $id");
- } else {
- if (!defined $votes{$id} || $votes{$id} != $v) {
- AlertBadVoteCache($id);
- $offer_votecache_rebuild = 1;
+ while (my ($id, $v, $k) = $sth->fetchrow_array) {
+ if ($v != 0) {
+ $votes{$id} = $v;
+ }
+ if ($k) {
+ $keyword{$id} = $k;
}
- delete $votes{$id};
}
-}
-foreach my $id (keys %votes) {
- AlertBadVoteCache($id);
- $offer_votecache_rebuild = 1;
-}
-if ($offer_votecache_rebuild) {
- print qq{<a href="sanitycheck.cgi?rebuildvotecache=1">Click here to rebuild the vote cache</a><p>\n};
+ # If we only want to check keywords, skip checks about votes.
+ _check_votes(\%votes) unless ($check eq 'keywords');
+ # If we only want to check votes, skip checks about keywords.
+ _check_keywords(\%keyword) unless ($check eq 'votes');
}
+sub _check_votes {
+ my $votes = shift;
-Status("Checking keywords table");
-
-my %keywordids;
+ Status("Checking cached vote counts");
+ my $dbh = Bugzilla->dbh;
+ my $sth = $dbh->prepare(q{SELECT bug_id, SUM(vote_count)
+ FROM votes }.
+ $dbh->sql_group_by('bug_id'));
+ $sth->execute;
-my $keywords = $dbh->selectall_arrayref(q{SELECT id, name
- FROM keyworddefs});
+ my $offer_votecache_rebuild = 0;
-foreach my $keyword (@$keywords) {
- my ($id, $name) = @$keyword;
- if ($keywordids{$id}) {
- Alert("Duplicate entry in keyworddefs for id $id");
+ while (my ($id, $v) = $sth->fetchrow_array) {
+ if ($v <= 0) {
+ Alert("Bad vote sum for bug $id");
+ } else {
+ if (!defined $votes->{$id} || $votes->{$id} != $v) {
+ AlertBadVoteCache($id);
+ $offer_votecache_rebuild = 1;
+ }
+ delete $votes->{$id};
+ }
}
- $keywordids{$id} = 1;
- if ($name =~ /[\s,]/) {
- Alert("Bogus name in keyworddefs for id $id");
+ foreach my $id (keys %$votes) {
+ AlertBadVoteCache($id);
+ $offer_votecache_rebuild = 1;
}
-}
-$sth = $dbh->prepare(q{SELECT bug_id, keywordid
- FROM keywords
- ORDER BY bug_id, keywordid});
-$sth->execute;
-my $lastid;
-my $lastk;
-while (my ($id, $k) = $sth->fetchrow_array) {
- if (!$keywordids{$k}) {
- Alert("Bogus keywordids $k found in keywords table");
+ if ($offer_votecache_rebuild) {
+ print qq{<a href="sanitycheck.cgi?rebuildvotecache=1">Click here to rebuild the vote cache</a><p>\n};
}
- if (defined $lastid && $id eq $lastid && $k eq $lastk) {
- Alert("Duplicate keyword ids found in bug " . BugLink($id));
- }
- $lastid = $id;
- $lastk = $k;
}
-Status("Checking cached keywords");
-
-my %realk;
+sub _check_keywords {
+ my $keyword = shift;
-if (defined $cgi->param('rebuildkeywordcache')) {
- $dbh->bz_lock_tables('bugs write', 'keywords read',
- 'keyworddefs read');
-}
+ Status("Checking keywords table");
+ my $dbh = Bugzilla->dbh;
+ my $cgi = Bugzilla->cgi;
-my $query = q{SELECT keywords.bug_id, keyworddefs.name
- FROM keywords
- INNER JOIN keyworddefs
- ON keyworddefs.id = keywords.keywordid
- INNER JOIN bugs
- ON keywords.bug_id = bugs.bug_id
- ORDER BY keywords.bug_id, keyworddefs.name};
+ my %keywordids;
+ my $keywords = $dbh->selectall_arrayref(q{SELECT id, name
+ FROM keyworddefs});
-$sth = $dbh->prepare($query);
-$sth->execute;
+ foreach (@$keywords) {
+ my ($id, $name) = @$_;
+ if ($keywordids{$id}) {
+ Alert("Duplicate entry in keyworddefs for id $id");
+ }
+ $keywordids{$id} = 1;
+ if ($name =~ /[\s,]/) {
+ Alert("Bogus name in keyworddefs for id $id");
+ }
+ }
-my $lastb = 0;
-my @list;
-while (1) {
- my ($b, $k) = $sth->fetchrow_array;
- if (!defined $b || $b != $lastb) {
- if (@list) {
- $realk{$lastb} = join(', ', @list);
+ my $sth = $dbh->prepare(q{SELECT bug_id, keywordid
+ FROM keywords
+ ORDER BY bug_id, keywordid});
+ $sth->execute;
+ my $lastid;
+ my $lastk;
+ while (my ($id, $k) = $sth->fetchrow_array) {
+ if (!$keywordids{$k}) {
+ Alert("Bogus keywordids $k found in keywords table");
}
- if (!$b) {
- last;
+ if (defined $lastid && $id eq $lastid && $k eq $lastk) {
+ Alert("Duplicate keyword ids found in bug " . BugLink($id));
}
- $lastb = $b;
- @list = ();
+ $lastid = $id;
+ $lastk = $k;
}
- push(@list, $k);
-}
-my @badbugs = ();
+ Status("Checking cached keywords");
-foreach my $b (keys(%keyword)) {
- if (!exists $realk{$b} || $realk{$b} ne $keyword{$b}) {
- push(@badbugs, $b);
+ if (defined $cgi->param('rebuildkeywordcache')) {
+ $dbh->bz_lock_tables('bugs write', 'keywords read', 'keyworddefs read');
}
-}
-foreach my $b (keys(%realk)) {
- if (!exists $keyword{$b}) {
- push(@badbugs, $b);
+
+ my $query = q{SELECT keywords.bug_id, keyworddefs.name
+ FROM keywords
+ INNER JOIN keyworddefs
+ ON keyworddefs.id = keywords.keywordid
+ INNER JOIN bugs
+ ON keywords.bug_id = bugs.bug_id
+ ORDER BY keywords.bug_id, keyworddefs.name};
+
+ $sth = $dbh->prepare($query);
+ $sth->execute;
+
+ my $lastb = 0;
+ my @list;
+ my %realk;
+ while (1) {
+ my ($b, $k) = $sth->fetchrow_array;
+ if (!defined $b || $b != $lastb) {
+ if (@list) {
+ $realk{$lastb} = join(', ', @list);
+ }
+ last unless $b;
+
+ $lastb = $b;
+ @list = ();
+ }
+ push(@list, $k);
}
-}
-if (@badbugs) {
- @badbugs = sort {$a <=> $b} @badbugs;
- Alert(scalar(@badbugs) . " bug(s) found with incorrect keyword cache: " .
- BugListLinks(@badbugs));
-
- my $sth_update = $dbh->prepare(q{UPDATE bugs
- SET keywords = ?
- WHERE bug_id = ?});
-
- if (defined $cgi->param('rebuildkeywordcache')) {
- Status("OK, now fixing keyword cache.");
- foreach my $b (@badbugs) {
- my $k = '';
- if (exists($realk{$b})) {
- $k = $realk{$b};
+
+ my @badbugs = ();
+
+ foreach my $b (keys(%$keyword)) {
+ if (!exists $realk{$b} || $realk{$b} ne $keyword->{$b}) {
+ push(@badbugs, $b);
+ }
+ }
+ foreach my $b (keys(%realk)) {
+ if (!exists $keyword->{$b}) {
+ push(@badbugs, $b);
+ }
+ }
+ if (@badbugs) {
+ @badbugs = sort {$a <=> $b} @badbugs;
+ Alert(scalar(@badbugs) . " bug(s) found with incorrect keyword cache: " .
+ BugListLinks(@badbugs));
+
+ my $sth_update = $dbh->prepare(q{UPDATE bugs
+ SET keywords = ?
+ WHERE bug_id = ?});
+
+ if (defined $cgi->param('rebuildkeywordcache')) {
+ Status("OK, now fixing keyword cache.");
+ foreach my $b (@badbugs) {
+ my $k = '';
+ if (exists($realk{$b})) {
+ $k = $realk{$b};
+ }
+ $sth_update->execute($k, $b);
}
- $sth_update->execute($k, $b);
+ Status("Keyword cache fixed.");
+ } else {
+ print qq{<a href="sanitycheck.cgi?rebuildkeywordcache=1">Click here to rebuild the keyword cache</a><p>\n};
}
- Status("Keyword cache fixed.");
- } else {
- print qq{<a href="sanitycheck.cgi?rebuildkeywordcache=1">Click here to rebuild the keyword cache</a><p>\n};
}
-}
-if (defined $cgi->param('rebuildkeywordcache')) {
- $dbh->bz_unlock_tables();
+ if (defined $cgi->param('rebuildkeywordcache')) {
+ $dbh->bz_unlock_tables();
+ }
}
###########################################################################
@@ -888,7 +917,7 @@ BugCheck("bugs INNER JOIN products ON bugs.product_id = products.id " .
Status("Checking for bad values in group_control_map");
my $groups = join(", ", (CONTROLMAPNA, CONTROLMAPSHOWN, CONTROLMAPDEFAULT,
CONTROLMAPMANDATORY));
-$query = qq{
+my $query = qq{
SELECT COUNT(product_id)
FROM group_control_map
WHERE membercontrol NOT IN( $groups )