+# XXX: should be generalized
+sub _JoinGroupMembersForGroupRights
+{
+ my $self = shift;
+ my %args = (@_);
+ my $group_members = $self->_JoinGroupMembers( %args );
+ $self->Limit( ALIAS => $args{'ACLAlias'},
+ FIELD => 'PrincipalId',
+ VALUE => "$group_members.GroupId",
+ QUOTEVALUE => 0,
+ );
+}
+
+# XXX: should be generalized
+sub WhoHaveGroupRight
+{
+ my $self = shift;
+ my %args = (
+ Right => undef,
+ Object => undef,
+ IncludeSystemRights => undef,
+ IncludeSuperusers => undef,
+ IncludeSubgroupMembers => 1,
+ EquivObjects => [ ],
+ @_
+ );
+
+ # Find only rows where the right granted is
+ # the one we're looking up or _possibly_ superuser
+ my $acl = $self->_JoinACL( %args );
+
+ my ($check_objects) = ('');
+ my @objects = $self->_GetEquivObjects( %args );
+
+ if ( @objects ) {
+ my @object_clauses;
+ foreach my $obj ( @objects ) {
+ my $type = ref($obj)? ref($obj): $obj;
+ my $id;
+ $id = $obj->id if ref($obj) && UNIVERSAL::can($obj, 'id') && $obj->id;
+
+ my $object_clause = "$acl.ObjectType = '$type'";
+ $object_clause .= " AND $acl.ObjectId = $id" if $id;
+ push @object_clauses, "($object_clause)";
+ }
+
+ $check_objects = join ' OR ', @object_clauses;
+ } else {
+ if( !$args{'IncludeSystemRights'} ) {
+ $check_objects = "($acl.ObjectType != 'RT::System')";
+ }
+ }
+ $self->_AddSubClause( "WhichObject", "($check_objects)" );
+
+ $self->_JoinGroupMembersForGroupRights( %args, ACLAlias => $acl );
+ # Find only members of groups that have the right.
+ $self->Limit( ALIAS => $acl,
+ FIELD => 'PrincipalType',
+ VALUE => 'Group',
+ );
+
+ # no system user
+ $self->Limit( ALIAS => $self->PrincipalsAlias,
+ FIELD => 'id',
+ OPERATOR => '!=',
+ VALUE => $RT::SystemUser->id
+ );
+ return;
+}