1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 package fr.paris.lutece.plugins.mylutece.modules.wssodatabase.authentication.service;
35
36 import fr.paris.lutece.plugins.mylutece.modules.wssodatabase.authentication.business.IdxWSSODatabaseHome;
37 import fr.paris.lutece.plugins.mylutece.modules.wssodatabase.authentication.business.WssoProfil;
38 import fr.paris.lutece.plugins.mylutece.modules.wssodatabase.authentication.business.WssoProfilHome;
39 import fr.paris.lutece.plugins.mylutece.modules.wssodatabase.authentication.business.WssoUser;
40 import fr.paris.lutece.plugins.mylutece.modules.wssodatabase.authentication.business.WssoUserHome;
41 import fr.paris.lutece.plugins.mylutece.modules.wssodatabase.authentication.business.WssoUserRoleHome;
42 import fr.paris.lutece.plugins.mylutece.service.attribute.MyLuteceUserFieldService;
43 import fr.paris.lutece.portal.business.role.Role;
44 import fr.paris.lutece.portal.business.role.RoleHome;
45 import fr.paris.lutece.portal.service.csv.CSVMessageDescriptor;
46 import fr.paris.lutece.portal.service.csv.CSVMessageLevel;
47 import fr.paris.lutece.portal.service.csv.CSVReaderService;
48 import fr.paris.lutece.portal.service.i18n.I18nService;
49 import fr.paris.lutece.portal.service.mail.MailService;
50 import fr.paris.lutece.portal.service.plugin.Plugin;
51 import fr.paris.lutece.portal.service.plugin.PluginService;
52 import fr.paris.lutece.portal.service.template.AppTemplateService;
53 import fr.paris.lutece.portal.service.util.AppPathService;
54 import fr.paris.lutece.portal.service.util.AppPropertiesService;
55 import fr.paris.lutece.util.html.HtmlTemplate;
56
57 import java.util.ArrayList;
58 import java.util.Collection;
59 import java.util.HashMap;
60 import java.util.List;
61 import java.util.Locale;
62 import java.util.Map;
63 import java.util.regex.Pattern;
64
65 import org.apache.commons.collections.CollectionUtils;
66 import org.apache.commons.lang.StringUtils;
67
68
69
70
71
72 public class ImportWssoDatabaseUserService extends CSVReaderService
73 {
74 private static final String MESSAGE_ACCESS_CODE_ALREADY_USED = "module.mylutece.wssodatabase.message.user_exist";
75 private static final String MESSAGE_EMAIL_ALREADY_USED = "module.mylutece.wssodatabase.message.user_exist";
76 private static final String MESSAGE_USERS_IMPORTED = "module.mylutece.wssodatabase.import_users_from_file.usersImported";
77 private static final String MESSAGE_ERROR_MIN_NUMBER_COLUMNS = "module.mylutece.wssodatabase.import_users_from_file.messageErrorMinColumnNumber";
78 private static final String MESSAGE_ACCOUNT_IMPORTED_MAIL_SUBJECT = "module.mylutece.wssodatabase.import_users_from_file.email.mailSubject";
79 private static final String MESSAGE_ROLE_UNKNOWN = "module.mylutece.wssodatabase.message.import_user_role_unknown";
80
81
82 private static final String MESSAGE_PROFIL_UNKNOWN = "module.mylutece.wssodatabase.message.import_user_profil_unknown";
83 private static final String MESSAGE_GUID_EMPTY = "module.mylutece.wssodatabase.message.import_user_guid_empty";
84 private static final String MESSAGE_FIRST_NAME_EMPTY = "module.mylutece.wssodatabase.message.import_user_first_name_empty";
85 private static final String MESSAGE_LAST_NAME_EMPTY = "module.mylutece.wssodatabase.message.import_user_last_name_empty";
86 private static final String MESSAGE_EMAIL_EMPTY = "module.mylutece.wssodatabase.message.import_user_email_empty";
87 private static final String MESSAGE_EMAIL_INVALID = "module.mylutece.wssodatabase.message.import_user_email_invalid";
88 private static final String PROPERTY_NO_REPLY_EMAIL = "mail.noreply.email";
89 private static final String PROPERTY_IMPORT_EXPORT_USER_SEPARATOR = "lutece.importExportUser.defaultSeparator";
90 private static final String PROPERTY_SITE_NAME = "lutece.name";
91 private static final String TEMPLATE_MAIL_USER_IMPORTED = "admin/plugins/mylutece/modules/wssodatabase/mail_user_imported.html";
92 private static final String MARK_SITE_NAME = "site_name";
93 private static final String MARK_USER = "user";
94 private static final String MARK_SITE_LINK = "site_link";
95 private static final String CONSTANT_DEFAULT_IMPORT_EXPORT_USER_SEPARATOR = ":";
96 private static final String CONSTANT_ROLE = "role";
97 private static final int CONSTANT_MINIMUM_COLUMNS_PER_LINE = 4;
98
99
100
101
102 private static final String CONSTANT_EMAIL = "(^([a-zA-Z0-9]+(([\\.\\-\\_]?[a-zA-Z0-9]+)+)?)\\@(([a-zA-Z0-9]+[\\.\\-\\_])+[a-zA-Z]{2,4})$)|(^$)";
103 private Character _strAttributesSeparator;
104 private boolean _bUpdateExistingUsers;
105
106
107
108
109 @Override
110 protected List<CSVMessageDescriptor> readLineOfCSVFile( String[] strLineDataArray, int nLineNumber, Locale locale,
111 String strBaseUrl )
112 {
113 Plugin databasePlugin = PluginService.getPlugin( WssoDatabasePlugin.PLUGIN_NAME );
114 List<CSVMessageDescriptor> listMessages = new ArrayList<CSVMessageDescriptor>( );
115 int nIndex = 0;
116
117 String strGuid = strLineDataArray[nIndex++];
118
119 if ( StringUtils.isBlank( strGuid ) )
120 {
121 String strErrorMessage = I18nService.getLocalizedString( MESSAGE_GUID_EMPTY, null, locale );
122 CSVMessageDescriptor error = new CSVMessageDescriptor( CSVMessageLevel.ERROR, nLineNumber, strErrorMessage );
123 listMessages.add( error );
124 }
125
126 String strLastName = strLineDataArray[nIndex++];
127
128 if ( StringUtils.isBlank( strLastName ) )
129 {
130 String strErrorMessage = I18nService.getLocalizedString( MESSAGE_LAST_NAME_EMPTY, null, locale );
131 CSVMessageDescriptor error = new CSVMessageDescriptor( CSVMessageLevel.ERROR, nLineNumber, strErrorMessage );
132 listMessages.add( error );
133 }
134
135 String strFirstName = strLineDataArray[nIndex++];
136
137 if ( StringUtils.isBlank( strFirstName ) )
138 {
139 String strErrorMessage = I18nService.getLocalizedString( MESSAGE_FIRST_NAME_EMPTY, null, locale );
140 CSVMessageDescriptor error = new CSVMessageDescriptor( CSVMessageLevel.ERROR, nLineNumber, strErrorMessage );
141 listMessages.add( error );
142 }
143
144 String strEmail = strLineDataArray[nIndex++];
145
146 if ( StringUtils.isBlank( strEmail ) )
147 {
148 String strErrorMessage = I18nService.getLocalizedString( MESSAGE_EMAIL_EMPTY, null, locale );
149 CSVMessageDescriptor error = new CSVMessageDescriptor( CSVMessageLevel.ERROR, nLineNumber, strErrorMessage );
150 listMessages.add( error );
151 }
152 else
153 {
154 if ( !Pattern.matches( CONSTANT_EMAIL, strEmail ) )
155 {
156 String strErrorMessage = I18nService.getLocalizedString( MESSAGE_EMAIL_INVALID, null, locale );
157 CSVMessageDescriptor error = new CSVMessageDescriptor( CSVMessageLevel.ERROR, nLineNumber,
158 strErrorMessage );
159 listMessages.add( error );
160 }
161 }
162
163 if ( CollectionUtils.isNotEmpty( listMessages ) )
164 {
165 return listMessages;
166 }
167
168 boolean bUpdateUser = getUpdateExistingUsers( );
169 int nUserId = 0;
170
171 if ( bUpdateUser )
172 {
173 int nAccessCodeUserId = WssoUserHome.findDatabaseUserIdFromGuid( strGuid, databasePlugin );
174
175 if ( nAccessCodeUserId > 0 )
176 {
177 nUserId = nAccessCodeUserId;
178 }
179
180 bUpdateUser = nUserId > 0;
181 }
182
183 WssoUser wssoUser = new WssoUser( );
184
185 wssoUser.setGuid( strGuid );
186 wssoUser.setLastName( strLastName );
187 wssoUser.setFirstName( strFirstName );
188 wssoUser.setEmail( strEmail );
189
190 if ( bUpdateUser )
191 {
192 wssoUser.setMyluteceWssoUserId( nUserId );
193
194 WssoUserHome.update( wssoUser, databasePlugin );
195 }
196 else
197 {
198
199 WssoUserHome.create( wssoUser, databasePlugin );
200 notifyUserAccountCreated( wssoUser, locale, AppPathService.getProdUrl( strBaseUrl ) );
201 }
202
203
204 WssoUserRoleHome.deleteRolesForUser( wssoUser.getMyluteceWssoUserId( ), databasePlugin );
205
206 IdxWSSODatabaseHome.removeProfilsForUser( wssoUser.getMyluteceWssoUserId( ), databasePlugin );
207 MyLuteceUserFieldService.doRemoveUserFields( wssoUser.getMyluteceWssoUserId( ), locale );
208
209
210 List<String> listRoles = new ArrayList<String>( );
211
212
213 List<String> listProfils = new ArrayList<String>( );
214
215 while ( nIndex < strLineDataArray.length )
216 {
217 String strValue = strLineDataArray[nIndex];
218
219 if ( StringUtils.isNotBlank( strValue ) && ( strValue.indexOf( getAttributesSeparator( ) ) > 0 ) )
220 {
221 int nSeparatorIndex = strValue.indexOf( getAttributesSeparator( ) );
222 String strLineId = strValue.substring( 0, nSeparatorIndex );
223
224 if ( StringUtils.isNotBlank( strLineId ) )
225 {
226 if ( StringUtils.equalsIgnoreCase( strLineId, CONSTANT_ROLE ) )
227 {
228 String strRole = strValue.substring( nSeparatorIndex + 1 );
229 Role role = RoleHome.findByPrimaryKey( strRole );
230
231 if ( role == null )
232 {
233 Object[] args = { strRole };
234 String strErrorMessage = I18nService
235 .getLocalizedString( MESSAGE_ROLE_UNKNOWN, args, locale );
236 CSVMessageDescriptor error = new CSVMessageDescriptor( CSVMessageLevel.ERROR, nLineNumber,
237 strErrorMessage );
238 listMessages.add( error );
239 }
240 else
241 {
242 listRoles.add( strRole );
243 }
244 }
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260 else
261 {
262 String strProfil = strValue.substring( nSeparatorIndex + 1 );
263 WssoProfil profil = WssoProfilHome.findWssoProfilByCode( strProfil, databasePlugin );
264
265 if ( profil == null )
266 {
267 Object[] args = { strProfil };
268 String strErrorMessage = I18nService.getLocalizedString( MESSAGE_PROFIL_UNKNOWN, args,
269 locale );
270 CSVMessageDescriptor error = new CSVMessageDescriptor( CSVMessageLevel.ERROR, nLineNumber,
271 strErrorMessage );
272 listMessages.add( error );
273 }
274 else
275 {
276 listProfils.add( strProfil );
277 }
278 }
279 }
280 }
281
282 nIndex++;
283 }
284
285
286 if ( CollectionUtils.isNotEmpty( listRoles ) )
287 {
288 for ( String strRole : listRoles )
289 {
290 WssoUserRoleHome.createRoleForUser( wssoUser.getMyluteceWssoUserId( ), strRole, databasePlugin );
291 }
292 }
293
294
295
296
297
298
299 if ( CollectionUtils.isNotEmpty( listProfils ) )
300 {
301 for ( String profil : listProfils )
302 {
303 IdxWSSODatabaseHome.addUserForProfil( wssoUser.getMyluteceWssoUserId( ), profil, databasePlugin );
304 }
305 }
306
307 return listMessages;
308 }
309
310
311
312
313 @Override
314 protected List<CSVMessageDescriptor> checkLineOfCSVFile( String[] strLineDataArray, int nLineNumber, Locale locale )
315 {
316 int nMinColumnNumber = CONSTANT_MINIMUM_COLUMNS_PER_LINE;
317 Plugin databasePlugin = PluginService.getPlugin( WssoDatabasePlugin.PLUGIN_NAME );
318 List<CSVMessageDescriptor> listMessages = new ArrayList<CSVMessageDescriptor>( );
319
320 if ( ( strLineDataArray == null ) || ( strLineDataArray.length < nMinColumnNumber ) )
321 {
322 int nNbCol;
323
324 if ( strLineDataArray == null )
325 {
326 nNbCol = 0;
327 }
328 else
329 {
330 nNbCol = strLineDataArray.length;
331 }
332
333 Object[] args = { nNbCol, nMinColumnNumber };
334 String strErrorMessage = I18nService.getLocalizedString( MESSAGE_ERROR_MIN_NUMBER_COLUMNS, args, locale );
335 CSVMessageDescriptor error = new CSVMessageDescriptor( CSVMessageLevel.ERROR, nLineNumber, strErrorMessage );
336 listMessages.add( error );
337
338 return listMessages;
339 }
340
341 if ( !getUpdateExistingUsers( ) )
342 {
343 String strAccessCode = strLineDataArray[0];
344 String strEmail = strLineDataArray[3];
345
346 if ( WssoUserHome.findDatabaseUserIdFromGuid( strAccessCode, databasePlugin ) > 0 )
347 {
348 String strMessage = I18nService.getLocalizedString( MESSAGE_ACCESS_CODE_ALREADY_USED, locale );
349 CSVMessageDescriptor error = new CSVMessageDescriptor( CSVMessageLevel.ERROR, nLineNumber, strMessage );
350 listMessages.add( error );
351 }
352 else
353 {
354 Collection<WssoUser> listUsers = WssoUserHome.findWssoUserssByLastNameOrFirtNameOrEmailByProfil( null,
355 null, null, strEmail, databasePlugin );
356
357 if ( ( listUsers != null ) && ( listUsers.size( ) > 0 ) )
358 {
359 String strMessage = I18nService.getLocalizedString( MESSAGE_EMAIL_ALREADY_USED, locale );
360 CSVMessageDescriptor error = new CSVMessageDescriptor( CSVMessageLevel.ERROR, nLineNumber,
361 strMessage );
362 listMessages.add( error );
363 }
364 }
365 }
366
367 return listMessages;
368 }
369
370
371
372
373 @Override
374 protected List<CSVMessageDescriptor> getEndOfProcessMessages( int nNbLineParses, int nNbLinesWithoutErrors,
375 Locale locale )
376 {
377 List<CSVMessageDescriptor> listMessages = new ArrayList<CSVMessageDescriptor>( );
378 Object[] args = { nNbLineParses, nNbLinesWithoutErrors };
379 String strMessageContent = I18nService.getLocalizedString( MESSAGE_USERS_IMPORTED, args, locale );
380 CSVMessageDescriptor message = new CSVMessageDescriptor( CSVMessageLevel.INFO, 0, strMessageContent );
381 listMessages.add( message );
382
383 return listMessages;
384 }
385
386
387
388
389
390
391
392 private void notifyUserAccountCreated( WssoUser user, Locale locale, String strProdUrl )
393 {
394 String strSenderEmail = AppPropertiesService.getProperty( PROPERTY_NO_REPLY_EMAIL );
395 String strSiteName = AppPropertiesService.getProperty( PROPERTY_SITE_NAME );
396
397 String strEmailSubject = I18nService.getLocalizedString( MESSAGE_ACCOUNT_IMPORTED_MAIL_SUBJECT,
398 new String[] { strSiteName }, locale );
399 String strBaseURL = strProdUrl;
400 Map<String, Object> model = new HashMap<String, Object>( );
401 model.put( MARK_USER, user );
402 model.put( MARK_SITE_NAME, strSiteName );
403 model.put( MARK_SITE_LINK, MailService.getSiteLink( strBaseURL, true ) );
404
405 HtmlTemplate template = AppTemplateService.getTemplate( TEMPLATE_MAIL_USER_IMPORTED, locale, model );
406
407 MailService
408 .sendMailHtml( user.getEmail( ), strSenderEmail, strSenderEmail, strEmailSubject, template.getHtml( ) );
409 }
410
411
412
413
414
415 public Character getAttributesSeparator( )
416 {
417 if ( _strAttributesSeparator == null )
418 {
419 _strAttributesSeparator = AppPropertiesService.getProperty( PROPERTY_IMPORT_EXPORT_USER_SEPARATOR,
420 CONSTANT_DEFAULT_IMPORT_EXPORT_USER_SEPARATOR ).charAt( 0 );
421 }
422
423 return _strAttributesSeparator;
424 }
425
426
427
428
429
430
431 public boolean getUpdateExistingUsers( )
432 {
433 return _bUpdateExistingUsers;
434 }
435
436
437
438
439
440
441 public void setUpdateExistingUsers( boolean bUpdateExistingUsers )
442 {
443 this._bUpdateExistingUsers = bUpdateExistingUsers;
444 }
445 }