WIP: FindUser skeleton (#1976)
This commit is contained in:
parent
48df4a8807
commit
4d04672c20
|
@ -29,8 +29,8 @@ use constant DEFAULTCONFBACKEND => "File";
|
|||
use constant DEFAULTCONFBACKENDOPTIONS => (
|
||||
dirName => '/usr/local/lemonldap-ng/data/conf',
|
||||
);
|
||||
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(?:S(?:ervice(?:DynamicRegistrationEx(?:portedVar|traClaim)s|MetaDataAuthnContext)|torageOptions)|RPMetaData(?:(?:Option(?:sExtraClaim)?|ExportedVar|Macro)s|Node)|OPMetaData(?:(?:ExportedVar|Option)s|J(?:SON|WKS)|Node))|penIdExportedVars)|c(?:as(?:A(?:ppMetaData(?:(?:ExportedVar|Option|Macro)s|Node)|ttributes)|S(?:rvMetaData(?:(?:ExportedVar|Option)s|Node)|torageOptions))|(?:ustom(?:Plugins|Add)Param|heckUserHiddenHeader|ombModule)s)|s(?:aml(?:S(?:PMetaData(?:(?:ExportedAttribute|Option|Macro)s|Node|XML)|torageOptions)|IDPMetaData(?:(?:ExportedAttribute|Option)s|Node|XML))|essionDataToRemember|laveExportedVars|fExtra)|a(?:(?:daptativeAuthenticationLevelR|ut(?:hChoiceMod|oSigninR))ules|pplicationList)|p(?:ersistentStorageOptions|o(?:rtalSkinRules|st))|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)|f(?:RemovedUseNotif|OnlyUpgrade)|kip(?:Upgrade|Renew)Confirmation|oap(?:Session|Config)Server|t(?:ayConnecte|orePasswor)d|laveDisplayLogo|howLanguages|slByAjax)|o(?:idc(?:RPMetaDataOptions(?:Allow(?:PasswordGrant|Offline)|Re(?:freshToken|quirePKCE)|LogoutSessionRequired|IDTokenForceClaims|BypassConsent|Public)|ServiceAllow(?:(?:AuthorizationCode|Implicit|Hybrid)Flow|DynamicRegistration)|OPMetaDataOptions(?:(?:CheckJWTSignatur|UseNonc)e|StoreIDToken))|ldNotifFormat)|p(?:ortal(?:Display(?:Re(?:freshMyRights|setPassword|gister)|CertificateResetByMail|GeneratePassword|PasswordPolicy)|ErrorOn(?:ExpiredSession|MailNotFound)|(?:CheckLogin|Statu)s|OpenLinkInNewWindow|ForceAuthn|AntiFrame)|roxyUseSoap)|c(?:o(?:ntextSwitching(?:Allowed2fModifications|StopWithLogout)|mpactConf|rsEnabled)|a(?:ptcha_(?:register|login|mail)_enabled|sSrvMetaDataOptions(?:Gateway|Renew))|heck(?:State|User|XSS)|da)|l(?:dap(?:(?:Group(?:DecodeSearchedValu|Recursiv)|UsePasswordResetAttribut)e|(?:AllowResetExpired|Set)Password|ChangePasswordAsUser|PpolicyControl|ITDS)|oginHistoryEnabled)|no(?:tif(?:ication(?:Server(?:(?:POS|GE)T|DELETE)?|sExplorer)?|y(?:Deleted|Other))|AjaxHook)|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)|re(?:st(?:(?:Password|Session|Config|Auth)Server|ExportSecretKeys)|freshSessions)|br(?:uteForceProtection(?:IncrementalTempo)?|owsersDontStorePassword)|d(?:is(?:ablePersistentStorage|playSessionId)|biDynamicHashEnabled)|(?:mai(?:lOnPasswordChang|ntenanc)|vhostMaintenanc)e|g(?:roupsBeforeMacros|lobalLogoutTimer)|a(?:voidAssignment|ctiveTimer)|h(?:ideOldPassword|ttpOnly)|yubikey2fUserCanRemoveKey|krb(?:RemoveDomain|ByJs)|wsdlServer)$/;
|
||||
our $hashParameters = qr/^(?:(?:l(?:o(?:ca(?:lSessionStorageOption|tionRule)|goutService)|dapExportedVar|wp(?:Ssl)?Opt)|(?:(?:d(?:emo|bi)|webID)ExportedVa|exported(?:Heade|Va)|issuerDBGetParamete)r|f(?:indUser(?:Exclud|Search)ingAttribute|acebookExportedVar)|re(?:moteGlobalStorageOption|st2f(?:Verify|Init)Arg|loadUrl)|g(?:r(?:antSessionRule|oup)|lobalStorageOption)|n(?:otificationStorageOption|ginxCustomHandler)|macro)s|o(?:idc(?:S(?:ervice(?:DynamicRegistrationEx(?:portedVar|traClaim)s|MetaDataAuthnContext)|torageOptions)|RPMetaData(?:(?:Option(?:sExtraClaim)?|ExportedVar|Macro)s|Node)|OPMetaData(?:(?:ExportedVar|Option)s|J(?:SON|WKS)|Node))|penIdExportedVars)|c(?:as(?:A(?:ppMetaData(?:(?:ExportedVar|Option|Macro)s|Node)|ttributes)|S(?:rvMetaData(?:(?:ExportedVar|Option)s|Node)|torageOptions))|(?:ustom(?:Plugins|Add)Param|heckUserHiddenHeader|ombModule)s)|s(?:aml(?:S(?:PMetaData(?:(?:ExportedAttribute|Option|Macro)s|Node|XML)|torageOptions)|IDPMetaData(?:(?:ExportedAttribute|Option)s|Node|XML))|essionDataToRemember|laveExportedVars|fExtra)|a(?:(?:daptativeAuthenticationLevelR|ut(?:hChoiceMod|oSigninR))ules|pplicationList)|p(?:ersistentStorageOptions|o(?:rtalSkinRules|st))|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)|f(?:RemovedUseNotif|OnlyUpgrade)|kip(?:Upgrade|Renew)Confirmation|oap(?:Session|Config)Server|t(?:ayConnecte|orePasswor)d|laveDisplayLogo|howLanguages|slByAjax)|o(?:idc(?:RPMetaDataOptions(?:Allow(?:PasswordGrant|Offline)|Re(?:freshToken|quirePKCE)|LogoutSessionRequired|IDTokenForceClaims|BypassConsent|Public)|ServiceAllow(?:(?:AuthorizationCode|Implicit|Hybrid)Flow|DynamicRegistration)|OPMetaDataOptions(?:(?:CheckJWTSignatur|UseNonc)e|StoreIDToken))|ldNotifFormat)|p(?:ortal(?:Display(?:Re(?:freshMyRights|setPassword|gister)|CertificateResetByMail|GeneratePassword|PasswordPolicy)|ErrorOn(?:ExpiredSession|MailNotFound)|(?:CheckLogin|Statu)s|OpenLinkInNewWindow|ForceAuthn|AntiFrame)|roxyUseSoap)|c(?:o(?:ntextSwitching(?:Allowed2fModifications|StopWithLogout)|mpactConf|rsEnabled)|a(?:ptcha_(?:register|login|mail)_enabled|sSrvMetaDataOptions(?:Gateway|Renew))|heck(?:State|User|XSS)|da)|l(?:dap(?:(?:Group(?:DecodeSearchedValu|Recursiv)|UsePasswordResetAttribut)e|(?:AllowResetExpired|Set)Password|ChangePasswordAsUser|PpolicyControl|ITDS)|oginHistoryEnabled)|no(?:tif(?:ication(?:Server(?:(?:POS|GE)T|DELETE)?|sExplorer)?|y(?:Deleted|Other))|AjaxHook)|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)|re(?:st(?:(?:Password|Session|Config|Auth)Server|ExportSecretKeys)|freshSessions)|br(?:uteForceProtection(?:IncrementalTempo)?|owsersDontStorePassword)|d(?:is(?:ablePersistentStorage|playSessionId)|biDynamicHashEnabled)|(?:mai(?:lOnPasswordChang|ntenanc)|vhostMaintenanc)e|g(?:roupsBeforeMacros|lobalLogoutTimer)|a(?:voidAssignment|ctiveTimer)|h(?:ideOldPassword|ttpOnly)|yubikey2fUserCanRemoveKey|krb(?:RemoveDomain|ByJs)|(?:wsdlServ|findUs)er)$/;
|
||||
|
||||
our @sessionTypes = ( 'remoteGlobal', 'global', 'localSession', 'persistent', 'saml', 'oidc', 'cas' );
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ our $specialNodeHash = {
|
|||
};
|
||||
|
||||
our $doubleHashKeys = 'issuerDBGetParameters';
|
||||
our $simpleHashKeys = '(?:(?:c(?:as(?:StorageOption|Attribute)|ustom(?:Plugins|Add)Param|heckUserHiddenHeader|ombModule)|l(?:o(?:calSessionStorageOption|goutService)|dapExportedVar|wp(?:Ssl)?Opt)|re(?:moteGlobalStorageOption|st2f(?:Verify|Init)Arg|loadUrl)|(?:(?:d(?:emo|bi)|facebook|webID)E|e)xportedVar|g(?:r(?:antSessionRule|oup)|lobalStorageOption)|n(?:otificationStorageOption|ginxCustomHandler)|p(?:ersistentStorageOption|ortalSkinRule)|macro)s|o(?:idcS(?:ervice(?:DynamicRegistrationEx(?:portedVar|traClaim)s|MetaDataAuthnContext)|torageOptions)|penIdExportedVars)|a(?:(?:daptativeAuthenticationLevelR|ut(?:hChoiceMod|oSigninR))ules|pplicationList)|s(?:(?:amlStorageOption|laveExportedVar)s|essionDataToRemember|fExtra)|S(?:MTPTLSOpts|SLVarIf))';
|
||||
our $simpleHashKeys = '(?:(?:c(?:as(?:StorageOption|Attribute)|ustom(?:Plugins|Add)Param|heckUserHiddenHeader|ombModule)|l(?:o(?:calSessionStorageOption|goutService)|dapExportedVar|wp(?:Ssl)?Opt)|f(?:indUser(?:Exclud|Search)ingAttribute|acebookExportedVar)|re(?:moteGlobalStorageOption|st2f(?:Verify|Init)Arg|loadUrl)|g(?:r(?:antSessionRule|oup)|lobalStorageOption)|n(?:otificationStorageOption|ginxCustomHandler)|p(?:ersistentStorageOption|ortalSkinRule)|(?:(?:d(?:emo|bi)|webID)E|e)xportedVar|macro)s|o(?:idcS(?:ervice(?:DynamicRegistrationEx(?:portedVar|traClaim)s|MetaDataAuthnContext)|torageOptions)|penIdExportedVars)|a(?:(?:daptativeAuthenticationLevelR|ut(?:hChoiceMod|oSigninR))ules|pplicationList)|s(?:(?:amlStorageOption|laveExportedVar)s|essionDataToRemember|fExtra)|S(?:MTPTLSOpts|SLVarIf))';
|
||||
our $specialNodeKeys = '(?:(?:(?:saml(?:ID|S)|oidc[OR])P|cas(?:App|Srv))MetaDataNode|virtualHost)s';
|
||||
our $casAppMetaDataNodeKeys = 'casAppMetaData(?:Options(?:(?:UserAttribut|Servic|Rul)e|AuthnLevel)|(?:ExportedVar|Macro)s)';
|
||||
our $casSrvMetaDataNodeKeys = 'casSrvMetaData(?:Options(?:ProxiedServices|DisplayName|SortNumber|Gateway|Renew|Icon|Url)|ExportedVars)';
|
||||
|
|
|
@ -1357,6 +1357,18 @@ qr/^(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.])*(?:[a-zA-Z][-a-zA-
|
|||
'default' => 5,
|
||||
'type' => 'int'
|
||||
},
|
||||
'findUser' => {
|
||||
'default' => 0,
|
||||
'type' => 'bool'
|
||||
},
|
||||
'findUserExcludingAttributes' => {
|
||||
'keyTest' => qr/^\S+$/,
|
||||
'type' => 'keyTextContainer'
|
||||
},
|
||||
'findUserSearchingAttributes' => {
|
||||
'keyTest' => qr/^\S+$/,
|
||||
'type' => 'keyTextContainer'
|
||||
},
|
||||
'forceGlobalStorageIssuerOTT' => {
|
||||
'type' => 'bool'
|
||||
},
|
||||
|
|
|
@ -528,6 +528,22 @@ sub attributes {
|
|||
},
|
||||
documentation => 'Header values to hide if not empty',
|
||||
},
|
||||
findUser => {
|
||||
default => 0,
|
||||
type => 'bool',
|
||||
documentation => 'Enable find user',
|
||||
flags => 'p',
|
||||
},
|
||||
findUserSearchingAttributes => {
|
||||
type => 'keyTextContainer',
|
||||
keyTest => qr/^\S+$/,
|
||||
documentation => 'Attributes used for searching accounts',
|
||||
},
|
||||
findUserExcludingAttributes => {
|
||||
type => 'keyTextContainer',
|
||||
keyTest => qr/^\S+$/,
|
||||
documentation => 'Attributes used for excluding accounts',
|
||||
},
|
||||
globalLogoutRule => {
|
||||
type => 'boolOrExpr',
|
||||
default => 0,
|
||||
|
|
|
@ -774,7 +774,6 @@ sub tree {
|
|||
{
|
||||
title => 'impersonation',
|
||||
help => 'impersonation.html',
|
||||
form => 'simpleInputContainer',
|
||||
nodes => [
|
||||
'impersonationRule',
|
||||
'impersonationIdRule',
|
||||
|
@ -782,6 +781,9 @@ sub tree {
|
|||
'impersonationHiddenAttributes',
|
||||
'impersonationSkipEmptyValues',
|
||||
'impersonationMergeSSOgroups',
|
||||
'findUser',
|
||||
'findUserSearchingAttributes',
|
||||
'findUserExcludingAttributes'
|
||||
]
|
||||
},
|
||||
{
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -155,6 +155,48 @@ sub getUser {
|
|||
return PE_OK;
|
||||
}
|
||||
|
||||
sub findUser {
|
||||
my ( $self, $req, %args ) = @_;
|
||||
|
||||
$self->validateLdap;
|
||||
return PE_LDAPCONNECTFAILED unless $self->ldap;
|
||||
|
||||
$self->bind();
|
||||
|
||||
my $mesg = $self->ldap->search(
|
||||
base => $self->conf->{ldapBase},
|
||||
scope => 'sub',
|
||||
filter => (
|
||||
$args{useMail}
|
||||
? $self->mailFilter->($req)
|
||||
: $self->filter->($req)
|
||||
),
|
||||
deref => $self->conf->{ldapSearchDeref} || 'find',
|
||||
attrs => $self->attrs,
|
||||
);
|
||||
if ( $mesg->code() != 0 ) {
|
||||
$self->logger->error(
|
||||
'LDAP Search error ' . $mesg->code . ": " . $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->{ldapentry} = $mesg->entry(0) ) {
|
||||
$self->userLogger->warn(
|
||||
"$req->{user} was not found in LDAP directory ("
|
||||
. $req->address
|
||||
. ")" );
|
||||
eval { $self->p->_authentication->setSecurity($req) };
|
||||
return PE_BADCREDENTIALS;
|
||||
}
|
||||
$req->data->{dn} = $req->data->{ldapentry}->dn();
|
||||
|
||||
return PE_OK;
|
||||
}
|
||||
|
||||
# Validate LDAP connection before use
|
||||
sub validateLdap {
|
||||
my ($self) = @_;
|
||||
|
|
|
@ -389,7 +389,7 @@ sub display {
|
|||
REGISTER_URL => $self->conf->{registerUrl},
|
||||
HIDDEN_INPUTS => $self->buildHiddenForm($req),
|
||||
STAYCONNECTED => $self->conf->{stayConnected},
|
||||
SPOOFID => $self->conf->{impersonationRule},
|
||||
IMPERSONATION => $self->conf->{impersonationRule},
|
||||
(
|
||||
$req->data->{customScript}
|
||||
? ( CUSTOM_SCRIPT => $req->data->{customScript} )
|
||||
|
@ -479,6 +479,20 @@ sub display {
|
|||
|
||||
# Display authentication form
|
||||
else {
|
||||
my $fields = [];
|
||||
if ( $self->conf->{findUser}
|
||||
&& $self->conf->{findUserSearchingAttributes} )
|
||||
{
|
||||
$login = $req->{findUser};
|
||||
$self->logger->debug(
|
||||
'Build an array ref with searching fields...');
|
||||
@$fields = map { {
|
||||
key => $_,
|
||||
value =>
|
||||
$self->conf->{findUserSearchingAttributes}->{$_}
|
||||
};
|
||||
} sort keys %{ $self->conf->{findUserSearchingAttributes} };
|
||||
}
|
||||
|
||||
# Authentication loop
|
||||
if ( $self->conf->{authentication} eq 'Choice'
|
||||
|
@ -493,6 +507,9 @@ sub display {
|
|||
DISPLAY_FORM => 0,
|
||||
DISPLAY_OPENID_FORM => 0,
|
||||
DISPLAY_YUBIKEY_FORM => 0,
|
||||
FIELDS => $fields,
|
||||
SPOOFID => $req->{findUser},
|
||||
FINDUSER => $self->conf->{findUser} && scalar @$fields
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -523,7 +540,10 @@ sub display {
|
|||
AUTH_LOOP => [],
|
||||
PORTAL_URL =>
|
||||
( $displayType eq "logo" ? $self->conf->{portal} : 0 ),
|
||||
MSG => $req->info(),
|
||||
MSG => $req->info(),
|
||||
FIELDS => $fields,
|
||||
SPOOFID => $req->{findUser},
|
||||
FINDUSER => $self->conf->{findUser} && scalar @$fields
|
||||
);
|
||||
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
# into "plugins" list in lemonldap-ng.ini, section "portal"
|
||||
package Lemonldap::NG::Portal::Main::Plugins;
|
||||
|
||||
our $VERSION = '2.0.10';
|
||||
our $VERSION = '2.0.11';
|
||||
|
||||
package Lemonldap::NG::Portal::Main;
|
||||
|
||||
|
@ -31,6 +31,7 @@ our @pList = (
|
|||
impersonationRule => '::Plugins::Impersonation',
|
||||
contextSwitchingRule => '::Plugins::ContextSwitching',
|
||||
decryptValueRule => '::Plugins::DecryptValue',
|
||||
findUser => '::Plugins::FindUser',
|
||||
adaptativeAuthenticationLevelRules =>
|
||||
'::Plugins::AdaptativeAuthenticationLevel',
|
||||
globalLogoutRule => '::Plugins::GlobalLogout',
|
||||
|
|
|
@ -357,6 +357,12 @@ sub getUser {
|
|||
return $self->_userDB->getUser( $req, %args );
|
||||
}
|
||||
|
||||
sub findUser {
|
||||
my ( $self, $req, %args ) = @_;
|
||||
return PE_ERROR unless ( $self->_userDB );
|
||||
return $self->_userDB->findUser( $req, %args );
|
||||
}
|
||||
|
||||
sub authenticate {
|
||||
my ( $self, $req ) = @_;
|
||||
my $ret = $req->authResult( $self->_authentication->authenticate($req) );
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
package Lemonldap::NG::Portal::Plugins::FindUser;
|
||||
|
||||
use strict;
|
||||
use Mouse;
|
||||
use Lemonldap::NG::Portal::Main::Constants qw(
|
||||
PE_OK
|
||||
PE_FIRSTACCESS
|
||||
);
|
||||
|
||||
our $VERSION = '2.0.11';
|
||||
|
||||
extends 'Lemonldap::NG::Portal::Main::Plugin';
|
||||
|
||||
# INITIALIZATION
|
||||
sub init {
|
||||
my ($self) = @_;
|
||||
my $imp = grep /::Plugins::Impersonation$/, $self->p->enabledPlugins;
|
||||
$self->addUnauthRoute( finduser => 'provideUser', ['POST'] ) if $imp;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
# RUNNING METHOD
|
||||
sub provideUser {
|
||||
my ( $self, $req ) = @_;
|
||||
$req->steps( ['findUser'] );
|
||||
if ( my $error = $self->p->process($req) ) {
|
||||
$self->logger->debug("Process returned error: $error");
|
||||
return $req->error($error);
|
||||
}
|
||||
$req->mustRedirect(1);
|
||||
return $self->p->do( $req, [ sub { PE_FIRSTACCESS } ] );
|
||||
}
|
||||
|
||||
sub retreiveFindUserParams {
|
||||
my ( $self, $req ) = @_;
|
||||
my @params = ();
|
||||
$self->logger->debug("FindUser: reading parameters...");
|
||||
foreach ( sort keys %{ $self->conf->{findUserSearchingAttributes} } ) {
|
||||
$self->logger->debug("Pushing $_");
|
||||
push @params, { key => $_ , value => $req->params($_)};
|
||||
}
|
||||
return @params;
|
||||
}
|
||||
|
||||
1;
|
|
@ -46,6 +46,31 @@ sub getUser {
|
|||
PE_OK;
|
||||
}
|
||||
|
||||
sub findUser {
|
||||
my ( $self, $req, %args ) = @_;
|
||||
my $table = $self->table;
|
||||
my $pivot = $args{useMail} ? $self->mailField : $self->pivot;
|
||||
my $user = $req->{user};
|
||||
my $sth;
|
||||
eval {
|
||||
$sth = $self->dbh->prepare("SELECT * FROM $table WHERE $pivot=?");
|
||||
$sth->execute($user);
|
||||
};
|
||||
if ($@) {
|
||||
|
||||
# If connection isn't available, error is displayed by dbh()
|
||||
$self->logger->error("DBI error: $@") if ( $self->_dbh );
|
||||
eval { $self->p->_authentication->setSecurity($req) };
|
||||
return PE_ERROR;
|
||||
}
|
||||
unless ( $req->data->{dbientry} = $sth->fetchrow_hashref() ) {
|
||||
$self->userLogger->warn("User $user not found");
|
||||
eval { $self->p->_authentication->setSecurity($req) };
|
||||
return PE_BADCREDENTIALS;
|
||||
}
|
||||
PE_OK;
|
||||
}
|
||||
|
||||
sub setSessionInfo {
|
||||
my ( $self, $req ) = @_;
|
||||
|
||||
|
|
|
@ -69,6 +69,36 @@ sub getUser {
|
|||
PE_BADCREDENTIALS;
|
||||
}
|
||||
|
||||
## @apmethod int findUser()
|
||||
# Search for accounts
|
||||
# @return Lemonldap::NG::Portal constant
|
||||
sub findUser {
|
||||
my ( $self, $req, %args ) = @_;
|
||||
my $plugin =
|
||||
$self->p->loadedModules->{"Lemonldap::NG::Portal::Plugins::FindUser"};
|
||||
my @params = $plugin->retreiveFindUserParams($req);
|
||||
my $cond = '';
|
||||
|
||||
$cond .= '$' . $_->{key} . " eq '$_->{value}' && " foreach (@params);
|
||||
$cond =~ s/&&\s$//;
|
||||
$self->logger->debug("Demo UserDB built condition: $cond");
|
||||
my @results = map {
|
||||
my $cn = $demoAccounts{$_}->{cn};
|
||||
my $mail = $demoAccounts{$_}->{mail};
|
||||
my $uid = $demoAccounts{$_}->{uid};
|
||||
eval "($cond)"
|
||||
? $_
|
||||
: ();
|
||||
} keys %demoAccounts;
|
||||
|
||||
my $rank = rand( scalar @results );
|
||||
$self->logger->debug("Demo UserDB random rank: $rank");
|
||||
$req->{findUser} = $results[$rank];
|
||||
|
||||
eval { $self->p->_authentication->setSecurity($req) };
|
||||
PE_OK;
|
||||
}
|
||||
|
||||
## @apmethod int setSessionInfo()
|
||||
# Get sample data
|
||||
# @return Lemonldap::NG::Portal constant
|
||||
|
|
23
lemonldap-ng-portal/site/templates/bootstrap/finduser.tpl
Normal file
23
lemonldap-ng-portal/site/templates/bootstrap/finduser.tpl
Normal file
|
@ -0,0 +1,23 @@
|
|||
<TMPL_IF NAME="FINDUSER">
|
||||
<br>
|
||||
<div class="card">
|
||||
<br>
|
||||
<form action="/finduser" method="post" role="form" class="login">
|
||||
<div class="form">
|
||||
<TMPL_LOOP NAME="FIELDS">
|
||||
<div class="input-group mb-3">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><label for="<TMPL_VAR NAME="key">" class="mb-0"><i class="fa fa-user"></i></label></span>
|
||||
</div>
|
||||
<input id="findUser<TMPL_VAR NAME="key">" name="<TMPL_VAR NAME="key">" type="text" autocomplete="off" class="form-control" placeholder="<TMPL_VAR NAME="value">" />
|
||||
</div>
|
||||
</TMPL_LOOP>
|
||||
<button type="submit" class="btn btn-info" >
|
||||
<span class="fa fa-eye"></span>
|
||||
<span trspan="searchAccount">Search an account</span>
|
||||
</button>
|
||||
</div>
|
||||
<br>
|
||||
</form>
|
||||
</div>
|
||||
</TMPL_IF>
|
|
@ -1,8 +1,8 @@
|
|||
<TMPL_IF NAME="SPOOFID">
|
||||
<TMPL_IF NAME="IMPERSONATION">
|
||||
<div class="input-group mb-3">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><label for="spoofIdfield" class="mb-0"><i class="fa fa-user icon-blue"></i></label></span>
|
||||
</div>
|
||||
<input id="spoofIdfield" name="spoofId" type="text" class="form-control" trplaceholder="spoofId" aria-required="false"/>
|
||||
<input id="spoofIdfield" name="spoofId" type="text" class="form-control" value="<TMPL_VAR NAME="SPOOFID">" autocomplete="off" trplaceholder="spoofId" aria-required="false"/>
|
||||
</div>
|
||||
</TMPL_IF>
|
||||
|
|
|
@ -222,6 +222,8 @@
|
|||
</div>
|
||||
</TMPL_IF>
|
||||
|
||||
<TMPL_INCLUDE NAME="finduser.tpl">
|
||||
|
||||
<TMPL_IF NAME="DISPLAY_PASSWORD">
|
||||
<div id="password" class="card">
|
||||
<TMPL_INCLUDE NAME="password.tpl">
|
||||
|
|
Loading…
Reference in New Issue
Block a user