View Javadoc
1   /*
2    * Copyright (c) 2002-2022, City of 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.portal.web.user;
35  
36  import fr.paris.lutece.portal.business.user.AdminUser;
37  import fr.paris.lutece.portal.business.user.AdminUserHome;
38  import fr.paris.lutece.portal.business.user.authentication.LuteceDefaultAdminUser;
39  import fr.paris.lutece.portal.business.user.log.UserLog;
40  import fr.paris.lutece.portal.business.user.log.UserLogHome;
41  import fr.paris.lutece.portal.service.admin.AccessDeniedException;
42  import fr.paris.lutece.portal.service.admin.AdminAuthenticationService;
43  import fr.paris.lutece.portal.service.admin.AdminUserService;
44  import fr.paris.lutece.portal.service.i18n.I18nService;
45  import fr.paris.lutece.portal.service.init.AppInfo;
46  import fr.paris.lutece.portal.service.mail.MailService;
47  import fr.paris.lutece.portal.service.message.AdminMessage;
48  import fr.paris.lutece.portal.service.message.AdminMessageService;
49  import fr.paris.lutece.portal.service.portal.PortalService;
50  import fr.paris.lutece.portal.service.security.AccessLogService;
51  import fr.paris.lutece.portal.service.security.AccessLoggerConstants;
52  import fr.paris.lutece.portal.service.security.SecurityTokenService;
53  import fr.paris.lutece.portal.service.spring.SpringContextService;
54  import fr.paris.lutece.portal.service.template.AppTemplateService;
55  import fr.paris.lutece.portal.service.util.AppException;
56  import fr.paris.lutece.portal.service.util.AppHTTPSService;
57  import fr.paris.lutece.portal.service.util.AppLogService;
58  import fr.paris.lutece.portal.service.util.AppPathService;
59  import fr.paris.lutece.portal.service.util.AppPropertiesService;
60  import fr.paris.lutece.portal.web.constants.Messages;
61  import fr.paris.lutece.portal.web.constants.Parameters;
62  import fr.paris.lutece.portal.web.l10n.LocaleService;
63  import fr.paris.lutece.util.ReferenceList;
64  import fr.paris.lutece.util.html.HtmlTemplate;
65  import fr.paris.lutece.util.http.SecurityUtil;
66  import fr.paris.lutece.util.password.IPasswordFactory;
67  import fr.paris.lutece.util.string.StringUtil;
68  import fr.paris.lutece.util.url.UrlItem;
69  import java.io.IOException;
70  
71  import org.apache.commons.lang3.StringUtils;
72  
73  import java.io.Serializable;
74  import java.util.Collection;
75  import java.util.Date;
76  import java.util.Enumeration;
77  import java.util.HashMap;
78  import java.util.Locale;
79  import java.util.Map;
80  
81  import javax.security.auth.login.FailedLoginException;
82  import javax.security.auth.login.LoginException;
83  
84  import javax.servlet.http.HttpServletRequest;
85  import javax.servlet.http.HttpServletResponse;
86  import javax.servlet.http.HttpSession;
87  
88  /**
89   * This class provides the user interface to manage login features ( login, logout, ... )
90   */
91  public class AdminLoginJspBean implements Serializable
92  {
93  
94      /**
95       * Serial version UID
96       */
97      private static final long serialVersionUID = 1437296329596757569L;
98  
99      // //////////////////////////////////////////////////////////////////////////
100     // Constants
101     private static final String ERROR_INVALID_TOKEN = "Invalid security token";
102     private static final String CONSTANT_EMAIL_DELIMITER = ";";
103     private static final String CONSTANT_EMPTY_STRING = "";
104     private static final String CONSTANT_SLASH = "/";
105     private static final String CONSTANT_HTTP = "http";
106     private static final String REGEX_ID = "^[\\d]+$";
107 
108     private static final String CONSTANT_ACTION_DORESETPASSWORD = "doResetPwd";
109     private static final String CONSTANT_ACTION_DOFORGOTPASSWORD = "doForgotPwd";
110     private static final String CONSTANT_ACTION_DOFORGOTLOGIN = "doForgotLogin";
111     private static final String CONSTANT_ACTION_DOLOGOUT = "doLogout";
112     private static final String CONSTANT_BO = "BO";
113 
114     // Jsp
115     private static final String JSP_URL_MODIFY_DEFAULT_USER_PASSOWRD = "jsp/admin/user/ModifyDefaultUserPassword.jsp";
116     private static final String JSP_URL_FORM_CONTACT = "AdminFormContact.jsp";
117     private static final String JSP_URL_DO_ADMIN_LOGIN = "jsp/admin/DoAdminLogin.jsp";
118     private static final String JSP_URL_ADMIN_LOGIN = "jsp/admin/AdminLogin.jsp";
119 
120     // Templates
121     private static final String TEMPLATE_ADMIN_LOGIN = "admin/admin_login.html";
122     private static final String TEMPLATE_ADMIN_FORGOT_PASSWORD = "admin/admin_forgot_password.html";
123     private static final String TEMPLATE_ADMIN_RESET_PASSWORD = "admin/admin_reset_password.html";
124     private static final String TEMPLATE_ADMIN_FORGOT_LOGIN = "admin/admin_forgot_login.html";
125     private static final String TEMPLATE_ADMIN_FORM_CONTACT = "admin/admin_form_contact.html";
126     private static final String TEMPLATE_ADMIN_EMAIL_FORGOT_PASSWORD = "admin/admin_email_forgot_password.html";
127     private static final String TEMPLATE_ADMIN_EMAIL_FORGOT_LOGIN = "admin/admin_email_forgot_login.html";
128 
129     // Markers
130     private static final String MARK_PARAMS_LIST = "params_list";
131     private static final String MARK_FORGOT_PASSWORD_URL = "forgot_password_url";
132     private static final String MARK_FORGOT_LOGIN_URL = "forgot_login_url";
133     private static final String MARK_PARAM_VERSION = "version";
134     private static final String MARK_SITE_NAME = "site_name";
135     private static final String MARK_LOGIN_URL = "login_url";
136     private static final String MARK_DO_ADMIN_LOGIN_URL = "do_admin_login_url";
137     private static final String MARK_SITE_LINK = "site_link";
138     private static final String MARK_LOGIN = "login";
139     private static final String MARK_USER_ID = "user_id";
140     private static final String MARK_TOKEN = "token";
141     private static final String MARK_TIMESTAMP = "timestamp";
142     private static final String MARK_RESET_TOKEN_VALIDITY = "reset_password_validity";
143     private static final String MARK_LOCK_RESET_TOKEN_TO_SESSION = "lock_reset_token_to_session";
144     private static final String SESSION_ATTRIBUTE_USER = "lutece_admin_user"; // Used by all JSP
145 
146     // parameters
147     private static final String PARAMETER_MESSAGE = "message_contact";
148     private static final String PARAMETER_TOKEN = "token";
149     private static final String PARAMETER_TIMESTAMP = "ts";
150 
151     // I18n message keys
152     private static final String MESSAGE_SENDING_SUCCESS = "portal.admin.message.admin_forgot_password.sendingSuccess";
153     private static final String MESSAGE_ADMIN_SENDING_SUCCESS = "portal.admin.message.admin_form_contact.sendingSuccess";
154     private static final String MESSAGE_EMAIL_SUBJECT = "portal.admin.admin_forgot_password.email.subject";
155     private static final String MESSAGE_FORGOT_LOGIN_EMAIL_SUBJECT = "portal.admin.admin_forgot_login.email.subject";
156     private static final String MESSAGE_FORGOT_LOGIN_SENDING_SUCCESS = "portal.admin.message.admin_forgot_login.sendingSuccess";
157     private static final String MESSAGE_EMAIL_ADMIN_SUBJECT = "portal.admin.admin_form_contact.email.subject";
158     private static final String MESSAGE_WRONG_EMAIL_FORMAT = "portal.admin.message.admin_forgot_login.wrongEmailFormat";
159     private static final String MESSAGE_CONTROL_PASSWORD_NO_CORRESPONDING = "portal.users.message.password.confirm.error";
160     private static final String MESSAGE_INVALID_RESET_TOKEN = "portal.admin.message.invalid.reset.token";
161     private static final String MESSAGE_EXPIRED_RESET_TOKEN = "portal.admin.message.expired.reset.token";
162     private static final String MESSAGE_RESET_PASSORWD_SUCCESS = "portal.admin.message.reset.password.success";
163     private static final String MESSAGE_FORGOT_PASSWORD_NOT_FOUND = "portal.admin.message.admin_forgot_password.notFound";
164 
165     // Properties
166     private static final String PROPERTY_LEVEL = "askPasswordReinitialization.admin.level";
167 
168     /**
169      * Returns the view of login form
170      *
171      * @param request
172      *            The request
173      * @param response
174      *            The response
175      * @return The HTML form
176      * @throws IOException
177      *             when redirection doesn't work
178      */
179     public String getLogin( HttpServletRequest request, HttpServletResponse response ) throws IOException
180     {
181         HashMap<String, Object> model = new HashMap<>( );
182 
183         HttpSession session = request.getSession( );
184 
185         if ( session != null )
186         {
187             // Invalidate a previous session
188             session.removeAttribute( SESSION_ATTRIBUTE_USER );
189 
190             // Put real base url in session
191             request.getSession( ).setAttribute( AppPathService.SESSION_BASE_URL, AppPathService.getBaseUrl( request ) );
192 
193             if ( !JSP_URL_ADMIN_LOGIN.equals( AdminAuthenticationService.getInstance( ).getLoginPageUrl( ) ) )
194             {
195                 String strRedirectUrl = AdminAuthenticationService.getInstance( ).getLoginPageUrl( );
196                 if ( strRedirectUrl == null )
197                 {
198                     strRedirectUrl = AppPathService.getAdminMenuUrl( );
199                 }
200                 response.sendRedirect( AppPathService.resolveRedirectUrl( request, strRedirectUrl ).getUrl( ) );
201                 return null;
202             }
203 
204         }
205 
206         Locale locale = AdminUserService.getLocale( request );
207 
208         StringBuilder sbUrl = new StringBuilder( );
209 
210         if ( AppHTTPSService.isHTTPSSupportEnabled( ) )
211         {
212             sbUrl.append( AppHTTPSService.getHTTPSUrl( request ) );
213         }
214         else
215         {
216             sbUrl.append( AppPathService.getBaseUrl( request ) );
217         }
218 
219         if ( !sbUrl.toString( ).endsWith( CONSTANT_SLASH ) )
220         {
221             sbUrl.append( CONSTANT_SLASH );
222         }
223 
224         sbUrl.append( JSP_URL_DO_ADMIN_LOGIN );
225 
226         model.put( MARK_PARAM_VERSION, AppInfo.getVersion( ) );
227         model.put( MARK_SITE_NAME, PortalService.getSiteName( ) );
228         model.put( MARK_FORGOT_PASSWORD_URL, AdminAuthenticationService.getInstance( ).getLostPasswordPageUrl( ) );
229         model.put( MARK_FORGOT_LOGIN_URL, AdminAuthenticationService.getInstance( ).getLostLoginPageUrl( ) );
230         model.put( MARK_DO_ADMIN_LOGIN_URL, sbUrl.toString( ) );
231         model.put( MARK_TOKEN, SecurityTokenService.getInstance( ).getToken( request, TEMPLATE_ADMIN_LOGIN ) );
232 
233         HtmlTemplate template = AppTemplateService.getTemplate( TEMPLATE_ADMIN_LOGIN, locale, model );
234 
235         return template.getHtml( );
236     }
237 
238     /**
239      * Returns the view of forgot password form
240      *
241      * @param request
242      *            The request
243      * @return The HTML form
244      */
245     public String getForgotPassword( HttpServletRequest request )
246     {
247         Map<String, Object> model = new HashMap<>( );
248 
249         // Invalidate a previous session
250         HttpSession session = request.getSession( );
251 
252         if ( session != null )
253         {
254             session.removeAttribute( SESSION_ATTRIBUTE_USER );
255         }
256 
257         Locale locale = AdminUserService.getLocale( request );
258 
259         Enumeration<String> enumParams = request.getParameterNames( );
260         ReferenceListt.html#ReferenceList">ReferenceList listParams = new ReferenceList( );
261         String strParamName;
262 
263         while ( enumParams.hasMoreElements( ) )
264         {
265             strParamName = enumParams.nextElement( );
266 
267             String strParamValue = request.getParameter( strParamName );
268             listParams.addItem( strParamName, strParamValue );
269         }
270 
271         model.put( MARK_PARAM_VERSION, AppInfo.getVersion( ) );
272         model.put( MARK_PARAMS_LIST, listParams );
273         model.put( MARK_SITE_NAME, PortalService.getSiteName( ) );
274 
275         HtmlTemplate template = AppTemplateService.getTemplate( TEMPLATE_ADMIN_FORGOT_PASSWORD, locale, model );
276 
277         return template.getHtml( );
278     }
279 
280     public String getResetPassword( HttpServletRequest request )
281     {
282         // Invalidate a previous session
283         HttpSession session = request.getSession( false );
284 
285         if ( session != null )
286         {
287             session.removeAttribute( SESSION_ATTRIBUTE_USER );
288         }
289 
290         Map<String, Object> model = new HashMap<>( );
291 
292         Locale locale = AdminUserService.getLocale( request );
293 
294         Enumeration<String> enumParams = request.getParameterNames( );
295         ReferenceListt.html#ReferenceList">ReferenceList listParams = new ReferenceList( );
296         String strParamName;
297 
298         while ( enumParams.hasMoreElements( ) )
299         {
300             strParamName = enumParams.nextElement( );
301 
302             String strParamValue = request.getParameter( strParamName );
303             listParams.addItem( strParamName, strParamValue );
304         }
305 
306         model.put( MARK_PARAM_VERSION, AppInfo.getVersion( ) );
307         model.put( MARK_PARAMS_LIST, listParams );
308         model.put( MARK_SITE_NAME, PortalService.getSiteName( ) );
309 
310         HtmlTemplate template = AppTemplateService.getTemplate( TEMPLATE_ADMIN_RESET_PASSWORD, locale, model );
311 
312         return template.getHtml( );
313     }
314 
315     /**
316      * Returns the view of forgot password form
317      *
318      * @param request
319      *            The request
320      * @return The HTML form
321      */
322     public String getForgotLogin( HttpServletRequest request )
323     {
324         Map<String, Object> model = new HashMap<>( );
325 
326         // Invalidate a previous session
327         HttpSession session = request.getSession( );
328 
329         if ( session != null )
330         {
331             session.removeAttribute( SESSION_ATTRIBUTE_USER );
332         }
333 
334         Locale locale = AdminUserService.getLocale( request );
335 
336         Enumeration<String> enumParams = request.getParameterNames( );
337         ReferenceListt.html#ReferenceList">ReferenceList listParams = new ReferenceList( );
338         String strParamName;
339 
340         while ( enumParams.hasMoreElements( ) )
341         {
342             strParamName = enumParams.nextElement( );
343 
344             String strParamValue = request.getParameter( strParamName );
345             listParams.addItem( strParamName, strParamValue );
346         }
347 
348         model.put( MARK_PARAM_VERSION, AppInfo.getVersion( ) );
349         model.put( MARK_PARAMS_LIST, listParams );
350         model.put( MARK_SITE_NAME, PortalService.getSiteName( ) );
351 
352         HtmlTemplate template = AppTemplateService.getTemplate( TEMPLATE_ADMIN_FORGOT_LOGIN, locale, model );
353 
354         return template.getHtml( );
355     }
356 
357     /**
358      * Get the admin contact form
359      * 
360      * @param request
361      *            The Http request
362      * @return The HTML form
363      */
364     public String getFormContact( HttpServletRequest request )
365     {
366         HashMap<String, Object> model = new HashMap<>( );
367 
368         // Invalidate a previous session
369         HttpSession session = request.getSession( );
370 
371         if ( session != null )
372         {
373             session.removeAttribute( SESSION_ATTRIBUTE_USER );
374         }
375 
376         Locale locale = AdminUserService.getLocale( request );
377 
378         model.put( MARK_PARAM_VERSION, AppInfo.getVersion( ) );
379 
380         HtmlTemplate template = AppTemplateService.getTemplate( TEMPLATE_ADMIN_FORM_CONTACT, locale, model );
381 
382         return template.getHtml( );
383     }
384 
385     /**
386      * Process the login of user
387      *
388      * @param request
389      *            The HTTP Request
390      * @return The Jsp URL of the process result
391      * @throws AccessDeniedException
392      */
393     public String doLogin( HttpServletRequest request ) throws AccessDeniedException
394     {
395         if ( request.getScheme( ).equals( CONSTANT_HTTP ) && AppHTTPSService.isHTTPSSupportEnabled( ) )
396         {
397             return JSP_URL_ADMIN_LOGIN;
398         }
399         if ( !SecurityTokenService.getInstance( ).validate( request, TEMPLATE_ADMIN_LOGIN ) )
400         {
401             throw new AccessDeniedException( ERROR_INVALID_TOKEN );
402         }
403 
404         // recovery of the login attributes
405         String strAccessCode = request.getParameter( Parameters.ACCESS_CODE );
406         String strPassword = request.getParameter( Parameters.PASSWORD );
407 
408         if ( strAccessCode == null || strPassword == null )
409         {
410             // TIME RESISTANT ATTACK
411             // Computation time is equal to the time needed by a legitimate user
412             strAccessCode = "";
413             strPassword = "";
414         }
415 
416         String strLoginUrl = AdminAuthenticationService.getInstance( ).getLoginPageUrl( );
417 
418         try
419         {
420             AdminAuthenticationService.getInstance( ).loginUser( request, strAccessCode, strPassword );
421         }
422         catch( FailedLoginException ex )
423         {
424             // Creating a record of connections log
425             UserLogusiness/user/log/UserLog.html#UserLog">UserLog userLog = new UserLog( );
426             userLog.setAccessCode( strAccessCode );
427             userLog.setIpAddress( SecurityUtil.getRealIp( request ) );
428             userLog.setDateLogin( new java.sql.Timestamp( new java.util.Date( ).getTime( ) ) );
429             userLog.setLoginStatus( UserLog.LOGIN_DENIED ); // will be inserted only if access denied
430             UserLogHome.addUserLog( userLog );
431 
432             return AdminMessageService.getMessageUrl( request, Messages.MESSAGE_AUTH_FAILURE, strLoginUrl, AdminMessage.TYPE_STOP );
433         }
434         catch( LoginException ex )
435         {
436             AppLogService.error( "Error during connection for user access code :{}", SecurityUtil.logForgingProtect( strAccessCode ), ex );
437 
438             return AdminMessageService.getMessageUrl( request, Messages.MESSAGE_AUTH_FAILURE, strLoginUrl, AdminMessage.TYPE_STOP );
439         }
440 
441         UrlItem url;
442 
443         AdminUser user = AdminUserHome.findUserByLogin( strAccessCode );
444 
445         if ( user.isPasswordReset( ) )
446         {
447             String strRedirectUrl = AdminMessageService.getMessageUrl( request, Messages.MESSAGE_USER_MUST_CHANGE_PASSWORD,
448                     JSP_URL_MODIFY_DEFAULT_USER_PASSOWRD, AdminMessage.TYPE_INFO );
449             url = new UrlItem( strRedirectUrl );
450         }
451         else
452         {
453             String strNextUrl = AdminAuthenticationService.getInstance( ).getLoginNextUrl( request );
454 
455             if ( StringUtils.isNotBlank( strNextUrl ) )
456             {
457                 url = new UrlItem( strNextUrl );
458             }
459             else
460             {
461                 url = AppPathService.resolveRedirectUrl( request, AppPathService.getAdminMenuUrl( ) );
462             }
463         }
464 
465         return url.getUrl( );
466     }
467 
468     /**
469      * Process the sending to user password
470      *
471      * @param request
472      *            The HTTP Request
473      * @return The Jsp URL of the process result
474      * @throws Exception
475      *             The exception
476      */
477     public String doForgotPassword( HttpServletRequest request )
478     {
479         // get mail from user
480         String strAccessCode = request.getParameter( Parameters.ACCESS_CODE );
481         Locale locale = AdminUserService.getLocale( request );
482 
483         if ( StringUtils.isEmpty( strAccessCode ) )
484         {
485             return AdminMessageService.getMessageUrl( request, Messages.MANDATORY_FIELDS, AdminMessage.TYPE_STOP );
486         }
487 
488         if ( locale == null )
489         {
490             locale = LocaleService.getDefault( );
491         }
492 
493         // if user or mail not found, send admin message
494         AdminUser user = AdminUserHome.findUserByLogin( strAccessCode );
495 
496         if ( ( user == null ) || StringUtils.isEmpty( user.getEmail( ) ) )
497         {
498             return AdminMessageService.getMessageUrl( request, MESSAGE_FORGOT_PASSWORD_NOT_FOUND, JSP_URL_ADMIN_LOGIN, AdminMessage.TYPE_INFO );
499         }
500 
501         // make password reset token
502         Date timestamp = new Date( );
503         String strToken = AdminUserService.getUserPasswordResetToken( user, timestamp, request );
504 
505         // send password rest token by e-mail
506         String strSenderEmail = MailService.getNoReplyEmail( );
507         String strEmailSubject = I18nService.getLocalizedString( MESSAGE_EMAIL_SUBJECT, locale );
508         HashMap<String, Object> model = new HashMap<>( );
509         model.put( MARK_TOKEN, strToken );
510         model.put( MARK_TIMESTAMP, timestamp.getTime( ) );
511         model.put( MARK_USER_ID, user.getUserId( ) );
512         model.put( MARK_LOGIN_URL, AppPathService.getBaseUrl( request ) + "jsp/admin/AdminResetPassword.jsp" );
513         model.put( MARK_SITE_LINK, MailService.getSiteLink( AppPathService.getBaseUrl( request ), false ) );
514         Date tokenExpiryDate = new Date(
515                 timestamp.getTime( ) + ( 1000L * 60 * AdminUserService.getIntegerSecurityParameter( AdminUserService.DSKEY_RESET_TOKEN_VALIDITY ) ) );
516         model.put( MARK_RESET_TOKEN_VALIDITY, tokenExpiryDate );
517         model.put( MARK_LOCK_RESET_TOKEN_TO_SESSION, AdminUserService.getBooleanSecurityParameter( AdminUserService.DSKEY_LOCK_RESET_TOKEN_TO_SESSION ) );
518         HtmlTemplate template = AppTemplateService.getTemplate( TEMPLATE_ADMIN_EMAIL_FORGOT_PASSWORD, locale, model );
519 
520         MailService.sendMailHtml( user.getEmail( ), strSenderEmail, strSenderEmail, strEmailSubject, template.getHtml( ) );
521 
522         AccessLogService.getInstance( ).info( AccessLoggerConstants.EVENT_TYPE_CONNECT, CONSTANT_ACTION_DOFORGOTPASSWORD, user, null, CONSTANT_BO );
523 
524         return AdminMessageService.getMessageUrl( request, MESSAGE_SENDING_SUCCESS, JSP_URL_ADMIN_LOGIN, AdminMessage.TYPE_INFO );
525     }
526 
527     public String doResetPassword( HttpServletRequest request )
528     {
529         if ( !"POST".equals( request.getMethod( ) ) )
530         {
531             throw new AppException( "This method should requested via POST" );
532         }
533 
534         String strUserId = request.getParameter( Parameters.USER_ID );
535 
536         if ( !StringUtils.isNumeric( strUserId ) || StringUtils.isBlank( strUserId ) )
537         {
538             return AdminMessageService.getMessageUrl( request, Messages.MANDATORY_FIELDS, AdminMessage.TYPE_STOP );
539         }
540 
541         String strTimestamp = request.getParameter( PARAMETER_TIMESTAMP );
542 
543         if ( !StringUtils.isNumeric( strTimestamp ) )
544         {
545             return AdminMessageService.getMessageUrl( request, Messages.MANDATORY_FIELDS, AdminMessage.TYPE_STOP );
546         }
547 
548         String strToken = request.getParameter( PARAMETER_TOKEN );
549 
550         if ( StringUtils.isEmpty( strToken ) )
551         {
552             return AdminMessageService.getMessageUrl( request, Messages.MANDATORY_FIELDS, AdminMessage.TYPE_STOP );
553         }
554 
555         String strNewPassword = request.getParameter( Parameters.NEW_PASSWORD );
556         String strConfirmNewPassword = request.getParameter( Parameters.CONFIRM_NEW_PASSWORD );
557 
558         if ( StringUtils.isEmpty( strNewPassword ) || StringUtils.isEmpty( strConfirmNewPassword ) )
559         {
560             return AdminMessageService.getMessageUrl( request, Messages.MANDATORY_FIELDS, AdminMessage.TYPE_STOP );
561         }
562 
563         if ( !strNewPassword.equals( strConfirmNewPassword ) )
564         {
565             return AdminMessageService.getMessageUrl( request, MESSAGE_CONTROL_PASSWORD_NO_CORRESPONDING, AdminMessage.TYPE_STOP );
566         }
567 
568         LuteceDefaultAdminUser user = AdminUserHome.findLuteceDefaultAdminUserByPrimaryKey( Integer.parseInt( strUserId ) );
569 
570         if ( user == null )
571         {
572             user = new LuteceDefaultAdminUser( );
573         }
574 
575         Date timestamp = new Date( Long.valueOf( strTimestamp ) );
576 
577         String strSystemToken = AdminUserService.getUserPasswordResetToken( user, timestamp, request );
578 
579         if ( !strSystemToken.equals( strToken ) )
580         {
581             return AdminMessageService.getMessageUrl( request, MESSAGE_INVALID_RESET_TOKEN, AdminMessage.TYPE_STOP );
582         }
583 
584         long lTokenAge = new Date( ).getTime( ) - timestamp.getTime( );
585 
586         if ( lTokenAge < 0 || lTokenAge > ( 1000L * 60 * AdminUserService.getIntegerSecurityParameter( AdminUserService.DSKEY_RESET_TOKEN_VALIDITY ) ) )
587         {
588             return AdminMessageService.getMessageUrl( request, MESSAGE_EXPIRED_RESET_TOKEN, AdminMessage.TYPE_STOP );
589         }
590 
591         String strUrl = AdminUserService.checkPassword( request, strNewPassword, user.getUserId( ) );
592         if ( StringUtils.isNotEmpty( strUrl ) )
593         {
594             return strUrl;
595         }
596 
597         // all checks are OK. Proceed to password change
598         user.setPasswordMaxValidDate( AdminUserService.getPasswordMaxValidDate( ) );
599         IPasswordFactory passwordFactory = SpringContextService.getBean( IPasswordFactory.BEAN_NAME );
600         user.setPassword( passwordFactory.getPasswordFromCleartext( strNewPassword ) );
601         AdminUserHome.update( user );
602         AdminUserHome.insertNewPasswordInHistory( user.getPassword( ), user.getUserId( ) );
603 
604         AccessLogService.getInstance( ).info( AccessLoggerConstants.EVENT_TYPE_CONNECT, CONSTANT_ACTION_DORESETPASSWORD, user, null, CONSTANT_BO );
605 
606         return AdminMessageService.getMessageUrl( request, MESSAGE_RESET_PASSORWD_SUCCESS, JSP_URL_ADMIN_LOGIN, AdminMessage.TYPE_INFO );
607     }
608 
609     /**
610      * Process the sending of the login
611      * 
612      * @param request
613      *            The HTTP Request
614      * @return The Jsp URL of the process result
615      * @throws Exception
616      *             The exception
617      */
618     public String doForgotLogin( HttpServletRequest request )
619     {
620         String strEmail = request.getParameter( Parameters.EMAIL );
621         Locale locale = AdminUserService.getLocale( request );
622 
623         if ( ( strEmail == null ) || strEmail.equals( CONSTANT_EMPTY_STRING ) )
624         {
625             return AdminMessageService.getMessageUrl( request, Messages.MANDATORY_FIELDS, AdminMessage.TYPE_STOP );
626         }
627 
628         if ( !AdminUserService.checkEmail( strEmail ) )
629         {
630             return AdminMessageService.getMessageUrl( request, MESSAGE_WRONG_EMAIL_FORMAT, AdminMessage.TYPE_STOP );
631         }
632 
633         if ( locale == null )
634         {
635             locale = LocaleService.getDefault( );
636         }
637 
638         // if access code not found, send admin message
639         String strAccessCode = AdminUserHome.findUserByEmail( strEmail );
640 
641         if ( StringUtils.isEmpty( strAccessCode ) )
642         {
643             return JSP_URL_FORM_CONTACT;
644         }
645 
646         // send access code by e-mail
647         String strSenderEmail = MailService.getNoReplyEmail( );
648         String strEmailSubject = I18nService.getLocalizedString( MESSAGE_FORGOT_LOGIN_EMAIL_SUBJECT, locale );
649         HashMap<String, Object> model = new HashMap<>( );
650         model.put( MARK_LOGIN, strAccessCode );
651         model.put( MARK_LOGIN_URL, AppPathService.getBaseUrl( request ) + AdminAuthenticationService.getInstance( ).getLoginPageUrl( ) );
652         model.put( MARK_SITE_LINK, MailService.getSiteLink( AppPathService.getBaseUrl( request ), false ) );
653 
654         HtmlTemplate template = AppTemplateService.getTemplate( TEMPLATE_ADMIN_EMAIL_FORGOT_LOGIN, locale, model );
655 
656         MailService.sendMailHtml( strEmail, strSenderEmail, strSenderEmail, strEmailSubject, template.getHtml( ) );
657 
658         AccessLogService.getInstance( ).info( AccessLoggerConstants.EVENT_TYPE_CONNECT, CONSTANT_ACTION_DOFORGOTLOGIN, null, strAccessCode, CONSTANT_BO );
659 
660         return AdminMessageService.getMessageUrl( request, MESSAGE_FORGOT_LOGIN_SENDING_SUCCESS, AdminMessage.TYPE_INFO );
661     }
662 
663     /**
664      * Send the message to the adminsitrator(s)
665      * 
666      * @param request
667      *            The {@link HttpServletRequest}
668      * @return an adminMessage
669      */
670     public String doFormContact( HttpServletRequest request )
671     {
672         // Get message, check if empty
673         String strMessage = request.getParameter( PARAMETER_MESSAGE );
674 
675         if ( ( strMessage == null ) || strMessage.equals( CONSTANT_EMPTY_STRING ) )
676         {
677             return AdminMessageService.getMessageUrl( request, Messages.MANDATORY_FIELDS, AdminMessage.TYPE_STOP );
678         }
679 
680         Locale locale = AdminUserService.getLocale( request );
681 
682         if ( locale == null )
683         {
684             locale = LocaleService.getDefault( );
685         }
686 
687         // send mail to admin wich have level
688         int nIdLevel = 0;
689         String strLevelId = AppPropertiesService.getProperty( PROPERTY_LEVEL, "0" );
690 
691         if ( ( strLevelId != null ) && strLevelId.matches( REGEX_ID ) )
692         {
693             nIdLevel = Integer.parseInt( strLevelId );
694         }
695 
696         Collection<AdminUser> adminUserList = AdminUserHome.findByLevel( nIdLevel );
697         StringBuilder sbMailsTo = new StringBuilder( CONSTANT_EMPTY_STRING );
698 
699         for ( AdminUser adminUser : adminUserList )
700         {
701             if ( StringUtil.checkEmail( adminUser.getEmail( ) ) )
702             {
703                 sbMailsTo.append( adminUser.getEmail( ) ).append( CONSTANT_EMAIL_DELIMITER );
704             }
705         }
706 
707         String strMailsTo = sbMailsTo.toString( );
708 
709         if ( !strMailsTo.equals( CONSTANT_EMPTY_STRING ) )
710         {
711             String strSenderEmail = MailService.getNoReplyEmail( );
712             String strEmailSubject = I18nService.getLocalizedString( MESSAGE_EMAIL_ADMIN_SUBJECT, locale );
713 
714             MailService.sendMailHtml( strMailsTo, strSenderEmail, strSenderEmail, strEmailSubject, strMessage );
715         }
716 
717         return AdminMessageService.getMessageUrl( request, MESSAGE_ADMIN_SENDING_SUCCESS, AdminAuthenticationService.getInstance( ).getLoginPageUrl( ),
718                 AdminMessage.TYPE_INFO );
719     }
720 
721     /**
722      * Process the logout of user
723      *
724      * @param request
725      *            Http request
726      * @return The Jsp URL of the process result
727      */
728     public String doLogout( HttpServletRequest request )
729     {
730         // Invalidation of the session
731         HttpSession session = request.getSession( );
732 
733         AdminUser user = AdminAuthenticationService.getInstance( ).getRegisteredUser( request );
734 
735         if ( session != null )
736         {
737             session.invalidate( );
738         }
739 
740         String strLoginUrl = AdminAuthenticationService.getInstance( ).getLoginPageUrl( );
741 
742         AccessLogService.getInstance( ).info( AccessLoggerConstants.EVENT_TYPE_DISCONNECT, CONSTANT_ACTION_DOLOGOUT, user, null, CONSTANT_BO );
743 
744         return AdminMessageService.getMessageUrl( request, Messages.MESSAGE_LOGOUT, strLoginUrl, AdminMessage.TYPE_INFO );
745     }
746 }