View Javadoc
1   /*
2    * Copyright (c) 2002-2017, Mairie de Paris
3    * All rights reserved.
4    *
5    * Redistribution and use in source and binary forms, with or without
6    * modification, are permitted provided that the following conditions
7    * are met:
8    *
9    *  1. Redistributions of source code must retain the above copyright notice
10   *     and the following disclaimer.
11   *
12   *  2. Redistributions in binary form must reproduce the above copyright notice
13   *     and the following disclaimer in the documentation and/or other materials
14   *     provided with the distribution.
15   *
16   *  3. Neither the name of 'Mairie de Paris' nor 'Lutece' nor the names of its
17   *     contributors may be used to endorse or promote products derived from
18   *     this software without specific prior written permission.
19   *
20   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23   * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
24   * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25   * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26   * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27   * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28   * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30   * POSSIBILITY OF SUCH DAMAGE.
31   *
32   * License 1.0
33   */
34  package fr.paris.lutece.plugins.mylutece.modules.openiddatabase.authentication.web;
35  
36  import fr.paris.lutece.plugins.mylutece.modules.openiddatabase.authentication.business.OpenIdDatabaseUser;
37  import fr.paris.lutece.plugins.mylutece.modules.openiddatabase.authentication.business.OpenIdDatabaseUserHome;
38  import fr.paris.lutece.plugins.mylutece.modules.openiddatabase.authentication.business.PasswordRecoveryHome;
39  import fr.paris.lutece.plugins.mylutece.web.MyLuteceApp;
40  import fr.paris.lutece.portal.service.captcha.CaptchaSecurityService;
41  import fr.paris.lutece.portal.service.i18n.I18nService;
42  import fr.paris.lutece.portal.service.message.SiteMessage;
43  import fr.paris.lutece.portal.service.message.SiteMessageException;
44  import fr.paris.lutece.portal.service.message.SiteMessageService;
45  import fr.paris.lutece.portal.service.plugin.Plugin;
46  import fr.paris.lutece.portal.service.plugin.PluginService;
47  import fr.paris.lutece.portal.service.security.LuteceUser;
48  import fr.paris.lutece.portal.service.security.SecurityService;
49  import fr.paris.lutece.portal.service.security.UserNotSignedException;
50  import fr.paris.lutece.portal.service.template.AppTemplateService;
51  import fr.paris.lutece.portal.service.util.AppLogService;
52  import fr.paris.lutece.portal.service.util.AppPathService;
53  import fr.paris.lutece.portal.service.util.AppPropertiesService;
54  import fr.paris.lutece.portal.web.xpages.XPage;
55  import fr.paris.lutece.portal.web.xpages.XPageApplication;
56  import fr.paris.lutece.util.html.HtmlTemplate;
57  import fr.paris.lutece.util.string.StringUtil;
58  import fr.paris.lutece.util.url.UrlItem;
59  
60  import org.apache.log4j.Logger;
61  
62  import org.openid4java.consumer.ConsumerException;
63  import org.openid4java.consumer.ConsumerManager;
64  
65  import java.util.Collection;
66  import java.util.HashMap;
67  import java.util.Locale;
68  
69  import javax.servlet.http.HttpServletRequest;
70  
71  
72  /**
73   * This class provides the XPageApp that manage personalization features for Mylutece Database module
74   * : login, account management, ...
75   */
76  public class MyLuteceOpenIdDatabaseApp implements XPageApplication
77  {
78      private static final String PARAMETER_PAGE = "page";
79      private static final String PARAMETER_PAGE_VALUE = "openid";
80      private static final String PROPERTY_DATABASE_TYPE = "database";
81  
82      // Markers
83      private static final String MARK_USER = "user";
84      private static final String MARK_ROLES = "roles";
85      private static final String MARK_GROUPS = "groups";
86      private static final String MARK_PLUGIN_NAME = "plugin_name";
87      private static final String MARK_ERROR_CODE = "error_code";
88      private static final String MARK_ACTION_SUCCESSFUL = "action_successful";
89      private static final String MARK_EMAIL = "email";
90      private static final String MARK_ID_TOKEN = "id_token";
91  
92      // Markers
93      private static final String MARK_ERROR_MESSAGE = "error_message";
94      private static final String MARK_URL_DOLOGIN = "url_dologin";
95  
96      // Parameters
97      private static final String PARAMETER_ACTION = "action";
98      private static final String PARAMETER_OLD_PASSWORD = "old_password";
99      private static final String PARAMETER_NEW_PASSWORD = "new_password";
100     private static final String PARAMETER_CONFIRMATION_PASSWORD = "confirmation_password";
101     private static final String PARAMETER_PLUGIN_NAME = "plugin_name";
102     private static final String PARAMETER_ERROR_CODE = "error_code";
103     private static final String PARAMETER_EMAIL = "email";
104     private static final String PARAMETER_ACTION_SUCCESSFUL = "action_successful";
105     private static final String PARAMETER_LOGIN = "login";
106     private static final String PARAMETER_PASSWORD = "password";
107     private static final String PARAMETER_LAST_NAME = "last_name";
108     private static final String PARAMETER_FIRST_NAME = "first_name";
109     private static final String PARAMETER_ID_TOKEN = "id_token";
110 
111     //OpenId 
112     public static final String PARAMETER_ERROR = "error";
113 
114     // Actions
115     private static final String ACTION_CHANGE_PASSWORD = "changePassword";
116     private static final String ACTION_CHANGE_PASSWORD_LINK = "changePasswordLink";
117     private static final String ACTION_VIEW_ACCOUNT = "viewAccount";
118     private static final String ACTION_LOST_PASSWORD = "lostPassword";
119     private static final String ACTION_ACCESS_DENIED = "accessDenied";
120     private static final String ACTION_CREATE_ACCOUNT = "createAccount";
121     private static final String ACTION_LOGIN_OPENID = "loginOpenId";
122     private static final String ACTION_DETAILS_OPENID = "detailsOpenId";
123 
124     // Errors
125     private static final String ERROR_OLD_PASSWORD = "error_old_password";
126     private static final String ERROR_CONFIRMATION_PASSWORD = "error_confirmation_password";
127     private static final String ERROR_SAME_PASSWORD = "error_same_password";
128     private static final String ERROR_SYNTAX_EMAIL = "error_syntax_email";
129     private static final String ERROR_SENDING_EMAIL = "error_sending_email";
130     private static final String ERROR_UNKNOWN_EMAIL = "error_unknown_email";
131     private static final String ERROR_MANDATORY_FIELDS = "error_mandatory_fields";
132     private static final String ERROR_LOGIN_ALREADY_EXISTS = "error_login_already_exists";
133 
134     // Templates
135     private static final String TEMPLATE_LOST_PASSWORD_PAGE = "skin/plugins/mylutece/modules/openiddatabase/lost_password.html";
136     private static final String TEMPLATE_VIEW_ACCOUNT_PAGE = "skin/plugins/mylutece/modules/openiddatabase/view_account.html";
137     private static final String TEMPLATE_CHANGE_PASSWORD_PAGE = "skin/plugins/mylutece/modules/openiddatabase/change_password.html";
138     private static final String TEMPLATE_CHANGE_PASSWORD_PAGE_LINK = "skin/plugins/mylutece/modules/openiddatabase/change_password_link.html";
139     private static final String TEMPLATE_CREATE_ACCOUNT_PAGE = "skin/plugins/mylutece/modules/openiddatabase/create_account.html";
140     private static final String TEMPLATE_USER_CONFIRMATION = "skin/plugins/mylutece/modules/openiddatabase/user_confirmation.html";
141 
142     // Properties
143     private static final String PROPERTY_MYLUTECE_CHANGE_PASSWORD_URL = "mylutece-openiddatabase.url.changePassword.page";
144     private static final String PROPERTY_MYLUTECE_VIEW_ACCOUNT_URL = "mylutece-openiddatabase.url.viewAccount.page";
145     private static final String PROPERTY_MYLUTECE_CREATE_ACCOUNT_URL = "mylutece-openiddatabase.url.createAccount.page";
146     private static final String PROPERTY_MYLUTECE_LOST_PASSWORD_URL = "mylutece-openiddatabase.url.lostPassword.page";
147     private static final String PROPERTY_MYLUTECE_CHANGE_PASSWORD_LINK_URL = "mylutece-openiddatabase.url.changePasswordLink.page";
148     private static final String PROPERTY_MYLUTECE_ACCESS_DENIED_URL = "mylutece-openiddatabase.url.accessDenied.page";
149     private static final String PROPERTY_MYLUTECE_DEFAULT_REDIRECT_URL = "mylutece-openiddatabase.url.default.redirect";
150     private static final String PROPERTY_MYLUTECE_TEMPLATE_ACCESS_DENIED = "mylutece-openiddatabase.template.accessDenied";
151     private static final String PROPERTY_MYLUTECE_TEMPLATE_ACCESS_CONTROLED = "mylutece-openiddatabase.template.accessControled";
152     private static final String PROPERTY_MAIL_HOST = "mail.server";
153     private static final String PROPERTY_PORTAL_NAME = "lutece.name";
154     private static final String PROPERTY_NOREPLY_EMAIL = "mail.noreply.email";
155 
156     //OpenId
157     private static final String PROPERTY_PAGETITLE_LOGIN = "module.mylutece.openiddatabase.xpage.loginPageTitle"; //TODO Add in properties
158     private static final String PROPERTY_PATHLABEL_LOGIN = "module.mylutece.openiddatabase.xpage.loginPagePath"; //TODO Add in properties
159 
160     // i18n Properties
161     private static final String PROPERTY_CHANGE_PASSWORD_LABEL = "module.mylutece.openiddatabase.xpage.changePassword.label";
162     private static final String PROPERTY_CHANGE_PASSWORD_TITLE = "module.mylutece.openiddatabase.xpage.changePassword.title";
163     private static final String PROPERTY_VIEW_ACCOUNT_LABEL = "module.mylutece.openiddatabase.xpage.viewAccount.label";
164     private static final String PROPERTY_VIEW_ACCOUNT_TITLE = "module.mylutece.openiddatabase.xpage.viewAccount.title";
165     private static final String PROPERTY_LOST_PASSWORD_LABEL = "module.mylutece.openiddatabase.xpage.lostPassword.label";
166     private static final String PROPERTY_LOST_PASSWORD_TITLE = "module.mylutece.openiddatabase.xpage.lostPassword.title";
167     private static final String PROPERTY_CREATE_ACCOUNT_LABEL = "module.mylutece.openiddatabase.xpage.createAccount.label";
168     private static final String PROPERTY_CREATE_ACCOUNT_TITLE = "module.mylutece.openiddatabase.xpage.createAccount.title";
169     private static final String PROPERTY_ACCESS_DENIED_ERROR_MESSAGE = "module.mylutece.openiddatabase.siteMessage.access_denied.errorMessage";
170     private static final String PROPERTY_ACCESS_DENIED_TITLE_MESSAGE = "module.mylutece.openiddatabase.siteMessage.access_denied.title";
171     private static final String PROPERTY_LINK_EXPIRED_ERROR_MESSAGE = "module.mylutece.openiddatabase.siteMessage.link_expired.errorMessage";
172     private static final String PROPERTY_LINK_EXPIRED_TITLE_MESSAGE = "module.mylutece.openiddatabase.siteMessage.link_expired.title";
173     private static final String PLUGIN_NAME = "mylutece-openiddatabase";
174     private static final String JCAPTCHA_PLUGIN = "jcaptcha";
175 
176     // Templates Open Id
177     private static final String TEMPLATE_LOGIN_PAGE = "skin/plugins/mylutece/modules/openiddatabase/login_form.html";
178     private static final String MARK_CAPTCHA = "captcha";
179     private static final String MARK_IS_ACTIVE_CAPTCHA = "is_active_captcha";
180     private static final String ERROR_CAPTCHA = "error_captcha";
181     private static Logger _logger = Logger.getLogger( "openiddatabase" );
182     private static ConsumerManager _manager;
183 
184     //Captcha
185     private CaptchaSecurityService _captchaService = new CaptchaSecurityService(  );
186 
187     // private fields
188     private Plugin _plugin;
189     private Locale _locale;
190 
191     /**
192      *
193      * @param request The HTTP request
194      * @param plugin The plugin
195      */
196     public void init( HttpServletRequest request, Plugin plugin )
197     {
198         _locale = request.getLocale(  );
199         _plugin = plugin;
200 
201         // instantiate a ConsumerManager object
202         if ( _manager == null )
203         {
204             try
205             {
206                 _manager = new ConsumerManager(  );
207             }
208             catch ( ConsumerException e )
209             {
210                 AppLogService.error( "Error instantiating OpenID ConsumerManager : " + e.getMessage(  ), e );
211             }
212         }
213     }
214 
215     /**
216      *
217      * @param request The HTTP request
218      * @param nMode The mode (admin, ...)
219      * @param plugin The plugin
220      * @return The Xpage
221      * @throws UserNotSignedException if user not signed
222      * @throws SiteMessageException Occurs when a site message need to be displayed
223      */
224     public XPage getPage( HttpServletRequest request, int nMode, Plugin plugin )
225         throws UserNotSignedException, SiteMessageException
226     {
227         XPage page = new XPage(  );
228         String strAction = request.getParameter( PARAMETER_ACTION );
229         Locale locale = request.getLocale(  );
230         init( request, plugin );
231 
232         if ( ( strAction == null ) || strAction.equals( ACTION_LOGIN_OPENID ) )
233         {
234             return getLoginPage( page, request, locale );
235         }
236 
237         if ( strAction.equals( ACTION_DETAILS_OPENID ) )
238         {
239             return getUserConfirmation( page, request, locale );
240         }
241 
242         if ( strAction.equals( ACTION_CHANGE_PASSWORD ) )
243         {
244             page = getChangePasswordPage( page, request );
245         }
246         else if ( strAction.equals( ACTION_VIEW_ACCOUNT ) )
247         {
248             page = getViewAccountPage( page, request );
249         }
250         else if ( strAction.equals( ACTION_LOST_PASSWORD ) )
251         {
252             page = getLostPasswordPage( page, request );
253         }
254         else if ( strAction.equals( ACTION_CREATE_ACCOUNT ) )
255         {
256             page = getCreateAccountPage( page, request );
257         }
258         else if ( strAction.equals( ACTION_CHANGE_PASSWORD_LINK ) )
259         {
260             page = getChangePasswordLinkPage( page, request );
261         }
262 
263         if ( strAction.equals( ACTION_ACCESS_DENIED ) || ( page == null ) )
264         {
265             SiteMessageService.setMessage( request, PROPERTY_ACCESS_DENIED_ERROR_MESSAGE, null,
266                 PROPERTY_ACCESS_DENIED_TITLE_MESSAGE, null, null, SiteMessage.TYPE_STOP );
267         }
268         return page;
269     }
270 
271     /**
272      * Returns the NewAccount URL of the Authentication Service
273      * @return The URL
274      */
275     public static String getChangePasswordUrl(  )
276     {
277         return AppPropertiesService.getProperty( PROPERTY_MYLUTECE_CHANGE_PASSWORD_URL );
278     }
279 
280     /**
281      * Returns the Change password link
282      * @return The URL
283      */
284     public static String getChangePasswordLinkUrl(  )
285     {
286         return AppPropertiesService.getProperty( PROPERTY_MYLUTECE_CHANGE_PASSWORD_LINK_URL );
287     }
288 
289     /**
290      * Returns the ViewAccount URL of the Authentication Service
291      * @return The URL
292      */
293     public static String getViewAccountUrl(  )
294     {
295         return AppPropertiesService.getProperty( PROPERTY_MYLUTECE_VIEW_ACCOUNT_URL );
296     }
297 
298     /**
299      * Returns the createAccount URL of the Authentication Service
300      * @return The URL
301      */
302     public static String getNewAccountUrl(  )
303     {
304         return AppPropertiesService.getProperty( PROPERTY_MYLUTECE_CREATE_ACCOUNT_URL );
305     }
306 
307     /**
308      * Returns the Lost Password URL of the Authentication Service
309      * @return The URL
310      */
311     public static String getLostPasswordUrl(  )
312     {
313         return AppPropertiesService.getProperty( PROPERTY_MYLUTECE_LOST_PASSWORD_URL );
314     }
315 
316     /**
317      * Returns the Default redirect URL of the Authentication Service
318      * @return The URL
319      */
320     public static String getDefaultRedirectUrl(  )
321     {
322         return AppPropertiesService.getProperty( PROPERTY_MYLUTECE_DEFAULT_REDIRECT_URL );
323     }
324 
325     /**
326      * Returns the NewAccount URL of the Authentication Service
327      * @return The URL
328      */
329     public static String getAccessDeniedUrl(  )
330     {
331         return AppPropertiesService.getProperty( PROPERTY_MYLUTECE_ACCESS_DENIED_URL );
332     }
333 
334     /**
335      * This method is call by the JSP named DoMyLuteceLogout.jsp
336      * @param request The HTTP request
337      * @return The URL to forward depending of the result of the login.
338      */
339     public String doLogout( HttpServletRequest request )
340     {
341         SecurityService.getInstance(  ).logoutUser( request );
342 
343         return getDefaultRedirectUrl(  );
344     }
345 
346     /**
347      * Build the ViewAccount page
348      * @param page The XPage object to fill
349      * @param request The HTTP request
350      * @return The XPage object containing the page content
351      */
352     private XPage getViewAccountPage( XPage page, HttpServletRequest request )
353     {
354         HashMap<String, Object> model = new HashMap<String, Object>(  );
355         OpenIdDatabaseUser user = getRemoteUser( request );
356 
357         if ( user == null )
358         {
359             return null;
360         }
361 
362         LuteceUser luteceUser = SecurityService.getInstance(  ).getRegisteredUser( request );
363 
364         if ( luteceUser == null )
365         {
366             return null;
367         }
368 
369         model.put( MARK_USER, user );
370         model.put( MARK_ROLES, luteceUser.getRoles(  ) );
371         model.put( MARK_GROUPS, luteceUser.getGroups(  ) );
372 
373         HtmlTemplate t = AppTemplateService.getTemplate( TEMPLATE_VIEW_ACCOUNT_PAGE, _locale, model );
374         page.setContent( t.getHtml(  ) );
375         page.setPathLabel( I18nService.getLocalizedString( PROPERTY_VIEW_ACCOUNT_LABEL, _locale ) );
376         page.setTitle( I18nService.getLocalizedString( PROPERTY_VIEW_ACCOUNT_TITLE, _locale ) );
377 
378         return page;
379     }
380 
381     /**
382      * Build the createAccount page
383      * @param page The XPage object to fill
384      * @param request The HTTP request
385      * @return The XPage object containing the page content
386      */
387     private XPage getCreateAccountPage( XPage page, HttpServletRequest request )
388     {
389         HashMap<String, Object> model = new HashMap<String, Object>(  );
390         OpenIdDatabaseUser user = new OpenIdDatabaseUser(  );
391 
392         String strErrorCode = request.getParameter( PARAMETER_ERROR_CODE );
393         String strLogin = request.getParameter( PARAMETER_LOGIN );
394         String strLastName = request.getParameter( PARAMETER_LAST_NAME );
395         String strFirstName = request.getParameter( PARAMETER_FIRST_NAME );
396         String strEmail = request.getParameter( PARAMETER_EMAIL );
397         String strSuccess = request.getParameter( PARAMETER_ACTION_SUCCESSFUL );
398 
399         if ( strLogin != null )
400         {
401             user.setLogin( strLogin );
402         }
403 
404         if ( strLastName != null )
405         {
406             user.setLastName( strLastName );
407         }
408 
409         if ( strFirstName != null )
410         {
411             user.setFirstName( strFirstName );
412         }
413 
414         if ( strEmail != null )
415         {
416             user.setEmail( strEmail );
417         }
418 
419         model.put( MARK_PLUGIN_NAME, _plugin.getName(  ) );
420         model.put( MARK_ERROR_CODE, strErrorCode );
421         model.put( MARK_USER, user );
422         model.put( MARK_IS_ACTIVE_CAPTCHA, PluginService.isPluginEnable( JCAPTCHA_PLUGIN ) );
423         model.put( MARK_CAPTCHA, _captchaService.getHtmlCode(  ) );
424         model.put( MARK_ACTION_SUCCESSFUL, strSuccess );
425 
426         HtmlTemplate t = AppTemplateService.getTemplate( TEMPLATE_CREATE_ACCOUNT_PAGE, _locale, model );
427         page.setContent( t.getHtml(  ) );
428         page.setPathLabel( I18nService.getLocalizedString( PROPERTY_CREATE_ACCOUNT_LABEL, _locale ) );
429         page.setTitle( I18nService.getLocalizedString( PROPERTY_CREATE_ACCOUNT_TITLE, _locale ) );
430 
431         return page;
432     }
433 
434     /**
435      * This method is call by the JSP named DoCreateAccount.jsp
436      * @param request The HTTP request
437      * @return The URL to forward depending of the result of the change.
438      */
439     public String doCreateAccount( HttpServletRequest request )
440     {
441         Plugin plugin = PluginService.getPlugin( request.getParameter( PARAMETER_PLUGIN_NAME ) );
442         OpenIdDatabaseUser databaseUser = new OpenIdDatabaseUser(  );
443         init( request, plugin );
444 
445         UrlItem url = new UrlItem( AppPathService.getBaseUrl( request ) + getNewAccountUrl(  ) );
446         url.addParameter( PARAMETER_PLUGIN_NAME, _plugin.getName(  ) );
447 
448         String strError = null;
449         String strLogin = request.getParameter( PARAMETER_LOGIN );
450         String strPassword = request.getParameter( PARAMETER_PASSWORD );
451         String strConfirmation = request.getParameter( PARAMETER_CONFIRMATION_PASSWORD );
452         String strLastName = request.getParameter( PARAMETER_LAST_NAME );
453         String strFirstName = request.getParameter( PARAMETER_FIRST_NAME );
454         String strEmail = request.getParameter( PARAMETER_EMAIL );
455 
456         url.addParameter( PARAMETER_LOGIN, strLogin );
457         url.addParameter( PARAMETER_LAST_NAME, strLastName );
458         url.addParameter( PARAMETER_FIRST_NAME, strFirstName );
459         url.addParameter( PARAMETER_EMAIL, strEmail );
460 
461         if ( ( strLogin == null ) || ( strPassword == null ) || ( strConfirmation == null ) || ( strFirstName == null ) ||
462                 ( ( strEmail == null ) || ( strLastName == null ) || strLogin.equals( "" ) || strPassword.equals( "" ) ||
463                 strConfirmation.equals( "" ) || strLastName.equals( "" ) || strFirstName.equals( "" ) ) ||
464                 strEmail.equals( "" ) )
465         {
466             strError = ERROR_MANDATORY_FIELDS;
467         }
468 
469         //Check login unique code
470         if ( ( strError == null ) &&
471                 !OpenIdDatabaseUserHome.findDatabaseUsersListForLogin( strLogin, _plugin ).isEmpty(  ) )
472         {
473             strError = ERROR_LOGIN_ALREADY_EXISTS;
474         }
475 
476         //Check password confirmation
477         if ( ( strError == null ) && !checkPassword( strPassword, strConfirmation ) )
478         {
479             strError = ERROR_CONFIRMATION_PASSWORD;
480         }
481 
482         //Check email format
483         if ( ( strError == null ) && !StringUtil.checkEmail( strEmail ) )
484         {
485             strError = ERROR_SYNTAX_EMAIL;
486         }
487 
488         // test the captcha
489         if ( PluginService.isPluginEnable( JCAPTCHA_PLUGIN ) )
490         {
491             if ( !_captchaService.validate( request ) )
492             {
493                 strError = ERROR_CAPTCHA;
494             }
495         }
496 
497         if ( strError != null )
498         {
499             url.addParameter( PARAMETER_ERROR_CODE, strError );
500 
501             return url.getUrl(  );
502         }
503         else
504         {
505             databaseUser.setLogin( strLogin );
506             databaseUser.setLastName( strLastName );
507             databaseUser.setFirstName( strFirstName );
508             databaseUser.setEmail( strEmail );
509             databaseUser.setAuthentificationType( PROPERTY_DATABASE_TYPE );
510             OpenIdDatabaseUserHome.create( databaseUser, strPassword, _plugin );
511         }
512 
513         url.addParameter( PARAMETER_ACTION_SUCCESSFUL, getDefaultRedirectUrl(  ) );
514 
515         return url.getUrl(  );
516     }
517 
518     /**
519      * Build the default Lost password page
520      * @param page The XPage object to fill
521      * @param request The HTTP request
522      * @return The XPage object containing the page content
523      */
524     private XPage getLostPasswordPage( XPage page, HttpServletRequest request )
525     {
526         HashMap<String, Object> model = new HashMap<String, Object>(  );
527         String strErrorCode = request.getParameter( PARAMETER_ERROR_CODE );
528         String strStateSending = request.getParameter( PARAMETER_ACTION_SUCCESSFUL );
529         String strEmail = request.getParameter( PARAMETER_EMAIL );
530 
531         model.put( MARK_PLUGIN_NAME, _plugin.getName(  ) );
532         model.put( MARK_ERROR_CODE, strErrorCode );
533         model.put( MARK_ACTION_SUCCESSFUL, strStateSending );
534         model.put( MARK_EMAIL, strEmail );
535 
536         HtmlTemplate t = AppTemplateService.getTemplate( TEMPLATE_LOST_PASSWORD_PAGE, _locale, model );
537         page.setContent( t.getHtml(  ) );
538         page.setPathLabel( I18nService.getLocalizedString( PROPERTY_LOST_PASSWORD_LABEL, _locale ) );
539         page.setTitle( I18nService.getLocalizedString( PROPERTY_LOST_PASSWORD_TITLE, _locale ) );
540 
541         return page;
542     }
543 
544     /**
545      * Build the default Change password page
546      * @param page The XPage object to fill
547      * @param request The HTTP request
548      * @return The XPage object containing the page content
549      */
550     private XPage getChangePasswordLinkPage( XPage page, HttpServletRequest request )
551     {
552         HashMap<String, Object> model = new HashMap<String, Object>(  );
553         String strErrorCode = request.getParameter( PARAMETER_ERROR_CODE );
554         String strSuccess = request.getParameter( PARAMETER_ACTION_SUCCESSFUL );
555         String strToken = request.getParameter( PARAMETER_ID_TOKEN );
556 
557         model.put( MARK_PLUGIN_NAME, _plugin.getName(  ) );
558         model.put( MARK_ERROR_CODE, strErrorCode );
559         model.put( MARK_ACTION_SUCCESSFUL, strSuccess );
560         model.put( MARK_ID_TOKEN, strToken );
561 
562         HtmlTemplate t = AppTemplateService.getTemplate( TEMPLATE_CHANGE_PASSWORD_PAGE_LINK, _locale, model );
563         page.setContent( t.getHtml(  ) );
564         page.setPathLabel( I18nService.getLocalizedString( PROPERTY_CHANGE_PASSWORD_LABEL, _locale ) );
565         page.setTitle( I18nService.getLocalizedString( PROPERTY_CHANGE_PASSWORD_TITLE, _locale ) );
566 
567         return page;
568     }
569 
570     /**
571      * Build the default Change password page
572      * @param page The XPage object to fill
573      * @param request The HTTP request
574      * @return The XPage object containing the page content
575      */
576     private XPage getChangePasswordPage( XPage page, HttpServletRequest request )
577     {
578         HashMap<String, Object> model = new HashMap<String, Object>(  );
579         String strErrorCode = request.getParameter( PARAMETER_ERROR_CODE );
580         String strSuccess = request.getParameter( PARAMETER_ACTION_SUCCESSFUL );
581 
582         model.put( MARK_PLUGIN_NAME, _plugin.getName(  ) );
583         model.put( MARK_ERROR_CODE, strErrorCode );
584         model.put( MARK_ACTION_SUCCESSFUL, strSuccess );
585 
586         HtmlTemplate t = AppTemplateService.getTemplate( TEMPLATE_CHANGE_PASSWORD_PAGE, _locale, model );
587         page.setContent( t.getHtml(  ) );
588         page.setPathLabel( I18nService.getLocalizedString( PROPERTY_CHANGE_PASSWORD_LABEL, _locale ) );
589         page.setTitle( I18nService.getLocalizedString( PROPERTY_CHANGE_PASSWORD_TITLE, _locale ) );
590 
591         return page;
592     }
593 
594     /**
595      * This method is call by the JSP named DoChangePassword.jsp
596      * @param request The HTTP request
597      * @return The URL to forward depending of the result of the change.
598      */
599     public String doChangePassword( HttpServletRequest request )
600     {
601         Plugin plugin = PluginService.getPlugin( request.getParameter( PARAMETER_PLUGIN_NAME ) );
602         init( request, plugin );
603 
604         UrlItem url = new UrlItem( AppPathService.getBaseUrl( request ) + getChangePasswordUrl(  ) );
605         url.addParameter( PARAMETER_PLUGIN_NAME, _plugin.getName(  ) );
606 
607         String strError = null;
608         OpenIdDatabaseUser user = getRemoteUser( request );
609         String strOldPassword = request.getParameter( PARAMETER_OLD_PASSWORD );
610         String strNewPassword = request.getParameter( PARAMETER_NEW_PASSWORD );
611         String strConfirmationPassword = request.getParameter( PARAMETER_CONFIRMATION_PASSWORD );
612 
613         if ( user == null )
614         {
615             try
616             {
617                 SiteMessageService.setMessage( request, PROPERTY_ACCESS_DENIED_ERROR_MESSAGE, null,
618                     PROPERTY_ACCESS_DENIED_TITLE_MESSAGE, null, null, SiteMessage.TYPE_STOP );
619             }
620             catch ( SiteMessageException e )
621             {
622                 return AppPathService.getBaseUrl( request );
623             }
624         }
625 
626         if ( ( strOldPassword == null ) || ( strNewPassword == null ) || ( strConfirmationPassword == null ) ||
627                 strOldPassword.equals( "" ) || strNewPassword.equals( "" ) || strConfirmationPassword.equals( "" ) )
628         {
629             strError = ERROR_MANDATORY_FIELDS;
630         }
631 
632         if ( ( strError == null ) &&
633                 !OpenIdDatabaseUserHome.checkPassword( user.getLogin(  ), strOldPassword, _plugin ) )
634         {
635             strError = ERROR_OLD_PASSWORD;
636         }
637 
638         if ( ( strError == null ) && !checkPassword( strNewPassword, strConfirmationPassword ) )
639         {
640             strError = ERROR_CONFIRMATION_PASSWORD;
641         }
642 
643         if ( ( strError == null ) && strNewPassword.equals( strOldPassword ) )
644         {
645             strError = ERROR_SAME_PASSWORD;
646         }
647 
648         if ( strError != null )
649         {
650             url.addParameter( PARAMETER_ERROR_CODE, strError );
651         }
652         else
653         {
654             OpenIdDatabaseUserHome.updatePassword( user, strNewPassword, _plugin );
655             url.addParameter( PARAMETER_ACTION_SUCCESSFUL, getDefaultRedirectUrl(  ) );
656         }
657 
658         return url.getUrl(  );
659     }
660 
661     /**
662      * This method is call by the JSP named DoChangePassword.jsp
663      * @param request The HTTP request
664      * @return The URL to forward depending of the result of the change.
665      */
666     public String doChangePasswordLink( HttpServletRequest request )
667     {
668         Plugin plugin = PluginService.getPlugin( request.getParameter( PARAMETER_PLUGIN_NAME ) );
669         init( request, plugin );
670 
671         UrlItem url = new UrlItem( AppPathService.getBaseUrl( request ) + getChangePasswordUrl(  ) );
672         url.addParameter( PARAMETER_PLUGIN_NAME, _plugin.getName(  ) );
673 
674         String strError = null;
675 
676         String strIdToken = request.getParameter( PARAMETER_ID_TOKEN );
677         String strNewPassword = request.getParameter( PARAMETER_NEW_PASSWORD );
678         String strConfirmationPassword = request.getParameter( PARAMETER_CONFIRMATION_PASSWORD );
679         int nUserId = PasswordRecoveryHome.findUserId( strIdToken, plugin );
680 
681         OpenIdDatabaseUser user = OpenIdDatabaseUserHome.findByPrimaryKey( nUserId, plugin );
682 
683         if ( user == null )
684         {
685             try
686             {
687                 SiteMessageService.setMessage( request, PROPERTY_ACCESS_DENIED_ERROR_MESSAGE, null,
688                     PROPERTY_ACCESS_DENIED_TITLE_MESSAGE, null, null, SiteMessage.TYPE_STOP );
689             }
690             catch ( SiteMessageException e )
691             {
692                 return AppPathService.getBaseUrl( request );
693             }
694         }
695 
696         boolean bExpired = PasswordRecoveryHome.isExpired( strIdToken, plugin );
697 
698         if ( bExpired )
699         {
700             try
701             {
702                 SiteMessageService.setMessage( request, PROPERTY_LINK_EXPIRED_ERROR_MESSAGE, null,
703                     PROPERTY_LINK_EXPIRED_TITLE_MESSAGE, null, null, SiteMessage.TYPE_STOP );
704             }
705             catch ( SiteMessageException e )
706             {
707                 return AppPathService.getBaseUrl( request );
708             }
709         }
710 
711         if ( ( strNewPassword == null ) || ( strConfirmationPassword == null ) || strNewPassword.equals( "" ) ||
712                 strConfirmationPassword.equals( "" ) )
713         {
714             strError = ERROR_MANDATORY_FIELDS;
715         }
716 
717         if ( ( strError == null ) && !checkPassword( strNewPassword, strConfirmationPassword ) )
718         {
719             strError = ERROR_CONFIRMATION_PASSWORD;
720         }
721 
722         if ( strError != null )
723         {
724             url.addParameter( PARAMETER_ERROR_CODE, strError );
725         }
726         else
727         {
728             OpenIdDatabaseUserHome.updatePassword( user, strNewPassword, _plugin );
729             url.addParameter( PARAMETER_ACTION_SUCCESSFUL, getDefaultRedirectUrl(  ) );
730         }
731 
732         return url.getUrl(  );
733     }
734 
735     /**
736      * Check the password with the password confirmation string
737      * Check if password is empty
738      *
739      * @param strPassword The password
740      * @param strConfirmation The password confirmation
741      * @return true if password is equal to confirmation password and not empty
742      */
743     private boolean checkPassword( String strPassword, String strConfirmation )
744     {
745         Boolean bReturn = true;
746 
747         if ( ( strPassword == null ) || ( strConfirmation == null ) || strPassword.equals( "" ) ||
748                 !strPassword.equals( strConfirmation ) )
749         {
750             bReturn = false;
751         }
752 
753         return bReturn;
754     }
755 
756     /**
757      * This method is call by the JSP named DoSendPassword.jsp
758      * @param request The HTTP request
759      * @return The URL to forward depending of the result of the sending.
760      */
761     public String doSendPassword( HttpServletRequest request )
762     {
763         Plugin plugin = PluginService.getPlugin( request.getParameter( PARAMETER_PLUGIN_NAME ) );
764         init( request, plugin );
765 
766         HashMap<String, Object> model = new HashMap<String, Object>(  );
767         String strError = null;
768         UrlItem url = null;
769         OpenIdDatabaseUser user = null;
770 
771         String strEmail = request.getParameter( PARAMETER_EMAIL );
772         url = new UrlItem( AppPathService.getBaseUrl( request ) + getLostPasswordUrl(  ) );
773         url.addParameter( PARAMETER_PLUGIN_NAME, _plugin.getName(  ) );
774         url.addParameter( PARAMETER_EMAIL, strEmail );
775 
776         // Check mandatory fields
777         if ( ( strEmail == null ) || strEmail.equals( "" ) )
778         {
779             strError = ERROR_MANDATORY_FIELDS;
780         }
781 
782         // Check email format
783         if ( ( strError == null ) && !StringUtil.checkEmail( strEmail ) )
784         {
785             strError = ERROR_SYNTAX_EMAIL;
786         }
787 
788         user = OpenIdDatabaseUserHome.selectDatabaseUserByEmail( strEmail, _plugin );
789 
790         if ( ( strError == null ) && ( user == null ) )
791         {
792             strError = ERROR_UNKNOWN_EMAIL;
793         }
794 
795         if ( strError == null )
796         {
797             model.put( MARK_USER, user );
798 
799             String strHost = AppPropertiesService.getProperty( PROPERTY_MAIL_HOST );
800             String strName = AppPropertiesService.getProperty( PROPERTY_PORTAL_NAME );
801             String strSender = AppPropertiesService.getProperty( PROPERTY_NOREPLY_EMAIL );
802 
803             if ( ( strError == null ) && ( strHost.equals( "" ) || strName.equals( "" ) || strSender.equals( "" ) ) )
804             {
805                 strError = ERROR_SENDING_EMAIL;
806             }
807             else
808             {
809                 PasswordRecoveryHome.processOperations( user, _locale, plugin );
810             }
811         }
812 
813         else
814         {
815             url.addParameter( PARAMETER_ERROR_CODE, strError );
816 
817             return url.getUrl(  );
818         }
819 
820         url.addParameter( PARAMETER_ACTION_SUCCESSFUL, getDefaultRedirectUrl(  ) );
821 
822         return url.getUrl(  );
823     }
824 
825     /**
826      * Returns the template for access denied
827      * @return The template path
828      */
829     public static String getAccessDeniedTemplate(  )
830     {
831         return AppPropertiesService.getProperty( PROPERTY_MYLUTECE_TEMPLATE_ACCESS_DENIED );
832     }
833 
834     /**
835      * Returns the template for access controled
836      * @return The template path
837      */
838     public static String getAccessControledTemplate(  )
839     {
840         return AppPropertiesService.getProperty( PROPERTY_MYLUTECE_TEMPLATE_ACCESS_CONTROLED );
841     }
842 
843     /**
844      * Get the remote user
845      *
846      * @param request The HTTP request
847      * @return The Database User
848      */
849     private OpenIdDatabaseUser getRemoteUser( HttpServletRequest request )
850     {
851         LuteceUser luteceUser = SecurityService.getInstance(  ).getRegisteredUser( request );
852 
853         if ( luteceUser == null )
854         {
855             return null;
856         }
857 
858         Collection<OpenIdDatabaseUser> listUsers = OpenIdDatabaseUserHome.findDatabaseUsersListForLogin( luteceUser.getName(  ),
859                 _plugin );
860 
861         if ( listUsers.size(  ) != 1 )
862         {
863             return null;
864         }
865 
866         OpenIdDatabaseUser user = (OpenIdDatabaseUser) listUsers.iterator(  ).next(  );
867 
868         return user;
869     }
870 
871     /**
872     * Build the Login page
873     * @param page The XPage object to fill
874     * @param request The HTTP request
875     * @param locale The current locale
876     * @return The XPage object containing the page content
877     */
878     private XPage getLoginPage( XPage page, HttpServletRequest request, Locale locale )
879     {
880         HashMap<String, Object> model = new HashMap<String, Object>(  );
881 
882         String strError = request.getParameter( PARAMETER_ERROR );
883         String strErrorMessage = "";
884 
885         if ( strError != null )
886         {
887             strErrorMessage = I18nService.getLocalizedString( strError, locale );
888         }
889 
890         model.put( MARK_ERROR_MESSAGE, strErrorMessage );
891         model.put( MARK_URL_DOLOGIN, MyLuteceApp.getDoLoginUrl(  ) );
892 
893         HtmlTemplate template = AppTemplateService.getTemplate( TEMPLATE_LOGIN_PAGE, locale, model );
894 
895         page.setContent( template.getHtml(  ) );
896         page.setTitle( I18nService.getLocalizedString( PROPERTY_PAGETITLE_LOGIN, locale ) );
897         page.setPathLabel( I18nService.getLocalizedString( PROPERTY_PATHLABEL_LOGIN, locale ) );
898 
899         return page;
900     }
901 
902     /**
903      * Build the user confirmation page
904      * @param page The XPage object to fill
905      * @param request The HTTP request
906      * @param locale The current locale
907      * @return The XPage object containing the page content
908      */
909     private XPage getUserConfirmation( XPage page, HttpServletRequest request, Locale locale )
910     {
911         HashMap<String, Object> model = new HashMap<String, Object>(  );
912 
913         String strError = request.getParameter( PARAMETER_ERROR );
914         String strErrorMessage = "";
915 
916         if ( strError != null )
917         {
918             strErrorMessage = I18nService.getLocalizedString( strError, locale );
919         }
920 
921         String strEmail = request.getParameter( PARAMETER_EMAIL );
922         String strFirstName = request.getParameter( PARAMETER_FIRST_NAME );
923         String strLastName = request.getParameter( PARAMETER_LAST_NAME );
924         String strLogin = request.getParameter( PARAMETER_LOGIN );
925 
926         OpenIdDatabaseUser user = new OpenIdDatabaseUser(  );
927         user.setEmail( strEmail );
928         user.setFirstName( strFirstName );
929         user.setLastName( strLastName );
930         user.setLogin( strLogin );
931         user.setAuthentificationType( "openid" );
932 
933         model.put( MARK_USER, user );
934         model.put( MARK_ERROR_MESSAGE, strErrorMessage );
935         model.put( MARK_URL_DOLOGIN, MyLuteceApp.getDoLoginUrl(  ) );
936 
937         HtmlTemplate template = AppTemplateService.getTemplate( TEMPLATE_USER_CONFIRMATION, locale, model );
938 
939         page.setContent( template.getHtml(  ) );
940         page.setTitle( I18nService.getLocalizedString( PROPERTY_PAGETITLE_LOGIN, locale ) );
941         page.setPathLabel( I18nService.getLocalizedString( PROPERTY_PATHLABEL_LOGIN, locale ) );
942 
943         return page;
944     }
945 
946     /**
947     * Build the URL to display a message
948     * @param request The HTTP request
949     * @param strMessageKey The message key
950     * @return The URL to display the message
951     */
952     private String getMessageUrl( HttpServletRequest request, String strMessageKey )
953     {
954         UrlItem url = new UrlItem( AppPathService.getBaseUrl( request ) + AppPathService.getPortalUrl(  ) );
955         url.addParameter( PARAMETER_PAGE, PARAMETER_PAGE_VALUE );
956         url.addParameter( PARAMETER_ERROR, strMessageKey );
957 
958         return url.getUrl(  );
959     }
960 
961     /**
962      * This method is call by the JSP named DoCreateAccount.jsp
963      * @param request The HTTP request
964      * @return The URL to forward depending of the result of the change.
965      */
966     public String doModifyUserDetails( HttpServletRequest request )
967     {
968         Plugin plugin = PluginService.getPlugin( PLUGIN_NAME );
969         OpenIdDatabaseUser databaseUser = new OpenIdDatabaseUser(  );
970         init( request, plugin );
971 
972         UrlItem url = new UrlItem( AppPathService.getBaseUrl( request ) + getNewAccountUrl(  ) );
973         url.addParameter( PARAMETER_PLUGIN_NAME, PLUGIN_NAME );
974 
975         String strError = null;
976         String strLogin = request.getParameter( PARAMETER_LOGIN );
977         String strLastName = request.getParameter( PARAMETER_LAST_NAME );
978         String strFirstName = request.getParameter( PARAMETER_FIRST_NAME );
979         String strEmail = request.getParameter( PARAMETER_EMAIL );
980 
981         url.addParameter( PARAMETER_LOGIN, strLogin );
982         url.addParameter( PARAMETER_LAST_NAME, strLastName );
983         url.addParameter( PARAMETER_FIRST_NAME, strFirstName );
984         url.addParameter( PARAMETER_EMAIL, strEmail );
985 
986         if (  strLogin == null  ||  strFirstName == null ||
987                 ( ( strEmail == null ) || ( strLastName == null ) || strLogin.equals( "" ) || strLastName.equals( "" ) ||
988                 strFirstName.equals( "" ) ) || strEmail.equals( "" ) )
989         {
990             strError = ERROR_MANDATORY_FIELDS;
991         }
992 
993         //Check email format
994         if ( ( strError == null ) && !StringUtil.checkEmail( strEmail ) )
995         {
996             strError = ERROR_SYNTAX_EMAIL;
997         }
998 
999         if ( strError != null )
1000         {
1001             url.addParameter( PARAMETER_ERROR_CODE, strError );
1002 
1003             return url.getUrl(  );
1004         }
1005         else
1006         {
1007             databaseUser.setLogin( strLogin );
1008             databaseUser.setLastName( strLastName );
1009             databaseUser.setFirstName( strFirstName );
1010             databaseUser.setEmail( strEmail );
1011             databaseUser.setAuthentificationType( "openid" );
1012             OpenIdDatabaseUserHome.updateByLogin( databaseUser, plugin );
1013         }
1014 
1015         url.addParameter( PARAMETER_ACTION_SUCCESSFUL, getDefaultRedirectUrl(  ) );
1016 
1017         return url.getUrl(  );
1018     }
1019 }