+IncludeSystemRights is true by default, rights
+granted on system level are not accouned when option
+is set to false value.
+
+IncludeSuperusers is true by default, SuperUser right
+is not checked if it's set to false value.
+
+=cut
+
+sub RolesWithRight {
+ my $self = shift;
+ my %args = (
+ Right => undef,
+ IncludeSystemRights => 1,
+ IncludeSuperusers => 1,
+ EquivObjects => [],
+ @_
+ );
+ my $right = $args{'Right'};
+
+ my $query =
+ "SELECT DISTINCT PrincipalType FROM ACL"
+ # Only find superuser or rights with the name $right
+ ." WHERE ( RightName = '$right' "
+ # Check SuperUser if we were asked to
+ . ($args{'IncludeSuperusers'}? "OR RightName = 'SuperUser' " : '' )
+ .")"
+ # we need only roles
+ ." AND PrincipalType != 'Group'"
+ ;
+
+ # skip rights granted on system level if we were asked to
+ unless ( $args{'IncludeSystemRights'} ) {
+ $query .= " AND ObjectType != 'RT::System'";
+ }
+
+ my (@object_clauses);
+ foreach my $obj ( @{ $args{'EquivObjects'} } ) {
+ my $type = ref($obj)? ref($obj): $obj;
+ my $id;
+ $id = $obj->id if ref($obj) && UNIVERSAL::can($obj, 'id') && $obj->id;
+
+ my $object_clause = "ObjectType = '$type'";
+ $object_clause .= " AND ObjectId = $id" if $id;
+ push @object_clauses, "($object_clause)";
+ }
+ # find ACLs that are related to our objects only
+ $query .= " AND (". join( ' OR ', @object_clauses ) .")"
+ if @object_clauses;
+
+ my $dbh = $RT::Handle->dbh;
+ my $roles = $dbh->selectcol_arrayref($query);
+ unless ( $roles ) {
+ $RT::Logger->warning( $dbh->errstr );
+ return ();
+ }
+ return @$roles;