use Bugzilla::Config;
use Bugzilla::Error;
use Bugzilla::Util;
+use Bugzilla::Constants;
use Date::Format;
use Date::Parse;
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);
},
$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;
}
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;
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};
}
}
sub flatten_group_membership {
- my (@groups) = @_;
+ my ($self, @groups) = @_;
my $dbh = Bugzilla->dbh;
my $sth;
}
}
}
- return @groups;
+ return \@groups;
}
sub match {
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.
" 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)
$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
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 %]