diff --git a/docs/changelog/7.x.x.txt b/docs/changelog/7.x.x.txt index c8532c7dd..c5c489f9b 100644 --- a/docs/changelog/7.x.x.txt +++ b/docs/changelog/7.x.x.txt @@ -4,6 +4,11 @@ - fix: Bug in HttpProxy.pm - fix: Storage::Image copy does not create thumbnails - fix: Static export - redirect problems + - fixed a bug in Session::ErrorHandler::canShowPerformanceIndicators. Moving + to CIDR format in debugIp broke it. Added a new convenience method called + canShowBasedOnIP, which refactored out the identical code to share + between canShowDebug, canShowPerformanceIndicators and any other IP based + check for privileges. 7.2.1 - Made a change to version tag commits to deal with unusually long commit diff --git a/lib/WebGUI/Session/ErrorHandler.pm b/lib/WebGUI/Session/ErrorHandler.pm index 02db3288d..105ff2281 100644 --- a/lib/WebGUI/Session/ErrorHandler.pm +++ b/lib/WebGUI/Session/ErrorHandler.pm @@ -74,6 +74,31 @@ sub audit { } +#------------------------------------------------------------------- + +=head2 canShowBasedOnIP ( $ipSetting ) + +Returns true if the the user's IP address matches the requested IP setting. + +=head3 ipSetting + +The setting to pull from the database. It should containt a CSV list of IP +addresses in CIDR format. + +=cut + +sub canShowBasedOnIP { + my $self = shift; + my $ipSetting = shift; + return 0 unless $ipSetting; + return 1 if ($self->session->setting->get($ipSetting) eq ""); + my $ips = $self->session->setting->get($ipSetting); + $ips =~ s/\s+//g; + my @ips = split(",", $ips); + my $ok = WebGUI::Utility::isInSubnet($self->session->env->getIp, [ @ips] ); + return $ok; +} + #------------------------------------------------------------------- =head2 canShowDebug ( ) @@ -86,12 +111,7 @@ sub canShowDebug { my $self = shift; return 0 unless ($self->session->setting->get("showDebug")); return 0 unless (substr($self->session->http->getMimeType(),0,9) eq "text/html"); - return 1 if ($self->session->setting->get("debugIp") eq ""); - my $ips = $self->session->setting->get("debugIp"); - $ips =~ s/\s+//g; - my @ips = split(",", $ips); - my $ok = WebGUI::Utility::isInSubnet($self->session->env->getIp, [ @ips] ); - return $ok; + return $self->canShowBasedOnIP('debugIp'); } #------------------------------------------------------------------- @@ -104,16 +124,8 @@ Returns true if the user meets the conditions to see performance indicators and sub canShowPerformanceIndicators { my $self = shift; - my $mask = $self->session->setting->get("debugIp"); - my $ip = $self->session->env->getIp; - return ( - ( - $self->session->setting->get("showPerformanceIndicators") - ) && ( - $ip =~ /^$mask/ || - $self->session->setting->get("debugIp") eq "" - ) - ); + return 0 unless $self->session->setting->get("showPerformanceIndicators"); + return $self->canShowBasedOnIP('debugIp'); } diff --git a/lib/WebGUI/i18n/English/WebGUI.pm b/lib/WebGUI/i18n/English/WebGUI.pm index 445ace955..c2e4ea104 100644 --- a/lib/WebGUI/i18n/English/WebGUI.pm +++ b/lib/WebGUI/i18n/English/WebGUI.pm @@ -83,8 +83,8 @@ our $I18N = { }, 'debug ip description' => { - message => q|This will limit debugging output to a specific IP address or IP range. Enter the subnet that you want to be able to view debug output in CIDR format. For example: 10.0.0.0/24. Multiple CIDR addresses may be entered, separated by commas.|, - lastUpdated => 1139948380 + message => q|This will limit debugging and/or performance output to a specific IP address or IP range. Enter the subnet that you want to be able to view debug output in CIDR format. For example: 10.0.0.0/24. Multiple CIDR addresses may be entered, separated by commas.|, + lastUpdated => 1164055466 }, 'debug ip' => { diff --git a/t/Session/ErrorHandler.t b/t/Session/ErrorHandler.t index ff5b0fa2f..53d8d1bf7 100644 --- a/t/Session/ErrorHandler.t +++ b/t/Session/ErrorHandler.t @@ -18,14 +18,14 @@ use WebGUI::Session; use Test::More; use Test::MockObject::Extends; -my $numTests = 15; +my $numTests = 38; plan tests => $numTests; my $session = WebGUI::Test->session; ##Setup for security method test -my %newEnv = ( REMOTE_ADDR => '192.168.0.2' ); +my %newEnv = ( REMOTE_ADDR => '192.168.0.6' ); $session->env->{_env} = \%newEnv; my ($eh) = $session->quick('errorHandler'); @@ -34,11 +34,12 @@ $logger = Test::MockObject::Extends->new( $logger ); is( $logger, $session->errorHandler->getLogger, 'Main logger mocked'); -my ($warns, $debug, $info); +my ($warns, $debug, $info, $error); $logger->mock( 'warn', sub { $warns = $_[1]} ); $logger->mock( 'debug', sub { $debug = $_[1]} ); -$logger->mock( 'info', sub { $info = $_[1]} ); +$logger->mock( 'info', sub { $info = $_[1]} ); +$logger->mock( 'error', sub { $error = $_[1]} ); #################################################### # @@ -81,7 +82,7 @@ is($info, $audit, 'audit: calls info with username and userId'); #################################################### # -# debug +# debug, query # #################################################### @@ -92,3 +93,119 @@ is($eh->{'_debug_debug'}, "This is a bug\n", "debug: message internally appended $eh->debug("More bugs"); is($debug, "More bugs", "debug: Log4perl called again"); is($eh->{'_debug_debug'}, "This is a bug\nMore bugs\n", "debug: second message appended"); + +$eh->{'_debug_debug'} = ''; ##Manually clean debug +my $queryCount = $eh->{_queryCount}; +$eh->query('select this'); +++$queryCount; +is($debug, "query $queryCount: select this", "query: Log4perl called debug via query"); + +$eh->query('select that', 'literal'); +++$queryCount; +is($debug, "query $queryCount: select that", "query: Log4perl called debug via query, literal placeholder"); + +$eh->query('select more', []); +++$queryCount; +is($debug, "query $queryCount: select more", "query: Log4perl called debug via query, empty placeholder"); + +$eh->query('select many', [1, 2]); +++$queryCount; +is($debug, "query $queryCount: select many\n  with placeholders:  ['1', '2']", "query: Log4perl called debug via query, empty placeholder"); + +#################################################### +# +# error +# +#################################################### + +$eh->{'_debug_debug'} = ''; ##Manually clean debug +$eh->error("ERROR"); +is($error, "ERROR", "error: Log4perl called error"); +like($debug, qr/^Stack trace for ERROR ERROR/, "error: Log4perl called debug"); +is($eh->{'_debug_error'}, "ERROR\n", "error: message internally appended"); +$eh->error("More errors"); +is($error, "More errors", "error: Log4perl called error again"); +is($eh->{'_debug_error'}, "ERROR\nMore errors\n", "error: new message internally appended"); + +#################################################### +# +# getStackTrace +# +#################################################### + +is ($eh->getStackTrace, undef, 'no stack trace due to shallow depth, must be 2 deep for a stack trace'); +like(&depth1(), qr/main,ErrorHandler\.t/, 'stack trace has correct information'); + +sub depth1 { + return &depth2(); +} + +sub depth2 { + return $eh->getStackTrace; +} + +#################################################### +# +# canShowBasedOnIP +# +#################################################### + +is($eh->canShowBasedOnIP(''), 0, 'canShowBasedOnIP: must send IP setting'); + +#################################################### +# +# canShowDebug +# +#################################################### + +my $origDebugIp = $session->setting->get('debugIp'); +my $origShowDebug = $session->setting->get('showDebug'); + +$session->setting->set('showDebug', 0); +is($eh->canShowDebug, 0, 'canShowDebug: returns 0 if not enabled'); + +$session->setting->set('showDebug', 1); +$session->http->setMimeType('audio/mp3'); +is($eh->canShowDebug, 0, 'canShowDebug: returns 0 if mime type is wrong'); + +$session->http->setMimeType('text/html'); +$session->setting->set('debugIp', ''); +is($eh->canShowDebug, 1, 'canShowDebug: returns 1 if debugIp is empty string'); + +$session->setting->set('debugIp', '10.0.0.5/32, 192.168.0.4/30'); +$newEnv{REMOTE_ADDR} = '172.17.0.5'; +is($eh->canShowDebug, 0, 'canShowDebug: returns 0 if debugIp is set and IP address is out of filter'); +$newEnv{REMOTE_ADDR} = '10.0.0.5'; +is($eh->canShowDebug, 1, 'canShowDebug: returns 1 if debugIp is set and IP address matches filter'); +$newEnv{REMOTE_ADDR} = '192.168.0.5'; +is($eh->canShowDebug, 1, 'canShowDebug: returns 1 if debugIp is set and IP address matches filter'); + +#################################################### +# +# canShowPerformanceIndicators +# +#################################################### + +my $origShowPerf = $session->setting->get('showPerformanceIndicators'); + +$session->setting->set('showPerformanceIndicators', 0); +is($eh->canShowPerformanceIndicators, 0, 'canShowPerformanceIndicators: returns 0 if not enabled'); + +$session->setting->set('showPerformanceIndicators', 1); +$session->setting->set('debugIp', ''); +is($eh->canShowPerformanceIndicators, 1, 'canShowPerformanceIndicators: returns 1 if debugIp is blank'); + +$session->setting->set('debugIp', '10.0.0.5/32, 192.168.0.4/30'); +$newEnv{REMOTE_ADDR} = '172.17.0.5'; +is($eh->canShowPerformanceIndicators, 0, 'canShowPerformanceIndicators: returns 0 if debugIp is set and IP address does not match'); +$newEnv{REMOTE_ADDR} = '10.0.0.5'; +is($eh->canShowPerformanceIndicators, 1, 'canShowPerformanceIndicators: returns 0 if debugIp is set and IP address matches exactly'); +$newEnv{REMOTE_ADDR} = '192.168.0.5'; +is($eh->canShowPerformanceIndicators, 1, 'canShowPerformanceIndicators: returns 0 if debugIp is set and IP address matches subnet'); + +END { + $session->setting->set('debugIp', $origDebugIp); + $session->setting->set('showDebug', $origShowDebug); + + $session->setting->set('showPerformanceIndicators', $origShowPerf); +}