+=head2 _BootstrapCreate
+
+Grant a right with no error checking and no ACL. this is _only_ for
+installation. If you use this routine without the author's explicit
+written approval, he will hunt you down and make you spend eternity
+translating mozilla's code into FORTRAN or intercal.
+
+If you think you need this routine, you've mistaken.
+
+=cut
+
+sub _BootstrapCreate {
+ my $self = shift;
+ my %args = (@_);
+
+ # When bootstrapping, make sure we get the _right_ users
+ if ( $args{'UserId'} ) {
+ my $user = RT::User->new( $self->CurrentUser );
+ $user->Load( $args{'UserId'} );
+ delete $args{'UserId'};
+ $args{'PrincipalId'} = $user->PrincipalId;
+ $args{'PrincipalType'} = 'User';
+ }
+
+ my $id = $self->SUPER::Create(%args);
+
+ if ( $id > 0 ) {
+ return ($id);
+ }
+ else {
+ $RT::Logger->err('System error. right not granted.');
+ return (undef);
+ }
+
+}
+
+
+
+sub RightName {
+ my $self = shift;
+ my $val = $self->_Value('RightName');
+ return $val unless $val;
+
+ my $available = $self->Object->AvailableRights;
+ foreach my $right ( keys %$available ) {
+ return $right if $val eq $self->CanonicalizeRightName($right);
+ }
+
+ $RT::Logger->error("Invalid right. Couldn't canonicalize right '$val'");
+ return $val;
+}
+
+=head2 CanonicalizeRightName <RIGHT>
+
+Takes a queue or system right name in any case and returns it in
+the correct case. If it's not found, will return undef.
+
+=cut
+
+sub CanonicalizeRightName {
+ my $self = shift;
+ return $LOWERCASERIGHTNAMES{ lc shift };
+}
+
+
+
+
+=head2 Object
+
+If the object this ACE applies to is a queue, returns the queue object.
+If the object this ACE applies to is a group, returns the group object.
+If it's the system object, returns undef.
+
+If the user has no rights, returns undef.
+
+=cut
+
+
+
+
+sub Object {
+ my $self = shift;
+
+ my $appliesto_obj;
+
+ if ($self->__Value('ObjectType') && $OBJECT_TYPES{$self->__Value('ObjectType')} ) {
+ $appliesto_obj = $self->__Value('ObjectType')->new($self->CurrentUser);
+ unless (ref( $appliesto_obj) eq $self->__Value('ObjectType')) {
+ return undef;
+ }
+ $appliesto_obj->Load( $self->__Value('ObjectId') );
+ return ($appliesto_obj);
+ }
+ else {
+ $RT::Logger->warning( "$self -> Object called for an object "
+ . "of an unknown type:"
+ . $self->__Value('ObjectType') );
+ return (undef);
+ }
+}
+
+
+
+=head2 PrincipalObj
+
+Returns the RT::Principal object for this ACE.
+
+=cut
+
+sub PrincipalObj {
+ my $self = shift;
+
+ my $princ_obj = RT::Principal->new( $self->CurrentUser );
+ $princ_obj->Load( $self->__Value('PrincipalId') );
+
+ unless ( $princ_obj->Id ) {
+ $RT::Logger->err(
+ "ACE " . $self->Id . " couldn't load its principal object" );
+ }
+ return ($princ_obj);
+
+}
+
+
+
+
+sub _Set {
+ my $self = shift;
+ return ( 0, $self->loc("ACEs can only be created and deleted.") );
+}
+
+
+
+sub _Value {
+ my $self = shift;
+
+ if ( $self->PrincipalObj->IsGroup
+ && $self->PrincipalObj->Object->HasMemberRecursively(
+ $self->CurrentUser->PrincipalObj
+ )
+ ) {
+ return ( $self->__Value(@_) );
+ }
+ elsif ( $self->CurrentUser->HasRight(Right => 'ShowACL', Object => $self->Object) ) {
+ return ( $self->__Value(@_) );
+ }
+ else {
+ return undef;
+ }
+}
+
+
+
+
+
+=head2 _CanonicalizePrincipal (PrincipalId, PrincipalType)
+
+Takes a principal id and a principal type.
+
+If the principal is a user, resolves it to the proper acl equivalence group.
+Returns a tuple of (RT::Principal, PrincipalType) for the principal we really want to work with
+
+=cut
+
+sub _CanonicalizePrincipal {
+ my $self = shift;
+ my $princ_id = shift;
+ my $princ_type = shift || '';
+
+ my $princ_obj = RT::Principal->new(RT->SystemUser);
+ $princ_obj->Load($princ_id);
+
+ unless ( $princ_obj->Id ) {
+ use Carp;
+ $RT::Logger->crit(Carp::longmess);
+ $RT::Logger->crit("Can't load a principal for id $princ_id");
+ return ( $princ_obj, undef );
+ }
+
+ # Rights never get granted to users. they get granted to their
+ # ACL equivalence groups
+ if ( $princ_type eq 'User' ) {
+ my $equiv_group = RT::Group->new( $self->CurrentUser );
+ $equiv_group->LoadACLEquivalenceGroup($princ_obj);
+ unless ( $equiv_group->Id ) {
+ $RT::Logger->crit( "No ACL equiv group for princ " . $princ_obj->id );
+ return ( RT::Principal->new(RT->SystemUser), undef );
+ }
+ $princ_obj = $equiv_group->PrincipalObj();
+ $princ_type = 'Group';
+
+ }
+ return ( $princ_obj, $princ_type );
+}
+
+sub _ParseObjectArg {
+ my $self = shift;
+ my %args = ( Object => undef,
+ ObjectId => undef,
+ ObjectType => undef,
+ @_ );
+
+ if( $args{'Object'} && ($args{'ObjectId'} || $args{'ObjectType'}) ) {
+ $RT::Logger->crit( "Method called with an ObjectType or an ObjectId and Object args" );
+ return ();
+ } elsif( $args{'Object'} && ref($args{'Object'}) && !$args{'Object'}->can('id') ) {
+ $RT::Logger->crit( "Method called called Object that has no id method" );
+ return ();
+ } elsif( $args{'Object'} ) {
+ my $obj = $args{'Object'};
+ return ($obj, ref $obj, $obj->id);
+ } elsif ( $args{'ObjectType'} ) {
+ my $obj = $args{'ObjectType'}->new( $self->CurrentUser );
+ $obj->Load( $args{'ObjectId'} );
+ return ($obj, ref $obj, $obj->id);
+ } else {
+ $RT::Logger->crit( "Method called with wrong args" );
+ return ();
+ }
+}
+
+
+# }}}
+
+
+