From ca7a5cd771dd29362b6a8aff38f453a1219af010 Mon Sep 17 00:00:00 2001 From: bernhard Date: Sat, 17 Jul 2021 17:06:00 +0200 Subject: [PATCH] Issue #1121: move OTOBO::RPC into a dedicated .pm file Avoid redefined subroutines. Downside is the package name does not conform to the file name. --- Kernel/System/Web/RPC.pm | 236 +++++++++++++++++++++++++++++++++++++++ bin/psgi-bin/otobo.psgi | 187 +------------------------------ 2 files changed, 240 insertions(+), 183 deletions(-) create mode 100644 Kernel/System/Web/RPC.pm diff --git a/Kernel/System/Web/RPC.pm b/Kernel/System/Web/RPC.pm new file mode 100644 index 0000000000..16c2c16015 --- /dev/null +++ b/Kernel/System/Web/RPC.pm @@ -0,0 +1,236 @@ +#!/usr/bin/env perl +# -- +# OTOBO is a web-based ticketing system for service organisations. +# -- +# Copyright (C) 2001-2020 OTRS AG, https://otrs.com/ +# Copyright (C) 2019-2021 Rother OSS GmbH, https://otobo.de/ +# -- +# This program is free software: you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free Software +# Foundation, either version 3 of the License, or (at your option) any later version. +# This program 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, see . +# -- + +package OTOBO::RPC; + +=head1 NAME + +OTOBO::RPC - subroutines for the SOAP service 'rpc.pl' + +=head1 SYNOPSIS + + # see the app $RPCApp in bin/psgi-bin/otobo.psgi + +=head1 DESCRIPTION + +The SOAP service rpc.pl will dispatch to this module. Note that the package name M diverges +frome the file name F. This is intended as M dispatches based on the package name. + +The module is not managed with the object manager. + +=head1 SUBROUTINES + +=cut + +use strict; +use warnings; +use v5.24; +use utf8; + +# core modules + +# CPAN modules + +# OTOBO modules + +=head2 new + +Constructor for a dummy object, as M dispatches on objects. + +=cut + +sub new { + my $Self = shift; + + my $Class = ref($Self) || $Self; + + return bless {} => $Class; +} + +=head2 Dispatch + +Call the methods that were requested by the SOAP client. + +=cut + +sub Dispatch { + my ( $Self, $User, $Pw, $Object, $Method, %Param ) = @_; + + $User ||= ''; + $Pw ||= ''; + local $Kernel::OM = Kernel::System::ObjectManager->new( + 'Kernel::System::Log' => { + LogPrefix => 'OTOBO-RPC', + }, + ); + + my %CommonObject; + + $CommonObject{ConfigObject} = $Kernel::OM->Get('Kernel::Config'); + $CommonObject{CustomerCompanyObject} = $Kernel::OM->Get('Kernel::System::CustomerCompany'); + $CommonObject{CustomerUserObject} = $Kernel::OM->Get('Kernel::System::CustomerUser'); + $CommonObject{EncodeObject} = $Kernel::OM->Get('Kernel::System::Encode'); + $CommonObject{GroupObject} = $Kernel::OM->Get('Kernel::System::Group'); + $CommonObject{LinkObject} = $Kernel::OM->Get('Kernel::System::LinkObject'); + $CommonObject{LogObject} = $Kernel::OM->Get('Kernel::System::Log'); + $CommonObject{PIDObject} = $Kernel::OM->Get('Kernel::System::PID'); + $CommonObject{QueueObject} = $Kernel::OM->Get('Kernel::System::Queue'); + $CommonObject{SessionObject} = $Kernel::OM->Get('Kernel::System::AuthSession'); + $CommonObject{TicketObject} = $Kernel::OM->Get('Kernel::System::Ticket'); + + # We want to keep providing the TimeObject as legacy API for now. + ## nofilter(TidyAll::Plugin::OTOBO::Migrations::OTOBO10::TimeObject) + $CommonObject{TimeObject} = $Kernel::OM->Get('Kernel::System::Time'); + $CommonObject{UserObject} = $Kernel::OM->Get('Kernel::System::User'); + + my $RequiredUser = $CommonObject{ConfigObject}->Get('SOAP::User'); + my $RequiredPassword = $CommonObject{ConfigObject}->Get('SOAP::Password'); + + if ( + !defined $RequiredUser + || !length $RequiredUser + || !defined $RequiredPassword || !length $RequiredPassword + ) + { + $CommonObject{LogObject}->Log( + Priority => 'notice', + Message => "SOAP::User or SOAP::Password is empty, SOAP access denied!", + ); + return; + } + + if ( $User ne $RequiredUser || $Pw ne $RequiredPassword ) { + $CommonObject{LogObject}->Log( + Priority => 'notice', + Message => "Auth for user $User (pw $Pw) failed!", + ); + + return; + } + + if ( !$CommonObject{$Object} ) { + $CommonObject{LogObject}->Log( + Priority => 'error', + Message => "No such Object $Object!", + ); + return "No such Object $Object!"; + } + + return $CommonObject{$Object}->$Method(%Param); +} + +=item DispatchMultipleTicketMethods() + +to dispatch multiple ticket methods and get the TicketID + + my $TicketID = $RPC->DispatchMultipleTicketMethods( + $SOAP_User, + $SOAP_Pass, + 'TicketObject', + [ { Method => 'TicketCreate', Parameter => \%TicketData }, { Method => 'ArticleCreate', Parameter => \%ArticleData } ], + ); + +=cut + +sub DispatchMultipleTicketMethods { + my ( $Self, $User, $Pw, $Object, $MethodParamArrayRef ) = @_; + + $User ||= ''; + $Pw ||= ''; + + # common objects + local $Kernel::OM = Kernel::System::ObjectManager->new( + 'Kernel::System::Log' => { + LogPrefix => 'OTOBO-RPC', + }, + ); + + my %CommonObject; + + $CommonObject{ConfigObject} = $Kernel::OM->Get('Kernel::Config'); + $CommonObject{CustomerCompanyObject} = $Kernel::OM->Get('Kernel::System::CustomerCompany'); + $CommonObject{CustomerUserObject} = $Kernel::OM->Get('Kernel::System::CustomerUser'); + $CommonObject{EncodeObject} = $Kernel::OM->Get('Kernel::System::Encode'); + $CommonObject{GroupObject} = $Kernel::OM->Get('Kernel::System::Group'); + $CommonObject{LinkObject} = $Kernel::OM->Get('Kernel::System::LinkObject'); + $CommonObject{LogObject} = $Kernel::OM->Get('Kernel::System::Log'); + $CommonObject{PIDObject} = $Kernel::OM->Get('Kernel::System::PID'); + $CommonObject{QueueObject} = $Kernel::OM->Get('Kernel::System::Queue'); + $CommonObject{SessionObject} = $Kernel::OM->Get('Kernel::System::AuthSession'); + $CommonObject{TicketObject} = $Kernel::OM->Get('Kernel::System::Ticket'); + $CommonObject{TimeObject} = $Kernel::OM->Get('Kernel::System::Time'); + $CommonObject{UserObject} = $Kernel::OM->Get('Kernel::System::User'); + + my $RequiredUser = $CommonObject{ConfigObject}->Get('SOAP::User'); + my $RequiredPassword = $CommonObject{ConfigObject}->Get('SOAP::Password'); + + if ( + !defined $RequiredUser + || !length $RequiredUser + || !defined $RequiredPassword || !length $RequiredPassword + ) + { + $CommonObject{LogObject}->Log( + Priority => 'notice', + Message => "SOAP::User or SOAP::Password is empty, SOAP access denied!", + ); + return; + } + + if ( $User ne $RequiredUser || $Pw ne $RequiredPassword ) { + $CommonObject{LogObject}->Log( + Priority => 'notice', + Message => "Auth for user $User (pw $Pw) failed!", + ); + return; + } + + if ( !$CommonObject{$Object} ) { + $CommonObject{LogObject}->Log( + Priority => 'error', + Message => "No such Object $Object!", + ); + return "No such Object $Object!"; + } + + my $TicketID; + my $Counter; + + for my $MethodParamEntry ( @{$MethodParamArrayRef} ) { + + my $Method = $MethodParamEntry->{Method}; + my %Parameter = %{ $MethodParamEntry->{Parameter} }; + + # push ticket id to params if there is no ticket id + if ( !$Parameter{TicketID} && $TicketID ) { + $Parameter{TicketID} = $TicketID; + } + + my $ReturnValue = $CommonObject{$Object}->$Method(%Parameter); + + # remember ticket id if method was TicketCreate + if ( !$Counter && $Object eq 'TicketObject' && $Method eq 'TicketCreate' ) { + $TicketID = $ReturnValue; + } + + $Counter++; + } + + return $TicketID; +} + +1; diff --git a/bin/psgi-bin/otobo.psgi b/bin/psgi-bin/otobo.psgi index c8814c0203..2fdfe7d20a 100755 --- a/bin/psgi-bin/otobo.psgi +++ b/bin/psgi-bin/otobo.psgi @@ -78,193 +78,13 @@ use lib "$Bin/../../Custom"; ## nofilter(TidyAll::Plugin::OTOBO::Perl::SyntaxCheck) ## nofilter(TidyAll::Plugin::OTOBO::Perl::Time) -# This package is used by rpc.pl. -# NOTE: this is mostly untested -package OTOBO::RPC { - - use Kernel::System::ObjectManager; - - sub new { - my $Self = shift; - - my $Class = ref($Self) || $Self; - - return bless {} => $Class; - } - - sub Dispatch { - my ( $Self, $User, $Pw, $Object, $Method, %Param ) = @_; - - $User ||= ''; - $Pw ||= ''; - local $Kernel::OM = Kernel::System::ObjectManager->new( - 'Kernel::System::Log' => { - LogPrefix => 'OTOBO-RPC', - }, - ); - - my %CommonObject; - - $CommonObject{ConfigObject} = $Kernel::OM->Get('Kernel::Config'); - $CommonObject{CustomerCompanyObject} = $Kernel::OM->Get('Kernel::System::CustomerCompany'); - $CommonObject{CustomerUserObject} = $Kernel::OM->Get('Kernel::System::CustomerUser'); - $CommonObject{EncodeObject} = $Kernel::OM->Get('Kernel::System::Encode'); - $CommonObject{GroupObject} = $Kernel::OM->Get('Kernel::System::Group'); - $CommonObject{LinkObject} = $Kernel::OM->Get('Kernel::System::LinkObject'); - $CommonObject{LogObject} = $Kernel::OM->Get('Kernel::System::Log'); - $CommonObject{PIDObject} = $Kernel::OM->Get('Kernel::System::PID'); - $CommonObject{QueueObject} = $Kernel::OM->Get('Kernel::System::Queue'); - $CommonObject{SessionObject} = $Kernel::OM->Get('Kernel::System::AuthSession'); - $CommonObject{TicketObject} = $Kernel::OM->Get('Kernel::System::Ticket'); - - # We want to keep providing the TimeObject as legacy API for now. - ## nofilter(TidyAll::Plugin::OTOBO::Migrations::OTOBO10::TimeObject) - $CommonObject{TimeObject} = $Kernel::OM->Get('Kernel::System::Time'); - $CommonObject{UserObject} = $Kernel::OM->Get('Kernel::System::User'); - - my $RequiredUser = $CommonObject{ConfigObject}->Get('SOAP::User'); - my $RequiredPassword = $CommonObject{ConfigObject}->Get('SOAP::Password'); - - if ( - !defined $RequiredUser - || !length $RequiredUser - || !defined $RequiredPassword || !length $RequiredPassword - ) - { - $CommonObject{LogObject}->Log( - Priority => 'notice', - Message => "SOAP::User or SOAP::Password is empty, SOAP access denied!", - ); - return; - } - - if ( $User ne $RequiredUser || $Pw ne $RequiredPassword ) { - $CommonObject{LogObject}->Log( - Priority => 'notice', - Message => "Auth for user $User (pw $Pw) failed!", - ); - return; - } - - if ( !$CommonObject{$Object} ) { - $CommonObject{LogObject}->Log( - Priority => 'error', - Message => "No such Object $Object!", - ); - return "No such Object $Object!"; - } - - return $CommonObject{$Object}->$Method(%Param); - } - -=item DispatchMultipleTicketMethods() - -to dispatch multiple ticket methods and get the TicketID - - my $TicketID = $RPC->DispatchMultipleTicketMethods( - $SOAP_User, - $SOAP_Pass, - 'TicketObject', - [ { Method => 'TicketCreate', Parameter => \%TicketData }, { Method => 'ArticleCreate', Parameter => \%ArticleData } ], - ); - -=cut - - sub DispatchMultipleTicketMethods { - my ( $Self, $User, $Pw, $Object, $MethodParamArrayRef ) = @_; - - $User ||= ''; - $Pw ||= ''; - - # common objects - local $Kernel::OM = Kernel::System::ObjectManager->new( - 'Kernel::System::Log' => { - LogPrefix => 'OTOBO-RPC', - }, - ); - - my %CommonObject; - - $CommonObject{ConfigObject} = $Kernel::OM->Get('Kernel::Config'); - $CommonObject{CustomerCompanyObject} = $Kernel::OM->Get('Kernel::System::CustomerCompany'); - $CommonObject{CustomerUserObject} = $Kernel::OM->Get('Kernel::System::CustomerUser'); - $CommonObject{EncodeObject} = $Kernel::OM->Get('Kernel::System::Encode'); - $CommonObject{GroupObject} = $Kernel::OM->Get('Kernel::System::Group'); - $CommonObject{LinkObject} = $Kernel::OM->Get('Kernel::System::LinkObject'); - $CommonObject{LogObject} = $Kernel::OM->Get('Kernel::System::Log'); - $CommonObject{PIDObject} = $Kernel::OM->Get('Kernel::System::PID'); - $CommonObject{QueueObject} = $Kernel::OM->Get('Kernel::System::Queue'); - $CommonObject{SessionObject} = $Kernel::OM->Get('Kernel::System::AuthSession'); - $CommonObject{TicketObject} = $Kernel::OM->Get('Kernel::System::Ticket'); - $CommonObject{TimeObject} = $Kernel::OM->Get('Kernel::System::Time'); - $CommonObject{UserObject} = $Kernel::OM->Get('Kernel::System::User'); - - my $RequiredUser = $CommonObject{ConfigObject}->Get('SOAP::User'); - my $RequiredPassword = $CommonObject{ConfigObject}->Get('SOAP::Password'); - - if ( - !defined $RequiredUser - || !length $RequiredUser - || !defined $RequiredPassword || !length $RequiredPassword - ) - { - $CommonObject{LogObject}->Log( - Priority => 'notice', - Message => "SOAP::User or SOAP::Password is empty, SOAP access denied!", - ); - return; - } - - if ( $User ne $RequiredUser || $Pw ne $RequiredPassword ) { - $CommonObject{LogObject}->Log( - Priority => 'notice', - Message => "Auth for user $User (pw $Pw) failed!", - ); - return; - } - - if ( !$CommonObject{$Object} ) { - $CommonObject{LogObject}->Log( - Priority => 'error', - Message => "No such Object $Object!", - ); - return "No such Object $Object!"; - } - - my $TicketID; - my $Counter; - - for my $MethodParamEntry ( @{$MethodParamArrayRef} ) { - - my $Method = $MethodParamEntry->{Method}; - my %Parameter = %{ $MethodParamEntry->{Parameter} }; - - # push ticket id to params if there is no ticket id - if ( !$Parameter{TicketID} && $TicketID ) { - $Parameter{TicketID} = $TicketID; - } - - my $ReturnValue = $CommonObject{$Object}->$Method(%Parameter); - - # remember ticket id if method was TicketCreate - if ( !$Counter && $Object eq 'TicketObject' && $Method eq 'TicketCreate' ) { - $TicketID = $ReturnValue; - } - - $Counter++; - } - - return $TicketID; - } -} - # core modules use Data::Dumper; +use Encode qw(:all); # CPAN modules -use DateTime (); -use Template (); -use Encode qw(:all); +use DateTime 1.08; +use Template (); use CGI (); use CGI::Carp (); use CGI::PSGI; @@ -285,6 +105,7 @@ use Kernel::System::Web::InterfaceCustomer (); use Kernel::System::Web::InterfaceInstaller (); use Kernel::System::Web::InterfaceMigrateFromOTRS (); use Kernel::System::Web::InterfacePublic (); +use Kernel::System::Web::RPC (); # provides OTOBO::RPC # Preload Net::DNS if it is installed. It is important to preload Net::DNS because otherwise loading # could take more than 30 seconds.