diff --git a/lemonldap-ng-common/lib/Lemonldap/NG/Common/Conf/RESTServer.pm b/lemonldap-ng-common/lib/Lemonldap/NG/Common/Conf/RESTServer.pm index ba046da11..9fe481c8a 100644 --- a/lemonldap-ng-common/lib/Lemonldap/NG/Common/Conf/RESTServer.pm +++ b/lemonldap-ng-common/lib/Lemonldap/NG/Common/Conf/RESTServer.pm @@ -541,9 +541,10 @@ sub authChoiceModules { my @res; foreach my $k ( sort keys %$value ) { my $data = [ split /;/, $value->{$k} ]; - eval {$data->[5] = from_json($data->[5]) if $data->[5] }; - if($@){ - $self->logger->error("Bad value in choice over parameters, deleted ($@)"); + eval { $data->[5] = from_json( $data->[5] ) if $data->[5] }; + if ($@) { + $self->logger->error( + "Bad value in choice over parameters, deleted ($@)"); } push @res, { diff --git a/lemonldap-ng-handler/lib/Lemonldap/NG/Handler/Main/Init.pm b/lemonldap-ng-handler/lib/Lemonldap/NG/Handler/Main/Init.pm index 018ddbe6e..5aed26b59 100644 --- a/lemonldap-ng-handler/lib/Lemonldap/NG/Handler/Main/Init.pm +++ b/lemonldap-ng-handler/lib/Lemonldap/NG/Handler/Main/Init.pm @@ -107,7 +107,7 @@ sub statusInit { exec $perl_exec, '-MLemonldap::NG::Handler::Lib::Status', # Insert @INC in Perl path - map( { "-I$_" } @INC ), + map( {"-I$_"} @INC ), # Command to launch '-e', '&Lemonldap::NG::Handler::Lib::Status::run()', diff --git a/lemonldap-ng-handler/t/63-Lemonldap-NG-Handler-PSGI-Try.t b/lemonldap-ng-handler/t/63-Lemonldap-NG-Handler-PSGI-Try.t index 6b9e8be7b..b7affe815 100644 --- a/lemonldap-ng-handler/t/63-Lemonldap-NG-Handler-PSGI-Try.t +++ b/lemonldap-ng-handler/t/63-Lemonldap-NG-Handler-PSGI-Try.t @@ -21,7 +21,7 @@ ok( cookieName => 'lemonldap', securedCookie => 0, https => 0, - userLogger => 'Lemonldap::NG::Common::Logger::Null', + userLogger => 'Lemonldap::NG::Common::Logger::Null', } ), 'initialization' diff --git a/lemonldap-ng-handler/t/test-psgi-lib.pm b/lemonldap-ng-handler/t/test-psgi-lib.pm index 780e4f4ea..c62c3d1b1 100644 --- a/lemonldap-ng-handler/t/test-psgi-lib.pm +++ b/lemonldap-ng-handler/t/test-psgi-lib.pm @@ -29,7 +29,7 @@ sub init { cookieName => 'lemonldap', securedCookie => 0, https => 0, - logger => 'Lemonldap::NG::Common::Logger::Std', + logger => 'Lemonldap::NG::Common::Logger::Std', %$prms ); ok( diff --git a/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/Attributes.pm b/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/Attributes.pm index a23523812..aa97b326d 100644 --- a/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/Attributes.pm +++ b/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/Attributes.pm @@ -8,17 +8,17 @@ sub types { 'array' => { 'test' => sub { 1; - } + } }, 'authParamsText' => { 'test' => sub { 1; - } + } }, 'blackWhiteList' => { 'test' => sub { 1; - } + } }, 'bool' => { 'msgFail' => '__notABoolean__', @@ -36,17 +36,17 @@ sub types { split( /\n/, $@, 0 ) ) ); return $err ? ( 1, "__badExpression__: $err" ) : 1; - } + } }, 'catAndAppList' => { 'test' => sub { 1; - } + } }, 'file' => { 'test' => sub { 1; - } + } }, 'hostname' => { 'form' => 'text', @@ -80,48 +80,48 @@ qr/^(?:(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.])*(?:[a-zA-Z][-a- if $_ =~ /exportedvars$/i and defined $conf->{$_}{$val}; } return 1, "__unknownAttrOrMacro__: $val"; - } + } }, 'longtext' => { 'test' => sub { 1; - } + } }, 'menuApp' => { 'test' => sub { 1; - } + } }, 'menuCat' => { 'test' => sub { 1; - } + } }, 'oidcmetadatajson' => { 'test' => sub { 1; - } + } }, 'oidcmetadatajwks' => { 'test' => sub { 1; - } + } }, 'oidcOPMetaDataNode' => { 'test' => sub { 1; - } + } }, 'oidcRPMetaDataNode' => { 'test' => sub { 1; - } + } }, 'password' => { 'msgFail' => '__malformedValue__', 'test' => sub { 1; - } + } }, 'pcre' => { 'form' => 'text', @@ -132,7 +132,7 @@ qr/^(?:(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.])*(?:[a-zA-Z][-a- } }; return $@ ? ( 0, "__badRegexp__: $@" ) : 1; - } + } }, 'PerlModule' => { 'form' => 'text', @@ -142,17 +142,17 @@ qr/^(?:(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.])*(?:[a-zA-Z][-a- 'portalskin' => { 'test' => sub { 1; - } + } }, 'portalskinbackground' => { 'test' => sub { 1; - } + } }, 'post' => { 'test' => sub { 1; - } + } }, 'RSAPrivateKey' => { 'test' => sub { @@ -160,7 +160,7 @@ qr/^(?:(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.])*(?:[a-zA-Z][-a- m[^(?:(?:\-+\s*BEGIN\s+(?:RSA\s+)?PRIVATE\s+KEY\s*\-+\r?\n)?(?:Proc-Type:.*\r?\nDEK-Info:.*\r?\n[\r\n]*)?[a-zA-Z0-9/\+\r\n]+={0,2}(?:\r?\n\-+\s*END\s+(?:RSA\s+)PRIVATE\s+KEY\s*\-+)?[\r\n]*)?$]s ? 1 : ( 1, '__badPemEncoding__' ); - } + } }, 'RSAPublicKey' => { 'test' => sub { @@ -168,7 +168,7 @@ m[^(?:(?:\-+\s*BEGIN\s+(?:RSA\s+)?PRIVATE\s+KEY\s*\-+\r?\n)?(?:Proc-Type:.*\r?\n m[^(?:(?:\-+\s*BEGIN\s+PUBLIC\s+KEY\s*\-+\r?\n)?[a-zA-Z0-9/\+\r\n]+={0,2}(?:\r?\n\-+\s*END\s+PUBLIC\s+KEY\s*\-+)?[\r\n]*)?$]s ? 1 : ( 1, '__badPemEncoding__' ); - } + } }, 'RSAPublicKeyOrCertificate' => { 'test' => sub { @@ -176,37 +176,37 @@ m[^(?:(?:\-+\s*BEGIN\s+PUBLIC\s+KEY\s*\-+\r?\n)?[a-zA-Z0-9/\+\r\n]+={0,2}(?:\r?\ m[^(?:(?:\-+\s*BEGIN\s+(?:PUBLIC\s+KEY|CERTIFICATE)\s*\-+\r?\n)?[a-zA-Z0-9/\+\r\n]+={0,2}(?:\r?\n\-+\s*END\s+(?:PUBLIC\s+KEY|CERTIFICATE)\s*\-+)?[\r\n]*)?$]s ? 1 : ( 1, '__badPemEncoding__' ); - } + } }, 'rule' => { 'test' => sub { 1; - } + } }, 'samlAssertion' => { 'test' => sub { 1; - } + } }, 'samlAttribute' => { 'test' => sub { 1; - } + } }, 'samlIDPMetaDataNode' => { 'test' => sub { 1; - } + } }, 'samlService' => { 'test' => sub { 1; - } + } }, 'samlSPMetaDataNode' => { 'test' => sub { 1; - } + } }, 'select' => { 'test' => sub { @@ -216,19 +216,19 @@ m[^(?:(?:\-+\s*BEGIN\s+(?:PUBLIC\s+KEY|CERTIFICATE)\s*\-+\r?\n)?[a-zA-Z0-9/\+\r\ return $test ? 1 : ( 1, "Invalid value '$_[0]' for this select" ); - } + } }, 'subContainer' => { 'keyTest' => qr/\w/, 'test' => sub { 1; - } + } }, 'text' => { 'msgFail' => '__malformedValue__', 'test' => sub { 1; - } + } }, 'trool' => { 'msgFail' => '__authorizedValues__: -1, 0, 1', @@ -1050,7 +1050,7 @@ qr/^(?:\*\.)?(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.])*(?:[a-zA-Z][ split( /\n/, $@, 0 ) ) ); return $err ? ( 1, "__badExpression__: $err" ) : 1; - } + } }, 'type' => 'keyTextContainer' }, @@ -1219,7 +1219,7 @@ qr/^(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.])*(?:[a-zA-Z][-a-zA-Z0- and defined $conf->{$_}{$val}; } return 1, "__unknownAttrOrMacro__: $val"; - } + } }, 'type' => 'doubleHash' }, @@ -1502,7 +1502,7 @@ qr/^(?:\*\.)?(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.])*(?:[a-zA-Z][ split( /\n/, $@, 0 ) ) ); return $err ? ( 1, "__badExpression__: $err" ) : 1; - } + } }, 'type' => 'ruleContainer' }, diff --git a/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/Build/Attributes.pm b/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/Build/Attributes.pm index 55761958a..54d807e3e 100644 --- a/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/Build/Attributes.pm +++ b/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/Build/Attributes.pm @@ -29,15 +29,15 @@ sub types { # Simple text types text => { - test => sub {1}, + test => sub { 1 }, msgFail => '__malformedValue__', }, password => { - test => sub {1}, + test => sub { 1 }, msgFail => '__malformedValue__', }, longtext => { - test => sub {1} + test => sub { 1 } }, url => { form => 'text', @@ -57,7 +57,7 @@ sub types { pcre => { form => 'text', test => sub { - eval {qr/$_[0]/}; + eval { qr/$_[0]/ }; return $@ ? ( 0, "__badRegexp__: $@" ) : (1); }, }, @@ -66,11 +66,11 @@ sub types { test => sub { my ( $val, $conf ) = @_; return 1 - if ( defined $conf->{macros}->{$val} + if ( defined $conf->{macros}->{$val} or $val eq '_timezone' ); foreach ( keys %$conf ) { return 1 - if ( $_ =~ /exportedvars$/i + if ( $_ =~ /exportedvars$/i and defined $conf->{$_}->{$val} ); } return ( 1, "__unknownAttrOrMacro__: $val" ); @@ -102,27 +102,27 @@ sub types { }, subContainer => { keyTest => qr/\w/, - test => sub {1}, + test => sub { 1 }, }, select => { test => sub { my $test = grep ( { $_ eq $_[0] } map ( { $_->{k} } @{ $_[2]->{select} } ) ); return $test - ? 1 - : ( 1, "Invalid value '$_[0]' for this select" ); + ? 1 + : ( 1, "Invalid value '$_[0]' for this select" ); }, }, # Files type (long text) file => { - test => sub {1} + test => sub { 1 } }, RSAPublicKey => { test => sub { return ( - $_[0] - =~ /^(?:(?:\-+\s*BEGIN\s+PUBLIC\s+KEY\s*\-+\r?\n)?[a-zA-Z0-9\/\+\r\n]+={0,2}(?:\r?\n\-+\s*END\s+PUBLIC\s+KEY\s*\-+)?[\r\n]*)?$/s + $_[0] =~ +/^(?:(?:\-+\s*BEGIN\s+PUBLIC\s+KEY\s*\-+\r?\n)?[a-zA-Z0-9\/\+\r\n]+={0,2}(?:\r?\n\-+\s*END\s+PUBLIC\s+KEY\s*\-+)?[\r\n]*)?$/s ? (1) : ( 1, '__badPemEncoding__' ) ); @@ -131,8 +131,8 @@ sub types { 'RSAPublicKeyOrCertificate' => { 'test' => sub { return ( - $_[0] - =~ /^(?:(?:\-+\s*BEGIN\s+(?:PUBLIC\s+KEY|CERTIFICATE)\s*\-+\r?\n)?[a-zA-Z0-9\/\+\r\n]+={0,2}(?:\r?\n\-+\s*END\s+(?:PUBLIC\s+KEY|CERTIFICATE)\s*\-+)?[\r\n]*)?$/s + $_[0] =~ +/^(?:(?:\-+\s*BEGIN\s+(?:PUBLIC\s+KEY|CERTIFICATE)\s*\-+\r?\n)?[a-zA-Z0-9\/\+\r\n]+={0,2}(?:\r?\n\-+\s*END\s+(?:PUBLIC\s+KEY|CERTIFICATE)\s*\-+)?[\r\n]*)?$/s ? (1) : ( 1, '__badPemEncoding__' ) ); @@ -141,8 +141,8 @@ sub types { RSAPrivateKey => { test => sub { return ( - $_[0] - =~ /^(?:(?:\-+\s*BEGIN\s+(?:RSA\s+)?PRIVATE\s+KEY\s*\-+\r?\n)?(?:Proc-Type:.*\r?\nDEK-Info:.*\r?\n[\r\n]*)?[a-zA-Z0-9\/\+\r\n]+={0,2}(?:\r?\n\-+\s*END\s+(?:RSA\s+)PRIVATE\s+KEY\s*\-+)?[\r\n]*)?$/s + $_[0] =~ +/^(?:(?:\-+\s*BEGIN\s+(?:RSA\s+)?PRIVATE\s+KEY\s*\-+\r?\n)?(?:Proc-Type:.*\r?\nDEK-Info:.*\r?\n[\r\n]*)?[a-zA-Z0-9\/\+\r\n]+={0,2}(?:\r?\n\-+\s*END\s+(?:RSA\s+)PRIVATE\s+KEY\s*\-+)?[\r\n]*)?$/s ? (1) : ( 1, '__badPemEncoding__' ) ); @@ -150,13 +150,13 @@ sub types { }, authParamsText => { - test => sub {1} + test => sub { 1 } }, blackWhiteList => { - test => sub {1} + test => sub { 1 } }, catAndAppList => { - test => sub {1} + test => sub { 1 } }, keyText => { keyTest => qr/^[a-zA-Z0-9_]+$/, @@ -164,52 +164,52 @@ sub types { msgFail => '__badValue__', }, menuApp => { - test => sub {1} + test => sub { 1 } }, menuCat => { - test => sub {1} + test => sub { 1 } }, oidcOPMetaDataNode => { - test => sub {1} + test => sub { 1 } }, oidcRPMetaDataNode => { - test => sub {1} + test => sub { 1 } }, oidcmetadatajson => { - test => sub {1} + test => sub { 1 } }, oidcmetadatajwks => { - test => sub {1} + test => sub { 1 } }, portalskin => { - test => sub {1} + test => sub { 1 } }, portalskinbackground => { - test => sub {1} + test => sub { 1 } }, post => { - test => sub {1} + test => sub { 1 } }, rule => { - test => sub {1} + test => sub { 1 } }, samlAssertion => { - test => sub {1} + test => sub { 1 } }, samlAttribute => { - test => sub {1} + test => sub { 1 } }, samlIDPMetaDataNode => { - test => sub {1} + test => sub { 1 } }, samlSPMetaDataNode => { - test => sub {1} + test => sub { 1 } }, samlService => { - test => sub {1} + test => sub { 1 } }, array => { - test => sub {1} + test => sub { 1 } }, }; } @@ -221,7 +221,7 @@ sub attributes { checkTime => { type => 'int', documentation => - 'Timeout to check new configuration in local cache', + 'Timeout to check new configuration in local cache', default => 600, flags => 'hp', }, @@ -229,7 +229,7 @@ sub attributes { type => 'array', documentation => 'Alterable session keys by user itself', default => - [ '_appsListOrder', '_oidcConnectedRP', '_oidcConsents' ], + [ '_appsListOrder', '_oidcConnectedRP', '_oidcConsents' ], }, configStorage => { type => 'text', @@ -252,14 +252,12 @@ sub attributes { documentation => 'Enable Cross Domain Authentication', }, cfgAuthor => { - type => 'text', - documentation => - 'Name of the author of the current configuration', + type => 'text', + documentation => 'Name of the author of the current configuration', }, cfgAuthorIP => { - type => 'text', - documentation => - 'Uploader IP address of the current configuration', + type => 'text', + documentation => 'Uploader IP address of the current configuration', }, cfgDate => { type => 'int', @@ -281,7 +279,7 @@ sub attributes { confirmFormMethod => { type => "select", select => - [ { k => 'get', v => 'GET' }, { k => 'post', v => 'POST' }, ], + [ { k => 'get', v => 'GET' }, { k => 'post', v => 'POST' }, ], default => 'post', documentation => 'HTTP method for confirm page form', }, @@ -301,7 +299,7 @@ sub attributes { infoFormMethod => { type => "select", select => - [ { k => 'get', v => 'GET' }, { k => 'post', v => 'POST' }, ], + [ { k => 'get', v => 'GET' }, { k => 'post', v => 'POST' }, ], default => 'get', documentation => 'HTTP method for info page form', }, @@ -316,11 +314,10 @@ sub attributes { documentation => 'Use javascript for redirections', }, logoutServices => { - type => 'keyTextContainer', - help => 'logoutforward.html', - default => {}, - documentation => - 'Send logout trough GET request to these services', + type => 'keyTextContainer', + help => 'logoutforward.html', + default => {}, + documentation => 'Send logout trough GET request to these services', }, maintenance => { default => 0, @@ -358,24 +355,24 @@ sub attributes { default => '_user', help => 'monitoring.html', documentation => - 'Session parameter to display connected user in portal', + 'Session parameter to display connected user in portal', }, redirectFormMethod => { type => "select", select => - [ { k => 'get', v => 'GET' }, { k => 'post', v => 'POST' }, ], + [ { k => 'get', v => 'GET' }, { k => 'post', v => 'POST' }, ], default => 'get', documentation => 'HTTP method for redirect page form', }, reloadUrls => { - type => 'keyTextContainer', - help => 'configlocation.html#configuration_reload', - keyTest => qr/^$Regexp::Common::URI::RFC2396::host(?::\d+)?$/, - test => $url, - msgFail => '__badUrl__', + type => 'keyTextContainer', + help => 'configlocation.html#configuration_reload', + keyTest => qr/^$Regexp::Common::URI::RFC2396::host(?::\d+)?$/, + test => $url, + msgFail => '__badUrl__', documentation => 'URL to call on reload', }, - portalMainLogo => { + portalMainLogo => { type => 'text', default => 'common/logos/logo_llng_400px.png', documentation => 'Portal main logo path', @@ -407,7 +404,7 @@ sub attributes { skipRenewConfirmation => { type => 'bool', documentation => - 'Avoid asking confirmation when an Issuer asks to renew auth', + 'Avoid asking confirmation when an Issuer asks to renew auth', }, # Loggers (ini only) @@ -449,9 +446,9 @@ sub attributes { # Manager or PSGI protected apps protection => { - type => 'text', - test => qr/^(?:none|authenticate|manager|)$/, - msgFail => '__authorizedValues__: none authenticate manager', + type => 'text', + test => qr/^(?:none|authenticate|manager|)$/, + msgFail => '__authorizedValues__: none authenticate manager', documentation => 'Manager protection method', flags => 'hm', }, @@ -467,8 +464,7 @@ sub attributes { keyTest => qr/\w/, help => 'portalmenu.html#categories_and_applications', default => { - default => - { catname => 'Default category', type => "category" } + default => { catname => 'Default category', type => "category" } }, documentation => 'Applications list', }, @@ -481,7 +477,7 @@ sub attributes { type => 'bool', default => 0, documentation => - 'Show error if mail is not found in password reset process', + 'Show error if mail is not found in password reset process', }, portalOpenLinkInNewWindow => { type => 'bool', @@ -504,22 +500,26 @@ sub attributes { documentation => 'Background image of portal skin', select => [ { k => "", v => 'None' }, - { k => "1280px-Anse_Source_d'Argent_2-La_Digue.jpg", + { + k => "1280px-Anse_Source_d'Argent_2-La_Digue.jpg", v => 'Anse' }, - { k => - "1280px-Autumn-clear-water-waterfall-landscape_-_Virginia_-_ForestWander.jpg", + { + k => +"1280px-Autumn-clear-water-waterfall-landscape_-_Virginia_-_ForestWander.jpg", v => 'Waterfall' }, { k => "1280px-BrockenSnowedTrees.jpg", v => 'Snowed Trees' }, - { k => - "1280px-Cedar_Breaks_National_Monument_partially.jpg", + { + k => "1280px-Cedar_Breaks_National_Monument_partially.jpg", v => 'National Monument' }, - { k => "1280px-Parry_Peak_from_Winter_Park.jpg", + { + k => "1280px-Parry_Peak_from_Winter_Park.jpg", v => 'Winter' }, - { k => "Aletschgletscher_mit_Pinus_cembra1.jpg", + { + k => "Aletschgletscher_mit_Pinus_cembra1.jpg", v => 'Pinus' }, ], @@ -565,13 +565,13 @@ sub attributes { default => 0, type => 'bool', documentation => - 'Enable force to authenticate when displaying portal', + 'Enable force to authenticate when displaying portal', }, portalForceAuthnInterval => { default => 5, type => 'int', documentation => - 'Maximun interval in seconds since last authentifcation to force reauthentication', +'Maximun interval in seconds since last authentifcation to force reauthentication', }, bruteForceProtection => { default => 0, @@ -582,18 +582,18 @@ sub attributes { default => 30, type => 'int', documentation => - 'Brute force attack protection -> Tempo before try again', + 'Brute force attack protection -> Tempo before try again', }, bruteForceProtectionMaxAge => { default => 300, type => 'int', documentation => - 'Brute force attack protection -> Max age third failed login', + 'Brute force attack protection -> Max age third failed login', }, grantSessionRules => { type => 'grantContainer', keyTest => $perlExpr, - test => sub {1}, + test => sub { 1 }, documentation => 'Rules to grant sessions', }, hiddenAttributes => { @@ -629,7 +629,7 @@ sub attributes { type => 'text', default => "'self'", documentation => - 'Authorizated Ajax destination for Content-Security-Policy', + 'Authorizated Ajax destination for Content-Security-Policy', }, cspFont => { type => 'text', @@ -652,7 +652,7 @@ sub attributes { documentation => 'Regular expression to create a random password', }, trustedDomains => - { type => 'text', documentation => 'Trusted domains', }, + { type => 'text', documentation => 'Trusted domains', }, storePassword => { default => 0, type => 'bool', @@ -788,10 +788,10 @@ sub attributes { flags => 'hp', }, domain => { - type => 'text', - test => qr/^(?:$Regexp::Common::URI::RFC2396::hostname)?$/, - msgFail => '__badDomainName__', - default => 'example.com', + type => 'text', + test => qr/^(?:$Regexp::Common::URI::RFC2396::hostname)?$/, + msgFail => '__badDomainName__', + default => 'example.com', documentation => 'DNS domain', flags => 'hp', }, @@ -886,7 +886,7 @@ sub attributes { groups => { type => 'keyTextContainer', help => - 'exportedvars.html#extend_variables_using_macros_and_groups', + 'exportedvars.html#extend_variables_using_macros_and_groups', test => $perlExpr, default => {}, documentation => 'Groups', @@ -894,7 +894,7 @@ sub attributes { macros => { type => 'keyTextContainer', help => - 'exportedvars.html#extend_variables_using_macros_and_groups', + 'exportedvars.html#extend_variables_using_macros_and_groups', keyTest => qr/^[_a-zA-Z][a-zA-Z0-9_]*$/, keyMsgFail => '__badMacroName__', test => $perlExpr, @@ -915,7 +915,7 @@ sub attributes { 'Directory' => '/var/lib/lemonldap-ng/sessions/', 'LockDirectory' => '/var/lib/lemonldap-ng/sessions/lock/', 'generateModule' => - 'Lemonldap::NG::Common::Apache::Session::Generate::SHA256', + 'Lemonldap::NG::Common::Apache::Session::Generate::SHA256', }, documentation => 'Session backend module options', flags => 'hp', @@ -1014,11 +1014,11 @@ sub attributes { test => sub { my ( $val, $conf ) = @_; return 1 - if ( defined $conf->{macros}->{$val} + if ( defined $conf->{macros}->{$val} or $val eq '_timezone' ); foreach ( keys %$conf ) { return 1 - if ( $_ =~ /exportedvars$/i + if ( $_ =~ /exportedvars$/i and defined $conf->{$_}->{$val} ); } return ( 1, "__unknownAttrOrMacro__: $val" ); @@ -1034,10 +1034,9 @@ sub attributes { documentation => 'Send a mail when password is changed', }, portalRequireOldPassword => { - default => 1, - type => 'bool', - documentation => - 'Old password is required to change the password', + default => 1, + type => 'bool', + documentation => 'Old password is required to change the password', }, hideOldPassword => { default => 0, @@ -1047,7 +1046,7 @@ sub attributes { # Mails mailBody => - { type => 'longtext', documentation => 'Custom mail body', }, + { type => 'longtext', documentation => 'Custom mail body', }, mailCharset => { type => 'text', default => 'utf-8', @@ -1066,8 +1065,7 @@ sub attributes { default => 'noreply@example.com', documentation => 'Sender email', }, - mailReplyTo => - { type => 'text', documentation => 'Reply-To address' }, + mailReplyTo => { type => 'text', documentation => 'Reply-To address' }, mailSessionKey => { type => 'text', default => 'mail', @@ -1090,7 +1088,7 @@ sub attributes { SMTPServer => { type => 'text', default => '', - test => qr/^(?:$Regexp::Common::URI::RFC2396::host(?::\d+)?)?$/, + test => qr/^(?:$Regexp::Common::URI::RFC2396::host(?::\d+)?)?$/, documentation => 'SMTP Server', }, SMTPPort => { @@ -1185,7 +1183,7 @@ sub attributes { u2fAuthnLevel => { type => 'int', documentation => - 'Authentication level for users authentified by password+U2F' + 'Authentication level for users authentified by password+U2F' }, u2fUserCanRemoveKey => { type => 'bool', @@ -1207,7 +1205,7 @@ sub attributes { totp2fAuthnLevel => { type => 'int', documentation => - 'Authentication level for users authentified by password+TOTP' + 'Authentication level for users authentified by password+TOTP' }, totp2fIssuer => { type => 'text', @@ -1232,7 +1230,7 @@ sub attributes { type => 'bool', default => 0, documentation => - 'Display existing TOTP secret in registration form', + 'Display existing TOTP secret in registration form', }, totp2fUserCanChangeKey => { type => 'bool', @@ -1254,7 +1252,7 @@ sub attributes { utotp2fAuthnLevel => { type => 'int', documentation => - 'Authentication level for users authentified by password+(U2F or TOTP)' +'Authentication level for users authentified by password+(U2F or TOTP)' }, # External second factor @@ -1274,7 +1272,7 @@ sub attributes { ext2fAuthnLevel => { type => 'int', documentation => - 'Authentication level for users authentified by External second factor' +'Authentication level for users authentified by External second factor' }, ext2fLogo => { type => 'text', @@ -1314,7 +1312,7 @@ sub attributes { rest2fAuthnLevel => { type => 'int', documentation => - 'Authentication level for users authentified by REST second factor' +'Authentication level for users authentified by REST second factor' }, rest2fLogo => { type => 'text', @@ -1335,7 +1333,7 @@ sub attributes { yubikey2fAuthnLevel => { type => 'int', documentation => - 'Authentication level for users authentified by Yubikey second factor' +'Authentication level for users authentified by Yubikey second factor' }, yubikey2fClientID => { type => 'text', @@ -1424,7 +1422,7 @@ sub attributes { exportedAttr => { type => 'text', documentation => - 'List of attributes to export by SOAP or REST servers', + 'List of attributes to export by SOAP or REST servers', }, wsdlServer => { type => 'bool', @@ -1452,7 +1450,7 @@ sub attributes { help => 'writingrulesand_headers.html#rules', test => { keyTest => sub { - eval {qr/$_[0]/}; + eval { qr/$_[0]/ }; return $@ ? 0 : 1; }, keyMsgFail => '__badRegexp__', @@ -1461,15 +1459,15 @@ sub attributes { my $s = $val; if ( $s =~ s/^logout(?:_(?:sso|app(?:_sso)?))?\s*// ) { return $s =~ m{^(?:https?://.*)?$} - ? (1) - : ( 0, '__badUrl__' ); + ? (1) + : ( 0, '__badUrl__' ); } $s =~ s/\b(accept|deny|unprotect|skip)\b/1/g; no warnings( 'redefine', 'uninitialized' ); eval $s; my $err = join( '', grep { $_ =~ /Undefined subroutine/ ? () : $_ } - split( /\n/, $@ ) ); + split( /\n/, $@ ) ); return $err ? ( 1, "__badExpression__: $err" ) : (1); }, msgFail => '__badExpression__', @@ -1495,9 +1493,9 @@ sub attributes { eval $s; my $err = join( '', grep { $_ =~ /Undefined subroutine/ ? () : $_ } - split( /\n/, $@ ) ); + split( /\n/, $@ ) ); return $err ? ( 1, "__badExpression__: $err" ) : (1); - } + } }, documentation => 'Virtualhost headers', flags => 'h', @@ -1505,7 +1503,7 @@ sub attributes { post => { type => 'postContainer', help => 'formreplay.html', - test => sub {1}, + test => sub { 1 }, keyTest => qr/^(?:\*\.)?$Regexp::Common::URI::RFC2396::hostname$/, keyMsgFail => '__badHostname__', documentation => 'Virtualhost urls/Data to post', @@ -1603,7 +1601,7 @@ sub attributes { # CAS IDP casAttr => - { type => 'text', documentation => 'Pivot attribute for CAS', }, + { type => 'text', documentation => 'Pivot attribute for CAS', }, casAttributes => { type => 'keyTextContainer', documentation => 'CAS exported attributes', @@ -1762,7 +1760,7 @@ sub attributes { samlAttributeAuthorityDescriptorAttributeServiceSOAP => { type => 'samlService', default => 'urn:oasis:names:tc:SAML:2.0:bindings:SOAP;' - . '#PORTAL#/saml/AA/SOAP;', + . '#PORTAL#/saml/AA/SOAP;', documentation => 'SAML Attribute Authority SOAP', }, samlServicePrivateKeySig => { @@ -1803,7 +1801,7 @@ sub attributes { type => 'bool', default => 0, documentation => - 'Use certificate instead of public key in SAML responses', + 'Use certificate instead of public key in SAML responses', }, samlIdPResolveCookie => { type => 'text', @@ -1832,7 +1830,7 @@ sub attributes { type => 'int', default => 3, documentation => - 'SAML authn context password protected transport level', + 'SAML authn context password protected transport level', }, samlAuthnContextMapTLSClient => { type => 'int', @@ -1901,45 +1899,45 @@ sub attributes { samlIDPSSODescriptorSingleSignOnServiceHTTPRedirect => { type => 'samlService', default => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect;' - . '#PORTAL#/saml/singleSignOn;', + . '#PORTAL#/saml/singleSignOn;', documentation => 'SAML IDP SSO HTTP Redirect', }, samlIDPSSODescriptorSingleSignOnServiceHTTPPost => { type => 'samlService', default => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST;' - . '#PORTAL#/saml/singleSignOn;', + . '#PORTAL#/saml/singleSignOn;', documentation => 'SAML IDP SSO HTTP POST', }, samlIDPSSODescriptorSingleSignOnServiceHTTPArtifact => { type => 'samlService', default => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact;' - . '#PORTAL#/saml/singleSignOnArtifact;', + . '#PORTAL#/saml/singleSignOnArtifact;', documentation => 'SAML IDP SSO HTTP Artifact', }, samlIDPSSODescriptorSingleLogoutServiceHTTPRedirect => { type => 'samlService', default => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect;' - . '#PORTAL#/saml/singleLogout;' - . '#PORTAL#/saml/singleLogoutReturn', + . '#PORTAL#/saml/singleLogout;' + . '#PORTAL#/saml/singleLogoutReturn', documentation => 'SAML IDP SLO HTTP Redirect', }, samlIDPSSODescriptorSingleLogoutServiceHTTPPost => { type => 'samlService', default => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST;' - . '#PORTAL#/saml/singleLogout;' - . '#PORTAL#/saml/singleLogoutReturn', + . '#PORTAL#/saml/singleLogout;' + . '#PORTAL#/saml/singleLogoutReturn', documentation => 'SAML IDP SLO HTTP POST', }, samlIDPSSODescriptorSingleLogoutServiceSOAP => { type => 'samlService', default => 'urn:oasis:names:tc:SAML:2.0:bindings:SOAP;' - . '#PORTAL#/saml/singleLogoutSOAP;', + . '#PORTAL#/saml/singleLogoutSOAP;', documentation => 'SAML IDP SLO SOAP', }, samlIDPSSODescriptorArtifactResolutionServiceArtifact => { type => 'samlAssertion', default => '1;0;urn:oasis:names:tc:SAML:2.0:bindings:SOAP;' - . '#PORTAL#/saml/artifact', + . '#PORTAL#/saml/artifact', documentation => 'SAML IDP artifact resolution service', }, @@ -1979,8 +1977,8 @@ sub attributes { my $res = 1; my %entityIds; foreach my $idpId ( keys %$v ) { - unless ( $v->{$idpId}->{samlIDPMetaDataXML} - =~ /entityID="(.+?)"/si ) + unless ( $v->{$idpId}->{samlIDPMetaDataXML} =~ + /entityID="(.+?)"/si ) { push @msg, "$idpId SAML metadata has ne EntityID"; $res = 0; @@ -1989,7 +1987,7 @@ sub attributes { my $eid = $1; if ( defined $entityIds{$eid} ) { push @msg, - "$idpId and $entityIds{$eid} have the same SAML EntityID"; +"$idpId and $entityIds{$eid} have the same SAML EntityID"; $res = 0; next; } @@ -2040,7 +2038,8 @@ sub attributes { select => [ { k => '', v => '' }, { k => 'kerberos', v => 'Kerberos' }, - { k => 'password-protected-transport', + { + k => 'password-protected-transport', v => 'Password protected transport' }, { k => 'password', v => 'Password' }, @@ -2152,40 +2151,40 @@ sub attributes { samlSPSSODescriptorSingleLogoutServiceHTTPRedirect => { type => 'samlService', default => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect;' - . '#PORTAL#/saml/proxySingleLogout;' - . '#PORTAL#/saml/proxySingleLogoutReturn', + . '#PORTAL#/saml/proxySingleLogout;' + . '#PORTAL#/saml/proxySingleLogoutReturn', documentation => 'SAML SP SLO HTTP Redirect', }, samlSPSSODescriptorSingleLogoutServiceHTTPPost => { type => 'samlService', default => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST;' - . '#PORTAL#/saml/proxySingleLogout;' - . '#PORTAL#/saml/proxySingleLogoutReturn', + . '#PORTAL#/saml/proxySingleLogout;' + . '#PORTAL#/saml/proxySingleLogoutReturn', documentation => 'SAML SP SLO HTTP POST', }, samlSPSSODescriptorSingleLogoutServiceSOAP => { type => 'samlService', default => 'urn:oasis:names:tc:SAML:2.0:bindings:SOAP;' - . '#PORTAL#/saml/proxySingleLogoutSOAP;', + . '#PORTAL#/saml/proxySingleLogoutSOAP;', documentation => 'SAML SP SLO SOAP', }, samlSPSSODescriptorAssertionConsumerServiceHTTPArtifact => { type => 'samlAssertion', default => - '1;0;urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact;' - . '#PORTAL#/saml/proxySingleSignOnArtifact', + '1;0;urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact;' + . '#PORTAL#/saml/proxySingleSignOnArtifact', documentation => 'SAML SP ACS HTTP artifact', }, samlSPSSODescriptorAssertionConsumerServiceHTTPPost => { type => 'samlAssertion', default => '0;1;urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST;' - . '#PORTAL#/saml/proxySingleSignOnPost', + . '#PORTAL#/saml/proxySingleSignOnPost', documentation => 'SAML SP ACS HTTP POST', }, samlSPSSODescriptorArtifactResolutionServiceArtifact => { type => 'samlAssertion', default => '1;0;urn:oasis:names:tc:SAML:2.0:bindings:SOAP;' - . '#PORTAL#/saml/artifact', + . '#PORTAL#/saml/artifact', documentation => 'SAML SP artifact resolution service ', }, samlSPMetaDataOptionsNameIDFormat => { @@ -2277,8 +2276,8 @@ sub attributes { { k => 'Demo', v => 'Demonstration' }, { k => 'Choice', v => 'authChoice' }, { k => 'Combination', v => 'combineMods' }, - { k => 'CAS', v => 'Central Authentication Service (CAS)' }, - { k => 'OpenID', v => 'OpenID' }, + { k => 'CAS', v => 'Central Authentication Service (CAS)' }, + { k => 'OpenID', v => 'OpenID' }, { k => 'OpenIDConnect', v => 'OpenID Connect' }, { k => 'SAML', v => 'SAML v2' }, { k => 'Proxy', v => 'Proxy' }, @@ -2341,7 +2340,7 @@ sub attributes { type => 'text', default => 'TOTP,U2F,Yubikey', documentation => - 'Available self-registration modules for second factor', + 'Available self-registration modules for second factor', }, # DEMO @@ -2414,9 +2413,9 @@ sub attributes { my $l = shift; my (@s) = split( /[\s,]+/, $l ); foreach my $s (@s) { - $s - =~ m{^(?:ldapi://[^/]*/?|\w[\w\-\.]*(?::\d{1,5})?|ldap(?:s|\+tls)?://\w[\w\-\.]*(?::\d{1,5})?/?.*)$}o - or return ( 0, "__badLdapUri__: \"$s\"" ); + $s =~ +m{^(?:ldapi://[^/]*/?|\w[\w\-\.]*(?::\d{1,5})?|ldap(?:s|\+tls)?://\w[\w\-\.]*(?::\d{1,5})?/?.*)$}o + or return ( 0, "__badLdapUri__: \"$s\"" ); } return 1; }, @@ -2474,7 +2473,7 @@ sub attributes { documentation => 'LDAP filter for mail search' }, LDAPFilter => - { type => 'text', documentation => 'Default LDAP filter' }, + { type => 'text', documentation => 'Default LDAP filter' }, AuthLDAPFilter => { type => 'text', documentation => 'LDAP filter for auth search' @@ -2499,7 +2498,7 @@ sub attributes { type => 'text', default => 'dn', documentation => - 'LDAP attribute name in user entry referenced as member in groups', +'LDAP attribute name in user entry referenced as member in groups', }, ldapGroupAttributeNameSearch => { type => 'text', @@ -2510,7 +2509,7 @@ sub attributes { type => 'text', default => 'dn', documentation => - 'LDAP attribute name in group entry referenced as member in groups', +'LDAP attribute name in group entry referenced as member in groups', }, ldapTimeout => { type => 'int', @@ -2637,7 +2636,7 @@ sub attributes { default => { proxy => 'http://auth.example.com/sessions', ns => - 'http://auth.example.com/Lemonldap/NG/Common/PSGI/SOAPService', +'http://auth.example.com/Lemonldap/NG/Common/PSGI/SOAPService', }, documentation => 'Apache::Session module parameters', }, @@ -2719,7 +2718,7 @@ sub attributes { }, linkedInUserField => { type => 'text', default => 'emailAddress' }, linkedInScope => - { type => 'text', default => 'r_basicprofile r_emailaddress' }, + { type => 'text', default => 'r_basicprofile r_emailaddress' }, # WebID webIDAuthnLevel => { @@ -2759,15 +2758,15 @@ sub attributes { dbiPasswordMailCol => { type => 'text', }, userPivot => { type => 'text', }, dbiAuthPasswordHash => - { type => 'text', help => 'authdbi.html#password', }, + { type => 'text', help => 'authdbi.html#password', }, dbiDynamicHashEnabled => - { type => 'bool', help => 'authdbi.html#password', }, + { type => 'bool', help => 'authdbi.html#password', }, dbiDynamicHashValidSchemes => - { type => 'text', help => 'authdbi.html#password', }, + { type => 'text', help => 'authdbi.html#password', }, dbiDynamicHashValidSaltedSchemes => - { type => 'text', help => 'authdbi.html#password', }, + { type => 'text', help => 'authdbi.html#password', }, dbiDynamicHashNewPasswordScheme => - { type => 'text', help => 'authdbi.html#password', }, + { type => 'text', help => 'authdbi.html#password', }, dbiExportedVars => { type => 'keyTextContainer', keyTest => qr/^!?[a-zA-Z][a-zA-Z0-9_-]*$/, @@ -2847,11 +2846,13 @@ sub attributes { type => 'authChoiceContainer', keyTest => qr/^(\d*)?[a-zA-Z0-9_]+$/, keyMsgFail => '__badChoiceKey__', - test => sub {1}, + test => sub { 1 }, select => [ - [ { k => 'Apache', v => 'Apache' }, + [ + { k => 'Apache', v => 'Apache' }, { k => 'AD', v => 'Active Directory' }, - { k => 'CAS', + { + k => 'CAS', v => 'Central Authentication Service (CAS)' }, { k => 'DBI', v => 'Database (DBI)' }, @@ -2876,8 +2877,10 @@ sub attributes { { k => 'WebID', v => 'WebID' }, { k => 'Custom', v => 'customModule' }, ], - [ { k => 'AD', v => 'Active Directory' }, - { k => 'CAS', + [ + { k => 'AD', v => 'Active Directory' }, + { + k => 'CAS', v => 'Central Authentication Service (CAS)' }, { k => 'DBI', v => 'Database (DBI)' }, @@ -2896,7 +2899,8 @@ sub attributes { { k => 'WebID', v => 'WebID' }, { k => 'Custom', v => 'customModule' }, ], - [ { k => 'AD', v => 'Active Directory' }, + [ + { k => 'AD', v => 'Active Directory' }, { k => 'DBI', v => 'Database (DBI)' }, { k => 'Demo', v => 'Demo' }, { k => 'LDAP', v => 'LDAP' }, @@ -2916,7 +2920,7 @@ sub attributes { combModules => { type => 'cmbModuleContainer', keyTest => qr/^\w+$/, - test => sub {1}, + test => sub { 1 }, documentation => 'Combination module description', select => [ { k => 'Apache', v => 'Apache' }, @@ -2933,8 +2937,8 @@ sub attributes { { k => 'Twitter', v => 'Twitter' }, { k => 'WebID', v => 'WebID' }, { k => 'Demo', v => 'Demonstration' }, - { k => 'CAS', v => 'Central Authentication Service (CAS)' }, - { k => 'OpenID', v => 'OpenID' }, + { k => 'CAS', v => 'Central Authentication Service (CAS)' }, + { k => 'OpenID', v => 'OpenID' }, { k => 'OpenIDConnect', v => 'OpenID Connect' }, { k => 'SAML', v => 'SAML v2' }, { k => 'Proxy', v => 'Proxy' }, @@ -3045,8 +3049,7 @@ sub attributes { 'loa-4' => 4, 'loa-5' => 5, }, - documentation => - 'OpenID Connect Authentication Context Class Ref', + documentation => 'OpenID Connect Authentication Context Class Ref', }, oidcServicePrivateKeySig => { type => 'RSAPrivateKey', }, oidcServicePublicKeySig => { type => 'RSAPublicKey', }, @@ -3055,10 +3058,9 @@ sub attributes { documentation => 'OpenID Connect Signature Key ID', }, oidcServiceAllowDynamicRegistration => { - type => 'bool', - default => 0, - documentation => - 'OpenID Connect allow dynamic client registration', + type => 'bool', + default => 0, + documentation => 'OpenID Connect allow dynamic client registration', }, oidcServiceAllowAuthorizationCodeFlow => { type => 'bool', @@ -3088,12 +3090,12 @@ sub attributes { oidcOPMetaDataNodes => { type => 'oidcOPMetaDataNodeContainer', help => - 'authopenidconnect.html#declare_the_openid_connect_provider_in_llng', +'authopenidconnect.html#declare_the_openid_connect_provider_in_llng', }, oidcRPMetaDataNodes => { type => 'oidcRPMetaDataNodeContainer', help => - 'idpopenidconnect.html#configuration_of_relying_party_in_llng', + 'idpopenidconnect.html#configuration_of_relying_party_in_llng', }, oidcOPMetaDataOptions => { type => 'subContainer', }, oidcRPMetaDataOptions => { type => 'subContainer', }, @@ -3115,7 +3117,7 @@ sub attributes { oidcOPMetaDataOptionsClientID => { type => 'text', }, oidcOPMetaDataOptionsClientSecret => { type => 'password', }, oidcOPMetaDataOptionsScope => - { type => 'text', default => 'openid profile' }, + { type => 'text', default => 'openid profile' }, oidcOPMetaDataOptionsDisplay => { type => 'select', select => [ @@ -3140,10 +3142,9 @@ sub attributes { default => 'client_secret_post', }, oidcOPMetaDataOptionsCheckJWTSignature => - { type => 'bool', default => 1 }, - oidcOPMetaDataOptionsIDTokenMaxAge => - { type => 'int', default => 30 }, - oidcOPMetaDataOptionsUseNonce => { type => 'bool', default => 1 }, + { type => 'bool', default => 1 }, + oidcOPMetaDataOptionsIDTokenMaxAge => { type => 'int', default => 30 }, + oidcOPMetaDataOptionsUseNonce => { type => 'bool', default => 1 }, oidcOPMetaDataOptionsDisplayName => { type => 'text', }, oidcOPMetaDataOptionsIcon => { type => 'text', }, oidcOPMetaDataOptionsStoreIDToken => { type => 'bool', default => 0 }, @@ -3182,12 +3183,12 @@ sub attributes { default => 'HS512', }, oidcRPMetaDataOptionsIDTokenExpiration => - { type => 'int', default => 3600 }, + { type => 'int', default => 3600 }, oidcRPMetaDataOptionsAccessTokenExpiration => - { type => 'int', default => 3600 }, + { type => 'int', default => 3600 }, oidcRPMetaDataOptionsRedirectUris => { type => 'text', }, oidcRPMetaDataOptionsExtraClaims => - { type => 'keyTextContainer', default => {} }, + { type => 'keyTextContainer', default => {} }, oidcRPMetaDataOptionsBypassConsent => { type => 'bool', help => 'openidconnectclaims.html', diff --git a/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/Conf/Parser.pm b/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/Conf/Parser.pm index 79e5ab1b3..720565309 100644 --- a/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/Conf/Parser.pm +++ b/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/Conf/Parser.pm @@ -69,7 +69,7 @@ has confChanged => ( ); # Properties required during build -has refConf => ( is => 'ro', isa => 'HashRef', required => 1 ); +has refConf => ( is => 'ro', isa => 'HashRef', required => 1 ); has req => ( is => 'ro', required => 1 ); has newConf => ( is => 'rw', isa => 'HashRef' ); has tree => ( is => 'rw', isa => 'ArrayRef' ); @@ -158,7 +158,7 @@ sub _scanNodes { hdebug("Looking to $name"); # subnode - my $subNodes = $leaf->{nodes} // $leaf->{_nodes}; + my $subNodes = $leaf->{nodes} // $leaf->{_nodes}; my $subNodesCond = $leaf->{nodes_cond} // $leaf->{_nodes_cond}; ################################## @@ -763,11 +763,12 @@ sub _scanNodes { foreach my $n (@$subNodes) { hdebug(" looking at $n subnode"); if ( ref $n->{data} and ref $n->{data} eq 'ARRAY' ) { + # authChoiceModules if ( $name eq 'authChoiceModules' ) { hdebug(' combModules'); $n->{data}->[5] ||= {}; - $n->{data}->[5] = to_json($n->{data}->[5]); + $n->{data}->[5] = to_json( $n->{data}->[5] ); } $n->{data} = join ';', @{ $n->{data} }; @@ -1059,15 +1060,15 @@ sub _unitTest { or $attr->{type} =~ /Container$/ ) { my $keyMsg = $attr->{keyMsgFail} // $type->{keyMsgFail}; - my $msg = $attr->{msgFail} // $type->{msgFail}; + my $msg = $attr->{msgFail} // $type->{msgFail}; $res = 0 unless ( $self->_execTest( { - keyTest => $attr->{keyTest} // $type->{keyTest}, + keyTest => $attr->{keyTest} // $type->{keyTest}, keyMsgFail => $attr->{keyMsgFail} // $type->{keyMsgFail}, - test => $attr->{test} // $type->{test}, + test => $attr->{test} // $type->{test}, msgFail => $attr->{msgFail} // $type->{msgFail}, }, $conf->{$key}, diff --git a/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/Conf/Tests.pm b/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/Conf/Tests.pm index 715244b83..28d24adc9 100644 --- a/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/Conf/Tests.pm +++ b/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/Conf/Tests.pm @@ -30,7 +30,8 @@ sub tests { portalIsInDomain => sub { return ( 1, - ( index( $conf->{portal}, $conf->{domain} ) > 0 + ( + index( $conf->{portal}, $conf->{domain} ) > 0 ? '' : "Portal seems not to be in the domain $conf->{domain}" ) @@ -42,7 +43,7 @@ sub tests { # Checking for ending slash $conf->{portal} .= '/' - unless ( $conf->{portal} =~ qr#/$# ); + unless ( $conf->{portal} =~ qr#/$# ); # Deleting trailing ending slash my $regex = qr#/+$#; @@ -60,10 +61,11 @@ sub tests { } return ( 1, - ( @pb + ( + @pb ? 'Virtual hosts ' - . join( ', ', @pb ) - . " are not in $conf->{domain} and cross-domain-authentication is not set" + . join( ', ', @pb ) + . " are not in $conf->{domain} and cross-domain-authentication is not set" : undef ) ); @@ -77,9 +79,9 @@ sub tests { } if (@pb) { return ( 0, - 'Virtual hosts ' - . join( ', ', @pb ) - . " contain a port, this is not allowed" ); + 'Virtual hosts ' + . join( ', ', @pb ) + . " contain a port, this is not allowed" ); } else { return 1; } }, @@ -92,9 +94,9 @@ sub tests { } if (@pb) { return ( 0, - 'Virtual hosts ' - . join( ', ', @pb ) - . " must be in lower case" ); + 'Virtual hosts ' + . join( ', ', @pb ) + . " must be in lower case" ); } else { return 1; } }, @@ -102,12 +104,12 @@ sub tests { # Check if "userDB" and "authentication" are consistent authAndUserDBConsistency => sub { foreach - my $type (qw(Facebook Google OpenID OpenIDConnect SAML WebID)) + my $type (qw(Facebook Google OpenID OpenIDConnect SAML WebID)) { return ( 0, - "\"$type\" can not be used as user database without using \"$type\" for authentication" - ) - if ($conf->{userDB} =~ /$type/ +"\"$type\" can not be used as user database without using \"$type\" for authentication" + ) + if ( $conf->{userDB} =~ /$type/ and $conf->{authentication} !~ /$type/ ); } return 1; @@ -117,29 +119,30 @@ sub tests { checkAttrAndMacros => sub { my @tmp; foreach my $k ( keys %$conf ) { - if ( $k - =~ /^(?:openIdSreg_(?:(?:(?:full|nick)nam|languag|postcod|timezon)e|country|gender|email|dob)|whatToTrace)$/ - ) + if ( $k =~ +/^(?:openIdSreg_(?:(?:(?:full|nick)nam|languag|postcod|timezon)e|country|gender|email|dob)|whatToTrace)$/ + ) { my $v = $conf->{$k}; $v =~ s/^$//; next if ( $v =~ /^_/ ); push @tmp, - $k - unless ( + $k + unless ( defined( $conf->{exportedVars}->{$v} - or defined( $conf->{macros}->{$v} ) + or defined( $conf->{macros}->{$v} ) ) - ); + ); } } return ( 1, - ( @tmp + ( + @tmp ? 'Values of parameter(s) "' - . join( ', ', @tmp ) - . '" are not defined in exported attributes or macros' + . join( ', ', @tmp ) + . '" are not defined in exported attributes or macros' : '' ) ); @@ -151,18 +154,18 @@ sub tests { if ( $conf->{userDB} =~ /^Google$/ ) { foreach my $k ( keys %{ $conf->{exportedVars} } ) { my $v = $conf->{exportedVars}->{$k}; - if ( $v !~ Lemonldap::NG::Common::Regexp::GOOGLEAXATTR() ) - { + if ( $v !~ Lemonldap::NG::Common::Regexp::GOOGLEAXATTR() ) { push @tmp, $v; } } } return ( 1, - ( @tmp + ( + @tmp ? 'Values of parameter(s) "' - . join( ', ', @tmp ) - . '" are not exported by Google' + . join( ', ', @tmp ) + . '" are not exported by Google' : '' ) ); @@ -174,8 +177,7 @@ sub tests { if ( $conf->{userDB} =~ /^OpenID$/ ) { foreach my $k ( keys %{ $conf->{exportedVars} } ) { my $v = $conf->{exportedVars}->{$k}; - if ( $v - !~ Lemonldap::NG::Common::Regexp::OPENIDSREGATTR() ) + if ( $v !~ Lemonldap::NG::Common::Regexp::OPENIDSREGATTR() ) { push @tmp, $v; } @@ -183,10 +185,11 @@ sub tests { } return ( 1, - ( @tmp + ( + @tmp ? 'Values of parameter(s) "' - . join( ', ', @tmp ) - . '" are not exported by OpenID SREG' + . join( ', ', @tmp ) + . '" are not exported by OpenID SREG' : '' ) ); @@ -195,40 +198,40 @@ sub tests { # Try to use Apache::Session module testApacheSession => sub { my ( $id, %h ); - my $gc = $Lemonldap::NG::Handler::PSGI::Main::tsv - ->{sessionStorageModule}; + my $gc = + $Lemonldap::NG::Handler::PSGI::Main::tsv->{sessionStorageModule}; return 1 - if ( ( $gc and $gc eq $conf->{globalStorage} ) - or $conf->{globalStorage} - =~ /^Lemonldap::NG::Common::Apache::Session::/ ); + if ( ( $gc and $gc eq $conf->{globalStorage} ) + or $conf->{globalStorage} =~ + /^Lemonldap::NG::Common::Apache::Session::/ ); eval "use $conf->{globalStorage}"; return ( -1, "Unknown package $conf->{globalStorage}" ) if ($@); eval { tie %h, 'Lemonldap::NG::Common::Apache::Session', undef, - { + { %{ $conf->{globalStorageOptions} }, backend => $conf->{globalStorage} - }; + }; }; return ( -1, "Unable to create a session ($@)" ) - if ( $@ or not tied(%h) ); + if ( $@ or not tied(%h) ); eval { $h{a} = 1; $id = $h{_session_id} or return ( -1, 'No _session_id' ); untie(%h); tie %h, 'Lemonldap::NG::Common::Apache::Session', $id, - { + { %{ $conf->{globalStorageOptions} }, backend => $conf->{globalStorage} - }; + }; }; return ( -1, "Unable to insert data ($@)" ) if ($@); return ( -1, "Unable to recover data stored" ) - unless ( $h{a} == 1 ); + unless ( $h{a} == 1 ); eval { tied(%h)->delete; }; return ( -1, "Unable to delete session ($@)" ) if ($@); return ( -1, - 'All sessions may be lost and you must restart all your Apache servers' +'All sessions may be lost and you must restart all your Apache servers' ) if ( $gc and $conf->{globalStorage} ne $gc ); return 1; }, @@ -238,8 +241,9 @@ sub tests { my $cn = $Lemonldap::NG::Handler::PSGI::API::tsv->{cookieName}; return ( 1, - ( $cn - and $cn ne $conf->{cookieName} + ( + $cn + and $cn ne $conf->{cookieName} ? 'Cookie name has changed, you must restart all your web servers' : () ) @@ -250,9 +254,9 @@ sub tests { cookieTTL => sub { return 1 unless ( defined $conf->{cookieExpiration} ); return ( 0, "Cookie TTL must be higher than one minute" ) - unless ( $conf->{cookieExpiration} > 60 ); + unless ( $conf->{cookieExpiration} > 60 ); return ( 1, "Cookie TTL should be higher or equal than one hour" ) - unless ( $conf->{cookieExpiration} >= 3600 + unless ( $conf->{cookieExpiration} >= 3600 || $conf->{cookieExpiration} == 0 ); # Return @@ -263,7 +267,8 @@ sub tests { managerProtection => sub { return ( 1, - ( $conf->{cfgAuthor} eq 'anonymous' + ( + $conf->{cfgAuthor} eq 'anonymous' ? 'Your manager seems to be unprotected' : '' ) @@ -279,21 +284,21 @@ sub tests { # Use SMTP eval "use Net::SMTP"; return ( 1, "Net::SMTP module is required to use SMTP server" ) - if ($@); + if ($@); # Create SMTP object my $smtp = Net::SMTP->new( $conf->{SMTPServer}, Timeout => 5 ); return ( 1, "SMTP connection to " . $conf->{SMTPServer} . " failed" ) - unless ($smtp); + unless ($smtp); # Skip other tests if no authentication return 1 - unless ( $conf->{SMTPAuthUser} and $conf->{SMTPAuthPass} ); + unless ( $conf->{SMTPAuthUser} and $conf->{SMTPAuthPass} ); # Try authentication return ( 1, "SMTP authentication failed" ) - unless $smtp->auth( $conf->{SMTPAuthUser}, + unless $smtp->auth( $conf->{SMTPAuthUser}, $conf->{SMTPAuthPass} ); # Return @@ -303,14 +308,15 @@ sub tests { # SAML entity ID must be uniq samlIDPEntityIdUniqueness => sub { return 1 - unless ( $conf->{samlIDPMetaDataXML} + unless ( $conf->{samlIDPMetaDataXML} and %{ $conf->{samlIDPMetaDataXML} } ); my @msg; my $res = 1; my %entityIds; foreach my $idpId ( keys %{ $conf->{samlIDPMetaDataXML} } ) { - unless ( $conf->{samlIDPMetaDataXML}->{$idpId} - ->{samlIDPMetaDataXML} =~ /entityID=(['"])(.+?)\1/si ) + unless ( + $conf->{samlIDPMetaDataXML}->{$idpId}->{samlIDPMetaDataXML} + =~ /entityID=(['"])(.+?)\1/si ) { push @msg, "$idpId SAML metadata has no EntityID"; $res = 0; @@ -319,7 +325,7 @@ sub tests { my $eid = $2; if ( defined $entityIds{$eid} ) { push @msg, - "$idpId and $entityIds{$eid} have the same SAML EntityID"; + "$idpId and $entityIds{$eid} have the same SAML EntityID"; $res = 0; next; } @@ -329,15 +335,15 @@ sub tests { }, samlSPEntityIdUniqueness => sub { return 1 - unless ( $conf->{samlSPMetaDataXML} + unless ( $conf->{samlSPMetaDataXML} and %{ $conf->{samlSPMetaDataXML} } ); my @msg; my $res = 1; my %entityIds; foreach my $spId ( keys %{ $conf->{samlSPMetaDataXML} } ) { unless ( - $conf->{samlSPMetaDataXML}->{$spId}->{samlSPMetaDataXML} - =~ /entityID=(['"])(.+?)\1/si ) + $conf->{samlSPMetaDataXML}->{$spId}->{samlSPMetaDataXML} =~ + /entityID=(['"])(.+?)\1/si ) { push @msg, "$spId SAML metadata has no EntityID"; $res = 0; @@ -346,7 +352,7 @@ sub tests { my $eid = $2; if ( defined $entityIds{$eid} ) { push @msg, - "$spId and $entityIds{$eid} have the same SAML EntityID"; + "$spId and $entityIds{$eid} have the same SAML EntityID"; $res = 0; next; } @@ -360,7 +366,7 @@ sub tests { return 1 unless ( $conf->{authentication} eq 'Combination' ); require Lemonldap::NG::Common::Combination::Parser; return ( 0, 'No module declared for combination' ) - unless ( $conf->{combModules} and %{ $conf->{combModules} } ); + unless ( $conf->{combModules} and %{ $conf->{combModules} } ); my $moduleList; foreach my $md ( keys %{ $conf->{combModules} } ) { my $entry = $conf->{combModules}->{$md}; @@ -371,8 +377,8 @@ sub tests { ); } eval { - Lemonldap::NG::Common::Combination::Parser->parse( - $moduleList, $conf->{combination} ); + Lemonldap::NG::Common::Combination::Parser->parse( $moduleList, + $conf->{combination} ); }; return ( 0, $@ ) if ($@); @@ -397,7 +403,7 @@ sub tests { eval "use Convert::Base32"; return ( 1, "Convert::Base32 module is required to enable TOTP" ) - if ($@); + if ($@); } # Use U2F @@ -406,7 +412,7 @@ sub tests { { eval "use Crypt::U2F::Server::Simple"; return ( 1, - "Crypt::U2F::Server::Simple module is required to enable U2F" +"Crypt::U2F::Server::Simple module is required to enable U2F" ) if ($@); } @@ -414,7 +420,7 @@ sub tests { if ( $conf->{yubikey2fActivation} ) { eval "use Auth::Yubikey_WebClient"; return ( 1, - "Auth::Yubikey_WebClient module is required to enable Yubikey" +"Auth::Yubikey_WebClient module is required to enable Yubikey" ) if ($@); } @@ -428,7 +434,7 @@ sub tests { my $w = ""; foreach ( 'totp', 'u' ) { $w .= uc($_) . "2F is activated twice \n" - if ( $conf->{ $_ . '2fActivation' } eq '1' ); + if ( $conf->{ $_ . '2fActivation' } eq '1' ); } return ( 1, ( $w ? $w : () ) ); }, @@ -439,8 +445,10 @@ sub tests { return 1 unless ( defined $conf->{totp2fDigits} ); return ( 1, - ( ( $conf->{totp2fDigits} == 6 - or $conf->{totp2fDigits} == 8 + ( + ( + $conf->{totp2fDigits} == 6 + or $conf->{totp2fDigits} == 8 ) ? '' : 'TOTP should be 6 or 8 digits long' @@ -452,9 +460,9 @@ sub tests { totp2fParams => sub { return 1 unless ( $conf->{totp2fActivation} ); return ( 0, 'TOTP range must be defined' ) - unless ( $conf->{totp2fRange} ); + unless ( $conf->{totp2fRange} ); return ( 1, "TOTP interval should be higher than 10s" ) - unless ( $conf->{totp2fInterval} > 10 ); + unless ( $conf->{totp2fInterval} > 10 ); # Return return 1; @@ -465,11 +473,12 @@ sub tests { yubikey2fParams => sub { return 1 unless ( $conf->{yubikey2fActivation} ); return ( 0, "Yubikey client ID and secret key must be set" ) - unless ( defined $conf->{yubikey2fSecretKey} + unless ( defined $conf->{yubikey2fSecretKey} && defined $conf->{yubikey2fClientID} ); return ( 1, - ( ( $conf->{yubikey2fPublicIDSize} == 12 ) + ( + ( $conf->{yubikey2fPublicIDSize} == 12 ) ? '' : 'Yubikey public ID size should be 12 digits long' ) @@ -480,7 +489,7 @@ sub tests { rest2fVerifyUrl => sub { return 1 unless ( $conf->{rest2fActivation} ); return ( 0, "REST 2F Verify URL must be set" ) - unless ( defined $conf->{rest2fVerifyUrl} ); + unless ( defined $conf->{rest2fVerifyUrl} ); # Return return 1; @@ -494,16 +503,15 @@ sub tests { my $ok = 0; foreach (qw(u totp yubikey)) { $ok ||= $conf->{ $_ . '2fActivation' } - && $conf->{ $_ . '2fSelfRegistration' }; + && $conf->{ $_ . '2fSelfRegistration' }; last if ($ok); } $ok ||= $conf->{'utotp2fActivation'} - && ( $conf->{'u2fSelfRegistration'} + && ( $conf->{'u2fSelfRegistration'} || $conf->{'totp2fSelfRegistration'} ); - $msg - = "A self registrable module should be enabled to require 2FA" - unless ($ok); + $msg = "A self registrable module should be enabled to require 2FA" + unless ($ok); return ( 1, $msg ); }, @@ -512,7 +520,7 @@ sub tests { ext2fCommands => sub { return 1 unless ( $conf->{ext2fActivation} ); return ( 0, "External 2F Send or Validate command must be set" ) - unless ( defined $conf->{ext2FSendCommand} + unless ( defined $conf->{ext2FSendCommand} && defined $conf->{ext2FValidateCommand} ); # Return @@ -523,9 +531,9 @@ sub tests { formTimeout => sub { return 1 unless ( defined $conf->{formTimeout} ); return ( 0, "XSRF form token TTL must be higher than 30s" ) - unless ( $conf->{formTimeout} > 30 ); + unless ( $conf->{formTimeout} > 30 ); return ( 1, "XSRF form token TTL should not be higher than 2mn" ) - if ( $conf->{formTimeout} > 120 ); + if ( $conf->{formTimeout} > 120 ); # Return return 1; diff --git a/lemonldap-ng-manager/t/03-HTML-forms.t b/lemonldap-ng-manager/t/03-HTML-forms.t index 8ac3d4490..8aee4d466 100644 --- a/lemonldap-ng-manager/t/03-HTML-forms.t +++ b/lemonldap-ng-manager/t/03-HTML-forms.t @@ -24,7 +24,7 @@ delete $forms{restore}; my ( @types, $attr, $tree, $ctrees ); ok( $tree = Lemonldap::NG::Manager::Build::Tree::tree(), 'Get tree' ); ok( $ctrees = Lemonldap::NG::Manager::Build::CTrees::cTrees(), 'Get cTrees' ); -ok( $attr = Lemonldap::NG::Manager::Build::Attributes::attributes(), +ok( $attr = Lemonldap::NG::Manager::Build::Attributes::attributes(), 'Get attributes' ); $count += 4; diff --git a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/2F/Engines/Default.pm b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/2F/Engines/Default.pm index 0a3bf71e5..024d265c6 100644 --- a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/2F/Engines/Default.pm +++ b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/2F/Engines/Default.pm @@ -13,11 +13,11 @@ use strict; use Mouse; use JSON qw(from_json to_json); use Lemonldap::NG::Portal::Main::Constants qw( - PE_ERROR - PE_NOTOKEN - PE_OK - PE_SENDRESPONSE - PE_TOKENEXPIRED + PE_ERROR + PE_NOTOKEN + PE_OK + PE_SENDRESPONSE + PE_TOKENEXPIRED ); our $VERSION = '2.0.0'; @@ -35,8 +35,8 @@ has sfReq => ( is => 'rw' ); has ott => ( is => 'rw', default => sub { - my $ott = $_[0]->{p} - ->loadModule('Lemonldap::NG::Portal::Lib::OneTimeToken'); + my $ott = + $_[0]->{p}->loadModule('Lemonldap::NG::Portal::Lib::OneTimeToken'); $ott->timeout( $_[0]->{conf}->{formTimeout} ); return $ott; } @@ -49,10 +49,12 @@ sub init { for my $i ( 0 .. 1 ) { foreach ( split /,\s*/, - $self->conf->{ $i + $self->conf->{ + $i ? 'available2FSelfRegistration' - : 'available2F' } - ) + : 'available2F' + } + ) { my $prefix = lc($_); $prefix =~ s/2f$//i; @@ -64,10 +66,9 @@ sub init { # Unless $rule, skip loading if ( $self->conf->{$ap} ) { $self->logger->debug("Trying to load $_ 2F"); - my $m - = $self->p->loadPlugin( - $i ? "::2F::Register::$_" : "::2F::$_" ) - or return 0; + my $m = + $self->p->loadPlugin( $i ? "::2F::Register::$_" : "::2F::$_" ) + or return 0; # Rule and prefix may be modified by 2F module, reread them my $rule = $self->conf->{$ap}; @@ -77,13 +78,13 @@ sub init { $rule = $self->p->HANDLER->substitute($rule); unless ( $rule = $self->p->HANDLER->buildSub($rule) ) { $self->error( 'External 2F rule error: ' - . $self->p->HANDLER->tsv->{jail}->error ); + . $self->p->HANDLER->tsv->{jail}->error ); return 0; } # Store module push @{ $self->{ $i ? 'sfRModules' : 'sfModules' } }, - { p => $prefix, m => $m, r => $rule }; + { p => $prefix, m => $m, r => $rule }; } else { $self->logger->debug(' -> not enabled'); @@ -97,10 +98,10 @@ sub init { $self->p->HANDLER->substitute( $self->conf->{sfRequired} ) ) ) - ) + ) { $self->error( 'Error in sfRequired rule' - . $self->p->HANDLER->tsv->{jail}->error ); + . $self->p->HANDLER->tsv->{jail}->error ); return 0; } @@ -161,14 +162,14 @@ sub run { if ( $self->sfReq->( $req, $req->sessionInfo ) ) { $self->logger->debug("2F is required..."); $self->logger->debug(" -> Register 2F"); - $req->pdata->{sfRegToken} - = $self->ott->createToken( $req->sessionInfo ); + $req->pdata->{sfRegToken} = + $self->ott->createToken( $req->sessionInfo ); $self->logger->debug("Just one 2F is enabled"); $self->logger->debug(" -> Redirect to /2fregisters/"); $req->response( - [ 302, - [ Location => $self->conf->{portal} . '/2fregisters/' ], - [] + [ + 302, + [ Location => $self->conf->{portal} . '/2fregisters/' ], [] ] ); return PE_SENDRESPONSE; @@ -179,7 +180,7 @@ sub run { } $self->userLogger->info( 'Second factor required for ' - . $req->sessionInfo->{ $self->conf->{whatToTrace} } ); + . $req->sessionInfo->{ $self->conf->{whatToTrace} } ); # Store user data in a token $req->sessionInfo->{_2fRealSession} = $req->id; @@ -201,10 +202,9 @@ sub run { $req, '2fchoice', params => { - SKIN => $self->conf->{portalSkin}, - TOKEN => $token, - MODULES => - [ map { { CODE => $_->prefix, LOGO => $_->logo } } @am ], + SKIN => $self->conf->{portalSkin}, + TOKEN => $token, + MODULES => [ map { { CODE => $_->prefix, LOGO => $_->logo } } @am ], CHECKLOGINS => $checkLogins } ); @@ -230,16 +230,15 @@ sub _choice { # Restore session unless ( $token = $req->param('token') ) { - $self->userLogger->error( - $self->prefix . ' 2F access without token' ); + $self->userLogger->error( $self->prefix . ' 2F access without token' ); $req->mustRedirect(1); - return $self->p->do( $req, [ sub {PE_NOTOKEN} ] ); + return $self->p->do( $req, [ sub { PE_NOTOKEN } ] ); } my $session; unless ( $session = $self->ott->getToken($token) ) { $self->userLogger->info('Token expired'); - return $self->p->do( $req, [ sub {PE_TOKENEXPIRED} ] ); + return $self->p->do( $req, [ sub { PE_TOKENEXPIRED } ] ); } $req->sessionInfo($session); @@ -254,7 +253,8 @@ sub _choice { $req->authResult($res); return $self->p->do( $req, - [ sub {$res}, 'controlUrl', + [ + sub { $res }, 'controlUrl', 'buildCookie', @{ $self->p->endAuth }, ] ); @@ -269,8 +269,7 @@ sub _redirect { my $arg = $req->env->{QUERY_STRING}; $self->logger->debug('Call sfEngine _redirect method'); return [ - 302, [ Location => $self->conf->{portal} . ( $arg ? "?$arg" : '' ) ], - [] + 302, [ Location => $self->conf->{portal} . ( $arg ? "?$arg" : '' ) ], [] ]; } @@ -300,26 +299,25 @@ sub _displayRegister { 'Looking if ' . $m->{m}->prefix . '2F register is available' ); if ( $m->{r}->( $req, $req->userData ) ) { push @am, - { + { CODE => $m->{m}->prefix, URL => '/2fregisters/' . $m->{m}->prefix, LOGO => $m->{m}->logo, - }; + }; } } if ( @am == 1 - and - not( $req->userData->{_2fDevices} or $req->data->{sfRegRequired} ) ) + and not( $req->userData->{_2fDevices} or $req->data->{sfRegRequired} ) ) { return [ 302, [ Location => $self->conf->{portal} . $am[0]->{URL} ], [] ]; } - my $_2fDevices = $req->userData->{_2fDevices} - ? eval { - from_json( $req->userData->{_2fDevices}, { allow_nonref => 1 } ); - } - : undef; + my $_2fDevices = + $req->userData->{_2fDevices} + ? eval { + from_json( $req->userData->{_2fDevices}, { allow_nonref => 1 } ); } + : undef; unless ($_2fDevices) { $self->logger->debug("No 2F Device found"); @@ -365,11 +363,11 @@ sub register { $self->logger->debug(' -> OK'); my $name = $m->{m}->prefix; push @am, - { + { name => $name, logo => $m->{m}->logo, url => "/2fregisters/$name" - }; + }; } } return $self->p->sendJSONresponse( $req, \@am ); @@ -378,12 +376,12 @@ sub register { sub restoreSession { my ( $self, $req, @path ) = @_; my $token = $req->pdata->{sfRegToken} - or return [ 302, [ Location => $self->conf->{portal} ], [] ]; + or return [ 302, [ Location => $self->conf->{portal} ], [] ]; $req->userData( $self->ott->getToken( $token, 1 ) ); $req->data->{sfRegRequired} = 1; return $req->method eq 'POST' - ? $self->register( $req, @path ) - : $self->_displayRegister( $req, @path ); + ? $self->register( $req, @path ) + : $self->_displayRegister( $req, @path ); } 1; diff --git a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/2F/Ext2F.pm b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/2F/Ext2F.pm index 8eeebae06..e08aef0bc 100644 --- a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/2F/Ext2F.pm +++ b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/2F/Ext2F.pm @@ -39,11 +39,12 @@ sub run { $self->logger->debug("Ext2F checkLogins set") if ($checkLogins); # Prepare command and launch it - $self->logger->debug('Launching "Send" external 2F command -> ' . $self->conf->{ext2FSendCommand}); + $self->logger->debug( 'Launching "Send" external 2F command -> ' + . $self->conf->{ext2FSendCommand} ); if ( my $c = $self->launch( $req->sessionInfo, $self->conf->{ext2FSendCommand} ) ) { - $self->logger->error("External send command failed (code $c)"); + $self->logger->error("External send command failed (code $c)"); return $self->p->do( $req, [ sub { PE_ERROR } ] ); } @@ -72,7 +73,8 @@ sub verify { } # Prepare command and launch it - $self->logger->debug('Launching "Validate" external 2F command -> ' . $self->conf->{ext2FValidateCommand}); + $self->logger->debug( 'Launching "Validate" external 2F command -> ' + . $self->conf->{ext2FValidateCommand} ); $self->logger->debug(" code -> $code"); if ( my $c = $self->launch( $session, $self->conf->{ext2FValidateCommand}, $code ) ) diff --git a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/2F/Register/U2F.pm b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/2F/Register/U2F.pm index 5bd2a80b1..e1b1954f9 100644 --- a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/2F/Register/U2F.pm +++ b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/2F/Register/U2F.pm @@ -7,7 +7,8 @@ use JSON qw(from_json to_json); our $VERSION = '2.0.0'; -extends 'Lemonldap::NG::Portal::Main::Plugin', 'Lemonldap::NG::Portal::Lib::U2F'; +extends 'Lemonldap::NG::Portal::Main::Plugin', + 'Lemonldap::NG::Portal::Lib::U2F'; # INITIALIZATION diff --git a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Auth/OpenIDConnect.pm b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Auth/OpenIDConnect.pm index d83f9a366..ec9a36f14 100644 --- a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Auth/OpenIDConnect.pm +++ b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Auth/OpenIDConnect.pm @@ -16,7 +16,7 @@ extends 'Lemonldap::NG::Portal::Main::Auth', # INTERFACE -has opList => ( is => 'rw', default => sub { [] } ); +has opList => ( is => 'rw', default => sub { [] } ); has opNumber => ( is => 'rw', default => 0 ); has path => ( is => 'rw', default => 'oauth2' ); diff --git a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Lib/SMTP.pm b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Lib/SMTP.pm index 4ec8853e5..5b448a2b3 100644 --- a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Lib/SMTP.pm +++ b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Lib/SMTP.pm @@ -174,7 +174,7 @@ sub send_mail { foreach ( keys %cid ) { $message->attach( Type => "image/" . ( $cid{$_} =~ m/\.(\w+)/ )[0], - Id => $_, + Id => $_, Path => $self->p->{templateDir} . "/" . $cid{$_}, ); } diff --git a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Main/Display.pm b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Main/Display.pm index 55c941641..131a7078b 100644 --- a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Main/Display.pm +++ b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Main/Display.pm @@ -16,17 +16,16 @@ sub displayInit { my ($self) = @_; $self->skinRules( [] ); if ( $self->conf->{portalSkinRules} ) { - foreach my $skinRule ( sort keys %{ $self->conf->{portalSkinRules} } ) - { + foreach my $skinRule ( sort keys %{ $self->conf->{portalSkinRules} } ) { my $sub = HANDLER->buildSub( HANDLER->substitute($skinRule) ); if ($sub) { push @{ $self->skinRules }, - [ $self->conf->{portalSkinRules}->{$skinRule}, $sub ]; + [ $self->conf->{portalSkinRules}->{$skinRule}, $sub ]; } else { $self->logger->error( qq(Skin rule "$skinRule" returns an error: ) - . HANDLER->tsv->{jail}->error ); + . HANDLER->tsv->{jail}->error ); } } } @@ -55,7 +54,8 @@ sub display { AUTH_URL => $req->{data}->{_url}, CHOICE_PARAM => $self->conf->{authChoiceParam}, CHOICE_VALUE => $req->data->{_authChoice}, - ( $req->data->{customScript} + ( + $req->data->{customScript} ? ( CUSTOM_SCRIPT => $req->data->{customScript} ) : () ), @@ -79,11 +79,12 @@ sub display { CHOICE_PARAM => $self->conf->{authChoiceParam}, CHOICE_VALUE => $req->data->{_authChoice}, CHECK_LOGINS => $self->conf->{portalCheckLogins} - && $req->data->{login}, + && $req->data->{login}, ASK_LOGINS => $req->param('checkLogins') || 0, CONFIRMKEY => $self->stamp(), REMEMBER => $req->data->{confirmRemember}, - ( $req->data->{customScript} + ( + $req->data->{customScript} ? ( CUSTOM_SCRIPT => $req->data->{customScript} ) : () ), @@ -106,12 +107,13 @@ sub display { CHOICE_PARAM => $self->conf->{authChoiceParam}, CHOICE_VALUE => $req->data->{_authChoice}, CHECK_LOGINS => $self->conf->{portalCheckLogins} - && $req->data->{login}, + && $req->data->{login}, ASK_LOGINS => $req->param('checkLogins') || 0, CONFIRMKEY => $self->stamp(), LIST => $req->data->{list} || [], REMEMBER => $req->data->{confirmRemember}, - ( $req->data->{customScript} + ( + $req->data->{customScript} ? ( CUSTOM_SCRIPT => $req->data->{customScript} ) : () ), @@ -135,7 +137,8 @@ sub display { FORM_METHOD => $self->conf->{infoFormMethod}, CHOICE_PARAM => $self->conf->{authChoiceParam}, CHOICE_VALUE => $req->data->{_authChoice}, - ( $req->data->{customScript} + ( + $req->data->{customScript} ? ( CUSTOM_SCRIPT => $req->data->{customScript} ) : () ), @@ -150,14 +153,15 @@ sub display { my $p = $self->conf->{portal} . $self->conf->{issuerDBOpenIDPath}; $p =~ s#(?{sessionInfo} - ->{ $self->conf->{openIdAttr} || $self->conf->{whatToTrace} }; + ->{ $self->conf->{openIdAttr} || $self->conf->{whatToTrace} }; %templateParams = ( MAIN_LOGO => $self->conf->{portalMainLogo}, AUTH_ERROR => $self->error, AUTH_ERROR_TYPE => $req->error_type, PROVIDERURI => $p, MSG => $req->info(), - ( $req->data->{customScript} + ( + $req->data->{customScript} ? ( CUSTOM_SCRIPT => $req->data->{customScript} ) : () ), @@ -174,7 +178,8 @@ sub display { URL => $req->{urldc}, HIDDEN_INPUTS => $self->buildHiddenForm($req), FORM_METHOD => $req->data->{redirectFormMethod} || 'get', - ( $req->data->{customScript} + ( + $req->data->{customScript} ? ( CUSTOM_SCRIPT => $req->data->{customScript} ) : () ), @@ -188,16 +193,16 @@ sub display { #utf8::decode($auth_user); %templateParams = ( MAIN_LOGO => $self->conf->{portalMainLogo}, - AUTH_USER => - $req->{sessionInfo}->{ $self->conf->{portalUserAttr} }, - NEWWINDOW => $self->conf->{portalOpenLinkInNewWindow}, + AUTH_USER => $req->{sessionInfo}->{ $self->conf->{portalUserAttr} }, + NEWWINDOW => $self->conf->{portalOpenLinkInNewWindow}, LOGOUT_URL => $self->conf->{portal} . "?logout=1", APPSLIST_ORDER => $req->{sessionInfo}->{'_appsListOrder'}, PING => $self->conf->{portalPingInterval}, REQUIRE_OLDPASSWORD => $self->conf->{portalRequireOldPassword}, HIDE_OLDPASSWORD => 0, $self->menu->params($req), - ( $req->data->{customScript} + ( + $req->data->{customScript} ? ( CUSTOM_SCRIPT => $req->data->{customScript} ) : () ), @@ -212,7 +217,8 @@ sub display { CONFIRMKEY => $self->stamp, PORTAL => $self->conf->{portal}, URL => $req->data->{_url}, - ( $req->data->{customScript} + ( + $req->data->{customScript} ? ( CUSTOM_SCRIPT => $req->data->{customScript} ) : () ), @@ -227,7 +233,8 @@ sub display { CONFIRMKEY => $self->stamp, PORTAL => $self->conf->{portal}, URL => $req->data->{_url}, - ( $req->data->{customScript} + ( + $req->data->{customScript} ? ( CUSTOM_SCRIPT => $req->data->{customScript} ) : () ), @@ -240,14 +247,15 @@ sub display { or ( not $req->data->{noerror} and $req->userData and %{ $req->userData } ) - ) + ) { $skinfile = 'error'; %templateParams = ( MAIN_LOGO => $self->conf->{portalMainLogo}, AUTH_ERROR => $req->error, AUTH_ERROR_TYPE => $req->error_type, - ( $req->data->{customScript} + ( + $req->data->{customScript} ? ( CUSTOM_SCRIPT => $req->data->{customScript} ) : () ), @@ -260,21 +268,21 @@ sub display { my $login = $self->userId($req); $login = '' if ( $login eq 'anonymous' ); %templateParams = ( - MAIN_LOGO => $self->conf->{portalMainLogo}, - AUTH_ERROR => $req->error, - AUTH_ERROR_TYPE => $req->error_type, - AUTH_URL => $req->{data}->{_url}, - LOGIN => $login, - CHECK_LOGINS => $self->conf->{portalCheckLogins}, - ASK_LOGINS => $req->param('checkLogins') || 0, - DISPLAY_RESETPASSWORD => - $self->conf->{portalDisplayResetPassword}, - DISPLAY_REGISTER => $self->conf->{portalDisplayRegister}, - MAIL_URL => $self->conf->{mailUrl}, - REGISTER_URL => $self->conf->{registerUrl}, - HIDDEN_INPUTS => $self->buildHiddenForm($req), - STAYCONNECTED => $self->conf->{stayConnected}, - ( $req->data->{customScript} + MAIN_LOGO => $self->conf->{portalMainLogo}, + AUTH_ERROR => $req->error, + AUTH_ERROR_TYPE => $req->error_type, + AUTH_URL => $req->{data}->{_url}, + LOGIN => $login, + CHECK_LOGINS => $self->conf->{portalCheckLogins}, + ASK_LOGINS => $req->param('checkLogins') || 0, + DISPLAY_RESETPASSWORD => $self->conf->{portalDisplayResetPassword}, + DISPLAY_REGISTER => $self->conf->{portalDisplayRegister}, + MAIL_URL => $self->conf->{mailUrl}, + REGISTER_URL => $self->conf->{registerUrl}, + HIDDEN_INPUTS => $self->buildHiddenForm($req), + STAYCONNECTED => $self->conf->{stayConnected}, + ( + $req->data->{customScript} ? ( CUSTOM_SCRIPT => $req->data->{customScript} ) : () ), @@ -306,12 +314,12 @@ sub display { or $req->{error} == PE_PASSWORDFORMEMPTY or ( $req->{error} == PE_PP_PASSWORD_EXPIRED and $self->conf->{ldapAllowResetExpiredPassword} ) - ) + ) { %templateParams = ( %templateParams, REQUIRE_OLDPASSWORD => - 1, # Old password is required to check user credentials + 1, # Old password is required to check user credentials DISPLAY_FORM => 0, DISPLAY_OPENID_FORM => 0, DISPLAY_YUBIKEY_FORM => 0, @@ -368,8 +376,8 @@ sub display { # Choose what form to display if not in a loop else { - my $displayType - = eval { $self->_authentication->getDisplayType($req) }; + my $displayType = + eval { $self->_authentication->getDisplayType($req) }; $self->logger->debug("Display type $displayType "); @@ -377,8 +385,7 @@ sub display { %templateParams, DISPLAY_FORM => $displayType =~ /\bstandardform\b/ ? 1 : 0, - DISPLAY_OPENID_FORM => $displayType =~ /\bopenidform\b/ - ? 1 + DISPLAY_OPENID_FORM => $displayType =~ /\bopenidform\b/ ? 1 : 0, DISPLAY_YUBIKEY_FORM => $displayType =~ /\byubikeyform\b/ ? 1 @@ -388,10 +395,9 @@ sub display { module => $displayType eq "logo" ? $self->getModule( $req, 'auth' ) : "", - AUTH_LOOP => [], - PORTAL_URL => ( - $displayType eq "logo" ? $self->conf->{portal} : 0 - ), + AUTH_LOOP => [], + PORTAL_URL => + ( $displayType eq "logo" ? $self->conf->{portal} : 0 ), MSG => $req->info(), ); @@ -402,8 +408,8 @@ sub display { } # Additional $req param - %templateParams - = ( %templateParams, %{ $req->{customParameters} // {} }, ); + %templateParams = + ( %templateParams, %{ $req->{customParameters} // {} }, ); $self->logger->debug("Skin returned: $skinfile"); return ( $skinfile, \%templateParams ); @@ -419,16 +425,15 @@ sub staticFile { require Plack::Util; require Cwd; require HTTP::Date; - open my $fh, '<:raw', - $self->conf->{templatesDir} - . "/$file" - or return $self->sendError( $req, + open my $fh, '<:raw', $self->conf->{templatesDir} . "/$file" + or return $self->sendError( $req, $self->conf->{templatesDir} . "/$file: $!", 403 ); my @stat = stat $file; Plack::Util::set_io_path( $fh, Cwd::realpath($file) ); return [ 200, - [ 'Content-Type' => $type, + [ + 'Content-Type' => $type, 'Content-Length' => $stat[7], 'Last-Modified' => HTTP::Date::time2str( $stat[9] ) ], @@ -445,12 +450,11 @@ sub buildHiddenForm { # Check XSS attacks next - if $self->checkXSSAttack( $_, - $req->{portalHiddenFormValues}->{$_} ); + if $self->checkXSSAttack( $_, $req->{portalHiddenFormValues}->{$_} ); # Build hidden input HTML code $val .= qq{'; + . $req->{portalHiddenFormValues}->{$_} . '" />'; } return $val; @@ -521,12 +525,13 @@ sub mkSessionArray { displayError => $displayError, fields => [ map { { name => $self->conf->{sessionDataToRemember}->{$_} } } - @fields + @fields ], sessions => [ map { my $session = $_; - { user => $session->{user}, + { + user => $session->{user}, utime => $session->{_utime}, ip => $session->{ipAddr}, values => [ map { { v => $session->{$_} } } @fields ], @@ -548,7 +553,7 @@ sub mkOidcConsent { # Set default RP displayname foreach my $oidc ( keys %{ $self->conf->{oidcRPMetaDataOptions} } ) { $self->conf->{oidcRPMetaDataOptions}->{$oidc} - ->{oidcRPMetaDataOptionsDisplayName} ||= $oidc; + ->{oidcRPMetaDataOptionsDisplayName} ||= $oidc; } } @@ -574,9 +579,9 @@ sub mkOidcConsent { $self->logger->debug("RP { $rp } Consent found"); $consents->{$rp}->{epoch} = $_->{epoch}; $consents->{$rp}->{scope} = $_->{scope}; - $consents->{$rp}->{displayName} - = $self->conf->{oidcRPMetaDataOptions}->{$rp} - ->{oidcRPMetaDataOptionsDisplayName}; + $consents->{$rp}->{displayName} = + $self->conf->{oidcRPMetaDataOptions}->{$rp} + ->{oidcRPMetaDataOptionsDisplayName}; } } @@ -586,7 +591,8 @@ sub mkOidcConsent { params => { partners => [ map { - { name => $_, + { + name => $_, epoch => $consents->{$_}->{epoch}, scope => $consents->{$_}->{scope}, displayName => $consents->{$_}->{displayName} diff --git a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Main/Init.pm b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Main/Init.pm index 5d7b3957a..b59686604 100644 --- a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Main/Init.pm +++ b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Main/Init.pm @@ -84,8 +84,9 @@ sub init { my ( $self, $args ) = @_; $args ||= {}; $self->localConfig( - { %{ Lemonldap::NG::Common::Conf->new( $args->{configStorage} ) - ->getLocalConf('portal') + { + %{ Lemonldap::NG::Common::Conf->new( $args->{configStorage} ) + ->getLocalConf('portal') }, %$args } @@ -109,33 +110,33 @@ sub init { # Handle requests (other path may be declared in enabled plugins) $self - # "/" or undeclared paths - ->addUnauthRoute( '*' => 'login', ['GET'] ) - ->addUnauthRoute( '*' => 'postLogin', ['POST'] ) - ->addAuthRoute( '*' => 'authenticatedRequest', ['GET'] ) - ->addAuthRoute( '*' => 'postAuthenticatedRequest', ['POST'] ) + # "/" or undeclared paths + ->addUnauthRoute( '*' => 'login', ['GET'] ) + ->addUnauthRoute( '*' => 'postLogin', ['POST'] ) + ->addAuthRoute( '*' => 'authenticatedRequest', ['GET'] ) + ->addAuthRoute( '*' => 'postAuthenticatedRequest', ['POST'] ) - # psgi.js - ->addUnauthRoute( 'psgi.js' => 'sendJs', ['GET'] ) - ->addAuthRoute( 'psgi.js' => 'sendJs', ['GET'] ) + # psgi.js + ->addUnauthRoute( 'psgi.js' => 'sendJs', ['GET'] ) + ->addAuthRoute( 'psgi.js' => 'sendJs', ['GET'] ) - # portal.css - ->addUnauthRoute( 'portal.css' => 'sendCss', ['GET'] ) - ->addAuthRoute( 'portal.css' => 'sendCss', ['GET'] ) + # portal.css + ->addUnauthRoute( 'portal.css' => 'sendCss', ['GET'] ) + ->addAuthRoute( 'portal.css' => 'sendCss', ['GET'] ) - # lmerror - ->addUnauthRoute( lmerror => { ':code' => 'lmError' }, ['GET'] ) - ->addAuthRoute( lmerror => { ':code' => 'lmError' }, ['GET'] ) + # lmerror + ->addUnauthRoute( lmerror => { ':code' => 'lmError' }, ['GET'] ) + ->addAuthRoute( lmerror => { ':code' => 'lmError' }, ['GET'] ) - # Core REST API - ->addUnauthRoute( ping => 'pleaseAuth', ['GET'] ) - ->addAuthRoute( ping => 'authenticated', ['GET'] ) + # Core REST API + ->addUnauthRoute( ping => 'pleaseAuth', ['GET'] ) + ->addAuthRoute( ping => 'authenticated', ['GET'] ) - # Refresh session - ->addAuthRoute( refresh => 'refresh', ['GET'] ) + # Refresh session + ->addAuthRoute( refresh => 'refresh', ['GET'] ) - # Logout - ->addAuthRoute( logout => 'logout', ['GET'] ); + # Logout + ->addAuthRoute( logout => 'logout', ['GET'] ); # Default routes must point to routines declared above $self->defaultAuthRoute(''); @@ -169,8 +170,8 @@ sub reloadConf { $self->csp($csp); # Initialize templateDir - $self->{templateDir} - = $self->conf->{templateDir} . '/' . $self->conf->{portalSkin}; + $self->{templateDir} = + $self->conf->{templateDir} . '/' . $self->conf->{portalSkin}; unless ( -d $self->{templateDir} ) { $self->error("Template dir $self->{templateDir} doesn't exist"); return $self->fail; @@ -190,8 +191,8 @@ sub reloadConf { # Initialize persistent session DB unless ( $self->conf->{persistentStorage} ) { $self->conf->{persistentStorage} = $self->conf->{globalStorage}; - $self->conf->{persistentStorageOptions} - = $self->conf->{globalStorageOptions}; + $self->conf->{persistentStorageOptions} = + $self->conf->{globalStorageOptions}; } # Initialize cookie domain @@ -215,19 +216,19 @@ sub reloadConf { return $self->fail; } $mod = $self->conf->{$type} - unless ( $self->conf->{$type} eq 'Same' ); + unless ( $self->conf->{$type} eq 'Same' ); my $module = '::' . ucfirst($type) . '::' . $mod; $module =~ s/Authentication/Auth/; # Launch and initialize module return $self->fail - unless ( $self->{"_$type"} = $self->loadPlugin($module) ); + unless ( $self->{"_$type"} = $self->loadPlugin($module) ); } # Load second-factor engine return $self->fail - unless $self->{_sfEngine} - = $self->loadPlugin( $self->conf->{'sfEngine'} ); + unless $self->{_sfEngine} = + $self->loadPlugin( $self->conf->{'sfEngine'} ); # Initialize trusted domain regexp if ( $self->conf->{trustedDomains} @@ -250,8 +251,8 @@ sub reloadConf { # - $domainlabel.$td # $domainlabel is build looking RFC2396 # (see Regexp::Common::URI::RFC2396) - $_ - =~ s/\*\\\./(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9]\\.)*/g; + $_ =~ + s/\*\\\./(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9]\\.)*/g; $re->add("$_"); } } @@ -262,8 +263,8 @@ sub reloadConf { $self->logger->debug("Vhost $vhost added in trusted domains"); $re->add( quotemeta($vhost) ); $self->conf->{vhostOptions} ||= {}; - if ( my $tmp - = $self->conf->{vhostOptions}->{$vhost}->{vhostAliases} ) + if ( my $tmp = + $self->conf->{vhostOptions}->{$vhost}->{vhostAliases} ) { foreach my $alias ( split /\s+/, $tmp ) { $self->logger->debug( @@ -281,22 +282,22 @@ sub reloadConf { $self->{"_$type"} = {}; if ( $self->conf->{$type} ) { for my $name ( sort keys %{ $self->conf->{$type} } ) { - my $sub = HANDLER->buildSub( + my $sub = + HANDLER->buildSub( HANDLER->substitute( $self->conf->{$type}->{$name} ) ); if ($sub) { $self->{"_$type"}->{$name} = $sub; } else { $self->logger->error( "$type $name returns an error: " - . HANDLER->tsv->{jail}->error ); + . HANDLER->tsv->{jail}->error ); } } } } - $self->{_jsRedirect} - = HANDLER->buildSub( - HANDLER->substitute( $self->conf->{jsRedirect} ) ) - or $self->logger->error( + $self->{_jsRedirect} = + HANDLER->buildSub( HANDLER->substitute( $self->conf->{jsRedirect} ) ) + or $self->logger->error( 'jsRedirect returns an error: ' . HANDLER->tsv->{jail}->error ); # Load plugins @@ -332,7 +333,7 @@ sub loadPlugin { } my $obj; return 0 - unless ( $obj = $self->loadModule("$plugin") ); + unless ( $obj = $self->loadModule("$plugin") ); return $self->findEP( $plugin, $obj ); } @@ -361,7 +362,7 @@ sub findEP { if ( $obj->can('spRules') ) { foreach my $k ( keys %{ $obj->{spRules} } ) { $self->logger->info( - "$k is defined more than one time, it can have some bad effect on Menu display" +"$k is defined more than one time, it can have some bad effect on Menu display" ) if ( $self->spRules->{$k} ); $self->spRules->{$k} = $obj->{spRules}->{$k}; } diff --git a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Main/Issuer.pm b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Main/Issuer.pm index 92f33e712..c0b59afa0 100644 --- a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Main/Issuer.pm +++ b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Main/Issuer.pm @@ -111,7 +111,7 @@ sub _redirect { # Restore urldc if auth doesn't need to dial with browser $self->restoreRequest( $req, $ir ); return $self->run( @_, @path ); - } + } : () ) ] diff --git a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Main/Run.pm b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Main/Run.pm index 7b9aaaf38..95f10aff5 100644 --- a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Main/Run.pm +++ b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Main/Run.pm @@ -17,11 +17,11 @@ use strict; use URI::Escape; # List constants -sub authProcess {qw(extractFormInfo getUser authenticate)} +sub authProcess { qw(extractFormInfo getUser authenticate) } sub sessionData { qw(setAuthSessionInfo setSessionInfo setMacros setGroups setPersistentSessionInfo - setLocalGroups store secondFactor); + setLocalGroups store secondFactor); } sub validSession { @@ -56,9 +56,11 @@ sub handler { if ( $sp or %{ $req->pdata } ) { my %v = ( name => $self->conf->{cookieName} . 'pdata', - ( %{ $req->pdata } + ( + %{ $req->pdata } ? ( value => uri_escape( JSON::to_json( $req->pdata ) ) ) - : ( value => '', + : ( + value => '', expires => 'Wed, 21 Oct 2015 00:00:00 GMT' ) ) @@ -92,7 +94,8 @@ sub login { my ( $self, $req ) = @_; return $self->do( $req, - [ 'controlUrl', @{ $self->beforeAuth }, + [ + 'controlUrl', @{ $self->beforeAuth }, $self->authProcess, @{ $self->betweenAuthAndData }, $self->sessionData, @{ $self->afterData }, $self->validSession, @{ $self->endAuth }, @@ -104,7 +107,8 @@ sub postLogin { my ( $self, $req ) = @_; return $self->do( $req, - [ 'restoreArgs', 'controlUrl', + [ + 'restoreArgs', 'controlUrl', @{ $self->beforeAuth }, $self->authProcess, @{ $self->betweenAuthAndData }, $self->sessionData, @{ $self->afterData }, $self->validSession, @@ -117,7 +121,8 @@ sub authenticatedRequest { my ( $self, $req ) = @_; return $self->do( $req, - [ 'importHandlerData', 'controlUrl', + [ + 'importHandlerData', 'controlUrl', 'checkLogout', @{ $self->forAuthUser } ] ); @@ -127,7 +132,8 @@ sub postAuthenticatedRequest { my ( $self, $req ) = @_; return $self->do( $req, - [ 'importHandlerData', 'restoreArgs', + [ + 'importHandlerData', 'restoreArgs', 'controlUrl', 'checkLogout', @{ $self->forAuthUser } ] @@ -145,7 +151,8 @@ sub refresh { delete $data{$_} unless ( /^_/ or /^(?:startTime)$/ ); } $req->steps( - [ 'getUser', + [ + 'getUser', @{ $self->betweenAuthAndData }, 'setAuthSessionInfo', 'setSessionInfo', @@ -163,21 +170,21 @@ sub refresh { if ($res) { $req->info( $self->loadTemplate( - 'simpleInfo', - params => { trspan => 'rightsReloadNeedsLogout' } + 'simpleInfo', params => { trspan => 'rightsReloadNeedsLogout' } ) ); $req->urldc( $self->conf->{portal} ); - return $self->do( $req, [ sub {PE_INFO} ] ); + return $self->do( $req, [ sub { PE_INFO } ] ); } - return $self->do( $req, [ sub {PE_OK} ] ); + return $self->do( $req, [ sub { PE_OK } ] ); } sub logout { my ( $self, $req ) = @_; return $self->do( $req, - [ 'controlUrl', @{ $self->beforeLogout }, + [ + 'controlUrl', @{ $self->beforeLogout }, 'authLogout', 'deleteSession' ] ); @@ -194,9 +201,9 @@ sub do { # Update status if ( my $p = $self->HANDLER->tsv->{statusPipe} ) { - $p->print(( $req->user ? $req->user : $req->address ) . ' => ' - . $req->uri - . " $err\n" ); + $p->print( ( $req->user ? $req->user : $req->address ) . ' => ' + . $req->uri + . " $err\n" ); } # Update history @@ -208,7 +215,8 @@ sub do { if ( ( $err > 0 and !$req->id ) or $err eq PE_SESSIONNOTGRANTED ) { return [ 401, - [ 'WWW-Authenticate' => "SSO " . $self->conf->{portal}, + [ + 'WWW-Authenticate' => "SSO " . $self->conf->{portal}, 'Access-Control-Allow-Origin' => '*' ], [qq'{"result":0,"error":$err}'] @@ -224,14 +232,16 @@ sub do { else { return $self->sendJSONresponse( $req, - { result => 1, + { + result => 1, code => $err } ); } } else { - if ( $err + if ( + $err and $err != PE_LOGOUT_OK and ( $err != PE_REDIRECT @@ -240,7 +250,7 @@ sub do { and $req->data->{redirectFormMethod} eq 'post' ) or $req->info ) - ) + ) { my ( $tpl, $prms ) = $self->display($req); $self->logger->debug("Calling sendHtml with template $tpl"); @@ -258,20 +268,21 @@ sub do { sub getModule { my ( $self, $req, $type ) = @_; - if (my $mod = { + if ( + my $mod = { auth => '_authentication', user => '_userDB', password => '_passwordDB' }->{$type} - ) + ) { if ( my $sub = $self->$mod->can('name') ) { return $sub->( $self->$mod, $req, $type ); } else { my $s = ref( $self->$mod ); - $s - =~ s/^Lemonldap::NG::Portal::(?:(?:Issuer|UserDB|Auth|Password)::)?//; + $s =~ +s/^Lemonldap::NG::Portal::(?:(?:Issuer|UserDB|Auth|Password)::)?//; return $s; } } @@ -288,7 +299,7 @@ sub autoRedirect { # Set redirection URL if needed $req->{urldc} ||= $self->conf->{portal} - if ( $req->mustRedirect and not( $req->info ) ); + if ( $req->mustRedirect and not( $req->info ) ); # Redirection should be made if urldc defined if ( $req->{urldc} ) { @@ -298,9 +309,8 @@ sub autoRedirect { $req->data->{redirectFormMethod} = "get"; } else { - return [ - 302, [ Location => $req->{urldc}, @{ $req->respHeaders } ], [] - ]; + return [ 302, + [ Location => $req->{urldc}, @{ $req->respHeaders } ], [] ]; } } my ( $tpl, $prms ) = $self->display($req); @@ -322,7 +332,8 @@ sub getApacheSession { } my $as = Lemonldap::NG::Common::Session->new( - { storageModule => $self->conf->{globalStorage}, + { + storageModule => $self->conf->{globalStorage}, storageModuleOptions => $self->conf->{globalStorageOptions}, cacheModule => $self->conf->{localSessionStorage}, cacheModuleOptions => $self->conf->{localSessionStorageOptions}, @@ -336,7 +347,8 @@ sub getApacheSession { if ( my $err = $as->error ) { $self->lmLog( $err, - ( $err =~ /(?:Object does not exist|Invalid session ID)/ + ( + $err =~ /(?:Object does not exist|Invalid session ID)/ ? 'notice' : 'error' ) @@ -350,16 +362,17 @@ sub getApacheSession { } my $now = time; - if ( $id + if ( + $id and defined $as->data->{_utime} and ( $now - $as->data->{_utime} > $self->conf->{timeout} or ( $self->conf->{timeoutActivity} and $as->data->{_lastSeen} - and $now - $as->data->{_lastSeen} - > $self->conf->{timeoutActivity} ) - ) + and $now - $as->data->{_lastSeen} > + $self->conf->{timeoutActivity} ) ) + ) { $self->logger->debug("Session $args{kind} $id expired"); return; @@ -382,7 +395,8 @@ sub getPersistentSession { $info->{_session_uid} = $uid; my $ps = Lemonldap::NG::Common::Session->new( - { storageModule => $self->conf->{persistentStorage}, + { + storageModule => $self->conf->{persistentStorage}, storageModuleOptions => $self->conf->{persistentStorageOptions}, id => $pid, force => 1, @@ -423,11 +437,10 @@ sub updatePersistentSession { # Return if no infos to update return () unless ( ref $infos eq 'HASH' and %$infos ); $uid ||= $req->{sessionInfo}->{ $self->conf->{whatToTrace} } - || $req->userData->{ $self->conf->{whatToTrace} }; + || $req->userData->{ $self->conf->{whatToTrace} }; $self->logger->debug("Found 'whatToTrace' -> $uid"); unless ($uid) { - $self->logger->debug( - 'No uid found, skipping updatePersistentSession'); + $self->logger->debug('No uid found, skipping updatePersistentSession'); return (); } $self->logger->debug("Update $uid persistent session"); @@ -469,14 +482,14 @@ sub updateSession { foreach ( keys %$infos ) { $self->logger->debug( "Update sessionInfo $_ with " . $infos->{$_} ); - $req->{sessionInfo}->{$_} = $self->HANDLER->data->{$_} - = $infos->{$_}; + $req->{sessionInfo}->{$_} = $self->HANDLER->data->{$_} = + $infos->{$_}; } # Update session in global storage with _updateTime $infos->{_updateTime} = strftime( "%Y%m%d%H%M%S", localtime() ); - if ( my $apacheSession - = $self->getApacheSession( $id, info => $infos ) ) + if ( my $apacheSession = + $self->getApacheSession( $id, info => $infos ) ) { if ( $apacheSession->error ) { $self->logger->error("Cannot update session $id"); @@ -559,10 +572,10 @@ sub isTrustedUrl { sub stamp { my $self = shift; - my $res - = $self->conf->{cipher} - ? $self->conf->{cipher}->encrypt( time() ) - : 1; + my $res = + $self->conf->{cipher} + ? $self->conf->{cipher}->encrypt( time() ) + : 1; $res =~ s/\+/%2B/g; return $res; } @@ -694,7 +707,7 @@ sub cookie { $h{path} ||= '/'; $h{HttpOnly} //= $self->conf->{httpOnly}; $h{max_age} //= $self->conf->{cookieExpiration} - if ( $self->conf->{cookieExpiration} ); + if ( $self->conf->{cookieExpiration} ); foreach (qw(domain path expires max_age HttpOnly)) { my $f = $_; $f =~ s/_/-/g; @@ -717,8 +730,8 @@ sub sendHtml { my ( $self, $req, $template, %args ) = @_; my $res = $self->SUPER::sendHtml( $req, $template, %args ); push @{ $res->[1] }, - 'X-XSS-Protection' => '1; mode=block', - 'X-Content-Type-Options' => 'nosniff'; + 'X-XSS-Protection' => '1; mode=block', + 'X-Content-Type-Options' => 'nosniff'; # Set authorized URL for POST my $csp = $self->csp . "form-action 'self'"; @@ -732,14 +745,13 @@ sub sendHtml { if ( defined $url ) { $self->logger->debug("Required Params URL : $url"); if ( $url =~ s#(https?://[^/]+).*#$1# ) { - $self->logger->debug( - "Set CSP form-action with Params URL : $url"); + $self->logger->debug("Set CSP form-action with Params URL : $url"); $csp .= " $url"; } } if ( defined $req->{cspFormAction} ) { - $self->logger->debug( "Set CSP form-action with request URL: " - . $req->{cspFormAction} ); + $self->logger->debug( + "Set CSP form-action with request URL: " . $req->{cspFormAction} ); $csp .= " " . $req->{cspFormAction}; } $csp .= ';'; @@ -754,7 +766,7 @@ sub sendHtml { my @url; if ( $req->info ) { @url = map { s#https?://([^/]+).*#$1#; $_ } - ( $req->info =~ /info =~ /staticPrefix - . '/common/backgrounds/' - . $self->conf->{portalSkinBackground} - . '") no-repeat center fixed;' - . 'background-size:cover;}'; + my $s = + 'html,body{background:url("' + . $self->staticPrefix + . '/common/backgrounds/' + . $self->conf->{portalSkinBackground} + . '") no-repeat center fixed;' + . 'background-size:cover;}'; return [ 200, - [ 'Content-Type' => 'text/css', + [ + 'Content-Type' => 'text/css', 'Content-Length' => length($s), 'Cache-Control' => 'public,max-age=3600', ], @@ -799,16 +812,16 @@ sub lmError { # Error code $templateParams{"ERROR$_"} = ( $httpError == $_ ? 1 : 0 ) - foreach ( 403, 404, 500, 502, 503 ); + foreach ( 403, 404, 500, 502, 503 ); return $self->sendHtml( $req, 'error', params => \%templateParams ); } sub rebuildCookies { my ( $self, $req ) = @_; my @tmp; - for ( my $i = 0; $i < @{ $req->{respHeaders} }; $i += 2 ) { + for ( my $i = 0 ; $i < @{ $req->{respHeaders} } ; $i += 2 ) { push @tmp, $req->respHeaders->[0], $req->respHeaders->[1] - unless ( $req->respHeaders->[0] eq 'Set-Cookie' ); + unless ( $req->respHeaders->[0] eq 'Set-Cookie' ); } $req->{respHeaders} = \@tmp; $self->buildCookie($req); @@ -831,7 +844,7 @@ sub tplParams { sub registerLogin { my ( $self, $req ) = @_; return - unless ( $self->conf->{loginHistoryEnabled} + unless ( $self->conf->{loginHistoryEnabled} and defined $req->authResult ); my $history = $req->sessionInfo->{_loginHistory} ||= {}; my $type = ( $req->authResult > 0 ? 'failed' : 'success' ) . 'Login'; @@ -841,17 +854,17 @@ sub registerLogin { # Gather current login's parameters my $login = $self->_sumUpSession( $req->{sessionInfo}, 1 ); $login->{error} = $self->error( $req->authResult ) - if ( $req->authResult ); + if ( $req->authResult ); - $self->logger->debug(" Current login -> " . $login->{error}) if ( $login->{error} ); + $self->logger->debug( " Current login -> " . $login->{error} ) + if ( $login->{error} ); # Add current login into history unshift @{ $history->{$type} }, $login; # Forget oldest logins splice @{ $history->{$type} }, $self->conf->{ $type . "Number" } - if ( - scalar @{ $history->{$type} } > $self->conf->{ $type . "Number" } ); + if ( scalar @{ $history->{$type} } > $self->conf->{ $type . "Number" } ); # Save into persistent session $self->updatePersistentSession( $req, { _loginHistory => $history, } ); @@ -862,12 +875,12 @@ sub registerLogin { # @return hashref sub _sumUpSession { my ( $self, $session, $withoutUser ) = @_; - my $res - = $withoutUser - ? {} - : { user => $session->{ $self->conf->{whatToTrace} } }; + my $res = + $withoutUser + ? {} + : { user => $session->{ $self->conf->{whatToTrace} } }; $res->{$_} = $session->{$_} - foreach ( "_utime", "ipAddr", + foreach ( "_utime", "ipAddr", keys %{ $self->conf->{sessionDataToRemember} } ); return $res; } @@ -876,12 +889,12 @@ sub _sumUpSession { sub loadTemplate { my ( $self, $name, %prm ) = @_; $name .= '.tpl'; - my $file - = $self->conf->{templateDir} . '/' - . $self->conf->{portalSkin} . '/' - . $name; + my $file = + $self->conf->{templateDir} . '/' + . $self->conf->{portalSkin} . '/' + . $name; $file = $self->conf->{templateDir} . '/common/' . $name - unless ( -e $file ); + unless ( -e $file ); unless ( -e $file ) { die "Unable to find $name in $self->conf->{templateDir}"; } diff --git a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Main/SecondFactor.pm b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Main/SecondFactor.pm index 17aae63a6..0162a7e6f 100644 --- a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Main/SecondFactor.pm +++ b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Main/SecondFactor.pm @@ -3,11 +3,11 @@ package Lemonldap::NG::Portal::Main::SecondFactor; use strict; use Mouse; use Lemonldap::NG::Portal::Main::Constants qw( - PE_SENDRESPONSE - PE_OK - PE_NOTOKEN - PE_TOKENEXPIRED - PE_BADCREDENTIALS + PE_SENDRESPONSE + PE_OK + PE_NOTOKEN + PE_TOKENEXPIRED + PE_BADCREDENTIALS ); our $VERSION = '2.0.0'; @@ -19,8 +19,8 @@ extends 'Lemonldap::NG::Portal::Main::Plugin'; has ott => ( is => 'rw', default => sub { - my $ott = $_[0]->{p} - ->loadModule('Lemonldap::NG::Portal::Lib::OneTimeToken'); + my $ott = + $_[0]->{p}->loadModule('Lemonldap::NG::Portal::Lib::OneTimeToken'); $ott->timeout( $_[0]->{conf}->{formTimeout} ); return $ott; } @@ -52,8 +52,7 @@ sub _redirect { my ( $self, $req ) = @_; my $arg = $req->env->{QUERY_STRING}; return [ - 302, [ Location => $self->conf->{portal} . ( $arg ? "?$arg" : '' ) ], - [] + 302, [ Location => $self->conf->{portal} . ( $arg ? "?$arg" : '' ) ], [] ]; } @@ -66,16 +65,15 @@ sub _verify { # Check token my $token; unless ( $token = $req->param('token') ) { - $self->userLogger->error( - $self->prefix . ' 2F access without token' ); + $self->userLogger->error( $self->prefix . ' 2F access without token' ); $req->mustRedirect(1); - return $self->p->do( $req, [ sub {PE_NOTOKEN} ] ); + return $self->p->do( $req, [ sub { PE_NOTOKEN } ] ); } my $session; unless ( $session = $self->ott->getToken($token) ) { $self->userLogger->info('Token expired'); - return $self->p->do( $req, [ sub {PE_TOKENEXPIRED} ] ); + return $self->p->do( $req, [ sub { PE_TOKENEXPIRED } ] ); } # Launch second factor verification @@ -90,7 +88,7 @@ sub _verify { $req->{sessionInfo}->{_utime} = delete $req->{sessionInfo}->{_2fUtime}; $req->authResult(PE_BADCREDENTIALS); return $self->p->do( $req, - [ $self->p->storeHistory($req), sub {$res} ] ); + [ $self->p->storeHistory($req), sub { $res } ] ); } # Else restore session @@ -101,15 +99,22 @@ sub _verify { $self->p->rebuildCookies($req); $req->mustRedirect(1); $self->userLogger->notice( $self->prefix - . '2F verification for ' - . $req->sessionInfo->{ $self->conf->{whatToTrace} } ); + . '2F verification for ' + . $req->sessionInfo->{ $self->conf->{whatToTrace} } ); if ( my $l = $self->conf->{ $self->prefix . '2fAuthnLevel' } ) { $self->p->updateSession( $req, { authenticationLevel => $l } ); } $req->authResult(PE_SENDRESPONSE); - return $self->p->do( $req, - [ @{ $self->p->afterData }, $self->p->validSession, @{ $self->p->endAuth }, sub {PE_OK} ] ); + return $self->p->do( + $req, + [ + @{ $self->p->afterData }, + $self->p->validSession, + @{ $self->p->endAuth }, + sub { PE_OK } + ] + ); } 1; diff --git a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Plugins/BruteForceProtection.pm b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Plugins/BruteForceProtection.pm index 9ddb8525f..5152ba3be 100644 --- a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Plugins/BruteForceProtection.pm +++ b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Plugins/BruteForceProtection.pm @@ -40,11 +40,9 @@ sub run { return PE_OK if ( $countFailed < 3 ); foreach ( 0 .. 2 ) { - if ( defined $req->sessionInfo->{_loginHistory}->{failedLogin}->[$_] ) - { + if ( defined $req->sessionInfo->{_loginHistory}->{failedLogin}->[$_] ) { push @lastFailedLoginEpoch, - $req->sessionInfo->{_loginHistory}->{failedLogin}->[$_] - ->{_utime}; + $req->sessionInfo->{_loginHistory}->{failedLogin}->[$_]->{_utime}; } } $self->logger->debug("BruteForceProtection enabled"); @@ -53,7 +51,7 @@ sub run { $MaxAge = $lastFailedLoginEpoch[0] - $lastFailedLoginEpoch[2]; $self->logger->debug(" -> MaxAge = $MaxAge"); return PE_OK - if ( $MaxAge > $self->conf->{bruteForceProtectionMaxAge} ); + if ( $MaxAge > $self->conf->{bruteForceProtectionMaxAge} ); # Delta between the two last failed logins -> Auth_N - Auth_N-1 my $delta = time - $lastFailedLoginEpoch[1]; @@ -61,7 +59,7 @@ sub run { # Delta between the two last failed logins < 30s => wait return PE_OK - unless ( $delta <= $self->conf->{bruteForceProtectionTempo} ); + unless ( $delta <= $self->conf->{bruteForceProtectionTempo} ); # Account locked #shift @{ $req->sessionInfo->{_loginHistory}->{failedLogin} }; diff --git a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Plugins/ForceAuthn.pm b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Plugins/ForceAuthn.pm index 21cdfc23e..8c8b3f041 100644 --- a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Plugins/ForceAuthn.pm +++ b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Plugins/ForceAuthn.pm @@ -12,7 +12,7 @@ extends 'Lemonldap::NG::Portal::Main::Plugin'; use constant forAuthUser => 'run'; -sub init {1} +sub init { 1 } # RUNNING METHOD @@ -25,8 +25,8 @@ sub run { $self->logger->debug( "Delta with last Authn -> " . $delta ); $delta <= $self->conf->{portalForceAuthnInterval} - ? return PE_OK - : return PE_MUSTAUTHN; + ? return PE_OK + : return PE_MUSTAUTHN; } } diff --git a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Plugins/GrantSession.pm b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Plugins/GrantSession.pm index 7db296385..730d53fe4 100644 --- a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Plugins/GrantSession.pm +++ b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Plugins/GrantSession.pm @@ -3,8 +3,8 @@ package Lemonldap::NG::Portal::Plugins::GrantSession; use strict; use Mouse; use Lemonldap::NG::Portal::Main::Constants qw( - PE_OK - PE_SESSIONNOTGRANTED + PE_OK + PE_SESSIONNOTGRANTED ); our $VERSION = '2.0.0'; @@ -22,11 +22,11 @@ sub init { $self->logger->debug("GrantRule key -> $_"); $self->logger->debug( "GrantRule value -> " . $self->conf->{grantSessionRules}->{$_} ); - my $rule = $hd->buildSub( + my $rule = + $hd->buildSub( $hd->substitute( $self->conf->{grantSessionRules}->{$_} ) ); unless ($rule) { - $self->error( - "Bad grantSession rule " . $hd->tsv->{jail}->error ); + $self->error( "Bad grantSession rule " . $hd->tsv->{jail}->error ); return 0; } $self->rules->{$_} = $rule; @@ -45,7 +45,7 @@ sub run { foreach ( sort sortByComment keys %{ $self->rules } ) { $self->logger->debug( "Grant session condition -> " - . $self->conf->{grantSessionRules}->{$_} ); + . $self->conf->{grantSessionRules}->{$_} ); unless ( $self->rules->{$_}->( $req, $req->sessionInfo ) ) { $req->userData( {} ); @@ -54,7 +54,7 @@ sub run { if ($1) { $self->logger->debug("Message -> $1"); - # Message can contain session data as user attributes or macros + # Message can contain session data as user attributes or macros my $hd = $self->p->HANDLER; my $msg = $hd->substitute($1); unless ( $msg = $hd->buildSub($msg) ) { @@ -68,17 +68,17 @@ sub run { ) ); $self->userLogger->error( 'User ' - . $req->sessionInfo->{uid} - . " was not granted to open session (rule -> $msg)" ); + . $req->sessionInfo->{uid} + . " was not granted to open session (rule -> $msg)" ); $req->urldc( $self->conf->{portal} ); return $req->authResult(PE_SESSIONNOTGRANTED); } else { $self->userLogger->error( 'User ' - . $req->sessionInfo->{uid} - . " was not granted to open session (rule -> " - . $self->conf->{grantSessionRules}->{$_} - . ")" ); + . $req->sessionInfo->{uid} + . " was not granted to open session (rule -> " + . $self->conf->{grantSessionRules}->{$_} + . ")" ); $req->urldc( $self->conf->{portal} ); return $req->authResult(PE_SESSIONNOTGRANTED); } diff --git a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Plugins/History.pm b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Plugins/History.pm index 5f862b89c..6252ae3a8 100644 --- a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Plugins/History.pm +++ b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Plugins/History.pm @@ -28,15 +28,15 @@ sub run { $req->sessionInfo->{_loginHistory}->{successLogin}, 'lastLogins', 0, 0 ) : "" - ) - . ("
") . - ( + ) + . ("
") + . ( $req->sessionInfo->{_loginHistory}->{failedLogin} ? $self->p->mkSessionArray( $req->sessionInfo->{_loginHistory}->{failedLogin}, 'lastFailedLogins', 0, 1 ) : "" - ) + ) ); unless ( $req->info ) { $req->info( $self->loadTemplate('noHistory') ); diff --git a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Register/AD.pm b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Register/AD.pm index ebab90c02..651dd7964 100644 --- a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Register/AD.pm +++ b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Register/AD.pm @@ -32,7 +32,7 @@ sub createUser { givenName => $gn, unicodePwd => utf8( chr(34) . $req->data->{registerInfo}->{password} . chr(34) - )->utf16le(), + )->utf16le(), mail => $req->data->{registerInfo}->{mail}, ] ); diff --git a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Register/Custom.pm b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Register/Custom.pm index 537c6b5c8..36602793b 100644 --- a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Register/Custom.pm +++ b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Register/Custom.pm @@ -9,7 +9,7 @@ sub new { } my $res = $self->{p}->loadModule( $self->{conf}->{customRegister} ); - unless($res) { + unless ($res) { die 'Unable to load register module ' . $self->{conf}->{customRegister}; } return $res; diff --git a/lemonldap-ng-portal/t/40-Notifications-JSON-DBI.t b/lemonldap-ng-portal/t/40-Notifications-JSON-DBI.t index ca45d7dd8..055327d4b 100644 --- a/lemonldap-ng-portal/t/40-Notifications-JSON-DBI.t +++ b/lemonldap-ng-portal/t/40-Notifications-JSON-DBI.t @@ -20,7 +20,7 @@ SKIP: { ); $dbh->prepare( q{INSERT INTO notifications VALUES ('dwho','testref','2016-05-30 00:00:00',?,null,null)} - )->execute( + )->execute( '[ { "uid": "dwho", @@ -32,7 +32,7 @@ q{INSERT INTO notifications VALUES ('dwho','testref','2016-05-30 00:00:00',?,nul "check": ["Accept test"] } ]' - ); + ); my $client = LLNG::Manager::Test->new( { diff --git a/lemonldap-ng-portal/t/40-Notifications-JSON-File.t b/lemonldap-ng-portal/t/40-Notifications-JSON-File.t index 65f76f428..fa4b7c87d 100644 --- a/lemonldap-ng-portal/t/40-Notifications-JSON-File.t +++ b/lemonldap-ng-portal/t/40-Notifications-JSON-File.t @@ -111,8 +111,8 @@ ok( ), 'New auth query' ); -expectAuthenticatedAs($res,'dwho'); -ok($res->[2]->[0] =~ /yourApp/s, 'Menu displayed'); +expectAuthenticatedAs( $res, 'dwho' ); +ok( $res->[2]->[0] =~ /yourApp/s, 'Menu displayed' ); count(2); clean_sessions(); diff --git a/lemonldap-ng-portal/t/43-MailReset-DBI.t b/lemonldap-ng-portal/t/43-MailReset-DBI.t index 651f921e6..15c1f3b5f 100644 --- a/lemonldap-ng-portal/t/43-MailReset-DBI.t +++ b/lemonldap-ng-portal/t/43-MailReset-DBI.t @@ -16,7 +16,6 @@ my $mailSend = 0; my $mail2 = 0; - SKIP: { eval 'require Email::Sender::Simple;use GD::SecurityImage;use Image::Magick;'; diff --git a/lemonldap-ng-portal/t/61-BruteForceProtection.t b/lemonldap-ng-portal/t/61-BruteForceProtection.t index f47bd6dbe..8de0d8f4e 100644 --- a/lemonldap-ng-portal/t/61-BruteForceProtection.t +++ b/lemonldap-ng-portal/t/61-BruteForceProtection.t @@ -10,7 +10,8 @@ BEGIN { my $res; my $client = LLNG::Manager::Test->new( - { ini => { + { + ini => { logLevel => 'error', authentication => 'Demo', userDB => 'Same', @@ -22,7 +23,8 @@ my $client = LLNG::Manager::Test->new( ); ## First successful connection -ok( $res = $client->_post( +ok( + $res = $client->_post( '/', IO::String->new('user=dwho&password=dwho'), length => 23, @@ -37,7 +39,8 @@ expectRedirection( $res, 'http://auth.example.com/' ); $client->logout($id1); ## Second successful connection -ok( $res = $client->_post( +ok( + $res = $client->_post( '/', IO::String->new('user=dwho&password=dwho'), length => 23, @@ -52,7 +55,8 @@ expectRedirection( $res, 'http://auth.example.com/' ); $client->logout($id1); ## First failed connection -ok( $res = $client->_post( +ok( + $res = $client->_post( '/', IO::String->new('user=dwho&password=ohwd'), length => 23 @@ -63,7 +67,8 @@ count(1); expectReject($res); ## Second failed connection -ok( $res = $client->_post( +ok( + $res = $client->_post( '/', IO::String->new('user=dwho&password=ohwd'), length => 23 @@ -74,7 +79,8 @@ count(1); expectReject($res); ## Third failed connection -> rejected -ok( $res = $client->_post( +ok( + $res = $client->_post( '/', IO::String->new('user=dwho&password=ohwd'), length => 23, @@ -89,7 +95,8 @@ count(1); sleep 1; ## Fourth failed connection -> Rejected -ok( $res = $client->_post( +ok( + $res = $client->_post( '/', IO::String->new('user=dwho&password=ohwd'), length => 23, @@ -104,7 +111,8 @@ count(1); sleep 2; ## Third successful connection -> Rejected -ok( $res = $client->_post( +ok( + $res = $client->_post( '/', IO::String->new('user=dwho&password=dwho'), length => 23, @@ -119,7 +127,8 @@ count(1); sleep 3; ## Fourth successful connection -> Accepted -ok( $res = $client->_post( +ok( + $res = $client->_post( '/', IO::String->new('user=dwho&password=dwho&checkLogins=1'), length => 37, @@ -131,7 +140,7 @@ count(1); $id1 = expectCookie($res); ok( $res->[2]->[0] =~ /trspan="lastLogins"/, 'History found' ) - or print STDERR Dumper( $res->[2]->[0] ); + or print STDERR Dumper( $res->[2]->[0] ); my @c = ( $res->[2]->[0] =~ /127.0.0.1/gs ); my @cf = ( $res->[2]->[0] =~ /PE5<\/td>/gs ); diff --git a/lemonldap-ng-portal/t/61-ForceAuthn.t b/lemonldap-ng-portal/t/61-ForceAuthn.t index adaf0e93a..ca6d7a68c 100644 --- a/lemonldap-ng-portal/t/61-ForceAuthn.t +++ b/lemonldap-ng-portal/t/61-ForceAuthn.t @@ -10,7 +10,8 @@ BEGIN { my $res; my $client = LLNG::Manager::Test->new( - { ini => { + { + ini => { authentication => 'Demo', userdb => 'Same', portalForceAuthn => 1, @@ -19,7 +20,8 @@ my $client = LLNG::Manager::Test->new( } ); -ok( $res = $client->_post( +ok( + $res = $client->_post( '/', IO::String->new('user=dwho&password=dwho'), length => 23 @@ -33,7 +35,8 @@ count(1); sleep 3; -ok( $res = $client->_get( +ok( + $res = $client->_get( '/', cookie => "lemonldap=$id1", accept => 'text/html', @@ -41,10 +44,11 @@ ok( $res = $client->_get( 'Form ReAuthentification' ); ok( $res->[2]->[0] =~ qr%%, 'Found PE87 code' ) - or print STDERR Dumper( $res->[2]->[0] ); + or print STDERR Dumper( $res->[2]->[0] ); count(1); -ok( $res = $client->_post( +ok( + $res = $client->_post( '/', IO::String->new('user=dwho&password=dwho'), length => 23, @@ -56,7 +60,8 @@ expectOK($res); $id1 = expectCookie($res); count(1); -ok( $res = $client->_get( +ok( + $res = $client->_get( '/', cookie => "lemonldap=$id1", accept => 'text/html', @@ -65,7 +70,7 @@ ok( $res = $client->_get( ); ok( $res->[2]->[0] =~ qr%Your applications%, 'Found applications list' ) - or print STDERR Dumper( $res->[2]->[0] ); + or print STDERR Dumper( $res->[2]->[0] ); count(1); $client->logout($id1); diff --git a/lemonldap-ng-portal/t/61-GrantSession.t b/lemonldap-ng-portal/t/61-GrantSession.t index 0e082eb05..eac56ef59 100644 --- a/lemonldap-ng-portal/t/61-GrantSession.t +++ b/lemonldap-ng-portal/t/61-GrantSession.t @@ -10,7 +10,8 @@ BEGIN { my $res; my $client = LLNG::Manager::Test->new( - { ini => { + { + ini => { logLevel => 'error', authentication => 'Demo', userdb => 'Same', @@ -23,7 +24,8 @@ my $client = LLNG::Manager::Test->new( } ); -ok( $res = $client->_post( +ok( + $res = $client->_post( '/', IO::String->new('user=dwho&password=dwho'), accept => 'text/html', @@ -33,15 +35,16 @@ ok( $res = $client->_post( ); count(1); ok( $res->[2]->[0] =~ /

dwho not allowed<\/h3>/, - 'dwho rejected with custom message and session data' -) or print STDERR Dumper( $res->[2]->[0] ); + 'dwho rejected with custom message and session data' ) + or print STDERR Dumper( $res->[2]->[0] ); count(1); ok( $res->[2]->[0] =~ qr%src="/static/common/js/info.(?:min\.)?js">%, - 'Found INFO js' -) or print STDERR Dumper( $res->[2]->[0] ); + 'Found INFO js' ) + or print STDERR Dumper( $res->[2]->[0] ); count(1); -ok( $res = $client->_post( +ok( + $res = $client->_post( '/', IO::String->new('user=rtyler&password=rtyler'), length => 27 @@ -52,7 +55,8 @@ count(1); expectOK($res); expectCookie($res); -ok( $res = $client->_post( +ok( + $res = $client->_post( '/', IO::String->new('user=mrsmith&password=mrsmith'), accept => 'text/html', @@ -61,7 +65,8 @@ ok( $res = $client->_post( 'Auth query' ); count(1); -ok( $res->[2]->[0] =~ /<\/span><\/div>/, +ok( + $res->[2]->[0] =~ /<\/span><\/div>/, 'rtyler rejected with PE_SESSIONNOTGRANTED' ) or print STDERR Dumper( $res->[2]->[0] ); count(1); @@ -72,7 +77,8 @@ count(1); &Lemonldap::NG::Handler::Main::cfgNum( 0, 0 ); $client = LLNG::Manager::Test->new( - { ini => { + { + ini => { authentication => 'Demo', userdb => 'Same', grantSessionRules => { '' => '$uid eq "dwho"', } @@ -80,7 +86,8 @@ $client = LLNG::Manager::Test->new( } ); -ok( $res = $client->_post( +ok( + $res = $client->_post( '/', IO::String->new('user=dwho&password=dwho'), length => 23 diff --git a/lemonldap-ng-portal/t/63-History.t b/lemonldap-ng-portal/t/63-History.t index 4bce96cb7..d7e9fbe40 100644 --- a/lemonldap-ng-portal/t/63-History.t +++ b/lemonldap-ng-portal/t/63-History.t @@ -9,7 +9,8 @@ BEGIN { my $res; my $client = LLNG::Manager::Test->new( - { ini => { + { + ini => { logLevel => 'error', authentication => 'Demo', userDB => 'Same', @@ -20,7 +21,8 @@ my $client = LLNG::Manager::Test->new( ); ## First successful connection -ok( $res = $client->_post( +ok( + $res = $client->_post( '/', IO::String->new('user=dwho&password=dwho&checkLogins=1'), length => 37, @@ -32,7 +34,7 @@ count(1); expectOK($res); my $id1 = expectCookie($res); ok( $res->[2]->[0] =~ /trspan="lastLogins"/, 'History found' ) - or explain( $res->[2]->[0], 'trspan="noHistory"' ); + or explain( $res->[2]->[0], 'trspan="noHistory"' ); my @c = ( $res->[2]->[0] =~ /127.0.0.1/gs ); # History with 1 successLogin @@ -47,7 +49,8 @@ expectOK($res); $client->logout($id1); ## Second successful connection -ok( $res = $client->_post( +ok( + $res = $client->_post( '/', IO::String->new('user=dwho&password=dwho&checkLogins=1'), length => 37, @@ -69,7 +72,8 @@ count(2); $client->logout($id1); ## First failed connection -ok( $res = $client->_post( +ok( + $res = $client->_post( '/', IO::String->new('user=dwho&password=ohwd'), length => 23 @@ -80,7 +84,8 @@ count(1); expectReject($res); ## Second failed connection -ok( $res = $client->_post( +ok( + $res = $client->_post( '/', IO::String->new('user=dwho&password=ohwd'), length => 23 @@ -91,7 +96,8 @@ count(1); expectReject($res); ## Third successful connection -ok( $res = $client->_post( +ok( + $res = $client->_post( '/', IO::String->new('user=dwho&password=dwho&checkLogins=1'), length => 37, diff --git a/lemonldap-ng-portal/t/72-2F-REST-with-HISTORY.t b/lemonldap-ng-portal/t/72-2F-REST-with-HISTORY.t index e3b2b0698..480631204 100644 --- a/lemonldap-ng-portal/t/72-2F-REST-with-HISTORY.t +++ b/lemonldap-ng-portal/t/72-2F-REST-with-HISTORY.t @@ -34,13 +34,13 @@ LWP::Protocol::PSGI->register( my $client = LLNG::Manager::Test->new( { ini => { - logLevel => 'error', - rest2fActivation => 1, - rest2fInitUrl => 'http://auth.example.com/init', - rest2fInitArgs => { name => 'uid' }, - rest2fVerifyUrl => 'http://auth.example.com/vrfy', - rest2fVerifyArgs => { code => 'code' }, - loginHistoryEnabled => 1, + logLevel => 'error', + rest2fActivation => 1, + rest2fInitUrl => 'http://auth.example.com/init', + rest2fInitArgs => { name => 'uid' }, + rest2fVerifyUrl => 'http://auth.example.com/vrfy', + rest2fVerifyArgs => { code => 'code' }, + loginHistoryEnabled => 1, authentication => 'Demo', userDB => 'Same', } @@ -74,9 +74,8 @@ ok( ); my $id = expectCookie($res); - ok( $res->[2]->[0] =~ /trspan="lastLogins"/, 'History found' ) - or print STDERR Dumper( $res->[2]->[0] ); + or print STDERR Dumper( $res->[2]->[0] ); my @c = ( $res->[2]->[0] =~ /127.0.0.1/gs ); ok( @c == 1, 'One entry found' ); diff --git a/lemonldap-ng-portal/t/76-2F-Ext-with-BruteForce.t b/lemonldap-ng-portal/t/76-2F-Ext-with-BruteForce.t index 53d9c588b..acd724eba 100644 --- a/lemonldap-ng-portal/t/76-2F-Ext-with-BruteForce.t +++ b/lemonldap-ng-portal/t/76-2F-Ext-with-BruteForce.t @@ -9,7 +9,8 @@ use_ok('Lemonldap::NG::Common::FormEncode'); count(1); my $client = LLNG::Manager::Test->new( - { ini => { + { + ini => { logLevel => 'error', ext2fActivation => 1, ext2FSendCommand => 't/sendOTP.pl -uid $uid', @@ -26,7 +27,8 @@ my $client = LLNG::Manager::Test->new( my $res; ## First failed connection -ok( $res = $client->_post( +ok( + $res = $client->_post( '/', IO::String->new('user=dwho&password=ohwd'), length => 23 @@ -37,7 +39,8 @@ count(1); expectReject($res); ## Second failed connection -ok( $res = $client->_post( +ok( + $res = $client->_post( '/', IO::String->new('user=dwho&password=ohwd'), length => 23 @@ -48,7 +51,8 @@ count(1); expectReject($res); ## Third failed connection -> rejected -ok( $res = $client->_post( +ok( + $res = $client->_post( '/', IO::String->new('user=dwho&password=ohwd'), length => 23, @@ -64,7 +68,8 @@ sleep 2; # Try to authenticate # ------------------- -ok( $res = $client->_post( +ok( + $res = $client->_post( '/', IO::String->new('user=dwho&password=dwho&checkLogins=1'), length => 37, @@ -74,18 +79,19 @@ ok( $res = $client->_post( ); count(1); -my ( $host, $url, $query ) - = expectForm( $res, undef, '/ext2fcheck', 'token', 'code', - 'checkLogins' ); +my ( $host, $url, $query ) = + expectForm( $res, undef, '/ext2fcheck', 'token', 'code', 'checkLogins' ); -ok( $res->[2]->[0] - =~ qr%%, +ok( + $res->[2]->[0] =~ +qr%%, 'Found EXTCODE input' ) or print STDERR Dumper( $res->[2]->[0] ); count(1); $query =~ s/code=/code=123456/; -ok( $res = $client->_post( +ok( + $res = $client->_post( '/ext2fcheck', IO::String->new($query), length => length($query), @@ -102,7 +108,8 @@ sleep 4; # Try to authenticate again # ------------------------- -ok( $res = $client->_post( +ok( + $res = $client->_post( '/', IO::String->new('user=dwho&password=dwho&checkLogins=1'), length => 37, @@ -112,18 +119,19 @@ ok( $res = $client->_post( ); count(1); -( $host, $url, $query ) - = expectForm( $res, undef, '/ext2fcheck', 'token', 'code', - 'checkLogins' ); +( $host, $url, $query ) = + expectForm( $res, undef, '/ext2fcheck', 'token', 'code', 'checkLogins' ); -ok( $res->[2]->[0] - =~ qr%%, +ok( + $res->[2]->[0] =~ +qr%%, 'Found EXTCODE input' ) or print STDERR Dumper( $res->[2]->[0] ); count(1); $query =~ s/code=/code=123456/; -ok( $res = $client->_post( +ok( + $res = $client->_post( '/ext2fcheck', IO::String->new($query), length => length($query), @@ -136,11 +144,11 @@ count(1); my $id = expectCookie($res); ok( $res->[2]->[0] =~ /trspan="lastLogins"/, 'History found' ) - or print STDERR Dumper( $res->[2]->[0] ); + or print STDERR Dumper( $res->[2]->[0] ); count(1); my @c = ( $res->[2]->[0] =~ /127.0.0.1/gs ); ok( @c == 4, 'Four entries found' ) - or print STDERR Dumper( $res->[2]->[0] ); + or print STDERR Dumper( $res->[2]->[0] ); count(1); $client->logout($id); diff --git a/lemonldap-ng-portal/t/76-2F-Ext-with-GrantSession.t b/lemonldap-ng-portal/t/76-2F-Ext-with-GrantSession.t index 48020befb..444d20495 100644 --- a/lemonldap-ng-portal/t/76-2F-Ext-with-GrantSession.t +++ b/lemonldap-ng-portal/t/76-2F-Ext-with-GrantSession.t @@ -9,15 +9,15 @@ use_ok('Lemonldap::NG::Common::FormEncode'); count(1); my $client = LLNG::Manager::Test->new( - { ini => { + { + ini => { logLevel => 'error', ext2fActivation => 1, ext2FSendCommand => 't/sendOTP.pl -uid $uid', ext2FValidateCommand => 't/vrfyOTP.pl -uid $uid -code $code', authentication => 'Demo', userDB => 'Same', - grantSessionRules => - { 'Dwho_notAllowed##Test' => '$uid ne "dwho"' } + grantSessionRules => { 'Dwho_notAllowed##Test' => '$uid ne "dwho"' } } } ); @@ -26,7 +26,8 @@ my $res; # Try to authenticate # ------------------- -ok( $res = $client->_post( +ok( + $res = $client->_post( '/', IO::String->new('user=dwho&password=dwho'), length => 23, @@ -36,17 +37,19 @@ ok( $res = $client->_post( ); count(1); -my ( $host, $url, $query ) - = expectForm( $res, undef, '/ext2fcheck', 'token', 'code' ); +my ( $host, $url, $query ) = + expectForm( $res, undef, '/ext2fcheck', 'token', 'code' ); -ok( $res->[2]->[0] - =~ qr%%, +ok( + $res->[2]->[0] =~ +qr%%, 'Found EXTCODE input' ) or print STDERR Dumper( $res->[2]->[0] ); count(1); $query =~ s/code=/code=123456/; -ok( $res = $client->_post( +ok( + $res = $client->_post( '/ext2fcheck', IO::String->new($query), length => length($query), @@ -58,12 +61,12 @@ count(1); ok( $res->[2]->[0] =~ /

Dwho_notAllowed<\/h3>/, 'dwho rejected with custom message' ) - or print STDERR Dumper( $res->[2]->[0] ); + or print STDERR Dumper( $res->[2]->[0] ); count(1); ok( $res->[2]->[0] =~ qr%src="/static/common/js/info.(?:min\.)?js">%, - 'Found INFO js' -) or print STDERR Dumper( $res->[2]->[0] ); + 'Found INFO js' ) + or print STDERR Dumper( $res->[2]->[0] ); count(1); clean_sessions(); diff --git a/lemonldap-ng-portal/t/sendOTP.pl b/lemonldap-ng-portal/t/sendOTP.pl index 8138cd796..635ddd128 100755 --- a/lemonldap-ng-portal/t/sendOTP.pl +++ b/lemonldap-ng-portal/t/sendOTP.pl @@ -2,6 +2,6 @@ use strict; use warnings; -my ($swt, $user) = @ARGV; +my ( $swt, $user ) = @ARGV; exit !( $swt eq '-uid' && $user eq 'dwho' ); diff --git a/lemonldap-ng-portal/t/test-lib.pm b/lemonldap-ng-portal/t/test-lib.pm index eb1951b6f..42eaa6041 100644 --- a/lemonldap-ng-portal/t/test-lib.pm +++ b/lemonldap-ng-portal/t/test-lib.pm @@ -58,6 +58,7 @@ use Data::Dumper; use LWP::UserAgent; use URI::Escape; use Lemonldap::NG::Common::FormEncode; + #use 5.10.0; no warnings 'redefine'; @@ -625,7 +626,7 @@ sub _get { : () ), 'REQUEST_METHOD' => $args{method} || 'GET', - 'REQUEST_URI' => $path . ( $args{query} ? "?$args{query}" : '' ), + 'REQUEST_URI' => $path . ( $args{query} ? "?$args{query}" : '' ), ( $args{query} ? ( QUERY_STRING => $args{query} ) : () ), 'SCRIPT_NAME' => '', 'SERVER_NAME' => 'auth.example.com', @@ -677,10 +678,10 @@ sub _post { : () ), 'REQUEST_METHOD' => $args{method} || 'POST', - 'REQUEST_URI' => $path . ( $args{query} ? "?$args{query}" : '' ), - 'SCRIPT_NAME' => '', - 'SERVER_NAME' => 'auth.example.com', - 'SERVER_PORT' => '80', + 'REQUEST_URI' => $path . ( $args{query} ? "?$args{query}" : '' ), + 'SCRIPT_NAME' => '', + 'SERVER_NAME' => 'auth.example.com', + 'SERVER_PORT' => '80', 'SERVER_PROTOCOL' => 'HTTP/1.1', ( $args{custom} ? %{ $args{custom} } : () ), 'psgix.input.buffered' => 0, diff --git a/lemonldap-ng-portal/t/test-psgi.pm b/lemonldap-ng-portal/t/test-psgi.pm index 2e8255975..1691b8a7d 100644 --- a/lemonldap-ng-portal/t/test-psgi.pm +++ b/lemonldap-ng-portal/t/test-psgi.pm @@ -53,7 +53,7 @@ sub mirror { : () ), 'REQUEST_METHOD' => $args{method} || 'GET', - 'REQUEST_URI' => ( $args{path} || '/' ) + 'REQUEST_URI' => ( $args{path} || '/' ) . ( $args{query} ? "?$args{query}" : '' ), ( $args{query} ? ( QUERY_STRING => $args{query} ) : () ), 'SCRIPT_NAME' => '', diff --git a/lemonldap-ng-portal/t/vrfyOTP.pl b/lemonldap-ng-portal/t/vrfyOTP.pl index 6c01fb5ec..69966dfa5 100755 --- a/lemonldap-ng-portal/t/vrfyOTP.pl +++ b/lemonldap-ng-portal/t/vrfyOTP.pl @@ -2,6 +2,9 @@ use strict; use warnings; -my ($swt1, $user, $swt2, $code) = @ARGV; +my ( $swt1, $user, $swt2, $code ) = @ARGV; -exit !( $swt1 eq '-uid' && $user eq 'dwho' && $swt2 eq '-code' && $code eq '123456' ); +exit !($swt1 eq '-uid' + && $user eq 'dwho' + && $swt2 eq '-code' + && $code eq '123456' );