Index: main/plugin-web/plugin.xml
===================================================================
--- main/plugin-web/plugin.xml	(revision 40648)
+++ main/plugin-web/plugin.xml	(working copy)
@@ -214,8 +214,27 @@
         <single-extension-point id="org.ametys.runtime.plugins.core.userpref.DefaultUserPreferencesStorage.FO"
                                 class="org.ametys.runtime.plugins.core.userpref.DefaultUserPreferencesStorage"
                                 default-extension-id="org.ametys.runtime.plugins.core.userpref.JdbcXmlUserPreferencesStorage.FO"/>
+                                
+        <!-- User sign up configuration -->                        
+        <single-extension-point id="org.ametys.web.usermanagement.UserSignUpConfiguration"
+                                class="org.ametys.web.usermanagement.UserSignUpConfiguration"
+                                default-extension-id="org.ametys.web.usermanagement.DefaultUserSignUpConfiguration"/>
     </extension-points>
     
+    <feature name="user.signup.configuration">
+        <extensions>
+            <extension point="org.ametys.web.usermanagement.UserSignUpConfiguration" 
+                       id="org.ametys.web.usermanagement.DefaultUserSignUpConfiguration" 
+                       class="org.ametys.web.usermanagement.DefaultUserSignUpConfiguration">
+                   <token-validity>15</token-validity>
+                   <signup-email-subject>PLUGINS_WEB_USER_SIGNUP_CONFIRM_MAIL_SUBJECT</signup-email-subject>
+                   <signup-email-text-body>PLUGINS_WEB_USER_SIGNUP_CONFIRM_MAIL_BODY</signup-email-text-body>
+                   <reset-pwd-email-subject>PLUGINS_WEB_USER_RESET_PASSWORD_CONFIRM_MAIL_SUBJECT</reset-pwd-email-subject>
+                   <reset-pwd-email-text-body>PLUGINS_WEB_USER_RESET_PASSWORD_CONFIRM_MAIL_BODY</reset-pwd-email-text-body>
+            </extension>
+        </extensions>
+    </feature>
+    
     <feature name="rights.context.prefix">
         <extensions>
             <extension point="org.ametys.runtime.right.RightsContextPrefixExtensionPoint"
