View Javadoc
1   /*
2    * Copyright (c) 2002-2021, 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.plugins.mylutece.modules.database.authentication.service;
35  
36  import java.sql.Timestamp;
37  import java.text.DateFormat;
38  import java.text.SimpleDateFormat;
39  import java.util.ArrayList;
40  import java.util.Collection;
41  import java.util.Date;
42  import java.util.HashMap;
43  import java.util.List;
44  import java.util.Locale;
45  import java.util.Map;
46  
47  import javax.servlet.http.HttpServletRequest;
48  
49  import org.apache.commons.lang3.StringUtils;
50  
51  import fr.paris.lutece.api.user.User;
52  import fr.paris.lutece.plugins.mylutece.authentication.MultiLuteceAuthentication;
53  import fr.paris.lutece.plugins.mylutece.business.attribute.AttributeField;
54  import fr.paris.lutece.plugins.mylutece.business.attribute.AttributeFieldHome;
55  import fr.paris.lutece.plugins.mylutece.business.attribute.AttributeHome;
56  import fr.paris.lutece.plugins.mylutece.business.attribute.IAttribute;
57  import fr.paris.lutece.plugins.mylutece.business.attribute.MyLuteceUserField;
58  import fr.paris.lutece.plugins.mylutece.business.attribute.MyLuteceUserFieldFilter;
59  import fr.paris.lutece.plugins.mylutece.business.attribute.MyLuteceUserFieldHome;
60  import fr.paris.lutece.plugins.mylutece.modules.database.authentication.BaseAuthentication;
61  import fr.paris.lutece.plugins.mylutece.modules.database.authentication.BaseUser;
62  import fr.paris.lutece.plugins.mylutece.modules.database.authentication.business.DatabaseHome;
63  import fr.paris.lutece.plugins.mylutece.modules.database.authentication.business.DatabaseUser;
64  import fr.paris.lutece.plugins.mylutece.modules.database.authentication.business.DatabaseUserFieldListener;
65  import fr.paris.lutece.plugins.mylutece.modules.database.authentication.business.DatabaseUserFilter;
66  import fr.paris.lutece.plugins.mylutece.modules.database.authentication.business.DatabaseUserHome;
67  import fr.paris.lutece.plugins.mylutece.modules.database.authentication.business.DatabaseUserRoleRemovalListener;
68  import fr.paris.lutece.plugins.mylutece.modules.database.authentication.business.GroupRoleHome;
69  import fr.paris.lutece.plugins.mylutece.modules.database.authentication.service.parameter.DatabaseUserParameterService;
70  import fr.paris.lutece.plugins.mylutece.service.MyLutecePlugin;
71  import fr.paris.lutece.plugins.mylutece.util.SecurityUtils;
72  import fr.paris.lutece.portal.business.rbac.RBAC;
73  import fr.paris.lutece.portal.business.role.Role;
74  import fr.paris.lutece.portal.business.role.RoleHome;
75  import fr.paris.lutece.portal.business.user.AdminUser;
76  import fr.paris.lutece.portal.service.admin.AdminAuthenticationService;
77  import fr.paris.lutece.portal.service.mail.MailService;
78  import fr.paris.lutece.portal.service.plugin.Plugin;
79  import fr.paris.lutece.portal.service.plugin.PluginService;
80  import fr.paris.lutece.portal.service.rbac.RBACService;
81  import fr.paris.lutece.portal.service.role.RoleRemovalListenerService;
82  import fr.paris.lutece.portal.service.security.LuteceUser;
83  import fr.paris.lutece.portal.service.security.SecurityService;
84  import fr.paris.lutece.portal.service.spring.SpringContextService;
85  import fr.paris.lutece.portal.service.template.AppTemplateService;
86  import fr.paris.lutece.portal.service.template.DatabaseTemplateService;
87  import fr.paris.lutece.portal.service.util.AppLogService;
88  import fr.paris.lutece.portal.service.workgroup.AdminWorkgroupService;
89  import fr.paris.lutece.util.ReferenceItem;
90  import fr.paris.lutece.util.html.HtmlTemplate;
91  import fr.paris.lutece.util.password.IPasswordFactory;
92  import fr.paris.lutece.util.url.UrlItem;
93  import fr.paris.lutece.util.xml.XmlUtil;
94  
95  /**
96   *
97   * DatabaseService
98   *
99   */
100 public final class DatabaseService
101 {
102     private static final String BEAN_DATABASE_SERVICE = "mylutece-database.databaseService";
103     private static final String AUTHENTICATION_BEAN_NAME = "mylutece-database.authentication";
104 
105     // CONSTANTS
106     private static final String AMPERSAND = "&";
107     private static final String PLUGIN_JCAPTCHA = "jcaptcha";
108     private static final String CONSTANT_XML_USER = "user";
109     private static final String CONSTANT_XML_ACCESS_CODE = "access_code";
110     private static final String CONSTANT_XML_LAST_NAME = "last_name";
111     private static final String CONSTANT_XML_FIRST_NAME = "first_name";
112     private static final String CONSTANT_XML_EMAIL = "email";
113     private static final String CONSTANT_XML_STATUS = "status";
114     private static final String CONSTANT_XML_PASSWORD_MAX_VALID_DATE = "password_max_valid_date";
115     private static final String CONSTANT_XML_ACCOUNT_MAX_VALID_DATE = "account_max_valid_date";
116     private static final String CONSTANT_XML_ROLES = "roles";
117     private static final String CONSTANT_XML_GROUPS = "groups";
118     private static final String CONSTANT_XML_ROLE = "role";
119     private static final String CONSTANT_XML_GROUP = "group";
120     private static final String CONSTANT_XML_ATTRIBUTES = "attributes";
121     private static final String CONSTANT_XML_ATTRIBUTE = "attribute";
122     private static final String CONSTANT_XML_ATTRIBUTE_ID = "attribute-id";
123     private static final String CONSTANT_XML_ATTRIBUTE_FIELD_ID = "attribute-field-id";
124     private static final String CONSTANT_XML_ATTRIBUTE_VALUE = "attribute-value";
125 
126     // MARKS
127     private static final String MARK_SEARCH_IS_SEARCH = "search_is_search";
128     private static final String MARK_SORT_SEARCH_ATTRIBUTE = "sort_search_attribute";
129     private static final String MARK_SEARCH_USER_FILTER = "search_user_filter";
130     private static final String MARK_SEARCH_MYLUTECE_USER_FIELD_FILTER = "search_mylutece_user_field_filter";
131     private static final String MARK_ATTRIBUTES_LIST = "attributes_list";
132     private static final String MARK_IS_PLUGIN_JCAPTCHA_ENABLE = "is_plugin_jcatpcha_enable";
133     private static final String MARK_LOGIN_URL = "login_url";
134     private static final String MARK_NEW_PASSWORD = "new_password";
135     private static final String MARK_ENABLE_JCAPTCHA = "enable_jcaptcha";
136     private static final String MARK_SITE_LINK = "site_link";
137     private static final String MARK_BANNED_DOMAIN_NAMES = "banned_domain_names";
138 
139     // PARAMETERS
140     private static final String PARAMETER_ACCOUNT_CREATION_VALIDATION_EMAIL = "account_creation_validation_email";
141     private static final String PARAMETER_ACCOUNT_REACTIVATED_MAIL_SENDER = "account_reactivated_mail_sender";
142     private static final String PARAMETER_ACCOUNT_REACTIVATED_MAIL_SUBJECT = "account_reactivated_mail_subject";
143     private static final String PARAMETER_ACCOUNT_REACTIVATED_MAIL_BODY = "mylutece_database_account_reactivated_mail";
144     private static final String PARAMETER_MAIL_PASSWORD_ENCRYPTION_CHANGED = "mylutece_database_mailPasswordEncryptionChanged";
145     private static final String PARAMETER_MAIL_PASSWORD_ENCRYPTION_CHANGED_SENDER = "mail_password_encryption_changed_sender";
146     private static final String PARAMETER_MAIL_PASSWORD_ENCRYPTION_CHANGED_SUBJECT = "mail_password_encryption_changed_subject";
147     private static final String PARAMETER_AUTO_LOGIN_AFTER_VALIDATION_EMAIL = "auto_login_after_validation_email";
148 
149     // VARIABLES
150     private static DatabaseService _singleton;
151     private DatabaseUserParameterService _userParamService;
152     private BaseAuthentication _baseAuthentication;
153     private IPasswordFactory _passwordFactory;
154 
155     /**
156      * Private constructor
157      */
158     private DatabaseService( )
159     {
160     }
161 
162     /**
163      * Set the database user parameter service
164      * 
165      * @param userParamService
166      *            the user parameter service
167      */
168     public void setDatabaseUserParameterService( DatabaseUserParameterService userParamService )
169     {
170         _userParamService = userParamService;
171     }
172 
173     /**
174      * Set the password factory
175      * 
176      * @param passwordFactory
177      *            the password factory
178      */
179     public void setPasswordFactory( IPasswordFactory passwordFactory )
180     {
181         _passwordFactory = passwordFactory;
182     }
183 
184     /**
185      * Initialize the Database service
186      *
187      */
188     public void init( )
189     {
190         RoleRemovalListenerService.getService( ).registerListener( new DatabaseUserRoleRemovalListener( ) );
191         DatabaseMyLuteceUserFieldListenerService.getService( ).registerListener( new DatabaseUserFieldListener( ) );
192 
193         _baseAuthentication = SpringContextService.getBean( AUTHENTICATION_BEAN_NAME );
194 
195         if ( _baseAuthentication != null )
196         {
197             MultiLuteceAuthentication.registerAuthentication( _baseAuthentication );
198         }
199         else
200         {
201             AppLogService.error( "BaseAuthentication not found, please check your database_context.xml configuration" );
202         }
203     }
204 
205     /**
206      * Returns the instance of the singleton
207      * 
208      * @return The instance of the singleton
209      */
210     public static synchronized DatabaseService getService( )
211     {
212         if ( _singleton == null )
213         {
214             _singleton = SpringContextService.getBean( BEAN_DATABASE_SERVICE );
215         }
216 
217         return _singleton;
218     }
219 
220     /**
221      * Build the advanced parameters management
222      * 
223      * @param user
224      *            the admin user
225      * @return The model for the advanced parameters
226      */
227     public Map<String, Object> getManageAdvancedParameters( AdminUser user )
228     {
229         Map<String, Object> model = new HashMap<>( );
230         Plugin plugin = PluginService.getPlugin( DatabasePlugin.PLUGIN_NAME );
231 
232         if ( RBACService.isAuthorized( DatabaseResourceIdService.RESOURCE_TYPE, RBAC.WILDCARD_RESOURCES_ID, DatabaseResourceIdService.PERMISSION_MANAGE,
233                 (User) user ) )
234         {
235             model.put( MARK_IS_PLUGIN_JCAPTCHA_ENABLE, isPluginJcaptchaEnable( ) );
236 
237             if ( isPluginJcaptchaEnable( ) )
238             {
239                 model.put( MARK_ENABLE_JCAPTCHA, SecurityUtils.getBooleanSecurityParameter( _userParamService, plugin, MARK_ENABLE_JCAPTCHA ) );
240             }
241 
242             model.put( PARAMETER_ACCOUNT_CREATION_VALIDATION_EMAIL,
243                     SecurityUtils.getBooleanSecurityParameter( _userParamService, plugin, PARAMETER_ACCOUNT_CREATION_VALIDATION_EMAIL ) );
244 
245             model.put( PARAMETER_AUTO_LOGIN_AFTER_VALIDATION_EMAIL,
246                     SecurityUtils.getBooleanSecurityParameter( _userParamService, plugin, PARAMETER_AUTO_LOGIN_AFTER_VALIDATION_EMAIL ) );
247 
248             model.put( MARK_BANNED_DOMAIN_NAMES, SecurityUtils.getLargeSecurityParameter( _userParamService, plugin, MARK_BANNED_DOMAIN_NAMES ) );
249 
250             model = SecurityUtils.checkSecurityParameters( _userParamService, model, plugin );
251         }
252 
253         return model;
254     }
255 
256     /**
257      * Check if an Lutece user should be visible to the user according its workgroup
258      * 
259      * @param user
260      *            the Lutece user
261      * @param adminUser
262      *            the admin user
263      * @param plugin
264      *            the plugin
265      * @return true if the Lutece user should be visible, false otherwise
266      */
267     public boolean isAuthorized( DatabaseUser user, AdminUser adminUser, Plugin plugin )
268     {
269         boolean bHasRole = false;
270         List<String> userRoleKeyList = DatabaseHome.findUserRolesFromLogin( user.getLogin( ), plugin );
271 
272         for ( String userRoleKey : userRoleKeyList )
273         {
274             bHasRole = true;
275 
276             Role role = RoleHome.findByPrimaryKey( userRoleKey );
277 
278             if ( AdminWorkgroupService.isAuthorized( role, (User) adminUser ) )
279             {
280                 return true;
281             }
282         }
283 
284         List<String> userGroupKeyList = DatabaseHome.findUserGroupsFromLogin( user.getLogin( ), plugin );
285 
286         for ( String userGroupKey : userGroupKeyList )
287         {
288             List<String> groupRoleKeyList = GroupRoleHome.findGroupRoles( userGroupKey, plugin );
289 
290             for ( String groupRoleKey : groupRoleKeyList )
291             {
292                 bHasRole = true;
293 
294                 Role role = RoleHome.findByPrimaryKey( groupRoleKey );
295 
296                 if ( AdminWorkgroupService.isAuthorized( role, (User) adminUser ) )
297                 {
298                     return true;
299                 }
300             }
301         }
302 
303         return !bHasRole;
304     }
305 
306     /**
307      * Get authorized users list
308      * 
309      * @param adminUser
310      *            the admin user
311      * @param plugin
312      *            the plugin
313      * @return a list of users
314      */
315     public List<DatabaseUser> getAuthorizedUsers( AdminUser adminUser, Plugin plugin )
316     {
317         Collection<DatabaseUser> userList = DatabaseUserHome.findDatabaseUsersList( plugin );
318         List<DatabaseUser> authorizedUserList = new ArrayList<>( );
319 
320         for ( DatabaseUser user : userList )
321         {
322             if ( isAuthorized( user, adminUser, plugin ) )
323             {
324                 authorizedUserList.add( user );
325             }
326         }
327 
328         return authorizedUserList;
329     }
330 
331     /**
332      * Get the filtered list of database users
333      * 
334      * @param duFilter
335      *            The filter
336      * @param bIsSearch
337      *            True if the user used search filters, false otherwise
338      * @param listUsers
339      *            the initial list to filter
340      * @param request
341      *            HttpServletRequest
342      * @param model
343      *            Map
344      * @param url
345      *            UrlItem
346      * @return the filtered list
347      */
348     public List<DatabaseUser> getFilteredUsersInterface( DatabaseUserFilter duFilter, boolean bIsSearch, List<DatabaseUser> listUsers,
349             HttpServletRequest request, Map<String, Object> model, UrlItem url )
350     {
351         Plugin myLutecePlugin = PluginService.getPlugin( MyLutecePlugin.PLUGIN_NAME );
352         List<DatabaseUser> filteredUsers = getListFilteredUsers( request, duFilter, listUsers );
353         MyLuteceUserFieldFilter mlFieldFilter = new MyLuteceUserFieldFilter( );
354         mlFieldFilter.setMyLuteceUserFieldFilter( request, request.getLocale( ) );
355 
356         List<IAttribute> listAttributes = AttributeHome.findAll( request.getLocale( ), myLutecePlugin );
357 
358         for ( IAttribute attribute : listAttributes )
359         {
360             List<AttributeField> listAttributeFields = AttributeFieldHome.selectAttributeFieldsByIdAttribute( attribute.getIdAttribute( ), myLutecePlugin );
361             attribute.setListAttributeFields( listAttributeFields );
362         }
363 
364         String strSortSearchAttribute = StringUtils.EMPTY;
365 
366         if ( bIsSearch )
367         {
368             duFilter.setUrlAttributes( url );
369 
370             if ( !StringUtils.EMPTY.equals( duFilter.getUrlAttributes( ) ) )
371             {
372                 strSortSearchAttribute = AMPERSAND + duFilter.getUrlAttributes( );
373             }
374 
375             mlFieldFilter.setUrlAttributes( url );
376 
377             if ( !StringUtils.EMPTY.equals( mlFieldFilter.getUrlAttributes( ) ) )
378             {
379                 strSortSearchAttribute += ( AMPERSAND + mlFieldFilter.getUrlAttributes( ) );
380             }
381         }
382 
383         model.put( MARK_SEARCH_IS_SEARCH, bIsSearch );
384         model.put( MARK_SEARCH_USER_FILTER, duFilter );
385         model.put( MARK_SORT_SEARCH_ATTRIBUTE, strSortSearchAttribute );
386         model.put( MARK_SEARCH_MYLUTECE_USER_FIELD_FILTER, mlFieldFilter );
387         model.put( MARK_ATTRIBUTES_LIST, listAttributes );
388 
389         return filteredUsers;
390     }
391 
392     /**
393      * Get th list of filteredUsers
394      * 
395      * @param request
396      *            the HTTP request
397      * @param duFilter
398      *            the filter
399      * @param listUsers
400      *            the list of users
401      * @return a list of {@link DatabaseUser}
402      */
403     public List<DatabaseUser> getListFilteredUsers( HttpServletRequest request, DatabaseUserFilter duFilter, List<DatabaseUser> listUsers )
404     {
405         Plugin plugin = PluginService.getPlugin( DatabasePlugin.PLUGIN_NAME );
406 
407         List<DatabaseUser> listFilteredUsers = DatabaseUserHome.findDatabaseUsersListByFilter( duFilter, plugin );
408         List<DatabaseUser> listAvailableUsers = new ArrayList<>( );
409 
410         for ( DatabaseUser filteredUser : listFilteredUsers )
411         {
412             for ( DatabaseUser user : listUsers )
413             {
414                 if ( filteredUser.getUserId( ) == user.getUserId( ) )
415                 {
416                     listAvailableUsers.add( user );
417                 }
418             }
419         }
420 
421         Plugin myLutecePlugin = PluginService.getPlugin( MyLutecePlugin.PLUGIN_NAME );
422         List<DatabaseUser> filteredUsers = new ArrayList<>( );
423 
424         MyLuteceUserFieldFilter mlFieldFilter = new MyLuteceUserFieldFilter( );
425         mlFieldFilter.setMyLuteceUserFieldFilter( request, request.getLocale( ) );
426 
427         List<Integer> listFilteredUserIdsByUserFields = MyLuteceUserFieldHome.findUsersByFilter( mlFieldFilter, myLutecePlugin );
428 
429         if ( listFilteredUserIdsByUserFields != null )
430         {
431             for ( DatabaseUser filteredUser : listAvailableUsers )
432             {
433                 for ( Integer nFilteredUserIdByUserField : listFilteredUserIdsByUserFields )
434                 {
435                     if ( filteredUser.getUserId( ) == nFilteredUserIdByUserField )
436                     {
437                         filteredUsers.add( filteredUser );
438                     }
439                 }
440             }
441         }
442         else
443         {
444             filteredUsers = listAvailableUsers;
445         }
446 
447         return filteredUsers;
448     }
449 
450     /**
451      * Do create a new database user
452      * 
453      * @param user
454      *            the user
455      * @param strPassword
456      *            the password
457      * @param plugin
458      *            the plugin
459      * @return the new database user with a new ID
460      */
461     public DatabaseUser./../../../../../fr/paris/lutece/plugins/mylutece/modules/database/authentication/business/DatabaseUser.html#DatabaseUser">DatabaseUser doCreateUser( DatabaseUser user, String strPassword, Plugin plugin )
462     {
463         user.setPasswordMaxValidDate( SecurityUtils.getPasswordMaxValidDate( _userParamService, plugin ) );
464         user.setAccountMaxValidDate( SecurityUtils.getAccountMaxValidDate( _userParamService, plugin ) );
465 
466         return DatabaseUserHome.create( user, _passwordFactory.getPasswordFromCleartext( strPassword ), plugin );
467     }
468 
469     /**
470      * Do modify the password
471      * 
472      * @param user
473      *            the DatabaseUser
474      * @param strPassword
475      *            the new password not encrypted
476      * @param plugin
477      *            the plugin
478      */
479     public void doModifyPassword( DatabaseUser user, String strPassword, Plugin plugin )
480     {
481         // Updates password
482         if ( StringUtils.isNotBlank( strPassword ) )
483         {
484             DatabaseUser userStored = DatabaseUserHome.findByPrimaryKey( user.getUserId( ), plugin );
485 
486             if ( userStored != null )
487             {
488                 userStored.setPasswordMaxValidDate( SecurityUtils.getPasswordMaxValidDate( _userParamService, plugin ) );
489                 DatabaseUserHome.updatePassword( userStored, _passwordFactory.getPasswordFromCleartext( strPassword ), plugin );
490             }
491         }
492     }
493 
494     /**
495      * Do modify the reset password attribute
496      * 
497      * @param user
498      *            the DatabaseUser
499      * @param bNewValue
500      *            the new value
501      * @param plugin
502      *            the plugin
503      */
504     public void doModifyResetPassword( DatabaseUser user, boolean bNewValue, Plugin plugin )
505     {
506         DatabaseUser userStored = DatabaseUserHome.findByPrimaryKey( user.getUserId( ), plugin );
507 
508         if ( userStored != null )
509         {
510             DatabaseUserHome.updateResetPassword( userStored, bNewValue, plugin );
511         }
512     }
513 
514     /**
515      * Update the info of the user
516      * 
517      * @param user
518      *            the user
519      * @param plugin
520      *            the plugin
521      */
522     public void doUpdateUser( DatabaseUser user, Plugin plugin )
523     {
524         DatabaseUserHome.update( user, plugin );
525     }
526 
527     /**
528      * Check the password
529      * 
530      * @param strUserGuid
531      *            the user guid
532      * @param strPassword
533      *            the password
534      * @param plugin
535      *            the plugin
536      * @return true if the password is the same as stored in the database, false otherwise
537      */
538     public boolean checkPassword( String strUserGuid, String strPassword, Plugin plugin )
539     {
540         return DatabaseUserHome.checkPassword( strUserGuid, strPassword, plugin );
541     }
542 
543     /**
544      * Check if the user is active or not
545      * 
546      * @param strUserName
547      *            the user name
548      * @param plugin
549      *            the plugin
550      * @return true if it is active, false otherwise
551      */
552     public boolean isUserActive( String strUserName, Plugin plugin )
553     {
554         boolean bIsActive = false;
555 
556         List<DatabaseUser> listUsers = (List<DatabaseUser>) DatabaseUserHome.findDatabaseUsersListForLogin( strUserName, plugin );
557 
558         if ( ( listUsers != null ) && !listUsers.isEmpty( ) )
559         {
560             DatabaseUser user = listUsers.get( 0 );
561             bIsActive = user.isActive( );
562         }
563 
564         return bIsActive;
565     }
566 
567     /**
568      * Check if the plugin jcaptcha is activated or not
569      * 
570      * @return true if it is activated, false otherwise
571      */
572     public boolean isPluginJcaptchaEnable( )
573     {
574         return PluginService.isPluginEnable( PLUGIN_JCAPTCHA );
575     }
576 
577     /**
578      * Change all user's password and notify them with an email.
579      * 
580      * @param strBaseURL
581      *            The base url of the application
582      * @param plugin
583      *            The plugin
584      * @param locale
585      *            The locale to use
586      */
587     public void changeUserPasswordAndNotify( String strBaseURL, Plugin plugin, Locale locale )
588     {
589         // Alert all users their password have been reinitialized.
590         Collection<DatabaseUser> listUsers = DatabaseUserHome.findDatabaseUsersList( plugin );
591 
592         for ( DatabaseUser user : listUsers )
593         {
594             // Makes password
595             String strPassword = SecurityUtils.makePassword( _userParamService, plugin );
596             doModifyPassword( user, strPassword, plugin );
597 
598             if ( StringUtils.isNotBlank( user.getEmail( ) ) )
599             {
600                 // Sends password by e-mail
601                 ReferenceItem referenceItem = _userParamService.findByKey( PARAMETER_MAIL_PASSWORD_ENCRYPTION_CHANGED_SENDER, plugin );
602                 String strSenderEmail = ( referenceItem == null ) ? StringUtils.EMPTY : referenceItem.getName( );
603                 referenceItem = _userParamService.findByKey( PARAMETER_MAIL_PASSWORD_ENCRYPTION_CHANGED_SUBJECT, plugin );
604 
605                 String strEmailSubject = ( referenceItem == null ) ? StringUtils.EMPTY : referenceItem.getName( );
606 
607                 Map<String, Object> model = new HashMap<>( );
608                 model.put( MARK_NEW_PASSWORD, strPassword );
609                 model.put( MARK_LOGIN_URL, strBaseURL + AdminAuthenticationService.getInstance( ).getLoginPageUrl( ) );
610                 model.put( MARK_SITE_LINK, MailService.getSiteLink( strBaseURL, true ) );
611 
612                 String strTemplate = DatabaseTemplateService.getTemplateFromKey( PARAMETER_MAIL_PASSWORD_ENCRYPTION_CHANGED );
613 
614                 HtmlTemplate template = AppTemplateService.getTemplateFromStringFtl( strTemplate, locale, model );
615 
616                 MailService.sendMailHtml( user.getEmail( ), strSenderEmail, strSenderEmail, strEmailSubject, template.getHtml( ) );
617             }
618         }
619     }
620 
621     /**
622      * Check whether a user must change his password
623      * 
624      * @param databaseUser
625      *            The user to check
626      * @param plugin
627      *            The plugin
628      * @return True if a user must change his password, false otherwise.
629      */
630     public boolean mustUserChangePassword( LuteceUser databaseUser, Plugin plugin )
631     {
632         return DatabaseHome.findResetPasswordFromLogin( databaseUser.getName( ), plugin );
633     }
634 
635     /**
636      * Log a password change in the password history
637      * 
638      * @param strPassword
639      *            New password of the user
640      * @param nUserId
641      *            Id of the user
642      * @param plugin
643      *            The plugin
644      */
645     public void doInsertNewPasswordInHistory( String strPassword, int nUserId, Plugin plugin )
646     {
647         DatabaseUserHome.insertNewPasswordInHistory( _passwordFactory.getPasswordFromCleartext( strPassword ), nUserId, plugin );
648     }
649 
650     /**
651      * Update the user expiration date with new values, and notify him with an email.
652      * 
653      * @param nIdUser
654      *            Id of the user to update
655      * @param plugin
656      *            The plugin
657      */
658     @SuppressWarnings( "deprecation" )
659     public void updateUserExpirationDate( int nIdUser, Plugin plugin )
660     {
661         // We update the user account
662         int nbMailSend = DatabaseUserHome.getNbAccountLifeTimeNotification( nIdUser, plugin );
663         Timestamp newExpirationDate = SecurityUtils.getAccountMaxValidDate( _userParamService, plugin );
664         DatabaseUserHome.updateUserExpirationDate( nIdUser, newExpirationDate, plugin );
665 
666         // We notify the user
667         DatabaseAccountLifeTimeServicehentication/service/DatabaseAccountLifeTimeService.html#DatabaseAccountLifeTimeService">DatabaseAccountLifeTimeService accountLifeTimeService = new DatabaseAccountLifeTimeService( );
668         String strUserMail = accountLifeTimeService.getUserMainEmail( nIdUser );
669 
670         if ( ( nbMailSend > 0 ) && StringUtils.isNotBlank( strUserMail ) )
671         {
672             String strBody = DatabaseTemplateService.getTemplateFromKey( PARAMETER_ACCOUNT_REACTIVATED_MAIL_BODY );
673 
674             ReferenceItem referenceItem = _userParamService.findByKey( PARAMETER_ACCOUNT_REACTIVATED_MAIL_SENDER, plugin );
675             String strSender = ( referenceItem == null ) ? StringUtils.EMPTY : referenceItem.getName( );
676 
677             referenceItem = _userParamService.findByKey( PARAMETER_ACCOUNT_REACTIVATED_MAIL_SUBJECT, plugin );
678 
679             String strSubject = ( referenceItem == null ) ? StringUtils.EMPTY : referenceItem.getName( );
680 
681             Map<String, String> model = new HashMap<>( );
682             accountLifeTimeService.addParametersToModel( model, nIdUser );
683 
684             HtmlTemplate template = AppTemplateService.getTemplateFromStringFtl( strBody, Locale.getDefault( ), model );
685             MailService.sendMailHtml( strUserMail, strSender, strSender, strSubject, template.getHtml( ) );
686         }
687     }
688 
689     /**
690      * Update a user last login date.
691      * 
692      * @param strLogin
693      *            Login of the user to update
694      * @param plugin
695      *            The plugin
696      */
697     public void updateUserLastLoginDate( String strLogin, Plugin plugin )
698     {
699         DatabaseUserHome.updateUserLastLoginDate( strLogin, new Date( ), plugin );
700     }
701 
702     /**
703      * Get a XML string describing a given user
704      * 
705      * @param user
706      *            The user to get the XML of.
707      * @param bExportRoles
708      *            True to export roles of the user, false otherwise.
709      * @param bExportGroups
710      *            True to export groups of the user, false otherwise.
711      * @param bExportAttributes
712      *            True to export attributes of the user, false otherwise.
713      * @param listAttributes
714      *            The list of attributes to export.
715      * @param locale
716      *            The locale
717      * @return A string of XML with the information of the user.
718      */
719     public String getXmlFromUser( DatabaseUser user, boolean bExportRoles, boolean bExportGroups, boolean bExportAttributes, List<IAttribute> listAttributes,
720             Locale locale )
721     {
722         Plugin databasePlugin = PluginService.getPlugin( DatabasePlugin.PLUGIN_NAME );
723         Plugin mylutecePlugin = PluginService.getPlugin( MyLutecePlugin.PLUGIN_NAME );
724         StringBuffer sbXml = new StringBuffer( );
725         DateFormat dateFormat = new SimpleDateFormat( );
726 
727         XmlUtil.beginElement( sbXml, CONSTANT_XML_USER );
728         XmlUtil.addElement( sbXml, CONSTANT_XML_ACCESS_CODE, user.getLogin( ) );
729         XmlUtil.addElement( sbXml, CONSTANT_XML_LAST_NAME, user.getLastName( ) );
730         XmlUtil.addElement( sbXml, CONSTANT_XML_FIRST_NAME, user.getFirstName( ) );
731         XmlUtil.addElement( sbXml, CONSTANT_XML_EMAIL, user.getEmail( ) );
732         XmlUtil.addElement( sbXml, CONSTANT_XML_STATUS, Integer.toString( user.getStatus( ) ) );
733 
734         String strPasswordMaxValidDate = StringUtils.EMPTY;
735 
736         if ( user.getPasswordMaxValidDate( ) != null )
737         {
738             strPasswordMaxValidDate = dateFormat.format( user.getPasswordMaxValidDate( ) );
739         }
740 
741         XmlUtil.addElement( sbXml, CONSTANT_XML_PASSWORD_MAX_VALID_DATE, strPasswordMaxValidDate );
742 
743         String strAccountMaxValidDate = StringUtils.EMPTY;
744 
745         if ( user.getAccountMaxValidDate( ) != null )
746         {
747             strAccountMaxValidDate = dateFormat.format( user.getAccountMaxValidDate( ) );
748         }
749 
750         XmlUtil.addElement( sbXml, CONSTANT_XML_ACCOUNT_MAX_VALID_DATE, strAccountMaxValidDate );
751 
752         if ( bExportRoles )
753         {
754             List<String> listRoles = DatabaseHome.findUserRolesFromLogin( user.getLogin( ), databasePlugin );
755             XmlUtil.beginElement( sbXml, CONSTANT_XML_ROLES );
756 
757             for ( String strRole : listRoles )
758             {
759                 XmlUtil.addElement( sbXml, CONSTANT_XML_ROLE, strRole );
760             }
761 
762             XmlUtil.endElement( sbXml, CONSTANT_XML_ROLES );
763         }
764 
765         if ( bExportGroups )
766         {
767             List<String> listGroups = DatabaseHome.findUserGroupsFromLogin( user.getLogin( ), databasePlugin );
768             XmlUtil.beginElement( sbXml, CONSTANT_XML_GROUPS );
769 
770             for ( String strGoup : listGroups )
771             {
772                 XmlUtil.addElement( sbXml, CONSTANT_XML_GROUP, strGoup );
773             }
774 
775             XmlUtil.endElement( sbXml, CONSTANT_XML_GROUPS );
776         }
777 
778         if ( bExportAttributes )
779         {
780             XmlUtil.beginElement( sbXml, CONSTANT_XML_ATTRIBUTES );
781 
782             for ( IAttribute attribute : listAttributes )
783             {
784                 List<MyLuteceUserField> listUserFields = MyLuteceUserFieldHome.selectUserFieldsByIdUserIdAttribute( user.getUserId( ),
785                         attribute.getIdAttribute( ), mylutecePlugin );
786 
787                 for ( MyLuteceUserField userField : listUserFields )
788                 {
789                     XmlUtil.beginElement( sbXml, CONSTANT_XML_ATTRIBUTE );
790                     XmlUtil.addElement( sbXml, CONSTANT_XML_ATTRIBUTE_ID, Integer.toString( attribute.getIdAttribute( ) ) );
791                     XmlUtil.addElement( sbXml, CONSTANT_XML_ATTRIBUTE_FIELD_ID, userField.getAttributeField( ).getIdField( ) );
792                     XmlUtil.addElement( sbXml, CONSTANT_XML_ATTRIBUTE_VALUE, userField.getValue( ) );
793                     XmlUtil.endElement( sbXml, CONSTANT_XML_ATTRIBUTE );
794                 }
795             }
796 
797             XmlUtil.endElement( sbXml, CONSTANT_XML_ATTRIBUTES );
798         }
799 
800         XmlUtil.endElement( sbXml, CONSTANT_XML_USER );
801 
802         return sbXml.toString( );
803     }
804 
805     /**
806      * Login automatically the database user
807      * 
808      * @param request
809      *            the HTTP request
810      * @param DatabaseUser
811      *            databaseUser
812      * @param plugin
813      *            the plugin
814      */
815     public void doAutoLoginDatabaseUser( HttpServletRequest request, DatabaseUser databaseUser, Plugin plugin )
816     {
817         if ( _baseAuthentication != null )
818         {
819             BaseUser user = DatabaseHome.findLuteceUserByLogin( databaseUser.getLogin( ), plugin, _baseAuthentication );
820             SecurityService.getInstance( ).registerUser( request, user );
821         }
822     }
823 }