Commit 9ac5834b authored by Christophe Maudoux's avatar Christophe Maudoux

Merge branch 'v2.0'

parents 44e472f0 774a82d6
Pipeline #5620 passed with stages
in 12 minutes and 53 seconds
......@@ -24,7 +24,7 @@ use constant MANAGERSECTION => "manager";
use constant SESSIONSEXPLORERSECTION => "sessionsExplorer";
use constant APPLYSECTION => "apply";
our $hashParameters = qr/^(?:(?:l(?:o(?:ca(?:lSessionStorageOption|tionRule)|goutService)|dapExportedVar|wp(?:Ssl)?Opt)|(?:(?:d(?:emo|bi)|facebook|webID)ExportedVa|exported(?:Heade|Va)|issuerDBGetParamete)r|re(?:moteGlobalStorageOption|st2f(?:Verify|Init)Arg|loadUrl)|g(?:r(?:antSessionRule|oup)|lobalStorageOption)|n(?:otificationStorageOption|ginxCustomHandler)|macro)s|o(?:idc(?:RPMetaData(?:(?:Option(?:sExtraClaim)?|ExportedVar)s|Node)|OPMetaData(?:(?:ExportedVar|Option)s|J(?:SON|WKS)|Node)|S(?:erviceMetaDataAuthnContext|torageOptions))|penIdExportedVars)|s(?:aml(?:S(?:PMetaData(?:(?:ExportedAttribute|Option)s|Node|XML)|torageOptions)|IDPMetaData(?:(?:ExportedAttribute|Option)s|Node|XML))|essionDataToRemember|laveExportedVars)|c(?:as(?:S(?:rvMetaData(?:(?:ExportedVar|Option)s|Node)|torageOptions)|A(?:ppMetaData(?:(?:ExportedVar|Option)s|Node)|ttributes))|(?:ustomAddParam|ombModule)s)|p(?:ersistentStorageOptions|o(?:rtalSkinRules|st))|a(?:ut(?:hChoiceMod|oSigninR)ules|pplicationList)|v(?:hostOptions|irtualHost)|S(?:MTPTLSOpts|SLVarIf))$/;
our $boolKeys = qr/^(?:s(?:aml(?:IDP(?:MetaDataOptions(?:(?:Check(?:S[LS]OMessageSignatur|Audienc|Tim)|IsPassiv)e|A(?:llow(?:LoginFromIDP|ProxiedAuthn)|daptSessionUtime)|Force(?:Authn|UTF8)|StoreSAMLToken|RelayStateURL)|SSODescriptorWantAuthnRequestsSigned)|S(?:P(?:MetaDataOptions(?:(?:CheckS[LS]OMessageSignatur|OneTimeUs)e|EnableIDPInitiatedURL|ForceUTF8)|SSODescriptor(?:WantAssertion|AuthnRequest)sSigned)|erviceUseCertificateInResponse)|DiscoveryProtocol(?:Activation|IsPassive)|CommonDomainCookieActivation|UseQueryStringSpecific|MetadataForceUTF8)|ingle(?:Session(?:UserByIP)?|(?:UserBy)?IP)|oap(?:Session|Config)Server|t(?:ayConnecte|orePasswor)d|kipRenewConfirmation|howLanguages|slByAjax)|o(?:idc(?:ServiceAllow(?:(?:AuthorizationCode|Implicit|Hybrid)Flow|DynamicRegistration)|RPMetaDataOptions(?:LogoutSessionRequired|BypassConsent|RequirePKCE|Public)|OPMetaDataOptions(?:(?:CheckJWTSignatur|UseNonc)e|StoreIDToken))|ldNotifFormat)|p(?:ortal(?:ErrorOn(?:ExpiredSession|MailNotFound)|DisplayRe(?:setPassword|gister)|(?:CheckLogin|Statu)s|OpenLinkInNewWindow|RequireOldPassword|ForceAuthn|AntiFrame)|roxyUseSoap)|l(?:dap(?:(?:Group(?:DecodeSearchedValu|Recursiv)|UsePasswordResetAttribut)e|(?:AllowResetExpired|Set)Password|ChangePasswordAsUser|PpolicyControl)|oginHistoryEnabled)|c(?:a(?:ptcha_(?:register|login|mail)_enabled|sSrvMetaDataOptions(?:Gateway|Renew))|heck(?:User(?:Display(?:PersistentInfo|EmptyValues))?|State|XSS)|orsEnabled|da)|i(?:ssuerDB(?:OpenID(?:Connect)?|SAML|CAS|Get)Activation|mpersonationSkipEmptyValues)|to(?:tp2f(?:UserCan(?:Chang|Remov)eKey|DisplayExistingSecret)|kenUseGlobalStorage)|u(?:se(?:RedirectOn(?:Forbidden|Error)|SafeJail)|2fUserCanRemoveKey|pgradeSession)|no(?:tif(?:ication(?:Server)?|y(?:Deleted|Other))|AjaxHook)|(?:mai(?:lOnPasswordChang|ntenanc)|vhostMaintenanc)e|rest(?:(?:Session|Config)Server|ExportSecretKeys)|h(?:ideOldPassword|ttpOnly)|yubikey2fUserCanRemoveKey|(?:activeTim|wsdlServ)er|krb(?:RemoveDomain|ByJs)|dbiDynamicHashEnabled|bruteForceProtection)$/;
our $boolKeys = qr/^(?:s(?:aml(?:IDP(?:MetaDataOptions(?:(?:Check(?:S[LS]OMessageSignatur|Audienc|Tim)|IsPassiv)e|A(?:llow(?:LoginFromIDP|ProxiedAuthn)|daptSessionUtime)|Force(?:Authn|UTF8)|StoreSAMLToken|RelayStateURL)|SSODescriptorWantAuthnRequestsSigned)|S(?:P(?:MetaDataOptions(?:(?:CheckS[LS]OMessageSignatur|OneTimeUs)e|EnableIDPInitiatedURL|ForceUTF8)|SSODescriptor(?:WantAssertion|AuthnRequest)sSigned)|erviceUseCertificateInResponse)|DiscoveryProtocol(?:Activation|IsPassive)|CommonDomainCookieActivation|UseQueryStringSpecific|MetadataForceUTF8)|ingle(?:Session(?:UserByIP)?|(?:UserBy)?IP)|oap(?:Session|Config)Server|t(?:ayConnecte|orePasswor)d|kipRenewConfirmation|fRemovedUseNotif|howLanguages|slByAjax)|o(?:idc(?:ServiceAllow(?:(?:AuthorizationCode|Implicit|Hybrid)Flow|DynamicRegistration)|RPMetaDataOptions(?:LogoutSessionRequired|BypassConsent|RequirePKCE|Public)|OPMetaDataOptions(?:(?:CheckJWTSignatur|UseNonc)e|StoreIDToken))|ldNotifFormat)|p(?:ortal(?:ErrorOn(?:ExpiredSession|MailNotFound)|DisplayRe(?:setPassword|gister)|(?:CheckLogin|Statu)s|OpenLinkInNewWindow|RequireOldPassword|ForceAuthn|AntiFrame)|roxyUseSoap)|l(?:dap(?:(?:Group(?:DecodeSearchedValu|Recursiv)|UsePasswordResetAttribut)e|(?:AllowResetExpired|Set)Password|ChangePasswordAsUser|PpolicyControl)|oginHistoryEnabled)|c(?:a(?:ptcha_(?:register|login|mail)_enabled|sSrvMetaDataOptions(?:Gateway|Renew))|heck(?:User(?:Display(?:PersistentInfo|EmptyValues))?|State|XSS)|orsEnabled|da)|i(?:ssuerDB(?:OpenID(?:Connect)?|SAML|CAS|Get)Activation|mpersonationSkipEmptyValues)|to(?:tp2f(?:UserCan(?:Chang|Remov)eKey|DisplayExistingSecret)|kenUseGlobalStorage)|u(?:se(?:RedirectOn(?:Forbidden|Error)|SafeJail)|2fUserCanRemoveKey|pgradeSession)|no(?:tif(?:ication(?:Server)?|y(?:Deleted|Other))|AjaxHook)|(?:mai(?:lOnPasswordChang|ntenanc)|vhostMaintenanc)e|rest(?:(?:Session|Config)Server|ExportSecretKeys)|h(?:ideOldPassword|ttpOnly)|yubikey2fUserCanRemoveKey|(?:activeTim|wsdlServ)er|krb(?:RemoveDomain|ByJs)|dbiDynamicHashEnabled|bruteForceProtection)$/;
our @sessionTypes = ( 'remoteGlobal', 'global', 'localSession', 'persistent', 'saml', 'oidc', 'cas' );
......
......@@ -28,7 +28,7 @@ sub defaultValues {
'casAccessControlPolicy' => 'none',
'casAuthnLevel' => 1,
'checkTime' => 600,
'checkUserHiddenAttributes' => '_2fDevices _loginHistory hGroups',
'checkUserHiddenAttributes' => '_loginHistory hGroups',
'checkUserIdRule' => 1,
'checkXSS' => 1,
'confirmFormMethod' => 'post',
......@@ -78,7 +78,7 @@ sub defaultValues {
'groups' => {},
'handlerInternalCache' => 15,
'handlerServiceTokenTTL' => 30,
'hiddenAttributes' => '_password',
'hiddenAttributes' => '_password _2fDevices',
'httpOnly' => 1,
'https' => -1,
'impersonationHiddenAttributes' => '_2fDevices _loginHistory',
......@@ -279,43 +279,47 @@ sub defaultValues {
'samlSPSSODescriptorWantAssertionsSigned' => 1,
'securedCookie' => 0,
'sfEngine' => '::2F::Engines::Default',
'sfRemovedMsg' => 0,
'sfRequired' => 0,
'showLanguages' => 1,
'slaveAuthnLevel' => 2,
'slaveExportedVars' => {},
'SMTPServer' => '',
'SMTPTLS' => '',
'SSLAuthnLevel' => 5,
'SSLVar' => 'SSL_CLIENT_S_DN_Email',
'SSLVarIf' => {},
'successLoginNumber' => 5,
'timeout' => 72000,
'timeoutActivity' => 0,
'timeoutActivityInterval' => 60,
'totp2fActivation' => 0,
'totp2fDigits' => 6,
'totp2fInterval' => 30,
'totp2fRange' => 1,
'totp2fSelfRegistration' => 0,
'totp2fUserCanRemoveKey' => 1,
'twitterAuthnLevel' => 1,
'twitterUserField' => 'screen_name',
'u2fActivation' => 0,
'u2fSelfRegistration' => 0,
'u2fUserCanRemoveKey' => 1,
'upgradeSession' => 1,
'userControl' => '^[\\w\\.\\-@]+$',
'userDB' => 'Same',
'useRedirectOnError' => 1,
'useSafeJail' => 1,
'utotp2fActivation' => 0,
'viewerHiddenKeys' => 'samlIDPMetaDataNodes samlSPMetaDataNodes',
'webIDAuthnLevel' => 1,
'webIDExportedVars' => {},
'whatToTrace' => 'uid',
'yubikey2fActivation' => 0,
'yubikey2fPublicIDSize' => 12,
'sfRemovedMsgRule' => 0,
'sfRemovedNotifMsg' =>
'_removedSF_ expired second factor(s) has/have been removed!',
'sfRemovedNotifRef' => 'RemoveSF',
'sfRemovedNotifTitle' => 'Second factor notification',
'sfRequired' => 0,
'showLanguages' => 1,
'slaveAuthnLevel' => 2,
'slaveExportedVars' => {},
'SMTPServer' => '',
'SMTPTLS' => '',
'SSLAuthnLevel' => 5,
'SSLVar' => 'SSL_CLIENT_S_DN_Email',
'SSLVarIf' => {},
'successLoginNumber' => 5,
'timeout' => 72000,
'timeoutActivity' => 0,
'timeoutActivityInterval' => 60,
'totp2fActivation' => 0,
'totp2fDigits' => 6,
'totp2fInterval' => 30,
'totp2fRange' => 1,
'totp2fSelfRegistration' => 0,
'totp2fUserCanRemoveKey' => 1,
'twitterAuthnLevel' => 1,
'twitterUserField' => 'screen_name',
'u2fActivation' => 0,
'u2fSelfRegistration' => 0,
'u2fUserCanRemoveKey' => 1,
'upgradeSession' => 1,
'userControl' => '^[\\w\\.\\-@]+$',
'userDB' => 'Same',
'useRedirectOnError' => 1,
'useSafeJail' => 1,
'utotp2fActivation' => 0,
'viewerHiddenKeys' => 'samlIDPMetaDataNodes samlSPMetaDataNodes',
'webIDAuthnLevel' => 1,
'webIDExportedVars' => {},
'whatToTrace' => 'uid',
'yubikey2fActivation' => 0,
'yubikey2fPublicIDSize' => 12,
'yubikey2fSelfRegistration' => 0,
'yubikey2fUserCanRemoveKey' => 1
};
......
......@@ -786,7 +786,7 @@ qr/(?:(?:https?):\/\/(?:(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.]
'type' => 'bool'
},
'checkUserHiddenAttributes' => {
'default' => '_2fDevices _loginHistory hGroups',
'default' => '_loginHistory hGroups',
'type' => 'text'
},
'checkUserIdRule' => {
......@@ -1216,7 +1216,7 @@ qr/^(?:\*\.)?(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.])*(?:[a-zA-Z][
'type' => 'int'
},
'hiddenAttributes' => {
'default' => '_password',
'default' => '_password _2fDevices',
'type' => 'text'
},
'hideOldPassword' => {
......@@ -3197,10 +3197,27 @@ qr/(?:(?:https?):\/\/(?:(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.]
'default' => '::2F::Engines::Default',
'type' => 'text'
},
'sfRemovedMsg' => {
'sfRemovedMsgRule' => {
'default' => 0,
'type' => 'boolOrExpr'
},
'sfRemovedNotifMsg' => {
'default' =>
'_removedSF_ expired second factor(s) has/have been removed!',
'type' => 'text'
},
'sfRemovedNotifRef' => {
'default' => 'RemoveSF',
'type' => 'text'
},
'sfRemovedNotifTitle' => {
'default' => 'Second factor notification',
'type' => 'text'
},
'sfRemovedUseNotif' => {
'default' => 0,
'type' => 'bool'
},
'sfRequired' => {
'default' => 0,
'type' => 'boolOrExpr'
......
......@@ -435,7 +435,7 @@ sub attributes {
},
checkUserHiddenAttributes => {
type => 'text',
default => '_2fDevices _loginHistory hGroups',
default => '_loginHistory hGroups',
documentation => 'Attributes to hide in CheckUser plugin',
flags => 'p',
},
......@@ -716,7 +716,7 @@ sub attributes {
},
hiddenAttributes => {
type => 'text',
default => '_password',
default => '_password _2fDevices',
documentation => 'Name of attributes to hide in logs',
},
key => {
......@@ -2587,11 +2587,36 @@ sub attributes {
help => 'secondfactor.html',
documentation => 'Second factor required',
},
sfRemovedMsg => {
type => 'boolOrExpr',
sfRemovedMsgRule => {
type => 'boolOrExpr',
default => 0,
help => 'secondfactor.html',
documentation =>
'Display a message if at leat one expired SF has been removed',
},
sfRemovedUseNotif => {
default => 0,
type => 'bool',
documentation => 'Use Notifications plugin to display message',
},
sfRemovedNotifRef => {
type => 'text',
default => 'RemoveSF',
help => 'secondfactor.html',
documentation => 'Display a message if at leat one expired SF has been removed',
documentation => 'Notification reference',
},
sfRemovedNotifTitle => {
type => 'text',
default => 'Second factor notification',
help => 'secondfactor.html',
documentation => 'Notification title',
},
sfRemovedNotifMsg => {
type => 'text',
default =>
'_removedSF_ expired second factor(s) has/have been removed!',
help => 'secondfactor.html',
documentation => 'Notification message',
},
available2F => {
type => 'text',
......@@ -2692,7 +2717,6 @@ m{^(?:ldapi://[^/]*/?|\w[\w\-\.]*(?::\d{1,5})?|ldap(?:s|\+tls)?://\w[\w\-\.]*(?:
documentation => 'LDAP password encoding',
},
ldapUsePasswordResetAttribute => {
default => 0,
type => 'bool',
default => 1,
documentation => 'LDAP store reset flag in an attribute',
......
......@@ -763,7 +763,17 @@ sub tree {
'yubikey2fTTL',
],
},
'sfRequired', 'sfRemovedMsg',
{
title => 'sfRemovedNotification',
help => 'secondfactor.html',
form => 'simpleInputContainer',
nodes => [
'sfRemovedMsgRule', 'sfRemovedUseNotif',
'sfRemovedNotifRef', 'sfRemovedNotifTitle',
'sfRemovedNotifMsg',
],
},
'sfRequired',
]
},
{
......
......@@ -734,6 +734,12 @@
"sessionTitle":"محتوى الجلسة",
"sfaTitle":"Second Factors Authentication",
"sfRequired":"Require 2FA",
"sfRemovedNotification":"Display a message if an expired SF is removed",
"sfRemovedMsgRule":"تفعيل",
"sfRemovedUseNotif":"Use Notifications plugin",
"sfRemovedNotifMsg":"Notification message",
"sfRemovedNotifRef":"Notification reference",
"sfRemovedNotifTitle":"Notification title",
"sfRemovedMsg":"Display a message if an expired SF is removed",
"show":"عرض",
"showHelp":"عرض المساعدة",
......
......@@ -733,6 +733,12 @@
"sessionTitle":"Session content",
"sfaTitle":"Second Factors Authentication",
"sfRequired":"Require 2FA",
"sfRemovedNotification":"Display a message if an expired SF is removed",
"sfRemovedMsgRule":"Activation",
"sfRemovedUseNotif":"Use Notifications plugin",
"sfRemovedNotifMsg":"Notification message",
"sfRemovedNotifRef":"Notification reference",
"sfRemovedNotifTitle":"Notification title",
"sfRemovedMsg":"Display a message if an expired SF is removed",
"show":"Show",
"showHelp":"Show help",
......
......@@ -733,6 +733,12 @@
"sessionTitle":"Session content",
"sfaTitle":"Second Factors Authentication",
"sfRequired":"Require 2FA",
"sfRemovedNotification":"Display a message if an expired SF is removed",
"sfRemovedMsgRule":"Activation",
"sfRemovedUseNotif":"Use Notifications plugin",
"sfRemovedNotifMsg":"Notification message",
"sfRemovedNotifRef":"Notification reference",
"sfRemovedNotifTitle":"Notification title",
"sfRemovedMsg":"Display a message if an expired SF is removed",
"show":"Show",
"showHelp":"Show help",
......
......@@ -733,6 +733,12 @@
"sessionTitle":"Contenu de la session",
"sfaTitle":"Seconds Facteurs d'Authentification",
"sfRequired":"Exiger 2FA",
"sfRemovedNotification":"Afficher un message si un SF expiré a été supprimé",
"sfRemovedMsgRule":"Activation",
"sfRemovedUseNotif":"Utiliser les notifications",
"sfRemovedNotifMsg":"Message de la notification",
"sfRemovedNotifRef":"Référence de la notification",
"sfRemovedNotifTitle":"Titre de la notification",
"sfRemovedMsg":"Afficher un message si un SF expiré est supprimé",
"show":"Montrer",
"showHelp":"Montrer l'aide",
......
......@@ -733,6 +733,12 @@
"sessionTitle":"Contenuto della sessione",
"sfaTitle":"Autenticazione a due fattori",
"sfRequired":"Richiedi 2FA",
"sfRemovedNotification":"Display a message if an expired SF is removed",
"sfRemovedMsgRule":"Attivazione",
"sfRemovedUseNotif":"Use Notifications plugin",
"sfRemovedNotifMsg":"Notification message",
"sfRemovedNotifRef":"Notification reference",
"sfRemovedNotifTitle":"Notification title",
"sfRemovedMsg":"Display a message if an expired SF is removed",
"show":"Mostra",
"showHelp":"Mostra aiuto",
......
......@@ -148,7 +148,7 @@
"cspConnect":"Đích cúa Ajax",
"cspFont":"Nguồn phông chữ",
"crossOrigineResourceSharing":"Cross-Origin Resource Sharing",
"corsEnabled":"Activation",
"corsEnabled":"Kích hoạt",
"corsAllow_Credentials":"Access-Control-Allow-Credentials",
"corsAllow_Headers":"Access-Control-Allow-Headers",
"corsAllow_Methods":"Access-Control-Allow-Methods",
......@@ -733,6 +733,12 @@
"sessionTitle":"Nội dung phiên",
"sfaTitle":"Second Factors Authentication",
"sfRequired":"Require 2FA",
"sfRemovedNotification":"Display a message if an expired SF is removed",
"sfRemovedMsgRule":"Kích hoạt",
"sfRemovedUseNotif":"Use Notifications plugin",
"sfRemovedNotifMsg":"Notification message",
"sfRemovedNotifRef":"Notification reference",
"sfRemovedNotifTitle":"Notification title",
"sfRemovedMsg":"Display a message if an expired SF is removed",
"show":"Hiển thị",
"showHelp":"Hiển thị trợ giúp",
......
......@@ -733,6 +733,12 @@
"sessionTitle":"Session content",
"sfaTitle":"Second Factors Authentication",
"sfRequired":"Require 2FA",
"sfRemovedNotification":"Display a message if an expired SF is removed",
"sfRemovedMsgRule":"Activation",
"sfRemovedUseNotif":"Use Notifications plugin",
"sfRemovedNotifMsg":"Notification message",
"sfRemovedNotifRef":"Notification reference",
"sfRemovedNotifTitle":"Notification title",
"sfRemovedMsg":"Display a message if an expired SF is removed",
"show":"Show",
"showHelp":"Show help",
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -12,6 +12,7 @@ package Lemonldap::NG::Portal::2F::Engines::Default;
use strict;
use Mouse;
use JSON qw(from_json to_json);
use POSIX qw(strftime);
use Lemonldap::NG::Portal::Main::Constants qw(
PE_ERROR
PE_NOTOKEN
......@@ -30,7 +31,7 @@ extends 'Lemonldap::NG::Portal::Main::Plugin';
has sfModules => ( is => 'rw', default => sub { [] } );
has sfRModules => ( is => 'rw', default => sub { [] } );
has sfReq => ( is => 'rw' );
has sfMsg => ( is => 'rw' );
has sfRule => ( is => 'rw' );
has ott => (
is => 'rw',
......@@ -107,9 +108,11 @@ sub init {
}
unless (
$self->sfMsg(
$self->sfRule(
$self->p->HANDLER->buildSub(
$self->p->HANDLER->substitute( $self->conf->{sfRemovedMsg} )
$self->p->HANDLER->substitute(
$self->conf->{sfRemovedMsgRule}
)
)
)
)
......@@ -199,23 +202,20 @@ sub run {
$self->p->updatePersistentSession( $req,
{ _2fDevices => to_json($_2fDevices) } );
# Display message if required
if ( $self->sfMsg->( $req, $req->sessionInfo ) ) {
$req->info(
$self->loadTemplate(
'simpleInfo',
(
$removed > 1
? (
params => {
trspan => "expired2Fremoved, $removed"
}
)
: ( params => { trspan => "oneExpired2Fremoved" } )
)
)
);
return PE_INFO;
# Display notification or message if required
my $res = 0;
if ( $self->sfRule->( $req, $req->sessionInfo ) ) {
my $notifEngine = $self->p->loadedModules->{
'Lemonldap::NG::Portal::Plugins::Notifications'};
if ( $notifEngine && $self->conf->{sfRemovedUseNotif} ) {
$self->logger->debug("Notifications plugin enabled");
$res =
$self->_sendNotification( $req, $notifEngine, $removed );
}
else {
$res = $self->_sendInfo( $req, $removed );
}
return $res if $res;
}
}
}
......@@ -494,4 +494,57 @@ sub restoreSession {
: $self->_displayRegister( $req, @path );
}
sub _sendInfo {
my ( $self, $req, $removed ) = @_;
$self->logger->debug("Return simpleInfo template");
$req->info(
$self->loadTemplate(
'simpleInfo',
(
$removed > 1
? (
params => {
trspan => "expired2Fremoved, $removed"
}
)
: ( params => { trspan => "oneExpired2Fremoved" } )
)
)
);
return PE_INFO;
}
sub _sendNotification {
my ( $self, $req, $notifEngine, $removed ) = @_;
my $uid = $req->user;
my $date = strftime "%Y-%m-%d", localtime;
my $ref = $self->conf->{sfRemovedNotifRef} || 'RemoveSF';
my $title =
$self->conf->{sfRemovedNotifTitle} || 'Second factor notification';
my $msg = $self->conf->{sfRemovedNotifMsg}
|| "$removed expired second factor(s) has/have been removed!";
$msg =~ s/_removedSF_/$removed/;
# Prepare notification
my $content =
$self->conf->{oldNotifFormat}
? '<?xml version="1.0" encoding="UTF-8"?><root><notification uid="_uid_" date="_date_" reference="_ref_"><title>_title_</title><text>_msg_</text></notification></root>'
: '[{"uid":"_uid_","date":"_date_","title":"_title_","reference":"_ref_","text":"_msg_"}]';
$content =~ s/_uid_/$uid/;
$content =~ s/_ref_/$ref/;
$content =~ s/_date_/$date/;
$content =~ s/_title_/$title/;
$content =~ s/_msg_/$msg/;
if ( $notifEngine->module->notifObject->newNotification($content) ) {
$self->logger->debug("Notification SF successfully appended");
$self->userLogger->notice("Notification SF successfully appended");
return PE_OK;
}
else {
$self->logger->debug("Notification NOT created!");
return $self->_sendInfo( $req, $removed );
}
}
1;
......@@ -42,7 +42,8 @@ sub authenticate {
# Set the dn unless done before
unless ( $req->data->{dn} ) {
if ( my $tmp = $self->getUser($req) ) {
$self->setSecurity($req);
eval { $self->setSecurity($req) };
$self->logger->warn($@) if ($@);
return $tmp;
}
}
......
......@@ -3,6 +3,8 @@ package Lemonldap::NG::Portal::Lib::LDAP;
use strict;
use Mouse;
use Lemonldap::NG::Portal::Lib::Net::LDAP;
use Lemonldap::NG::Portal::Main::Constants
qw(PE_OK PE_LDAPCONNECTFAILED PE_LDAPERROR PE_BADCREDENTIALS);
extends 'Lemonldap::NG::Common::Module';
......@@ -16,6 +18,17 @@ has ldap => (
builder => 'newLdap',
);
has attrs => (
is => 'rw',
lazy => 1,
builder => sub {
return [
values %{ $_[0]->{conf}->{exportedVars} },
values %{ $_[0]->{conf}->{ldapExportedVars} }
];
}
);
sub newLdap {
my $self = $_[0];
my $ldap;
......@@ -98,6 +111,38 @@ sub init {
# RUNNING METHODS
sub getUser {
my ( $self, $req, %args ) = @_;
return PE_LDAPCONNECTFAILED unless $self->ldap and $self->bind();
my $mesg = $self->ldap->search(
base => $self->conf->{ldapBase},
scope => 'sub',
filter => (
$args{useMail}
? $self->mailFilter->($req)
: $self->filter->($req)
),
defer => $self->conf->{ldapSearchDeref} || 'find',
attrs => $self->attrs,
);
if ( $mesg->code() != 0 ) {
$self->logger->error( 'LDAP Search error: ' . $mesg->error );
return PE_LDAPERROR;
}
if ( $mesg->count() > 1 ) {
$self->logger->error('More than one entry returned by LDAP directory');
eval { $self->p->_authentication->setSecurity($req) };
return PE_BADCREDENTIALS;
}
unless ( $req->data->{entry} = $mesg->entry(0) ) {
$self->userLogger->warn("$req->{user} was not found in LDAP directory");
eval { $self->p->_authentication->setSecurity($req) };
return PE_BADCREDENTIALS;
}
$req->data->{dn} = $req->data->{entry}->dn();
PE_OK;
}
# Test LDAP connection before trying to bind
sub bind {
my $self = shift;
......
......@@ -3,8 +3,7 @@ package Lemonldap::NG::Portal::UserDB::LDAP;
use strict;
use Mouse;
use utf8;
use Lemonldap::NG::Portal::Main::Constants
qw(PE_OK PE_LDAPCONNECTFAILED PE_LDAPERROR PE_BADCREDENTIALS);
use Lemonldap::NG::Portal::Main::Constants qw(PE_OK);
extends 'Lemonldap::NG::Portal::Lib::LDAP';
......@@ -25,50 +24,9 @@ has ldapGroupAttributeNameSearch => (
}
);
has attrs => (
is => 'rw',
lazy => 1,
builder => sub {
return [
values %{ $_[0]->{conf}->{exportedVars} },
values %{ $_[0]->{conf}->{ldapExportedVars} }
];
}
);
# RUNNING METHODS
sub getUser {
my ( $self, $req, %args ) = @_;
return PE_LDAPCONNECTFAILED unless $self->ldap and $self->bind();
my $mesg = $self->ldap->search(
base => $self->conf->{ldapBase},
scope => 'sub',
filter => (
$args{useMail}
? $self->mailFilter->($req)
: $self->filter->($req)
),
defer => $self->conf->{ldapSearchDeref} || 'find',
attrs => $self->attrs,
);
if ( $mesg->code() != 0 ) {
$self->logger->error( 'LDAP Search error: ' . $mesg->error );
return PE_LDAPERROR;
}
if ( $mesg->count() > 1 ) {
$self->logger->error('More than one entry returned by LDAP directory');
eval { $self->p->_authentication->setSecurity($req) };
return PE_BADCREDENTIALS;
}
unless ( $req->data->{entry} = $mesg->entry(0) ) {
$self->userLogger->warn("$req->{user} was not found in LDAP directory");
eval { $self->p->_authentication->setSecurity($req) };
return PE_BADCREDENTIALS;
}
$req->data->{dn} = $req->data->{entry}->dn();
PE_OK;
}
#
# getUser is provided by Portal::Lib::LDAP
# Load all parameters included in exportedVars parameter.
# Multi-value parameters are loaded in a single string with
......
......@@ -162,4 +162,4 @@ div.oidc_consent_message > ul {
.progress-bar-animated {
width: 100%;
}
\ No newline at end of file
}
<TMPL_INCLUDE NAME="header.tpl">
<div id="errorcontent" class="container">
<!--
<div class="message message-positive alert"><span trspan="<TMPL_VAR NAME="MSG">"></span></div>
<!--
<div class="message message-positive alert"><span trspan="<TMPL_VAR NAME="MSG">"></span></div>
-->
<div class="alert <TMPL_VAR NAME="ALERTE"> alert"><span trspan="<TMPL_VAR NAME="MSG">"></span></div>
<form id="checkuser" action="/checkuser" method="post" class="password" role="form">
<div class="buttons">
<TMPL_IF NAME="TOKEN">
<input type="hidden" name="token" value="<TMPL_VAR NAME="TOKEN">" />
</TMPL_IF>
<div class="alert <TMPL_VAR NAME="ALERTE"> alert"><div class="text-center"><span trspan="<TMPL_VAR NAME="MSG">"></span></div></div>
<form id="checkuser" action="/checkuser" method="post" class="password" role="form">
<div class="buttons">
<TMPL_IF NAME="TOKEN">
<input type="hidden" name="token" value="<TMPL_VAR NAME="TOKEN">" />
</TMPL_IF>
<div class="input-group mb-3">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-user"></i> </span>
</div>
<input name="user" type="text" class="form-control" value="<TMPL_VAR NAME="LOGIN">" trplaceholder="user" aria-required="true"/>
</div>
<div class="input-group mb-3">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-link"></i> </span>
</div>
<input name="url" type="text" class="form-control" value="<TMPL_VAR NAME="URL">" trplaceholder="URL / DNS" aria-required="true"/>
</div>
<button type="submit" class="btn btn-success">
<span class="fa fa-search"></span>
<span trspan="search">Search</span>
</button>
</div>
</form>
<div>
<TMPL_IF NAME="ALLOWED">
<div class="alert <TMPL_VAR NAME="ALERTE_AUTH">"><div class="text-center"><b><span trspan="<TMPL_VAR NAME="ALLOWED">"></span></b></div></div>
</TMPL_IF>
<div class="input-group mb-3">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-user"></i> </span>
<TMPL_IF NAME="HEADERS">
<div class="row">
<div class="card col border-secondary">
<div class="text-center bg-light text-dark"><b><span trspan="headers">HEADERS</span></b></div>
<div class="font-weight-bold">
<TMPL_LOOP NAME="HEADERS">
<TMPL_VAR NAME="key">: <TMPL_VAR NAME="value"><br/>