]>
Commit | Line | Data |
---|---|---|
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 SYNOPSIS | |
50 | ||
51 | use RT::ACE; | |
52 | my $ace = RT::ACE->new($CurrentUser); | |
53 | ||
54 | ||
55 | =head1 DESCRIPTION | |
56 | ||
57 | ||
58 | ||
59 | =head1 METHODS | |
60 | ||
61 | ||
62 | =cut | |
63 | ||
64 | ||
65 | package RT::ACE; | |
66 | use base 'RT::Record'; | |
67 | ||
68 | sub Table {'ACL'} | |
69 | ||
70 | ||
71 | use strict; | |
72 | use warnings; | |
73 | ||
3ffc5f4f MKG |
74 | require RT::Principals; |
75 | require RT::Queues; | |
76 | require RT::Groups; | |
84fb5b46 | 77 | |
3ffc5f4f MKG |
78 | our %RIGHTS; |
79 | ||
80 | my (@_ACL_CACHE_HANDLERS); | |
84fb5b46 MKG |
81 | |
82 | ||
83 | ||
84 | =head1 Rights | |
85 | ||
86 | # Queue rights are the sort of queue rights that can only be granted | |
87 | # to real people or groups | |
88 | ||
89 | =cut | |
90 | ||
84fb5b46 MKG |
91 | =head2 LoadByValues PARAMHASH |
92 | ||
93 | Load an ACE by specifying a paramhash with the following fields: | |
94 | ||
95 | PrincipalId => undef, | |
96 | PrincipalType => undef, | |
3ffc5f4f | 97 | RightName => undef, |
84fb5b46 MKG |
98 | |
99 | And either: | |
100 | ||
3ffc5f4f | 101 | Object => undef, |
84fb5b46 MKG |
102 | |
103 | OR | |
104 | ||
3ffc5f4f MKG |
105 | ObjectType => undef, |
106 | ObjectId => undef | |
84fb5b46 MKG |
107 | |
108 | =cut | |
109 | ||
110 | sub LoadByValues { | |
111 | my $self = shift; | |
112 | my %args = ( PrincipalId => undef, | |
113 | PrincipalType => undef, | |
114 | RightName => undef, | |
115 | Object => undef, | |
116 | ObjectId => undef, | |
117 | ObjectType => undef, | |
118 | @_ ); | |
119 | ||
120 | if ( $args{'RightName'} ) { | |
121 | my $canonic_name = $self->CanonicalizeRightName( $args{'RightName'} ); | |
122 | unless ( $canonic_name ) { | |
3ffc5f4f | 123 | return wantarray ? ( 0, $self->loc("Invalid right. Couldn't canonicalize right '[_1]'", $args{'RightName'}) ) : 0; |
84fb5b46 MKG |
124 | } |
125 | $args{'RightName'} = $canonic_name; | |
126 | } | |
127 | ||
128 | my $princ_obj; | |
129 | ( $princ_obj, $args{'PrincipalType'} ) = | |
130 | $self->_CanonicalizePrincipal( $args{'PrincipalId'}, | |
131 | $args{'PrincipalType'} ); | |
132 | ||
133 | unless ( $princ_obj->id ) { | |
3ffc5f4f | 134 | return wantarray ? ( 0, |
84fb5b46 | 135 | $self->loc( 'Principal [_1] not found.', $args{'PrincipalId'} ) |
3ffc5f4f | 136 | ) : 0; |
84fb5b46 MKG |
137 | } |
138 | ||
139 | my ($object, $object_type, $object_id) = $self->_ParseObjectArg( %args ); | |
140 | unless( $object ) { | |
3ffc5f4f | 141 | return wantarray ? ( 0, $self->loc("System error. Right not granted.")) : 0; |
84fb5b46 MKG |
142 | } |
143 | ||
144 | $self->LoadByCols( PrincipalId => $princ_obj->Id, | |
145 | PrincipalType => $args{'PrincipalType'}, | |
146 | RightName => $args{'RightName'}, | |
147 | ObjectType => $object_type, | |
148 | ObjectId => $object_id); | |
149 | ||
150 | #If we couldn't load it. | |
151 | unless ( $self->Id ) { | |
3ffc5f4f | 152 | return wantarray ? ( 0, $self->loc("ACE not found") ) : 0; |
84fb5b46 MKG |
153 | } |
154 | ||
155 | # if we could | |
3ffc5f4f | 156 | return wantarray ? ( $self->Id, $self->loc("Right Loaded") ) : $self->Id; |
84fb5b46 MKG |
157 | |
158 | } | |
159 | ||
160 | ||
161 | ||
162 | =head2 Create <PARAMS> | |
163 | ||
164 | PARAMS is a parameter hash with the following elements: | |
165 | ||
166 | PrincipalId => The id of an RT::Principal object | |
167 | PrincipalType => "User" "Group" or any Role type | |
168 | RightName => the name of a right. in any case | |
169 | ||
170 | ||
171 | Either: | |
172 | ||
173 | Object => An object to create rights for. ususally, an RT::Queue or RT::Group | |
174 | This should always be a DBIx::SearchBuilder::Record subclass | |
175 | ||
176 | OR | |
177 | ||
178 | ObjectType => the type of the object in question (ref ($object)) | |
179 | ObjectId => the id of the object in question $object->Id | |
180 | ||
181 | ||
182 | ||
183 | Returns a tuple of (STATUS, MESSAGE); If the call succeeded, STATUS is true. Otherwise it's false. | |
184 | ||
185 | ||
186 | ||
187 | =cut | |
188 | ||
189 | sub Create { | |
190 | my $self = shift; | |
191 | my %args = ( | |
192 | PrincipalId => undef, | |
193 | PrincipalType => undef, | |
194 | RightName => undef, | |
195 | Object => undef, | |
196 | @_ | |
197 | ); | |
198 | ||
199 | unless ( $args{'RightName'} ) { | |
200 | return ( 0, $self->loc('No right specified') ); | |
201 | } | |
202 | ||
203 | #if we haven't specified any sort of right, we're talking about a global right | |
204 | if (!defined $args{'Object'} && !defined $args{'ObjectId'} && !defined $args{'ObjectType'}) { | |
205 | $args{'Object'} = $RT::System; | |
206 | } | |
207 | ($args{'Object'}, $args{'ObjectType'}, $args{'ObjectId'}) = $self->_ParseObjectArg( %args ); | |
208 | unless( $args{'Object'} ) { | |
3ffc5f4f | 209 | return ( 0, $self->loc("System error. Right not granted.") ); |
84fb5b46 MKG |
210 | } |
211 | ||
212 | # Validate the principal | |
213 | my $princ_obj; | |
214 | ( $princ_obj, $args{'PrincipalType'} ) = | |
215 | $self->_CanonicalizePrincipal( $args{'PrincipalId'}, | |
216 | $args{'PrincipalType'} ); | |
217 | ||
218 | unless ( $princ_obj->id ) { | |
219 | return ( 0, | |
220 | $self->loc( 'Principal [_1] not found.', $args{'PrincipalId'} ) | |
221 | ); | |
222 | } | |
223 | ||
224 | # }}} | |
225 | ||
226 | # Check the ACL | |
227 | ||
228 | if (ref( $args{'Object'}) eq 'RT::Group' ) { | |
229 | unless ( $self->CurrentUser->HasRight( Object => $args{'Object'}, | |
230 | Right => 'AdminGroup' ) | |
231 | ) { | |
232 | return ( 0, $self->loc('Permission Denied') ); | |
233 | } | |
234 | } | |
235 | ||
236 | else { | |
237 | unless ( $self->CurrentUser->HasRight( Object => $args{'Object'}, Right => 'ModifyACL' )) { | |
238 | return ( 0, $self->loc('Permission Denied') ); | |
239 | } | |
240 | } | |
241 | # }}} | |
242 | ||
243 | # Canonicalize and check the right name | |
244 | my $canonic_name = $self->CanonicalizeRightName( $args{'RightName'} ); | |
245 | unless ( $canonic_name ) { | |
246 | return ( 0, $self->loc("Invalid right. Couldn't canonicalize right '[_1]'", $args{'RightName'}) ); | |
247 | } | |
248 | $args{'RightName'} = $canonic_name; | |
249 | ||
250 | #check if it's a valid RightName | |
251 | if ( $args{'Object'}->can('AvailableRights') ) { | |
3ffc5f4f | 252 | my $available = $args{'Object'}->AvailableRights($princ_obj); |
84fb5b46 MKG |
253 | unless ( grep $_ eq $args{'RightName'}, map $self->CanonicalizeRightName( $_ ), keys %$available ) { |
254 | $RT::Logger->warning( | |
255 | "Couldn't validate right name '$args{'RightName'}'" | |
256 | ." for object of ". ref( $args{'Object'} ) ." class" | |
257 | ); | |
258 | return ( 0, $self->loc('Invalid right') ); | |
259 | } | |
260 | } | |
261 | # }}} | |
262 | ||
263 | # Make sure the right doesn't already exist. | |
264 | $self->LoadByCols( PrincipalId => $princ_obj->id, | |
265 | PrincipalType => $args{'PrincipalType'}, | |
266 | RightName => $args{'RightName'}, | |
267 | ObjectType => $args{'ObjectType'}, | |
268 | ObjectId => $args{'ObjectId'}, | |
269 | ); | |
270 | if ( $self->Id ) { | |
403d7b0b MKG |
271 | return ( 0, $self->loc('[_1] already has that right', |
272 | $princ_obj->Object->Name) ); | |
84fb5b46 MKG |
273 | } |
274 | ||
275 | my $id = $self->SUPER::Create( PrincipalId => $princ_obj->id, | |
276 | PrincipalType => $args{'PrincipalType'}, | |
277 | RightName => $args{'RightName'}, | |
278 | ObjectType => ref( $args{'Object'} ), | |
279 | ObjectId => $args{'Object'}->id, | |
280 | ); | |
281 | ||
84fb5b46 | 282 | if ( $id ) { |
3ffc5f4f MKG |
283 | RT::ACE->InvalidateCaches( |
284 | Action => "Grant", | |
285 | RightName => $self->RightName, | |
286 | ACE => $self, | |
287 | ); | |
84fb5b46 MKG |
288 | return ( $id, $self->loc('Right Granted') ); |
289 | } | |
290 | else { | |
291 | return ( 0, $self->loc('System error. Right not granted.') ); | |
292 | } | |
293 | } | |
294 | ||
295 | ||
296 | ||
297 | =head2 Delete { InsideTransaction => undef} | |
298 | ||
299 | Delete this object. This method should ONLY ever be called from RT::User or RT::Group (or from itself) | |
300 | If this is being called from within a transaction, specify a true value for the parameter InsideTransaction. | |
301 | Really, DBIx::SearchBuilder should use and/or fake subtransactions | |
302 | ||
303 | This routine will also recurse and delete any delegations of this right | |
304 | ||
305 | =cut | |
306 | ||
307 | sub Delete { | |
308 | my $self = shift; | |
309 | ||
310 | unless ( $self->Id ) { | |
311 | return ( 0, $self->loc('Right not loaded.') ); | |
312 | } | |
313 | ||
314 | # A user can delete an ACE if the current user has the right to modify it and it's not a delegated ACE | |
315 | # or if it's a delegated ACE and it was delegated by the current user | |
316 | unless ($self->CurrentUser->HasRight(Right => 'ModifyACL', Object => $self->Object)) { | |
317 | return ( 0, $self->loc('Permission Denied') ); | |
318 | } | |
319 | $self->_Delete(@_); | |
320 | } | |
321 | ||
322 | # Helper for Delete with no ACL check | |
323 | sub _Delete { | |
324 | my $self = shift; | |
325 | my %args = ( InsideTransaction => undef, | |
326 | @_ ); | |
327 | ||
328 | my $InsideTransaction = $args{'InsideTransaction'}; | |
329 | ||
330 | $RT::Handle->BeginTransaction() unless $InsideTransaction; | |
331 | ||
3ffc5f4f MKG |
332 | my $right = $self->RightName; |
333 | ||
84fb5b46 MKG |
334 | my ( $val, $msg ) = $self->SUPER::Delete(@_); |
335 | ||
336 | if ($val) { | |
3ffc5f4f | 337 | RT::ACE->InvalidateCaches( Action => "Revoke", RightName => $right ); |
84fb5b46 MKG |
338 | $RT::Handle->Commit() unless $InsideTransaction; |
339 | return ( $val, $self->loc('Right revoked') ); | |
340 | } | |
341 | ||
342 | $RT::Handle->Rollback() unless $InsideTransaction; | |
343 | return ( 0, $self->loc('Right could not be revoked') ); | |
344 | } | |
345 | ||
346 | ||
347 | ||
348 | =head2 _BootstrapCreate | |
349 | ||
350 | Grant a right with no error checking and no ACL. this is _only_ for | |
351 | installation. If you use this routine without the author's explicit | |
352 | written approval, he will hunt you down and make you spend eternity | |
353 | translating mozilla's code into FORTRAN or intercal. | |
354 | ||
355 | If you think you need this routine, you've mistaken. | |
356 | ||
357 | =cut | |
358 | ||
359 | sub _BootstrapCreate { | |
360 | my $self = shift; | |
361 | my %args = (@_); | |
362 | ||
363 | # When bootstrapping, make sure we get the _right_ users | |
364 | if ( $args{'UserId'} ) { | |
365 | my $user = RT::User->new( $self->CurrentUser ); | |
366 | $user->Load( $args{'UserId'} ); | |
367 | delete $args{'UserId'}; | |
368 | $args{'PrincipalId'} = $user->PrincipalId; | |
369 | $args{'PrincipalType'} = 'User'; | |
370 | } | |
371 | ||
372 | my $id = $self->SUPER::Create(%args); | |
373 | ||
374 | if ( $id > 0 ) { | |
375 | return ($id); | |
376 | } | |
377 | else { | |
378 | $RT::Logger->err('System error. right not granted.'); | |
379 | return (undef); | |
380 | } | |
381 | ||
382 | } | |
383 | ||
3ffc5f4f MKG |
384 | =head2 InvalidateCaches |
385 | ||
386 | Calls any registered ACL cache handlers (see L</RegisterCacheHandler>). | |
387 | ||
388 | Usually called from L</Create> and L</Delete>. | |
389 | ||
390 | =cut | |
391 | ||
392 | sub InvalidateCaches { | |
393 | my $class = shift; | |
394 | ||
395 | for my $handler (@_ACL_CACHE_HANDLERS) { | |
396 | next unless ref($handler) eq "CODE"; | |
397 | $handler->(@_); | |
398 | } | |
399 | } | |
400 | ||
401 | =head2 RegisterCacheHandler | |
402 | ||
403 | Class method. Takes a coderef and adds it to the ACL cache handlers. These | |
404 | handlers are called by L</InvalidateCaches>, usually called itself from | |
405 | L</Create> and L</Delete>. | |
406 | ||
407 | The handlers are passed a hash which may contain any (or none) of these | |
408 | optional keys: | |
84fb5b46 | 409 | |
3ffc5f4f MKG |
410 | =over |
411 | ||
412 | =item Action | |
413 | ||
414 | A string indicating the action that (may have) invalidated the cache. Expected | |
415 | values are currently: | |
416 | ||
417 | =over | |
418 | ||
419 | =item Grant | |
420 | ||
421 | =item Revoke | |
422 | ||
423 | =back | |
424 | ||
425 | However, other values may be passed in the future. | |
426 | ||
427 | =item RightName | |
428 | ||
429 | The (canonicalized) right being granted or revoked. | |
430 | ||
431 | =item ACE | |
432 | ||
433 | The L<RT::ACE> object just created. | |
434 | ||
435 | =back | |
436 | ||
437 | Your handler should be flexible enough to account for additional arguments | |
438 | being passed in the future. | |
439 | ||
440 | =cut | |
441 | ||
442 | sub RegisterCacheHandler { | |
443 | push @_ACL_CACHE_HANDLERS, $_[1]; | |
444 | } | |
84fb5b46 MKG |
445 | |
446 | sub RightName { | |
447 | my $self = shift; | |
448 | my $val = $self->_Value('RightName'); | |
449 | return $val unless $val; | |
450 | ||
451 | my $available = $self->Object->AvailableRights; | |
452 | foreach my $right ( keys %$available ) { | |
453 | return $right if $val eq $self->CanonicalizeRightName($right); | |
454 | } | |
455 | ||
456 | $RT::Logger->error("Invalid right. Couldn't canonicalize right '$val'"); | |
457 | return $val; | |
458 | } | |
459 | ||
460 | =head2 CanonicalizeRightName <RIGHT> | |
461 | ||
462 | Takes a queue or system right name in any case and returns it in | |
463 | the correct case. If it's not found, will return undef. | |
464 | ||
465 | =cut | |
466 | ||
467 | sub CanonicalizeRightName { | |
3ffc5f4f MKG |
468 | my $self = shift; |
469 | my $name = shift; | |
470 | for my $class (sort keys %RIGHTS) { | |
471 | return $RIGHTS{$class}{ lc $name }{Name} | |
472 | if $RIGHTS{$class}{ lc $name }; | |
473 | } | |
474 | return undef; | |
84fb5b46 MKG |
475 | } |
476 | ||
477 | ||
478 | ||
84fb5b46 MKG |
479 | =head2 Object |
480 | ||
481 | If the object this ACE applies to is a queue, returns the queue object. | |
482 | If the object this ACE applies to is a group, returns the group object. | |
483 | If it's the system object, returns undef. | |
484 | ||
485 | If the user has no rights, returns undef. | |
486 | ||
487 | =cut | |
488 | ||
489 | ||
490 | ||
491 | ||
492 | sub Object { | |
493 | my $self = shift; | |
494 | ||
495 | my $appliesto_obj; | |
496 | ||
3ffc5f4f | 497 | if ($self->__Value('ObjectType') && $self->__Value('ObjectType')->DOES('RT::Record::Role::Rights') ) { |
84fb5b46 MKG |
498 | $appliesto_obj = $self->__Value('ObjectType')->new($self->CurrentUser); |
499 | unless (ref( $appliesto_obj) eq $self->__Value('ObjectType')) { | |
500 | return undef; | |
501 | } | |
502 | $appliesto_obj->Load( $self->__Value('ObjectId') ); | |
503 | return ($appliesto_obj); | |
504 | } | |
505 | else { | |
506 | $RT::Logger->warning( "$self -> Object called for an object " | |
507 | . "of an unknown type:" | |
508 | . $self->__Value('ObjectType') ); | |
509 | return (undef); | |
510 | } | |
511 | } | |
512 | ||
513 | ||
514 | ||
515 | =head2 PrincipalObj | |
516 | ||
517 | Returns the RT::Principal object for this ACE. | |
518 | ||
519 | =cut | |
520 | ||
521 | sub PrincipalObj { | |
522 | my $self = shift; | |
523 | ||
524 | my $princ_obj = RT::Principal->new( $self->CurrentUser ); | |
525 | $princ_obj->Load( $self->__Value('PrincipalId') ); | |
526 | ||
527 | unless ( $princ_obj->Id ) { | |
528 | $RT::Logger->err( | |
529 | "ACE " . $self->Id . " couldn't load its principal object" ); | |
530 | } | |
531 | return ($princ_obj); | |
532 | ||
533 | } | |
534 | ||
535 | ||
536 | ||
537 | ||
538 | sub _Set { | |
539 | my $self = shift; | |
540 | return ( 0, $self->loc("ACEs can only be created and deleted.") ); | |
541 | } | |
542 | ||
543 | ||
544 | ||
545 | sub _Value { | |
546 | my $self = shift; | |
547 | ||
548 | if ( $self->PrincipalObj->IsGroup | |
549 | && $self->PrincipalObj->Object->HasMemberRecursively( | |
550 | $self->CurrentUser->PrincipalObj | |
551 | ) | |
552 | ) { | |
553 | return ( $self->__Value(@_) ); | |
554 | } | |
555 | elsif ( $self->CurrentUser->HasRight(Right => 'ShowACL', Object => $self->Object) ) { | |
556 | return ( $self->__Value(@_) ); | |
557 | } | |
558 | else { | |
559 | return undef; | |
560 | } | |
561 | } | |
562 | ||
563 | ||
564 | ||
565 | ||
566 | ||
567 | =head2 _CanonicalizePrincipal (PrincipalId, PrincipalType) | |
568 | ||
569 | Takes a principal id and a principal type. | |
570 | ||
571 | If the principal is a user, resolves it to the proper acl equivalence group. | |
572 | Returns a tuple of (RT::Principal, PrincipalType) for the principal we really want to work with | |
573 | ||
574 | =cut | |
575 | ||
576 | sub _CanonicalizePrincipal { | |
577 | my $self = shift; | |
578 | my $princ_id = shift; | |
579 | my $princ_type = shift || ''; | |
580 | ||
581 | my $princ_obj = RT::Principal->new(RT->SystemUser); | |
582 | $princ_obj->Load($princ_id); | |
583 | ||
584 | unless ( $princ_obj->Id ) { | |
585 | use Carp; | |
586 | $RT::Logger->crit(Carp::longmess); | |
587 | $RT::Logger->crit("Can't load a principal for id $princ_id"); | |
588 | return ( $princ_obj, undef ); | |
589 | } | |
590 | ||
591 | # Rights never get granted to users. they get granted to their | |
592 | # ACL equivalence groups | |
593 | if ( $princ_type eq 'User' ) { | |
594 | my $equiv_group = RT::Group->new( $self->CurrentUser ); | |
595 | $equiv_group->LoadACLEquivalenceGroup($princ_obj); | |
596 | unless ( $equiv_group->Id ) { | |
597 | $RT::Logger->crit( "No ACL equiv group for princ " . $princ_obj->id ); | |
598 | return ( RT::Principal->new(RT->SystemUser), undef ); | |
599 | } | |
600 | $princ_obj = $equiv_group->PrincipalObj(); | |
601 | $princ_type = 'Group'; | |
602 | ||
603 | } | |
604 | return ( $princ_obj, $princ_type ); | |
605 | } | |
606 | ||
607 | sub _ParseObjectArg { | |
608 | my $self = shift; | |
609 | my %args = ( Object => undef, | |
610 | ObjectId => undef, | |
611 | ObjectType => undef, | |
612 | @_ ); | |
613 | ||
614 | if( $args{'Object'} && ($args{'ObjectId'} || $args{'ObjectType'}) ) { | |
3ffc5f4f MKG |
615 | $RT::Logger->crit( "Method called with an ObjectType or an ObjectId and Object args" ); |
616 | return (); | |
84fb5b46 | 617 | } elsif( $args{'Object'} && ref($args{'Object'}) && !$args{'Object'}->can('id') ) { |
3ffc5f4f MKG |
618 | $RT::Logger->crit( "Method called called Object that has no id method" ); |
619 | return (); | |
84fb5b46 | 620 | } elsif( $args{'Object'} ) { |
3ffc5f4f MKG |
621 | my $obj = $args{'Object'}; |
622 | return ($obj, ref $obj, $obj->id); | |
84fb5b46 | 623 | } elsif ( $args{'ObjectType'} ) { |
3ffc5f4f MKG |
624 | my $obj = $args{'ObjectType'}->new( $self->CurrentUser ); |
625 | $obj->Load( $args{'ObjectId'} ); | |
626 | return ($obj, ref $obj, $obj->id); | |
84fb5b46 | 627 | } else { |
3ffc5f4f MKG |
628 | $RT::Logger->crit( "Method called with wrong args" ); |
629 | return (); | |
84fb5b46 MKG |
630 | } |
631 | } | |
632 | ||
633 | ||
634 | # }}} | |
635 | ||
636 | ||
637 | ||
638 | =head2 id | |
639 | ||
640 | Returns the current value of id. | |
641 | (In the database, id is stored as int(11).) | |
642 | ||
643 | ||
644 | =cut | |
645 | ||
646 | ||
647 | =head2 PrincipalType | |
648 | ||
649 | Returns the current value of PrincipalType. | |
650 | (In the database, PrincipalType is stored as varchar(25).) | |
651 | ||
652 | ||
653 | ||
654 | =head2 SetPrincipalType VALUE | |
655 | ||
656 | ||
657 | Set PrincipalType to VALUE. | |
658 | Returns (1, 'Status message') on success and (0, 'Error Message') on failure. | |
659 | (In the database, PrincipalType will be stored as a varchar(25).) | |
660 | ||
661 | ||
662 | =cut | |
663 | ||
664 | ||
665 | =head2 PrincipalId | |
666 | ||
667 | Returns the current value of PrincipalId. | |
668 | (In the database, PrincipalId is stored as int(11).) | |
669 | ||
670 | ||
671 | ||
672 | =head2 SetPrincipalId VALUE | |
673 | ||
674 | ||
675 | Set PrincipalId to VALUE. | |
676 | Returns (1, 'Status message') on success and (0, 'Error Message') on failure. | |
677 | (In the database, PrincipalId will be stored as a int(11).) | |
678 | ||
679 | ||
680 | =cut | |
681 | ||
682 | ||
683 | =head2 RightName | |
684 | ||
685 | Returns the current value of RightName. | |
686 | (In the database, RightName is stored as varchar(25).) | |
687 | ||
688 | ||
689 | ||
690 | =head2 SetRightName VALUE | |
691 | ||
692 | ||
693 | Set RightName to VALUE. | |
694 | Returns (1, 'Status message') on success and (0, 'Error Message') on failure. | |
695 | (In the database, RightName will be stored as a varchar(25).) | |
696 | ||
697 | ||
698 | =cut | |
699 | ||
700 | ||
701 | =head2 ObjectType | |
702 | ||
703 | Returns the current value of ObjectType. | |
704 | (In the database, ObjectType is stored as varchar(25).) | |
705 | ||
706 | ||
707 | ||
708 | =head2 SetObjectType VALUE | |
709 | ||
710 | ||
711 | Set ObjectType to VALUE. | |
712 | Returns (1, 'Status message') on success and (0, 'Error Message') on failure. | |
713 | (In the database, ObjectType will be stored as a varchar(25).) | |
714 | ||
715 | ||
716 | =cut | |
717 | ||
718 | ||
719 | =head2 ObjectId | |
720 | ||
721 | Returns the current value of ObjectId. | |
722 | (In the database, ObjectId is stored as int(11).) | |
723 | ||
724 | ||
725 | ||
726 | =head2 SetObjectId VALUE | |
727 | ||
728 | ||
729 | Set ObjectId to VALUE. | |
730 | Returns (1, 'Status message') on success and (0, 'Error Message') on failure. | |
731 | (In the database, ObjectId will be stored as a int(11).) | |
732 | ||
733 | ||
734 | =cut | |
735 | ||
736 | ||
737 | =head2 Creator | |
738 | ||
739 | Returns the current value of Creator. | |
740 | (In the database, Creator is stored as int(11).) | |
741 | ||
742 | =cut | |
743 | ||
744 | ||
745 | =head2 Created | |
746 | ||
747 | Returns the current value of Created. | |
748 | (In the database, Created is stored as datetime.) | |
749 | ||
750 | =cut | |
751 | ||
752 | ||
753 | =head2 LastUpdatedBy | |
754 | ||
755 | Returns the current value of LastUpdatedBy. | |
756 | (In the database, LastUpdatedBy is stored as int(11).) | |
757 | ||
758 | =cut | |
759 | ||
760 | ||
761 | =head2 LastUpdated | |
762 | ||
763 | Returns the current value of LastUpdated. | |
764 | (In the database, LastUpdated is stored as datetime.) | |
765 | ||
766 | =cut | |
767 | ||
768 | ||
769 | ||
770 | sub _CoreAccessible { | |
771 | { | |
772 | ||
773 | id => | |
3ffc5f4f | 774 | {read => 1, sql_type => 4, length => 11, is_blob => 0, is_numeric => 1, type => 'int(11)', default => ''}, |
84fb5b46 | 775 | PrincipalType => |
3ffc5f4f | 776 | {read => 1, write => 1, sql_type => 12, length => 25, is_blob => 0, is_numeric => 0, type => 'varchar(25)', default => ''}, |
84fb5b46 | 777 | PrincipalId => |
3ffc5f4f | 778 | {read => 1, write => 1, sql_type => 4, length => 11, is_blob => 0, is_numeric => 1, type => 'int(11)', default => '0'}, |
84fb5b46 | 779 | RightName => |
3ffc5f4f | 780 | {read => 1, write => 1, sql_type => 12, length => 25, is_blob => 0, is_numeric => 0, type => 'varchar(25)', default => ''}, |
84fb5b46 | 781 | ObjectType => |
3ffc5f4f | 782 | {read => 1, write => 1, sql_type => 12, length => 25, is_blob => 0, is_numeric => 0, type => 'varchar(25)', default => ''}, |
84fb5b46 | 783 | ObjectId => |
3ffc5f4f | 784 | {read => 1, write => 1, sql_type => 4, length => 11, is_blob => 0, is_numeric => 1, type => 'int(11)', default => '0'}, |
84fb5b46 | 785 | Creator => |
3ffc5f4f | 786 | {read => 1, auto => 1, sql_type => 4, length => 11, is_blob => 0, is_numeric => 1, type => 'int(11)', default => '0'}, |
84fb5b46 | 787 | Created => |
3ffc5f4f | 788 | {read => 1, auto => 1, sql_type => 11, length => 0, is_blob => 0, is_numeric => 0, type => 'datetime', default => ''}, |
84fb5b46 | 789 | LastUpdatedBy => |
3ffc5f4f | 790 | {read => 1, auto => 1, sql_type => 4, length => 11, is_blob => 0, is_numeric => 1, type => 'int(11)', default => '0'}, |
84fb5b46 | 791 | LastUpdated => |
3ffc5f4f | 792 | {read => 1, auto => 1, sql_type => 11, length => 0, is_blob => 0, is_numeric => 0, type => 'datetime', default => ''}, |
84fb5b46 MKG |
793 | |
794 | } | |
795 | }; | |
796 | ||
3ffc5f4f MKG |
797 | sub FindDependencies { |
798 | my $self = shift; | |
799 | my ($walker, $deps) = @_; | |
800 | ||
801 | $self->SUPER::FindDependencies($walker, $deps); | |
802 | ||
803 | $deps->Add( out => $self->PrincipalObj->Object ); | |
804 | $deps->Add( out => $self->Object ); | |
805 | } | |
806 | ||
84fb5b46 MKG |
807 | RT::Base->_ImportOverlays(); |
808 | ||
809 | 1; |