diff --git a/webtools/bugzilla/defparams.pl b/webtools/bugzilla/defparams.pl index c65de76640bf..04e90ad0da29 100644 --- a/webtools/bugzilla/defparams.pl +++ b/webtools/bugzilla/defparams.pl @@ -20,7 +20,7 @@ # Contributor(s): Terry Weissman # Dawn Endico # Dan Mosedale - +# Joe Robins # This file defines all the parameters that we have a GUI to edit within # Bugzilla. @@ -158,6 +158,18 @@ DefParam("usequip", "b", 1); +# Added parameter - JMR, 2/16/00 +DefParam("usebuggroups", + "If this is on, Bugzilla will associate a bug group with each product in the database, and use it for querying bugs.", + "b", + 0); + +# Added parameter - JMR, 2/16/00 +DefParam("usebuggroupsentry", + "If this is on, Bugzilla will use product bug groups to restrict who can enter bugs. Requires usebuggroups to be on as well.", + "b", + 0); + DefParam("shadowdb", "If non-empty, then this is the name of another database in which Bugzilla will keep a shadow read-only copy of everything. This is done so that long slow read-only operations can be used against this db, and not lock up things for everyone else. Turning on this parameter will create the given database; be careful not to use the name of an existing database with useful data in it!", "t", diff --git a/webtools/bugzilla/editproducts.cgi b/webtools/bugzilla/editproducts.cgi index d224077b3539..db607b40471c 100755 --- a/webtools/bugzilla/editproducts.cgi +++ b/webtools/bugzilla/editproducts.cgi @@ -21,6 +21,7 @@ # Contributor(s): Holger Schurig # Terry Weissman # Dawn Endico +# Joe Robins # # Direct any questions on this source code to # @@ -78,9 +79,9 @@ sub CheckProduct ($) # Displays the form to edit a products parameters # -sub EmitFormElements ($$$$$$$) +sub EmitFormElements ($$$$$$$$) { - my ($product, $description, $milestoneurl, $disallownew, + my ($product, $description, $milestoneurl, $userregexp, $disallownew, $votesperuser, $maxvotesperbug, $votestoconfirm) = @_; $product = value_quote($product); @@ -100,6 +101,14 @@ sub EmitFormElements ($$$$$$$) print " \n"; } + # Added -JMR, 2/16/00 + if (Param("usebuggroups")) { + $userregexp = value_quote($userregexp); + print "\n"; + print " User Regexp for Bug Group:\n"; + print " \n"; + } + print "\n"; print " Closed for bug entry:\n"; my $closed = $disallownew ? "CHECKED" : ""; @@ -245,7 +254,7 @@ if ($action eq 'add') { print "
\n"; print "\n"; - EmitFormElements('', '', '', 0, 0, 10000, 0); + EmitFormElements('', '', '', '', 0, 0, 10000, 0); print "\n"; print " \n"; @@ -271,7 +280,7 @@ if ($action eq 'add') { if ($action eq 'new') { PutHeader("Adding new product"); - # Cleanups and valididy checks + # Cleanups and validity checks unless ($product) { print "You must enter a name for the new product. Please press\n"; @@ -297,6 +306,7 @@ if ($action eq 'new') { my $description = trim($::FORM{description} || ''); my $milestoneurl = trim($::FORM{milestoneurl} || ''); + my $userregexp = trim($::FORM{userregexp} || ''); my $disallownew = 0; $disallownew = 1 if $::FORM{disallownew}; my $votesperuser = $::FORM{votesperuser}; @@ -322,6 +332,53 @@ if ($action eq 'new') { SqlQuote($version) . "," . SqlQuote($product) . ")" ); + # If we're using bug groups, then we need to create a group for this + # product as well. -JMR, 2/16/00 + if(Param("usebuggroups")) { + # First we need to figure out the bit for this group. We'll simply + # use the next highest bit available. We'll use a minimum bit of 256, + # to leave room for a few more Bugzilla operation groups at the bottom. + SendSQL("SELECT MAX(bit) FROM groups"); + my $bit = FetchOneColumn(); + if($bit < 256) { + $bit = 256; + } else { + $bit = $bit * 2; + } + + # Next we insert into the groups table + SendSQL("INSERT INTO groups " . + "(bit, name, description, isbuggroup, userregexp) " . + "VALUES (" . + $bit . ", " . + SqlQuote($product) . ", " . + SqlQuote($product . " Bugs Access") . ", " . + "1, " . + SqlQuote($userregexp) . ")"); + + # And last, we need to add any existing users that match the regexp + # to the group. + # There may be a better way to do this in MySql, but I need to compare + # the login_names to this regexp, and the only way I can think of to + # do that is to get the list of login_names, and then update them + # one by one if they match. Furthermore, I need to do it with two + # separate loops, since opening a new SQL statement to do the update + # seems to clobber the previous one. + SendSQL("SELECT login_name FROM profiles"); + my @login_list = (); + my $this_login; + while($this_login = FetchOneColumn()) { + push @login_list, $this_login; + } + foreach $this_login (@login_list) { + if($this_login =~ /$userregexp/) { + SendSQL("UPDATE profiles " . + "SET groupset = groupset | " . $bit . " " . + "WHERE login_name = " . SqlQuote($this_login)); + } + } + } + # Make versioncache flush unlink "data/versioncache"; @@ -369,6 +426,23 @@ if ($action eq 'del') { print " \n"; } + # Added -JMR, 2/16/00 + if(Param('usebuggroups')) { + # Get the regexp for this product. + SendSQL("SELECT userregexp + FROM groups + WHERE name=" . SqlQuote($product)); + my $userregexp = FetchOneColumn(); + if(!defined $userregexp) { + $userregexp = "undefined"; + } elsif ($userregexp eq "") { + $userregexp = "blank"; + } + print "\n"; + print " \n"; + print " \n"; + } + print "\n"; print " \n"; print " \n"; @@ -472,7 +546,9 @@ if ($action eq 'delete') { components WRITE, dependencies WRITE, versions WRITE, - products WRITE"); + products WRITE, + groups WRITE, + profiles WRITE"); # According to MySQL doc I cannot do a DELETE x.* FROM x JOIN Y, # so I have to iterate over bugs and delete all the indivial entries @@ -516,6 +592,32 @@ if ($action eq 'delete') { SendSQL("DELETE FROM products WHERE product=" . SqlQuote($product)); print "Product '$product' deleted.
\n"; + + # Added -JMR, 2/16/00 + if (Param("usebuggroups")) { + # We need to get the bit of the group from the table, then update the + # groupsets of members of that group and remove the group. + SendSQL("SELECT bit, description FROM groups " . + "WHERE name = " . SqlQuote($product)); + my ($bit, $group_desc) = FetchSQLData(); + + # Make sure there is a group before we try to do any deleting... + if($bit) { + # I'm kludging a bit so that I don't break superuser access; + # I'm merely checking to make sure that the groupset is not + # the superuser groupset in doing this update... + SendSQL("UPDATE profiles " . + "SET groupset = groupset - $bit " . + "WHERE (groupset & $bit) " . + "AND (groupset != 9223372036854710271)"); + print "Users dropped from group '$group_desc'.
\n"; + + SendSQL("DELETE FROM groups " . + "WHERE bit = $bit"); + print "Group '$group_desc' deleted.
\n"; + } + } + SendSQL("UNLOCK TABLES"); unlink "data/versioncache"; @@ -544,11 +646,20 @@ if ($action eq 'edit') { $votesperuser, $maxvotesperbug, $votestoconfirm) = FetchSQLData(); + my $userregexp = ''; + if(Param("usebuggroups")) { + SendSQL("SELECT userregexp + FROM groups + WHERE name=" . SqlQuote($product)); + $userregexp = FetchOneColumn(); + } + print "\n"; print "
Version:$milestoneurl
User Regexp for Bug Group:$userregexp
Closed for bugs:$disallownew
\n"; - EmitFormElements($product, $description, $milestoneurl, $disallownew, - $votesperuser, $maxvotesperbug, $votestoconfirm); + EmitFormElements($product, $description, $milestoneurl, $userregexp, + $disallownew, $votesperuser, $maxvotesperbug, + $votestoconfirm); print "\n"; print " \n"; @@ -609,6 +720,10 @@ if ($action eq 'edit') { value_quote($description) . "\">\n"; print "\n"; + if(Param("usebuggroups")) { + print "\n"; + } print "\n"; print "\n"; print "\n"; @@ -642,6 +757,8 @@ if ($action eq 'update') { my $milestoneurlold = trim($::FORM{milestoneurlold} || ''); my $votesperuser = trim($::FORM{votesperuser} || 0); my $votesperuserold = trim($::FORM{votesperuserold} || ''); + my $userregexp = trim($::FORM{userregexp} || ''); + my $userregexpold = trim($::FORM{userregexpold} || ''); my $maxvotesperbug = trim($::FORM{maxvotesperbug} || 0); my $maxvotesperbugold = trim($::FORM{maxvotesperbugold} || ''); my $votestoconfirm = trim($::FORM{votestoconfirm} || 0); @@ -663,7 +780,9 @@ if ($action eq 'update') { SendSQL("LOCK TABLES bugs WRITE, components WRITE, products WRITE, - versions WRITE"); + versions WRITE, + groups WRITE, + profiles WRITE"); if ($disallownew ne $disallownewold) { $disallownew ||= 0; @@ -693,11 +812,74 @@ if ($action eq 'update') { print "Updated mile stone URL.
\n"; } + # Added -JMR, 2/16/00 + if (Param("usebuggroups") && $userregexp ne $userregexpold) { + # This will take a little bit of work here, since there may not be + # an existing bug group for this product, and we will also have to + # update users groupsets. + # First we find out if there's an existing group for this product, and + # get its bit if there is. + SendSQL("SELECT bit " . + "FROM groups " . + "WHERE name = " . SqlQuote($productold)); + my $bit = FetchOneColumn(); + if($bit) { + # Group exists, so we do an update statement. + SendSQL("UPDATE groups " . + "SET userregexp = " . SqlQuote($userregexp) . " " . + "WHERE name = " . SqlQuote($productold)); + print "Updated user regexp for bug group.
\n"; + } else { + # Group doesn't exist. Let's make it, the same way as we make a + # group for a new product above. + SendSQL("SELECT MAX(bit) FROM groups"); + my $tmp_bit = FetchOneColumn(); + if($tmp_bit < 256) { + $bit = 256; + } else { + $bit = $tmp_bit * 2; + } + SendSQL("INSERT INTO groups " . + "(bit, name, description, isbuggroup, userregexp) " . + "values (" . $bit . ", " . + SqlQuote($productold) . ", " . + SqlQuote($productold . " Bugs Access") . ", " . + "1, " . + SqlQuote($userregexp) . ")"); + print "Created bug group.
\n"; + } + + # And now we have to update the profiles again to add any users who + # match the new regexp to the group. I'll do this the same way as + # when I create a new group above. Note that I'm not taking out + # users who matched the old regexp and not the new one; that would + # be insanely messy. Use the group administration page for that + # instead. + SendSQL("SELECT login_name FROM profiles"); + my @login_list = (); + my $this_login; + while($this_login = FetchOneColumn()) { + push @login_list, $this_login; + } + my $updated_profiles = 0; + foreach $this_login (@login_list) { + if($this_login =~ /$userregexp/) { + SendSQL("UPDATE profiles " . + "SET groupset = groupset | " . $bit . " " . + "WHERE login_name = " . SqlQuote($this_login)); + $updated_profiles = 1; + } + } + if($updated_profiles) { + print "Added users matching regexp to group.
\n"; + } + } + if ($votesperuser ne $votesperuserold) { SendSQL("UPDATE products SET votesperuser=$votesperuser WHERE product=" . SqlQuote($productold)); - print "Update votes per user.
\n"; + print "Updated votes per user.
\n"; $checkvotes = 1; } @@ -706,7 +888,7 @@ if ($action eq 'update') { SendSQL("UPDATE products SET maxvotesperbug=$maxvotesperbug WHERE product=" . SqlQuote($productold)); - print "Update max votes per bug.
\n"; + print "Updated max votes per bug.
\n"; $checkvotes = 1; } @@ -715,7 +897,7 @@ if ($action eq 'update') { SendSQL("UPDATE products SET votestoconfirm=$votestoconfirm WHERE product=" . SqlQuote($productold)); - print "Update votes to confirm.
\n"; + print "Updated votes to confirm.
\n"; $checkvotes = 1; } @@ -741,7 +923,15 @@ if ($action eq 'update') { SendSQL("UPDATE components SET program=$qp WHERE program=$qpold"); SendSQL("UPDATE products SET product=$qp WHERE product=$qpold"); SendSQL("UPDATE versions SET program=$qp WHERE program=$qpold"); - + # Need to do an update to groups as well. If there is a corresponding + # bug group, whether usebuggroups is currently set or not, we want to + # update it so it will match in the future. If there is no group, this + # update statement will do nothing, so no harm done. -JMR, 3/8/00 + SendSQL("UPDATE groups " . + "SET name=$qp, " . + "description=".SqlQuote($product." Bugs Access")." ". + "WHERE name=$qpold"); + print "Updated product name.
\n"; } unlink "data/versioncache"; diff --git a/webtools/bugzilla/enter_bug.cgi b/webtools/bugzilla/enter_bug.cgi index d9c7ea24d391..f89f2f436ee8 100755 --- a/webtools/bugzilla/enter_bug.cgi +++ b/webtools/bugzilla/enter_bug.cgi @@ -19,6 +19,7 @@ # # Contributor(s): Terry Weissman # Dave Miller +# Joe Robins ######################################################################## @@ -48,6 +49,15 @@ sub sillyness { $zz = @::legal_severity; } +# I've moved the call to confirm_login up to here, since if we're using bug +# groups to restrict bug entry, we need to know who the user is right from +# the start. If that parameter is turned off, there's still no harm done in +# doing it now instead of a bit later. -JMR, 2/18/00 +# Except that it will cause people without cookies enabled to have to log +# in an extra time. Only do it here if we really need to. -terry, 3/10/00 +if (Param("usebuggroupsentry")) { + confirm_login(); +} if (!defined $::FORM{'product'}) { GetVersionTable(); @@ -59,6 +69,14 @@ if (!defined $::FORM{'product'}) { # to allow people to specify that product here. next; } + if(Param("usebuggroupsentry") + && GroupExists($p) + && !UserInGroup($p)) { + # If we're using bug groups to restrict entry on products, and + # this product has a bug group, and the user is not in that + # group, we don't want to include that product in this list. + next; + } push(@prodlist, $p); } if (1 != @prodlist) { @@ -75,6 +93,14 @@ if (!defined $::FORM{'product'}) { # to allow people to specify that product here. next; } + if(Param("usebuggroupsentry") + && GroupExists($p) + && !UserInGroup($p)) { + # If we're using bug groups to restrict entry on products, and + # this product has a bug group, and the user is not in that + # group, we don't want to include that product in this list. + next; + } print "\n"; if (defined $::proddesc{$p}) { print "\n"; @@ -221,6 +247,40 @@ my $component_popup = make_popup('component', $::components{$product}, PutHeader ("Enter Bug","Enter Bug","This page lets you enter a new bug into Bugzilla."); +# Modified, -JMR, 2/24,00 +# If the usebuggroupsentry parameter is set, we need to check and make sure +# that the user has permission to enter a bug against this product. +if(Param("usebuggroupsentry")) { + if(!UserInGroup($product)) { + print "

Permission denied.

\n"; + print "Sorry; you do not have the permissions necessary to enter\n"; + print "a bug against this product.\n"; + print "

\n"; + PutFooter(); + exit; + } +} + +# Modified, -JMR, 2/18/00 +# I'm putting in a select box in order to select whether to restrict this bug to +# the product's bug group or not, if the usebuggroups parameter is set, and if +# this product has a bug group. This box will default to selected, but can be +# turned off if this bug should be world-viewable for some reason. +# +# To do this, I need to (1) get the bit and description for the bug group from +# the database, (2) insert the select box in the giant print statements below, +# and (3) update post_bug.cgi to process the additional input field. + +# First we get the bit and description for the group. +my $group_bit=0; +my $group_desc; +if(Param("usebuggroups") && GroupExists($product)) { + SendSQL("select bit, description from groups ". + "where name = ".SqlQuote($product)." ". + "and isbuggroup != 0"); + ($group_bit, $group_desc) = FetchSQLData(); +} + print " @@ -327,7 +387,36 @@ print "

- + "; +# In between the Description field and the Submit buttons, we'll put in the +# select box for the bug group, if necessary. +# Rather than waste time with another Param check and another database access, +# $group_bit will only have a non-zero value if we're using bug groups and have +# one for this product, so I'll check on that instead here. -JMR, 2/18/00 +if($group_bit) { + # In addition, we need to handle the possibility that we're coming from + # a bookmark template. We'll simply check if we've got a parameter called + # groupset passed with a value other than the current bit. If so, then we're + # coming from a template, and we don't have group_bit set, so turn it off. + my $check0 = (formvalue("groupset",$group_bit) == $group_bit) ? "" : " SELECTED"; + my $check1 = ($check0 eq "") ? " SELECTED" : ""; + print " + + + + " +} + +print "
Edit components:
$p:$::proddesc{$p}
Access: + +
"; diff --git a/webtools/bugzilla/globals.pl b/webtools/bugzilla/globals.pl index 82447389deb9..8e05fc0d27cf 100644 --- a/webtools/bugzilla/globals.pl +++ b/webtools/bugzilla/globals.pl @@ -30,7 +30,6 @@ use strict; sub globals_pl_sillyness { my $zz; $zz = @main::chooseone; - $zz = @main::db_errstr; $zz = @main::default_column_list; $zz = $main::defaultqueryname; $zz = @main::dontchange; @@ -498,7 +497,10 @@ sub InsertNewUser { my $groupset = "0"; while (MoreSQLData()) { my @row = FetchSQLData(); - if ($username =~ m/$row[1]/) { + # Modified -Joe Robins, 2/17/00 + # Making this case insensitive, since usernames are email addresses, + # and could be any case. + if ($username =~ m/$row[1]/i) { $groupset .= "+ $row[0]"; # Silly hack to let MySQL do the math, # not Perl, since we're dealing with 64 # bit ints here, and I don't *think* Perl @@ -681,6 +683,13 @@ sub UserInGroup { return 0; } +sub GroupExists { + my ($groupname) = (@_); + ConnectToDatabase(); + SendSQL("select count(*) from groups where name=" . SqlQuote($groupname)); + my $count = FetchOneColumn(); + return $count; +} # Determines if the given bug_status string represents an "Opened" bug. This # routine ought to be paramaterizable somehow, as people tend to introduce diff --git a/webtools/bugzilla/post_bug.cgi b/webtools/bugzilla/post_bug.cgi index 46843fac58e0..975d407d8895 100755 --- a/webtools/bugzilla/post_bug.cgi +++ b/webtools/bugzilla/post_bug.cgi @@ -20,6 +20,7 @@ # # Contributor(s): Terry Weissman # Dan Mosedale +# Joe Robins use diagnostics; use strict; @@ -67,6 +68,19 @@ PutHeader("Posting Bug -- Please wait", "Posting Bug", "One moment please..."); umask 0; ConnectToDatabase(); +my $product = $::FORM{'product'}; + +if(Param("usebuggroupsentry") && GroupExists($product)) { + if(!UserInGroup($product)) { + print "

Permission denied.

\n"; + print "Sorry; you do not have the permissions necessary to enter\n"; + print "a bug against this product.\n"; + print "

\n"; + PutFooter(); + exit; + } +} + if (!defined $::FORM{'component'} || $::FORM{'component'} eq "") { PuntTryAgain("You must choose a component that corresponds to this bug. " . "If necessary, just guess."); @@ -104,7 +118,11 @@ if (Param("useqacontact")) { } } - +# If we're using bug groups, we need to include the groupset in the list of +# fields. -JMR, 2/18/00 +if(Param("usebuggroups")) { + push(@bug_fields, "groupset"); +} if (exists $::FORM{'bug_status'}) { if (!UserInGroup("canedit") && !UserInGroup("canconfirm")) { @@ -121,7 +139,6 @@ if (!exists $::FORM{'bug_status'}) { } } - if ( Param("strictvaluechecks") ) { GetVersionTable(); CheckFormField(\%::FORM, 'reporter');