Commit 8941ee4d authored by Xavier Guimard's avatar Xavier Guimard

Merge branch 'v2.0'

parents 77301e70 d620ae2e
Pipeline #4678 passed with stages
in 11 minutes and 56 seconds
......@@ -29,6 +29,7 @@ sub defaultValues {
'casAuthnLevel' => 1,
'checkTime' => 600,
'checkUserHiddenAttributes' => '_2fDevices _loginHistory hGroups',
'checkUserIdRule' => 1,
'checkXSS' => 1,
'confirmFormMethod' => 'post',
'cookieName' => 'lemonldap',
......@@ -71,6 +72,7 @@ sub defaultValues {
'httpOnly' => 1,
'https' => -1,
'impersonationHiddenAttributes' => '_2fDevices _loginHistory',
'impersonationIdRule' => 1,
'impersonationPrefix' => 'real_',
'impersonationRule' => 0,
'impersonationSkipEmptyValues' => 1,
......@@ -245,6 +247,7 @@ sub defaultValues {
'samlOrganizationDisplayName' => 'Example',
'samlOrganizationName' => 'Example',
'samlOrganizationURL' => 'http://www.example.com',
'samlOverrideIDPEntityID' => '',
'samlRelayStateTimeout' => 600,
'samlServiceSignatureMethod' => 'RSA_SHA1',
'samlSPSSODescriptorArtifactResolutionServiceArtifact' =>
......
......@@ -66,7 +66,7 @@ our $issuerParameters = {
issuerDBOpenIDConnect => [qw(issuerDBOpenIDConnectActivation issuerDBOpenIDConnectPath issuerDBOpenIDConnectRule)],
issuerDBSAML => [qw(issuerDBSAMLActivation issuerDBSAMLPath issuerDBSAMLRule)],
};
our $samlServiceParameters = [qw(samlEntityID samlServicePrivateKeySig samlServicePrivateKeySigPwd samlServicePublicKeySig samlServicePrivateKeyEnc samlServicePrivateKeyEncPwd samlServicePublicKeyEnc samlServiceUseCertificateInResponse samlServiceSignatureMethod samlNameIDFormatMapEmail samlNameIDFormatMapX509 samlNameIDFormatMapWindows samlNameIDFormatMapKerberos samlAuthnContextMapPassword samlAuthnContextMapPasswordProtectedTransport samlAuthnContextMapTLSClient samlAuthnContextMapKerberos samlOrganizationDisplayName samlOrganizationName samlOrganizationURL samlSPSSODescriptorAuthnRequestsSigned samlSPSSODescriptorWantAssertionsSigned samlSPSSODescriptorSingleLogoutServiceHTTPRedirect samlSPSSODescriptorSingleLogoutServiceHTTPPost samlSPSSODescriptorSingleLogoutServiceSOAP samlSPSSODescriptorAssertionConsumerServiceHTTPArtifact samlSPSSODescriptorAssertionConsumerServiceHTTPPost samlSPSSODescriptorArtifactResolutionServiceArtifact samlIDPSSODescriptorWantAuthnRequestsSigned samlIDPSSODescriptorSingleSignOnServiceHTTPRedirect samlIDPSSODescriptorSingleSignOnServiceHTTPPost samlIDPSSODescriptorSingleSignOnServiceHTTPArtifact samlIDPSSODescriptorSingleLogoutServiceHTTPRedirect samlIDPSSODescriptorSingleLogoutServiceHTTPPost samlIDPSSODescriptorSingleLogoutServiceSOAP samlIDPSSODescriptorArtifactResolutionServiceArtifact samlAttributeAuthorityDescriptorAttributeServiceSOAP samlIdPResolveCookie samlMetadataForceUTF8 samlStorage samlStorageOptions samlRelayStateTimeout samlUseQueryStringSpecific samlCommonDomainCookieActivation samlCommonDomainCookieDomain samlCommonDomainCookieReader samlCommonDomainCookieWriter samlDiscoveryProtocolActivation samlDiscoveryProtocolURL samlDiscoveryProtocolPolicy samlDiscoveryProtocolIsPassive)];
our $samlServiceParameters = [qw(samlEntityID samlServicePrivateKeySig samlServicePrivateKeySigPwd samlServicePublicKeySig samlServicePrivateKeyEnc samlServicePrivateKeyEncPwd samlServicePublicKeyEnc samlServiceUseCertificateInResponse samlServiceSignatureMethod samlNameIDFormatMapEmail samlNameIDFormatMapX509 samlNameIDFormatMapWindows samlNameIDFormatMapKerberos samlAuthnContextMapPassword samlAuthnContextMapPasswordProtectedTransport samlAuthnContextMapTLSClient samlAuthnContextMapKerberos samlOrganizationDisplayName samlOrganizationName samlOrganizationURL samlSPSSODescriptorAuthnRequestsSigned samlSPSSODescriptorWantAssertionsSigned samlSPSSODescriptorSingleLogoutServiceHTTPRedirect samlSPSSODescriptorSingleLogoutServiceHTTPPost samlSPSSODescriptorSingleLogoutServiceSOAP samlSPSSODescriptorAssertionConsumerServiceHTTPArtifact samlSPSSODescriptorAssertionConsumerServiceHTTPPost samlSPSSODescriptorArtifactResolutionServiceArtifact samlIDPSSODescriptorWantAuthnRequestsSigned samlIDPSSODescriptorSingleSignOnServiceHTTPRedirect samlIDPSSODescriptorSingleSignOnServiceHTTPPost samlIDPSSODescriptorSingleSignOnServiceHTTPArtifact samlIDPSSODescriptorSingleLogoutServiceHTTPRedirect samlIDPSSODescriptorSingleLogoutServiceHTTPPost samlIDPSSODescriptorSingleLogoutServiceSOAP samlIDPSSODescriptorArtifactResolutionServiceArtifact samlAttributeAuthorityDescriptorAttributeServiceSOAP samlIdPResolveCookie samlMetadataForceUTF8 samlStorage samlStorageOptions samlRelayStateTimeout samlUseQueryStringSpecific samlCommonDomainCookieActivation samlCommonDomainCookieDomain samlCommonDomainCookieReader samlCommonDomainCookieWriter samlDiscoveryProtocolActivation samlDiscoveryProtocolURL samlDiscoveryProtocolPolicy samlDiscoveryProtocolIsPassive samlOverrideIDPEntityID)];
our $oidcServiceParameters = [qw(oidcServiceMetaDataIssuer oidcServiceMetaDataAuthorizeURI oidcServiceMetaDataTokenURI oidcServiceMetaDataUserInfoURI oidcServiceMetaDataJWKSURI oidcServiceMetaDataRegistrationURI oidcServiceMetaDataEndSessionURI oidcServiceMetaDataCheckSessionURI oidcServiceMetaDataFrontChannelURI oidcServiceMetaDataBackChannelURI oidcServiceMetaDataAuthnContext oidcServicePrivateKeySig oidcServicePublicKeySig oidcServiceKeyIdSig oidcServiceAllowDynamicRegistration oidcServiceAllowAuthorizationCodeFlow oidcServiceAllowImplicitFlow oidcServiceAllowHybridFlow oidcStorage oidcStorageOptions)];
1;
......@@ -53,6 +53,11 @@ sub serviceToXML {
$template->param( $_, $self->getValue( $_, $conf ) );
}
# When asked to provide only IDP metadata, take into account EntityID override
if ( $type eq "idp" and $conf->{samlOverrideIDPEntityID} ) {
$template->param( 'samlEntityID', $conf->{samlOverrideIDPEntityID} );
}
# Boolean parameters
my @param_boolean = qw(
samlSPSSODescriptorAuthnRequestsSigned
......
......@@ -783,6 +783,21 @@ qr/(?:(?:https?):\/\/(?:(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.]
'default' => '_2fDevices _loginHistory hGroups',
'type' => 'text'
},
'checkUserIdRule' => {
'default' => 1,
'test' => sub {
my ( $val, $conf ) = @_;
my $s = '';
'Safe'->new->reval("BEGIN { warnings->unimport; } $s $val");
my $err = join(
'',
grep( { $_ =~ /Undefined subroutine/ ? () : $_; }
split( /\n/, $@, 0 ) )
);
return $err ? ( 1, "__badExpression__: $err" ) : 1;
},
'type' => 'text'
},
'checkXSS' => {
'default' => 1,
'type' => 'bool'
......@@ -1199,6 +1214,21 @@ qr/^(?:\*\.)?(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.])*(?:[a-zA-Z][
'default' => '_2fDevices _loginHistory',
'type' => 'text'
},
'impersonationIdRule' => {
'default' => 1,
'test' => sub {
my ( $val, $conf ) = @_;
my $s = '';
'Safe'->new->reval("BEGIN { warnings->unimport; } $s $val");
my $err = join(
'',
grep( { $_ =~ /Undefined subroutine/ ? () : $_; }
split( /\n/, $@, 0 ) )
);
return $err ? ( 1, "__badExpression__: $err" ) : 1;
},
'type' => 'text'
},
'impersonationMergeSSOgroups' => {
'default' => 0,
'type' => 'bool'
......@@ -2885,6 +2915,10 @@ qr/(?:(?:https?):\/\/(?:(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.]
'default' => 'http://www.example.com',
'type' => 'text'
},
'samlOverrideIDPEntityID' => {
'default' => '',
'type' => 'text'
},
'samlRelayStateTimeout' => {
'default' => 600,
'type' => 'int'
......
......@@ -422,6 +422,12 @@ sub attributes {
documentation => 'Enable check user',
flags => 'p',
},
checkUserIdRule => {
type => 'text',
test => $perlExpr,
default => 1,
documentation => 'checkUser identities rule',
},
checkUserHiddenAttributes => {
type => 'text',
default => '_2fDevices _loginHistory hGroups',
......@@ -457,6 +463,12 @@ sub attributes {
default => 0,
documentation => 'Impersonation activation rule',
},
impersonationIdRule => {
type => 'text',
test => $perlExpr,
default => 1,
documentation => 'Impersonation identities rule',
},
impersonationHiddenAttributes => {
type => 'text',
default => '_2fDevices _loginHistory',
......@@ -2021,6 +2033,11 @@ sub attributes {
default => 600,
documentation => 'SAML timeout of relay state',
},
samlOverrideIDPEntityID => {
type => 'text',
documentation => 'Override SAML EntityID when acting as an IDP',
default => '',
},
samlUseQueryStringSpecific => {
default => 0,
type => 'bool',
......
......@@ -642,6 +642,7 @@ sub tree {
form => 'simpleInputContainer',
nodes => [
'checkUser',
'checkUserIdRule',
'checkUserHiddenAttributes',
'checkUserDisplayPersistentInfo',
'checkUserDisplayEmptyValues',
......@@ -653,6 +654,7 @@ sub tree {
form => 'simpleInputContainer',
nodes => [
'impersonationRule',
'impersonationIdRule',
'impersonationPrefix',
'impersonationHiddenAttributes',
'impersonationSkipEmptyValues',
......@@ -1008,7 +1010,8 @@ sub tree {
'samlDiscoveryProtocolPolicy',
'samlDiscoveryProtocolIsPassive'
]
}
},
'samlOverrideIDPEntityID',
]
}
]
......
......@@ -153,6 +153,7 @@
"checkStateSecret":"Shared secret",
"checkUsers":"SSO profile Check",
"checkUser":"Activation",
"checkUserIdRule":"Identities use rule",
"checkUserHiddenAttributes":"Hidden attributes",
"checkUserDisplayPersistentInfo":"Display persistent session",
"checkUserDisplayEmptyValues":"Display empty values",
......@@ -288,6 +289,7 @@
"https":"إتش تي تي بي س",
"impersonation":"Impersonation",
"impersonationRule":"Use rule",
"impersonationIdRule":"Identities use rule",
"impersonationHiddenAttributes":"Hidden attributes",
"impersonationMergeSSOgroups":"Merge spoofed and real SSO groups",
"impersonationPrefix":"Real attributes prefix",
......@@ -975,5 +977,6 @@
"samlCommonDomainCookieReader":"يو آر إل القارئ",
"samlCommonDomainCookieWriter":"يو آر إل الكاتب",
"samlRelayStateTimeout":"تناوب حالة مهلة الجلسة ",
"samlUseQueryStringSpecific":"استخدام أسلوب query_string المعين"
}
\ No newline at end of file
"samlUseQueryStringSpecific":"استخدام أسلوب query_string المعين",
"samlOverrideIDPEntityID": "Override Entity ID when acting as IDP"
}
......@@ -152,11 +152,12 @@
"checkState":"Activation",
"checkStateSecret":"Shared secret",
"checkUsers":"SSO profile Check",
"choiceParams":"Choice parameters",
"checkUser":"Activation",
"checkUserIdRule":"Identities use rule",
"checkUserHiddenAttributes":"Hidden attributes",
"checkUserDisplayPersistentInfo":"Display persistent session",
"checkUserDisplayEmptyValues":"Display empty values",
"choiceParams":"Choice parameters",
"chooseLogo":"Choose logo",
"chooseSkin":"Choose skin",
"combination":"Combination",
......@@ -288,6 +289,7 @@
"https":"HTTPS",
"impersonation":"Impersonation",
"impersonationRule":"Use rule",
"impersonationIdRule":"Identities use rule",
"impersonationHiddenAttributes":"Hidden attributes",
"impersonationMergeSSOgroups":"Merge spoofed and real SSO groups",
"impersonationPrefix":"Real attributes prefix",
......@@ -975,5 +977,6 @@
"samlCommonDomainCookieReader":"Reader URL",
"samlCommonDomainCookieWriter":"Writer URL",
"samlRelayStateTimeout":"RelayState session timeout",
"samlUseQueryStringSpecific":"Use specific query_string method"
}
\ No newline at end of file
"samlUseQueryStringSpecific":"Use specific query_string method",
"samlOverrideIDPEntityID": "Override Entity ID when acting as IDP"
}
......@@ -153,6 +153,7 @@
"checkStateSecret":"Shared secret",
"checkUsers":"SSO profile Check",
"checkUser":"Activation",
"checkUserIdRule":"Identities use rule",
"checkUserHiddenAttributes":"Hidden attributes",
"checkUserDisplayPersistentInfo":"Display persistent session",
"checkUserDisplayEmptyValues":"Display empty values",
......@@ -288,6 +289,7 @@
"https":"HTTPS",
"impersonation":"Impersonation",
"impersonationRule":"Use rule",
"impersonationIdRule":"Identities use rule",
"impersonationHiddenAttributes":"Hidden attributes",
"impersonationMergeSSOgroups":"Merge spoofed and real SSO groups",
"impersonationPrefix":"Real attributes prefix",
......@@ -975,5 +977,6 @@
"samlCommonDomainCookieReader":"Reader URL",
"samlCommonDomainCookieWriter":"Writer URL",
"samlRelayStateTimeout":"RelayState session timeout",
"samlUseQueryStringSpecific":"Use specific query_string method"
"samlUseQueryStringSpecific":"Use specific query_string method",
"samlOverrideIDPEntityID": "Override Entity ID when acting as IDP"
}
......@@ -153,6 +153,7 @@
"checkStateSecret":"Secret partagé",
"checkUsers":"Vérification des profils SSO",
"checkUser":"Activation",
"checkUserIdRule":"Règle d'utilisation des identités",
"checkUserHiddenAttributes":"Attributs masqués",
"checkUserDisplayPersistentInfo":"Afficher les données de session persistante",
"checkUserDisplayEmptyValues":"Afficher les valeurs nulles",
......@@ -288,6 +289,7 @@
"https":"HTTPS",
"impersonation":"Usurpation d'identité",
"impersonationRule":"Règle d'utilisation",
"impersonationIdRule":"Règle d'utilisation des identités",
"impersonationHiddenAttributes":"Attributs masqués",
"impersonationMergeSSOgroups":"Fusionner les groupes SSO réels et usurpés",
"impersonationPrefix":"Préfix des vrais attributs",
......@@ -975,5 +977,6 @@
"samlCommonDomainCookieReader":"URL de lecture",
"samlCommonDomainCookieWriter":"URL d'écriture",
"samlRelayStateTimeout":"Durée de vie d'une session RelayState",
"samlUseQueryStringSpecific":"Utilisation d'une fonction spécifique pour query_string"
"samlUseQueryStringSpecific":"Utilisation d'une fonction spécifique pour query_string",
"samlOverrideIDPEntityID": "Valeur de l'Entity ID en mode IDP"
}
......@@ -153,6 +153,7 @@
"checkStateSecret":"Segreto condiviso",
"checkUsers":"SSO profile Check",
"checkUser":"Activation",
"checkUserIdRule":"Identities use rule",
"checkUserHiddenAttributes":"Hidden attributes",
"checkUserDisplayPersistentInfo":"Display persistent session",
"checkUserDisplayEmptyValues":"Display empty values",
......@@ -288,6 +289,7 @@
"https":"HTTPS",
"impersonation":"Impersonation",
"impersonationRule":"Use rule",
"impersonationIdRule":"Identities use rule",
"impersonationHiddenAttributes":"Hidden attributes",
"impersonationMergeSSOgroups":"Merge spoofed and real SSO groups",
"impersonationPrefix":"Real attributes prefix",
......@@ -975,5 +977,6 @@
"samlCommonDomainCookieReader":"URL del lettore",
"samlCommonDomainCookieWriter":"URL dell'autore",
"samlRelayStateTimeout":"Timeout di sessione di RelayState",
"samlUseQueryStringSpecific":"Utilizza il metodo specifico query_string"
}
\ No newline at end of file
"samlUseQueryStringSpecific":"Utilizza il metodo specifico query_string",
"samlOverrideIDPEntityID": "Override Entity ID when acting as IDP"
}
......@@ -151,8 +151,9 @@
"clickHereToForce":"Nhấp vào đây để bắt buộc",
"checkState":"Kích hoạt",
"checkStateSecret":"Shared secret",
"checkUsers":"Session Check",
"checkUsers":"SSO profile Check",
"checkUser":"Activation",
"checkUserIdRule":"Identities use rule",
"checkUserHiddenAttributes":"Hidden attributes",
"checkUserDisplayPersistentInfo":"Display persistent session",
"checkUserDisplayEmptyValues":"Display empty values",
......@@ -288,6 +289,7 @@
"https":"HTTPS",
"impersonation":"Impersonation",
"impersonationRule":"Use rule",
"impersonationIdRule":"Identities use rule",
"impersonationHiddenAttributes":"Hidden attributes",
"impersonationMergeSSOgroups":"Merge spoofed and real SSO groups",
"impersonationPrefix":"Real attributes prefix",
......@@ -975,5 +977,6 @@
"samlCommonDomainCookieReader":"Trình đọc URL",
"samlCommonDomainCookieWriter":"Trình viết URL",
"samlRelayStateTimeout":"Thời gian hết hạn phiên RelayState ",
"samlUseQueryStringSpecific":"Sử dụng phương pháp query_string cụ thể"
}
\ No newline at end of file
"samlUseQueryStringSpecific":"Sử dụng phương pháp query_string cụ thể",
"samlOverrideIDPEntityID": "Override Entity ID when acting as IDP"
}
......@@ -153,6 +153,7 @@
"checkStateSecret":"Shared secret",
"checkUsers":"SSO profile Check",
"checkUser":"Activation",
"checkUserIdRule":"Identities use rule",
"checkUserHiddenAttributes":"Hidden attributes",
"checkUserDisplayPersistentInfo":"Display persistent session",
"checkUserDisplayEmptyValues":"Display empty values",
......@@ -288,6 +289,7 @@
"https":"HTTPS",
"impersonation":"Impersonation",
"impersonationRule":"Use rule",
"impersonationIdRule":"Identities use rule",
"impersonationHiddenAttributes":"Hidden attributes",
"impersonationMergeSSOgroups":"Merge spoofed and real SSO groups",
"impersonationPrefix":"Real attributes prefix",
......@@ -975,5 +977,6 @@
"samlCommonDomainCookieReader":"Reader URL",
"samlCommonDomainCookieWriter":"Writer URL",
"samlRelayStateTimeout":"RelayState session timeout",
"samlUseQueryStringSpecific":"Use specific query_string method"
}
\ No newline at end of file
"samlUseQueryStringSpecific":"Use specific query_string method",
"samlOverrideIDPEntityID": "Override Entity ID when acting as IDP"
}
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -114,6 +114,7 @@ sub extractFormInfo {
#$self->p->setHiddenFormValue( $req, kerberos => 0, '', 0 );
eval( $self->InitCmd );
die 'Unable to launch init commmand ' . $self->{InitCmd} if ($@);
$req->data->{waitingMessage} = 1;
return PE_FIRSTACCESS;
}
}
......
......@@ -893,6 +893,10 @@ sub extractFormInfo {
$self->logger->debug(
"Will try to use SAML Discovery Protocol for IDP resolution");
if ($req->urldc) {
$req->pdata->{_url} = encode_base64($req->urldc, '');
}
my $disco_url = $self->conf->{samlDiscoveryProtocolURL};
my $portal = $self->conf->{portal};
......
......@@ -51,6 +51,7 @@ sub extractFormInfo {
$req->data->{customScript} .= $self->{AjaxInitScript};
$self->logger->debug(
"Send init/script -> " . $req->data->{customScript} );
$req->data->{waitingMessage} = 1;
return PE_FIRSTACCESS;
}
else {
......
......@@ -91,6 +91,11 @@ qr/^($saml_sso_get_url|$saml_sso_get_url_ret|$saml_sso_post_url|$saml_sso_post_u
);
return 0 unless ($res);
if ( $self->conf->{samlOverrideIDPEntityID} ) {
$self->lassoServer->ProviderID(
$self->conf->{samlOverrideIDPEntityID} );
}
# Single logout routes
$self->addUnauthRouteFromMetaDataURL(
"samlIDPSSODescriptorSingleLogoutServiceSOAP",
......@@ -165,6 +170,8 @@ sub storeEnv {
$self->checkMessage( $req, $req->uri, $req->method, $req->content_type );
return PE_OK if ( $artifact or !$request );
my $login = $self->createLogin( $self->lassoServer );
$self->disableSignatureVerification($login);
$self->processAuthnRequestMsg( $login, $request );
if ( my $sp = $login->remote_providerID() ) {
$req->env->{llng_saml_sp} = $sp;
if ( my $spConfKey = $self->spList->{$sp}->{confKey} ) {
......@@ -1924,7 +1931,16 @@ sub imgnok {
sub sendImage {
my ( $self, $req,, $img ) = @_;
return $self->p->staticFile( $req, "common/$img", 'image/png' );
return [
302,
[
'Location' => $self->conf->{portal}
. $self->p->staticPrefix
. '/common/'
. $img,
],
[],
];
}
# Normalize url to be tolerant to SAML Path
......
......@@ -186,7 +186,7 @@ sub loadService {
# Create Lasso server with service metadata
my $server = $self->createServer(
$service_metadata->serviceToXML( $self->conf ),
$service_metadata->serviceToXML( $self->conf, ''),
$self->conf->{samlServicePrivateKeySig},
$self->conf->{samlServicePrivateKeySigPwd},
......@@ -2385,6 +2385,18 @@ sub samldate2timestamp {
sub sendLogoutResponseToServiceProvider {
my ( $self, $req, $logout, $method ) = @_;
my $httpmethod = $self->getFirstHttpMethod(
$self->lassoServer,
$logout->remote_providerID,
Lasso::Constants::MD_PROTOCOL_TYPE_SINGLE_LOGOUT
);
if ( $httpmethod == Lasso::Constants::HTTP_METHOD_NONE ) {
$self->logger->warn( "Provider "
. $logout->remote_providerID
. " has no SingleLogoutService in metadata, staying on portal" );
return $self->p->do( $req, [] );
}
# Logout response
unless ( $self->buildLogoutResponseMsg($logout) ) {
return $self->p->sendError( $req, "Unable to build SLO response", 500 );
......@@ -3074,7 +3086,7 @@ sub importRealSession {
sub metadata {
my ( $self, $req ) = @_;
my $type = $req->param('type');
my $type = $req->param('type') || 'all';
require Lemonldap::NG::Common::Conf::SAML::Metadata;
if ( my $metadata = Lemonldap::NG::Common::Conf::SAML::Metadata->new() ) {
my $s = $metadata->serviceToXML( $self->conf, $type );
......
......@@ -113,7 +113,7 @@ sub display {
&& $req->data->{login},
ASK_LOGINS => $req->param('checkLogins') || 0,
CONFIRMKEY => $self->stamp(),
LIST => $req->data->{list} || [],
LIST => $req->data->{list} || [],
REMEMBER => $req->data->{confirmRemember},
(
$req->data->{customScript}
......@@ -420,6 +420,10 @@ sub display {
}
if ( $req->data->{waitingMessage} ) {
$templateParams{WAITING_MESSAGE} = 1;
}
$self->logger->debug("Skin returned: $skinfile");
return ( $skinfile, \%templateParams );
}
......
......@@ -351,7 +351,7 @@ sub reloadConf {
}
};
my $portal = $self->conf->{portal};
$portal =~ s#^https?://(.*?)(?:/|$)/#$1#;
$portal =~ s#^https?://(.*?)(?:[:/].*)?$#$1#;
HANDLER->tsv->{defaultCondition}->{$portal} ||= sub { 1 };
1;
......
......@@ -25,6 +25,7 @@ has ott => (
return $ott;
}
);
has idRule => ( is => 'rw', default => sub { 1 } );
sub hAttr {
$_[0]->{conf}->{checkUserHiddenAttributes} . ' '
......@@ -33,8 +34,22 @@ sub hAttr {
sub init {
my ($self) = @_;
my $hd = $self->p->HANDLER;
$self->addAuthRoute( checkuser => 'check', ['POST'] );
$self->addAuthRoute( checkuser => 'display', ['GET'] );
# Parse identity rule
$self->logger->debug(
"checkUser identities rule -> " . $self->conf->{checkUserIdRule} );
my $rule =
$hd->buildSub( $hd->substitute( $self->conf->{checkUserIdRule} ) );
unless ($rule) {
$self->error(
"Bad checkUser identities rule -> " . $hd->tsv->{jail}->error );
return 0;
}
$self->{idRule} = $rule;
return 1;
}
......@@ -49,12 +64,12 @@ sub check {
if ( $self->conf->{requireToken} ) {
my $token = $req->param('token');
unless ($token) {
$self->userLogger->warn('CheckUser try without token');
$self->userLogger->warn('checkUser try without token');
$msg = PE_NOTOKEN;
$token = $self->ott->createToken( $req->userData );
}
unless ( $self->ott->getToken($token) ) {
$self->userLogger->warn('Checkuser try with expired/bad token');
$self->userLogger->warn('checkUser try with expired/bad token');
$msg = PE_TOKENEXPIRED;
$token = $self->ott->createToken( $req->userData );
}
......@@ -64,6 +79,7 @@ sub check {
LANGS => $self->conf->{showLanguages},
MSG => "PE$msg",
ALERTE => 'alert-warning',
LOGIN => '',
TOKEN => $token,
};
return $self->p->sendJSONresponse( $req, $params )
......@@ -91,7 +107,7 @@ sub check {
LANGS => $self->conf->{showLanguages},
MSG => 'PE' . PE_MALFORMEDUSER,
ALERTE => 'alert-warning',
LOGIN => $req->{user},
LOGIN => '',
TOKEN => (
$self->conf->{requireToken}
? $self->ott->createToken( $req->userData )
......@@ -108,7 +124,7 @@ sub check {
$attrs = $req->userData;
}
else {
$self->logger->debug("Check requested for $req->{user}");
$self->logger->debug("checkUser requested for $req->{user}");
$req->{user} = $user;
$self->userLogger->notice(
"Retrieve session from userDB and compute Groups & Macros");
......@@ -183,8 +199,8 @@ sub check {
MSG => $msg,
ALERTE => ( $msg eq 'checkUser' ? 'alert-info' : 'alert-warning' ),
LOGIN => (
$self->p->checkXSSAttack( 'LOGIN', $req->{user} ) ? ""
: $req->{user}
$self->p->checkXSSAttack( 'LOGIN', $req->{userData}->{uid} ) ? ""
: $req->{userData}->{uid}
),
URL => (
$self->p->checkXSSAttack( 'URL', $url ) ? ""
......@@ -210,19 +226,47 @@ sub check {
sub display {
my ( $self, $req ) = @_;
my ( $attrs, $array_attrs ) = ( {}, [] );
$self->userLogger->notice("Retrieve session from Sessions database");
$self->userLogger->warn("Using spoofed SSO groups if exist!!!")
if ( $self->conf->{impersonationRule} );
$attrs = $req->userData;
# Create an array of hashes for template loop
$self->logger->debug("Delete hidden or empty attributes");
if ( $self->conf->{checkUserDisplayEmptyValues} ) {
foreach my $k ( sort keys %$attrs ) {
# Ignore hidden attributes
push @$array_attrs, { key => $k, value => $attrs->{$k} }
unless ( $self->hAttr =~ /\b$k\b/ );
}
}
else {
foreach my $k ( sort keys %$attrs ) {
# Ignore hidden attributes and empty values
push @$array_attrs, { key => $k, value => $attrs->{$k} }
unless ( $self->hAttr =~ /\b$k\b/ or !$attrs->{$k} );
}
}
# ARRAY_REF = [ A_REF GROUPS, A_REF MACROS, A_REF OTHERS ]
$array_attrs = $self->_splitAttributes($array_attrs);
# Display form
my $params = {
PORTAL => $self->conf->{portal},
MAIN_LOGO => $self->conf->{portalMainLogo},
LANGS => $self->conf->{showLanguages},
MSG => 'checkUser',
ALERTE => 'alert-info',
LOGIN => (
$self->p->checkXSSAttack( 'LOGIN', $req->{user} ) ? ""
: $req->{user}
),
TOKEN => (
PORTAL => $self->conf->{portal},
MAIN_LOGO => $self->conf->{portalMainLogo},
LANGS => $self->conf->{showLanguages},
MSG => 'checkUser',
ALERTE => 'alert-info',
LOGIN => $req->{userData}->{uid},
ATTRIBUTES => $array_attrs->[2],
MACROS => $array_attrs->[1],
GROUPS => $array_attrs->[0],
TOKEN => (
$self->conf->{requireToken}
? $self->ott->createToken( $req->userData )
: ''
......@@ -244,11 +288,24 @@ sub _userDatas {
if ( my $error = $self->p->process($req) ) {
if ( $error == PE_BADCREDENTIALS ) {
$self->userLogger->warn(
'Check requested for an unvalid user (' . $req->{user} . ")" );
'checkUser requested for an unvalid user ('
. $req->{user}
. ")" );
}
$self->logger->debug("Process returned error: $error");
return $req->error($error);
}
# Check identities rule
unless ( $self->idRule->( $req, $req->sessionInfo ) ) {
$self->userLogger->warn(
'checkUser requested for an unvalid user (' . $req->{user} . ")" );
$req->{sessionInfo} = {};
$self->logger->debug('Identity not authorized');
return $req->error(PE_BADCREDENTIALS);
}
$self->logger->debug("Return \"$req->{user}\" sessionInfo");
return $req->{sessionInfo};
}
......@@ -266,6 +323,8 @@ sub _authorization {
last;
}
}
$self->logger->debug("Return \"$req->{user}\" authorization");
return $exist
? $self->p->HANDLER->grant( $req, $req->{userData}, $appuri,
undef, $vhost )
......@@ -278,6 +337,8 @@ sub _headers {
$vhost =~ s/:\d+$//;
$req->{env}->{HTTP_HOST} = $vhost;
$self->p->HANDLER->headersInit( $self->{conf} );
$self->logger->debug("Return \"$req->{user}\" headers");
return $self->p->HANDLER->checkHeaders( $req, $req->{userData} );
}
......
......@@ -13,7 +13,8 @@ extends 'Lemonldap::NG::Portal::Main::Plugin';
use constant endAuth => 'run';
has rule => ( is => 'rw', default => sub { 1 } );
has rule => ( is => 'rw', default => sub { 1 } );
has idRule => ( is => 'rw', default => sub { 1 } );
sub hAttr {