Pwd reset in progress (#595)
This commit is contained in:
parent
2582fc21f1
commit
7a3725db9d
|
@ -111,7 +111,7 @@ sub defaultValues {
|
|||
'mailSessionKey' => 'mail',
|
||||
'mailSubject' => '[LemonLDAP::NG] Your new password',
|
||||
'mailTimeout' => 0,
|
||||
'mailUrl' => 'http://auth.example.com/mail.pl',
|
||||
'mailUrl' => 'http://auth.example.com/resetpwd',
|
||||
'managerDn' => '',
|
||||
'managerPassword' => '',
|
||||
'multiValuesSeparator' => '; ',
|
||||
|
@ -177,7 +177,7 @@ sub defaultValues {
|
|||
'remoteGlobalStorageOptions' => {
|
||||
'ns' =>
|
||||
'http://auth.example.com/Lemonldap/NG/Common/CGI/SOAPService',
|
||||
'proxy' => 'http://auth.example.com/index.pl/sessions'
|
||||
'proxy' => 'http://auth.example.com/sessions'
|
||||
},
|
||||
'requireToken' => 1,
|
||||
'samlAttributeAuthorityDescriptorAttributeServiceSOAP' =>
|
||||
|
|
|
@ -1367,7 +1367,7 @@ qr/^(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.])*(?:[a-zA-Z][-a-zA-Z0-
|
|||
'type' => 'int'
|
||||
},
|
||||
'mailUrl' => {
|
||||
'default' => 'http://auth.example.com/mail.pl',
|
||||
'default' => 'http://auth.example.com/resetpwd',
|
||||
'type' => 'url'
|
||||
},
|
||||
'maintenance' => {
|
||||
|
@ -2084,7 +2084,7 @@ qr/(?:(?:https?):\/\/(?:(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.]
|
|||
'default' => {
|
||||
'ns' =>
|
||||
'http://auth.example.com/Lemonldap/NG/Common/CGI/SOAPService',
|
||||
'proxy' => 'http://auth.example.com/index.pl/sessions'
|
||||
'proxy' => 'http://auth.example.com/sessions'
|
||||
},
|
||||
'type' => 'keyTextContainer'
|
||||
},
|
||||
|
|
|
@ -903,7 +903,7 @@ sub attributes {
|
|||
},
|
||||
mailUrl => {
|
||||
type => 'url',
|
||||
default => 'http://auth.example.com/mail.pl',
|
||||
default => 'http://auth.example.com/resetpwd',
|
||||
documentation => 'URL of password reset page',
|
||||
},
|
||||
SMTPServer => {
|
||||
|
@ -2044,7 +2044,7 @@ m{^(?:ldapi://[^/]*/?|\w[\w\-\.]*(?::\d{1,5})?|ldap(?:s|\+tls)?://\w[\w\-\.]*(?:
|
|||
remoteGlobalStorageOptions => {
|
||||
type => 'keyTextContainer',
|
||||
default => {
|
||||
proxy => 'http://auth.example.com/index.pl/sessions',
|
||||
proxy => 'http://auth.example.com/sessions',
|
||||
ns =>
|
||||
'http://auth.example.com/Lemonldap/NG/Common/CGI/SOAPService',
|
||||
},
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -155,7 +155,7 @@ sub getMailSession {
|
|||
foreach my $id ( keys %$sessions ) {
|
||||
my $mailSession = $self->p->getApacheSession($id);
|
||||
next unless ($mailSession);
|
||||
return $id if ( $mailSession->data->{_type} =~ /^mail$/ );
|
||||
return $mailSession if ( $mailSession->data->{_type} =~ /^mail$/ );
|
||||
}
|
||||
|
||||
# No mail session found, return empty string
|
||||
|
|
|
@ -39,13 +39,16 @@ sub enabledPlugins {
|
|||
push @res, '::Plugins::Register'
|
||||
if ( $self->conf->{registerDB} and $self->conf->{registerDB} ne 'Null' );
|
||||
|
||||
push @res, '::Plugins::MailReset'
|
||||
if ( $self->conf->{portalDisplayResetPassword} );
|
||||
|
||||
# Check if SOAP is enabled
|
||||
push @res, '::Plugins::SOAPServer'
|
||||
if ( $self->conf->{soapSessionServer}
|
||||
or $self->conf->{soapConfigServer} );
|
||||
|
||||
# Check if portal status is enabled
|
||||
push @res, '::Plugins::Status' if($self->conf->{portalStatus});
|
||||
push @res, '::Plugins::Status' if ( $self->conf->{portalStatus} );
|
||||
|
||||
# Add REST (check is done by it)
|
||||
push @res, '::Plugins::RESTServer';
|
||||
|
@ -72,6 +75,7 @@ sub enabledPlugins {
|
|||
}
|
||||
|
||||
# Check if custom plugins are required
|
||||
# TODO: change this name
|
||||
if ( $self->conf->{plugins} ) {
|
||||
$self->lmLog( 'Custom plugins: ' . $self->conf->{plugins}, 'debug' );
|
||||
push @res, grep ( /\w/, split( /,\s*/, $self->conf->{plugins} ) );
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package Lemonldap::NG::Portal::Plugins::Register;
|
||||
package Lemonldap::NG::Portal::Plugins::MailReset;
|
||||
|
||||
use strict;
|
||||
use Encode;
|
||||
|
@ -9,10 +9,12 @@ use Lemonldap::NG::Portal::Main::Constants qw(
|
|||
PE_BADMAILTOKEN
|
||||
PE_CAPTCHAEMPTY
|
||||
PE_CAPTCHAERROR
|
||||
PE_MAILCONFIRMATION_ALREADY_SENT
|
||||
PE_MAILCONFIRMOK
|
||||
PE_MAILERROR
|
||||
PE_MAILFIRSTACCESS
|
||||
PE_MAILFORMEMPTY
|
||||
PE_MAILNOTFOUND
|
||||
PE_MAILOK
|
||||
PE_MALFORMEDUSER
|
||||
PE_NOTOKEN
|
||||
|
@ -90,7 +92,7 @@ sub _reset {
|
|||
my ( $mailToken, $newPwd, $confirmPwd );
|
||||
|
||||
# Check for first access
|
||||
$mailToken = $req->param('mail_token');
|
||||
$mailToken = $req->datas->{mailToken} = $req->param('mail_token');
|
||||
unless ( $req->param('mail') || $mailToken ) {
|
||||
$self->setSecurity($req);
|
||||
return PE_MAILFIRSTACCESS if ( $req->method eq 'GET' );
|
||||
|
@ -112,7 +114,7 @@ sub _reset {
|
|||
$req->{mail} = $mailSession->{user};
|
||||
$req->datas->{mailAddress} =
|
||||
$mailSession->{ $self->conf->{mailSessionKey} };
|
||||
$self->lmLog( 'User associated to: ' . $req->{mail} . 'debug' );
|
||||
$self->lmLog( 'User associated to: ' . $req->{mail}, 'debug' );
|
||||
}
|
||||
|
||||
# Check for values posted
|
||||
|
@ -168,7 +170,7 @@ sub _reset {
|
|||
}
|
||||
|
||||
# Search user in database
|
||||
$req->user( $req->{mail} );
|
||||
#$req->user( $req->{mail} );
|
||||
$req->steps(
|
||||
[
|
||||
'getUser', 'setSessionInfo',
|
||||
|
@ -188,10 +190,8 @@ sub _reset {
|
|||
}
|
||||
|
||||
# Build temporary session
|
||||
my $mailSession;
|
||||
unless ( ( $mailSession = $self->getMailSession( $req->{mail} ) )
|
||||
or $mailToken )
|
||||
{
|
||||
my $mailSession = $self->getMailSession( $req->{mail} );
|
||||
unless ( $mailSession or $mailToken ) {
|
||||
|
||||
# Create a new session
|
||||
|
||||
|
@ -226,32 +226,39 @@ sub _reset {
|
|||
|
||||
# Update session
|
||||
$mailSession->update($infos);
|
||||
$req->id($mailSession->id);
|
||||
}
|
||||
elsif($mailSession) {
|
||||
$self->lmLog( 'Mail session found: ' . $mailSession->id, 'debug' );
|
||||
$req->datas->{mailAlreadySent} = 1;
|
||||
}
|
||||
|
||||
# Send confirmation mail
|
||||
unless ($mailToken) {
|
||||
my $mailAlreadySent = ( $mailSession->{id} and !$req->id ) ? 1 : 0;
|
||||
$req->{id} ||= $mailSession->{id};
|
||||
|
||||
$self->lmLog( 'Mail session found: ' . $mailSession->id, 'debug' );
|
||||
|
||||
# Mail session expiration date
|
||||
my $expTimestamp = $mailSession->data->{mailSessionTimeoutTimestamp};
|
||||
|
||||
$self->lmLog( "Mail expiration timestamp: $expTimestamp", 'debug' );
|
||||
|
||||
my $expMailDate = strftime( "%d/%m/%Y", localtime $expTimestamp );
|
||||
my $expMailTime = strftime( "%H:%M", localtime $expTimestamp );
|
||||
$req->datas->{expMailDate} =
|
||||
strftime( "%d/%m/%Y", localtime $expTimestamp );
|
||||
$req->datas->{expMailTime} =
|
||||
strftime( "%H:%M", localtime $expTimestamp );
|
||||
|
||||
# Mail session start date
|
||||
my $startTimestamp = $mailSession->data->{mailSessionStartTimestamp};
|
||||
|
||||
$self->lmLog( "Mail start timestamp: $startTimestamp", 'debug' );
|
||||
my $startMailDate = strftime( "%d/%m/%Y", localtime $startTimestamp );
|
||||
my $startMailTime = strftime( "%H:%M", localtime $startTimestamp );
|
||||
$req->datas->{startMailDate} =
|
||||
strftime( "%d/%m/%Y", localtime $startTimestamp );
|
||||
$req->datas->{startMailTime} =
|
||||
strftime( "%H:%M", localtime $startTimestamp );
|
||||
|
||||
# Ask if user want another confirmation email
|
||||
if ( $self->mailAlreadySent and !$req->param('resendconfirmation') ) {
|
||||
if ( $req->datas->{mailAlreadySent}
|
||||
and !$req->param('resendconfirmation') )
|
||||
{
|
||||
$self->p->userNotice(
|
||||
'Reset mail already sent to ' . $req->{mail} );
|
||||
|
||||
|
@ -263,6 +270,7 @@ sub _reset {
|
|||
$req->datas->{mailAddress} ||=
|
||||
$self->p->getFirstValue(
|
||||
$req->{sessionInfo}->{ $self->conf->{mailSessionKey} } );
|
||||
return PE_MAILERROR unless($req->datas->{mailAddress});
|
||||
|
||||
# Build confirmation url
|
||||
my $url =
|
||||
|
@ -270,7 +278,7 @@ sub _reset {
|
|||
. "?mail_token="
|
||||
. $req->{id}
|
||||
. '&skin='
|
||||
. $self->p->getSkin;
|
||||
. $self->p->getSkin($req);
|
||||
$url .= '&'
|
||||
. $self->conf->{authChoiceParam} . '='
|
||||
. $req->datas->{_authChoice}
|
||||
|
@ -300,14 +308,14 @@ sub _reset {
|
|||
}
|
||||
|
||||
# Replace variables in body
|
||||
$body =~ s/\$expMailDate/$expMailDate/g;
|
||||
$body =~ s/\$expMailTime/$expMailTime/g;
|
||||
$body =~ s/\$expMailDate/$req->datas->{expMailDate}/ge;
|
||||
$body =~ s/\$expMailTime/$req->datas->{expMailTime}/ge;
|
||||
$body =~ s/\$url/$url/g;
|
||||
$body =~ s/\$(\w+)/decode("utf8",$req->{sessionInfo}->{$1})/ge;
|
||||
|
||||
# Send mail
|
||||
unless (
|
||||
$self->send_mail( $self->{mailAddress}, $subject, $body, $html ) )
|
||||
$self->send_mail( $req->datas->{mailAddress}, $subject, $body, $html ) )
|
||||
{
|
||||
$self->lmLog( 'Unable to send reset mail', 'debug' );
|
||||
|
||||
|
@ -404,4 +412,98 @@ sub setSecurity {
|
|||
}
|
||||
}
|
||||
|
||||
sub display {
|
||||
my ( $self, $req ) = @_;
|
||||
my %tplPrm = (
|
||||
PORTAL_URL => $self->conf->{portal},
|
||||
SKIN_PATH => '/static',
|
||||
SKIN => $self->conf->{portalSkin},
|
||||
SKIN_BG => $self->conf->{portalSkinBackground},
|
||||
AUTH_ERROR => $req->error,
|
||||
AUTH_ERROR_TYPE => $req->error_type,
|
||||
CHOICE_PARAM => $self->conf->{authChoiceParam},
|
||||
CHOICE_VALUE => $req->{_authChoice},
|
||||
EXPMAILDATE => $req->datas->{expMailDate},
|
||||
EXPMAILTIME => $req->datas->{expMailTime},
|
||||
STARTMAILDATE => $req->datas->{startMailDate},
|
||||
STARTMAILTIME => $req->datas->{startMailTime},
|
||||
MAILALREADYSENT => $req->datas->{mailAlreadySent},
|
||||
MAIL => (
|
||||
$self->p->checkXSSAttack( 'mail', $req->{mail} ) ? ""
|
||||
: $self->{mail}
|
||||
),
|
||||
MAIL_TOKEN => (
|
||||
$self->p->checkXSSAttack( 'mail_token', $req->datas->{mailToken} )
|
||||
? ""
|
||||
: $req->datas->{mailToken}
|
||||
),
|
||||
DISPLAY_FORM => 0,
|
||||
DISPLAY_RESEND_FORM => 0,
|
||||
DISPLAY_CONFIRMMAILSENT => 0,
|
||||
DISPLAY_MAILSENT => 0,
|
||||
DISPLAY_PASSWORD_FORM => 0,
|
||||
);
|
||||
|
||||
# Display captcha if it's enabled
|
||||
if ( $req->captcha ) {
|
||||
$tplPrm{CAPTCHA_SRC} = $req->captcha;
|
||||
$tplPrm{CAPTCHA_SIZE} = $self->conf->{captcha_size};
|
||||
}
|
||||
if ( $req->token ) {
|
||||
$tplPrm{TOKEN} = $req->token;
|
||||
}
|
||||
|
||||
# Display form the first time
|
||||
if (
|
||||
(
|
||||
$req->error == PE_MAILFORMEMPTY
|
||||
or $req->error == PE_MAILFIRSTACCESS
|
||||
or $req->error == PE_MAILNOTFOUND
|
||||
or $req->error == PE_CAPTCHAERROR
|
||||
or $req->error == PE_CAPTCHAEMPTY
|
||||
)
|
||||
and !$req->datas->{mailToken}
|
||||
)
|
||||
{
|
||||
$self->lmLog('Display form','debug');
|
||||
$tplPrm{DISPLAY_FORM} = 1;
|
||||
}
|
||||
|
||||
# Display mail confirmation resent form
|
||||
elsif ( $req->error == PE_MAILCONFIRMATION_ALREADY_SENT ) {
|
||||
$self->lmLog('Display resend form','debug');
|
||||
$tplPrm{DISPLAY_RESEND_FORM} = 1;
|
||||
}
|
||||
|
||||
# Display confirmation mail sent
|
||||
elsif ( $req->error == PE_MAILCONFIRMOK ) {
|
||||
$self->lmLog('Display "confirm mail sent"','debug');
|
||||
$tplPrm{DISPLAY_CONFIRMMAILSENT} = 1;
|
||||
}
|
||||
|
||||
# Display mail sent
|
||||
elsif ( $req->error == PE_MAILOK ) {
|
||||
$self->lmLog('Display "mail sent"','debug');
|
||||
$tplPrm{DISPLAY_MAILSENT} = 1;
|
||||
}
|
||||
|
||||
# Display password change form
|
||||
elsif ( $req->datas->{mailToken}
|
||||
and $req->error != PE_MAILERROR
|
||||
and $req->error != PE_BADMAILTOKEN
|
||||
and $req->error != PE_MAILOK )
|
||||
{
|
||||
$self->lmLog('Display password form','debug');
|
||||
$tplPrm{DISPLAY_PASSWORD_FORM} = 1;
|
||||
}
|
||||
|
||||
# Custom template parameters
|
||||
if ( my $customParams = $self->p->getCustomTemplateParameters() ) {
|
||||
foreach ( keys %$customParams ) {
|
||||
$tplPrm{$_} = $customParams->{$_};
|
||||
}
|
||||
}
|
||||
return 'mail', \%tplPrm;
|
||||
}
|
||||
|
||||
1;
|
||||
|
|
|
@ -13,24 +13,29 @@ extends 'Lemonldap::NG::Common::Module';
|
|||
|
||||
our $VERSION = '2.0.0';
|
||||
|
||||
# Sample accounts from Doctor Who characters
|
||||
has demoAccounts => (is=>'rw',default=>sub{{
|
||||
'rtyler' => {
|
||||
'uid' => 'rtyler',
|
||||
'cn' => 'Rose Tyler',
|
||||
'mail' => 'rtyler@badwolf.org',
|
||||
},
|
||||
'msmith' => {
|
||||
'uid' => 'msmith',
|
||||
'cn' => 'Mickey Smith',
|
||||
'mail' => 'msmith@badwolf.org',
|
||||
},
|
||||
'dwho' => {
|
||||
'uid' => 'dwho',
|
||||
'cn' => 'Doctor Who',
|
||||
'mail' => 'dwho@badwolf.org',
|
||||
},
|
||||
}});
|
||||
# Sample accounts from Doctor Who characters
|
||||
has demoAccounts => (
|
||||
is => 'rw',
|
||||
default => sub {
|
||||
{
|
||||
'rtyler' => {
|
||||
'uid' => 'rtyler',
|
||||
'cn' => 'Rose Tyler',
|
||||
'mail' => 'rtyler@badwolf.org',
|
||||
},
|
||||
'msmith' => {
|
||||
'uid' => 'msmith',
|
||||
'cn' => 'Mickey Smith',
|
||||
'mail' => 'msmith@badwolf.org',
|
||||
},
|
||||
'dwho' => {
|
||||
'uid' => 'dwho',
|
||||
'cn' => 'Doctor Who',
|
||||
'mail' => 'dwho@badwolf.org',
|
||||
},
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
# INITIALIZATION
|
||||
|
||||
|
@ -63,7 +68,7 @@ sub getUser {
|
|||
if ( $req->{mail} ) {
|
||||
return PE_OK
|
||||
if (
|
||||
my $req->{user} =
|
||||
( $req->{user} ) =
|
||||
grep { $self->demoAccounts->{$_}->{mail} eq $req->{mail} }
|
||||
keys %{ $self->demoAccounts }
|
||||
);
|
||||
|
@ -81,8 +86,7 @@ sub setSessionInfo {
|
|||
my %vars = ( %{ $self->conf->{exportedVars} },
|
||||
%{ $self->conf->{demoExportedVars} } );
|
||||
while ( my ( $k, $v ) = each %vars ) {
|
||||
$req->{sessionInfo}->{$k} =
|
||||
$self->demoAccounts->{ $req->{user} }->{$v}
|
||||
$req->{sessionInfo}->{$k} = $self->demoAccounts->{ $req->{user} }->{$v}
|
||||
|| "";
|
||||
}
|
||||
|
||||
|
|
95
lemonldap-ng-portal/t/43-MailReset.t
Normal file
95
lemonldap-ng-portal/t/43-MailReset.t
Normal file
|
@ -0,0 +1,95 @@
|
|||
use Test::More;
|
||||
use strict;
|
||||
use IO::String;
|
||||
|
||||
BEGIN {
|
||||
require MIME::Lite;
|
||||
require 't/test-lib.pm';
|
||||
}
|
||||
|
||||
my ( $res, $user, $pwd );
|
||||
my $mailSend = 0;
|
||||
|
||||
my $mail2 = 0;
|
||||
|
||||
my $client = LLNG::Manager::Test->new(
|
||||
{
|
||||
ini => {
|
||||
logLevel => 'debug',
|
||||
useSafeJail => 1,
|
||||
portalDisplayRegister => 1,
|
||||
authentication => 'Demo',
|
||||
userDB => 'Demo',
|
||||
passwordDB => 'Demo',
|
||||
captcha_mail_enabled => 0,
|
||||
portalDisplayResetPassword => 1,
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
# Test form
|
||||
# ------------------------
|
||||
ok( $res = $client->_get( '/resetpwd', accept => 'text/html' ), 'Reset form', );
|
||||
count(1);
|
||||
my ( $host, $url, $query ) = expectForm( $res, '#', undef, 'mail' );
|
||||
|
||||
$query = 'mail=dwho%40badwolf.org';
|
||||
|
||||
# Post email
|
||||
ok(
|
||||
$res = $client->_post(
|
||||
'/resetpwd', IO::String->new($query),
|
||||
length => length($query),
|
||||
accept => 'text/html'
|
||||
),
|
||||
'Post email'
|
||||
);
|
||||
count(1);
|
||||
|
||||
# $query has been set by MIME::Lite::send
|
||||
ok(
|
||||
$res = $client->_get( '/resetpwd', query => $query, accept => 'text/html' ),
|
||||
'Post mail token'
|
||||
);
|
||||
count(1);
|
||||
( $host, $url, $query ) = expectForm( $res, '#', undef, 'mail_token' );
|
||||
ok($res->[2]->[0]=~/newpassword/s,' Ask for a new password');
|
||||
count(1);
|
||||
|
||||
#print STDERR Dumper($query);
|
||||
|
||||
clean_sessions();
|
||||
|
||||
done_testing( count() );
|
||||
|
||||
no warnings 'redefine';
|
||||
|
||||
sub MIME::Lite::send {
|
||||
my ($mail) = @_;
|
||||
pass('----- Mail given to MIME::Lite -----');
|
||||
ok( $mail->header_as_string =~ /dwho\@badwolf.org/s, 'Found dest' )
|
||||
or explain( $mail->header_as_string, 'To: dwho@badwolf.org' );
|
||||
count(2);
|
||||
unless ($mail2) {
|
||||
$mailSend = 1;
|
||||
ok(
|
||||
$mail->body_as_string =~
|
||||
m#a href="http://auth.example.com/resetpwd\?(.*?)"#,
|
||||
'Found link'
|
||||
);
|
||||
count(1);
|
||||
$query = $1;
|
||||
$mail2++;
|
||||
}
|
||||
else {
|
||||
$mailSend = 2;
|
||||
ok(
|
||||
$mail->body_as_string =~
|
||||
m#yourLoginIs.+?<b>(\w+)</b>.*?pwdIs.+?<b>(.*?)</b>#s,
|
||||
'Get login/pwd'
|
||||
);
|
||||
( $user, $pwd ) = ( $1, $2 );
|
||||
count(1);
|
||||
}
|
||||
}
|
||||
|
|
@ -21,7 +21,8 @@
|
|||
}
|
||||
},
|
||||
"exportedVars": {
|
||||
"UA": "HTTP_USER_AGENT"
|
||||
"mail": "mail",
|
||||
"cn": "cn"
|
||||
},
|
||||
"globalStorage": "Apache::Session::File",
|
||||
"globalStorageOptions": {
|
||||
|
|
Loading…
Reference in New Issue
Block a user