# Contributor(s): Holger Schurig <holgerschurig@nikocity.de>
# Terry Weissman <terry@mozilla.org>
# Dawn Endico <endico@mozilla.org>
+# Joe Robins <jmrobins@tgix.com>
#
# Direct any questions on this source code to
#
# 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);
print " <TD><INPUT TYPE=TEXT SIZE=64 MAXLENGTH=255 NAME=\"milestoneurl\" VALUE=\"$milestoneurl\"></TD>\n";
}
+ # Added -JMR, 2/16/00
+ if (Param("usebuggroups")) {
+ $userregexp = value_quote($userregexp);
+ print "</TR><TR>\n";
+ print " <TH ALIGN=\"right\">User Regexp for Bug Group:</TH>\n";
+ print " <TD><INPUT TYPE=TEXT SIZE=64 MAXLENGTH=255 NAME=\"userregexp\" VALUE=\"$userregexp\"></TD>\n";
+ }
+
print "</TR><TR>\n";
print " <TH ALIGN=\"right\">Closed for bug entry:</TH>\n";
my $closed = $disallownew ? "CHECKED" : "";
print "<FORM METHOD=POST ACTION=editproducts.cgi>\n";
print "<TABLE BORDER=0 CELLPADDING=4 CELLSPACING=0><TR>\n";
- EmitFormElements('', '', '', 0, 0, 10000, 0);
+ EmitFormElements('', '', '', '', 0, 0, 10000, 0);
print "</TR><TR>\n";
print " <TH ALIGN=\"right\">Version:</TH>\n";
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";
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};
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";
print " <TD VALIGN=\"top\"><A HREF=\"$milestoneurl\">$milestoneurl</A></TD>\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 = "<FONT COLOR=\"red\">undefined</FONT>";
+ } elsif ($userregexp eq "") {
+ $userregexp = "<FONT COLOR=\"blue\">blank</FONT>";
+ }
+ print "</TR><TR>\n";
+ print " <TD VALIGN=\"top\">User Regexp for Bug Group:</TD>\n";
+ print " <TD VALIGN=\"top\">$userregexp</TD>\n";
+ }
+
print "</TR><TR>\n";
print " <TD VALIGN=\"top\">Closed for bugs:</TD>\n";
print " <TD VALIGN=\"top\">$disallownew</TD>\n";
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
SendSQL("DELETE FROM products
WHERE product=" . SqlQuote($product));
print "Product '$product' deleted.<BR>\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'.<BR>\n";
+
+ SendSQL("DELETE FROM groups " .
+ "WHERE bit = $bit");
+ print "Group '$group_desc' deleted.<BR>\n";
+ }
+ }
+
SendSQL("UNLOCK TABLES");
unlink "data/versioncache";
$votesperuser, $maxvotesperbug, $votestoconfirm) =
FetchSQLData();
+ my $userregexp = '';
+ if(Param("usebuggroups")) {
+ SendSQL("SELECT userregexp
+ FROM groups
+ WHERE name=" . SqlQuote($product));
+ $userregexp = FetchOneColumn();
+ }
+
print "<FORM METHOD=POST ACTION=editproducts.cgi>\n";
print "<TABLE BORDER=0 CELLPADDING=4 CELLSPACING=0><TR>\n";
- EmitFormElements($product, $description, $milestoneurl, $disallownew,
- $votesperuser, $maxvotesperbug, $votestoconfirm);
+ EmitFormElements($product, $description, $milestoneurl, $userregexp,
+ $disallownew, $votesperuser, $maxvotesperbug,
+ $votestoconfirm);
print "</TR><TR VALIGN=top>\n";
print " <TH ALIGN=\"right\"><A HREF=\"editcomponents.cgi?product=", url_quote($product), "\">Edit components:</A></TH>\n";
value_quote($description) . "\">\n";
print "<INPUT TYPE=HIDDEN NAME=\"milestoneurlold\" VALUE=\"" .
value_quote($milestoneurl) . "\">\n";
+ if(Param("usebuggroups")) {
+ print "<INPUT TYPE=HIDDEN NAME=\"userregexpold\" VALUE=\"" .
+ value_quote($userregexp) . "\">\n";
+ }
print "<INPUT TYPE=HIDDEN NAME=\"disallownewold\" VALUE=\"$disallownew\">\n";
print "<INPUT TYPE=HIDDEN NAME=\"votesperuserold\" VALUE=\"$votesperuser\">\n";
print "<INPUT TYPE=HIDDEN NAME=\"maxvotesperbugold\" VALUE=\"$maxvotesperbug\">\n";
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);
SendSQL("LOCK TABLES bugs WRITE,
components WRITE,
products WRITE,
- versions WRITE");
+ versions WRITE,
+ groups WRITE,
+ profiles WRITE");
if ($disallownew ne $disallownewold) {
$disallownew ||= 0;
print "Updated mile stone URL.<BR>\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.<BR>\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.<BR>\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.<BR>\n";
+ }
+ }
+
if ($votesperuser ne $votesperuserold) {
SendSQL("UPDATE products
SET votesperuser=$votesperuser
WHERE product=" . SqlQuote($productold));
- print "Update votes per user.<BR>\n";
+ print "Updated votes per user.<BR>\n";
$checkvotes = 1;
}
SendSQL("UPDATE products
SET maxvotesperbug=$maxvotesperbug
WHERE product=" . SqlQuote($productold));
- print "Update max votes per bug.<BR>\n";
+ print "Updated max votes per bug.<BR>\n";
$checkvotes = 1;
}
SendSQL("UPDATE products
SET votestoconfirm=$votestoconfirm
WHERE product=" . SqlQuote($productold));
- print "Update votes to confirm.<BR>\n";
+ print "Updated votes to confirm.<BR>\n";
$checkvotes = 1;
}
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.<BR>\n";
}
unlink "data/versioncache";
#
# Contributor(s): Terry Weissman <terry@mozilla.org>
# Dave Miller <dave@intrec.com>
+# Joe Robins <jmrobins@tgix.com>
########################################################################
$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();
# 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) {
# 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 "<tr><th align=right valign=top><a href=\"enter_bug.cgi?product=" . url_quote($p) . "\">$p</a>:</th>\n";
if (defined $::proddesc{$p}) {
print "<td valign=top>$::proddesc{$p}</td>\n";
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 "<H1>Permission denied.</H1>\n";
+ print "Sorry; you do not have the permissions necessary to enter\n";
+ print "a bug against this product.\n";
+ print "<P>\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 "
<FORM METHOD=POST ACTION=\"post_bug.cgi\">
<INPUT TYPE=HIDDEN NAME=reporter VALUE=\"$::COOKIE{'Bugzilla_login'}\">
<td colspan=5><TEXTAREA WRAP=HARD NAME=comment ROWS=10 COLS=80>" .
value_quote(formvalue('comment')) .
"</TEXTAREA><BR></td>
- </tr>
+ </tr>";
+# 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 "
+ <tr>
+ <td align=right><B>Access:</td>
+ <td colspan=5>
+ <select name=\"groupset\">
+ <option value=0$check0>
+ People not in the \"$group_desc\" group can see this bug
+ </option>
+ <option value=$group_bit$check1>
+ Only people in the \"$group_desc\" group can see this bug
+ </option>
+ </select>
+ </td>
+ </tr>"
+}
+
+print "
<tr>
<td></td><td colspan=5>
";