-# BEGIN LICENSE BLOCK
+# BEGIN BPS TAGGED BLOCK {{{
#
-# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+# COPYRIGHT:
+#
+# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+# <jesse@bestpractical.com>
#
-# (Except where explictly superceded by other copyright notices)
+# (Except where explicitly superseded by other copyright notices)
+#
+#
+# LICENSE:
#
# This work is made available to you under the terms of Version 2 of
# the GNU General Public License. A copy of that license should have
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
-# Unless otherwise specified, all modifications, corrections or
-# extensions to this work which alter its source code become the
-# property of Best Practical Solutions, LLC when submitted for
-# inclusion in the work.
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301 or visit their web page on the internet at
+# http://www.gnu.org/copyleft/gpl.html.
+#
#
+# CONTRIBUTION SUBMISSION POLICY:
#
-# END LICENSE BLOCK
+# (The following paragraph is not intended to limit the rights granted
+# to you to modify and distribute this software under the terms of
+# the GNU General Public License and is only of importance to you if
+# you choose to contribute your changes and enhancements to the
+# community by submitting them to Best Practical Solutions, LLC.)
+#
+# By intentionally submitting any modifications, corrections or
+# derivatives to this work, or any other work intended for use with
+# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+# you are the copyright holder for those contributions and you grant
+# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+# royalty-free, perpetual, license to use, copy, create derivative
+# works based on those contributions, and sublicense and distribute
+# those contributions and any derivatives thereof.
+#
+# END BPS TAGGED BLOCK }}}
=head1 SYNOPSIS
use RT::ACE;
=cut
+
+package RT::ACE;
+
use strict;
no warnings qw(redefine);
use RT::Principals;
OR
- ObjectType => undef,
- ObjectId => undef
+ ObjectType => undef,
+ ObjectId => undef
=cut
);
}
- my ($object_type, $object_id);
-
- if ($args{'Object'} && UNIVERSAL::can($args{'Object'},'id')) {
- $object_type = ref($args{'Object'});
- $object_id = $args{'Object'}->id;
- } elsif ($args{'ObjectId'} || $args{'ObjectType'}) {
- $object_type = $args{'ObjectType'};
- $object_id = $args{'ObjectId'};
- } else {
- return ( 0, $self->loc("System error. Right not granted.") );
+ my ($object, $object_type, $object_id) = $self->_ParseObjectArg( %args );
+ unless( $object ) {
+ return ( 0, $self->loc("System error. Right not granted.") );
}
$self->LoadByCols( PrincipalId => $princ_obj->Id,
ObjectType => the type of the object in question (ref ($object))
ObjectId => the id of the object in question $object->Id
+
+
+ Returns a tuple of (STATUS, MESSAGE); If the call succeeded, STATUS is true. Otherwise it's false.
+
+
+
=cut
sub Create {
my %args = ( PrincipalId => undef,
PrincipalType => undef,
RightName => undef,
- Object => $RT::System,
+ Object => undef,
@_ );
+ #if we haven't specified any sort of right, we're talking about a global right
+ if (!defined $args{'Object'} && !defined $args{'ObjectId'} && !defined $args{'ObjectType'}) {
+ $args{'Object'} = $RT::System;
+ }
+ ($args{'Object'}, $args{'ObjectType'}, $args{'ObjectId'}) = $self->_ParseObjectArg( %args );
+ unless( $args{'Object'} ) {
+ return ( 0, $self->loc("System error. Right not granted.") );
+ }
# {{{ Validate the principal
my $princ_obj;
# }}}
-
- if ($args{'Object'} && ($args{'ObjectId'} || $args{'ObjectType'})) {
- use Carp;
- $RT::Logger->crit(Carp::cluck("ACE::Create called with an ObjectType or an ObjectId"));
- }
-
-
-
- unless ($args{'Object'} && UNIVERSAL::can($args{'Object'},'id')) {
- return ( 0, $self->loc("System error. Right not granted.") );
- }
# {{{ Check the ACL
if (ref( $args{'Object'}) eq 'RT::Group' ) {
}
}
- unless ( $args{'RightName'} ) {
- return ( 0, $self->loc('Invalid right') );
- }
# }}}
# Make sure the right doesn't already exist.
$self->LoadByCols( PrincipalId => $princ_obj->id,
PrincipalType => $args{'PrincipalType'},
RightName => $args{'RightName'},
- ObjectType => ref($args{'Object'}),
- ObjectId => $args{'Object'}->id,
+ ObjectType => $args{'ObjectType'},
+ ObjectId => $args{'ObjectId'},
DelegatedBy => 0,
DelegatedFrom => 0 );
if ( $self->Id ) {
DelegatedFrom => 0 );
#Clear the key cache. TODO someday we may want to just clear a little bit of the keycache space.
- RT::Principal->_InvalidateACLCache();
+ RT::Principal->InvalidateACLCache();
if ( $id > 0 ) {
return ( $id, $self->loc('Right Granted') );
#Clear the key cache. TODO someday we may want to just clear a little bit of the keycache space.
# TODO what about the groups key cache?
- RT::Principal->_InvalidateACLCache();
+ RT::Principal->InvalidateACLCache();
if ( $id > 0 ) {
return ( $id, $self->loc('Right Delegated') );
while ( my $delegated_ace = $delegated_from_this->Next ) {
( $delete_succeeded, $submsg ) =
$delegated_ace->_Delete( InsideTransaction => 1 );
- last if ($delete_succeeded);
+ last unless ($delete_succeeded);
}
unless ($delete_succeeded) {
my ( $val, $msg ) = $self->SUPER::Delete(@_);
- #Clear the key cache. TODO someday we may want to just clear a little bit of the keycache space.
- # TODO what about the groups key cache?
- RT::Principal->_InvalidateACLCache();
+ # If we're revoking delegation rights (see above), we may need to
+ # revoke all rights delegated by the recipient.
+ if ($val and ($self->RightName() eq 'DelegateRights' or
+ $self->RightName() eq 'SuperUser')) {
+ $val = $self->PrincipalObj->_CleanupInvalidDelegations( InsideTransaction => 1 );
+ }
if ($val) {
+ #Clear the key cache. TODO someday we may want to just clear a little bit of the keycache space.
+ # TODO what about the groups key cache?
+ RT::Principal->InvalidateACLCache();
$RT::Handle->Commit() unless $InsideTransaction;
return ( $val, $self->loc('Right revoked') );
}
- else {
- $RT::Handle->Rollback() unless $InsideTransaction;
- return ( 0, $self->loc('Right could not be revoked') );
- }
+
+ $RT::Handle->Rollback() unless $InsideTransaction;
+ return ( 0, $self->loc('Right could not be revoked') );
}
# }}}
else {
$RT::Logger->warning( "$self -> Object called for an object "
. "of an unknown type:"
- . $self->ObjectType );
+ . $self->__Value('ObjectType') );
return (undef);
}
}
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 " . $self->__Value('ObjectId') );
- return ( 0, $self->loc('System error. Right not granted.') );
+ $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'} && !UNIVERSAL::can($args{'Object'},'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 ();
+ }
+}
+
+
# }}}
1;