* Use HTML templates to send fancy reset password mail, with translations
* Send the new password by mail instead of diplaying it n the web page
* Remove the need to configure : the value is now set with help of {DOCUMENT_ROOT}
This commit is contained in:
Clément Oudot 2010-01-22 11:25:37 +00:00
parent f6c250207c
commit 3222021897
17 changed files with 148 additions and 55 deletions

View File

@ -310,8 +310,6 @@ install_portal_site: install_conf_dir
@cp -pR --remove-destination ${SRCPORTALDIR}/example/error.pl ${RPORTALDIR}
@cp -pR --remove-destination ${SRCPORTALDIR}/example/mail.pl ${RPORTALDIR}
@cp -pR --remove-destination ${SRCPORTALDIR}/example/apps ${RPORTALDIR}
@$(PERL) -i -pe 's#__SKINDIR__#$(PORTALDIR)/skins#; \
s#__APPSXMLFILE__#$(CONFDIR)/apps-list.xml#;' ${RPORTALDIR}/index.pl ${RPORTALDIR}/error.pl ${RPORTALDIR}/mail.pl
@cp -pR --remove-destination ${SRCPORTALDIR}/example/skins/* $(RPORTALSKINSDIR)
@if [ "$(PORTALDIR)/skins/" != "$(PORTALSKINSDIR)/" ]; then \
for skin in $$(ls lemonldap-ng-portal/example/skins/); do \
@ -546,9 +544,9 @@ debian-diff:
@for i in $(PORTALSKINS); do \
$(DIFF) -x 'jquery*' lemonldap-ng-portal/example/skins/$$i /usr/share/lemonldap-ng/portal-skins/$$i; \
done ||true
@$(DIFF) -I '$$skin_dir' -I '$$appsxmlfile' lemonldap-ng-portal/example/index_skin.pl /var/lib/lemonldap-ng/portal/index.pl ||true
@$(DIFF) -I '$$skin_dir' lemonldap-ng-portal/example/error.pl /var/lib/lemonldap-ng/portal/error.pl ||true
@$(DIFF) -I '$$skin_dir' lemonldap-ng-portal/example/mail.pl /var/lib/lemonldap-ng/portal/mail.pl ||true
@$(DIFF) lemonldap-ng-portal/example/index_skin.pl /var/lib/lemonldap-ng/portal/index.pl ||true
@$(DIFF) lemonldap-ng-portal/example/error.pl /var/lib/lemonldap-ng/portal/error.pl ||true
@$(DIFF) lemonldap-ng-portal/example/mail.pl /var/lib/lemonldap-ng/portal/mail.pl ||true
@# Handler
@$(DIFF) lemonldap-ng-handler/lib/Lemonldap/NG/Handler /usr/share/perl5/Lemonldap/NG/Handler ||true
@# Common
@ -570,9 +568,9 @@ default-diff:
@$(DIFF) lemonldap-ng-portal/example/scripts/purgeCentralCache $(LMPREFIX)/bin/purgeCentralCache ||true
@$(DIFF) lemonldap-ng-portal/example/scripts/buildPortalWSDL $(LMPREFIX)/bin/buildPortalWSDL ||true
@$(DIFF) lemonldap-ng-portal/example/skins $(LMPREFIX)/htdocs/portal/skins ||true
@$(DIFF) -I '$$skin_dir' -I '$$appsxmlfile' lemonldap-ng-portal/example/index_skin.pl $(LMPREFIX)/htdocs/portal/index.pl ||true
@$(DIFF) -I '$$skin_dir' lemonldap-ng-portal/example/error.pl $(LMPREFIX)/htdocs/portal/error.pl ||true
@$(DIFF) -I '$$skin_dir' lemonldap-ng-portal/example/mail.pl $(LMPREFIX)/htdocs/portal/mail.pl ||true
@$(DIFF) lemonldap-ng-portal/example/index_skin.pl $(LMPREFIX)/htdocs/portal/index.pl ||true
@$(DIFF) lemonldap-ng-portal/example/error.pl $(LMPREFIX)/htdocs/portal/error.pl ||true
@$(DIFF) lemonldap-ng-portal/example/mail.pl $(LMPREFIX)/htdocs/portal/mail.pl ||true
@# Handler
@$(DIFF) lemonldap-ng-handler/lib/Lemonldap/NG/Handler /usr/local/share/perl/5.10.0/Lemonldap/NG/Handler ||true
@$(DIFF) lemonldap-ng-handler/example/MyHandler.pm $(LMPREFIX)/handler/MyHandler.pm ||true

View File

@ -1,8 +1,6 @@
#!/usr/bin/perl
use HTML::Template;
my $skin_dir = "__SKINDIR__";
my $portal = Lemonldap::NG::Portal::SharedConf->new(
# PORTAL CUSTOMIZATION
@ -11,6 +9,7 @@ my $portal = Lemonldap::NG::Portal::SharedConf->new(
);
my $skin = $portal->{portalSkin};
my $skin_dir = $ENV{DOCUMENT_ROOT} . "skins";
my $portal_url = $portal->{portal};
my $logout_url = "$portal_url?logout=1";

View File

@ -4,11 +4,6 @@ use Lemonldap::NG::Portal::SharedConf;
use HTML::Template;
use strict;
# Menu configuration
my $skin_dir = "__SKINDIR__";
my $appsxmlfile = "__APPSXMLFILE__";
my $appsimgpath = "apps/";
my $portal = Lemonldap::NG::Portal::SharedConf->new(
{
@ -149,7 +144,7 @@ my $portal = Lemonldap::NG::Portal::SharedConf->new(
# Get skin value
my $skin = $portal->{portalSkin};
my $skin_dir = $ENV{DOCUMENT_ROOT} . "skins";
my ( $skinfile, %templateParams );
####################
@ -180,10 +175,6 @@ if ( $portal->process() ) {
my $menu = Lemonldap::NG::Portal::Menu->new(
{
portalObject => $portal,
apps => {
xmlfile => "$appsxmlfile",
imgpath => "$appsimgpath",
},
modules => {
appslist => $portal->{portalDisplayAppslist},
password => $portal->{portalDisplayChangePassword},

View File

@ -4,12 +4,11 @@ use Lemonldap::NG::Portal::MailReset;
use HTML::Template;
use strict;
my $skin_dir = "__SKINDIR__";
# Load portal module
my $portal = Lemonldap::NG::Portal::MailReset->new();
my $skin = $portal->{portalSkin};
my $skin_dir = $ENV{DOCUMENT_ROOT} . "skins";
my $portal_url = $portal->{portal};
# Process
@ -33,10 +32,6 @@ $template->param( DISPLAY_FORM => 1 )
if ( $portal->{error} == PE_MAILFORMEMPTY
or ( $portal->{error} == PE_BADCREDENTIALS and !$portal->{mail_token} ) );
# Display password if change is OK
$template->param( NEW_PASSWORD => $portal->{reset_password} )
if ( $portal->{error} == PE_PASSWORD_OK );
print $portal->header('text/html; charset=utf8');
print $template->output;

View File

@ -0,0 +1,11 @@
<TMPL_INCLUDE NAME="mail_header.tpl">
<p>
<lang en="Hello" fr="Bonjour" />,<br />
<br />
<a href="$url" style="text-decoration:none;color:orange;">
<lang en="Click here to reset your password" fr="Cliquez ici pour r&eacute;initialiser votre mot de passe" />
</a>
</p>
<TMPL_INCLUDE NAME="mail_footer.tpl">

View File

@ -0,0 +1,11 @@
</div>
<div id="footer" style="font-size:9pt;">
<p>
<lang en="This mail was sent automatically" fr="Ceci est un message automatique" /><br />
<lang en="The reset password request was issued from IP" fr="La demande de changement de mot de passe provient de l'IP" />
$ipAddr
</p>
</div>
</div>

View File

@ -0,0 +1,17 @@
<div id="page" style="background:#000;font-family:sans-serif;font-size:12pt;color:#fff;padding:5px 20px;">
<div id="header">
<table>
<tr>
<td style="width:30px;height:30px;background:orange;">&nbsp;</td>
<td>&nbsp;</td>
<td rowspan=2 style="font-size:20pt;padding:5px 20px;color:#fff">LemonLDAP::NG</td>
</tr>
</tr>
<td>&nbsp;</td>
<td style="width:30px;height:30px;background:orange;">&nbsp;</td>
</tr>
</table>
</div>
<div id="content" style="color:#000;background:#eee;padding:5px 10px;margin:10px 0;">

View File

@ -0,0 +1,9 @@
<TMPL_INCLUDE NAME="mail_header.tpl">
<p>
<lang en="Hello" fr="Bonjour" />,<br />
<br />
<lang en="Your new password is" fr="Votre nouveau mot de passe est" /> $password
</p>
<TMPL_INCLUDE NAME="mail_footer.tpl">

View File

@ -27,11 +27,6 @@
</TMPL_IF>
<div class="link">
<TMPL_IF NAME="NEW_PASSWORD">
<h3><lang en="Your new password is" fr="Votre nouveau mot de passe est"/> <TMPL_VAR NAME="NEW_PASSWORD"></h3>
</TMPL_IF>
<a href="<TMPL_VAR NAME="PORTAL_URL">">
<lang en="Go back to portal" fr="Retourner au portail" />
</a>

View File

@ -20,7 +20,7 @@ margin:20px;
}
a img,:link img,:visited img {
border:none
border:none;
}
a, a:link, a:visited {

View File

@ -12,6 +12,7 @@ our $VERSION = '0.1';
use Lemonldap::NG::Portal::Simple qw(:all);
use base qw(Lemonldap::NG::Portal::SharedConf Exporter);
use HTML::Template;
*EXPORT_OK = *Lemonldap::NG::Portal::Simple::EXPORT_OK;
*EXPORT_TAGS = *Lemonldap::NG::Portal::Simple::EXPORT_TAGS;
@ -24,6 +25,7 @@ use base qw(Lemonldap::NG::Portal::SharedConf Exporter);
# - extractMailInfo
# - storeMailSession
# - sendConfirmationMail
# - sendPasswordMail
# - portal core module:
# - setMacros
# - setLocalGroups
@ -44,7 +46,7 @@ sub process {
$self->{error} = $self->_subProcess(
qw(smtpInit userDBInit passwordDBInit extractMailInfo
getUser setSessionInfo setMacros setLocalGroups setGroups
storeMailSession sendConfirmationMail resetPassword)
storeMailSession sendConfirmationMail resetPassword sendPasswordMail)
);
return (
(
@ -139,16 +141,71 @@ sub sendConfirmationMail {
# Build confirmation url
my $url = $self->{mailUrl} . "?mail_token=" . $self->{id};
# Replace variables in mail body
$self->{mailBody} =~ s/\$url/$url/g;
$self->{mailBody} =~ s/\$(\w+)/$self->{sessionInfo}->{$1}/g;
# Build mail content
my $subject = $self->{mailConfirmSubject};
my $body;
my $html;
if ( $self->{mailConfirmBody} ) {
# We use a specific text message, no html
$body = $self->{mailConfirmBody};
}
else {
# Use HTML template
my $template = HTML::Template->new(
filename => $ENV{DOCUMENT_ROOT} . "skins/common/mail_confirm.tpl",
filter => sub { $self->translate_template(@_) }
);
$body = $template->output();
$html = 1;
}
# Replace variables in body
$body =~ s/\$url/$url/g;
$body =~ s/\$(\w+)/$self->{sessionInfo}->{$1}/g;
# Send mail
return PE_MAILERROR unless $self->send_mail( $self->{mail} );
return PE_MAILERROR
unless $self->send_mail( $self->{mail}, $subject, $body, $html );
PE_MAILOK;
}
sub sendPasswordMail {
my ($self) = @_;
# Build mail content
my $subject = $self->{mailSubject};
my $body;
my $html;
if ( $self->{mailBody} ) {
# We use a specific text message, no html
$body = $self->{mailBody};
}
else {
# Use HTML template
my $template = HTML::Template->new(
filename => $ENV{DOCUMENT_ROOT} . "skins/common/mail_password.tpl",
filter => sub { $self->translate_template(@_) }
);
$body = $template->output();
$html = 1;
}
# Replace variables in body
my $password = $self->{reset_password};
$body =~ s/\$password/$password/g;
$body =~ s/\$(\w+)/$self->{sessionInfo}->{$1}/g;
# Send mail
return PE_MAILERROR
unless $self->send_mail( $self->{mail}, $subject, $body, $html );
PE_MAILOK;
}
1;
__END__

View File

@ -78,7 +78,6 @@ sub new {
#&Lemonldap::NG::Portal::Simple::getSessionInfo( $self->{portalObject} );
# Default values
$self->{apps}->{xmlfile} ||= 'apps-list.xml';
$self->{apps}->{imgpath} ||= 'apps/';
$self->{modules}->{appslist} = 0
unless defined $self->{modules}->{appslist};
@ -463,7 +462,7 @@ sub _isCategoryEmpty {
}
# Test this category
if ( $apphash->{type} eq "category" ) {
if ( $apphash->{type} and $apphash->{type} eq "category" ) {
# Temporary store 'options'
my $tmp_options = $apphash->{options};

View File

@ -108,10 +108,10 @@ sub resetPassword {
return PE_ERROR unless $result;
# Store password to display it to the user
# Store password to forward it to the user
$self->{reset_password} = $password;
PE_PASSWORD_OK;
PE_OK;
}
1;

View File

@ -106,10 +106,10 @@ sub resetPassword {
$self->lmLog( "pwdReset set to TRUE", 'debug' );
}
# Store password to display it to the user
# Store password to forward it to the user
$self->{reset_password} = $password;
PE_PASSWORD_OK;
PE_OK;
}
1;

View File

@ -270,6 +270,8 @@ sub getConf {
# Set default values.
sub setDefaultValues {
my $self = shift;
$self->{portal} ||=
"http" . ( $ENV{HTTPS} ? 's' : '' ) . '://' . $self->server_name();
$self->{whatToTrace} ||= 'uid';
$self->{whatToTrace} =~ s/^\$//;
$self->{httpOnly} = 1 unless ( defined( $self->{httpOnly} ) );
@ -296,8 +298,9 @@ sub setDefaultValues {
$self->{mailLDAPFilter} ||= '(&(mail=$mail)(objectClass=inetOrgPerson))';
$self->{randomPasswordRegexp} ||= '[A-Z]{3}[a-z]{5}.\d{2}';
$self->{mailFrom} ||= "noreply@" . $self->{domain};
$self->{mailSubject} ||= "[LemonLDAP::NG] Reset password confirmation";
$self->{mailBody} ||= 'Click here to reset your password: $url';
$self->{mailSubject} ||= "[LemonLDAP::NG] Your new password";
$self->{mailConfirmSubject} ||=
"[LemonLDAP::NG] Password reset confirmation";
$self->{mailSessionKey} ||= 'mail';
$self->{mailUrl} ||= $self->{portal} . "/mail.pl";
$self->{issuerDB} ||= 'Null';

View File

@ -25,24 +25,32 @@ sub gen_password {
## @method int send_mail()
# Send mail
# @param mail mail
# @param mail recipient address
# @param subject mail subject
# @param body mail body
# @param html optional set content type to HTML
# @return boolean result
sub send_mail {
my $self = shift;
my $mail = shift;
my $subject = shift;
my $body = shift;
my $html = shift;
$self->lmLog( "SMTP From " . $self->{mailFrom}, 'debug' );
$self->lmLog( "SMTP To " . $mail, 'debug' );
$self->lmLog( "SMTP Subject " . $self->{mailSubject}, 'debug' );
$self->lmLog( "SMTP Body " . $self->{mailBody}, 'debug' );
$self->lmLog( "SMTP Subject " . $subject, 'debug' );
$self->lmLog( "SMTP Body " . $body, 'debug' );
$self->lmLog( "SMTP HTML flag " . ($html?"on":"off"), 'debug' );
eval {
my $message = MIME::Lite->new(
From => $self->{mailFrom},
To => $mail,
Subject => $self->{mailSubject},
Subject => $subject,
Type => "TEXT",
Data => $self->{mailBody},
Data => $body,
);
$message->attr("content-type" => "text/html; charset=utf-8") if $html;
$self->{SMTPServer}
? $message->send( "smtp", $self->{SMTPServer} )
: $message->send();

View File

@ -161,8 +161,8 @@ sub error_fr {
"Confirmation demandée",
"Veuillez saisir votre adresse mail",
"La clé de confirmation est invalide ou trop ancienne",
"L'envoi du mail de confirmation a échoué",
"Un mail de confirmation vient d'être envoyé",
"L'envoi du mail a échoué",
"Un mail vous a été envoyé",
];
}
@ -217,7 +217,7 @@ sub error_en {
'Please provide your mail address',
'Confirmation key is invalid or too old',
'An error occurs when sending mail',
'Confirmation mail has been sent',
'A mail has been sent',
];
}
@ -272,8 +272,8 @@ sub error_ro {
'Confirmare necesare',
'Vă rugăm să introduceţi adresa dvs. de e-mail',
'Cheie de confirmare este invalid sau prea veche',
'Trimiterea mail de confirmare nu a reuşit',
'Un e-mail de confirmare a fost trimis',
'Trimiterea mail nu a reuşit',
'Un e-mail a fost trimis',
];
}