Index: main/plugin-web/src/org/ametys/web/usermanagement/DefaultUserSignUpConfiguration.java
===================================================================
--- main/plugin-web/src/org/ametys/web/usermanagement/DefaultUserSignUpConfiguration.java	(revision 0)
+++ main/plugin-web/src/org/ametys/web/usermanagement/DefaultUserSignUpConfiguration.java	(revision 0)
@@ -0,0 +1,141 @@
+/*
+ *  Copyright 2016 Anyware Services
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.ametys.web.usermanagement;
+
+import java.util.Map;
+
+import org.apache.avalon.framework.configuration.Configurable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.service.Serviceable;
+import org.apache.commons.lang.StringUtils;
+
+import org.ametys.runtime.util.I18nUtils;
+import org.ametys.runtime.util.I18nizableText;
+
+/**
+ * The default user sign up configuration
+ */
+public class DefaultUserSignUpConfiguration implements UserSignUpConfiguration, Configurable, Serviceable
+{
+    private int _tokenValidity;
+    private String _subjectKeyForSignupEmail;
+    private String _textBodyKeyForSignupEmail;
+    private String _htmlBodyKeyForSignupEmail;
+    private String _subjectKeyForResetPwd;
+    private String _textBodyKeyForResetPwd;
+    private String _htmlBodyKeyForResetPwd;
+    
+    private I18nUtils _i18nUtils;
+    
+    @Override
+    public void service(ServiceManager manager) throws ServiceException
+    {
+        _i18nUtils = (I18nUtils) manager.lookup(I18nUtils.ROLE);        
+    }
+    
+    @Override
+    public void configure(Configuration configuration) throws ConfigurationException
+    {
+        _tokenValidity = Integer.parseInt(configuration.getChild("token-validity").getValue(null));
+        _subjectKeyForSignupEmail = configuration.getChild("signup-email-subject").getValue(null);
+        _textBodyKeyForSignupEmail = configuration.getChild("signup-email-text-body").getValue(null);
+        _htmlBodyKeyForSignupEmail = configuration.getChild("signup-email-html-body").getValue(null);
+        _subjectKeyForResetPwd = configuration.getChild("reset-pwd-email-subject").getValue(null);
+        _textBodyKeyForResetPwd = configuration.getChild("reset-pwd-email-text-body").getValue(null);
+        _htmlBodyKeyForResetPwd = configuration.getChild("reset-pwd-email-html-body").getValue(null);
+    }
+    
+    @Override
+    public int getTokenValidity()
+    {
+        return _tokenValidity;
+    }
+
+    @Override
+    public String getSubjectForSignUpEmail (Map<String, I18nizableText> defaultI18nParams , String language)
+    {
+        if (StringUtils.isNotBlank(_subjectKeyForSignupEmail))
+        {
+            I18nizableText i18nSubject = new I18nizableText("plugin.web", _subjectKeyForSignupEmail, defaultI18nParams);
+            return _i18nUtils.translate(i18nSubject, language);
+        }
+        
+        return null;
+    }
+
+    @Override
+    public String getTextBodyForSignUpEmail(Map<String, I18nizableText> defaultI18nParams, String language)
+    {
+        if (StringUtils.isNotBlank(_textBodyKeyForSignupEmail))
+        {
+            I18nizableText i18nSubject = new I18nizableText("plugin.web", _textBodyKeyForSignupEmail, defaultI18nParams);
+            return _i18nUtils.translate(i18nSubject, language);
+        }
+        
+        return null;
+    }
+
+    @Override
+    public String getHtmlBodyForSignUpEmail(Map<String, I18nizableText> defaultI18nParams, String language)
+    {
+        if (StringUtils.isNotBlank(_htmlBodyKeyForSignupEmail))
+        {
+            I18nizableText i18nSubject = new I18nizableText("plugin.web", _htmlBodyKeyForSignupEmail, defaultI18nParams);
+            return _i18nUtils.translate(i18nSubject, language);
+        }
+        
+        return null;
+    }
+    
+    @Override
+    public String getSubjectForResetPwdEmail(Map<String, I18nizableText> defaultI18nParams, String language)
+    {
+        if (StringUtils.isNotBlank(_subjectKeyForResetPwd))
+        {
+            I18nizableText i18nSubject = new I18nizableText("plugin.web", _subjectKeyForResetPwd, defaultI18nParams);
+            return _i18nUtils.translate(i18nSubject, language);
+        }
+        
+        return null;
+    }
+
+    @Override
+    public String getTextBodyForResetPwdEmail(Map<String, I18nizableText> defaultI18nParams, String language)
+    {
+        if (StringUtils.isNotBlank(_textBodyKeyForResetPwd))
+        {
+            I18nizableText i18nSubject = new I18nizableText("plugin.web", _textBodyKeyForResetPwd, defaultI18nParams);
+            return _i18nUtils.translate(i18nSubject, language);
+        }
+        
+        return null;
+    }
+
+    @Override
+    public String getHtmlBodyForResetPwdEmail(Map<String, I18nizableText> defaultI18nParams, String language)
+    {
+        if (StringUtils.isNotBlank(_htmlBodyKeyForResetPwd))
+        {
+            I18nizableText i18nSubject = new I18nizableText("plugin.web", _htmlBodyKeyForResetPwd, defaultI18nParams);
+            return _i18nUtils.translate(i18nSubject, language);
+        }
+        
+        return null;
+    }
+}
Index: main/plugin-web/src/org/ametys/web/usermanagement/UserSignUpConfiguration.java
===================================================================
--- main/plugin-web/src/org/ametys/web/usermanagement/UserSignUpConfiguration.java	(revision 0)
+++ main/plugin-web/src/org/ametys/web/usermanagement/UserSignUpConfiguration.java	(revision 0)
@@ -0,0 +1,131 @@
+/*
+ *  Copyright 2016 Anyware Services
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.ametys.web.usermanagement;
+
+import java.util.Map;
+
+import org.ametys.runtime.util.I18nizableText;
+
+/**
+ * Interface for user sign up configuration
+ */
+public interface UserSignUpConfiguration
+{
+    /** Constant for Avalon ROLE */
+    public static final String ROLE = UserSignUpConfiguration.class.getName();
+    
+    /**
+     * The token validity period, in days.
+     * @return the token validity period, in days.
+     */
+    public int getTokenValidity ();
+    
+    /**
+     * The email subject when user sign up.
+     * @param defaultI18nParams The default i18n parameters with :
+     * siteName the site name
+     * login the login
+     * email the mail
+     * fullName the full name
+     * token the token
+     * confirmUri the confirmation uri
+     * siteTitle the site title
+     * siteUrl the site url
+     * @param language the language
+     * @return the email subject when user sign up.
+     */
+    public String getSubjectForSignUpEmail (Map<String, I18nizableText> defaultI18nParams , String language);
+    
+    /**
+     * The email text body when user sign up.
+     * @param defaultI18nParams The default i18n parameters with :
+     * siteName the site name
+     * login the login
+     * email the mail
+     * fullName the full name
+     * token the token
+     * confirmUri the confirmation uri
+     * siteTitle the site title
+     * siteUrl the site url
+     * @param language the language
+     * @return the email text body when user sign up.
+     */
+    public String getTextBodyForSignUpEmail (Map<String, I18nizableText> defaultI18nParams , String language);
+    
+    /**
+     * The email html body when user sign up.
+     * @param defaultI18nParams The default i18n parameters with :
+     * siteName the site name
+     * login the login
+     * email the mail
+     * fullName the full name
+     * token the token
+     * confirmUri the confirmation uri
+     * siteTitle the site title
+     * siteUrl the site url
+     * @param language the language
+     * @return the email html body when user sign up.
+     */
+    public String getHtmlBodyForSignUpEmail (Map<String, I18nizableText> defaultI18nParams , String language);
+    
+    /**
+     * The email subject when user reset password.
+     * @param defaultI18nParams The default i18n parameters with :
+     * siteName the site name
+     * login the login
+     * email the mail
+     * fullName the full name
+     * token the token
+     * confirmUri the confirmation uri
+     * siteTitle the site title
+     * siteUrl the site url 
+     * @param language the language
+     * @return the email subject when user reset password.
+     */
+    public String getSubjectForResetPwdEmail (Map<String, I18nizableText> defaultI18nParams , String language);
+    
+    /**
+     * The email text body when user reset password.
+     * @param defaultI18nParams The default i18n parameters with :
+     * siteName the site name
+     * login the login
+     * email the mail
+     * fullName the full name
+     * token the token
+     * confirmUri the confirmation uri
+     * siteTitle the site title
+     * siteUrl the site url 
+     * @param language the language
+     * @return the email text body when user reset password.
+     */
+    public String getTextBodyForResetPwdEmail (Map<String, I18nizableText> defaultI18nParams , String language);
+    
+    /**
+     * The email html body when user reset password.
+     * @param defaultI18nParams The default i18n parameters with :
+     * siteName the site name
+     * login the login
+     * email the mail
+     * fullName the full name
+     * token the token
+     * confirmUri the confirmation uri
+     * siteTitle the site title
+     * siteUrl the site url 
+     * @param language the language
+     * @return the email html body when user reset password.
+     */
+    public String getHtmlBodyForResetPwdEmail (Map<String, I18nizableText> defaultI18nParams , String language);
+}
Index: main/plugin-web/src/org/ametys/web/usermanagement/UserSignupManager.java
===================================================================
--- main/plugin-web/src/org/ametys/web/usermanagement/UserSignupManager.java	(revision 40648)
+++ main/plugin-web/src/org/ametys/web/usermanagement/UserSignupManager.java	(working copy)
@@ -93,9 +93,6 @@
     /** Lost password return code: the e-mail the user provided doesn't correspond to a user. */
     public static final int LOST_PASSWORD_USER_UNKNOWN = 5;
 
