зеркало из https://github.com/mozilla/gecko-dev.git
Patch for bug 180879: Implement privs for bug flags modification; patch by Fr�d�ric Buclin <LpSolit@netscape.net>, r=joel, a=justdave.
This commit is contained in:
Родитель
16735ddc71
Коммит
0ecd04b79e
|
@ -139,6 +139,7 @@ sub count {
|
|||
sub validate {
|
||||
# Validates fields containing flag modifications.
|
||||
|
||||
my $user = Bugzilla->user;
|
||||
my ($data, $bug_id) = @_;
|
||||
|
||||
# Get a list of flags to validate. Uses the "map" function
|
||||
|
@ -213,6 +214,24 @@ sub validate {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Make sure the user is authorized to modify flags, see bug 180879
|
||||
# - The flag is unchanged
|
||||
next if ($status eq $flag->{status});
|
||||
|
||||
# - User can clear flags set by itself
|
||||
next if (($status eq "X") && ($user->id eq $flag->{setter}));
|
||||
|
||||
# - User in the $grant_gid group can set/clear flags,
|
||||
# including "+" and "-"
|
||||
next if (!$flag->{type}->{grant_gid}
|
||||
|| $user->in_group(&::GroupIdToName($flag->{type}->{grant_gid})));
|
||||
|
||||
# - Any other flag modification is denied
|
||||
ThrowUserError("flag_update_denied",
|
||||
{ name => $flag->{type}->{name},
|
||||
status => $status,
|
||||
old_status => $flag->{status} });
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -49,7 +49,8 @@ my @base_columns =
|
|||
("1", "flagtypes.id", "flagtypes.name", "flagtypes.description",
|
||||
"flagtypes.cc_list", "flagtypes.target_type", "flagtypes.sortkey",
|
||||
"flagtypes.is_active", "flagtypes.is_requestable",
|
||||
"flagtypes.is_requesteeble", "flagtypes.is_multiplicable");
|
||||
"flagtypes.is_requesteeble", "flagtypes.is_multiplicable",
|
||||
"flagtypes.grant_group_id", "flagtypes.request_group_id");
|
||||
|
||||
# Note: when adding tables to @base_tables, make sure to include the separator
|
||||
# (i.e. a comma or words like "LEFT OUTER JOIN") before the table name,
|
||||
|
@ -181,6 +182,7 @@ sub count {
|
|||
}
|
||||
|
||||
sub validate {
|
||||
my $user = Bugzilla->user;
|
||||
my ($data, $bug_id, $attach_id) = @_;
|
||||
|
||||
# Get a list of flag types to validate. Uses the "map" function
|
||||
|
@ -249,6 +251,22 @@ sub validate {
|
|||
attach_id => $attach_id });
|
||||
}
|
||||
}
|
||||
|
||||
# Make sure the user is authorized to modify flags, see bug 180879
|
||||
# - User in the $grant_gid group can set flags, including "+" and "-"
|
||||
next if (!$flag_type->{grant_gid}
|
||||
|| $user->in_group(&::GroupIdToName($flag_type->{grant_gid})));
|
||||
|
||||
# - User in the $request_gid group can request flags
|
||||
next if ($status eq '?'
|
||||
&& (!$flag_type->{request_gid}
|
||||
|| $user->in_group(&::GroupIdToName($flag_type->{request_gid}))));
|
||||
|
||||
# - Any other flag modification is denied
|
||||
ThrowUserError("flag_update_denied",
|
||||
{ name => $flag_type->{name},
|
||||
status => $status,
|
||||
old_status => "X" });
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -348,6 +366,12 @@ sub sqlify_criteria {
|
|||
push(@$columns, "COUNT(flagexclusions.type_id) AS num_exclusions");
|
||||
$$having = "num_exclusions = 0";
|
||||
}
|
||||
if ($criteria->{group}) {
|
||||
my $gid = $criteria->{group};
|
||||
detaint_natural($gid);
|
||||
push(@criteria, "(flagtypes.grant_group_id = $gid " .
|
||||
" OR flagtypes.request_group_id = $gid)");
|
||||
}
|
||||
|
||||
return @criteria;
|
||||
}
|
||||
|
@ -368,7 +392,9 @@ sub perlify_record {
|
|||
$type->{'is_requestable'} = $_[8];
|
||||
$type->{'is_requesteeble'} = $_[9];
|
||||
$type->{'is_multiplicable'} = $_[10];
|
||||
$type->{'flag_count'} = $_[11];
|
||||
$type->{'grant_gid'} = $_[11];
|
||||
$type->{'request_gid'} = $_[12];
|
||||
$type->{'flag_count'} = $_[13];
|
||||
|
||||
return $type;
|
||||
}
|
||||
|
|
|
@ -1685,7 +1685,9 @@ $table{flagtypes} =
|
|||
is_requesteeble TINYINT NOT NULL DEFAULT 0 ,
|
||||
is_multiplicable TINYINT NOT NULL DEFAULT 0 ,
|
||||
|
||||
sortkey SMALLINT NOT NULL DEFAULT 0
|
||||
sortkey SMALLINT NOT NULL DEFAULT 0 ,
|
||||
grant_group_id MEDIUMINT NULL ,
|
||||
request_group_id MEDIUMINT NULL
|
||||
';
|
||||
|
||||
$table{flaginclusions} =
|
||||
|
@ -4124,6 +4126,11 @@ if (GetFieldDef("group_group_map", "isbless")) {
|
|||
# login data source
|
||||
AddField("profiles", "extern_id", "varchar(64)");
|
||||
|
||||
# 2004-11-20 - LpSolit@netscape.net - Bug 180879
|
||||
# Add grant and request groups for flags
|
||||
AddField('flagtypes', 'grant_group_id', 'mediumint null');
|
||||
AddField('flagtypes', 'request_group_id', 'mediumint null');
|
||||
|
||||
# If you had to change the --TABLE-- definition in any way, then add your
|
||||
# differential change code *** A B O V E *** this comment.
|
||||
#
|
||||
|
|
|
@ -90,9 +90,12 @@ exit;
|
|||
|
||||
sub list {
|
||||
# Define the variables and functions that will be passed to the UI template.
|
||||
$vars->{'bug_types'} = Bugzilla::FlagType::match({ 'target_type' => 'bug' }, 1);
|
||||
$vars->{'bug_types'} =
|
||||
Bugzilla::FlagType::match({ 'target_type' => 'bug',
|
||||
'group' => $::FORM{'group'} }, 1);
|
||||
$vars->{'attachment_types'} =
|
||||
Bugzilla::FlagType::match({ 'target_type' => 'attachment' }, 1);
|
||||
Bugzilla::FlagType::match({ 'target_type' => 'attachment',
|
||||
'group' => $::FORM{'group'} }, 1);
|
||||
|
||||
# Return the appropriate HTTP response headers.
|
||||
print Bugzilla->cgi->header();
|
||||
|
@ -129,6 +132,13 @@ sub edit {
|
|||
$vars->{'type'} = Bugzilla::FlagType::get($::FORM{'id'});
|
||||
$vars->{'type'}->{'inclusions'} = Bugzilla::FlagType::get_inclusions($::FORM{'id'});
|
||||
$vars->{'type'}->{'exclusions'} = Bugzilla::FlagType::get_exclusions($::FORM{'id'});
|
||||
# Users want to see group names, not IDs
|
||||
foreach my $group ("grant_gid", "request_gid") {
|
||||
my $gid = $vars->{'type'}->{$group};
|
||||
next if (!$gid);
|
||||
SendSQL("SELECT name FROM groups WHERE id = $gid");
|
||||
$vars->{'type'}->{$group} = FetchOneColumn();
|
||||
}
|
||||
}
|
||||
# Otherwise set the target type (the minimal information about the type
|
||||
# that the template needs to know) from the URL parameter and default
|
||||
|
@ -208,6 +218,7 @@ sub insert {
|
|||
validateIsRequestable();
|
||||
validateIsRequesteeble();
|
||||
validateAllowMultiple();
|
||||
validateGroups();
|
||||
|
||||
my $name = SqlQuote($::FORM{'name'});
|
||||
my $description = SqlQuote($::FORM{'description'});
|
||||
|
@ -224,11 +235,13 @@ sub insert {
|
|||
# Insert a record for the new flag type into the database.
|
||||
SendSQL("INSERT INTO flagtypes (id, name, description, cc_list,
|
||||
target_type, sortkey, is_active, is_requestable,
|
||||
is_requesteeble, is_multiplicable)
|
||||
is_requesteeble, is_multiplicable,
|
||||
grant_group_id, request_group_id)
|
||||
VALUES ($id, $name, $description, $cc_list, '$target_type',
|
||||
$::FORM{'sortkey'}, $::FORM{'is_active'},
|
||||
$::FORM{'is_requestable'}, $::FORM{'is_requesteeble'},
|
||||
$::FORM{'is_multiplicable'})");
|
||||
$::FORM{'is_multiplicable'}, $::FORM{'grant_gid'},
|
||||
$::FORM{'request_gid'})");
|
||||
|
||||
# Populate the list of inclusions/exclusions for this flag type.
|
||||
foreach my $category_type ("inclusions", "exclusions") {
|
||||
|
@ -267,6 +280,7 @@ sub update {
|
|||
validateIsRequestable();
|
||||
validateIsRequesteeble();
|
||||
validateAllowMultiple();
|
||||
validateGroups();
|
||||
|
||||
my $name = SqlQuote($::FORM{'name'});
|
||||
my $description = SqlQuote($::FORM{'description'});
|
||||
|
@ -282,7 +296,9 @@ sub update {
|
|||
is_active = $::FORM{'is_active'} ,
|
||||
is_requestable = $::FORM{'is_requestable'} ,
|
||||
is_requesteeble = $::FORM{'is_requesteeble'} ,
|
||||
is_multiplicable = $::FORM{'is_multiplicable'}
|
||||
is_multiplicable = $::FORM{'is_multiplicable'} ,
|
||||
grant_group_id = $::FORM{'grant_gid'} ,
|
||||
request_group_id = $::FORM{'request_gid'}
|
||||
WHERE id = $::FORM{'id'}");
|
||||
|
||||
# Update the list of inclusions/exclusions for this flag type.
|
||||
|
@ -499,3 +515,16 @@ sub validateAllowMultiple {
|
|||
$::FORM{'is_multiplicable'} = $::FORM{'is_multiplicable'} ? 1 : 0;
|
||||
}
|
||||
|
||||
sub validateGroups {
|
||||
# Convert group names to group IDs
|
||||
foreach my $col ("grant_gid", "request_gid") {
|
||||
my $name = $::FORM{$col};
|
||||
$::FORM{$col} ||= "NULL";
|
||||
next if (!$name);
|
||||
SendSQL("SELECT id FROM groups WHERE name = " . SqlQuote($name));
|
||||
$::FORM{$col} = FetchOneColumn();
|
||||
if (!$::FORM{$col}) {
|
||||
ThrowUserError("group_unknown", { name => $name });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -317,12 +317,20 @@ if ($action eq 'del') {
|
|||
$hasproduct = 1;
|
||||
}
|
||||
|
||||
my $hasflags = 0;
|
||||
SendSQL("SELECT id FROM flagtypes
|
||||
WHERE grant_group_id = $gid OR request_group_id = $gid");
|
||||
if (FetchOneColumn()) {
|
||||
$hasflags = 1;
|
||||
}
|
||||
|
||||
$vars->{'gid'} = $gid;
|
||||
$vars->{'name'} = $name;
|
||||
$vars->{'description'} = $desc;
|
||||
$vars->{'hasusers'} = $hasusers;
|
||||
$vars->{'hasbugs'} = $hasbugs;
|
||||
$vars->{'hasproduct'} = $hasproduct;
|
||||
$vars->{'hasflags'} = $hasflags;
|
||||
$vars->{'buglist'} = $buglist;
|
||||
|
||||
print Bugzilla->cgi->header();
|
||||
|
@ -365,8 +373,19 @@ if ($action eq 'delete') {
|
|||
$cantdelete = 1;
|
||||
}
|
||||
}
|
||||
SendSQL("SELECT id FROM flagtypes
|
||||
WHERE grant_group_id = $gid OR request_group_id = $gid");
|
||||
if (FetchOneColumn()) {
|
||||
if (!defined $cgi->param('removeflags')) {
|
||||
$cantdelete = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$cantdelete) {
|
||||
SendSQL("UPDATE flagtypes SET grant_group_id = NULL
|
||||
WHERE grant_group_id = $gid");
|
||||
SendSQL("UPDATE flagtypes SET request_group_id = NULL
|
||||
WHERE request_group_id = $gid");
|
||||
SendSQL("DELETE FROM user_group_map WHERE group_id = $gid");
|
||||
SendSQL("DELETE FROM group_group_map WHERE grantor_id = $gid");
|
||||
SendSQL("DELETE FROM bug_group_map WHERE group_id = $gid");
|
||||
|
|
|
@ -187,6 +187,25 @@
|
|||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th>Grant Group:</th>
|
||||
<td>
|
||||
the group allowed to grant/deny flags of this type
|
||||
(to allow all users to grant/deny these flags, leave this empty)<br>
|
||||
<input type="text" name="grant_gid" value="[% type.grant_gid FILTER html %]" size="50" maxlength="255">
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th>Request Group:</th>
|
||||
<td>
|
||||
if flags of this type are requestable, the group allowed to request them
|
||||
(to allow all users to request these flags, leave this empty)<br>
|
||||
Note that the request group alone has no effect if the grant group is not defined!<br>
|
||||
<input type="text" name="request_gid" value="[% type.request_gid FILTER html %]" size="50" maxlength="255">
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th></th>
|
||||
<td>
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
# hasusers: boolean int. True if the group includes users in it.
|
||||
# hasbugs: boolean int. True if the group includes bugs in it.
|
||||
# hasproduct: boolean int. True if the group is binded to a product.
|
||||
# hasflags: boolean int. True if the group is used by a flag type.
|
||||
# buglist: string. The list of bugs included in this group.
|
||||
#%]
|
||||
|
||||
|
@ -81,11 +82,20 @@
|
|||
<br><input type="checkbox" name="unbind">Delete this group anyway,
|
||||
and make the <U>[% name FILTER html %]</U> publicly visible.</p>
|
||||
[% END %]
|
||||
|
||||
[% IF hasflags %]
|
||||
<p><b>This group restricts who can make changes to flags of certain types.
|
||||
You cannot delete this group while there are flag types using it.</b>
|
||||
|
||||
<br><a href="editflagtypes.cgi?action=list&group=[% gid FILTER html %]">Show
|
||||
me which types</a> - <input type="checkbox" name="removeflags">Remove all
|
||||
flag types from this group for me.</p>
|
||||
[% END %]
|
||||
|
||||
<h2>Confirmation</h2>
|
||||
|
||||
<p>Do you really want to delete this group?</p>
|
||||
[% IF (hasusers || hasbugs || hasproduct) %]
|
||||
[% IF (hasusers || hasbugs || hasproduct || hasflags) %]
|
||||
<p><b>You must check all of the above boxes or correct the
|
||||
indicated problems first before you can proceed.</b></p>
|
||||
[% END %]
|
||||
|
|
|
@ -344,6 +344,17 @@
|
|||
[% title = "Flag Type Name Invalid" %]
|
||||
The name <em>[% name FILTER html %]</em> must be 1-50 characters long.
|
||||
|
||||
[% ELSIF error == "flag_update_denied" %]
|
||||
[% title = "Flag Modification Denied" %]
|
||||
You tried to [% IF status == "+" %] grant [% ELSIF status == "-" %] deny
|
||||
[% ELSIF status == "X" %] clear [% ELSE %] request [% END %]
|
||||
<code>[% name FILTER html %]</code>
|
||||
[% IF status == "?" && old_status != "X" %], but this flag is already
|
||||
set[% END %].
|
||||
Only a sufficiently empowered user [% IF status == "X" %] or the user who
|
||||
set <code>[% name FILTER html %][% old_status FILTER html %]</code> in
|
||||
the first place [% END %] can make this change.
|
||||
|
||||
[% ELSIF error == "format_not_found" %]
|
||||
[% title = "Format Not Found" %]
|
||||
The requested format <em>[% format FILTER html %]</em> does not exist with
|
||||
|
@ -362,6 +373,11 @@
|
|||
[% title = "Group not specified" %]
|
||||
No group was specified.
|
||||
|
||||
[% ELSIF error == "group_unknown" %]
|
||||
[% title = "Unknown Group" %]
|
||||
The group [% name FILTER html %] does not exist. Please specify
|
||||
a valid group name. Create it first if necessary!
|
||||
|
||||
[% ELSIF error == "illegal_at_least_x_votes" %]
|
||||
[% title = "Your Search Makes No Sense" %]
|
||||
The <em>At least ___ votes</em> field must be a simple number.
|
||||
|
|
Загрузка…
Ссылка в новой задаче