| blib/lib/Lemonldap/NG/Common/CGI.pm | |||
|---|---|---|---|
| Criterion | Covered | Total | % |
| statement | 77 | 187 | 41.1 |
| branch | 16 | 76 | 21.0 |
| condition | 7 | 43 | 16.2 |
| subroutine | 16 | 31 | 51.6 |
| pod | 2 | 19 | 10.5 |
| total | 118 | 356 | 33.1 |
| line | stmt | bran | cond | sub | pod | time | code |
|---|---|---|---|---|---|---|---|
| 1 | ## @file | ||||||
| 2 | # Base package for all Lemonldap::NG CGI | ||||||
| 3 | |||||||
| 4 | ## @class | ||||||
| 5 | # Base class for all Lemonldap::NG CGI | ||||||
| 6 | package Lemonldap::NG::Common::CGI; | ||||||
| 7 | |||||||
| 8 | 1 | 1 | 30619 | use strict; | |||
| 1 | 3 | ||||||
| 1 | 41 | ||||||
| 9 | |||||||
| 10 | 1 | 1 | 6 | use File::Basename; | |||
| 1 | 1 | ||||||
| 1 | 124 | ||||||
| 11 | 1 | 1 | 1052 | use MIME::Base64; | |||
| 1 | 907 | ||||||
| 1 | 64 | ||||||
| 12 | 1 | 1 | 1851 | use Time::Local; | |||
| 1 | 3915 | ||||||
| 1 | 83 | ||||||
| 13 | 1 | 1 | 16119 | use CGI; | |||
| 1 | 19669 | ||||||
| 1 | 8 | ||||||
| 14 | 1 | 1 | 6892 | use utf8; | |||
| 1 | 13 | ||||||
| 1 | 6 | ||||||
| 15 | 1 | 1 | 1249 | use Encode; | |||
| 1 | 12982 | ||||||
| 1 | 99 | ||||||
| 16 | 1 | 1 | 875 | use Net::CIDR::Lite; | |||
| 1 | 5142 | ||||||
| 1 | 179 | ||||||
| 17 | |||||||
| 18 | #parameter syslog Indicates syslog facility for logging user actions | ||||||
| 19 | |||||||
| 20 | our $VERSION = '1.4.0'; | ||||||
| 21 | our $_SUPER; | ||||||
| 22 | our @ISA; | ||||||
| 23 | |||||||
| 24 | BEGIN { | ||||||
| 25 | 1 | 50 | 1 | 8 | if ( exists $ENV{MOD_PERL} ) { | ||
| 26 | 0 | 0 | 0 | 0 | if ( $ENV{MOD_PERL_API_VERSION} and $ENV{MOD_PERL_API_VERSION} >= 2 ) { | ||
| 27 | 0 | 0 | eval 'use constant MP => 2;'; | ||||
| 28 | } | ||||||
| 29 | else { | ||||||
| 30 | 0 | 0 | eval 'use constant MP => 1;'; | ||||
| 31 | } | ||||||
| 32 | } | ||||||
| 33 | else { | ||||||
| 34 | 1 | 1 | 80 | eval 'use constant MP => 0;'; | |||
| 1 | 7 | ||||||
| 1 | 13 | ||||||
| 1 | 54 | ||||||
| 35 | } | ||||||
| 36 | 1 | 2 | $_SUPER = 'CGI'; | ||||
| 37 | 1 | 2830 | @ISA = ('CGI'); | ||||
| 38 | } | ||||||
| 39 | |||||||
| 40 | sub import { | ||||||
| 41 | 1 | 1 | 295 | my $pkg = shift; | |||
| 42 | 1 | 50 | 33 | 24 | if ( $pkg eq __PACKAGE__ and @_ and $_[0] eq "fastcgi" ) { | ||
| 33 | |||||||
| 43 | 0 | 0 | eval 'use CGI::Fast'; | ||||
| 44 | 0 | 0 | 0 | die($@) if ($@); | |||
| 45 | 0 | 0 | unshift @ISA, 'CGI::Fast'; | ||||
| 46 | 0 | 0 | $_SUPER = 'CGI::Fast'; | ||||
| 47 | } | ||||||
| 48 | } | ||||||
| 49 | |||||||
| 50 | ## @cmethod Lemonldap::NG::Common::CGI new(@p) | ||||||
| 51 | # Constructor: launch CGI::new() then secure parameters since CGI store them at | ||||||
| 52 | # the root of the object. | ||||||
| 53 | # @param p arguments for CGI::new() | ||||||
| 54 | # @return new Lemonldap::NG::Common::CGI object | ||||||
| 55 | sub new { | ||||||
| 56 | 3 | 3 | 1 | 7887 | my $class = shift; | ||
| 57 | 3 | 50 | 36 | my $self = $_SUPER->new(@_) or return undef; | |||
| 58 | 3 | 15238 | $self->{_prm} = {}; | ||||
| 59 | 3 | 12 | my @tmp = $self->param(); | ||||
| 60 | 3 | 51 | foreach (@tmp) { | ||||
| 61 | 0 | 0 | $self->{_prm}->{$_} = $self->param($_); | ||||
| 62 | 0 | 0 | $self->delete($_); | ||||
| 63 | } | ||||||
| 64 | 3 | 10 | $self->{lang} = extract_lang(); | ||||
| 65 | 3 | 17 | bless $self, $class; | ||||
| 66 | 3 | 26 | return $self; | ||||
| 67 | } | ||||||
| 68 | |||||||
| 69 | ## @method scalar param(string s, scalar newValue) | ||||||
| 70 | # Return the wanted parameter issued of GET or POST request. If $s is not set, | ||||||
| 71 | # return the list of parameters names | ||||||
| 72 | # @param $s name of the parameter | ||||||
| 73 | # @param $newValue if set, the parameter will be set to his value | ||||||
| 74 | # @return datas passed by GET or POST method | ||||||
| 75 | sub param { | ||||||
| 76 | 0 | 0 | 0 | 0 | my ( $self, $p, $v ) = @_; | ||
| 77 | 0 | 0 | 0 | $self->{_prm}->{$p} = $v if ($v); | |||
| 78 | 0 | 0 | 0 | unless ( defined $p ) { | |||
| 79 | 0 | 0 | return keys %{ $self->{_prm} }; | ||||
| 0 | 0 | ||||||
| 80 | } | ||||||
| 81 | 0 | 0 | return $self->{_prm}->{$p}; | ||||
| 82 | } | ||||||
| 83 | |||||||
| 84 | ## @method scalar rparam(string s) | ||||||
| 85 | # Return a reference to a parameter | ||||||
| 86 | # @param $s name of the parameter | ||||||
| 87 | # @return ref to parameter data | ||||||
| 88 | sub rparam { | ||||||
| 89 | 0 | 0 | 0 | 0 | my ( $self, $p ) = @_; | ||
| 90 | 0 | 0 | 0 | return $self->{_prm}->{$p} ? \$self->{_prm}->{$p} : undef; | |||
| 91 | } | ||||||
| 92 | |||||||
| 93 | ## @method void lmLog(string mess, string level) | ||||||
| 94 | # Log subroutine. Use Apache::Log in ModPerl::Registry context else simply | ||||||
| 95 | # print on STDERR non debug messages. | ||||||
| 96 | # @param $mess Text to log | ||||||
| 97 | # @param $level Level (debug|info|notice|error) | ||||||
| 98 | sub lmLog { | ||||||
| 99 | 2 | 2 | 0 | 5 | my ( $self, $mess, $level ) = @_; | ||
| 100 | 2 | 4 | my $call; | ||||
| 101 | 2 | 50 | 7 | if ( $level eq 'debug' ) { | |||
| 102 | 2 | 50 | 9 | $mess = ( ref($self) ? ref($self) : $self ) . ": $mess"; | |||
| 103 | } | ||||||
| 104 | else { | ||||||
| 105 | 0 | 0 | my @tmp = caller(); | ||||
| 106 | 0 | 0 | $call = "$tmp[1] $tmp[2]:"; | ||||
| 107 | } | ||||||
| 108 | 2 | 50 | 50 | 15 | if ( $self->r and MP() ) { | ||
| 109 | 0 | 0 | 0 | $self->abort( "Level is required", | |||
| 110 | 'the parameter "level" is required when lmLog() is used' ) | ||||||
| 111 | unless ($level); | ||||||
| 112 | 0 | 0 | if ( MP() == 2 ) { | ||||
| 113 | require Apache2::Log; | ||||||
| 114 | Apache2::ServerRec->log->debug($call) if ($call); | ||||||
| 115 | Apache2::ServerRec->log->$level($mess); | ||||||
| 116 | } | ||||||
| 117 | else { | ||||||
| 118 | 0 | 0 | 0 | Apache->server->log->debug($call) if ($call); | |||
| 119 | 0 | 0 | Apache->server->log->$level($mess); | ||||
| 120 | } | ||||||
| 121 | } | ||||||
| 122 | else { | ||||||
| 123 | 2 | 100 | 27 | $self->{hideLogLevels} = 'debug|info' | |||
| 124 | unless defined( $self->{hideLogLevels} ); | ||||||
| 125 | 2 | 55 | my $re = qr/^(?:$self->{hideLogLevels})$/; | ||||
| 126 | 2 | 50 | 33 | 9 | print STDERR "$call\n" if ( $call and 'debug' !~ $re ); | ||
| 127 | 2 | 50 | 20 | print STDERR "[$level] $mess\n" unless ( $level =~ $re ); | |||
| 128 | } | ||||||
| 129 | } | ||||||
| 130 | |||||||
| 131 | ## @method void setApacheUser(string user) | ||||||
| 132 | # Set user for Apache logs in ModPerl::Registry context. Does nothing else. | ||||||
| 133 | # @param $user data to set as user in Apache logs | ||||||
| 134 | sub setApacheUser { | ||||||
| 135 | 0 | 0 | 0 | 0 | my ( $self, $user ) = @_; | ||
| 136 | 0 | 0 | 0 | 0 | if ( $self->r and MP() ) { | ||
| 137 | 0 | 0 | $self->lmLog( "Inform Apache about the user connected", 'debug' ); | ||||
| 138 | 0 | 0 | if ( MP() == 2 ) { | ||||
| 139 | require Apache2::Connection; | ||||||
| 140 | $self->r->user($user); | ||||||
| 141 | } | ||||||
| 142 | else { | ||||||
| 143 | 0 | 0 | $self->r->connection->user($user); | ||||
| 144 | } | ||||||
| 145 | } | ||||||
| 146 | 0 | 0 | $ENV{REMOTE_USER} = $user; | ||||
| 147 | } | ||||||
| 148 | |||||||
| 149 | ##@method string getApacheHtdocsPath() | ||||||
| 150 | # Return absolute path to the htdocs directory where the current script is | ||||||
| 151 | # @return path string | ||||||
| 152 | sub getApacheHtdocsPath { | ||||||
| 153 | 0 | 0 | 0 | 0 | 0 | return dirname( $ENV{SCRIPT_FILENAME} || $0 ); | |
| 154 | } | ||||||
| 155 | |||||||
| 156 | ## @method void soapTest(string soapFunctions, object obj) | ||||||
| 157 | # Check if request is a SOAP request. If it is, launch | ||||||
| 158 | # Lemonldap::NG::Common::CGI::SOAPServer and exit. Else simply return. | ||||||
| 159 | # @param $soapFunctions list of authorized functions. | ||||||
| 160 | # @param $obj optional object that will receive SOAP requests | ||||||
| 161 | sub soapTest { | ||||||
| 162 | 0 | 0 | 0 | 0 | my ( $self, $soapFunctions, $obj ) = @_; | ||
| 163 | |||||||
| 164 | # If non form encoded datas are posted, we call SOAP Services | ||||||
| 165 | 0 | 0 | 0 | if ( $ENV{HTTP_SOAPACTION} ) { | |||
| 166 | require | ||||||
| 167 | 0 | 0 | Lemonldap::NG::Common::CGI::SOAPServer; #link protected dispatcher | ||||
| 168 | require | ||||||
| 169 | 0 | 0 | Lemonldap::NG::Common::CGI::SOAPService; #link protected soapService | ||||
| 170 | 0 | 0 | 0 | my @func = ( | |||
| 171 | ref($soapFunctions) ? @$soapFunctions : split /\s+/, | ||||||
| 172 | $soapFunctions | ||||||
| 173 | ); | ||||||
| 174 | 0 | 0 | 0 | my $dispatcher = | |||
| 175 | Lemonldap::NG::Common::CGI::SOAPService->new( $obj || $self, @func ); | ||||||
| 176 | 0 | 0 | Lemonldap::NG::Common::CGI::SOAPServer->dispatch_to($dispatcher) | ||||
| 177 | ->handle($self); | ||||||
| 178 | 0 | 0 | $self->quit(); | ||||
| 179 | } | ||||||
| 180 | } | ||||||
| 181 | |||||||
| 182 | ## @method string header_public(string filename) | ||||||
| 183 | # Implements the "304 Not Modified" HTTP mechanism. | ||||||
| 184 | # If HTTP request contains an "If-Modified-Since" header and if | ||||||
| 185 | # $filename was not modified since, prints the "304 Not Modified" response and | ||||||
| 186 | # exit. Else, launch CGI::header() with "Cache-Control" and "Last-Modified" | ||||||
| 187 | # headers. | ||||||
| 188 | # @param $filename Optional name of the reference file. Default | ||||||
| 189 | # $ENV{SCRIPT_FILENAME}. | ||||||
| 190 | # @return Common Gateway Interface standard response header | ||||||
| 191 | sub header_public { | ||||||
| 192 | 1 | 1 | 1 | 3 | my $self = shift; | ||
| 193 | 1 | 3 | my $filename = shift; | ||||
| 194 | 1 | 33 | 5 | $filename ||= $ENV{SCRIPT_FILENAME}; | |||
| 195 | 1 | 42 | my @tmp = stat($filename); | ||||
| 196 | 1 | 2 | my $date = $tmp[9]; | ||||
| 197 | 1 | 14 | my $hd = gmtime($date); | ||||
| 198 | 1 | 48 | $hd =~ s/^(\w+)\s+(\w+)\s+(\d+)\s+([\d:]+)\s+(\d+)$/$1, $3 $2 $5 $4 GMT/; | ||||
| 199 | 1 | 4 | my $year = $5; | ||||
| 200 | 1 | 3 | my $cm = $2; | ||||
| 201 | |||||||
| 202 | # TODO: Remove TODO_ for stable releases | ||||||
| 203 | 1 | 50 | 7 | if ( my $ref = $ENV{HTTP_IF_MODIFIED_SINCE} ) { | |||
| 204 | 0 | 0 | my %month = ( | ||||
| 205 | jan => 0, | ||||||
| 206 | feb => 1, | ||||||
| 207 | mar => 2, | ||||||
| 208 | apr => 3, | ||||||
| 209 | may => 4, | ||||||
| 210 | jun => 5, | ||||||
| 211 | jul => 6, | ||||||
| 212 | aug => 7, | ||||||
| 213 | sep => 8, | ||||||
| 214 | oct => 9, | ||||||
| 215 | nov => 10, | ||||||
| 216 | dec => 11 | ||||||
| 217 | ); | ||||||
| 218 | 0 | 0 | 0 | if ( $ref =~ /^\w+,\s+(\d+)\s+(\w+)\s+(\d+)\s+(\d+):(\d+):(\d+)/ ) { | |||
| 219 | 0 | 0 | my $m = $month{ lc($2) }; | ||||
| 220 | 0 | 0 | 0 | $year-- if ( $m > $month{ lc($cm) } ); | |||
| 221 | 0 | 0 | $ref = timegm( $6, $5, $4, $1, $m, $3 ); | ||||
| 222 | 0 | 0 | 0 | if ( $ref == $date ) { | |||
| 223 | 0 | 0 | print $self->SUPER::header( -status => '304 Not Modified', @_ ); | ||||
| 224 | 0 | 0 | $self->quit(); | ||||
| 225 | } | ||||||
| 226 | } | ||||||
| 227 | } | ||||||
| 228 | 1 | 20 | return $self->SUPER::header( | ||||
| 229 | '-Last-Modified' => $hd, | ||||||
| 230 | '-Cache-Control' => 'public; must-revalidate; max-age=1800', | ||||||
| 231 | @_ | ||||||
| 232 | ); | ||||||
| 233 | } | ||||||
| 234 | |||||||
| 235 | ## @method void abort(string title, string text) | ||||||
| 236 | # Display an error message and exit. | ||||||
| 237 | # Used instead of die() in Lemonldap::NG CGIs. | ||||||
| 238 | # @param title Title of the error message | ||||||
| 239 | # @param text Optional text. Default: "See Apache's logs" | ||||||
| 240 | sub abort { | ||||||
| 241 | 0 | 0 | 0 | 0 | my $self = shift; | ||
| 242 | 0 | 0 | my $cgi = CGI->new(); | ||||
| 243 | 0 | 0 | my ( $t1, $t2 ) = @_; | ||||
| 244 | |||||||
| 245 | # Default message | ||||||
| 246 | 0 | 0 | 0 | $t2 ||= "See Apache's logs"; | |||
| 247 | |||||||
| 248 | # Change \n into for HTML |
||||||
| 249 | 0 | 0 | my $t2html = $t2; | ||||
| 250 | 0 | 0 | $t2html =~ s#\n# #g; |
||||
| 251 | |||||||
| 252 | 0 | 0 | print $cgi->header( -type => 'text/html; charset=utf-8', ); | ||||
| 253 | 0 | 0 | print $cgi->start_html( | ||||
| 254 | -title => $t1, | ||||||
| 255 | -encoding => 'utf8', | ||||||
| 256 | -style => { | ||||||
| 257 | -code => ' | ||||||
| 258 | body{ | ||||||
| 259 | background:#000; | ||||||
| 260 | color:#fff; | ||||||
| 261 | padding:10px 50px; | ||||||
| 262 | font-family:sans-serif; | ||||||
| 263 | } | ||||||
| 264 | a { | ||||||
| 265 | text-decoration:none; | ||||||
| 266 | color:#fff; | ||||||
| 267 | } | ||||||
| 268 | ' | ||||||
| 269 | }, | ||||||
| 270 | ); | ||||||
| 271 | 0 | 0 | print "$t1$t2html "; |
||||
| 272 | 0 | 0 | |||||
| 273 | ' |
||||||
| 274 | 0 | 0 | 0 | print STDERR ( ref($self) || $self ) . " error: $t1, $t2\n"; | |||
| 275 | 0 | 0 | print $cgi->end_html(); | ||||
| 276 | 0 | 0 | $self->quit(); | ||||
| 277 | } | ||||||
| 278 | |||||||
| 279 | ##@method private void startSyslog() | ||||||
| 280 | # Open syslog connection. | ||||||
| 281 | sub startSyslog { | ||||||
| 282 | 0 | 0 | 0 | 0 | my $self = shift; | ||
| 283 | 0 | 0 | 0 | return if ( $self->{_syslog} ); | |||
| 284 | 0 | 0 | eval { | ||||
| 285 | 0 | 0 | require Sys::Syslog; | ||||
| 286 | 0 | 0 | Sys::Syslog->import(':standard'); | ||||
| 287 | 0 | 0 | openlog( 'lemonldap-ng', 'ndelay,pid', $self->{syslog} ); | ||||
| 288 | }; | ||||||
| 289 | 0 | 0 | 0 | $self->abort( "Unable to use syslog", $@ ) if ($@); | |||
| 290 | 0 | 0 | $self->{_syslog} = 1; | ||||
| 291 | } | ||||||
| 292 | |||||||
| 293 | ##@method void userLog(string mess, string level) | ||||||
| 294 | # Log user actions on Apache logs or syslog. | ||||||
| 295 | # @param $mess string to log | ||||||
| 296 | # @param $level level of log message | ||||||
| 297 | sub userLog { | ||||||
| 298 | 0 | 0 | 0 | 0 | my ( $self, $mess, $level ) = @_; | ||
| 299 | 0 | 0 | 0 | if ( $self->{syslog} ) { | |||
| 300 | 0 | 0 | $self->startSyslog(); | ||||
| 301 | 0 | 0 | $level =~ s/^warn$/warning/; | ||||
| 302 | 0 | 0 | 0 | syslog( $level || 'notice', $mess ); | |||
| 303 | } | ||||||
| 304 | else { | ||||||
| 305 | 0 | 0 | $self->lmLog( $mess, $level ); | ||||
| 306 | } | ||||||
| 307 | } | ||||||
| 308 | |||||||
| 309 | ##@method void userInfo(string mess) | ||||||
| 310 | # Log non important user actions. Alias for userLog() with facility "info". | ||||||
| 311 | # @param $mess string to log | ||||||
| 312 | sub userInfo { | ||||||
| 313 | 0 | 0 | 0 | 0 | my ( $self, $mess ) = @_; | ||
| 314 | 0 | 0 | $mess = "Lemonldap::NG : $mess (" . $self->ipAddr . ")"; | ||||
| 315 | 0 | 0 | $self->userLog( $mess, 'info' ); | ||||
| 316 | } | ||||||
| 317 | |||||||
| 318 | ##@method void userNotice(string mess) | ||||||
| 319 | # Log user actions like access and logout. Alias for userLog() with facility | ||||||
| 320 | # "notice". | ||||||
| 321 | # @param $mess string to log | ||||||
| 322 | sub userNotice { | ||||||
| 323 | 0 | 0 | 0 | 0 | my ( $self, $mess ) = @_; | ||
| 324 | 0 | 0 | $mess = "Lemonldap::NG : $mess (" . $self->ipAddr . ")"; | ||||
| 325 | 0 | 0 | $self->userLog( $mess, 'notice' ); | ||||
| 326 | } | ||||||
| 327 | |||||||
| 328 | ##@method void userError(string mess) | ||||||
| 329 | # Log user errors like "bad password". Alias for userLog() with facility | ||||||
| 330 | # "warn". | ||||||
| 331 | # @param $mess string to log | ||||||
| 332 | sub userError { | ||||||
| 333 | 0 | 0 | 0 | 0 | my ( $self, $mess ) = @_; | ||
| 334 | 0 | 0 | $mess = "Lemonldap::NG : $mess (" . $self->ipAddr . ")"; | ||||
| 335 | 0 | 0 | $self->userLog( $mess, 'warn' ); | ||||
| 336 | } | ||||||
| 337 | |||||||
| 338 | ## @method protected scalar _sub(string sub, array p) | ||||||
| 339 | # Launch $self->{$sub} if defined, else launch $self->$sub. | ||||||
| 340 | # @param $sub name of the sub to launch | ||||||
| 341 | # @param @p parameters for the sub | ||||||
| 342 | sub _sub { | ||||||
| 343 | 2 | 2 | 11429 | my ( $self, $sub, @p ) = @_; | |||
| 344 | 2 | 100 | 10 | if ( $self->{$sub} ) { | |||
| 345 | 1 | 8 | $self->lmLog( "processing to custom sub $sub", 'debug' ); | ||||
| 346 | 1 | 2 | return &{ $self->{$sub} }( $self, @p ); | ||||
| 1 | 5 | ||||||
| 347 | } | ||||||
| 348 | else { | ||||||
| 349 | 1 | 14 | $self->lmLog( "processing to sub $sub", 'debug' ); | ||||
| 350 | 1 | 7 | return $self->$sub(@p); | ||||
| 351 | } | ||||||
| 352 | } | ||||||
| 353 | |||||||
| 354 | ##@method string extract_lang | ||||||
| 355 | #@return array of user's preferred languages (two letters) | ||||||
| 356 | sub extract_lang { | ||||||
| 357 | 6 | 6 | 0 | 412 | my $self = shift; | ||
| 358 | |||||||
| 359 | 6 | 100 | 122 | my @langs = split /,\s*/, ( shift || $ENV{HTTP_ACCEPT_LANGUAGE} || "" ); | |||
| 360 | 6 | 12 | my @res = (); | ||||
| 361 | |||||||
| 362 | 6 | 14 | foreach (@langs) { | ||||
| 363 | |||||||
| 364 | # Languages are supposed to be sorted by preference | ||||||
| 365 | 12 | 30 | my $lang = ( split /;/ )[0]; | ||||
| 366 | |||||||
| 367 | # Take first part of lang code (part before -) | ||||||
| 368 | 12 | 28 | $lang = ( split /-/, $lang )[0]; | ||||
| 369 | |||||||
| 370 | # Go to next if lang was already added | ||||||
| 371 | 12 | 100 | 86 | next if grep( /$lang/, @res ); | |||
| 372 | |||||||
| 373 | # Store lang only if size is 2 characters | ||||||
| 374 | 8 | 50 | 81 | push @res, $lang if ( length($lang) == 2 ); | |||
| 375 | } | ||||||
| 376 | |||||||
| 377 | 6 | 35 | return \@res; | ||||
| 378 | } | ||||||
| 379 | |||||||
| 380 | ##@method void translate_template(string text_ref, string lang) | ||||||
| 381 | # translate_template is used as an HTML::Template filter to tranlate strings in | ||||||
| 382 | # the wanted language | ||||||
| 383 | #@param text_ref reference to the string to translate | ||||||
| 384 | #@param lang optionnal language wanted. Falls to browser language instead. | ||||||
| 385 | #@return | ||||||
| 386 | sub translate_template { | ||||||
| 387 | 0 | 0 | 0 | my $self = shift; | |||
| 388 | 0 | my $text_ref = shift; | |||||
| 389 | |||||||
| 390 | # Decode UTF-8 | ||||||
| 391 | 0 | 0 | utf8::decode($$text_ref) unless ( $ENV{FCGI_ROLE} ); | ||||
| 392 | |||||||
| 393 | # Test if a translation is available for the selected language | ||||||
| 394 | # If not available, return the first translated string | ||||||
| 395 | # |
||||||
| 396 | 0 | foreach ( @{ $self->{lang} } ) { | |||||
| 0 | |||||||
| 397 | 0 | 0 | if ( $$text_ref =~ m/$_=\"(.*?)\"/ ) { | ||||
| 398 | 0 | $$text_ref =~ s/ |
|||||
| 399 | 0 | return; | |||||
| 400 | } | ||||||
| 401 | } | ||||||
| 402 | 0 | $$text_ref =~ s/ |
|||||
| 403 | } | ||||||
| 404 | |||||||
| 405 | ##@method void session_template(string text_ref) | ||||||
| 406 | # session_template is used as an HTML::Template filter to replace session info | ||||||
| 407 | # by their value | ||||||
| 408 | #@param text_ref reference to the string to translate | ||||||
| 409 | #@return | ||||||
| 410 | sub session_template { | ||||||
| 411 | 0 | 0 | 0 | my $self = shift; | |||
| 412 | 0 | my $text_ref = shift; | |||||
| 413 | |||||||
| 414 | # Replace session information | ||||||
| 415 | 0 | $$text_ref =~ s/\$(\w+)/decode("utf8",$self->{sessionInfo}->{$1})/ge; | |||||
| 0 | |||||||
| 416 | } | ||||||
| 417 | |||||||
| 418 | ## @method private void quit() | ||||||
| 419 | # Simply exit. | ||||||
| 420 | sub quit { | ||||||
| 421 | 0 | 0 | 0 | my $self = shift; | |||
| 422 | 0 | 0 | if ( $_SUPER eq 'CGI::Fast' ) { | ||||
| 423 | 0 | next LMAUTH; | |||||
| 424 | } | ||||||
| 425 | else { | ||||||
| 426 | 0 | exit; | |||||
| 427 | } | ||||||
| 428 | } | ||||||
| 429 | |||||||
| 430 | ##@method string ipAddr() | ||||||
| 431 | # Retrieve client IP address from remote address or X-FORWARDED-FOR header | ||||||
| 432 | #@return client IP | ||||||
| 433 | sub ipAddr { | ||||||
| 434 | 0 | 0 | 0 | my $self = shift; | |||
| 435 | |||||||
| 436 | 0 | 0 | unless ( $self->{ipAddr} ) { | ||||
| 437 | 0 | $self->{ipAddr} = $ENV{REMOTE_ADDR}; | |||||
| 438 | 0 | 0 | if ( my $xheader = $ENV{HTTP_X_FORWARDED_FOR} ) { | ||||
| 439 | 0 | 0 | 0 | if ( $self->{trustedProxies} =~ /\*/ | |||
| 0 | |||||||
| 440 | or $self->{useXForwardedForIP} ) | ||||||
| 441 | { | ||||||
| 442 | 0 | 0 | $self->{ipAddr} = $1 if ( $xheader =~ /^([^,]*)/ ); | ||||
| 443 | } | ||||||
| 444 | elsif ( $self->{trustedProxies} ) { | ||||||
| 445 | 0 | my $localIP = | |||||
| 446 | Net::CIDR::Lite->new("127.0.0.0/8"); # TODO: add IPv6 local IP | ||||||
| 447 | 0 | my $trustedIP = | |||||
| 448 | Net::CIDR::Lite->new( split /\s+/, $self->{trustedProxies} ); | ||||||
| 449 | 0 | 0 | while ( | ||||
| 0 | |||||||
| 450 | ( | ||||||
| 451 | $localIP->find( $self->{ipAddr} ) | ||||||
| 452 | or $trustedIP->find( $self->{ipAddr} ) | ||||||
| 453 | ) | ||||||
| 454 | and $xheader =~ s/[,\s]*([^,\s]+)$// | ||||||
| 455 | ) | ||||||
| 456 | { | ||||||
| 457 | |||||||
| 458 | # because it is of no use to store a local IP as client IP | ||||||
| 459 | 0 | 0 | $self->{ipAddr} = $1 unless ( $localIP->find($1) ); | ||||
| 460 | } | ||||||
| 461 | } | ||||||
| 462 | } | ||||||
| 463 | } | ||||||
| 464 | 0 | return $self->{ipAddr}; | |||||
| 465 | } | ||||||
| 466 | |||||||
| 467 | 1; | ||||||
| 468 | |||||||
| 469 | __END__ |