LEMONLDAP::NG : * new auth architecture

* environment variables can now be used in exportedVars (usefull to access to SSL variables)
		* UTF-8 in examples
		* Romanian translation of portal
This commit is contained in:
Xavier Guimard 2008-06-06 03:51:39 +00:00
parent 9b523a3534
commit 7bac798370
14 changed files with 239 additions and 271 deletions

View File

@ -2,6 +2,10 @@ Revision history for Perl extension Lemonldap::NG::Portal.
0.83 Sat May 24 17:24:23 2008
- Integration in Handler status system
- Romanian translation
- New auth architecture
- ENV variables are now available using exportedValue (can be used to
send SSL variables to the remote application)
0.82 Mon Apr 7 15:01:02 2008
- 2 Net::LDAP password policy controls in the portal:

View File

@ -50,6 +50,7 @@ lib/Lemonldap/NG/Portal/_i18n.pm
lib/Lemonldap/NG/Portal/AuthApache.pm
lib/Lemonldap/NG/Portal/AuthCAS.pm
lib/Lemonldap/NG/Portal/AuthLA.pm
lib/Lemonldap/NG/Portal/AuthLDAP.pm
lib/Lemonldap/NG/Portal/AuthSSL.pm
lib/Lemonldap/NG/Portal/CDA.pm
lib/Lemonldap/NG/Portal/SharedConf.pm
@ -58,12 +59,12 @@ Makefile.PL
MANIFEST This list of files
META.yml
README
t/01-Lemonldap-NG-Portal-Simple.t
t/02-Lemonldap-NG-Portal-SharedConf.t
t/10-Lemonldap-NG-Portal-i18n.t
t/20-Lemonldap-NG-Portal-AuthApache.t
t/21-Lemonldap-NG-Portal-AuthSSL.t
t/22-Lemonldap-NG-Portal-AuthCAS.t
t/23-Lemonldap-NG-Portal-AuthLA.t
t/40-Lemonldap-NG-Portal-CDA.t
t/99-pod.t
t/Lemonldap-NG-Portal-AuthApache.t
t/Lemonldap-NG-Portal-AuthCAS.t
t/Lemonldap-NG-Portal-AuthLA.t
t/Lemonldap-NG-Portal-AuthSSL.t
t/Lemonldap-NG-Portal-CDA.t
t/Lemonldap-NG-Portal-i18n.t
t/Lemonldap-NG-Portal-SharedConf.t
t/Lemonldap-NG-Portal-Simple.t

View File

