summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Bugzilla/Search.pm68
-rw-r--r--Bugzilla/User.pm14
-rwxr-xr-xeditgroups.cgi4
-rw-r--r--template/en/default/admin/groups/edit.html.tmpl24
-rw-r--r--template/en/default/global/user-error.html.tmpl4
5 files changed, 101 insertions, 13 deletions
diff --git a/Bugzilla/Search.pm b/Bugzilla/Search.pm
index 6cff2940e..91785963f 100644
--- a/Bugzilla/Search.pm
+++ b/Bugzilla/Search.pm
@@ -36,6 +36,7 @@ package Bugzilla::Search;
use Bugzilla::Config;
use Bugzilla::Error;
use Bugzilla::Util;
+use Bugzilla::Constants;
use Date::Format;
use Date::Parse;
@@ -330,6 +331,26 @@ sub init {
my %funcsbykey;
my @funcdefs =
(
+ "^(?:assigned_to|reporter|qa_contact),(?:notequals|equals|anyexact),%group\\.(\\w+)%" => sub {
+ my $group = $1;
+ my $groupid = ValidateGroupName( $group, ($user));
+ $groupid || ThrowUserError('invalid_group_name',{name => $group});
+ my @childgroups = @{$user->flatten_group_membership($groupid)};
+ my $table = "user_group_map_$chartid";
+ push (@supptables, "LEFT JOIN user_group_map $table " .
+ "ON $table.user_id = bugs.$f " .
+ "AND $table.group_id IN(" .
+ join(',', @childgroups) . ") " .
+ "AND $table.isbless = 0 " .
+ "AND $table.grant_type IN(" .
+ GRANT_DIRECT . "," . GRANT_REGEXP . ")"
+ );
+ if ($t =~ /^not/) {
+ $term = "$table.group_id IS NULL";
+ } else {
+ $term = "$table.group_id IS NOT NULL";
+ }
+ },
"^(?:assigned_to|reporter|qa_contact),(?:equals|anyexact),(%\\w+%)" => sub {
$term = "bugs.$f = " . pronoun($1, $user);
},
@@ -347,6 +368,34 @@ sub init {
$f = "COALESCE(map_$f.login_name,'')";
},
+ "^(?:cc),(?:notequals|equals|anyexact),%group\\.(\\w+)%" => sub {
+ my $group = $1;
+ my $groupid = ValidateGroupName( $group, ($user));
+ $groupid || ThrowUserError('invalid_group_name',{name => $group});
+ my @childgroups = @{$user->flatten_group_membership($groupid)};
+ my $chartseq = $chartid;
+ if ($chartid eq "") {
+ $chartseq = "CC$sequence";
+ $sequence++;
+ }
+ my $table = "user_group_map_$chartseq";
+ push(@supptables, "LEFT JOIN cc cc_$chartseq " .
+ "ON bugs.bug_id = cc_$chartseq.bug_id");
+ push(@supptables, "LEFT JOIN user_group_map $table " .
+ "ON $table.user_id = cc_$chartseq.who " .
+ "AND $table.group_id IN(" .
+ join(',', @childgroups) . ") " .
+ "AND $table.isbless = 0 " .
+ "AND $table.grant_type IN(" .
+ GRANT_DIRECT . "," . GRANT_REGEXP . ")"
+ );
+ if ($t =~ /^not/) {
+ $term = "$table.group_id IS NULL";
+ } else {
+ $term = "$table.group_id IS NOT NULL";
+ }
+ },
+
"^cc,(?:equals|anyexact),(%\\w+%)" => sub {
my $match = pronoun($1, $user);
my $chartseq = $chartid;
@@ -1355,4 +1404,23 @@ sub pronoun {
}
return 0;
}
+
+# ValidateGroupName checks to see if ANY of the users in the provided list
+# of user objects can see the named group. It returns the group id if
+# successful and undef otherwise.
+sub ValidateGroupName {
+ my ($name, @users) = (@_);
+ my @visible = (-1);
+ foreach my $user (@users) {
+ $user && push @visible, @{$user->visible_groups_direct};
+ }
+ my $visible = join(', ', @visible);
+ my $dbh = Bugzilla->dbh;
+ my $sth = $dbh->prepare("SELECT id FROM groups " .
+ "WHERE name = ? AND id IN($visible)");
+ $sth->execute($name);
+ my ($ret) = $sth->fetchrow_array();
+ return $ret;
+}
+
1;
diff --git a/Bugzilla/User.pm b/Bugzilla/User.pm
index 38453841b..21585b3a4 100644
--- a/Bugzilla/User.pm
+++ b/Bugzilla/User.pm
@@ -340,7 +340,7 @@ sub visible_groups_inherited {
return $self->{visible_groups_inherited} if defined $self->{visible_groups_inherited};
return [] unless $self->id;
my @visgroups = @{$self->visible_groups_direct};
- @visgroups = flatten_group_membership(@visgroups);
+ @visgroups = @{$self->flatten_group_membership(@visgroups)};
$self->{visible_groups_inherited} = \@visgroups;
return $self->{visible_groups_inherited};
}
@@ -489,7 +489,7 @@ sub can_bless {
}
sub flatten_group_membership {
- my (@groups) = @_;
+ my ($self, @groups) = @_;
my $dbh = Bugzilla->dbh;
my $sth;
@@ -509,7 +509,7 @@ sub flatten_group_membership {
}
}
}
- return @groups;
+ return \@groups;
}
sub match {
@@ -1092,6 +1092,14 @@ Returns a reference to an array of users. The array is populated with hashrefs
containing the login, identity and visibility. Users that are not visible to this
user will have 'visible' set to zero.
+=item C<flatten_group_membership>
+
+Accepts a list of groups and returns a list of all the groups whose members
+inherit membership in any group on the list. So, we can determine if a user
+is in any of the groups input to flatten_group_membership by querying the
+user_group_map for any user with DIRECT or REGEXP membership IN() the list
+of groups returned.
+
=item C<visible_groups_inherited>
Returns a list of all groups whose members should be visible to this user.
diff --git a/editgroups.cgi b/editgroups.cgi
index 981fec48a..b3b6135e4 100755
--- a/editgroups.cgi
+++ b/editgroups.cgi
@@ -153,7 +153,7 @@ if ($action eq 'changeform') {
" ON C.member_id = groups.id" .
" AND C.grantor_id = $group_id" .
" AND C.grant_type = " . GROUP_VISIBLE .
- " WHERE groups.id != $group_id ORDER by name");
+ " ORDER by name");
while (MoreSQLData()) {
my ($grpid, $grpnam, $grpdesc, $grpmember, $blessmember, $membercansee)
@@ -531,7 +531,7 @@ sub doGroupChanges {
$b =~ /^oldgrp-(\d+)$/;
my $v = $1;
my $grp = $cgi->param("grp-$v") || 0;
- if ($cgi->param("oldgrp-$v") != $grp) {
+ if (($cgi->param("oldgrp-$v") != $grp) && ($v != $gid)) {
$chgs = 1;
if ($grp != 0) {
SendSQL("INSERT INTO group_group_map
diff --git a/template/en/default/admin/groups/edit.html.tmpl b/template/en/default/admin/groups/edit.html.tmpl
index bdda7e27b..d6044ad0f 100644
--- a/template/en/default/admin/groups/edit.html.tmpl
+++ b/template/en/default/admin/groups/edit.html.tmpl
@@ -143,14 +143,22 @@
value="[% group.membercansee FILTER none %]">
</td>
[% END %]
- <td align="center">
- <input type="checkbox" name="bless-[% group.grpid FILTER html %]" [% group.blessmember ? "checked " : "" %]value="1">
- <input type="hidden" name="oldbless-[% group.grpid FILTER html %]" value="[% group.blessmember FILTER html %]">
- </td>
- <td align="center">
- <input type="checkbox" name="grp-[% group.grpid FILTER html %]" [% group.grpmember ? "checked " : "" %]value="1">
- <input type="hidden" name="oldgrp-[% group.grpid FILTER html %]" value="[% group.grpmember FILTER html %]">
- </td>
+ [% IF group_id != group.grpid %]
+ <td align="center">
+ <input type="checkbox" name="bless-[% group.grpid FILTER html %]" [% group.blessmember ? "checked " : "" %]value="1">
+ <input type="hidden" name="oldbless-[% group.grpid FILTER html %]" value="[% group.blessmember FILTER html %]">
+ </td>
+ <td align="center">
+ <input type="checkbox" name="grp-[% group.grpid FILTER html %]" [% group.grpmember ? "checked " : "" %]value="1">
+ <input type="hidden" name="oldgrp-[% group.grpid FILTER html %]" value="[% group.grpmember FILTER html %]">
+ </td>
+ [% ELSE %]
+ <td>
+ </td>
+ <td>
+ <input type="hidden" name="oldgrp-[% group.grpid FILTER html %]" value="">
+ </td>
+ [% END %]
<td align="left" class="groupname">
<a href="[% "editgroups.cgi?action=changeform&group=${group.grpid}" FILTER html %]">
[% group.grpnam FILTER html %]
diff --git a/template/en/default/global/user-error.html.tmpl b/template/en/default/global/user-error.html.tmpl
index 964832db6..a17b1275b 100644
--- a/template/en/default/global/user-error.html.tmpl
+++ b/template/en/default/global/user-error.html.tmpl
@@ -459,6 +459,10 @@
[% title = "Invalid group ID" %]
The group you specified doesn't exist.
+ [% ELSIF error == "invalid_group_name" %]
+ [% title = "Invalid group name" %]
+ The group you specified, [% name FILTER html %], is not valid here.
+
[% ELSIF error == "invalid_maxrows" %]
[% title = "Invalid Max Rows" %]
The maximum number of rows, '[% maxrows FILTER html %]', must be