Added 'groups' stuff, where we have different group bits that we can

put on a person or on a bug.  Some of the group bits control access to bugzilla
features.  And a person can't access a bug unless he has every group bit set
that is also set on the bug.
This commit is contained in:
terry%netscape.com 1999-03-11 16:30:54 +00:00
Родитель e5223eb70a
Коммит 1cb8909d0c
18 изменённых файлов: 279 добавлений и 84 удалений

Просмотреть файл

@ -231,6 +231,35 @@ sub PasswordForLogin {
return $result;
}
sub quietly_check_login() {
$::usergroupset = '0';
my $loginok = 0;
if (defined $::COOKIE{"Bugzilla_login"} &&
defined $::COOKIE{"Bugzilla_logincookie"}) {
ConnectToDatabase();
SendSQL("select profiles.groupset, profiles.login_name = " .
SqlQuote($::COOKIE{"Bugzilla_login"}) .
" and profiles.cryptpassword = logincookies.cryptpassword " .
"and logincookies.hostname = " .
SqlQuote($ENV{"REMOTE_HOST"}) .
" from profiles,logincookies where logincookies.cookie = " .
$::COOKIE{"Bugzilla_logincookie"} .
" and profiles.userid = logincookies.userid");
my @row;
if (@row = FetchSQLData()) {
$loginok = $row[1];
if ($loginok) {
$::usergroupset = $row[0];
}
}
}
return $loginok;
}
sub confirm_login {
my ($nexturl) = (@_);
@ -324,25 +353,9 @@ To use the wonders of bugzilla, you can use the following:
}
my $loginok = 0;
my $loginok = quietly_check_login();
if (defined $::COOKIE{"Bugzilla_login"} &&
defined $::COOKIE{"Bugzilla_logincookie"}) {
SendSQL("select profiles.login_name = " .
SqlQuote($::COOKIE{"Bugzilla_login"}) .
" and profiles.cryptpassword = logincookies.cryptpassword " .
"and logincookies.hostname = " .
SqlQuote($ENV{"REMOTE_HOST"}) .
" from profiles,logincookies where logincookies.cookie = " .
$::COOKIE{"Bugzilla_logincookie"} .
" and profiles.userid = logincookies.userid");
$loginok = FetchOneColumn();
if (!defined $loginok) {
$loginok = 0;
}
}
if ($loginok ne "1") {
if ($loginok != 1) {
print "Content-type: text/html\n\n";
print "<H1>Please log in.</H1>\n";
print "I need a legitimate e-mail address and password to continue.\n";

Просмотреть файл

@ -10,6 +10,25 @@ query the CVS tree. For example,
will tell you what has been changed in the last week.
3/10/99 Added 'groups' stuff, where we have different group bits that we can
put on a person or on a bug. Some of the group bits control access to bugzilla
features. And a person can't access a bug unless he has every group bit set
that is also set on the bug. See the comments in makegroupstable.sh for a bit
more info.
The 'maintainer' param is now used only as an email address for people to send
complaints to. The groups table is what is now used to determine permissions.
You will need to run the new script "makegroupstable.sh". And then you need to
feed the following lines to MySQL (replace XXX with the login name of the
maintainer, the person you wish to be all-powerful).
alter table bugs add column groupset bigint not null;
alter table profiles add column groupset bigint not null;
update profiles set groupset=0x7fffffffffffffff where login_name = XXX;
3/8/99 Added params to control how priorities are set in a new bug. You can
now choose whether to let submitters of new bugs choose a priority, or whether
they should just accept the default priority (which is now no longer hardcoded

Просмотреть файл

@ -301,27 +301,23 @@ takes four parameters which are (with appropriate values):
Just fill in those values and close up global.pl
5. Setting the Maintainer Information
5. Setting up yourself as Maintainer
Before the last file level configuration can be done you'll have to create
a data/params file. This file is created when the first bugzilla page is
accessed that needs it. The easiest way is to go visit the "query.cgi"
bugzilla page. After that, the data subdirectory should have been created, and
the data/params file should have appeared.
Within that directory you'll find a file called 'params'. params contains
all sorts of juicy things that you'll be tempted to change, but don't bother --
there's a nice web form to change all except the maintainer's email address.
Find the line that begins with "$::param{'maintainer'}" and set the
maintainer's email address to your own.
Now, you can create your own bugzilla account. To do so, just try to "add
Start by creating your own bugzilla account. To do so, just try to "add
a bug" from the main bugzilla menu (now available from your system through your
web browser!). You'll be prompted for logon info, and you should enter your
email address and then select 'mail me my password'. When you get the password
mail, log in with it. Don't finish entering that new bug; instead, go to the
query page (off of the bugzilla main menu) where you'll now find a 'edit
parameters' option which is filled with editable treats.
mail, log in with it. Don't finish entering that new bug.
Now, bring up MySQL, and add yourself to every group. This will
effectively make you 'superuser'. The SQL to type is:
update profiles set groupset=0x7fffffffffffffff where login_name = XXX;
replacing XXX with your email address in quotes.
Now, if you go to the query page (off of the bugzilla main menu) where you'll
now find a 'edit parameters' option which is filled with editable treats.
6. Setting Up the Whining Cron Job (Optional)

Просмотреть файл

@ -21,6 +21,8 @@
use diagnostics;
use strict;
quietly_check_login();
my $query = "
select
bug_id,
@ -40,9 +42,11 @@ select
target_milestone,
qa_contact,
status_whiteboard,
date_format(creation_ts,'Y-m-d')
date_format(creation_ts,'Y-m-d'),
groupset
from bugs
where bug_id = $::FORM{'id'}";
where bug_id = $::FORM{'id'}
and bugs.groupset & $::usergroupset = bugs.groupset";
SendSQL($query);
my %bug;
@ -53,7 +57,8 @@ if (@row = FetchSQLData()) {
"op_sys", "bug_status", "resolution", "priority",
"bug_severity", "component", "assigned_to", "reporter",
"bug_file_loc", "short_desc", "target_milestone",
"qa_contact", "status_whiteboard", "creation_ts") {
"qa_contact", "status_whiteboard", "creation_ts",
"groupset") {
$bug{$field} = shift @row;
if (!defined $bug{$field}) {
$bug{$field} = "";
@ -212,11 +217,28 @@ print "
<br>
<B>Additional Comments:</B>
<BR>
<TEXTAREA WRAP=HARD NAME=comment ROWS=5 COLS=80></TEXTAREA><BR>
<br>
<TEXTAREA WRAP=HARD NAME=comment ROWS=5 COLS=80></TEXTAREA><BR>";
if ($::usergroupset ne '0') {
SendSQL("select bit, description, (bit & $bug{'groupset'} != 0) from groups where bit & $::usergroupset != 0 and isbuggroup != 0 order by bit");
while (MoreSQLData()) {
my ($bit, $description, $ison) = (FetchSQLData());
my $check0 = !$ison ? " SELECTED" : "";
my $check1 = $ison ? " SELECTED" : "";
print "<select name=bit-$bit><option value=0$check0>\n";
print "People not in the \"$description\" group can see this bug\n";
print "<option value=1$check1>\n";
print "Only people in the \"$description\" group can see this bug\n";
print "</select><br>\n";
}
}
print "<br>
<INPUT TYPE=radio NAME=knob VALUE=none CHECKED>
Leave as <b>$bug{'bug_status'} $bug{'resolution'}</b><br>";
# knum is which knob number we're generating, in javascript terms.
my $knum = 1;

Просмотреть файл

@ -177,12 +177,14 @@ my $dotweak = defined $::FORM{'tweak'};
if ($dotweak) {
confirm_login();
} else {
quietly_check_login();
}
print "Content-type: text/html\n\n";
my $query = "select bugs.bug_id";
my $query = "select bugs.bug_id, bugs.groupset";
foreach my $c (@collist) {
@ -210,6 +212,7 @@ where bugs.assigned_to = assign.userid
and bugs.reporter = report.userid
and bugs.product = projector.program
and bugs.version = projector.value
and bugs.groupset & $::usergroupset = bugs.groupset
";
if ((defined $::FORM{'emailcc1'} && $::FORM{'emailcc1'}) ||
@ -439,9 +442,19 @@ my %seen;
my @bugarray;
my %prodhash;
my %statushash;
my $buggroupset = "";
while (@row = FetchSQLData()) {
my $bug_id = shift @row;
my $g = shift @row; # Bug's group set.
if ($buggroupset eq "") {
$buggroupset = $g;
} elsif ($buggroupset ne $g) {
$buggroupset = "x"; # We only play games with tweaking the
# buggroupset if all the bugs have exactly
# the same group. If they don't, we leave
# it alone.
}
if (!defined $seen{$bug_id}) {
$seen{$bug_id} = 1;
$count++;
@ -627,6 +640,23 @@ document.write(\" <input type=button value=\\\"Uncheck All\\\" onclick=\\\"SetCh
<BR>
<TEXTAREA WRAP=HARD NAME=comment ROWS=5 COLS=80></TEXTAREA><BR>";
if ($::usergroupset ne '0' && $buggroupset =~ /^\d*$/) {
SendSQL("select bit, description, (bit & $buggroupset != 0) from groups where bit & $::usergroupset != 0 and isbuggroup != 0 order by bit");
while (MoreSQLData()) {
my ($bit, $description, $ison) = (FetchSQLData());
my $check0 = !$ison ? " SELECTED" : "";
my $check1 = $ison ? " SELECTED" : "";
print "<select name=bit-$bit><option value=0$check0>\n";
print "People not in the \"$description\" group can see these bugs\n";
print "<option value=1$check1>\n";
print "Only people in the \"$description\" group can see these bugs\n";
print "</select><br>\n";
}
}
# knum is which knob number we're generating, in javascript terms.
my $knum = 0;

Просмотреть файл

@ -90,17 +90,10 @@ sub check_numeric {
# the database tables. The name of the parameter is of the form
# "tablename.columnname".
# This very first one is silly. At some point, "superuserness" should be an
# attribute of the person's profile entry, and not a single name like this.
#
# When first installing bugzilla, you need to either change this line to be
# you, or (better) edit the initial "params" file and change the entry for
# param(maintainer).
DefParam("maintainer",
"The email address of the person who maintains this installation of Bugzilla.",
"t",
'terry@mozilla.org');
'THE MAINTAINER HAS NOT YET BEEN SET');
DefParam("urlbase",
"The URL that is the common initial leading part of all Bugzilla URLs.",

Просмотреть файл

@ -24,17 +24,13 @@ use strict;
require "CGI.pl";
# Shut up misguided -w warnings about "used only once":
use vars %::COOKIE;
confirm_login();
print "Content-type: text/html\n\n";
if (Param("maintainer") ne $::COOKIE{'Bugzilla_login'}) {
print "<H1>Sorry, you aren't the maintainer of this system.</H1>\n";
print "And so, you aren't allowed to edit the parameters of it.\n";
if (!UserInGroup("editcomponents")) {
print "<H1>Sorry, you aren't a member of the 'editcomponents' group.</H1>\n";
print "And so, you aren't allowed to edit the owners.\n";
exit;
}

Просмотреть файл

@ -28,17 +28,16 @@ require "defparams.pl";
# Shut up misguided -w warnings about "used only once":
use vars %::param,
%::param_default,
@::param_list,
%::COOKIE;
@::param_list;
confirm_login();
print "Content-type: text/html\n\n";
if (Param("maintainer") ne $::COOKIE{'Bugzilla_login'}) {
print "<H1>Sorry, you aren't the maintainer of this system.</H1>\n";
print "And so, you aren't allowed to edit the parameters of it.\n";
if (!UserInGroup("tweakparams")) {
print "<H1>Sorry, you aren't a member of the 'tweakparams' group.</H1>\n";
print "And so, you aren't allowed to edit the parameters.\n";
exit;
}

Просмотреть файл

@ -26,16 +26,13 @@ use strict;
require "CGI.pl";
# Shut up misguided -w warnings about "used only once":
use vars %::COOKIE;
confirm_login();
print "Content-type: text/html\n\n";
if (Param("maintainer") ne $::COOKIE{Bugzilla_login}) {
print "<H1>Sorry, you aren't the maintainer of this system.</H1>\n";
print "And so, you aren't allowed to edit the parameters of it.\n";
if (!UserInGroup("editcomponents")) {
print "<H1>Sorry, you aren't a member of the 'editcomponents' group.</H1>\n";
print "And so, you aren't allowed to edit the owners.\n";
exit;
}

Просмотреть файл

@ -28,16 +28,15 @@ require "defparams.pl";
# Shut up misguided -w warnings about "used only once":
use vars @::param_desc,
@::param_list,
%::COOKIE;
@::param_list;
confirm_login();
print "Content-type: text/html\n\n";
if (Param("maintainer") ne $::COOKIE{Bugzilla_login}) {
print "<H1>Sorry, you aren't the maintainer of this system.</H1>\n";
print "And so, you aren't allowed to edit the parameters of it.\n";
if (!UserInGroup("tweakparams")) {
print "<H1>Sorry, you aren't a member of the 'tweakparams' group.</H1>\n";
print "And so, you aren't allowed to edit the parameters.\n";
exit;
}

Просмотреть файл

@ -356,7 +356,19 @@ sub InsertNewUser {
for (my $i=0 ; $i<8 ; $i++) {
$password .= substr("abcdefghijklmnopqrstuvwxyz", int(rand(26)), 1);
}
SendSQL("insert into profiles (login_name, password, cryptpassword) values (@{[SqlQuote($username)]}, '$password', encrypt('$password'))");
SendSQL("select bit, userregexp from groups where userregexp != ''");
my $groupset = "0";
while (MoreSQLData()) {
my @row = FetchSQLData();
if ($username =~ m/$row[1]/) {
$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
# does that.
}
}
SendSQL("insert into profiles (login_name, password, cryptpassword, groupset) values (@{[SqlQuote($username)]}, '$password', encrypt('$password'), $groupset)");
return $password;
}
@ -484,6 +496,21 @@ sub SqlQuote {
sub UserInGroup {
my ($groupname) = (@_);
if ($::usergroupset eq "0") {
return 0;
}
ConnectToDatabase();
SendSQL("select (bit & $::usergroupset) != 0 from groups where name = " . SqlQuote($groupname));
my $bit = FetchOneColumn();
if ($bit) {
return 1;
}
return 0;
}
sub Param {
my ($value) = (@_);
if (defined $::param{$value}) {

Просмотреть файл

@ -31,6 +31,9 @@ use vars %::FORM;
print "Content-type: text/html\n\n";
print "<TITLE>Full Text Bug Listing</TITLE>\n";
ConnectToDatabase();
quietly_check_login();
my $generic_query = "
select
bugs.bug_id,
@ -52,9 +55,7 @@ select
bugs.status_whiteboard
from bugs,profiles assign,profiles report
where assign.userid = bugs.assigned_to and report.userid = bugs.reporter and
";
ConnectToDatabase();
bugs.groupset & $::usergroupset = bugs.groupset and";
foreach my $bug (split(/:/, $::FORM{'buglist'})) {
SendSQL("$generic_query bugs.bug_id = $bug");

Просмотреть файл

@ -29,6 +29,7 @@ mysql << OK_ALL_DONE
use bugs;
create table bugs (
bug_id mediumint not null auto_increment primary key,
groupset bigint not null,
assigned_to mediumint not null, # This is a comment.
bug_file_loc text,
bug_severity enum("critical", "major", "normal", "minor", "trivial", "enhancement") not null,

Просмотреть файл

@ -0,0 +1,69 @@
#!/bin/sh
#
# The contents of this file are subject to the Mozilla Public License
# Version 1.0 (the "License"); you may not use this file except in
# compliance with the License. You may obtain a copy of the License at
# http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
# License for the specific language governing rights and limitations
# under the License.
#
# The Original Code is the Bugzilla Bug Tracking System.
#
# The Initial Developer of the Original Code is Netscape Communications
# Corporation. Portions created by Netscape are Copyright (C) 1998
# Netscape Communications Corporation. All Rights Reserved.
#
# Contributor(s): Terry Weissman <terry@mozilla.org>
mysql > /dev/null 2>/dev/null << OK_ALL_DONE
use bugs;
drop table groups
OK_ALL_DONE
mysql << OK_ALL_DONE
use bugs;
create table groups (
# This must be a power of two. Groups are identified by a bit; sets of
# groups are indicated by or-ing these values together.
bit bigint not null,
name varchar(255) not null,
description text not null,
# isbuggroup is nonzero if this is a group that controls access to a set
# of bugs. In otherword, the groupset field in the bugs table should only
# have this group's bit set if isbuggroup is nonzero.
isbuggroup tinyint not null,
# User regexp is which email addresses are initially put into this group.
# This is only used when an email account is created; otherwise, profiles
# may be individually tweaked to add them in and out of groups.
userregexp tinytext not null,
unique(bit),
unique(name)
);
insert into groups (bit, name, description, userregexp) values (pow(2,0), "tweakparams", "Can tweak operating parameters", "");
insert into groups (bit, name, description, userregexp) values (pow(2,1), "editgroupmembers", "Can put people in and out of groups that they are members of.", "");
insert into groups (bit, name, description, userregexp) values (pow(2,2), "creategroups", "Can create and destroy groups.", "");
insert into groups (bit, name, description, userregexp) values (pow(2,3), "editcomponents", "Can create, destroy, and edit components.", "");
show columns from groups;
show index from groups;
# Check for bad bit values.
select "*** Bad bit value", bit from groups where bit != pow(2, round(log(bit) / log(2)));
OK_ALL_DONE

Просмотреть файл

@ -33,6 +33,7 @@ login_name varchar(255) not null,
password varchar(16),
cryptpassword varchar(64),
realname varchar(255),
groupset bigint not null,
index(login_name)
);

Просмотреть файл

@ -120,6 +120,22 @@ sub ChangeResolution {
}
my $foundbit = 0;
foreach my $b (grep(/^bit-\d*$/, keys %::FORM)) {
if (!$foundbit) {
$foundbit = 1;
DoComma();
$::query .= "groupset = 0";
}
if ($::FORM{$b}) {
my $v = substr($b, 4);
$::query .= "+ $v"; # Carefully written so that the math is
# done by MySQL, which can handle 64-bit math,
# and not by Perl, which I *think* can not.
}
}
foreach my $field ("rep_platform", "priority", "bug_severity", "url",
"summary", "component", "bug_file_loc", "short_desc",
"product", "version", "component", "op_sys",

Просмотреть файл

@ -377,17 +377,17 @@ print "
";
quietly_check_login();
if (UserInGroup("tweakparams")) {
print "<a href=editparams.cgi>Edit Bugzilla operating parameters</a><br>\n";
}
if (UserInGroup("editcomponents")) {
print "<a href=editowners.cgi>Edit Bugzilla component owners</a><br>\n";
}
if (defined $::COOKIE{"Bugzilla_login"}) {
if ($::COOKIE{"Bugzilla_login"} eq Param("maintainer")) {
print "<a href=editparams.cgi>Edit Bugzilla operating parameters</a><br>\n";
print "<a href=editowners.cgi>Edit Bugzilla component owners</a><br>\n";
}
print "<a href=relogin.cgi>Log in as someone besides <b>$::COOKIE{'Bugzilla_login'}</b></a><br>\n";
}
print "<a href=changepassword.cgi>Change your password.</a><br>\n";
print "<a href=\"enter_bug.cgi\">Create a new bug.</a><br>\n";
print "<a href=\"reports.cgi\">Bug reports</a><br>\n";

Просмотреть файл

@ -53,6 +53,22 @@ print "OK, now running sanity checks.<P>\n";
my @row;
my @checklist;
Status("Checking groups");
SendSQL("select bit from groups where bit != pow(2, round(log(bit) / log(2)))");
while (my $bit = FetchOneColumn()) {
Alert("Illegal bit number found in group table: $bit");
}
SendSQL("select sum(bit) from groups where isbuggroup != 0");
my $buggroupset = FetchOneColumn();
SendSQL("select bug_id, groupset from bugs where groupset & $buggroupset != groupset");
while (@row = FetchSQLData()) {
Alert("Bad groupset $row[1] found in bug " . BugLink($row[0]));
}
Status("Checking version/products");
SendSQL("select distinct product, version from bugs");