From 510a1dc1c2909389a35e097fae93beb824fd4318 Mon Sep 17 00:00:00 2001 From: Christophe Maudoux Date: Tue, 22 Dec 2020 15:17:23 +0100 Subject: [PATCH] WIP: UserDB findUser (#1976) --- .../lib/Lemonldap/NG/Portal/Lib/LDAP.pm | 33 +------------ .../lib/Lemonldap/NG/Portal/UserDB/CAS.pm | 7 ++- .../lib/Lemonldap/NG/Portal/UserDB/Choice.pm | 10 +++- .../lib/Lemonldap/NG/Portal/UserDB/DBI.pm | 47 ++++++++++++++----- .../lib/Lemonldap/NG/Portal/UserDB/Demo.pm | 2 + .../Lemonldap/NG/Portal/UserDB/Facebook.pm | 8 +++- .../lib/Lemonldap/NG/Portal/UserDB/Null.pm | 4 ++ .../lib/Lemonldap/NG/Portal/UserDB/OpenID.pm | 4 ++ .../NG/Portal/UserDB/OpenIDConnect.pm | 8 +++- .../lib/Lemonldap/NG/Portal/UserDB/REST.pm | 29 +++++++++++- .../lib/Lemonldap/NG/Portal/UserDB/SAML.pm | 4 ++ .../lib/Lemonldap/NG/Portal/UserDB/Slave.pm | 4 ++ .../lib/Lemonldap/NG/Portal/UserDB/WebID.pm | 4 ++ 13 files changed, 116 insertions(+), 48 deletions(-) diff --git a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Lib/LDAP.pm b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Lib/LDAP.pm index eb7a20d56..fb0882064 100644 --- a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Lib/LDAP.pm +++ b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Lib/LDAP.pm @@ -10,7 +10,7 @@ use Lemonldap::NG::Portal::Main::Constants qw( extends 'Lemonldap::NG::Common::Module'; -our $VERSION = '2.0.10'; +our $VERSION = '2.0.11'; # PROPERTIES @@ -163,37 +163,6 @@ sub findUser { $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; } diff --git a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/UserDB/CAS.pm b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/UserDB/CAS.pm index bd85d353b..b3c17f929 100644 --- a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/UserDB/CAS.pm +++ b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/UserDB/CAS.pm @@ -7,7 +7,7 @@ use Lemonldap::NG::Portal::Main::Constants qw( PE_OK ); -our $VERSION = '2.0.0'; +our $VERSION = '2.0.11'; extends 'Lemonldap::NG::Common::Module'; @@ -24,6 +24,11 @@ sub getUser { return PE_OK; } +sub findUser { + my ( $self, $req ) = @_; + return PE_OK; +} + # Get all required attributes sub setSessionInfo { my ( $self, $req ) = @_; diff --git a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/UserDB/Choice.pm b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/UserDB/Choice.pm index 33559058f..a02e656fc 100644 --- a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/UserDB/Choice.pm +++ b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/UserDB/Choice.pm @@ -4,7 +4,7 @@ use strict; use Mouse; use Lemonldap::NG::Portal::Main::Constants qw(PE_FIRSTACCESS); -our $VERSION = '2.0.0'; +our $VERSION = '2.0.11'; extends 'Lemonldap::NG::Portal::Lib::Choice'; @@ -24,6 +24,14 @@ sub getUser { return $res; } +sub findUser { + my ( $self, $req, %args ) = @_; + $self->checkChoice($req) or return PE_FIRSTACCESS; + my $res = $req->data->{enabledMods1}->[0]->findUser( $req, %args ); + delete $req->pdata->{_choice} if ( $res > 0 ); + return $res; +} + sub setSessionInfo { my $res = $_[1]->data->{enabledMods1}->[0]->setSessionInfo( $_[1] ); delete $_[1]->pdata->{_choice} if ( $res > 0 ); diff --git a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/UserDB/DBI.pm b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/UserDB/DBI.pm index ee27f3c79..85950acae 100644 --- a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/UserDB/DBI.pm +++ b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/UserDB/DBI.pm @@ -6,7 +6,7 @@ use Lemonldap::NG::Portal::Main::Constants qw(PE_OK PE_ERROR PE_BADCREDENTIALS); extends 'Lemonldap::NG::Portal::Lib::DBI'; -our $VERSION = '2.0.6'; +our $VERSION = '2.0.11'; # PROPERTIES @@ -48,26 +48,51 @@ sub getUser { sub findUser { my ( $self, $req, %args ) = @_; - my $table = $self->table; - my $pivot = $args{useMail} ? $self->mailField : $self->pivot; - my $user = $req->{user}; + my $plugin = + $self->p->loadedModules->{"Lemonldap::NG::Portal::Plugins::FindUser"}; + my ( $searching, $excluding ) = $plugin->retreiveFindUserParams($req); + return PE_OK unless scalar @$searching; + + my $table = $self->table; + my $pivot = $args{useMail} ? $self->mailField : $self->pivot; + my $request = 'SELECT $pivot FROM $table WHERE '; + my @args; my $sth; + foreach (@$searching) { + if ( $_->{value} ) { + $request .= '$' . $_->{key} . '=? AND '; + push @args, $_->{value}; + } + } + foreach (@$excluding) { + if ( $_->{value} ) { + $request .= '$' . $_->{key} . '!=? AND '; + push @args, $_->{value}; + } + } + $request =~ s/AND\s$//; + + $self->logger->debug("DBI UserDB built condition: $request"); eval { - $sth = $self->dbh->prepare("SELECT * FROM $table WHERE $pivot=?"); - $sth->execute($user); + $sth = $self->dbh->prepare(eval "$request"); + $sth->execute(@args); }; + eval { $self->p->_authentication->setSecurity($req) }; + 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; + if ( my $results = $sth->fetchrow_arrayref() ) { + my $rank = rand( scalar @$results ); + $self->logger->debug( + 'DBI UserDB number of result(s): ' . scalar @$results ); + $self->logger->debug("Demo UserDB random rank: $rank"); + $req->{findUser} = $results->[$rank]; } + PE_OK; } diff --git a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/UserDB/Demo.pm b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/UserDB/Demo.pm index 30dd54e9a..7dd28b24b 100644 --- a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/UserDB/Demo.pm +++ b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/UserDB/Demo.pm @@ -77,6 +77,8 @@ sub findUser { my $plugin = $self->p->loadedModules->{"Lemonldap::NG::Portal::Plugins::FindUser"}; my ( $searching, $excluding ) = $plugin->retreiveFindUserParams($req); + return PE_OK unless scalar @$searching; + my $cond = ''; foreach (@$searching) { $cond .= '$' . $_->{key} . " eq '$_->{value}' && " if $_->{value}; diff --git a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/UserDB/Facebook.pm b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/UserDB/Facebook.pm index 78e9fb85d..70b5a4d96 100644 --- a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/UserDB/Facebook.pm +++ b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/UserDB/Facebook.pm @@ -6,7 +6,7 @@ use Lemonldap::NG::Portal::Main::Constants qw(PE_OK PE_MISSINGREQATTR); extends 'Lemonldap::NG::Common::Module'; -our $VERSION = '2.0.0'; +our $VERSION = '2.0.11'; has vars => ( is => 'rw', @@ -33,6 +33,12 @@ sub getUser { PE_OK; } +sub findUser { + + # Nothing to do here + PE_OK; +} + sub setSessionInfo { my ( $self, $req ) = @_; diff --git a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/UserDB/Null.pm b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/UserDB/Null.pm index d55bba46e..7f119510f 100644 --- a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/UserDB/Null.pm +++ b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/UserDB/Null.pm @@ -20,6 +20,10 @@ sub getUser { PE_OK; } +sub findUser { + PE_OK; +} + sub setSessionInfo { PE_OK; } diff --git a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/UserDB/OpenID.pm b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/UserDB/OpenID.pm index 8f1d1be88..ac9eafd2c 100644 --- a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/UserDB/OpenID.pm +++ b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/UserDB/OpenID.pm @@ -25,6 +25,10 @@ sub getUser { PE_OK; } +sub findUser { + PE_OK; +} + sub setSessionInfo { my ( $self, $req ) = @_; my %vars = ( diff --git a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/UserDB/OpenIDConnect.pm b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/UserDB/OpenIDConnect.pm index 97a3ce497..befd3f649 100644 --- a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/UserDB/OpenIDConnect.pm +++ b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/UserDB/OpenIDConnect.pm @@ -8,7 +8,7 @@ use Lemonldap::NG::Portal::Main::Constants qw( PE_OK ); -our $VERSION = '2.0.0'; +our $VERSION = '2.0.11'; extends 'Lemonldap::NG::Common::Module', 'Lemonldap::NG::Portal::Lib::OpenIDConnect'; @@ -56,6 +56,12 @@ sub getUser { return PE_OK; } +sub findUser { + + # Nothing to do here + PE_OK; +} + # Get all required attributes sub setSessionInfo { my ( $self, $req ) = @_; diff --git a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/UserDB/REST.pm b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/UserDB/REST.pm index 8fb74e782..f46d4bd95 100644 --- a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/UserDB/REST.pm +++ b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/UserDB/REST.pm @@ -11,7 +11,7 @@ use Lemonldap::NG::Portal::Main::Constants qw( extends 'Lemonldap::NG::Common::Module', 'Lemonldap::NG::Portal::Lib::REST'; -our $VERSION = '2.0.9'; +our $VERSION = '2.0.11'; # INITIALIZATION @@ -55,6 +55,33 @@ sub getUser { return PE_OK; } +sub findUser { + my ( $self, $req, %args ) = @_; + my $res; + # $res = eval { + # $self->restCall( + # $self->conf->{restUserDBUrl}, + # { + # ( $args{useMail} ? 'mail' : 'user' ) => $req->user, + # 'useMail' => ( $args{useMail} ? JSON::true : JSON::false ), + + # } + # ); + # }; + # if ($@) { + # $self->logger->error("UserDB REST error: $@"); + # eval { $self->p->_authentication->setSecurity($req) }; + # return PE_ERROR; + # } + # unless ( $res->{result} ) { + # $self->userLogger->warn( 'User ' . $req->user . ' not found' ); + # eval { $self->p->_authentication->setSecurity($req) }; + # return PE_BADCREDENTIALS; + # } + # $req->data->{restUserDBInfo} = $res->{info} || {}; + return PE_OK; +} + sub setSessionInfo { my ( $self, $req ) = @_; $req->sessionInfo->{$_} = $req->data->{restUserDBInfo}->{$_} diff --git a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/UserDB/SAML.pm b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/UserDB/SAML.pm index c605a9433..7913fa80c 100644 --- a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/UserDB/SAML.pm +++ b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/UserDB/SAML.pm @@ -33,6 +33,10 @@ sub getUser { PE_OK; } +sub findUser { + PE_OK; +} + # Get all required attributes sub setSessionInfo { my ( $self, $req ) = @_; diff --git a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/UserDB/Slave.pm b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/UserDB/Slave.pm index 02f0bd607..11bbf7f5c 100644 --- a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/UserDB/Slave.pm +++ b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/UserDB/Slave.pm @@ -30,6 +30,10 @@ sub getUser { PE_OK; } +sub findUser { + PE_OK; +} + # Search exportedVars values in HTTP headers. sub setSessionInfo { my ( $self, $req ) = @_; diff --git a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/UserDB/WebID.pm b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/UserDB/WebID.pm index 639ed6bf3..ccb4792de 100644 --- a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/UserDB/WebID.pm +++ b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/UserDB/WebID.pm @@ -24,6 +24,10 @@ sub getUser { PE_OK; } +sub findUser { + PE_OK; +} + sub setSessionInfo { my ( $self, $req ) = @_; unless ( $req->data->{_webid} ) {