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