Possibility to change the password on the portal after password reset confirmation (#302)

This commit is contained in:
Clément Oudot 2011-05-30 15:45:56 +00:00
parent 068dd9d46f
commit 4152643ddd
5 changed files with 160 additions and 14 deletions

View File

@ -33,20 +33,40 @@ $template->param(
? ""
: $portal->{mail}
);
$template->param(
MAIL_TOKEN => $portal->checkXSSAttack( 'mail_token', $portal->{mail_token} )
? ""
: $portal->{mail_token}
);
# Display form the first time
if ( $portal->{error} == PE_MAILFORMEMPTY
or ( $portal->{error} == PE_BADCREDENTIALS and !$portal->{mail_token} ) )
if (
(
$portal->{error} == PE_MAILFORMEMPTY
or $portal->{error} == PE_BADCREDENTIALS
)
and !$portal->{mail_token}
)
{
$template->param( DISPLAY_FORM => 1 );
$template->param( DISPLAY_RESEND_FORM => 0 );
$template->param( DISPLAY_FORM => 1 );
$template->param( DISPLAY_RESEND_FORM => 0 );
$template->param( DISPLAY_PASSWORD_FORM => 0 );
}
# Display mail confirmation resent form
if ( $portal->{error} == PE_MAILCONFIRMATION_ALREADY_SENT ) {
$template->param( DISPLAY_FORM => 0 );
$template->param( DISPLAY_RESEND_FORM => 1 );
$template->param( DISPLAY_FORM => 0 );
$template->param( DISPLAY_RESEND_FORM => 1 );
$template->param( DISPLAY_PASSWORD_FORM => 0 );
}
if ( $portal->{mail_token}
and ( $portal->{error} != PE_MAILERROR and $portal->{error} != PE_MAILOK ) )
{
$template->param( DISPLAY_FORM => 0 );
$template->param( DISPLAY_RESEND_FORM => 0 );
$template->param( DISPLAY_PASSWORD_FORM => 1 );
}
print $portal->header('text/html; charset=utf8');

View File

@ -56,6 +56,34 @@
</form>
</TMPL_IF>
<TMPL_IF NAME="DISPLAY_PASSWORD_FORM">
<form action="#" method="post" class="password">
<input type="hidden" id="authKey" name="<TMPL_VAR NAME="CHOICE_PARAM">" value="<TMPL_VAR NAME="CHOICE_VALUE">" />
<input type="hidden" id="mail_token" name="mail_token" value="<TMPL_VAR NAME="MAIL_TOKEN">" />
<div id="content-all-info">
<table>
<tr><th><lang en="New password" fr="Nouveau mot de passe" /></th>
<td><input name="newpassword" type="password" tabindex="3" /></td></tr>
<tr><th><lang en="Confirm password" fr="Confirmez le mot de passe" /></th>
<td><input name="confirmpassword" type="password" tabindex="4" /></td></tr>
<tr><td colspan="2">
<input id="reset" type="checkbox" name="reset" />
<lang en="Generate the password automatically" fr="Générer le mot de passe automatiquement" />
</td></tr>
<tr><td colspan="2">
<div class="buttons">
<button type="reset" class="negative" tabindex="6">
<lang en="Cancel" fr="Annuler" />
</button>
<button type="submit" class="positive" tabindex="5">
<lang en="Submit" fr="Soumettre" />
</button>
</div>
</td></tr></table>
</div>
</form>
</TMPL_IF>
<div class="panel-buttons">
<button type="button" class="positive" tabindex="1" onclick="location.href='<TMPL_VAR NAME="PORTAL_URL">';return false;">
<lang en="Go to portal" fr="Aller au portail" />

View File

@ -55,6 +55,37 @@
</form>
</TMPL_IF>
<TMPL_IF NAME="DISPLAY_PASSWORD_FORM">
<div id="password">
<form action="#" method="post" class="password">
<input type="hidden" id="authKey" name="<TMPL_VAR NAME="CHOICE_PARAM">" value="<TMPL_VAR NAME="CHOICE_VALUE">" />
<input type="hidden" id="mail_token" name="mail_token" value="<TMPL_VAR NAME="MAIL_TOKEN">" />
<h3><lang en="Change your password" fr="Changez votre mot de passe" /></h3>
<table>
<tr><th><lang en="New password" fr="Nouveau mot de passe" /></th>
<td><input name="newpassword" type="password" tabindex="3" /></td></tr>
<tr><th><lang en="Confirm password" fr="Confirmez le mot de passe" /></th>
<td><input name="confirmpassword" type="password" tabindex="4" /></td></tr>
<tr><td colspan="2">
<input id="reset" type="checkbox" name="reset" />
<lang en="Generate the password automatically" fr="Générer le mot de passe automatiquement" />
</td></tr>
<tr><td colspan="2">
<div class="buttons">
<button type="reset" class="negative" tabindex="6">
<img src="/skins/common/cancel.png" alt="" />
<lang en="Cancel" fr="Annuler" />
</button>
<button type="submit" class="positive" tabindex="5">
<img src="/skins/common/accept.png" alt="" />
<lang en="Submit" fr="Soumettre" />
</button>
</div>
</td></tr></table>
</form>
</div>
</TMPL_IF>
<div class="link">
<a href="<TMPL_VAR NAME="PORTAL_URL">">
<lang en="Go back to portal" fr="Retourner au portail" />

View File

@ -28,6 +28,7 @@ use Encode;
# - extractMailInfo
# - storeMailSession
# - sendConfirmationMail
# - changePassword
# - sendPasswordMail
# - portal core module:
# - setMacros
@ -39,7 +40,6 @@ use Encode;
# - setSessionInfo
# - passwordDB module:
# - passwordDBInit
# - resetPassword
# @return 1 if all is OK
sub process {
my ($self) = splice @_;
@ -50,7 +50,7 @@ sub process {
$self->{error} = $self->_subProcess(
qw(smtpInit userDBInit passwordDBInit extractMailInfo
getUser setSessionInfo setMacros setLocalGroups setGroups setPersistentSessionInfo
storeMailSession sendConfirmationMail resetPassword sendPasswordMail)
storeMailSession sendConfirmationMail changePassword sendPasswordMail)
);
return (
@ -87,7 +87,9 @@ sub extractMailInfo {
return PE_MAILFORMEMPTY
unless ( $self->param('mail') || $self->param('mail_token') );
$self->{mail_token} = $self->param('mail_token');
$self->{mail_token} = $self->param('mail_token');
$self->{newpassword} = $self->param('newpassword');
$self->{confirmpassword} = $self->param('confirmpassword');
# If a mail token is present, find the corresponding mail
if ( $self->{mail_token} ) {
@ -105,8 +107,8 @@ sub extractMailInfo {
'debug' );
}
# Mail token can be used only one time, delete the session
tied(%$h)->delete() if ref $h;
# Close session, it will be deleted after password change success
untie %$h;
return PE_BADMAILTOKEN unless ( $self->{mail} );
}
@ -225,6 +227,53 @@ sub sendConfirmationMail {
PE_MAILOK;
}
## @method int changePassword
# Change the password or generate a new password
# @return Lemonldap::NG::Portal constant
sub changePassword {
my ($self) = splice @_;
# Check if user wants to generate the new password
if ( $self->param('reset') ) {
$self->lmLog(
"Reset password request for " . $self->{sessionInfo}->{_user},
'debug' );
# Generate a complex password
my $password = $self->gen_password( $self->{randomPasswordRegexp} );
$self->lmLog( "Generated password: " . $password, 'debug' );
$self->{newpassword} = $password;
$self->{confirmpassword} = $password;
}
# Else a password is required
else {
return PE_FORMEMPTY
unless ( $self->{newpassword} && $self->{confirmpassword} );
}
# Modify the password
my $result = $self->modifyPassword( $self->param('reset') );
# Mail token can be used only one time, delete the session if all is ok
if ( $result == PE_PASSWORD_OK ) {
# Get the corresponding session
my $h = $self->getApacheSession( $self->{mail_token} );
# Delete it
tied(%$h)->delete() if ref $h;
# Force result to PE_OK to continue the process
$result = PE_OK;
}
return $result;
}
## @method int sendPasswordMail
# Send mail containing the new password
# @return Lemonldap::NG::Portal constant
@ -269,7 +318,7 @@ sub sendPasswordMail {
}
# Replace variables in body
my $password = $self->{reset_password};
my $password = $self->{newpassword};
$body =~ s/\$password/$password/g;
$body =~ s/\$(\w+)/decode("utf8",$self->{sessionInfo}->{$1})/ge;

View File

@ -30,11 +30,12 @@ sub passwordDBInit {
PE_OK;
}
## @apmethod int modifyPassword()
## @apmethod int modifyPassword(boolean reset)
# Modify the password by LDAP mechanism.
# @param reset Force pwdReset flag to TRUE
# @return Lemonldap::NG::Portal constant
sub modifyPassword {
my $self = shift;
my ($self,$reset) = splice @_;
# Exit method if no password change requested
return PE_OK unless ( $self->{newpassword} );
@ -63,6 +64,23 @@ sub modifyPassword {
$self->updateSession($infos)
if ( $self->{storePassword} and $code == PE_PASSWORD_OK );
return $code unless ( $code == PE_PASSWORD_OK );
# If Password Policy and reset asked, set the PwdReset flag
if ( $self->{ldapPpolicyControl} and $reset) {
my $result =
$self->ldap->modify( $self->{dn},
replace => { 'pwdReset' => 'TRUE' } );
unless ( $result->code == 0 ) {
$self->lmLog( "LDAP modify pwdReset error: " . $result->code,
'error' );
$code = PE_LDAPERROR;
}
$self->lmLog( "pwdReset set to TRUE", 'debug' );
}
return $code;
}