#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
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
TransactionObj => $self->{'TransactionObj'} );
}
- # Apply the bandaid.
- $self->_RestoreCurrentUser( TicketObj => $self->{TicketObj} ) if $self->{TicketObj};
}
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'},
}
- # Apply the bandaid.
- $self->_RestoreCurrentUser( TicketObj => $args{TicketObj} ) if $args{TicketObj};
-
-
return (@{$self->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
@_ );
- 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 );