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.admin;
35  
36  import fr.paris.lutece.portal.business.rbac.AdminRole;
37  import fr.paris.lutece.portal.business.rbac.RBAC;
38  import fr.paris.lutece.portal.business.regularexpression.RegularExpression;
39  import fr.paris.lutece.portal.business.right.Level;
40  import fr.paris.lutece.portal.business.right.LevelHome;
41  import fr.paris.lutece.portal.business.right.Right;
42  import fr.paris.lutece.portal.business.user.AdminUser;
43  import fr.paris.lutece.portal.business.user.AdminUserFilter;
44  import fr.paris.lutece.portal.business.user.AdminUserHome;
45  import fr.paris.lutece.portal.business.user.attribute.AdminUserField;
46  import fr.paris.lutece.portal.business.user.attribute.AdminUserFieldFilter;
47  import fr.paris.lutece.portal.business.user.attribute.AdminUserFieldHome;
48  import fr.paris.lutece.portal.business.user.attribute.IAttribute;
49  import fr.paris.lutece.portal.business.user.parameter.DefaultUserParameterHome;
50  import fr.paris.lutece.portal.business.workgroup.AdminWorkgroupHome;
51  import fr.paris.lutece.portal.service.datastore.DatastoreService;
52  import fr.paris.lutece.portal.service.i18n.I18nService;
53  import fr.paris.lutece.portal.service.mail.MailService;
54  import fr.paris.lutece.portal.service.message.AdminMessage;
55  import fr.paris.lutece.portal.service.message.AdminMessageService;
56  import fr.paris.lutece.portal.service.plugin.PluginService;
57  import fr.paris.lutece.portal.service.portal.PortalService;
58  import fr.paris.lutece.portal.service.rbac.RBACService;
59  import fr.paris.lutece.portal.service.regularexpression.RegularExpressionService;
60  import fr.paris.lutece.portal.service.spring.SpringContextService;
61  import fr.paris.lutece.portal.service.template.AppTemplateService;
62  import fr.paris.lutece.portal.service.template.DatabaseTemplateService;
63  import fr.paris.lutece.portal.service.user.AdminUserResourceIdService;
64  import fr.paris.lutece.portal.service.user.attribute.AdminUserFieldService;
65  import fr.paris.lutece.portal.service.user.attribute.AttributeService;
66  import fr.paris.lutece.portal.service.util.AppPropertiesService;
67  import fr.paris.lutece.portal.service.util.CryptoService;
68  import fr.paris.lutece.portal.web.l10n.LocaleService;
69  import fr.paris.lutece.util.ReferenceItem;
70  import fr.paris.lutece.util.ReferenceList;
71  import fr.paris.lutece.util.date.DateUtil;
72  import fr.paris.lutece.util.html.HtmlTemplate;
73  import fr.paris.lutece.util.password.IPassword;
74  import fr.paris.lutece.util.password.IPasswordFactory;
75  import fr.paris.lutece.util.password.PasswordUtil;
76  import fr.paris.lutece.util.url.UrlItem;
77  import fr.paris.lutece.util.xml.XmlUtil;
78  
79  import org.apache.commons.lang.StringUtils;
80  
81  import java.sql.Timestamp;
82  import java.text.DateFormat;
83  import java.text.SimpleDateFormat;
84  import java.util.ArrayList;
85  import java.util.Calendar;
86  import java.util.Collection;
87  import java.util.Date;
88  import java.util.GregorianCalendar;
89  import java.util.HashMap;
90  import java.util.List;
91  import java.util.Locale;
92  import java.util.Map;
93  import java.util.Map.Entry;
94  
95  import javax.servlet.http.HttpServletRequest;
96  
97  
98  /**
99   * This service provides features concerning the administration users
100  */
101 public final class AdminUserService
102 {
103     // DataStore keys
104     public static final String DSKEY_ACCOUNT_REACTIVATED_MAIL_SENDER = "core.advanced_parameters.account_reactivated_mail_sender";
105     public static final String DSKEY_ACCOUNT_REACTIVATED_MAIL_SUBJECT = "core.advanced_parameters.account_reactivated_mail_subject";
106     public static final String DSKEY_ACCOUNT_REACTIVATED_MAIL_BODY = "core_account_reactivated_mail";
107     public static final String DSKEY_PASSWORD_DURATION = "core.advanced_parameters.password_duration";
108     public static final String DSKEY_MAXIMUM_NUMBER_PASSWORD_CHANGE = "core.advanced_parameters.maximum_number_password_change";
109     public static final String DSKEY_PASSWORD_HISTORY_SIZE = "core.advanced_parameters.password_history_size";
110     public static final String DSKEY_TSW_SIZE_PASSWORD_CHANGE = "core.advanced_parameters.tsw_size_password_change";
111     public static final String DSKEY_NOTIFY_USER_PASSWORD_EXPIRED = "core.advanced_parameters.notify_user_password_expired";
112     public static final String DSKEY_BANNED_DOMAIN_NAMES = "banned_domain_names";
113     public static final String DSKEY_ACCOUNT_LIFE_TIME = "core.advanced_parameters.account_life_time";
114     public static final String DSKEY_TIME_BEFORE_ALERT_ACCOUNT = "core.advanced_parameters.time_before_alert_account";
115     public static final String DSKEY_NB_ALERT_ACCOUNT = "core.advanced_parameters.nb_alert_account";
116     public static final String DSKEY_TIME_BETWEEN_ALERTS_ACCOUNT = "core.advanced_parameters.time_between_alerts_account";
117     public static final String DSKEY_ACCES_FAILURES_MAX = "core.advanced_parameters.access_failures_max";
118     public static final String DSKEY_ACCES_FAILURES_INTERVAL = "core.advanced_parameters.access_failures_interval";
119     public static final String DSKEY_EMAIL_PATTERN = "core.advanced_parameters.email_pattern";
120     public static final String DSKEY_EMAIL_PATTERN_VERIFY_BY = "core.advanced_parameters.email_pattern_verify_by";
121     public static final String DSKEY_PASSWORD_FORMAT_SPECIAL_CHARACTERS = "core.advanced_parameters.password_format_special_characters";
122     public static final String DSKEY_PASSWORD_FORMAT_NUMERO = "core.advanced_parameters.password_format_numero";
123     public static final String DSKEY_PASSWORD_FORMAT_UPPER_LOWER_CASE = "core.advanced_parameters.password_format_upper_lower_case";
124     public static final String DSKEY_FORCE_CHANGE_PASSWORD_REINIT = "core.advanced_parameters.force_change_password_reinit";
125     public static final String DSKEY_PASSWORD_MINIMUM_LENGTH = "core.advanced_parameters.password_minimum_length";
126     public static final String DSKEY_DEFAULT_USER_STATUS = "core.advanced_parameters.default_user_status";
127     public static final String DSKEY_DEFAULT_USER_LANGUAGE = "core.advanced_parameters.default_user_language";
128     public static final String DSKEY_DEFAULT_USER_NOTIFICATION = "core.advanced_parameters.default_user_notification";
129     public static final String DSKEY_DEFAULT_USER_LEVEL = "core.advanced_parameters.default_user_level";
130     public static final String DSKEY_USE_ADVANCED_SECURITY_PARAMETERS = "core.advanced_parameters.use_advanced_security_parameters";
131 
132     // Parameter
133     private static final String PARAMETER_ACCESS_CODE = "access_code";
134     private static final String PARAMETER_LAST_NAME = "last_name";
135     private static final String PARAMETER_FIRST_NAME = "first_name";
136     private static final String PARAMETER_EMAIL = "email";
137 
138     // Markers
139     private static final String MARK_DEFAULT_USER_LEVEL = "default_user_level";
140     private static final String MARK_DEFAULT_USER_NOTIFICATION = "default_user_notification";
141     private static final String MARK_DEFAULT_USER_LANGUAGE = "default_user_language";
142     private static final String MARK_DEFAULT_USER_STATUS = "default_user_status";
143     private static final String MARK_LANGUAGES_LIST = "languages_list";
144     private static final String MARK_USER_LEVELS_LIST = "user_levels";
145     private static final String MARK_SEARCH_IS_SEARCH = "search_is_search";
146     private static final String MARK_SEARCH_ADMIN_USER_FILTER = "search_admin_user_filter";
147     private static final String MARK_SEARCH_ADMIN_USER_FIELD_FILTER = "search_admin_user_field_filter";
148     private static final String MARK_ATTRIBUTES_LIST = "attributes_list";
149     private static final String MARK_LOCALE = "locale";
150     private static final String MARK_SORT_SEARCH_ATTRIBUTE = "sort_search_attribute";
151     private static final String MARK_MAP_ID_USER_LIST_USER_FIELDS = "map_id_user_list_user_fields";
152     private static final String MARK_EMAIL_PATTERN = "email_pattern";
153     private static final String MARK_AVAILABLE_REGULAREXPRESSIONS = "available_regularexpressions";
154     private static final String MARK_SELECTED_REGULAREXPRESSIONS = "selected_regularexpressions";
155     private static final String MARK_IS_EMAIL_PATTERN_SET_MANUALLY = "is_email_pattern_set_manually";
156     private static final String MARK_PLUGIN_REGULAREXPRESSION = "plugin_regularexpression";
157     private static final String MARK_FORCE_CHANGE_PASSWORD_REINIT = "force_change_password_reinit";
158     private static final String MARK_PASSWORD = "password";
159     private static final String MARK_PASSWORD_MINIMUM_LENGTH = "password_minimum_length";
160     private static final String MARK_PASSWORD_FORMAT_UPPER_LOWER_CASE = "password_format_upper_lower_case";
161     private static final String MARK_PASSWORD_FORMAT_NUMERO = "password_format_numero";
162     private static final String MARK_PASSWORD_FORMAT_SPECIAL_CHARACTERS = "password_format_special_characters";
163     private static final String MARK_PASSWORD_DURATION = "password_duration";
164     private static final String MARK_PASSWORD_HISTORY_SIZE = "password_history_size";
165     private static final String MARK_MAXIMUM_NUMBER_PASSWORD_CHANGE = "maximum_number_password_change";
166     private static final String MARK_TSW_SIZE_PASSWORD_CHANGE = "tsw_size_password_change";
167     private static final String MARK_USE_ADVANCED_SECURITY_PARAMETERS = "use_advanced_security_parameters";
168     private static final String MARK_ACCOUNT_LIFE_TIME = "account_life_time";
169     private static final String MARK_TIME_BEFORE_ALERT_ACCOUNT = "time_before_alert_account";
170     private static final String MARK_NB_ALERT_ACCOUNT = "nb_alert_account";
171     private static final String MARK_TIME_BETWEEN_ALERTS_ACCOUNT = "time_between_alerts_account";
172     private static final String MARK_ACCES_FAILURES_MAX = "access_failures_max";
173     private static final String MARK_ACCES_FAILURES_INTERVAL = "access_failures_interval";
174     private static final String MARK_NAME = "name";
175     private static final String MARK_FIRST_NAME = "first_name";
176     private static final String MARK_DATE_VALID = "date_valid";
177     private static final String MARK_BANNED_DOMAIN_NAMES = "banned_domain_names";
178     private static final String MARK_NOTIFY_USER_PASSWORD_EXPIRED = "notify_user_password_expired";
179     private static final String MARK_SITE_NAME = "site_name";
180     private static final String MARK_USER = "user";
181     private static final String MARK_SITE_LINK = "site_link";
182     private static final String MARK_LOGIN_URL = "login_url";
183 
184     // Properties
185     private static final String PROPERTY_ADMINISTRATOR = "right.administrator";
186     private static final String PROPERTY_EMAIL_PATTERN = "lutece.email.pattern";
187     private static final String PROPERTY_MESSAGE_EMAIL_FORMAT = "portal.users.message.user.emailFormat";
188     private static final String PROPERTY_MESSAGE_EMAIL_FORMAT_BANNED_DOMAIN_NAME = "portal.users.message.user.emailFormatBannedDomainNames";
189     private static final String PROPERTY_MESSAGE_MINIMUM_PASSWORD_LENGTH = "portal.users.message.password.minimumPasswordLength";
190     private static final String PROPERTY_MESSAGE_PASSWORD_FORMAT = "portal.users.message.password.format";
191     private static final String PROPERTY_MESSAGE_PASSWORD_FORMAT_UPPER_LOWER_CASE = "portal.users.message.password.formatUpperLowerCase";
192     private static final String PROPERTY_MESSAGE_PASSWORD_FORMAT_NUMERO = "portal.users.message.password.formatNumero";
193     private static final String PROPERTY_MESSAGE_PASSWORD_FORMAT_SPECIAL_CHARACTERS = "portal.users.message.password.formatSpecialCharacters";
194     private static final String PROPERTY_MESSAGE_PASSWORD_ALREADY_USED = "portal.users.message.password.passwordAlreadyUsed";
195     private static final String PROPERTY_MESSAGE_MAX_PASSWORD_CHANGE = "portal.users.message.password.maxPasswordChange";
196     private static final String PROPERTY_ANONYMIZATION_ENCRYPT_ALGO = "security.anonymization.encryptAlgo";
197     private static final String PROPERTY_DEFAULT_PASSWORD_MINIMAL_LENGTH = "security.defaultValues.passwordMinimalLength";
198     private static final String PROPERTY_DEFAULT_MAXIMUM_NUMBER_PASSWORD_CHANGE = "security.defaultValues.maximumPasswordChange";
199     private static final String PROPERTY_DEFAULT_TSW_SIZE_PASSWORD_CHANGE = "security.defaultValues.maximumPasswordChangeTSWSize";
200     private static final String PROPERTY_DEFAULT_HISTORY_SIZE = "security.defaultValues.passwordHistorySize";
201     private static final String PROPERTY_DEFAULT_PASSWORD_DURATION = "security.defaultValues.passwordDuration";
202 
203     // CONSTANTS
204     private static final String CONSTANT_DEFAULT_ENCRYPT_ALGO = "SHA-256";
205     private static final String COMMA = ",";
206     private static final String SEMICOLON = ";";
207     private static final String AMPERSAND = "&";
208     private static final String ZERO = "0";
209     private static final String CONSTANT_AT = "@";
210     private static final String CONSTANT_UNDERSCORE = "_";
211     private static final String CONSTANT_XML_USER = "user";
212     private static final String CONSTANT_XML_ACCESS_CODE = "access_code";
213     private static final String CONSTANT_XML_LAST_NAME = "last_name";
214     private static final String CONSTANT_XML_FIRST_NAME = "first_name";
215     private static final String CONSTANT_XML_EMAIL = "email";
216     private static final String CONSTANT_XML_STATUS = "status";
217     private static final String CONSTANT_XML_LOCALE = "locale";
218     private static final String CONSTANT_XML_LEVEL = "level";
219     private static final String CONSTANT_XML_MUST_CHANGE_PASSWORD = "must_change_password";
220     private static final String CONSTANT_XML_ACCESSIBILITY_MODE = "accessibility_mode";
221     private static final String CONSTANT_XML_PASSWORD_MAX_VALID_DATE = "password_max_valid_date";
222     private static final String CONSTANT_XML_ACCOUNT_MAX_VALID_DATE = "account_max_valid_date";
223     private static final String CONSTANT_XML_DATE_LAST_LOGIN = "date_last_login";
224     private static final String CONSTANT_XML_ROLES = "roles";
225     private static final String CONSTANT_XML_RIGHTS = "rights";
226     private static final String CONSTANT_XML_WORKGROUPS = "workgroups";
227     private static final String CONSTANT_XML_ROLE = "role";
228     private static final String CONSTANT_XML_RIGHT = "right";
229     private static final String CONSTANT_XML_WORKGROUP = "workgroup";
230     private static final String CONSTANT_XML_ATTRIBUTES = "attributes";
231     private static final String CONSTANT_XML_ATTRIBUTE = "attribute";
232     private static final String CONSTANT_XML_ATTRIBUTE_ID = "attribute-id";
233     private static final String CONSTANT_XML_ATTRIBUTE_FIELD_ID = "attribute-field-id";
234     private static final String CONSTANT_XML_ATTRIBUTE_VALUE = "attribute-value";
235 
236     /** Private constructor */
237     private AdminUserService(  )
238     {
239     }
240 
241     /**
242      * Init
243      */
244     public static void init(  )
245     {
246         AdminUser.init(  );
247     }
248 
249     /**
250      * Get the user in session
251      * @param request The HTTP request
252      * @return the user in session
253      */
254     public static AdminUser getAdminUser( HttpServletRequest request )
255     {
256         return AdminAuthenticationService.getInstance(  ).getRegisteredUser( request );
257     }
258 
259     /**
260      * Get the locale for the current request
261      * @param request The HTTP request
262      * @return the locale to use with this request
263      */
264     public static Locale getLocale( HttpServletRequest request )
265     {
266         Locale locale;
267         AdminUser user = getAdminUser( request );
268 
269         if ( user != null )
270         {
271             // Take the locale of the current user if exists
272             locale = user.getLocale(  );
273         }
274         else
275         {
276             // TODO : Add cookie search
277 
278             // Take the locale of the browser
279             locale = request.getLocale(  );
280         }
281 
282         return locale;
283     }
284 
285     /**
286      * Gets the admin right level
287      *
288      * @param request The HTTP request
289      * @return The boolean level right
290      */
291     @Deprecated
292     public static boolean getUserAdminRightLevel( HttpServletRequest request )
293     {
294         String strRightCode = AppPropertiesService.getProperty( PROPERTY_ADMINISTRATOR );
295 
296         AdminUser user = getAdminUser( request );
297         boolean bLevelRight = user.checkRight( strRightCode );
298 
299         return bLevelRight;
300     }
301 
302     /**
303      * Get the filtered list of admin users
304      * @param listUsers the initial list of users
305      * @param request HttpServletRequest
306      * @param model map
307      * @param url URL of the current interface
308      * @return The filtered list of admin users
309      */
310     public static List<AdminUser> getFilteredUsersInterface( Collection<AdminUser> listUsers,
311         HttpServletRequest request, Map<String, Object> model, UrlItem url )
312     {
313         AdminUser currentUser = getAdminUser( request );
314 
315         // FILTER
316         AdminUserFilter auFilter = new AdminUserFilter(  );
317         List<AdminUser> listFilteredUsers = new ArrayList<AdminUser>(  );
318         boolean bIsSearch = auFilter.setAdminUserFilter( request );
319         boolean bIsFiltered;
320 
321         for ( AdminUser filteredUser : AdminUserHome.findUserByFilter( auFilter ) )
322         {
323             bIsFiltered = false;
324 
325             for ( AdminUser user : listUsers )
326             {
327                 if ( user.getUserId(  ) == filteredUser.getUserId(  ) )
328                 {
329                     bIsFiltered = true;
330 
331                     break;
332                 }
333             }
334 
335             if ( bIsFiltered && ( currentUser.isParent( filteredUser ) || ( currentUser.isAdmin(  ) ) ) )
336             {
337                 listFilteredUsers.add( filteredUser );
338             }
339         }
340 
341         List<AdminUser> filteredUsers = new ArrayList<AdminUser>(  );
342 
343         AdminUserFieldFilter auFieldFilter = new AdminUserFieldFilter(  );
344         auFieldFilter.setAdminUserFieldFilter( request, currentUser.getLocale(  ) );
345 
346         List<AdminUser> listFilteredUsersByUserFields = AdminUserFieldHome.findUsersByFilter( auFieldFilter );
347 
348         if ( listFilteredUsersByUserFields != null )
349         {
350             for ( AdminUser filteredUser : listFilteredUsers )
351             {
352                 for ( AdminUser filteredUserByUserField : listFilteredUsersByUserFields )
353                 {
354                     if ( filteredUser.getUserId(  ) == filteredUserByUserField.getUserId(  ) )
355                     {
356                         filteredUsers.add( filteredUser );
357                     }
358                 }
359             }
360         }
361         else
362         {
363             filteredUsers = listFilteredUsers;
364         }
365 
366         Map<String, List<AdminUserField>> map = new HashMap<String, List<AdminUserField>>(  );
367 
368         for ( AdminUser user : filteredUsers )
369         {
370             auFieldFilter.setIdUser( user.getUserId(  ) );
371 
372             List<AdminUserField> listAdminUserFields = AdminUserFieldHome.findByFilter( auFieldFilter );
373             map.put( String.valueOf( user.getUserId(  ) ), listAdminUserFields );
374         }
375 
376         List<IAttribute> listAttributes = AttributeService.getInstance(  )
377                                                           .getAllAttributesWithFields( currentUser.getLocale(  ) );
378 
379         String strSortSearchAttribute = StringUtils.EMPTY;
380 
381         if ( bIsSearch )
382         {
383             auFilter.setUrlAttributes( url );
384             strSortSearchAttribute = AMPERSAND + auFilter.getUrlAttributes(  );
385             auFieldFilter.setUrlAttributes( url );
386             strSortSearchAttribute = auFieldFilter.getUrlAttributes(  );
387         }
388 
389         model.put( MARK_SEARCH_ADMIN_USER_FILTER, auFilter );
390         model.put( MARK_SEARCH_IS_SEARCH, bIsSearch );
391         model.put( MARK_SEARCH_ADMIN_USER_FIELD_FILTER, auFieldFilter );
392         model.put( MARK_LOCALE, currentUser.getLocale(  ) );
393         model.put( MARK_ATTRIBUTES_LIST, listAttributes );
394         model.put( MARK_SORT_SEARCH_ATTRIBUTE, strSortSearchAttribute );
395         model.put( MARK_MAP_ID_USER_LIST_USER_FIELDS, map );
396 
397         return filteredUsers;
398     }
399 
400     /**
401      * Build the advanced parameters management
402      * @param user The AdminUser object
403      * @return The model for the advanced parameters
404      */
405     public static Map<String, Object> getManageAdvancedParameters( AdminUser user )
406     {
407         Map<String, Object> model = new HashMap<String, Object>(  );
408 
409         boolean bPermissionManageAdvancedParameters = RBACService.isAuthorized( AdminUser.RESOURCE_TYPE,
410                 RBAC.WILDCARD_RESOURCES_ID, AdminUserResourceIdService.PERMISSION_MANAGE_ADVANCED_PARAMETERS, user );
411 
412         if ( bPermissionManageAdvancedParameters )
413         {
414             // USER LEVEL
415             String strDefaultLevel = DefaultUserParameterHome.findByKey( DSKEY_DEFAULT_USER_LEVEL );
416             Level defaultLevel = LevelHome.findByPrimaryKey( Integer.parseInt( strDefaultLevel ) );
417 
418             // USER NOTIFICATION
419             int nDefaultUserNotification = Integer.parseInt( DefaultUserParameterHome.findByKey( 
420                         DSKEY_DEFAULT_USER_NOTIFICATION ) );
421 
422             // USER LANGUAGE
423             ReferenceList listLanguages = I18nService.getAdminLocales( user.getLocale(  ) );
424             String strDefaultUserLanguage = DefaultUserParameterHome.findByKey( DSKEY_DEFAULT_USER_LANGUAGE );
425 
426             // USER STATUS
427             int nDefaultUserStatus = Integer.parseInt( DefaultUserParameterHome.findByKey( DSKEY_DEFAULT_USER_STATUS ) );
428 
429             model.put( MARK_USER_LEVELS_LIST, LevelHome.getLevelsList(  ) );
430             model.put( MARK_DEFAULT_USER_LEVEL, defaultLevel );
431             model.put( MARK_DEFAULT_USER_NOTIFICATION, nDefaultUserNotification );
432             model.put( MARK_LANGUAGES_LIST, listLanguages );
433             model.put( MARK_DEFAULT_USER_LANGUAGE, strDefaultUserLanguage );
434             model.put( MARK_DEFAULT_USER_STATUS, nDefaultUserStatus );
435 
436             // EMAIL PATTERN
437             model.put( MARK_PLUGIN_REGULAREXPRESSION, RegularExpressionService.getInstance(  ).isAvailable(  ) );
438             model.put( MARK_IS_EMAIL_PATTERN_SET_MANUALLY, isEmailPatternSetManually(  ) );
439             model.put( MARK_EMAIL_PATTERN, getEmailPattern(  ) );
440             model.put( MARK_AVAILABLE_REGULAREXPRESSIONS, getAvailableRegularExpressions(  ) );
441             model.put( MARK_SELECTED_REGULAREXPRESSIONS, getSelectedRegularExpressions(  ) );
442 
443             boolean bUseAdvancesSecurityParameters = getBooleanSecurityParameter( DSKEY_USE_ADVANCED_SECURITY_PARAMETERS );
444 
445             model.put( MARK_USE_ADVANCED_SECURITY_PARAMETERS, bUseAdvancesSecurityParameters );
446 
447             model.put( MARK_FORCE_CHANGE_PASSWORD_REINIT,
448                 getBooleanSecurityParameter( DSKEY_FORCE_CHANGE_PASSWORD_REINIT ) );
449             model.put( MARK_PASSWORD_MINIMUM_LENGTH, getIntegerSecurityParameter( DSKEY_PASSWORD_MINIMUM_LENGTH ) );
450 
451             if ( bUseAdvancesSecurityParameters )
452             {
453                 // SECURITY PARAMETERS
454                 model.put( MARK_PASSWORD_FORMAT_UPPER_LOWER_CASE,
455                     getBooleanSecurityParameter( DSKEY_PASSWORD_FORMAT_UPPER_LOWER_CASE ) );
456                 model.put( MARK_PASSWORD_FORMAT_NUMERO, getBooleanSecurityParameter( DSKEY_PASSWORD_FORMAT_NUMERO ) );
457                 model.put( MARK_PASSWORD_FORMAT_SPECIAL_CHARACTERS,
458                     getBooleanSecurityParameter( DSKEY_PASSWORD_FORMAT_SPECIAL_CHARACTERS ) );
459                 model.put( MARK_PASSWORD_DURATION, getIntegerSecurityParameter( DSKEY_PASSWORD_DURATION ) );
460                 model.put( MARK_PASSWORD_HISTORY_SIZE, getIntegerSecurityParameter( DSKEY_PASSWORD_HISTORY_SIZE ) );
461                 model.put( MARK_MAXIMUM_NUMBER_PASSWORD_CHANGE,
462                     getIntegerSecurityParameter( DSKEY_MAXIMUM_NUMBER_PASSWORD_CHANGE ) );
463                 model.put( MARK_TSW_SIZE_PASSWORD_CHANGE, getIntegerSecurityParameter( DSKEY_TSW_SIZE_PASSWORD_CHANGE ) );
464                 model.put( MARK_NOTIFY_USER_PASSWORD_EXPIRED,
465                     getBooleanSecurityParameter( DSKEY_NOTIFY_USER_PASSWORD_EXPIRED ) );
466             }
467 
468             model.put( MARK_BANNED_DOMAIN_NAMES, getLargeSecurityParameter( DSKEY_BANNED_DOMAIN_NAMES ) );
469             model.put( MARK_ACCOUNT_LIFE_TIME, getIntegerSecurityParameter( DSKEY_ACCOUNT_LIFE_TIME ) );
470             model.put( MARK_TIME_BEFORE_ALERT_ACCOUNT, getIntegerSecurityParameter( DSKEY_TIME_BEFORE_ALERT_ACCOUNT ) );
471             model.put( MARK_NB_ALERT_ACCOUNT, getIntegerSecurityParameter( DSKEY_NB_ALERT_ACCOUNT ) );
472             model.put( MARK_TIME_BETWEEN_ALERTS_ACCOUNT,
473                 getIntegerSecurityParameter( DSKEY_TIME_BETWEEN_ALERTS_ACCOUNT ) );
474             model.put( MARK_ACCES_FAILURES_MAX, getIntegerSecurityParameter( DSKEY_ACCES_FAILURES_MAX ) );
475             model.put( MARK_ACCES_FAILURES_INTERVAL, getIntegerSecurityParameter( DSKEY_ACCES_FAILURES_INTERVAL ) );
476         }
477 
478         return model;
479     }
480 
481     /**
482      * Check if the given email is valid or not. <br />
483      * The given email is compared to the value of the parameter
484      * <i>'core_user_parameter.email_pattern'</i>.
485      *
486      * @param strEmail the str email
487      * @return true, if successful
488      */
489     public static boolean checkEmail( String strEmail )
490     {
491         boolean bIsValid = true;
492 
493         if ( isEmailPatternSetManually(  ) )
494         {
495             if ( StringUtils.isBlank( strEmail ) || !strEmail.matches( getEmailPattern(  ) ) )
496             {
497                 bIsValid = false;
498             }
499         }
500         else
501         {
502             for ( RegularExpression regularExpression : getSelectedRegularExpressions(  ) )
503             {
504                 if ( !RegularExpressionService.getInstance(  ).isMatches( strEmail, regularExpression ) )
505                 {
506                     bIsValid = false;
507 
508                     break;
509                 }
510             }
511         }
512 
513         if ( bIsValid )
514         {
515             String strBannedDomainNames = AdminUserService.getSecurityParameter( DSKEY_BANNED_DOMAIN_NAMES );
516 
517             if ( !StringUtils.isEmpty( strBannedDomainNames ) )
518             {
519                 String[] strListBannedDomainNames = strBannedDomainNames.split( SEMICOLON );
520                 String strDomainName = strEmail.substring( strEmail.indexOf( CONSTANT_AT ) + 1 );
521 
522                 if ( ( strDomainName != null ) && ( strListBannedDomainNames != null ) &&
523                         ( strListBannedDomainNames.length > 0 ) )
524                 {
525                     for ( String strDomain : strListBannedDomainNames )
526                     {
527                         if ( strDomainName.equals( strDomain ) )
528                         {
529                             bIsValid = false;
530 
531                             break;
532                         }
533                     }
534                 }
535             }
536         }
537 
538         return bIsValid;
539     }
540 
541     /**
542      * Do modify the email pattern
543      * @param strEmailPattern the email pattern
544      * @param bIsSetManually true if it is know set manually, false otherwise
545      */
546     public static void doModifyEmailPattern( String strEmailPattern, boolean bIsSetManually )
547     {
548         if ( bIsSetManually )
549         {
550             DefaultUserParameterHome.update( DSKEY_EMAIL_PATTERN, strEmailPattern );
551             DefaultUserParameterHome.update( DSKEY_EMAIL_PATTERN_VERIFY_BY, StringUtils.EMPTY );
552         }
553         else
554         {
555             if ( isEmailPatternSetManually(  ) )
556             {
557                 // If the previous email pattern is set manually, then the parameter email_pattern_verify_by is set at 0
558                 // This way, the interface know the email pattern is not set manually
559                 // Indeed, the control is set on the content of the parameter 'email_pattern_verify_by'
560                 DefaultUserParameterHome.update( DSKEY_EMAIL_PATTERN_VERIFY_BY, ZERO );
561             }
562         }
563     }
564 
565     /**
566      * Reset the email pattern by putting the default email pattern that is set
567      * in the <b>lutece.properties</b>.
568      */
569     public static void doResetEmailPattern(  )
570     {
571         DefaultUserParameterHome.update( DSKEY_EMAIL_PATTERN, getDefaultEmailPattern(  ) );
572     }
573 
574     /**
575      * Get the email error message url.
576      *
577      * @param request the request
578      * @return the error message
579      */
580     public static String getEmailErrorMessageUrl( HttpServletRequest request )
581     {
582         String strMessage;
583 
584         if ( isEmailPatternSetManually(  ) )
585         {
586             strMessage = getEmailPattern(  );
587         }
588         else
589         {
590             StringBuilder sbMessage = new StringBuilder(  );
591             String emailPatternVerifyBy = DefaultUserParameterHome.findByKey( DSKEY_EMAIL_PATTERN_VERIFY_BY );
592             String[] regularExpressionIds = emailPatternVerifyBy.split( COMMA );
593 
594             for ( String strRegularExpressionId : regularExpressionIds )
595             {
596                 strRegularExpressionId.trim(  );
597 
598                 if ( StringUtils.isNotBlank( strRegularExpressionId ) &&
599                         StringUtils.isNumeric( strRegularExpressionId ) )
600                 {
601                     int nRegularExpressionId = Integer.parseInt( strRegularExpressionId );
602                     RegularExpression regularExpression = RegularExpressionService.getInstance(  )
603                                                                                   .getRegularExpressionByKey( nRegularExpressionId );
604 
605                     if ( regularExpression != null )
606                     {
607                         sbMessage.append( regularExpression.getValidExemple(  ) );
608                         sbMessage.append( COMMA );
609                     }
610                 }
611             }
612 
613             // Get all message except the last character which is a comma
614             strMessage = sbMessage.toString(  ).substring( 0, sbMessage.length(  ) - 1 );
615         }
616 
617         String strBannedDomainNames = getSecurityParameter( DSKEY_BANNED_DOMAIN_NAMES );
618         String strMessageProperty;
619 
620         if ( !StringUtils.isEmpty( strBannedDomainNames ) )
621         {
622             strMessageProperty = PROPERTY_MESSAGE_EMAIL_FORMAT_BANNED_DOMAIN_NAME;
623         }
624         else
625         {
626             strMessageProperty = PROPERTY_MESSAGE_EMAIL_FORMAT;
627         }
628 
629         Object[] param = { strMessage, strBannedDomainNames };
630 
631         return AdminMessageService.getMessageUrl( request, strMessageProperty, param, AdminMessage.TYPE_STOP );
632     }
633 
634     /**
635      * Do insert a regular expression
636      * @param nRegularExpressionId the ID of the regular expression
637      */
638     public static void doInsertRegularExpression( int nRegularExpressionId )
639     {
640         if ( !isEmailPatternSetManually(  ) )
641         {
642             // Retrieve the rules from the database
643             String emailPatternVerifyBy = DefaultUserParameterHome.findByKey( DSKEY_EMAIL_PATTERN_VERIFY_BY );
644             String[] regularExpressionIds = emailPatternVerifyBy.split( COMMA );
645 
646             // Check if the ID is already inserted
647             boolean bIsAlreadyInserted = false;
648 
649             for ( String strRegularExpressionId : regularExpressionIds )
650             {
651                 strRegularExpressionId.trim(  );
652 
653                 if ( StringUtils.isNotBlank( strRegularExpressionId ) &&
654                         StringUtils.isNumeric( strRegularExpressionId ) )
655                 {
656                     int nRegexId = Integer.parseInt( strRegularExpressionId );
657 
658                     if ( nRegexId == nRegularExpressionId )
659                     {
660                         bIsAlreadyInserted = true;
661 
662                         break;
663                     }
664                 }
665             }
666 
667             if ( !bIsAlreadyInserted )
668             {
669                 // If it is not inserted, then it is concatened to the list of regularExpression
670                 String strRegularExpressionIds = emailPatternVerifyBy + COMMA + nRegularExpressionId;
671                 emailPatternVerifyBy = strRegularExpressionIds;
672                 DefaultUserParameterHome.update( DSKEY_EMAIL_PATTERN_VERIFY_BY, emailPatternVerifyBy );
673             }
674         }
675     }
676 
677     /**
678      * Do remove a regular expression
679      * @param nRegularExpressionId the ID of the regularexpresion
680      */
681     public static void doRemoveRegularExpression( int nRegularExpressionId )
682     {
683         if ( !isEmailPatternSetManually(  ) )
684         {
685             List<Integer> listRegularExpressionIds = new ArrayList<Integer>(  );
686 
687             // Retrieve the rules from the database
688             String emailPatternVerifyBy = DefaultUserParameterHome.findByKey( DSKEY_EMAIL_PATTERN_VERIFY_BY );
689             String[] regularExpressionIds = emailPatternVerifyBy.split( COMMA );
690 
691             // Build the list of regular expression without the regular expression id to delete
692             for ( String strRegularExpressionId : regularExpressionIds )
693             {
694                 strRegularExpressionId.trim(  );
695 
696                 if ( StringUtils.isNotBlank( strRegularExpressionId ) &&
697                         StringUtils.isNumeric( strRegularExpressionId ) )
698                 {
699                     int nRegexId = Integer.parseInt( strRegularExpressionId );
700 
701                     if ( nRegexId != nRegularExpressionId )
702                     {
703                         listRegularExpressionIds.add( nRegexId );
704                     }
705                 }
706             }
707 
708             StringBuilder sbRegularExpressionIds = new StringBuilder(  );
709 
710             for ( int i = 0; i < listRegularExpressionIds.size(  ); i++ )
711             {
712                 sbRegularExpressionIds.append( listRegularExpressionIds.get( i ) );
713 
714                 if ( i < ( listRegularExpressionIds.size(  ) - 1 ) )
715                 {
716                     sbRegularExpressionIds.append( COMMA );
717                 }
718             }
719 
720             DefaultUserParameterHome.update( DSKEY_EMAIL_PATTERN_VERIFY_BY, sbRegularExpressionIds.toString(  ) );
721         }
722     }
723 
724     /**
725      * Get the default email pattern defined in the <b>lutece.properties</b>.
726      * @return the default email pattern
727      */
728     private static String getDefaultEmailPattern(  )
729     {
730         return AppPropertiesService.getProperty( PROPERTY_EMAIL_PATTERN );
731     }
732 
733     /**
734      * Get the AdminUser email pattern that is stored in
735      * <b>'core_user_parameter.email_pattern'</b>. <br />
736      * If it does not exist, then it will retrieve the value in the
737      * <b>lutece.properties</b> file (parameter <b>email.pattern</b>)
738      * @return the AdminUser email pattern
739      */
740     private static String getEmailPattern(  )
741     {
742         String strEmailPattern = getDefaultEmailPattern(  );
743         String emailPattern = DefaultUserParameterHome.findByKey( DSKEY_EMAIL_PATTERN );
744 
745         if ( emailPattern != null )
746         {
747             strEmailPattern = emailPattern;
748         }
749 
750         return strEmailPattern;
751     }
752 
753     /**
754      * Get the available rugalar expressions
755      * @return a list of {@link ReferenceList}
756      */
757     public static ReferenceList getAvailableRegularExpressions(  )
758     {
759         ReferenceList regularExpressionsList = new ReferenceList(  );
760 
761         if ( !isEmailPatternSetManually(  ) )
762         {
763             List<Integer> listRegularExpressionIds = new ArrayList<Integer>(  );
764 
765             // Retrieve the rules from the database
766             String emailPatternVerifyBy = DefaultUserParameterHome.findByKey( DSKEY_EMAIL_PATTERN_VERIFY_BY );
767             String[] regularExpressionIds = emailPatternVerifyBy.split( COMMA );
768 
769             for ( String strRegularExpressionId : regularExpressionIds )
770             {
771                 strRegularExpressionId.trim(  );
772 
773                 if ( StringUtils.isNotBlank( strRegularExpressionId ) &&
774                         StringUtils.isNumeric( strRegularExpressionId ) )
775                 {
776                     int nRegexId = Integer.parseInt( strRegularExpressionId );
777                     listRegularExpressionIds.add( nRegexId );
778                 }
779             }
780 
781             // Fetch all regular expressions
782             List<RegularExpression> listRegularExpression = RegularExpressionService.getInstance(  )
783                                                                                     .getAllRegularExpression(  );
784 
785             // Get only the expressions that are not already selected
786             for ( RegularExpression regularExpression : listRegularExpression )
787             {
788                 if ( !listRegularExpressionIds.contains( regularExpression.getIdExpression(  ) ) )
789                 {
790                     regularExpressionsList.addItem( regularExpression.getIdExpression(  ),
791                         regularExpression.getTitle(  ) );
792                 }
793             }
794         }
795 
796         return regularExpressionsList;
797     }
798 
799     /**
800      * Get the list of selected regular expression
801      * @return a list of {@link RegularExpression}
802      */
803     public static List<RegularExpression> getSelectedRegularExpressions(  )
804     {
805         List<RegularExpression> listRegularExpressions = new ArrayList<RegularExpression>(  );
806 
807         if ( !isEmailPatternSetManually(  ) )
808         {
809             // Retrieve the rules from the database
810             String emailPatternVerifyBy = DefaultUserParameterHome.findByKey( DSKEY_EMAIL_PATTERN_VERIFY_BY );
811             String[] regularExpressionIds = emailPatternVerifyBy.split( COMMA );
812 
813             for ( String strRegularExpressionId : regularExpressionIds )
814             {
815                 strRegularExpressionId.trim(  );
816 
817                 if ( StringUtils.isNotBlank( strRegularExpressionId ) &&
818                         StringUtils.isNumeric( strRegularExpressionId ) )
819                 {
820                     int nRegularExpressionId = Integer.parseInt( strRegularExpressionId );
821                     RegularExpression expression = RegularExpressionService.getInstance(  )
822                                                                            .getRegularExpressionByKey( nRegularExpressionId );
823 
824                     if ( expression != null )
825                     {
826                         listRegularExpressions.add( expression );
827                     }
828                 }
829             }
830         }
831 
832         return listRegularExpressions;
833     }
834 
835     /**
836      * Check whether the email pattern is set manually or by a set of rules from
837      * the plugin-regularexpression.
838      * @return true if it is set manually, false otherwise
839      */
840     private static boolean isEmailPatternSetManually(  )
841     {
842         boolean bIsSetManually = true;
843 
844         if ( RegularExpressionService.getInstance(  ).isAvailable(  ) )
845         {
846             String emailPatternVerifyBy = DefaultUserParameterHome.findByKey( DSKEY_EMAIL_PATTERN_VERIFY_BY );
847 
848             if ( StringUtils.isNotBlank( emailPatternVerifyBy ) )
849             {
850                 bIsSetManually = false;
851             }
852         }
853 
854         return bIsSetManually;
855     }
856 
857     /**
858      * Get an integer user parameter from its key.
859      * @param strParameterkey Key of the parameter
860      * @return The value of the user parameter, or 0 if there is no value or an
861      *         non integer value.
862      */
863     public static int getIntegerSecurityParameter( String strParameterkey )
864     {
865         String defaultUserParameter = DefaultUserParameterHome.findByKey( strParameterkey );
866 
867         if ( StringUtils.isBlank( defaultUserParameter ) )
868         {
869             return 0;
870         }
871 
872         try
873         {
874             int nValue = Integer.parseInt( defaultUserParameter );
875 
876             return nValue;
877         }
878         catch ( NumberFormatException e )
879         {
880             return 0;
881         }
882     }
883 
884     /**
885      * Get a boolean user parameter from its key.
886      * @param strParameterkey Key of the parameter
887      * @return The value of the user parameter, or false if there is no value or
888      *         an non boolean value.
889      */
890     public static boolean getBooleanSecurityParameter( String strParameterkey )
891     {
892         String defaultUserParameter = DefaultUserParameterHome.findByKey( strParameterkey );
893 
894         return ( defaultUserParameter == null ) ? false : Boolean.parseBoolean( defaultUserParameter );
895     }
896 
897     /**
898      * Get a user parameter from its key.
899      * @param strParameterkey Key of the parameter
900      * @return The value of the user parameter.
901      */
902     public static String getSecurityParameter( String strParameterkey )
903     {
904         String defaultUserParameter = DefaultUserParameterHome.findByKey( strParameterkey );
905 
906         return ( defaultUserParameter == null ) ? null : defaultUserParameter;
907     }
908 
909     /**
910      * Get a user parameter from its key.
911      * @param strParameterKey Key of the parameter
912      * @return The value of the user parameter.
913      */
914     public static String getLargeSecurityParameter( String strParameterKey )
915     {
916         return DatastoreService.getDataValue( PluginService.getCore(  ).getName(  ) + CONSTANT_UNDERSCORE +
917             strParameterKey, StringUtils.EMPTY );
918     }
919 
920     /**
921      * Update a security parameter value.
922      * @param strParameterKey The key of the parameter
923      * @param strValue The new value
924      */
925     public static void updateSecurityParameter( String strParameterKey, String strValue )
926     {
927         String strValueTmp = StringUtils.isNotBlank( strValue ) ? strValue : StringUtils.EMPTY;
928         DefaultUserParameterHome.update( strParameterKey, strValueTmp );
929     }
930 
931     /**
932      * Update a security parameter value.
933      * @param strParameterKey The key of the parameter
934      * @param strValue The new value
935      */
936     public static void updateLargeSecurityParameter( String strParameterKey, String strValue )
937     {
938         DatastoreService.setDataValue( PluginService.getCore(  ).getName(  ) + CONSTANT_UNDERSCORE + strParameterKey,
939             strValue );
940     }
941 
942     /**
943      * Check that the password respect user parameters
944      * @param request The request
945      * @param strPassword The password to check
946      * @param nUserId The id of the modified user
947      * @return Null if the password is correct, or the url of an admin message
948      *         describing the error
949      */
950     public static String checkPassword( HttpServletRequest request, String strPassword, int nUserId )
951     {
952         return checkPassword( request, strPassword, nUserId, Boolean.FALSE );
953     }
954 
955     /**
956      * Check that the password respect user parameters
957      * @param request The request
958      * @param strPassword The password to check
959      * @param nUserId The id of the modified user
960      * @param bSkipHistoryCheck Indicates if the password history should be
961      *            checked or not.
962      * @return Null if the password is correct, or the url of an admin message
963      *         describing the error
964      */
965     public static String checkPassword( HttpServletRequest request, String strPassword, int nUserId,
966         boolean bSkipHistoryCheck )
967     {
968         // Minimum password length
969         int nMinimumLength = AdminUserService.getIntegerSecurityParameter( DSKEY_PASSWORD_MINIMUM_LENGTH );
970 
971         if ( ( nMinimumLength > 0 ) && ( strPassword.length(  ) < nMinimumLength ) )
972         {
973             Object[] param = { nMinimumLength };
974 
975             return AdminMessageService.getMessageUrl( request, PROPERTY_MESSAGE_MINIMUM_PASSWORD_LENGTH, param,
976                 AdminMessage.TYPE_STOP );
977         }
978 
979         // Password format
980         boolean bUserPasswordFormatUpperLowerCase = AdminUserService.getBooleanSecurityParameter( DSKEY_PASSWORD_FORMAT_UPPER_LOWER_CASE );
981         boolean bUserPasswordFormatNumero = AdminUserService.getBooleanSecurityParameter( DSKEY_PASSWORD_FORMAT_NUMERO );
982         boolean bUserPasswordFormatSpecialCaracters = AdminUserService.getBooleanSecurityParameter( DSKEY_PASSWORD_FORMAT_SPECIAL_CHARACTERS );
983 
984         if ( ( bUserPasswordFormatUpperLowerCase || bUserPasswordFormatNumero || bUserPasswordFormatSpecialCaracters ) &&
985                 !PasswordUtil.checkPasswordFormat( strPassword, bUserPasswordFormatUpperLowerCase,
986                     bUserPasswordFormatNumero, bUserPasswordFormatSpecialCaracters ) )
987         {
988             StringBuffer strParam = new StringBuffer(  );
989 
990             //Add Message Upper Lower Case
991             if ( bUserPasswordFormatUpperLowerCase )
992             {
993                 strParam.append( I18nService.getLocalizedString( PROPERTY_MESSAGE_PASSWORD_FORMAT_UPPER_LOWER_CASE,
994                         request.getLocale(  ) ) );
995             }
996 
997             //Add Message Numero
998             if ( bUserPasswordFormatNumero )
999             {
1000                 if ( bUserPasswordFormatUpperLowerCase )
1001                 {
1002                     strParam.append( ", " );
1003                 }
1004 
1005                 strParam.append( I18nService.getLocalizedString( PROPERTY_MESSAGE_PASSWORD_FORMAT_NUMERO,
1006                         request.getLocale(  ) ) );
1007             }
1008 
1009             //Add Message Special Characters
1010             if ( bUserPasswordFormatSpecialCaracters )
1011             {
1012                 if ( bUserPasswordFormatUpperLowerCase || bUserPasswordFormatNumero )
1013                 {
1014                     strParam.append( ", " );
1015                 }
1016 
1017                 strParam.append( I18nService.getLocalizedString( PROPERTY_MESSAGE_PASSWORD_FORMAT_SPECIAL_CHARACTERS,
1018                         request.getLocale(  ) ) );
1019             }
1020 
1021             Object[] param = { strParam.toString(  ) };
1022 
1023             return AdminMessageService.getMessageUrl( request, PROPERTY_MESSAGE_PASSWORD_FORMAT, param,
1024                 AdminMessage.TYPE_STOP );
1025         }
1026 
1027         // Check password history
1028         if ( ( nUserId > 0 ) && !bSkipHistoryCheck )
1029         {
1030             int nPasswordHistorySize = AdminUserService.getIntegerSecurityParameter( DSKEY_PASSWORD_HISTORY_SIZE );
1031 
1032             if ( nPasswordHistorySize > 0 )
1033             {
1034                 List<IPassword> passwordHistory = AdminUserHome.selectUserPasswordHistory( nUserId );
1035 
1036                 if ( nPasswordHistorySize < passwordHistory.size(  ) )
1037                 {
1038                     passwordHistory = passwordHistory.subList( 0, nPasswordHistorySize );
1039                 }
1040 
1041                 for ( IPassword password : passwordHistory )
1042                 {
1043                     if ( password.check( strPassword ) ) {
1044                         return AdminMessageService.getMessageUrl( request, PROPERTY_MESSAGE_PASSWORD_ALREADY_USED,
1045                                 AdminMessage.TYPE_STOP );
1046                     }
1047                 }
1048             }
1049 
1050             int nTSWSizePasswordChange = AdminUserService.getIntegerSecurityParameter( DSKEY_TSW_SIZE_PASSWORD_CHANGE );
1051             int nMaximumNumberPasswordChange = AdminUserService.getIntegerSecurityParameter( DSKEY_MAXIMUM_NUMBER_PASSWORD_CHANGE );
1052 
1053             if ( nMaximumNumberPasswordChange > 0 )
1054             {
1055                 Timestamp minDate;
1056 
1057                 if ( nTSWSizePasswordChange > 0 )
1058                 {
1059                     minDate = new Timestamp( new java.util.Date(  ).getTime(  ) -
1060                             DateUtil.convertDaysInMiliseconds( nTSWSizePasswordChange ) );
1061                 }
1062                 else
1063                 {
1064                     minDate = new Timestamp( 0 );
1065                 }
1066 
1067                 if ( AdminUserHome.countUserPasswordHistoryFromDate( minDate, nUserId ) >= nMaximumNumberPasswordChange )
1068                 {
1069                     return AdminMessageService.getMessageUrl( request, PROPERTY_MESSAGE_MAX_PASSWORD_CHANGE,
1070                         AdminMessage.TYPE_STOP );
1071                 }
1072             }
1073         }
1074 
1075         return null;
1076     }
1077 
1078     /**
1079      * Generate a new random password
1080      * @return the new password
1081      */
1082     public static String makePassword(  )
1083     {
1084         // Password format
1085         boolean bUserPasswordFormatUpperLowerCase = AdminUserService.getBooleanSecurityParameter( DSKEY_PASSWORD_FORMAT_UPPER_LOWER_CASE );
1086         boolean bUserPasswordFormatNumero = AdminUserService.getBooleanSecurityParameter( DSKEY_PASSWORD_FORMAT_NUMERO );
1087         boolean bUserPasswordFormatSpecialCaracters = AdminUserService.getBooleanSecurityParameter( DSKEY_PASSWORD_FORMAT_SPECIAL_CHARACTERS );
1088         int nMinPasswordSize = AdminUserService.getIntegerSecurityParameter( DSKEY_PASSWORD_MINIMUM_LENGTH );
1089 
1090         return PasswordUtil.makePassword( nMinPasswordSize, bUserPasswordFormatUpperLowerCase,
1091             bUserPasswordFormatNumero, bUserPasswordFormatSpecialCaracters );
1092     }
1093 
1094     /**
1095      * Encrypt a password
1096      * @param strPassword The password to encrypt
1097      * @return The given password encrypted
1098      */
1099     public static IPassword encryptPassword( String strPassword )
1100     {
1101         IPasswordFactory passwordFactory = SpringContextService.getBean( IPasswordFactory.BEAN_NAME );
1102 
1103         return passwordFactory.getPasswordFromCleartext( strPassword );
1104     }
1105 
1106     /**
1107      * Enable advanced security parameters
1108      */
1109     public static void useAdvancedSecurityParameters(  )
1110     {
1111         updateSecurityParameter( DSKEY_USE_ADVANCED_SECURITY_PARAMETERS, Boolean.TRUE.toString(  ) );
1112         updateSecurityParameter( DSKEY_FORCE_CHANGE_PASSWORD_REINIT, Boolean.TRUE.toString(  ) );
1113         updateSecurityParameter( DSKEY_MAXIMUM_NUMBER_PASSWORD_CHANGE,
1114             AppPropertiesService.getProperty( PROPERTY_DEFAULT_MAXIMUM_NUMBER_PASSWORD_CHANGE ) );
1115         updateSecurityParameter( DSKEY_PASSWORD_DURATION,
1116             AppPropertiesService.getProperty( PROPERTY_DEFAULT_PASSWORD_DURATION ) );
1117         updateSecurityParameter( DSKEY_PASSWORD_FORMAT_UPPER_LOWER_CASE, Boolean.TRUE.toString(  ) );
1118         updateSecurityParameter( DSKEY_PASSWORD_FORMAT_NUMERO, Boolean.TRUE.toString(  ) );
1119         updateSecurityParameter( DSKEY_PASSWORD_FORMAT_SPECIAL_CHARACTERS, Boolean.TRUE.toString(  ) );
1120         updateSecurityParameter( DSKEY_PASSWORD_HISTORY_SIZE,
1121             AppPropertiesService.getProperty( PROPERTY_DEFAULT_HISTORY_SIZE ) );
1122         updateSecurityParameter( DSKEY_TSW_SIZE_PASSWORD_CHANGE,
1123             AppPropertiesService.getProperty( PROPERTY_DEFAULT_TSW_SIZE_PASSWORD_CHANGE ) );
1124 
1125         int nMinPwdLength = getIntegerSecurityParameter( DSKEY_PASSWORD_MINIMUM_LENGTH );
1126 
1127         if ( nMinPwdLength <= 0 )
1128         {
1129             updateSecurityParameter( DSKEY_PASSWORD_MINIMUM_LENGTH,
1130                 AppPropertiesService.getProperty( PROPERTY_DEFAULT_PASSWORD_MINIMAL_LENGTH ) );
1131         }
1132 
1133         updateSecurityParameter( DSKEY_NOTIFY_USER_PASSWORD_EXPIRED, Boolean.TRUE.toString(  ) );
1134     }
1135 
1136     /**
1137      * Disable advances security parameters
1138      */
1139     public static void removeAdvancedSecurityParameters(  )
1140     {
1141         updateSecurityParameter( DSKEY_USE_ADVANCED_SECURITY_PARAMETERS, StringUtils.EMPTY );
1142         updateSecurityParameter( DSKEY_MAXIMUM_NUMBER_PASSWORD_CHANGE, StringUtils.EMPTY );
1143         updateSecurityParameter( DSKEY_PASSWORD_DURATION, StringUtils.EMPTY );
1144         updateSecurityParameter( DSKEY_PASSWORD_FORMAT_UPPER_LOWER_CASE, StringUtils.EMPTY );
1145         updateSecurityParameter( DSKEY_PASSWORD_FORMAT_NUMERO, StringUtils.EMPTY );
1146         updateSecurityParameter( DSKEY_PASSWORD_FORMAT_SPECIAL_CHARACTERS, StringUtils.EMPTY );
1147         updateSecurityParameter( DSKEY_PASSWORD_HISTORY_SIZE, StringUtils.EMPTY );
1148         updateSecurityParameter( DSKEY_TSW_SIZE_PASSWORD_CHANGE, StringUtils.EMPTY );
1149         updateSecurityParameter( DSKEY_NOTIFY_USER_PASSWORD_EXPIRED, StringUtils.EMPTY );
1150     }
1151 
1152     /**
1153      * Compute the maximum valid date of a password with the current time and
1154      * the parameters in the database.
1155      * @return The maximum valid date of a password
1156      */
1157     public static Timestamp getPasswordMaxValidDate(  )
1158     {
1159         int nbDayPasswordValid = getIntegerSecurityParameter( DSKEY_PASSWORD_DURATION );
1160 
1161         if ( nbDayPasswordValid <= 0 )
1162         {
1163             return null;
1164         }
1165 
1166         return PasswordUtil.getPasswordMaxValidDate( nbDayPasswordValid );
1167     }
1168 
1169     /**
1170      * Compute the maximum valid date of an account with the current time and
1171      * the parameters in the database.
1172      * @return The maximum valid date of an account
1173      */
1174     public static Timestamp getAccountMaxValidDate(  )
1175     {
1176         int nbMonthsAccountValid = getIntegerSecurityParameter( DSKEY_ACCOUNT_LIFE_TIME );
1177 
1178         if ( nbMonthsAccountValid <= 0 )
1179         {
1180             return null;
1181         }
1182 
1183         Calendar calendar = new GregorianCalendar( LocaleService.getDefault(  ) );
1184         calendar.add( Calendar.MONTH, nbMonthsAccountValid );
1185 
1186         return new Timestamp( calendar.getTimeInMillis(  ) );
1187     }
1188 
1189     /**
1190      * Anonymize user data from his id. His rights, roles and his passwords
1191      * history are also deleted.
1192      * @param nAdminUserId Id of the user to anonymize
1193      * @param locale The locale
1194      */
1195     public static void anonymizeUser( int nAdminUserId, Locale locale )
1196     {
1197         AdminUser user = AdminUserHome.findByPrimaryKey( nAdminUserId );
1198 
1199         String strEncryptionAlgorithme = AppPropertiesService.getProperty( PROPERTY_ANONYMIZATION_ENCRYPT_ALGO,
1200                 CONSTANT_DEFAULT_ENCRYPT_ALGO );
1201 
1202         Map<String, Boolean> anonymizationStatus = AdminUserHome.getAnonymizationStatusUserStaticField(  );
1203 
1204         if ( anonymizationStatus.get( PARAMETER_ACCESS_CODE ) )
1205         {
1206             user.setAccessCode( CryptoService.encrypt( user.getAccessCode(  ), strEncryptionAlgorithme ) );
1207         }
1208 
1209         if ( anonymizationStatus.get( PARAMETER_FIRST_NAME ) )
1210         {
1211             user.setFirstName( CryptoService.encrypt( user.getFirstName(  ), strEncryptionAlgorithme ) );
1212         }
1213 
1214         if ( anonymizationStatus.get( PARAMETER_LAST_NAME ) )
1215         {
1216             user.setLastName( CryptoService.encrypt( user.getLastName(  ), strEncryptionAlgorithme ) );
1217         }
1218 
1219         if ( anonymizationStatus.get( PARAMETER_EMAIL ) )
1220         {
1221             user.setEmail( CryptoService.encrypt( user.getEmail(  ), strEncryptionAlgorithme ) );
1222         }
1223 
1224         user.setStatus( AdminUser.ANONYMIZED_CODE );
1225         AdminUserHome.removeAllRightsForUser( nAdminUserId );
1226         AdminUserHome.removeAllRolesForUser( nAdminUserId );
1227         AdminUserHome.removeAllPasswordHistoryForUser( nAdminUserId );
1228         AdminUserHome.update( user );
1229 
1230         AttributeService attributeService = AttributeService.getInstance(  );
1231         List<IAttribute> listAllAttributes = attributeService.getAllAttributesWithoutFields( locale );
1232         List<IAttribute> listAttributesText = new ArrayList<IAttribute>(  );
1233 
1234         for ( IAttribute attribut : listAllAttributes )
1235         {
1236             if ( attribut.isAnonymizable(  ) )
1237             {
1238                 listAttributesText.add( attribut );
1239             }
1240         }
1241 
1242         for ( IAttribute attribute : listAttributesText )
1243         {
1244             List<AdminUserField> listAdminUserField = AdminUserFieldHome.selectUserFieldsByIdUserIdAttribute( nAdminUserId,
1245                     attribute.getIdAttribute(  ) );
1246 
1247             for ( AdminUserField adminUserField : listAdminUserField )
1248             {
1249                 adminUserField.setValue( CryptoService.encrypt( adminUserField.getValue(  ), strEncryptionAlgorithme ) );
1250                 AdminUserFieldHome.update( adminUserField );
1251             }
1252         }
1253     }
1254 
1255     /**
1256      * Get the list of id of expired users
1257      * @return the list of id of expired users
1258      */
1259     public static List<Integer> getExpiredUserIdList(  )
1260     {
1261         return AdminUserHome.findAllExpiredUserId(  );
1262     }
1263 
1264     /**
1265      * Update the user expiration date with new values, and notify him with an
1266      * email if his account was close to expire.
1267      * @param user The user to update
1268      */
1269     @SuppressWarnings( "deprecation" )
1270     public static void updateUserExpirationDate( AdminUser user )
1271     {
1272         if ( user == null )
1273         {
1274             return;
1275         }
1276 
1277         Timestamp newExpirationDate = getAccountMaxValidDate(  );
1278         Timestamp maxValidDate = user.getAccountMaxValidDate(  );
1279         // We update the user account
1280         AdminUserHome.updateUserExpirationDate( user.getUserId(  ), newExpirationDate );
1281 
1282         // We notify the user
1283         String strUserMail = user.getEmail(  );
1284         int nbDaysBeforeFirstAlert = AdminUserService.getIntegerSecurityParameter( DSKEY_TIME_BEFORE_ALERT_ACCOUNT );
1285 
1286         if ( maxValidDate != null )
1287         {
1288             Timestamp firstAlertMaxDate = new Timestamp( maxValidDate.getTime(  ) -
1289                     DateUtil.convertDaysInMiliseconds( nbDaysBeforeFirstAlert ) );
1290             Timestamp currentTimestamp = new Timestamp( new java.util.Date(  ).getTime(  ) );
1291 
1292             if ( ( currentTimestamp.getTime(  ) > firstAlertMaxDate.getTime(  ) ) &&
1293                     StringUtils.isNotBlank( strUserMail ) )
1294             {
1295                 AdminUser completeUser = AdminUserHome.findByPrimaryKey( user.getUserId(  ) );
1296                 String strBody = DatabaseTemplateService.getTemplateFromKey( DSKEY_ACCOUNT_REACTIVATED_MAIL_BODY );
1297 
1298                 String defaultUserParameter = DefaultUserParameterHome.findByKey( DSKEY_ACCOUNT_REACTIVATED_MAIL_SENDER );
1299                 String strSender = ( defaultUserParameter == null ) ? StringUtils.EMPTY : defaultUserParameter;
1300 
1301                 defaultUserParameter = DefaultUserParameterHome.findByKey( DSKEY_ACCOUNT_REACTIVATED_MAIL_SUBJECT );
1302 
1303                 String strSubject = ( defaultUserParameter == null ) ? StringUtils.EMPTY : defaultUserParameter;
1304 
1305                 Map<String, String> model = new HashMap<String, String>(  );
1306 
1307                 DateFormat dateFormat = SimpleDateFormat.getDateInstance( DateFormat.SHORT, LocaleService.getDefault(  ) );
1308 
1309                 String accountMaxValidDate = dateFormat.format( new Date( newExpirationDate.getTime(  ) ) );
1310 
1311                 model.put( MARK_DATE_VALID, accountMaxValidDate );
1312                 model.put( MARK_NAME, completeUser.getLastName(  ) );
1313                 model.put( MARK_FIRST_NAME, completeUser.getFirstName(  ) );
1314 
1315                 HtmlTemplate template = AppTemplateService.getTemplateFromStringFtl( strBody,
1316                         LocaleService.getDefault(  ), model );
1317                 MailService.sendMailHtml( strUserMail, strSender, strSender, strSubject, template.getHtml(  ) );
1318             }
1319         }
1320     }
1321 
1322     /**
1323      * Update the date of last login of an admin user
1324      * @param nIdUser Id of the user to update
1325      */
1326     public static void updateDateLastLogin( int nIdUser )
1327     {
1328         AdminUserHome.updateDateLastLogin( nIdUser, new Timestamp( new Date(  ).getTime(  ) ) );
1329     }
1330 
1331     /**
1332      * Notify an user by email
1333      * @param strBaseUrl The base URL of the webapp
1334      * @param user The admin user to notify
1335      * @param strPropertyEmailSubject the property of the subject email
1336      * @param strTemplate the URL of the HTML Template
1337      */
1338     public static void notifyUser( String strBaseUrl, AdminUser user, String strPropertyEmailSubject, String strTemplate )
1339     {
1340         notifyUser( strBaseUrl, user, null, strPropertyEmailSubject, strTemplate );
1341     }
1342 
1343     /**
1344      * Notify an user by email
1345      * @param strBaseUrl The base URL of the webapp
1346      * @param user The admin user to notify
1347      * @param strPassword the user password in cleartext
1348      * @param strPropertyEmailSubject the property of the subject email
1349      * @param strTemplate the URL of the HTML Template
1350      */
1351     public static void notifyUser( String strBaseUrl, AdminUser user, String strPassword, String strPropertyEmailSubject, String strTemplate )
1352     {
1353         String strSenderEmail = MailService.getNoReplyEmail(  );
1354         String strSiteName = PortalService.getSiteName(  );
1355         Locale locale = user.getLocale(  );
1356         String strEmailSubject = I18nService.getLocalizedString( strPropertyEmailSubject, new String[] { strSiteName },
1357                 locale );
1358         Map<String, Object> model = new HashMap<String, Object>(  );
1359         model.put( MARK_USER, user );
1360         model.put( MARK_PASSWORD, strPassword );
1361         model.put( MARK_SITE_NAME, strSiteName );
1362         model.put( MARK_LOGIN_URL, strBaseUrl + AdminAuthenticationService.getInstance(  ).getLoginPageUrl(  ) );
1363         model.put( MARK_SITE_LINK, MailService.getSiteLink( strBaseUrl, false ) );
1364 
1365         HtmlTemplate template = AppTemplateService.getTemplate( strTemplate, locale, model );
1366 
1367         MailService.sendMailHtml( user.getEmail(  ), strSenderEmail, strSenderEmail, strEmailSubject,
1368             template.getHtml(  ) );
1369     }
1370 
1371     /**
1372      * Get a XML string describing a user.<br />
1373      * The XML is constructed as follow :<br />
1374      * <b>&lt;user&gt;</b><br />
1375      * &nbsp;&nbsp;<b>&lt;access_code&gt;</b>value<b>&lt;/value&gt;</b><br />
1376      * &nbsp;&nbsp;<b>&lt;last_name&gt;</b>value<b>&gt;/user&gt;</b><br />
1377      * &nbsp;&nbsp;<b>&lt;first_name&gt;</b>value<b>&lt;/value&gt;</b><br />
1378      * &nbsp;&nbsp;<b>&lt;email&gt;</b>value<b>&lt;/email&gt;</b><br />
1379      * &nbsp;&nbsp;<b>&lt;status&gt;</b>value<b>&lt;/status&gt;</b><br />
1380      * &nbsp;&nbsp;<b>&lt;locale&gt;</b>value<b>&lt;/locale&gt;</b><br />
1381      * &nbsp;&nbsp;<b>&lt;level&gt;</b>value<b>&lt;/level&gt;</b><br />
1382      * &nbsp;&nbsp;<b>&lt;must_change_password&gt;</b>value<b>&lt;
1383      * must_change_password&gt;</b><br />
1384      * &nbsp;&nbsp;<b>&lt;accessibility_mode&gt;</b>value<b>&lt;
1385      * accessibility_mode&gt;</b><br />
1386      * &nbsp;&nbsp;<b>&lt;password_max_valid_date&gt;</b>value<b>&lt;
1387      * password_max_valid_date&gt;</b><br />
1388      * &nbsp;&nbsp;<b>&lt;account_max_valid_date&gt;</b>value<b>&lt;
1389      * account_max_valid_date&gt;</b><br />
1390      * &nbsp;&nbsp;<b>&lt;date_last_login&gt;</b>value<b>&lt;/date_last_login&gt
1391      * ;</b><br />
1392      * &nbsp;&nbsp;<b>&lt;roles&gt;</b><br />
1393      * &nbsp;&nbsp;&nbsp;&nbsp;<b>&lt;role&gt;</b>value<b>&lt;/role&gt;</b><br />
1394      * &nbsp;&nbsp;&nbsp;&nbsp;...<br />
1395      * &nbsp;&nbsp;<b>&lt;/roles&gt;</b><br />
1396      * &nbsp;&nbsp;<b>&lt;rights&gt;</b><br />
1397      * &nbsp;&nbsp;&nbsp;&nbsp;<b>&lt;right&gt;</b>value<b>&lt;/right&gt;</b><br />
1398      * &nbsp;&nbsp;&nbsp;&nbsp;...<br />
1399      * &nbsp;&nbsp;<b>&lt;/rights&gt;</b><br />
1400      * &nbsp;&nbsp;<b>&lt;workspaces&gt;</b><br />
1401      * &nbsp;&nbsp;&nbsp;&nbsp;<b>&lt;workspace&gt;</b>value<b>&lt;/workspace&gt
1402      * ;</b><br />
1403      * &nbsp;&nbsp;&nbsp;&nbsp;...<br />
1404      * &nbsp;&nbsp;<b>&lt;/workspaces&gt;</b><br />
1405      * &nbsp;&nbsp;<b>&lt;attributes&gt;</b><br />
1406      * &nbsp;&nbsp;&nbsp;&nbsp;<b>&lt;attribute&gt;</b><br />
1407      * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<b>&lt;attribute-id&gt;</b>value<b>&
1408      * lt;/attribute-id&gt;</b><br />
1409      * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<b>&lt;attribute-field-id&gt;</b>
1410      * value<b>&lt;/attribute-id&gt;</b><br />
1411      * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<b>&lt;attribute-value&gt;</b>value<b
1412      * >&lt;/attribute-value&gt;</b><br />
1413      * &nbsp;&nbsp;&nbsp;&nbsp;<b>&lt;/attribute&gt;</b><br />
1414      * &nbsp;&nbsp;&nbsp;&nbsp;...<br />
1415      * &nbsp;&nbsp;<b>&lt;/attributes&gt;</b><br />
1416      * <b>&lt;/user&gt;</b><br />
1417      * <br />
1418      * Sections <b>roles</b>, <b>rights</b>, <b>workspaces</b> and
1419      * <b>attributes</b> are not included if data are not imported
1420      * @param user The user to get the XML description of.
1421      * @param bIncludeRoles True to include roles of the user in the XML, false
1422      *            otherwise.
1423      * @param bIncludeRights True to include rights of the user in the XML,
1424      *            false otherwise.
1425      * @param bIncludeWorkgroups True to include workgroups of the user in the
1426      *            XML, false otherwise.
1427      * @param bIncludeAttributes True to include attributes of the user in the
1428      *            XML, false otherwise.
1429      * @param listAttributes The list of attributes to include in the XML if
1430      *            attributes are included.
1431      * @return A string of XML describing the user.
1432      */
1433     public static String getXmlFromUser( AdminUser user, boolean bIncludeRoles, boolean bIncludeRights,
1434         boolean bIncludeWorkgroups, boolean bIncludeAttributes, List<IAttribute> listAttributes )
1435     {
1436         StringBuffer sbXml = new StringBuffer(  );
1437         DateFormat dateFormat = new SimpleDateFormat(  );
1438 
1439         XmlUtil.beginElement( sbXml, CONSTANT_XML_USER );
1440         XmlUtil.addElement( sbXml, CONSTANT_XML_ACCESS_CODE, user.getAccessCode(  ) );
1441         XmlUtil.addElement( sbXml, CONSTANT_XML_LAST_NAME, user.getLastName(  ) );
1442         XmlUtil.addElement( sbXml, CONSTANT_XML_FIRST_NAME, user.getFirstName(  ) );
1443         XmlUtil.addElement( sbXml, CONSTANT_XML_EMAIL, user.getEmail(  ) );
1444         XmlUtil.addElement( sbXml, CONSTANT_XML_STATUS, Integer.toString( user.getRealStatus(  ) ) );
1445         XmlUtil.addElement( sbXml, CONSTANT_XML_LOCALE, user.getLocale(  ).toString(  ) );
1446         XmlUtil.addElement( sbXml, CONSTANT_XML_LEVEL, Integer.toString( user.getUserLevel(  ) ) );
1447         XmlUtil.addElement( sbXml, CONSTANT_XML_MUST_CHANGE_PASSWORD, Boolean.toString( user.isPasswordReset(  ) ) );
1448         XmlUtil.addElement( sbXml, CONSTANT_XML_ACCESSIBILITY_MODE, Boolean.toString( user.getAccessibilityMode(  ) ) );
1449 
1450         String strPasswordMaxValidDate = StringUtils.EMPTY;
1451 
1452         if ( user.getPasswordMaxValidDate(  ) != null )
1453         {
1454             strPasswordMaxValidDate = dateFormat.format( user.getPasswordMaxValidDate(  ) );
1455         }
1456 
1457         XmlUtil.addElement( sbXml, CONSTANT_XML_PASSWORD_MAX_VALID_DATE, strPasswordMaxValidDate );
1458 
1459         String strAccountMaxValidDate = StringUtils.EMPTY;
1460 
1461         if ( user.getAccountMaxValidDate(  ) != null )
1462         {
1463             strAccountMaxValidDate = dateFormat.format( user.getAccountMaxValidDate(  ) );
1464         }
1465 
1466         XmlUtil.addElement( sbXml, CONSTANT_XML_ACCOUNT_MAX_VALID_DATE, strAccountMaxValidDate );
1467 
1468         String strDateLastLogin = StringUtils.EMPTY;
1469 
1470         if ( user.getDateLastLogin(  ) != null )
1471         {
1472             strDateLastLogin = dateFormat.format( user.getDateLastLogin(  ) );
1473         }
1474 
1475         XmlUtil.addElement( sbXml, CONSTANT_XML_DATE_LAST_LOGIN, strDateLastLogin );
1476 
1477         if ( bIncludeRoles )
1478         {
1479             Map<String, AdminRole> mapRoles = AdminUserHome.getRolesListForUser( user.getUserId(  ) );
1480             XmlUtil.beginElement( sbXml, CONSTANT_XML_ROLES );
1481 
1482             for ( String strRole : mapRoles.keySet(  ) )
1483             {
1484                 XmlUtil.addElement( sbXml, CONSTANT_XML_ROLE, strRole );
1485             }
1486 
1487             XmlUtil.endElement( sbXml, CONSTANT_XML_ROLES );
1488         }
1489 
1490         if ( bIncludeRights )
1491         {
1492             XmlUtil.beginElement( sbXml, CONSTANT_XML_RIGHTS );
1493 
1494             Map<String, Right> mapRights = AdminUserHome.getRightsListForUser( user.getUserId(  ) );
1495 
1496             for ( String strRight : mapRights.keySet(  ) )
1497             {
1498                 XmlUtil.addElement( sbXml, CONSTANT_XML_RIGHT, strRight );
1499             }
1500 
1501             XmlUtil.endElement( sbXml, CONSTANT_XML_RIGHTS );
1502         }
1503 
1504         if ( bIncludeWorkgroups )
1505         {
1506             XmlUtil.beginElement( sbXml, CONSTANT_XML_WORKGROUPS );
1507 
1508             ReferenceList refListWorkgroups = AdminWorkgroupHome.getUserWorkgroups( user );
1509 
1510             for ( ReferenceItem refItem : refListWorkgroups )
1511             {
1512                 XmlUtil.addElement( sbXml, CONSTANT_XML_WORKGROUP, refItem.getCode(  ) );
1513             }
1514 
1515             XmlUtil.endElement( sbXml, CONSTANT_XML_WORKGROUPS );
1516         }
1517 
1518         if ( bIncludeAttributes )
1519         {
1520             Map<String, Object> mapAttributes = AdminUserFieldService.getAdminUserFields( listAttributes,
1521                     user.getUserId(  ), LocaleService.getDefault(  ) );
1522             XmlUtil.beginElement( sbXml, CONSTANT_XML_ATTRIBUTES );
1523 
1524             for ( Entry<String, Object> entry : mapAttributes.entrySet(  ) )
1525             {
1526                 String strAttributeKey = entry.getKey(  );
1527                 Object value = entry.getValue(  );
1528 
1529                 if ( value instanceof List<?> )
1530                 {
1531                     List<AdminUserField> listFields = (List<AdminUserField>) value;
1532 
1533                     for ( AdminUserField adminUserFields : listFields )
1534                     {
1535                         if ( adminUserFields.getIdUserField(  ) > 0 )
1536                         {
1537                             XmlUtil.beginElement( sbXml, CONSTANT_XML_ATTRIBUTE );
1538                             XmlUtil.addElement( sbXml, CONSTANT_XML_ATTRIBUTE_ID, strAttributeKey );
1539                             XmlUtil.addElement( sbXml, CONSTANT_XML_ATTRIBUTE_FIELD_ID,
1540                                 adminUserFields.getAttributeField(  ).getIdField(  ) );
1541                             XmlUtil.addElement( sbXml, CONSTANT_XML_ATTRIBUTE_VALUE, adminUserFields.getValue(  ) );
1542                             XmlUtil.endElement( sbXml, CONSTANT_XML_ATTRIBUTE );
1543                         }
1544                     }
1545                 }
1546             }
1547 
1548             XmlUtil.endElement( sbXml, CONSTANT_XML_ATTRIBUTES );
1549         }
1550 
1551         XmlUtil.endElement( sbXml, CONSTANT_XML_USER );
1552 
1553         return sbXml.toString(  );
1554     }
1555 
1556 }