X-Git-Url: http://git.freeside.biz/gitweb/?a=blobdiff_plain;f=rt%2Flib%2FRT%2FScrips.pm;h=4649885f70e41a7a293baf06018740dba5affe64;hb=dd620f18b9a9dd01d4a21de9fb4f1194ba6d003d;hp=13a4b7d7d5946381eb625150d1eb462c257001bc;hpb=43a06151e47d2c59b833cbd8c26d97865ee850b6;p=freeside.git diff --git a/rt/lib/RT/Scrips.pm b/rt/lib/RT/Scrips.pm index 13a4b7d7d..4649885f7 100755 --- a/rt/lib/RT/Scrips.pm +++ b/rt/lib/RT/Scrips.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2015 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) @@ -114,35 +114,19 @@ sub LimitToGlobal { } -# {{{ sub Next +=head2 AddRecord -=head2 Next - -Returns the next scrip that this user can see. +Overrides the collection to ensure that only scrips the user can see are +returned. =cut - -sub Next { + +sub AddRecord { my $self = shift; - - - my $Scrip = $self->SUPER::Next(); - if ((defined($Scrip)) and (ref($Scrip))) { - - if ($Scrip->CurrentUserHasRight('ShowScrips')) { - return($Scrip); - } - - #If the user doesn't have the right to show this scrip - else { - return($self->Next()); - } - } - #if there never was any scrip - else { - return(undef); - } - + my ($record) = @_; + + return unless $record->CurrentUserHasRight('ShowScrips'); + return $self->SUPER::AddRecord( $record ); } =head2 Apply @@ -178,16 +162,6 @@ Commit all of this object's prepared scrips sub Commit { my $self = shift; - # RT::Scrips->_SetupSourceObjects will clobber - # the CurrentUser, but we need to keep this ticket - # so that the _TransactionBatch cache is maintained - # and doesn't run twice. sigh. - $self->_StashCurrentUser( TicketObj => $self->{TicketObj} ) if $self->{TicketObj}; - - #We're really going to need a non-acled ticket for the scrips to work - $self->_SetupSourceObjects( TicketObj => $self->{'TicketObj'}, - TransactionObj => $self->{'TransactionObj'} ); - foreach my $scrip (@{$self->Prepared}) { $RT::Logger->debug( "Committing scrip #". $scrip->id @@ -199,8 +173,6 @@ sub Commit { TransactionObj => $self->{'TransactionObj'} ); } - # Apply the bandaid. - $self->_RestoreCurrentUser( TicketObj => $self->{TicketObj} ) if $self->{TicketObj}; } @@ -221,12 +193,6 @@ sub Prepare { Type => undef, @_ ); - # RT::Scrips->_SetupSourceObjects will clobber - # the CurrentUser, but we need to keep this ticket - # so that the _TransactionBatch cache is maintained - # and doesn't run twice. sigh. - $self->_StashCurrentUser( TicketObj => $args{TicketObj} ) if $args{TicketObj}; - #We're really going to need a non-acled ticket for the scrips to work $self->_SetupSourceObjects( TicketObj => $args{'TicketObj'}, Ticket => $args{'Ticket'}, @@ -259,10 +225,6 @@ sub Prepare { } - # Apply the bandaid. - $self->_RestoreCurrentUser( TicketObj => $args{TicketObj} ) if $args{TicketObj}; - - return (@{$self->Prepared}); }; @@ -279,40 +241,6 @@ sub Prepared { return ($self->{'prepared_scrips'} || []); } -=head2 _StashCurrentUser TicketObj => RT::Ticket - -Saves aside the current user of the original ticket that was passed to these scrips. -This is used to make sure that we don't accidentally leak the RT_System current user -back to the calling code. - -=cut - -sub _StashCurrentUser { - my $self = shift; - my %args = @_; - - $self->{_TicketCurrentUser} = $args{TicketObj}->CurrentUser; -} - -=head2 _RestoreCurrentUser TicketObj => RT::Ticket - -Uses the current user saved by _StashCurrentUser to reset a Ticket object -back to the caller's current user and avoid leaking an RT_System ticket to -calling code. - -=cut - -sub _RestoreCurrentUser { - my $self = shift; - my %args = @_; - unless ( $self->{_TicketCurrentUser} ) { - RT->Logger->debug("Called _RestoreCurrentUser without a stashed current user object"); - return; - } - $args{TicketObj}->CurrentUser($self->{_TicketCurrentUser}); - -} - =head2 _SetupSourceObjects { TicketObj , Ticket, Transaction, TransactionObj } Setup a ticket and transaction for this Scrip collection to work with as it runs through the @@ -334,14 +262,22 @@ sub _SetupSourceObjects { @_ ); - if ( $self->{'TicketObj'} = $args{'TicketObj'} ) { - # This clobbers the passed in TicketObj by turning it into one - # whose current user is RT_System. Anywhere in the Web UI - # currently calling into this is thus susceptable to a privilege - # leak; the only current call site is ->Apply, which bandaids - # over the top of this by re-asserting the CurrentUser - # afterwards. - $self->{'TicketObj'}->CurrentUser( $self->CurrentUser ); + if ( $args{'TicketObj'} ) { + # This loads a clean copy of the Ticket object to ensure that we + # don't accidentally escalate the privileges of the passed in + # ticket (this function can be invoked from the UI). + # We copy the TransactionBatch transactions so that Scrips + # running against the new Ticket will have access to them. We + # use RanTransactionBatch to guard against running + # TransactionBatch Scrips more than once. + $self->{'TicketObj'} = RT::Ticket->new( $self->CurrentUser ); + $self->{'TicketObj'}->Load( $args{'TicketObj'}->Id ); + if ( $args{'TicketObj'}->TransactionBatch ) { + # try to ensure that we won't infinite loop if something dies, triggering DESTROY while + # we have the _TransactionBatch objects; + $self->{'TicketObj'}->RanTransactionBatch(1); + $self->{'TicketObj'}->{'_TransactionBatch'} = $args{'TicketObj'}->{'_TransactionBatch'}; + } } else { $self->{'TicketObj'} = RT::Ticket->new( $self->CurrentUser );