@ -40,7 +40,7 @@ my $portal = Lemonldap::NG::Portal::AuthLA->new({
if( $portal->process() ) {
print $portal->header;
print $portal->header('text/html; charset=utf8');
my $template = HTML::Template->new( filename => "__DIR__/tpl/menu.tpl");
my @sites = ();

View File

@ -12,14 +12,14 @@ my $portal = Lemonldap::NG::Portal::SharedConf->new(
);
if ( $portal->process() ) {
print $portal->header;
print $portal->header('text/html; charset=utf8');
print $portal->start_html;
print "<h1>Your well authenticated !</h1>";
print "Click <a href=\"$ENV{SCRIPT_NAME}?logout=1\">here</a> to logout";
print $portal->end_html;
}
else {
print $portal->header;
print $portal->header('text/html; charset=utf8');
print $portal->start_html;
print 'Error: ' . $portal->error . '<br />';
print '<form method="post" action="'.$ENV{SCRIPTNAME}.'">';

View File

@ -22,7 +22,7 @@ $template->param(AUTH_TITLE => "LemonLDAP::NG Portal");
$template->param(CSS_FILE => "skins/$skin/default.css");
if ( $portal->process() ) {
print $portal->header;
print $portal->header('text/html; charset=utf8');
# Get sites
my @sites = ();
@ -40,7 +40,7 @@ if ( $portal->process() ) {
print $template->output;
} else {
print $portal->header;
print $portal->header('text/html; charset=utf8');
$template->param(AUTH_ERROR => $portal->error);
$template->param(AUTH_URL => $portal->param('url'));
print $template->output;

View File

@ -105,13 +105,13 @@ my $portal = Lemonldap::NG::Portal::CDA->new(
# Else, we process as usual, but without prompting users with a form
if ( $portal->process() ) {
print $portal->header;
print $portal->header('text/html; charset=utf8');
print $portal->start_html;
print "<h1>Your well authenticated !</h1>";
print $portal->end_html;
}
else {
print $portal->header;
print $portal->header('text/html; charset=utf8');
print $portal->start_html;
print qq#<h2>Authentication failed</h2>
Portal is not able to recognize you

View File

@ -32,7 +32,7 @@ system.
# Write here the menu with CGI methods. This page is displayed ONLY IF
# the user was not redirected here by a Lemonldap::NG::Handler,
# else, the process sub redirect the user to the initial requested URI.
print $portal->header; # DON'T FORGET THIS (see L<CGI(3)>)
print $portal->header('text/html; charset=utf8'); # DON'T FORGET THIS (see L<CGI(3)>)
print "...";
# or redirect the user to the menu
@ -45,7 +45,7 @@ system.
# Write here the html form used to authenticate with CGI methods.
# $portal->error returns the error message if authentification failed
# Warning: by defaut, input names are "user" and "password"
print $portal->header; # DON'T FORGET THIS (see L<CGI(3)>)
print $portal->header('text/html; charset=utf8'); # DON'T FORGET THIS (see L<CGI(3)>)
print "<html> ...";
print '<form method="POST">';
# In your form, the following value is required for redirection

View File

@ -3,25 +3,30 @@ package Lemonldap::NG::Portal::AuthApache;
use strict;
use Lemonldap::NG::Portal::Simple;
our $VERSION = '0.01';
our $VERSION = '0.1';
our $OVERRIDE = {
# By default, authentication is valid if REMOTE_USER environment
# variable is present. Change formateFilter if this does not match with
# UID.
extractFormInfo => sub {
my $self = shift;
return PE_FORMEMPTY unless( $self->{user} = $ENV{REMOTE_USER} );
# This is needed for Kerberos authentication
$self->{user} =~ s/(.*)@(.*)/$1/g;
PE_OK;
},
sub authInit {
}
# Authentication is made by Apache.
authenticate => sub {
PE_OK;
},
};
# By default, authentication is valid if REMOTE_USER environment
# variable is present. Change formateFilter if this does not match with
# UID.
sub extractFormInfo {
my $self = shift;
unless ( $self->{user} = $ENV{REMOTE_USER} ) {
print STDERR "Apache is not configured to authenticate users !";
return PE_ERROR;
}
# This is needed for Kerberos authentication
$self->{user} =~ s/^(.*)@.*$/$1/g;
PE_OK;
}
# Authentication is made by Apache.
sub authenticate {
PE_OK;
}
1;
__END__
@ -42,7 +47,7 @@ compatible portals with Apache authentication.
if($portal->process()) {
# Write here the menu with CGI methods. This page is displayed ONLY IF
# the user was not redirected here.
print $portal->header; # DON'T FORGET THIS (see CGI(3))
print $portal->header('text/html; charset=utf8'); # DON'T FORGET THIS (see CGI(3))
print "...";
# or redirect the user to the menu
@ -50,7 +55,7 @@ compatible portals with Apache authentication.
}
else {
# If the user enters here, IT MEANS THAT CAS REDIRECTION DOES NOT WORK
print $portal->header; # DON'T FORGET THIS (see CGI(3))
print $portal->header('text/html; charset=utf8'); # DON'T FORGET THIS (see CGI(3))
print "<html><body><h1>Unable to work</h1>";
print "This server isn't well configured. Contact your administrator.";
print "</body></html>";

View File

@ -4,32 +4,37 @@ use strict;
use Lemonldap::NG::Portal::Simple;
use AuthCAS;
our $VERSION = '0.02';
our $VERSION = '0.03';
our $OVERRIDE = {
extractFormInfo => sub {
my $self = shift;
my $cas = new AuthCAS(casUrl => $self->{CAS_url},
CAFile => $self->{CAS_CAFile},
);
my $login_url = $cas->getServerLoginURL($self->{CAS_loginUrl});
sub authInit {
}
my $ticket = $self->param('ticket');
# Unless a ticket has been found, we redirect the user
unless( $self->{user} = $cas->validateST($self->{CAS_validationUrl}, $ticket) ) {
print $self->SUPER::redirect(
-uri => $login_url,
-status => '302 Moved Temporary'
);
exit;
}
PE_OK;
},
sub extractFormInfo {
my $self = shift;
my $cas = new AuthCAS(
casUrl => $self->{CAS_url},
CAFile => $self->{CAS_CAFile},
);
my $login_url = $cas->getServerLoginURL( $self->{CAS_loginUrl} );
authenticate => sub {
PE_OK;
},
};
my $ticket = $self->param('ticket');
# Unless a ticket has been found, we redirect the user
unless ( $self->{user} =
$cas->validateST( $self->{CAS_validationUrl}, $ticket ) )
{
print $self->SUPER::redirect(
-uri => $login_url,
-status => '302 Moved Temporary'
);
exit;
}
PE_OK;
}
sub authenticate {
PE_OK;
}
1;
__END__
@ -54,7 +59,7 @@ compatible portals with CAS authentication. EXPERIMENTAL AND NOT FINISHED!
if($portal->process()) {
# Write here the menu with CGI methods. This page is displayed ONLY IF
# the user was not redirected here.
print $portal->header; # DON'T FORGET THIS (see CGI(3))
print $portal->header('text/html; charset=utf8'); # DON'T FORGET THIS (see CGI(3))
print "...";
# or redirect the user to the menu
@ -62,7 +67,7 @@ compatible portals with CAS authentication. EXPERIMENTAL AND NOT FINISHED!
}
else {
# If the user enters here, IT MEANS THAT CAS REDIRECTION DOES NOT WORK
print $portal->header; # DON'T FORGET THIS (see CGI(3))
print $portal->header('text/html; charset=utf8'); # DON'T FORGET THIS (see CGI(3))
print "<html><body><h1>Unable to work</h1>";
print "This server isn't well configured. Contact your administrator.";
print "</body></html>";

View File

@ -2,77 +2,50 @@ package Lemonldap::NG::Portal::AuthSSL;
use strict;
use Lemonldap::NG::Portal::Simple;
use Lemonldap::NG::Portal::AuthLDAP;
our @ISA = qw(Lemonldap::NG::Portal::AuthLDAP);
our $VERSION = '0.1';
sub authInit {
my $self = shift;
$self->{SSLRequire} = 1 unless ( defined $self->{SSLRequire} );
$self->{SSLVar} ||= 'SSL_CLIENT_S_DN_Email';
$self->{SSLLDAPField} ||= 'mail';
}
# Authentication is made by Apache with SSL and here before searching the LDAP
# Directory.
# So authenticate is overloaded to return only PE_OK.
our $OVERRIDE = {
sub extractFormInfo {
my $self = shift;
my $user = $self->https ? $ENV{ $self->{SSLVar} } : 0;
if ($user) {
$self->{sessionInfo}->{authenticationLevel} = 5;
$self->{user} = $user;
$self->{authFilter} =
'(&(' . $self->{SSLLDAPField} . "=$user)(objectClass=inetOrgPerson))";
return PE_OK;
}
elsif ( $self->{SSLRequire} ) {
return PE_CERTIFICATEREQUIRED;
}
$self->{authFilter} = '';
return $self->SUPER::extractFormInfo(@_);
}
# By default, authentication is valid if SSL_CLIENT_S_DN_Email environment
# variable is present. Adapt it if you want
extractFormInfo => sub {
my $self = shift;
# Defaults values
$self->{SSLRequire} = 1 unless ( defined $self->{SSLRequire} );
$self->{SSLVar} ||= 'SSL_CLIENT_S_DN_Email';
$self->{SSLLDAPField} ||= 'mail';
my $user = $self->https ? $ENV{$self->{SSLVar}} : 0;
if ($user) {
$self->{sessionInfo}->{authenticationLevel} = 5;
$self->{user} = $user;
return PE_OK;
}
elsif ( $self->{SSLRequire} ) {
return PE_CERTIFICATEREQUIRED;
}
return $self->extractFormInfo(@_);
},
# As we know only user mail (or SSLVar), we have to use it to find him in
# the LDAP directory
formateFilter => sub {
my $self = shift;
if ( $self->{sessionInfo}->{authenticationLevel} and $self->{sessionInfo}->{authenticationLevel} > 4 ) {
$self->{filter} = '(&('
. $self->{SSLLDAPField} . '='
. $self->{user}
. ")(objectClass=person))";
return PE_OK;
}
return $self->formateFilter(@_);
},
# Apache SSL environment variable are available in exportedVars:
setSessionInfo => sub {
my $self = shift;
my $save = $self->{exportedVars};
if ( ref( $self->{exportedVars} ) eq 'HASH' ) {
foreach ( keys %{ $self->{exportedVars} } ) {
if (/^SSL/) {
$self->{sessionInfo}->{$_} = $ENV{$_};
delete $self->{exportedVars}->{$_};
}
}
}
my $r = $self->setSessionInfo(@_);
$self->{exportedVars} = $save;
return $r;
},
# If authentication has been done with SSL, LDAP bind is disabled
authenticate => sub {
my $self = shift;
if ( $self->{sessionInfo}->{authenticationLevel} and $self->{sessionInfo}->{authenticationLevel} > 4 ) {
return PE_OK;
}
return $self->authenticate(@_);
},
};
# If authentication has been done with SSL, LDAP bind is disabled
sub authenticate {
my $self = shift;
if ( $self->{sessionInfo}->{authenticationLevel}
and $self->{sessionInfo}->{authenticationLevel} > 4 )
{
return PE_OK;
}
return $self->SUPER::authenticate(@_);
}
1;
__END__
@ -119,7 +92,7 @@ With Lemonldap::NG::Portal::Simple:
if($portal->process()) {
# Write here the menu with CGI methods. This page is displayed ONLY IF
# the user was not redirected here.
print $portal->header; # DON'T FORGET THIS (see CGI(3))
print $portal->header('text/html; charset=utf8'); # DON'T FORGET THIS (see CGI(3))
print "...";
# or redirect the user to the menu
@ -127,7 +100,7 @@ With Lemonldap::NG::Portal::Simple:
}
else {
# If the user enters here, IT MEANS THAT YOUR SSL PARAMETERS ARE BAD
print $portal->header; # DON'T FORGET THIS (see CGI(3))
print $portal->header('text/html; charset=utf8'); # DON'T FORGET THIS (see CGI(3))
print "<html><body><h1>Unable to work</h1>";
print "This server isn't well configured. Contact your administrator.";
print "</body></html>";

View File

@ -56,7 +56,7 @@ compatible portals with Cross Domain Authentication.
if($portal->process()) {
# Write here the menu with CGI methods. This page is displayed ONLY IF
# the user was not redirected here.
print $portal->header; # DON'T FORGET THIS (see L<CGI(3)>)
print $portal->header('text/html; charset=utf8'); # DON'T FORGET THIS (see L<CGI(3)>)
print "...";
# or redirect the user to the menu
@ -66,7 +66,7 @@ compatible portals with Cross Domain Authentication.
# Write here the html form used to authenticate with CGI methods.
# $portal->error returns the error message if athentification failed
# Warning: by defaut, input names are "user" and "password"
print $portal->header; # DON'T FORGET THIS (see L<CGI(3)>)
print $portal->header('text/html; charset=utf8'); # DON'T FORGET THIS (see L<CGI(3)>)
print "...";
print '<form method="POST">';
# In your form, the following value is required for redirection

View File

@ -234,7 +234,7 @@ compatible portals using a central configuration database.
if($portal->process()) {
# Write here the menu with CGI methods. This page is displayed ONLY IF
# the user was not redirected here.
print $portal->header; # DON'T FORGET THIS (see L<CGI(3)>)
print $portal->header('text/html; charset=utf8'); # DON'T FORGET THIS (see L<CGI(3)>)
print "...";
# or redirect the user to the menu
@ -244,7 +244,7 @@ compatible portals using a central configuration database.
# Write here the html form used to authenticate with CGI methods.
# $portal->error returns the error message if athentification failed
# Warning: by defaut, input names are "user" and "password"
print $portal->header; # DON'T FORGET THIS (see L<CGI(3)>)
print $portal->header('text/html; charset=utf8'); # DON'T FORGET THIS (see L<CGI(3)>)
print "...";
print '<form method="POST">';
# In your form, the following value is required for redirection

View File

@ -19,23 +19,23 @@ our @ISA = qw(CGI Exporter);
# Constants
use constant {
PE_REDIRECT => -2,
PE_DONE => -1,
PE_OK => 0,
PE_SESSIONEXPIRED => 1,
PE_FORMEMPTY => 2,
PE_WRONGMANAGERACCOUNT => 3,
PE_USERNOTFOUND => 4,
PE_BADCREDENTIALS => 5,
PE_LDAPCONNECTFAILED => 6,
PE_LDAPERROR => 7,
PE_APACHESESSIONERROR => 8,
PE_FIRSTACCESS => 9,
PE_BADCERTIFICATE => 10,
PE_PP_ACCOUNT_LOCKED => 21,
PE_PP_PASSWORD_EXPIRED => 22,
PE_CERTIFICATEREQUIRED => 23,
PE_ERROR => 24,
PE_REDIRECT => -2,
PE_DONE => -1,
PE_OK => 0,
PE_SESSIONEXPIRED => 1,
PE_FORMEMPTY => 2,
PE_WRONGMANAGERACCOUNT => 3,
PE_USERNOTFOUND => 4,
PE_BADCREDENTIALS => 5,
PE_LDAPCONNECTFAILED => 6,
PE_LDAPERROR => 7,
PE_APACHESESSIONERROR => 8,
PE_FIRSTACCESS => 9,
PE_BADCERTIFICATE => 10,
PE_PP_ACCOUNT_LOCKED => 21,
PE_PP_PASSWORD_EXPIRED => 22,
PE_CERTIFICATEREQUIRED => 23,
PE_ERROR => 24,
};
# EXPORTER PARAMETERS
@ -43,7 +43,8 @@ our @EXPORT =
qw( PE_DONE PE_OK PE_SESSIONEXPIRED PE_FORMEMPTY PE_WRONGMANAGERACCOUNT
PE_USERNOTFOUND PE_BADCREDENTIALS PE_LDAPCONNECTFAILED PE_LDAPERROR
PE_APACHESESSIONERROR PE_FIRSTACCESS PE_BADCERTIFICATE PE_REDIRECT
PE_PP_ACCOUNT_LOCKED PE_PP_PASSWORD_EXPIRED PE_CERTIFICATEREQUIRED);
PE_PP_ACCOUNT_LOCKED PE_PP_PASSWORD_EXPIRED PE_CERTIFICATEREQUIRED
PE_ERROR);
our %EXPORT_TAGS = ( 'all' => [ @EXPORT, 'import' ], );
our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
@ -64,21 +65,24 @@ sub new {
$self->{securedCookie} ||= 0;
$self->{cookieName} ||= "lemonldap";
$self->{ldapPpolicyControl} ||= 0;
$self->{authentication} ||= 'LDAP';
$self->{authentication} =~ s/^ldap/LDAP/;
if ( $self->{authentication} and $self->{authentication} ne "ldap" ) {
# Authentication module is required and has to be in @ISA
my $tmp = 'Lemonldap::NG::Portal::Auth' . $self->{authentication};
$tmp =~ s/\s.*$//;
eval "require $tmp";
die($@) if ($@);
push @ISA, $tmp;
# $Lemonldap::NG::Portal::AuthSSL::OVERRIDE does not overload $self
# variables: if the administrator has defined a sub, we respect it
my $tmp =
'require Lemonldap::NG::Portal::Auth'
. $self->{authentication}
. '; $tmp = $Lemonldap::NG::Portal::Auth'
. $self->{authentication}
. '::OVERRIDE;';
eval $tmp;
die($@) if ($@);
%$self = ( %$tmp, %$self );
}
# $self->{authentication} can contains arguments (key1 = scalar_value;
# key2 = ...)
$tmp = $self->{authentication};
$tmp =~ s/^\w+\s*//;
my %h = split( /\s*[=;]\s*/, $tmp) if($tmp);
%$self = ( %h, %$self );
$self->authInit();
return $self;
}
@ -100,13 +104,13 @@ sub getConf {
sub error {
my $self = shift;
return &Lemonldap::NG::Portal::_i18n::error( $self->{error},
$ENV{HTTP_ACCEPT_LANGUAGE} );
shift || $ENV{HTTP_ACCEPT_LANGUAGE} );
}
# Private sub used to bind to LDAP server both with Lemonldap::NG account and user
# credentials if LDAP authentication is used
sub _bind {
my ( $ldap, $dn, $password ) = @_;
my ( $self, $ldap, $dn, $password ) = @_;
my $mesg;
if ( $dn and $password ) { # named bind
$mesg = $ldap->bind( $dn, password => $password );
@ -174,13 +178,17 @@ sub updateStatus {
# different than PE_OK #
###############################################################
# extractFormInfo, setAuthSessionInfo and authenticate must be implemented in
# auth modules
sub process {
my ($self) = @_;
$self->{error} = PE_OK;
$self->{error} = $self->_subProcess(
qw(controlUrlOrigin controlExistingSession extractFormInfo formateParams
formateFilter connectLDAP bind search setSessionInfo setMacros setGroups
authenticate store unbind buildCookie log autoRedirect)
formateFilter connectLDAP bind search setAuthSessionInfo
setSessionInfo setMacros setGroups authenticate store unbind
buildCookie log autoRedirect)
);
$self->updateStatus;
return ( ( $self->{error} > 0 ) ? 0 : 1 );
@ -256,7 +264,7 @@ sub controlExistingSession {
$r = $self->existingSession( $id, $datas );
}
if ( $r == PE_DONE ) {
$self->{error} = _subProcess(qw(log autoRedirect));
$self->{error} = $self->_subProcess(qw(log autoRedirect));
return $self->{error} || PE_DONE;
}
else {
@ -271,18 +279,6 @@ sub existingSession {
PE_OK;
}
# 3. In ldap authentication scheme, we load here user and password from HTML
# form
sub extractFormInfo {
my $self = shift;
return PE_FIRSTACCESS
unless ( $self->param('user') );
return PE_FORMEMPTY
unless ( length( $self->{'user'} = $self->param('user') ) > 0
&& length( $self->{'password'} = $self->param('password') ) > 0 );
PE_OK;
}
# Unused. You can overload if you have to modify user and password before
# authentication
sub formateParams() {
@ -293,7 +289,8 @@ sub formateParams() {
# it with Active Directory, overload it to use CN instead of UID.
sub formateFilter {
my $self = shift;
$self->{filter} = "(&(uid=" . $self->{user} . ")(objectClass=inetOrgPerson))";
$self->{filter} = $self->{authFilter} ||
"(&(uid=" . $self->{user} . ")(objectClass=inetOrgPerson))";
PE_OK;
}
@ -336,7 +333,10 @@ sub bind {
$self->connectLDAP unless ( $self->{ldap} );
return PE_WRONGMANAGERACCOUNT
unless (
&_bind( $self->{ldap}, $self->{managerDn}, $self->{managerPassword} ) );
$self->_bind(
$self->{ldap}, $self->{managerDn}, $self->{managerPassword}
)
);
PE_OK;
}
@ -357,6 +357,8 @@ sub search {
PE_OK;
}
# sub setAuthSessionInfo has to be defined in auth module
# 8. Load all parameters included in exportedVars parameter.
# Multi-value parameters are loaded in a single string with
# '; ' separator
@ -373,16 +375,19 @@ sub setSessionInfo {
}
elsif ( ref( $self->{exportedVars} ) eq 'HASH' ) {
foreach ( keys %{ $self->{exportedVars} } ) {
$self->{sessionInfo}->{$_} = join( '; ',
$self->{entry}->get_value( $self->{exportedVars}->{$_} ) )
|| "";
if ( my $tmp = $ENV{$_} ) {
$tmp =~ s/[\r\n]/ /gs;
$self->{sessionInfo}->{$_} = $tmp;
}
else {
$self->{sessionInfo}->{$_} = join( '; ',
$self->{entry}->get_value( $self->{exportedVars}->{$_} ) )
|| "";
}
}
}
else {
foreach ( @{ $self->{exportedVars} } ) {
$self->{sessionInfo}->{$_} =
join( '; ', $self->{entry}->get_value($_) ) || "";
}
die('Only hash reference are supported now in exportedVars');
}
PE_OK;
}
@ -406,64 +411,6 @@ sub unbind {
PE_OK;
}
# 12. Default authentication: LDAP bind with user credentials
sub authenticate {
my $self = shift;
$self->unbind();
my $err;
return $err unless ( ( $err = $self->connectLDAP ) == PE_OK );
# Check if we use Ppolicy control
if ( $self->{ldapPpolicyControl} ) {
# require Perl module
eval 'require Net::LDAP::Control::PasswordPolicy';
die('Module Net::LDAP::Control::PasswordPolicy not found in @INC')
if ($@);
eval
'use Net::LDAP::Constant qw( LDAP_CONTROL_PASSWORDPOLICY LDAP_PP_ACCOUNT_LOCKED LDAP_PP_PASSWORD_EXPIRED );';
no strict 'subs';
# Create Control object
my $pp = Net::LDAP::Control::PasswordPolicy->new;
# Bind with user credentials
my $mesg = $self->{ldap}->bind(
$self->{dn},
password => $self->{password},
control => [$pp]
);
# Get bind response
return PE_OK if ( $mesg->code == 0 );
# Get server control response
my ($resp) = $mesg->control(LDAP_CONTROL_PASSWORDPOLICY);
if ( defined $resp ) {
my $pp_error = $resp->error;
if ($pp_error) {
return PE_PP_ACCOUNT_LOCKED
if ( $pp_error == LDAP_PP_ACCOUNT_LOCKED );
return PE_PP_PASSWORD_EXPIRED
if ( $pp_error == LDAP_PP_PASSWORD_EXPIRED );
}
else {
return PE_BADCREDENTIALS;
}
}
else {
return PE_LDAPERROR;
}
}
else {
return PE_BADCREDENTIALS
unless ( &_bind( $self->{ldap}, $self->{dn}, $self->{password} ) );
}
$self->{sessionInfo}->{authenticationLevel} = 2;
PE_OK;
}
# 13. Now, the user is authenticated. It's time to store his parameters with
# Apache::Session::* module
sub store {
@ -487,7 +434,7 @@ sub store {
# 14. If all is done, we build the Lemonldap::NG cookie
sub buildCookie {
my $self = shift;
$self->{cookie} = $self->cookie(
push @{$self->{cookie}}, $self->cookie(
-name => $self->{cookieName},
-value => $self->{id},
-domain => $self->{domain},
@ -575,7 +522,7 @@ Lemonldap::NG::Portal::Simple - Base module for building Lemonldap::NG compatibl
if($portal->process()) {
# Write here the menu with CGI methods. This page is displayed ONLY IF
# the user was not redirected here.
print $portal->header; # DON'T FORGET THIS (see L<CGI(3)>)
print $portal->header('text/html; charset=utf8'); # DON'T FORGET THIS (see L<CGI(3)>)
print "...";
# or redirect the user to the menu
@ -585,7 +532,7 @@ Lemonldap::NG::Portal::Simple - Base module for building Lemonldap::NG compatibl
# Write here the html form used to authenticate with CGI methods.
# $portal->error returns the error message if athentification failed
# Warning: by defaut, input names are "user" and "password"
print $portal->header; # DON'T FORGET THIS (see L<CGI(3)>)
print $portal->header('text/html; charset=utf8'); # DON'T FORGET THIS (see L<CGI(3)>)
print "...";
print '<form method="POST">';
# In your form, the following value is required for redirection
@ -764,7 +711,7 @@ described above
=head3 _bind( $ldap, $dn, $password )
Non-object method used to bind to the ldap server.
Method used to bind to the ldap server.
=head3 header

View File

@ -1,26 +1,31 @@
package Lemonldap::NG::Portal::_i18n;
# Developpers warning : this file must stay UTF-8 encoded
use AutoLoader qw(AUTOLOAD);
our $VERSION = '0.11';
our $VERSION = '0.2';
sub error {
my($error,$lang) = @_;
my ( $error, $lang ) = @_;
$lang = lc($lang);
$lang =~ s/-/_/g;
$error = 0 if ( $error < 0 );
foreach ( split( /[,;]/, $lang ) ) {
next if /=/;
if ( __PACKAGE__->can("error_$_") ) {
return &{"error_$_"}->[$error];
}
s/^(..).*$/$1/;
if ( __PACKAGE__->can("error_$_") ) {
return &{"error_$_"}->[$error];
}
}
return &error_en->[$error];
}
*error_fr_fr = *error_fr;
*error_en_us = *error_en;
1;
__END__
# Order of the constants:
# * PE_OK 0
# * PE_SESSIONEXPIRED 1
@ -53,36 +58,36 @@ __END__
sub error_fr {
[
"Utilisateur authentifié",
"Votre session a expiré, vous devez vous réauthentifier",
"Identifiant ou mot de passe non renseigné",
"Utilisateur authentifié",
"Votre session a expiré, vous devez vous réauthentifier",
"Identifiant ou mot de passe non renseigné",
"Compte ou mot de passe LDAP de l'application incorrect",
"Utilisateur inexistant",
"Mot de passe ou identifiant incorrect",
"Connexion impossible au serveur LDAP",
"Erreur anormale du serveur LDAP",
"Erreur du module Apache::Session choisi",
"Authentification exigée",
"Authentification exigée",
"Certificat invalide",
"Échec de l'initialisation de Lasso:Login ou Lasso:Logout",
"Échec de la résolution de l'artefact Liberty Alliance",
"Échec de la défédération Liberty Alliance",
"La requête renvoyée par le fournisseur d'identité Liberty Alliance est vide",
"Un des appels SOAP Liberty Alliance a échoué",
"Un des appels de déconnexion Liberty Alliance a échoué",
"Aucun artefact SAML trouvé, ou échec de l'auto-acceptation SSO",
"Initialisation, construction ou requête SSO en échec",
"Échec de l'initialisation de Lasso:Login ou Lasso:Logout",
"Échec de la résolution de l'artefact Liberty Alliance",
"Échec de la défédération Liberty Alliance",
"La requête renvoyée par le fournisseur d'identité Liberty Alliance est vide",
"Un des appels SOAP Liberty Alliance a échoué",
"Un des appels de déconnexion Liberty Alliance a échoué",
"Aucun artefact SAML trouvé, ou échec de l'auto-acceptation SSO",
"Initialisation, construction ou requête SSO en échec",
"Impossible d'enregistrer l'identifiant de connexion Liberty Alliance",
"Un processus terminal Liberty Alliance a échoué",
"Votre compte est bloqué",
"Votre mot de passe a expiré",
"Certificat exig&eacute;",
"Un processus terminal Liberty Alliance a échoué",
"Votre compte est bloqué",
"Votre mot de passe a expiré",
"Certificat exigé",
];
}
sub error_en {
[
"Everything is OK",
"User authenticated",
"Your connection has expired; You must to be authentified once again",
"User and password fields must be filled",
"Wrong directory manager account or password",
@ -109,3 +114,31 @@ sub error_en {
];
}
sub error_ro {
[
"Utilizator autentificat",
"Sesiunea dvs. a expirat, trebuie să vă reautentificaţi",
"Identificator sau parolă inexistentă",
"Cont sau parolă LDAP a aplicaţiei incorect",
"Utilizator inexistent",
"Parolă sau identificator incorect",
"Conexiune imposibilă la serverul LDAP",
"Eroare anormală a serverului LDAP",
"Eroare a modulului Apache::Session aleasă",
"Autentificare cerută",
"Certificat invalid",
"Eşec al iniţializării Lasso:Login sau Lasso:Logout",
"Eşec al rezoluţiei artefact-ului Liberty Alliance",
"Eşec al defederaţiei Liberty Alliance",
"Cererea retrimisă de către furnizorul de identitate Liberty Alliance este goală",
"Unul dintre apelurile SOAP Liberty Alliance a eşuat",
"Unul dintre apelurile de deconectare Liberty Alliance a eşuat",
"Nici un artefact SAML găsit, sau eşec al auto-acceptării SSO",
"Iniţiere, construcţie sau cerere SSO în eşec",
"Imposibil de a înregistra identificatorul de conectare Liberty Alliance",
"Un proces terminal Liberty Alliance a eşuat",
"Contul dvs. este blocat",
"Parola dvs. a expirat",
"Certificat cerut",
];
}