Upgrade to 4.2.8
[usit-rt.git] / lib / RT / ACL.pm
CommitLineData
84fb5b46
MKG
1# BEGIN BPS TAGGED BLOCK {{{
2#
3# COPYRIGHT:
4#
3ffc5f4f 5# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC
84fb5b46
MKG
6# <sales@bestpractical.com>
7#
8# (Except where explicitly superseded by other copyright notices)
9#
10#
11# LICENSE:
12#
13# This work is made available to you under the terms of Version 2 of
14# the GNU General Public License. A copy of that license should have
15# been provided with this software, but in any event can be snarfed
16# from www.gnu.org.
17#
18# This work is distributed in the hope that it will be useful, but
19# WITHOUT ANY WARRANTY; without even the implied warranty of
20# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21# General Public License for more details.
22#
23# You should have received a copy of the GNU General Public License
24# along with this program; if not, write to the Free Software
25# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
26# 02110-1301 or visit their web page on the internet at
27# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
28#
29#
30# CONTRIBUTION SUBMISSION POLICY:
31#
32# (The following paragraph is not intended to limit the rights granted
33# to you to modify and distribute this software under the terms of
34# the GNU General Public License and is only of importance to you if
35# you choose to contribute your changes and enhancements to the
36# community by submitting them to Best Practical Solutions, LLC.)
37#
38# By intentionally submitting any modifications, corrections or
39# derivatives to this work, or any other work intended for use with
40# Request Tracker, to Best Practical Solutions, LLC, you confirm that
41# you are the copyright holder for those contributions and you grant
42# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
43# royalty-free, perpetual, license to use, copy, create derivative
44# works based on those contributions, and sublicense and distribute
45# those contributions and any derivatives thereof.
46#
47# END BPS TAGGED BLOCK }}}
48
49=head1 NAME
50
51 RT::ACL - collection of RT ACE objects
52
53=head1 SYNOPSIS
54
55 use RT::ACL;
56my $ACL = RT::ACL->new($CurrentUser);
57
58=head1 DESCRIPTION
59
60
61=head1 METHODS
62
63
64=cut
65
66
67package RT::ACL;
84fb5b46
MKG
68use base 'RT::SearchBuilder';
69
3ffc5f4f
MKG
70use RT::ACE;
71
84fb5b46
MKG
72sub Table { 'ACL'}
73
74use strict;
75use warnings;
76
77
78
79=head2 Next
80
81Hand out the next ACE that was found
82
83=cut
84
85
86
87=head2 LimitToObject $object
88
89Limit the ACL to rights for the object $object. It needs to be an RT::Record class.
90
91=cut
92
93sub LimitToObject {
94 my $self = shift;
95 my $obj = shift;
96
97 my $obj_type = ref($obj)||$obj;
98 my $obj_id = eval { $obj->id};
99
100 my $object_clause = 'possible_objects';
101 $self->_OpenParen($object_clause);
102 $self->Limit(
103 SUBCLAUSE => $object_clause,
104 FIELD => 'ObjectType',
105 OPERATOR => '=',
106 VALUE => (ref($obj)||$obj),
107 ENTRYAGGREGATOR => 'OR' # That "OR" applies to the separate objects we're searching on, not "Type Or ID"
108 );
109 if ($obj_id) {
110 $self->Limit(
111 SUBCLAUSE => $object_clause,
112 FIELD => 'ObjectId',
113 OPERATOR => '=',
114 VALUE => $obj_id,
115 ENTRYAGGREGATOR => 'AND',
116 QUOTEVALUE => 0
117 );
118 }
119 $self->_CloseParen($object_clause);
120
121}
122
123
124
84fb5b46
MKG
125=head2 LimitToPrincipal { Type => undef, Id => undef, IncludeGroupMembership => undef }
126
127Limit the ACL to the principal with PrincipalId Id and PrincipalType Type
128
129Id is not optional.
130Type is.
131
132if IncludeGroupMembership => 1 is specified, ACEs which apply to the principal due to group membership will be included in the resultset.
133
134
135=cut
136
137sub LimitToPrincipal {
138 my $self = shift;
139 my %args = ( Type => undef,
140 Id => undef,
141 IncludeGroupMembership => undef,
142 @_
143 );
144 if ( $args{'IncludeGroupMembership'} ) {
145 my $cgm = $self->NewAlias('CachedGroupMembers');
146 $self->Join( ALIAS1 => 'main',
147 FIELD1 => 'PrincipalId',
148 ALIAS2 => $cgm,
149 FIELD2 => 'GroupId'
150 );
151 $self->Limit( ALIAS => $cgm,
152 FIELD => 'Disabled',
153 VALUE => 0 );
154 $self->Limit( ALIAS => $cgm,
155 FIELD => 'MemberId',
156 OPERATOR => '=',
157 VALUE => $args{'Id'},
158 ENTRYAGGREGATOR => 'OR'
159 );
160 } else {
161 if ( defined $args{'Type'} ) {
162 $self->Limit( FIELD => 'PrincipalType',
163 OPERATOR => '=',
164 VALUE => $args{'Type'},
165 ENTRYAGGREGATOR => 'OR'
166 );
167 }
168
169 # if the principal id points to a user, we really want to point
170 # to their ACL equivalence group. The machinations we're going through
171 # lead me to start to suspect that we really want users and groups
172 # to just be the same table. or _maybe_ that we want an object db.
173 my $princ = RT::Principal->new( RT->SystemUser );
174 $princ->Load( $args{'Id'} );
175 if ( $princ->PrincipalType eq 'User' ) {
176 my $group = RT::Group->new( RT->SystemUser );
177 $group->LoadACLEquivalenceGroup($princ);
178 $args{'Id'} = $group->PrincipalId;
179 }
180 $self->Limit( FIELD => 'PrincipalId',
181 OPERATOR => '=',
182 VALUE => $args{'Id'},
183 ENTRYAGGREGATOR => 'OR'
184 );
185 }
186}
187
188
189
190
191sub Next {
192 my $self = shift;
193
194 my $ACE = $self->SUPER::Next();
195 # Short-circuit having to load up the ->Object
196 return $ACE
197 if $self->CurrentUser->PrincipalObj->Id == RT->SystemUser->Id;
198 if ( ( defined($ACE) ) and ( ref($ACE) ) ) {
199
200 if ( $self->CurrentUser->HasRight( Right => 'ShowACL',
201 Object => $ACE->Object )
202 or $self->CurrentUser->HasRight( Right => 'ModifyACL',
203 Object => $ACE->Object )
204 ) {
205 return ($ACE);
206 }
207
208 #If the user doesn't have the right to show this ACE
209 else {
210 return ( $self->Next() );
211 }
212 }
213
214 #if there never was any ACE
215 else {
216 return (undef);
217 }
218
219}
220
3ffc5f4f
MKG
221# The singular of ACL is ACE.
222sub _SingularClass { "RT::ACE" }
84fb5b46 223
84fb5b46
MKG
224RT::Base->_ImportOverlays();
225
2261;