-    /** The token validity period, in days. */
-    public static final int TOKEN_VALIDITY_DAYS = 15;
-
     /** The front-office users manager. */
     protected UsersManager _foUsersManager;
 
@@ -117,6 +114,9 @@
     /** The i18n utils. */
     protected I18nUtils _i18nUtils;
 
+    /** The user sign up configuration */
+    protected UserSignUpConfiguration _userSignUpConfiguration;
+    
     /** The database pool. */
     protected String _pool;
 
@@ -135,6 +135,7 @@
         _resolver = (AmetysObjectResolver) serviceManager.lookup(AmetysObjectResolver.ROLE);
         _uriResolverEP = (URIResolverExtensionPoint) serviceManager.lookup(URIResolverExtensionPoint.ROLE);
         _i18nUtils = (I18nUtils) serviceManager.lookup(I18nUtils.ROLE);
+        _userSignUpConfiguration = (UserSignUpConfiguration) serviceManager.lookup(UserSignUpConfiguration.ROLE);
     }
 
     @Override
@@ -615,7 +616,7 @@
             long subscriptionTime = rs.getTimestamp("subscription_date").getTime();
 
             // The validity limit
-            DateTime limit = new DateTime().withMillisOfDay(0).minusDays(TOKEN_VALIDITY_DAYS);
+            DateTime limit = new DateTime().withMillisOfDay(0).minusDays(_userSignUpConfiguration.getTokenValidity());
             DateTime subscriptionDate = new DateTime(subscriptionTime);
 
             if (subscriptionDate.isBefore(limit))
