X-Git-Url: http://git.freeside.biz/gitweb/?a=blobdiff_plain;f=rt%2Flib%2FRT%2FScrips_Overlay.pm;h=5dd83b72ca9636e21ab82bbe157e572b57556e15;hb=804bcfa0ca42ec19595d0cf79d010e66a09a2109;hp=64a8437a001411b9525a79cf13c81e88132e561c;hpb=ef20b2b6b1feb47ad02b5ff7525f1a0fd11d0fa4;p=freeside.git diff --git a/rt/lib/RT/Scrips_Overlay.pm b/rt/lib/RT/Scrips_Overlay.pm index 64a8437a0..5dd83b72c 100644 --- a/rt/lib/RT/Scrips_Overlay.pm +++ b/rt/lib/RT/Scrips_Overlay.pm @@ -1,40 +1,40 @@ # BEGIN BPS TAGGED BLOCK {{{ -# +# # COPYRIGHT: -# -# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC -# -# +# +# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC +# +# # (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 # been provided with this software, but in any event can be snarfed # from www.gnu.org. -# +# # This work is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. -# +# # 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. -# -# +# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html. +# +# # CONTRIBUTION SUBMISSION POLICY: -# +# # (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 @@ -43,8 +43,9 @@ # 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 NAME RT::Scrips - a collection of RT Scrip objects @@ -59,11 +60,6 @@ =head1 METHODS -=begin testing - -ok (require RT::Scrips); - -=end testing =cut @@ -189,12 +185,29 @@ 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 + ." on txn #". $self->{'TransactionObj'}->id + ." of ticket #". $self->{'TicketObj'}->id + ); $scrip->Commit( TicketObj => $self->{'TicketObj'}, TransactionObj => $self->{'TransactionObj'} ); } + + # Apply the bandaid. + $self->_RestoreCurrentUser( TicketObj => $self->{TicketObj} ) if $self->{TicketObj}; } @@ -215,6 +228,12 @@ 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'}, @@ -228,21 +247,29 @@ sub Prepare { #Iterate through each script and check it's applicability. while ( my $scrip = $self->Next() ) { - next unless ( $scrip->IsApplicable( TicketObj => $self->{'TicketObj'}, TransactionObj => $self->{'TransactionObj'} - ) ); + ) ) { + $RT::Logger->debug("Skipping Scrip #".$scrip->Id." because it isn't applicable"); + next; + } #If it's applicable, prepare and commit it - next unless ( $scrip->Prepare( TicketObj => $self->{'TicketObj'}, TransactionObj => $self->{'TransactionObj'} - ) ); + ) ) { + $RT::Logger->debug("Skipping Scrip #".$scrip->Id." because it didn't Prepare"); + next; + } push @{$self->{'prepared_scrips'}}, $scrip; } + # Apply the bandaid. + $self->_RestoreCurrentUser( TicketObj => $args{TicketObj} ) if $args{TicketObj}; + + return (@{$self->Prepared}); }; @@ -259,6 +286,39 @@ 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}); + +} # {{{ sup _SetupSourceObjects @@ -282,13 +342,20 @@ sub _SetupSourceObjects { TransactionObj => undef, @_ ); - if ( ( $self->{'TicketObj'} = $args{'TicketObj'} ) ) { + + 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 ); } else { $self->{'TicketObj'} = RT::Ticket->new( $self->CurrentUser ); $self->{'TicketObj'}->Load( $args{'Ticket'} ) - || $RT::Logger->err("$self couldn't load ticket $args{'Ticket'}\n"); + || $RT::Logger->err("$self couldn't load ticket $args{'Ticket'}"); } if ( ( $self->{'TransactionObj'} = $args{'TransactionObj'} ) ) { @@ -297,7 +364,7 @@ sub _SetupSourceObjects { else { $self->{'TransactionObj'} = RT::Transaction->new( $self->CurrentUser ); $self->{'TransactionObj'}->Load( $args{'Transaction'} ) - || $RT::Logger->err( "$self couldn't load transaction $args{'Transaction'}\n"); + || $RT::Logger->err( "$self couldn't load transaction $args{'Transaction'}"); } } @@ -360,9 +427,18 @@ sub _FindScrips { ); # Promise some kind of ordering - $self->OrderBy( FIELD => 'description' ); + $self->OrderBy( FIELD => 'Description' ); + + # we call Count below, but later we always do search + # so just do search and get count from results + $self->_DoSearch if $self->{'must_redo_search'}; - $RT::Logger->debug("Found ".$self->Count. " scrips"); + $RT::Logger->debug( + "Found ". $self->Count ." scrips for $args{'Stage'} stage" + ." with applicable type(s) $args{'Type'}" + ." for txn #".$self->{TransactionObj}->Id + ." on ticket #".$self->{TicketObj}->Id + ); } # }}}