%# BEGIN BPS TAGGED BLOCK {{{ %# %# COPYRIGHT: %# %# This software is Copyright (c) 1996-2022 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/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 %# 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 }}} <& /RTIR/Elements/Header, Title => $Title &> <& /Elements/Tabs &> <& /Elements/ListActions, actions => \@finalresults &>
% if ( $ARGS{'TestAddresses'} && keys %$addrhash ) { <&| /Widgets/TitleBox, contentbg => "#cccccc", title => 'Address test results' &>
% } <&| /Widgets/TitleBox, contentbg => "#cccccc", title => loc("Identify Recipients") &> % my $height = RT->Config->Get('MessageBoxHeight', $session{'CurrentUser'} ) || 15; % my $wrap = RT->Config->Get('MessageBoxWrap', $session{'CurrentUser'} ) || 'SOFT'; % if ($loop eq 'IP') { % } else { % }
WHOIS: <& Elements/SelectWhoisServer, Name => 'server', Default => $server &>
<&|/l&>Contact Field:
<&|/l&>IP Addresses:
arg: _IP_
<&|/l&>Addresses:
arg: _ADDR_
<&|/l&>Template: <& /Admin/Scrips/Elements/SelectTemplate, Default => $ARGS{'Template'} || 0, Queue => $investigationq &>
<&|/l&>Argument:
% if ($loop eq "IP") { <& /Elements/Submit, Name => "TestAddresses", Caption => loc("Test email addresses"), Label => loc("Test")&> % }
<&| /Widgets/TitleBox, contentbg => "#cccccc", title => loc("Message information") &> % if (!$incidentid) { <& /RTIR/Incident/Elements/Create, Title => $Title, QueueObj => $incidentq, %ARGS &> % } else { % }
<&|/l&>Owner: <%$session{'CurrentUser'}->Name%>
<&|/l&>Subject:
<&|/l&>Message: % if (exists $ARGS{Content}) { <& /Elements/MessageBox, Name=>"Content", Default=>$ARGS{Content}, %ARGS&> % } else { <& /Elements/MessageBox, Name=>"Content", %ARGS &> % }
<& /Elements/Submit, Name => "SubmitAction", Caption => loc("Create the Incidents and Investigations"), Label => loc("Create")&>
<%INIT> my ($Incident, $Ticket); my @finalresults; my $Title; if ( $incidentid ) { $Title = loc("Scripted Action: Create Investigations for Incident #[_1]", $incidentid); } else { $Title = loc("Scripted Action: Create Incidents and Investigations"); } # XXX: what's this? foreach my $arg (keys %ARGS) { if ($arg =~ /^Requestorbox-(.+)/) { $ARGS{'Addresses'} .= $1 . "\r"; } } if ($incidentid) { $Incident = RT::Ticket->new($session{'CurrentUser'}); $Incident->Load($incidentid); if (!exists $ARGS{Content}) { my $Transactions = $Incident->Transactions; if ($Transactions) { $ARGS{Content} = $m->scomp("/RTIR/Elements/TransactionData", Transactions => $Transactions, Type => 'messages', Include => {'Create', 'Correspond'}, QuoteText => 1); $ARGS{Content} =~ s/\>/>/g; } } } $ARGS{'loop'} = $loop if !defined $ARGS{'loop'}; # Load the Incidents Queue my $incidentq = RT::Queue->new($session{'CurrentUser'}); unless ( $incidentq->Load('Incidents') ) { Abort('Queue not found'); } # Load the Investigations Queue my $investigationq = RT::Queue->new($session{'CurrentUser'}); unless ($investigationq->Load('Investigations')) { Abort('Queue not found'); } # Load the Incident Reports Queue my $reportq = RT::Queue->new($session{'CurrentUser'}); unless ($reportq->Load('Incident Reports')) { Abort('Queue not found'); } my $addrhash = {}; if ( $ARGS{'SubmitAction'} || $ARGS{'TestAddresses'} ) { my $list = $loop eq 'IP'? $ARGS{'IPs'} : $ARGS{'Addresses'}; $list =~ s/\r+\n/\n/g; $list =~ s/^\s+//; $list =~ s/\s+$//; # replace newlines with commas (for use with parse_csv) $list =~ s/\n/,/g; if ($loop eq 'address') { my @addrs = parse_csv( $list ); my $i = 0; foreach my $addr (@addrs) { $addrhash->{$i} = {Address => $addr, IP => loc("IP_UNKNOWN")}; $i++; } } elsif ($loop eq 'IP') { my @ips = parse_csv( $list ); my $i = 0; foreach my $ip (@ips) { my ($a, $err); $m->comp('Elements/GetEmailFromIP', server => $ARGS{'server'}, q => $ip, field => $ARGS{'field'}, address => \$a, error => \$err, ); if ($err) { # no addresses push @finalresults, loc("Couldn't get address for [_1]: [_2]", $ip, $err); next; } $addrhash->{$i} = {Address => $a, IP => $ip}; $i++; } } } ProcessAttachments(ARGSRef => \%ARGS); if ( $ARGS{'SubmitAction'} ) { # if the subject contains _ADDR_ or _IP_ we will substitute my $original_subject = $ARGS{'Subject'}; my $original_content = $ARGS{'Content'}; foreach my $key ( keys %$addrhash ) { my $addr = $addrhash->{$key}->{'Address'}; my $ip = $addrhash->{$key}->{'IP'}; $ARGS{'Subject'} = $original_subject; $ARGS{'Content'} = $original_content; for (qw/Subject Content/) { $ARGS{$_} =~ s/_ADDR_/$addr/g; $ARGS{$_} =~ s/_IP_/$ip/g; } if ( $addr eq loc("ADDRESS_UNKNOWN") ) { # create an unlinked incident report unless ( $reportq->CurrentUserHasRight('CreateTicket') ) { Abort('You have no permission to create tickets in that queue.'); } my ($Ticket, @ChildActions) = CreateTicket( %ARGS, Queue => $reportq->Id, KeepAttachments => 1 ); unless ( $Ticket ) { Abort("Couldn't create an Incident Report"); } unless ( $Ticket->CurrentUserHasRight('ShowTicket') ) { Abort("No permission to view newly created ticket #".$Ticket->id."."); } push @finalresults, @ChildActions; next; } if ( !$Incident || !$incidentid ) { # create the Incident unless ( $incidentq->CurrentUserHasRight('CreateTicket') ) { Abort('You have no permission to create tickets in that queue.'); } my @IncidentActions; ($Incident, @IncidentActions) = CreateTicket( %ARGS, Queue => $incidentq->Id, ); unless ( $Incident ) { Abort("Couldn't create an Incident"); } unless ( $Incident->CurrentUserHasRight('ShowTicket') ) { Abort("No permission to view newly created ticket #".$Incident->id."."); } push @finalresults, @IncidentActions; } # create the linked investigation unless ( $investigationq->CurrentUserHasRight('CreateTicket') ) { Abort('You have no permission to create tickets in that queue.'); } my ($Ticket, @ChildActions) = CreateTicket( %ARGS, Queue => $investigationq->Id, 'new-MemberOf' => $Incident->Id, Requestor => $addr, ); unless ( $Ticket ) { Abort("Couldn't launch an Investigation"); } unless ( $Ticket->CurrentUserHasRight('ShowTicket') ) { Abort("No permission to view newly created ticket #".$Ticket->id."."); } push @finalresults, @ChildActions; my $TemplateObj = RT::Template->new( $session{'CurrentUser'} ); if ( $ARGS{'Template'} ) { $TemplateObj->Load( $ARGS{'Template'} ); RT->Logger->error("Couldn't load template '$ARGS{'Template'}'") unless $TemplateObj->id; } my @updateresults; if ( $TemplateObj->id ) { # find the Create transaction, so we can pass it to the template my $transaction; while ( $transaction = $Ticket->Transactions->Next ) { last if $transaction->Type eq 'Create'; } # if the template's argument contains _ADDR_ or _IP_ # substitute appropriately my $arg = $ARGS{'TemplateArg'}; $arg =~ s/_ADDR_/$addr/g; $arg =~ s/_IP_/$ip/g; my ( $result, $message ) = $TemplateObj->Parse( Argument => $arg, TicketObj => $Ticket, TransactionObj => $transaction, ); unless ( $result ) { RT->Logger->error("Couldn't parse template: $message"); } # add the template's MIMEObj to the Attachments list $session{'Attachments'}{$ARGS{'Token'}} = { %{$session{'Attachments'}{$ARGS{'Token'}} || {}}, _Body => $TemplateObj->MIMEObj, }; # the content will be part of the template, if desired $ARGS{'UpdateContent'} = " "; @updateresults = ProcessUpdateMessage( TicketObj => $Ticket, ARGSRef => \%ARGS, ); } push @finalresults, map { loc("Ticket [_1]: [_2]", $Ticket->Id, $_) } @updateresults; } # restore back arguments $ARGS{'Subject'} = $original_subject; $ARGS{'Content'} = $original_content; MaybeRedirectForResults( Actions => \@finalresults, Arguments => { map { $_ => $ARGS{ $_ } } grep defined $ARGS{ $_ } && length $ARGS{ $_ }, qw(incidentid loop server) }, ); } sub parse_csv { my $text = shift; # record containing comma-separated values my @new = (); push(@new, $+) while $text =~ m{ # the first part groups the phrase inside the quotes. # see explanation of this pattern in MRE "([^\"\\]*(?:\\.[^\"\\]*)*)",? | ([^,]+),? | , }gx; push(@new, undef) if substr($text, -1,1) eq ','; return @new; # list of values that were comma-separated } <%ARGS> $incidentid => 0 $server => undef $loop => 'address'