@@ -679,7 +680,7 @@
             long requestTime = rs.getTimestamp("request_date").getTime();
 
             // Check the validity.
-            DateTime limit = new DateTime().withMillisOfDay(0).minusDays(TOKEN_VALIDITY_DAYS);
+            DateTime limit = new DateTime().withMillisOfDay(0).minusDays(_userSignUpConfiguration.getTokenValidity());
             DateTime requestDate = new DateTime(requestTime);
 
             if (requestDate.isBefore(limit))
@@ -719,7 +720,7 @@
             sql.append("DELETE FROM ").append(_tempUsersTable);
             sql.append(" WHERE subscription_date < ?");
 
-            DateTime limit = new DateTime().withMillisOfDay(0).minusDays(TOKEN_VALIDITY_DAYS);
+            DateTime limit = new DateTime().withMillisOfDay(0).minusDays(_userSignUpConfiguration.getTokenValidity());
             Timestamp limitTimestamp = new Timestamp(limit.getMillis());
 
             stmt = conn.prepareStatement(sql.toString());
@@ -757,7 +758,7 @@
             sql.append("DELETE FROM ").append(_pwdChangeTable);
             sql.append(" WHERE request_date < ?");
 
-            DateTime limit = new DateTime().withMillisOfDay(0).minusDays(TOKEN_VALIDITY_DAYS);
+            DateTime limit = new DateTime().withMillisOfDay(0).minusDays(_userSignUpConfiguration.getTokenValidity());
             Timestamp limitTimestamp = new Timestamp(limit.getMillis());
 
             stmt = conn.prepareStatement(sql.toString());
@@ -917,17 +918,14 @@
             i18nParams.put("siteUrl", new I18nizableText(site.getUrl()));
         }
 
-        // Resolve the mail subject and body in the given language.
-        I18nizableText i18nSubject = new I18nizableText("plugin.web", "PLUGINS_WEB_USER_SIGNUP_CONFIRM_MAIL_SUBJECT", i18nParams);
-        String subject = _i18nUtils.translate(i18nSubject, language);
-
-        I18nizableText i18nBody = new I18nizableText("plugin.web", "PLUGINS_WEB_USER_SIGNUP_CONFIRM_MAIL_BODY", i18nParams);
-        String body = _i18nUtils.translate(i18nBody, language);
+        String subject = _userSignUpConfiguration.getSubjectForSignUpEmail(i18nParams, language);
+        String textBody = _userSignUpConfiguration.getTextBodyForSignUpEmail(i18nParams, language);
+        String htmlBody = _userSignUpConfiguration.getHtmlBodyForSignUpEmail(i18nParams, language);
 
         try
         {
             // Send the e-mail.
-            SendMailHelper.sendMail(subject, null, body, email, from);
+            SendMailHelper.sendMail(subject, htmlBody, textBody, email, from);
         }
         catch (MessagingException e)
         {
@@ -1290,17 +1288,14 @@
             i18nParams.put("siteUrl", new I18nizableText(site.getUrl()));
         }
 
-        // Resolve the mail subject and body in the given language.
-        I18nizableText i18nSubject = new I18nizableText("plugin.web", "PLUGINS_WEB_USER_RESET_PASSWORD_CONFIRM_MAIL_SUBJECT", i18nParams);
-        String subject = _i18nUtils.translate(i18nSubject, language);
-
-        I18nizableText i18nBody = new I18nizableText("plugin.web", "PLUGINS_WEB_USER_RESET_PASSWORD_CONFIRM_MAIL_BODY", i18nParams);
-        String body = _i18nUtils.translate(i18nBody, language);
+        String subject = _userSignUpConfiguration.getSubjectForResetPwdEmail(i18nParams, language);
+        String textBody = _userSignUpConfiguration.getTextBodyForResetPwdEmail(i18nParams, language);
+        String htmlBody = _userSignUpConfiguration.getHtmlBodyForResetPwdEmail(i18nParams, language);
 
         try
         {
             // Send the e-mail.
-            SendMailHelper.sendMail(subject, null, body, user.getEmail(), from);
+            SendMailHelper.sendMail(subject, htmlBody, textBody, user.getEmail(), from);
         }
         catch (MessagingException e)
         {
