View Javadoc
1   /*
2    * Copyright (c) 2002-2014, 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.portal.service.daemon;
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.parameter.DefaultUserParameterHome;
39  import fr.paris.lutece.portal.service.admin.AdminUserService;
40  import fr.paris.lutece.portal.service.mail.MailService;
41  import fr.paris.lutece.portal.service.template.AppTemplateService;
42  import fr.paris.lutece.portal.service.template.DatabaseTemplateService;
43  import fr.paris.lutece.portal.service.util.AppLogService;
44  import fr.paris.lutece.portal.service.util.AppPropertiesService;
45  import fr.paris.lutece.portal.web.l10n.LocaleService;
46  import fr.paris.lutece.util.date.DateUtil;
47  import fr.paris.lutece.util.html.HtmlTemplate;
48  
49  import org.apache.commons.lang.StringUtils;
50  
51  import java.sql.Timestamp;
52  
53  import java.text.DateFormat;
54  import java.text.SimpleDateFormat;
55  
56  import java.util.Date;
57  import java.util.HashMap;
58  import java.util.List;
59  import java.util.Map;
60  
61  
62  /**
63   * Daemon to anonymize admin users
64   */
65  public class AccountLifeTimeDaemon extends Daemon
66  {
67      private static final String PARAMETER_TIME_BEFORE_ALERT_ACCOUNT = "time_before_alert_account";
68      private static final String PARAMETER_NB_ALERT_ACCOUNT = "nb_alert_account";
69      private static final String PARAMETER_TIME_BETWEEN_ALERTS_ACCOUNT = "time_between_alerts_account";
70      private static final String PARAMETER_NOTIFY_USER_PASSWORD_EXPIRED = "notify_user_password_expired";
71      private static final String PARAMETER_EXPIRED_ALERT_MAIL_SENDER = "expired_alert_mail_sender";
72      private static final String PARAMETER_EXPIRED_ALERT_MAIL_SUBJECT = "expired_alert_mail_subject";
73      private static final String PARAMETER_FIRST_ALERT_MAIL_SENDER = "first_alert_mail_sender";
74      private static final String PARAMETER_FIRST_ALERT_MAIL_SUBJECT = "first_alert_mail_subject";
75      private static final String PARAMETER_OTHER_ALERT_MAIL_SENDER = "other_alert_mail_sender";
76      private static final String PARAMETER_OTHER_ALERT_MAIL_SUBJECT = "other_alert_mail_subject";
77      private static final String PARAMETER_PASSWORD_EXPIRED_MAIL_SENDER = "password_expired_mail_sender";
78      private static final String PARAMETER_PASSWORD_EXPIRED_MAIL_SUBJECT = "password_expired_mail_subject";
79      private static final String PARAMETER_CORE_EXPIRATION_MAIL = "core_expiration_mail";
80      private static final String PARAMETER_CORE_FIRST_ALERT_MAIL = "core_first_alert_mail";
81      private static final String PARAMETER_CORE_OTHER_ALERT_MAIL = "core_other_alert_mail";
82      private static final String PARAMETER_CORE_PASSWORD_EXPIRED_ALERT_MAIL = "core_password_expired";
83      private static final String MARK_LAST_NAME = "last_name";
84      private static final String MARK_FIRST_NAME = "first_name";
85      private static final String MARK_DATE_VALID = "date_valid";
86      private static final String MARK_URL = "url";
87      private static final String PROPERTY_PROD_URL = "init.webapp.prod.url";
88      private static final String JSP_URL_REACTIVATE_ACCOUNT = "/jsp/admin/user/ReactivateAccount.jsp";
89  
90      /**
91       * {@inheritDoc}
92       */
93      @SuppressWarnings( "deprecation" )
94      @Override
95      public void run(  )
96      {
97          StringBuilder sbLogs = null;
98          StringBuilder sbResult = new StringBuilder(  );
99  
100         Timestamp currentTimestamp = new Timestamp( new java.util.Date(  ).getTime(  ) );
101         List<Integer> accountsToSetAsExpired = AdminUserHome.getIdUsersWithExpiredLifeTimeList( currentTimestamp );
102 
103         // We first set as expirated user that have reached their life time limit
104         if ( ( accountsToSetAsExpired != null ) && ( accountsToSetAsExpired.size(  ) > 0 ) )
105         {
106             int nbAccountToExpire = accountsToSetAsExpired.size(  );
107             String strBody = DatabaseTemplateService.getTemplateFromKey( PARAMETER_CORE_EXPIRATION_MAIL );
108 
109             String defaultUserParameter = DefaultUserParameterHome.findByKey( PARAMETER_EXPIRED_ALERT_MAIL_SENDER );
110             String strSender = ( defaultUserParameter == null ) ? StringUtils.EMPTY : defaultUserParameter;
111 
112             defaultUserParameter = DefaultUserParameterHome.findByKey( PARAMETER_EXPIRED_ALERT_MAIL_SUBJECT );
113 
114             String strSubject = ( defaultUserParameter == null ) ? StringUtils.EMPTY : defaultUserParameter;
115 
116             for ( Integer nIdUser : accountsToSetAsExpired )
117             {
118                 try
119                 {
120                     AdminUser user = AdminUserHome.findByPrimaryKey( nIdUser );
121                     String strUserMail = user.getEmail(  );
122 
123                     if ( ( strUserMail != null ) && StringUtils.isNotBlank( strUserMail ) )
124                     {
125                         Map<String, String> model = new HashMap<String, String>(  );
126                         addParametersToModel( model, nIdUser );
127 
128                         HtmlTemplate template = AppTemplateService.getTemplateFromStringFtl( strBody,
129                                 user.getLocale(  ), model );
130                         MailService.sendMailHtml( strUserMail, strSender, strSender, strSubject, template.getHtml(  ) );
131                     }
132                 }
133                 catch ( Exception e )
134                 {
135                     AppLogService.error( "AccountLifeTimeDaemon - Error sending expiration alert to admin user : " +
136                         e.getMessage(  ), e );
137                 }
138             }
139 
140             AdminUserHome.updateUserStatus( accountsToSetAsExpired, AdminUser.EXPIRED_CODE );
141 
142             sbLogs = new StringBuilder(  );
143             sbLogs.append( "AccountLifeTimeDaemon - " );
144             sbLogs.append( Integer.toString( nbAccountToExpire ) );
145             sbLogs.append( " account(s) have expired" );
146             AppLogService.info( sbLogs.toString(  ) );
147             sbResult.append( sbLogs.toString(  ) );
148             sbResult.append( "\n" );
149         }
150         else
151         {
152             AppLogService.info( "AccountLifeTimeDaemon - No expired admin user found" );
153             sbResult.append( "AccountLifeTimeDaemon - No expired admin user found\n" );
154         }
155 
156         // We send first alert to users
157         long nbDaysBeforeFirstAlert = AdminUserService.getIntegerSecurityParameter( PARAMETER_TIME_BEFORE_ALERT_ACCOUNT );
158 
159         Timestamp firstAlertMaxDate = new Timestamp( currentTimestamp.getTime(  ) +
160                 DateUtil.convertDaysInMiliseconds( nbDaysBeforeFirstAlert ) );
161 
162         if ( nbDaysBeforeFirstAlert <= 0 )
163         {
164             AppLogService.info( "AccountLifeTimeDaemon - First alert deactivated, skipping" );
165             sbResult.append( "AccountLifeTimeDaemon - First alert deactivated, skipping\n" );
166         }
167         else
168         {
169             List<Integer> userIdListToSendFirstAlert = AdminUserHome.getIdUsersToSendFirstAlert( firstAlertMaxDate );
170 
171             if ( ( userIdListToSendFirstAlert != null ) && ( userIdListToSendFirstAlert.size(  ) > 0 ) )
172             {
173                 int nbFirstAlertSent = userIdListToSendFirstAlert.size(  );
174                 String strBody = DatabaseTemplateService.getTemplateFromKey( PARAMETER_CORE_FIRST_ALERT_MAIL );
175 
176                 String defaultUserParameter = DefaultUserParameterHome.findByKey( PARAMETER_FIRST_ALERT_MAIL_SENDER );
177                 String strSender = ( defaultUserParameter == null ) ? StringUtils.EMPTY : defaultUserParameter;
178 
179                 defaultUserParameter = DefaultUserParameterHome.findByKey( PARAMETER_FIRST_ALERT_MAIL_SUBJECT );
180 
181                 String strSubject = ( defaultUserParameter == null ) ? StringUtils.EMPTY : defaultUserParameter;
182 
183                 for ( Integer nIdUser : userIdListToSendFirstAlert )
184                 {
185                     try
186                     {
187                         AdminUser user = AdminUserHome.findByPrimaryKey( nIdUser );
188                         String strUserMail = user.getEmail(  );
189 
190                         if ( ( strUserMail != null ) && StringUtils.isNotBlank( strUserMail ) )
191                         {
192                             Map<String, String> model = new HashMap<String, String>(  );
193                             addParametersToModel( model, nIdUser );
194 
195                             HtmlTemplate template = AppTemplateService.getTemplateFromStringFtl( strBody,
196                                     user.getLocale(  ), model );
197                             MailService.sendMailHtml( strUserMail, strSender, strSender, strSubject,
198                                 template.getHtml(  ) );
199                         }
200                     }
201                     catch ( Exception e )
202                     {
203                         AppLogService.error( "AccountLifeTimeDaemon - Error sending first alert to admin user : " +
204                             e.getMessage(  ), e );
205                     }
206                 }
207 
208                 AdminUserHome.updateNbAlert( userIdListToSendFirstAlert );
209 
210                 sbLogs = new StringBuilder(  );
211                 sbLogs.append( "AccountLifeTimeDaemon - " );
212                 sbLogs.append( Integer.toString( nbFirstAlertSent ) );
213                 sbLogs.append( " first alert(s) have been sent" );
214                 AppLogService.info( sbLogs.toString(  ) );
215                 sbResult.append( sbLogs.toString(  ) );
216                 sbResult.append( "\n" );
217 
218                 userIdListToSendFirstAlert = null;
219             }
220             else
221             {
222                 AppLogService.info( "AccountLifeTimeDaemon - No first alert to send" );
223                 sbResult.append( "AccountLifeTimeDaemon - No first alert to send\n" );
224             }
225         }
226 
227         // We send other alert to users
228         int maxNumberOfAlerts = AdminUserService.getIntegerSecurityParameter( PARAMETER_NB_ALERT_ACCOUNT );
229         int nbDaysBetweenAlerts = AdminUserService.getIntegerSecurityParameter( PARAMETER_TIME_BETWEEN_ALERTS_ACCOUNT );
230         Timestamp timeBetweenAlerts = new Timestamp( DateUtil.convertDaysInMiliseconds( nbDaysBetweenAlerts ) );
231 
232         if ( ( maxNumberOfAlerts <= 0 ) || ( nbDaysBetweenAlerts <= 0 ) )
233         {
234             AppLogService.info( "AccountLifeTimeDaemon - Other alerts deactivated, skipping" );
235             sbResult.append( "AccountLifeTimeDaemon - Other alerts deactivated, skipping\n" );
236         }
237         else
238         {
239             List<Integer> userIdListToSendNextAlert = AdminUserHome.getIdUsersToSendOtherAlert( firstAlertMaxDate,
240                     timeBetweenAlerts, maxNumberOfAlerts );
241 
242             if ( ( userIdListToSendNextAlert != null ) && ( userIdListToSendNextAlert.size(  ) > 0 ) )
243             {
244                 int nbOtherAlertSent = userIdListToSendNextAlert.size(  );
245                 String strBody = DatabaseTemplateService.getTemplateFromKey( PARAMETER_CORE_OTHER_ALERT_MAIL );
246 
247                 String defaultUserParameter = DefaultUserParameterHome.findByKey( PARAMETER_OTHER_ALERT_MAIL_SENDER );
248                 String strSender = ( defaultUserParameter == null ) ? StringUtils.EMPTY : defaultUserParameter;
249 
250                 defaultUserParameter = DefaultUserParameterHome.findByKey( PARAMETER_OTHER_ALERT_MAIL_SUBJECT );
251 
252                 String strSubject = ( defaultUserParameter == null ) ? StringUtils.EMPTY : defaultUserParameter;
253 
254                 for ( Integer nIdUser : userIdListToSendNextAlert )
255                 {
256                     try
257                     {
258                         AdminUser user = AdminUserHome.findByPrimaryKey( nIdUser );
259                         String strUserMail = user.getEmail(  );
260 
261                         if ( ( strUserMail != null ) && StringUtils.isNotBlank( strUserMail ) )
262                         {
263                             Map<String, String> model = new HashMap<String, String>(  );
264                             addParametersToModel( model, nIdUser );
265 
266                             HtmlTemplate template = AppTemplateService.getTemplateFromStringFtl( strBody,
267                                     user.getLocale(  ), model );
268                             MailService.sendMailHtml( strUserMail, strSender, strSender, strSubject,
269                                 template.getHtml(  ) );
270                         }
271                     }
272                     catch ( Exception e )
273                     {
274                         AppLogService.error( "AccountLifeTimeDaemon - Error sending next alert to admin user : " +
275                             e.getMessage(  ), e );
276                     }
277                 }
278 
279                 AdminUserHome.updateNbAlert( userIdListToSendNextAlert );
280 
281                 sbLogs = new StringBuilder(  );
282                 sbLogs.append( "AccountLifeTimeDaemon - " );
283                 sbLogs.append( Integer.toString( nbOtherAlertSent ) );
284                 sbLogs.append( " next alert(s) have been sent" );
285                 AppLogService.info( sbLogs.toString(  ) );
286                 sbResult.append( sbLogs.toString(  ) );
287 
288                 userIdListToSendNextAlert = null;
289             }
290             else
291             {
292                 AppLogService.info( "AccountLifeTimeDaemon - No next alert to send" );
293                 sbResult.append( "AccountLifeTimeDaemon - No next alert to send" );
294             }
295         }
296 
297         if ( AdminUserService.getBooleanSecurityParameter( PARAMETER_NOTIFY_USER_PASSWORD_EXPIRED ) )
298         {
299             // We notify users with expired passwords
300             List<Integer> accountsWithPasswordsExpired = AdminUserHome.getIdUsersWithExpiredPasswordsList( currentTimestamp );
301 
302             if ( ( accountsWithPasswordsExpired != null ) && ( accountsWithPasswordsExpired.size(  ) > 0 ) )
303             {
304                 String strSender = AdminUserService.getSecurityParameter( PARAMETER_PASSWORD_EXPIRED_MAIL_SENDER );
305                 String strSubject = AdminUserService.getSecurityParameter( PARAMETER_PASSWORD_EXPIRED_MAIL_SUBJECT );
306                 String strBody = DatabaseTemplateService.getTemplateFromKey( PARAMETER_CORE_PASSWORD_EXPIRED_ALERT_MAIL );
307 
308                 if ( StringUtils.isNotBlank( strBody ) )
309                 {
310                     for ( Integer nIdUser : accountsWithPasswordsExpired )
311                     {
312                         AdminUser user = AdminUserHome.findByPrimaryKey( nIdUser );
313                         String strUserMail = user.getEmail(  );
314 
315                         if ( StringUtils.isNotBlank( strUserMail ) )
316                         {
317                             Map<String, String> model = new HashMap<String, String>(  );
318                             addParametersToModel( model, nIdUser );
319 
320                             HtmlTemplate template = AppTemplateService.getTemplateFromStringFtl( strBody,
321                                     LocaleService.getDefault(  ), model );
322 
323                             MailService.sendMailHtml( strUserMail, strSender, strSender, strSubject,
324                                 template.getHtml(  ) );
325                         }
326                     }
327                 }
328 
329                 AdminUserHome.updateChangePassword( accountsWithPasswordsExpired );
330                 sbLogs = new StringBuilder(  );
331                 sbLogs.append( "AccountLifeTimeDaemon - " );
332                 sbLogs.append( Integer.toString( accountsWithPasswordsExpired.size(  ) ) );
333                 sbLogs.append( " user(s) have been notified their password has expired" );
334                 AppLogService.info( sbLogs.toString(  ) );
335                 sbResult.append( sbLogs.toString(  ) );
336                 sbResult.append( "\n" );
337             }
338             else
339             {
340                 AppLogService.info( "AccountLifeTimeDaemon - No expired passwords" );
341                 sbResult.append( "AccountLifeTimeDaemon - No expired passwords" );
342             }
343         }
344         else
345         {
346             AppLogService.info( "AccountLifeTimeDaemon - Expired passwords notification deactivated, skipping" );
347             sbResult.append( "AccountLifeTimeDaemon - Expired passwords notification deactivated, skipping" );
348         }
349 
350         setLastRunLogs( sbResult.toString(  ) );
351     }
352 
353     /**
354      * Adds the parameters to model.
355      *
356      * @param model the model
357      * @param nIdUser the n id user
358      */
359     protected void addParametersToModel( Map<String, String> model, Integer nIdUser )
360     {
361         AdminUser user = AdminUserHome.findByPrimaryKey( nIdUser );
362 
363         if ( user.getAccountMaxValidDate(  ) != null )
364         {
365             DateFormat dateFormat = SimpleDateFormat.getDateInstance( DateFormat.SHORT, LocaleService.getDefault(  ) );
366 
367             String accountMaxValidDate = dateFormat.format( new Date( user.getAccountMaxValidDate(  ).getTime(  ) ) );
368 
369             String activationURL = AppPropertiesService.getProperty( PROPERTY_PROD_URL ) + JSP_URL_REACTIVATE_ACCOUNT;
370 
371             model.put( MARK_DATE_VALID, accountMaxValidDate );
372             model.put( MARK_URL, activationURL );
373         }
374 
375         model.put( MARK_LAST_NAME, user.getLastName(  ) );
376         model.put( MARK_FIRST_NAME, user.getFirstName(  ) );
377     }
378 }