1# -- 2# Copyright (C) 2001-2020 OTRS AG, https://otrs.com/ 3# -- 4# This software comes with ABSOLUTELY NO WARRANTY. For details, see 5# the enclosed file COPYING for license information (GPL). If you 6# did not receive this file, see https://www.gnu.org/licenses/gpl-3.0.txt. 7# -- 8 9package Kernel::System::Web::InterfacePublic; 10 11use strict; 12use warnings; 13 14use Kernel::Language qw(Translatable); 15 16our @ObjectDependencies = ( 17 'Kernel::Config', 18 'Kernel::Output::HTML::Layout', 19 'Kernel::System::DB', 20 'Kernel::System::Log', 21 'Kernel::System::Main', 22 'Kernel::System::Web::Request', 23); 24 25=head1 NAME 26 27Kernel::System::Web::InterfacePublic - the public web interface 28 29=head1 DESCRIPTION 30 31the global public web interface 32 33=head1 PUBLIC INTERFACE 34 35=head2 new() 36 37create public web interface object 38 39 use Kernel::System::Web::InterfacePublic; 40 41 my $Debug = 0; 42 my $Interface = Kernel::System::Web::InterfacePublic->new( 43 Debug => $Debug, 44 WebRequest => CGI::Fast->new(), # optional, e. g. if fast cgi is used, the CGI object is already provided 45 ); 46 47=cut 48 49sub new { 50 my ( $Type, %Param ) = @_; 51 52 # allocate new hash for object 53 my $Self = {}; 54 bless( $Self, $Type ); 55 56 # get debug level 57 $Self->{Debug} = $Param{Debug} || 0; 58 59 # performance log 60 $Self->{PerformanceLogStart} = time(); 61 62 $Kernel::OM->ObjectParamAdd( 63 'Kernel::System::Log' => { 64 LogPrefix => $Kernel::OM->Get('Kernel::Config')->Get('CGILogPrefix'), 65 }, 66 'Kernel::System::Web::Request' => { 67 WebRequest => $Param{WebRequest} || 0, 68 }, 69 ); 70 71 # debug info 72 if ( $Self->{Debug} ) { 73 $Kernel::OM->Get('Kernel::System::Log')->Log( 74 Priority => 'debug', 75 Message => 'Global handle started...', 76 ); 77 } 78 79 return $Self; 80} 81 82=head2 Run() 83 84execute the object 85 86 $Interface->Run(); 87 88=cut 89 90sub Run { 91 my $Self = shift; 92 93 my $ConfigObject = $Kernel::OM->Get('Kernel::Config'); 94 95 my $QueryString = $ENV{QUERY_STRING} || ''; 96 97 # Check if https forcing is active, and redirect if needed. 98 if ( $ConfigObject->Get('HTTPSForceRedirect') ) { 99 100 # Some web servers do not set HTTPS environment variable, so it's not possible to easily know if we are using 101 # https protocol. Look also for similarly named keys in environment hash, since this should prevent loops in 102 # certain cases. 103 if ( 104 ( 105 !defined $ENV{HTTPS} 106 && !grep {/^HTTPS(?:_|$)/} keys %ENV 107 ) 108 || $ENV{HTTPS} ne 'on' 109 ) 110 { 111 my $Host = $ENV{HTTP_HOST} || $ConfigObject->Get('FQDN'); 112 113 # Redirect with 301 code. Add two new lines at the end, so HTTP headers are validated correctly. 114 print "Status: 301 Moved Permanently\nLocation: https://$Host$ENV{REQUEST_URI}\n\n"; 115 return; 116 } 117 } 118 119 my $ParamObject = $Kernel::OM->Get('Kernel::System::Web::Request'); 120 121 my %Param; 122 123 # get session id 124 $Param{SessionName} = $ConfigObject->Get('CustomerPanelSessionName') || 'CSID'; 125 $Param{SessionID} = $ParamObject->GetParam( Param => $Param{SessionName} ) || ''; 126 127 # drop old session id (if exists) 128 $QueryString =~ s/(\?|&|;|)$Param{SessionName}(=&|=;|=.+?&|=.+?$)/;/g; 129 130 # define framework params 131 my $FrameworkParams = { 132 Lang => '', 133 Action => '', 134 Subaction => '', 135 RequestedURL => $QueryString, 136 }; 137 for my $Key ( sort keys %{$FrameworkParams} ) { 138 $Param{$Key} = $ParamObject->GetParam( Param => $Key ) 139 || $FrameworkParams->{$Key}; 140 } 141 142 # validate language 143 if ( $Param{Lang} && $Param{Lang} !~ m{\A[a-z]{2}(?:_[A-Z]{2})?\z}xms ) { 144 delete $Param{Lang}; 145 } 146 147 # Check if the browser sends the SessionID cookie and set the SessionID-cookie 148 # as SessionID! GET or POST SessionID have the lowest priority. 149 if ( $ConfigObject->Get('SessionUseCookie') ) { 150 $Param{SessionIDCookie} = $ParamObject->GetCookie( Key => $Param{SessionName} ); 151 if ( $Param{SessionIDCookie} ) { 152 $Param{SessionID} = $Param{SessionIDCookie}; 153 } 154 } 155 156 # get common application and add-on application params 157 # Important! 158 # This must be done before creating the layout object, 159 # because otherwise the action parameter is not passed and then 160 # the loader can not load module specific JavaScript and CSS 161 # For details see bug: http://bugs.otrs.org/show_bug.cgi?id=6471 162 my %CommonObjectParam = %{ $ConfigObject->Get('PublicFrontend::CommonParam') }; 163 for my $Key ( sort keys %CommonObjectParam ) { 164 $Param{$Key} = $ParamObject->GetParam( Param => $Key ) || $CommonObjectParam{$Key}; 165 } 166 167 # security check Action Param (replace non-word chars) 168 $Param{Action} =~ s/\W//g; 169 170 $Kernel::OM->ObjectParamAdd( 171 'Kernel::Output::HTML::Layout' => { 172 %Param, 173 SessionIDCookie => 1, 174 Debug => $Self->{Debug}, 175 }, 176 ); 177 178 my $DBCanConnect = $Kernel::OM->Get('Kernel::System::DB')->Connect(); 179 180 my $LayoutObject = $Kernel::OM->Get('Kernel::Output::HTML::Layout'); 181 182 if ( !$DBCanConnect ) { 183 $LayoutObject->CustomerFatalError( 184 Comment => Translatable('Please contact the administrator.'), 185 ); 186 } 187 if ( $ParamObject->Error() ) { 188 $LayoutObject->CustomerFatalError( 189 Message => $ParamObject->Error(), 190 Comment => Translatable('Please contact the administrator.'), 191 ); 192 } 193 194 # run modules if a version value exists 195 if ( !$Kernel::OM->Get('Kernel::System::Main')->Require("Kernel::Modules::$Param{Action}") ) { 196 $LayoutObject->CustomerFatalError( 197 Comment => Translatable('Please contact the administrator.'), 198 ); 199 return 1; 200 } 201 202 # module registry 203 my $ModuleReg = $ConfigObject->Get('PublicFrontend::Module')->{ $Param{Action} }; 204 if ( !$ModuleReg ) { 205 $Kernel::OM->Get('Kernel::System::Log')->Log( 206 Priority => 'error', 207 Message => 208 "Module Kernel::Modules::$Param{Action} not registered in Kernel/Config.pm!", 209 ); 210 $LayoutObject->CustomerFatalError( 211 Comment => Translatable('Please contact the administrator.'), 212 ); 213 return; 214 } 215 216 # debug info 217 if ( $Self->{Debug} ) { 218 $Kernel::OM->Get('Kernel::System::Log')->Log( 219 Priority => 'debug', 220 Message => 'Kernel::Modules::' . $Param{Action} . '->new', 221 ); 222 } 223 224 my $FrontendObject = ( 'Kernel::Modules::' . $Param{Action} )->new( 225 UserID => 1, 226 %Param, 227 Debug => $Self->{Debug}, 228 ); 229 230 # debug info 231 if ( $Self->{Debug} ) { 232 $Kernel::OM->Get('Kernel::System::Log')->Log( 233 Priority => 'debug', 234 Message => 'Kernel::Modules::' . $Param{Action} . '->run', 235 ); 236 } 237 238 # ->Run $Action with $FrontendObject 239 $LayoutObject->Print( Output => \$FrontendObject->Run() ); 240 241 # log request time 242 if ( $ConfigObject->Get('PerformanceLog') ) { 243 if ( ( !$QueryString && $Param{Action} ) || $QueryString !~ /Action=/ ) { 244 $QueryString = 'Action=' . $Param{Action} . '&Subaction=' . $Param{Subaction}; 245 } 246 my $File = $ConfigObject->Get('PerformanceLog::File'); 247 ## no critic 248 if ( open my $Out, '>>', $File ) { 249 ## use critic 250 print $Out time() 251 . '::Public::' 252 . ( time() - $Self->{PerformanceLogStart} ) 253 . "::-::$QueryString\n"; 254 close $Out; 255 $Kernel::OM->Get('Kernel::System::Log')->Log( 256 Priority => 'debug', 257 Message => 'Response::Public: ' 258 . ( time() - $Self->{PerformanceLogStart} ) 259 . "s taken (URL:$QueryString)", 260 ); 261 } 262 else { 263 $Kernel::OM->Get('Kernel::System::Log')->Log( 264 Priority => 'error', 265 Message => "Can't write $File: $!", 266 ); 267 } 268 } 269 270 return 1; 271} 272 273sub DESTROY { 274 my $Self = shift; 275 276 # debug info 277 if ( $Self->{Debug} ) { 278 $Kernel::OM->Get('Kernel::System::Log')->Log( 279 Priority => 'debug', 280 Message => 'Global handle stopped.', 281 ); 282 } 283 284 return 1; 285} 286 2871; 288 289=head1 TERMS AND CONDITIONS 290 291This software is part of the OTRS project (L<https://otrs.org/>). 292 293This software comes with ABSOLUTELY NO WARRANTY. For details, see 294the enclosed file COPYING for license information (GPL). If you 295did not receive this file, see L<https://www.gnu.org/licenses/gpl-3.0.txt>. 296 297=cut 298