1 #$Header: /home/cvs/cvsroot/freeside/rt/lib/RT/ACE.pm,v 1.1 2002-08-12 06:17:07 ivan Exp $
5 RT::ACE - RT\'s ACE object
10 my $ace = new RT::ACE($CurrentUser);
20 ok(require RT::TestHarness);
38 System => 'System-level right',
39 Queue => 'Queue-level right'
42 # {{{ Descriptions of rights
44 # Queue rights are the sort of queue rights that can only be granted
45 # to real people or groups
47 SeeQueue => 'Can this principal see this queue',
48 AdminQueue => 'Create, delete and modify queues',
49 ShowACL => 'Display Access Control List',
50 ModifyACL => 'Modify Access Control List',
51 ModifyQueueWatchers => 'Modify the queue watchers',
52 AdminKeywordSelects => 'Create, delete and modify keyword selections',
55 ModifyTemplate => 'Modify email templates for this queue',
56 ShowTemplate => 'Display email templates for this queue',
57 ModifyScrips => 'Modify Scrips for this queue',
58 ShowScrips => 'Display Scrips for this queue',
60 ShowTicket => 'Show ticket summaries',
61 ShowTicketComments => 'Show ticket private commentary',
63 Watch => 'Sign up as a ticket Requestor or ticket or queue Cc',
64 WatchAsAdminCc => 'Sign up as a ticket or queue AdminCc',
65 CreateTicket => 'Create tickets in this queue',
66 ReplyToTicket => 'Reply to tickets',
67 CommentOnTicket => 'Comment on tickets',
68 OwnTicket => 'Own tickets',
69 ModifyTicket => 'Modify tickets',
70 DeleteTicket => 'Delete tickets'
75 # System rights are rights granted to the whole system
77 SuperUser => 'Do anything and everything',
78 AdminKeywords => 'Creatte, delete and modify keywords',
79 AdminGroups => 'Create, delete and modify groups',
80 AdminUsers => 'Create, Delete and Modify users',
81 ModifySelf => 'Modify one\'s own RT account',
87 # {{{ Descriptions of principals
89 %TICKET_METAPRINCIPALS = ( Owner => 'The owner of a ticket',
90 Requestor => 'The requestor of a ticket',
91 Cc => 'The CC of a ticket',
92 AdminCc => 'The administrative CC of a ticket',
97 # {{{ We need to build a hash of all rights, keyed by lower case names
99 #since you can't do case insensitive hash lookups
101 foreach $right (keys %QUEUERIGHTS) {
102 $LOWERCASERIGHTNAMES{lc $right}=$right;
104 foreach $right (keys %SYSTEMRIGHTS) {
105 $LOWERCASERIGHTNAMES{lc $right}=$right;
113 $self->{'table'} = "ACL";
114 return($self->SUPER::_Init(@_));
118 # {{{ sub LoadByValues
120 =head2 LoadByValues PARAMHASH
122 Load an ACE by specifying a paramhash with the following fields:
124 PrincipalId => undef,
125 PrincipalType => undef,
128 RightAppliesTo => undef,
134 my %args = (PrincipalId => undef,
135 PrincipalType => undef,
138 RightAppliesTo => undef,
141 $self->LoadByCols (PrincipalId => $args{'PrincipalId'},
142 PrincipalType => $args{'PrincipalType'},
143 RightName => $args{'RightName'},
144 RightScope => $args{'RightScope'},
145 RightAppliesTo => $args{'RightAppliesTo'}
148 #If we couldn't load it.
150 return (0, "ACE not found");
153 return ($self->Id, "ACE Loaded");
161 =head2 Create <PARAMS>
163 PARAMS is a parameter hash with the following elements:
165 PrincipalType => "Queue"|"User"
166 PrincipalId => an intentifier you can use to ->Load a user or group
167 RightName => the name of a right. in any case
168 RightScope => "System" | "Queue"
169 RightAppliesTo => a queue id or undef
175 my %args = ( PrincipalId => undef,
176 PrincipalType => undef,
179 RightAppliesTo => undef,
183 # {{{ Validate the principal
185 if ($args{'PrincipalType'} eq 'User') {
186 $princ_obj = new RT::User($RT::SystemUser);
189 elsif ($args{'PrincipalType'} eq 'Group') {
191 $princ_obj = new RT::Group($RT::SystemUser);
194 return (0, 'Principal type '.$args{'PrincipalType'} . ' is invalid.');
197 $princ_obj->Load($args{'PrincipalId'});
198 my $princ_id = $princ_obj->Id();
201 return (0, 'Principal '.$args{'PrincipalId'}.' not found.');
206 #TODO allow loading of queues by name.
209 if ($args{'RightScope'} eq 'System') {
211 unless ($self->CurrentUserHasSystemRight('ModifyACL')) {
212 $RT::Logger->error("Permission Denied.");
217 elsif ($args{'RightScope'} eq 'Queue') {
218 unless ($self->CurrentUserHasQueueRight( Queue => $args{'RightAppliesTo'},
219 Right => 'ModifyACL')) {
220 return (0, 'Permission Denied.');
227 #If it's not a scope we recognise, something scary is happening.
229 $RT::Logger->err("RT::ACE->Create got a scope it didn't recognize: ".
230 $args{'RightScope'}." Bailing. \n");
231 return(0,"System error. Unable to grant rights.");
236 # {{{ Canonicalize and check the right name
237 $args{'RightName'} = $self->CanonicalizeRightName($args{'RightName'});
239 #check if it's a valid RightName
240 if ($args{'RightScope'} eq 'Queue') {
241 unless (exists $QUEUERIGHTS{$args{'RightName'}}) {
242 return(0, 'Invalid right');
245 elsif ($args{'RightScope' eq 'System'}) {
246 unless (exists $SYSTEMRIGHTS{$args{'RightName'}}) {
247 return(0, 'Invalid right');
252 # Make sure the right doesn't already exist.
253 $self->LoadByCols (PrincipalId => $princ_id,
254 PrincipalType => $args{'PrincipalType'},
255 RightName => $args{'RightName'},
256 RightScope => $args {'RightScope'},
257 RightAppliesTo => $args{'RightAppliesTo'}
260 return (0, 'That user already has that right');
263 my $id = $self->SUPER::Create( PrincipalId => $princ_id,
264 PrincipalType => $args{'PrincipalType'},
265 RightName => $args{'RightName'},
266 RightScope => $args {'RightScope'},
267 RightAppliesTo => $args{'RightAppliesTo'}
272 return ($id, 'Right Granted');
275 $RT::Logger->err('System error. right not granted.');
276 return(0, 'System Error. right not granted');
294 unless ($self->CurrentUserHasRight('ModifyACL')) {
295 return (0, 'Permission Denied');
299 my ($val,$msg) = $self->SUPER::Delete(@_);
301 return ($val, 'ACE Deleted');
304 return (0, 'ACE could not be deleted');
310 # {{{ sub _BootstrapRight
312 =head2 _BootstrapRight
314 Grant a right with no error checking and no ACL. this is _only_ for
315 installation. If you use this routine without jesse@fsck.com's explicit
316 written approval, he will hunt you down and make you spend eternity
317 translating mozilla's code into FORTRAN or intercal.
321 sub _BootstrapRight {
325 my $id = $self->SUPER::Create( PrincipalId => $args{'PrincipalId'},
326 PrincipalType => $args{'PrincipalType'},
327 RightName => $args{'RightName'},
328 RightScope => $args {'RightScope'},
329 RightAppliesTo => $args{'RightAppliesTo'}
336 $RT::Logger->err('System error. right not granted.');
344 # {{{ sub CanonicalizeRightName
346 =head2 CanonicalizeRightName <RIGHT>
348 Takes a queue or system right name in any case and returns it in
349 the correct case. If it's not found, will return undef.
353 sub CanonicalizeRightName {
357 if (exists $LOWERCASERIGHTNAMES{"$right"}) {
358 return ($LOWERCASERIGHTNAMES{"$right"});
367 # {{{ sub QueueRights
371 Returns a hash of all the possible rights at the queue scope
376 return (%QUEUERIGHTS);
381 # {{{ sub SystemRights
385 Returns a hash of all the possible rights at the system scope
390 return (%SYSTEMRIGHTS);
396 # {{{ sub _Accessible
401 PrincipalId => 'read/write',
402 PrincipalType => 'read/write',
403 RightName => 'read/write',
404 RightScope => 'read/write',
405 RightAppliesTo => 'read/write'
407 return($self->SUPER::_Accessible(@_, %Cols));
411 # {{{ sub AppliesToObj
415 If the AppliesTo is a queue, returns the queue object. If it's
416 the system object, returns undef. If the user has no rights, returns undef.
422 if ($self->RightScope eq 'Queue') {
423 my $appliesto_obj = new RT::Queue($self->CurrentUser);
424 $appliesto_obj->Load($self->RightAppliesTo);
425 return($appliesto_obj);
427 elsif ($self->RightScope eq 'System') {
431 $RT::Logger->warning("$self -> AppliesToObj called for an object ".
432 "of an unknown scope:" . $self->RightScope);
439 # {{{ sub PrincipalObj
443 If the AppliesTo is a group, returns the group object.
444 If the AppliesTo is a user, returns the user object.
445 Otherwise, it logs a warning and returns undef.
453 if ($self->PrincipalType eq 'Group') {
455 $princ_obj = new RT::Group($self->CurrentUser);
457 elsif ($self->PrincipalType eq 'User') {
458 $princ_obj = new RT::User($self->CurrentUser);
461 $RT::Logger->warning("$self -> PrincipalObj called for an object ".
462 "of an unknown principal type:" .
463 $self->PrincipalType ."\n");
467 $princ_obj->Load($self->PrincipalId);
474 # {{{ ACL related methods
480 return (0, "ACEs can only be created and deleted.");
490 unless ($self->CurrentUserHasRight('ShowACL')) {
494 return ($self->__Value(@_));
500 # {{{ sub CurrentUserHasQueueRight
502 =head2 CurrentUserHasQueueRight ( Queue => QUEUEID, Right => RIGHTNANAME )
504 Check to see whether the current user has the specified right for the specified queue.
508 sub CurrentUserHasQueueRight {
510 my %args = (Queue => undef,
514 return ($self->HasRight( Right => $args{'Right'},
515 Principal => $self->CurrentUser->UserObj,
516 Queue => $args{'Queue'}));
521 # {{{ sub CurrentUserHasSystemRight
522 =head2 CurrentUserHasSystemRight RIGHTNAME
524 Check to see whether the current user has the specified right for the 'system' scope.
528 sub CurrentUserHasSystemRight {
531 return ($self->HasRight( Right => $right,
532 Principal => $self->CurrentUser->UserObj,
540 # {{{ sub CurrentUserHasRight
542 =item CurrentUserHasRight RIGHT
543 Takes a rightname as a string.
545 Helper menthod for HasRight. Presets Principal to CurrentUser then
550 sub CurrentUserHasRight {
553 return ($self->HasRight( Principal => $self->CurrentUser->UserObj,
564 Takes a param-hash consisting of "Right" and "Principal" Principal is
565 an RT::User object or an RT::CurrentUser object. "Right" is a textual
566 Right string that applies to KeywordSelects
572 my %args = ( Right => undef,
578 #If we're explicitly specifying a queue, as we need to do on create
579 if (defined $args{'Queue'}) {
580 return ($args{'Principal'}->HasQueueRight(Right => $args{'Right'},
581 Queue => $args{'Queue'}));
583 #else if we're specifying to check a system right
584 elsif ((defined $args{'System'}) and (defined $args{'Right'})) {
585 return( $args{'Principal'}->HasSystemRight( $args{'Right'} ));
588 elsif ($self->__Value('RightScope') eq 'System') {
589 return $args{'Principal'}->HasSystemRight($args{'Right'});
591 elsif ($self->__Value('RightScope') eq 'Queue') {
592 return $args{'Principal'}->HasQueueRight( Queue => $self->__Value('RightAppliesTo'),
593 Right => $args{'Right'} );
596 $RT::Logger->warning("$self: Trying to check an acl for a scope we ".
597 "don't understand:" . $self->__Value('RightScope') ."\n");
614 =head1 Out of date docs
616 =head2 Table Structure
618 PrincipalType, PrincipalId, Right,Scope,AppliesTo
620 =head1 The docs are out of date. so you know.
624 Scope is the scope of the right granted, not the granularity of the grant.
625 For example, Queue and Ticket rights are both granted for a "queue."
626 Rights with a scope of 'System' don't have an AppliesTo. (They're global).
627 Rights with a scope of "Queue" are rights that act on a queue.
628 Rights with a scope of "System" are rights that act on some other aspect
640 =head2 Queue rights that apply to a ticket within a queue
642 Create Ticket in <queue>
645 Principals: <user> <group>
646 Display Ticket Summary in <queue>
649 Principals: <user> <group> Owner Requestor Cc AdminCc
651 Display Ticket History <queue>
654 Principals: <user> <group> Owner Requestor Cc AdminCc
656 Display Ticket Private Comments <queue>
659 Principals: <user> <group> Owner Requestor Cc AdminCc
661 Reply to Ticket in <queue>
664 Principals: <user> <group> Owner Requestor Cc AdminCc
666 Comment on Ticket in <queue>
669 Principals: <user> <group> Owner Requestor Cc AdminCc
671 Modify Ticket in <queue>
674 Principals: <user> <group> Owner Requestor Cc AdminCc
676 Delete Tickets in <queue>
679 Principals: <user> <group> Owner Requestor Cc AdminCc
682 =head2 Queue Rights that apply to a whole queue
684 These rights can only be granted to "real people"
686 List Tickets in <queue>
689 Principals: <user> <group>
691 Know that <queue> exists
694 Principals: <user> <group>
696 Display queue settings
699 Principals: <user> <group>
701 Modify Queue Watchers for <queue>
703 Name: ModifyQueueWatchers
704 Principals: <user> <group>
706 Modify Queue Attributes for <queue>
709 Principals: <user> <group>
711 Modify Queue ACL for queue <queue>
714 Principals: <user> <group>
717 =head2 Rights that apply to the System scope
724 Principals: <user> <group>
728 Principals: <user> <group>
733 Principals: <user> <group>
738 Principals: <user> <group>
743 Principals: <user> <group>
747 Principals: <user> <group>
751 Name: BrowseUsers (NOT IMPLEMENTED in 2.0)
752 Principals: <user> <group>
757 Principals: <user> <group>
762 Principals: <user> <group>
764 =head1 The Principal Side of the ACE
766 =head2 PrincipalTypes,PrincipalIds in our Neighborhood