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.plugins.adminauthenticationwsso.service;
35  
36  import fr.paris.lutece.plugins.adminauthenticationwsso.AdminWssoUser;
37  import fr.paris.lutece.plugins.adminauthenticationwsso.util.WssoLdapUtil;
38  import fr.paris.lutece.portal.business.user.AdminUser;
39  import fr.paris.lutece.portal.business.user.AdminUserHome;
40  import fr.paris.lutece.portal.business.user.attribute.AdminUserField;
41  import fr.paris.lutece.portal.business.user.attribute.AdminUserFieldHome;
42  import fr.paris.lutece.portal.business.user.attribute.IAttribute;
43  import fr.paris.lutece.portal.business.user.attribute.ISimpleValuesAttributes;
44  import fr.paris.lutece.portal.business.user.authentication.LuteceDefaultAdminUser;
45  import fr.paris.lutece.portal.business.workgroup.AdminWorkgroupHome;
46  import fr.paris.lutece.portal.service.admin.AdminUserService;
47  import fr.paris.lutece.portal.service.admin.ImportAdminUserService;
48  import fr.paris.lutece.portal.service.csv.CSVMessageDescriptor;
49  import fr.paris.lutece.portal.service.csv.CSVMessageLevel;
50  import fr.paris.lutece.portal.service.i18n.I18nService;
51  import fr.paris.lutece.portal.service.plugin.Plugin;
52  import fr.paris.lutece.portal.service.plugin.PluginService;
53  import fr.paris.lutece.portal.service.spring.SpringContextService;
54  import fr.paris.lutece.portal.service.user.attribute.AdminUserFieldListenerService;
55  import fr.paris.lutece.portal.service.user.attribute.AttributeService;
56  import fr.paris.lutece.portal.service.util.AppLogService;
57  import java.sql.Timestamp;
58  import java.text.DateFormat;
59  import java.text.ParseException;
60  import java.text.SimpleDateFormat;
61  import java.util.ArrayList;
62  import java.util.Date;
63  import java.util.HashMap;
64  import java.util.List;
65  import java.util.Locale;
66  import java.util.Map;
67  import javax.naming.directory.DirContext;
68  import org.apache.commons.lang3.StringUtils;
69  
70  
71  public class WssoAdminUserImportService extends ImportAdminUserService
72  {
73      
74      //Constants
75      private static final String CONSTANT_RIGHT = "right";
76      private static final String CONSTANT_ROLE = "role";
77      private static final String CONSTANT_WORKGROUP = "workgroup";
78      private static final int CONSTANT_MINIMUM_COLUMNS_PER_LINE = 9;
79      
80      //Template
81      private static final String TEMPLATE_WSSO_IMPORT_USERS_FROM_FILE = "admin/plugins/adminauthenticationwsso/import_wsso_users_from_file.html";
82      
83      //Messages
84      private static final String MESSAGE_ERROR_IMPORTING_ATTRIBUTES = "portal.users.import_users_from_file.errorImportingAttributes";
85      private static final String MESSAGE_NO_LEVEL = "adminauthenticationwsso.import_users_from_file.importNoLevel";
86      private static final String MESSAGE_NO_STATUS = "adminauthenticationwsso.import_users_from_file.importNoStatus";
87      private static final String MESSAGE_ERROR_USER_EMAIL_NOT_FOUND = "adminauthenticationwsso.import_users_from_file.emailNotFound";
88      private static final String MESSAGE_ERROR_SEVERAL_SAME_EMAIL = "adminauthenticationwsso.import_users_from_file.manyUsersWithThisEmail";
89      
90      
91      private static DirContext _context;
92      private static final AttributeService _attributeService = AttributeService.getInstance( );
93      
94      /**
95       * {@inheritDoc}
96       */
97      @Override
98      protected List<CSVMessageDescriptor> readLineOfCSVFile( String [ ] strLineDataArray, int nLineNumber, Locale locale, String strBaseUrl )
99      {
100         if ( nLineNumber == 1)
101         {
102             //Open a connection the the LDAP; used for all the import process.
103             _context = WssoLdapUtil.getNewContext( );
104         }
105         
106         List<CSVMessageDescriptor> listMessages = new ArrayList<CSVMessageDescriptor>( );
107         
108         //We skip the access code (because get from the LDAP, from the email)
109         int nIndex = 1;
110         
111         String strLastName = strLineDataArray [nIndex++];
112         String strFirstName = strLineDataArray [nIndex++];
113         String strEmail = strLineDataArray [nIndex++];
114 
115         boolean bUpdateUser = getUpdateExistingUsers( );
116         int nEmailUserId = AdminUserHome.checkEmailAlreadyInUse( strEmail );
117         bUpdateUser = nEmailUserId > 0;
118         String strStatus = strLineDataArray [nIndex++];
119         int nStatus = 0;
120 
121         if ( StringUtils.isNotEmpty( strStatus ) && StringUtils.isNumeric( strStatus ) )
122         {
123             nStatus = Integer.parseInt( strStatus );
124         }
125         else
126         {
127             Object [ ] args = {
128                     strEmail, nStatus
129             };
130             String strMessage = I18nService.getLocalizedString( MESSAGE_NO_STATUS, args, locale );
131             CSVMessageDescriptor message = new CSVMessageDescriptor( CSVMessageLevel.INFO, nLineNumber, strMessage );
132             listMessages.add( message );
133         }
134 
135         String strLocale = strLineDataArray [nIndex++];
136         String strLevelUser = strLineDataArray [nIndex++];
137         int nLevelUser = 3;
138 
139         if ( StringUtils.isNotEmpty( strLevelUser ) && StringUtils.isNumeric( strLevelUser ) )
140         {
141             nLevelUser = Integer.parseInt( strLevelUser );
142         }
143         else
144         {
145             Object [ ] args = {
146                     strEmail, nLevelUser
147             };
148             String strMessage = I18nService.getLocalizedString( MESSAGE_NO_LEVEL, args, locale );
149             CSVMessageDescriptor message = new CSVMessageDescriptor( CSVMessageLevel.INFO, nLineNumber, strMessage );
150             listMessages.add( message );
151         }
152 
153         // We ignore the reset password attribute because we set it to true anyway.
154         // String strResetPassword = strLineDataArray[nIndex++];
155         nIndex++;
156 
157         boolean bResetPassword = true;
158         String strAccessibilityMode = strLineDataArray [nIndex++];
159         boolean bAccessibilityMode = Boolean.parseBoolean( strAccessibilityMode );
160         // We ignore the password max valid date attribute because we changed the password.
161         // String strPasswordMaxValidDate = strLineDataArray[nIndex++];
162         nIndex++;
163 
164         Timestamp passwordMaxValidDate = null;
165         // We ignore the account max valid date attribute
166         // String strAccountMaxValidDate = strLineDataArray[nIndex++];
167         nIndex++;
168 
169         Timestamp accountMaxValidDate = AdminUserService.getAccountMaxValidDate( );
170         String strDateLastLogin = strLineDataArray [nIndex++];
171         Timestamp dateLastLogin = new Timestamp( AdminUser.getDefaultDateLastLogin( ).getTime( ) );
172 
173         if ( StringUtils.isNotBlank( strDateLastLogin ) )
174         {
175             DateFormat dateFormat = new SimpleDateFormat( );
176             Date dateParsed;
177 
178             try
179             {
180                 dateParsed = dateFormat.parse( strDateLastLogin );
181             }
182             catch( ParseException e )
183             {
184                 AppLogService.error( e.getMessage( ), e );
185                 dateParsed = null;
186             }
187 
188             if ( dateParsed != null )
189             {
190                 dateLastLogin = new Timestamp( dateParsed.getTime( ) );
191             }
192         }
193 
194         AdminUser user = null;
195 
196         if ( bUpdateUser )
197         {
198             user = AdminUserHome.findUserByLogin( AdminUserHome.findUserByEmail( strEmail ) );
199         }
200         else
201         {
202             user = new LuteceDefaultAdminUser( );
203         }
204         
205         List<AdminWssoUser> userList = WssoLdapUtil.getWssoUserListFromEmail( _context, strEmail );
206         
207         if ( userList.isEmpty( ) )
208         {
209             Object [ ] args = {
210                    strEmail
211             };
212             String strErrorMessage = I18nService.getLocalizedString( MESSAGE_ERROR_USER_EMAIL_NOT_FOUND, args, locale );
213             listMessages.add( new CSVMessageDescriptor(CSVMessageLevel.ERROR, nLineNumber , strErrorMessage ) );
214             AppLogService.error( "Ligne : " + nLineNumber + "  : " + strEmail + " non trouvé dans le LDAP.");
215         }
216         else if ( userList.size( ) > 1 )
217         {
218             Object [ ] args = {
219                    strEmail
220             };
221             String strErrorMessage = I18nService.getLocalizedString( MESSAGE_ERROR_SEVERAL_SAME_EMAIL, args, locale );
222             listMessages.add( new CSVMessageDescriptor(CSVMessageLevel.ERROR, nLineNumber , strErrorMessage ) );
223             AppLogService.error( "Ligne : " + nLineNumber + "  : " + strEmail + " trouvé plusieurs fois dans le LDAP.");
224         }
225         else
226         {
227             AdminWssoUser/../fr/paris/lutece/plugins/adminauthenticationwsso/AdminWssoUser.html#AdminWssoUser">AdminWssoUser adminWssoUser = (AdminWssoUser)userList.toArray( )[0];
228             user.setAccessCode( adminWssoUser.getAccessCode( ) );
229             user.setLastName( strLastName );
230             user.setFirstName( strFirstName );
231             user.setEmail( strEmail );
232             user.setStatus( nStatus );
233             user.setUserLevel( nLevelUser );
234             user.setLocale( new Locale( strLocale ) );
235             user.setAccessibilityMode( bAccessibilityMode );
236             
237             if ( bUpdateUser )
238             {
239                 // We update the user
240                 AdminUserHome.update( user );
241             }
242             else
243             {
244                 // We create the user
245                 user.setPasswordReset( bResetPassword );
246                 user.setPasswordMaxValidDate( passwordMaxValidDate );
247                 user.setAccountMaxValidDate( accountMaxValidDate );
248                 user.setDateLastLogin( dateLastLogin );
249                 AdminUserHome.create( user );
250             }
251 
252             // We remove any previous right, roles, workgroup and attributes of the user
253             AdminUserHome.removeAllRightsForUser( user.getUserId( ) );
254             AdminUserHome.removeAllRolesForUser( user.getUserId( ) );
255 
256             // We remove the user fields from id user
257             AdminUserFieldHome.removeUserFieldsFromIdUser( user.getUserId( ) );
258             
259             // We notify the remove user field listener (such as field profile)
260             for ( AdminUserFieldListenerService adminUserFieldListenerService : SpringContextService.getBeansOfType( AdminUserFieldListenerService.class ) )
261             {
262                 adminUserFieldListenerService.doRemoveUserFields( user, locale );
263             }
264 
265             // We get every attribute, role, right and workgroup of the user
266             Map<Integer, List<String>> mapAttributesValues = new HashMap<Integer, List<String>>( );
267             List<String> listAdminRights = new ArrayList<String>( );
268             List<String> listAdminRoles = new ArrayList<String>( );
269             List<String> listAdminWorkgroups = new ArrayList<String>( );
270 
271             while ( nIndex < strLineDataArray.length )
272             {
273                 String strValue = strLineDataArray [nIndex];
274 
275                 if ( StringUtils.isNotBlank( strValue ) && ( strValue.indexOf( getAttributesSeparator( ) ) > 0 ) )
276                 {
277                     int nSeparatorIndex = strValue.indexOf( getAttributesSeparator( ) );
278                     String strLineId = strValue.substring( 0, nSeparatorIndex );
279 
280                     if ( StringUtils.isNotBlank( strLineId ) )
281                     {
282                         if ( StringUtils.equalsIgnoreCase( strLineId, CONSTANT_RIGHT ) )
283                         {
284                             listAdminRights.add( strValue.substring( nSeparatorIndex + 1 ) );
285                         }
286                         else
287                             if ( StringUtils.equalsIgnoreCase( strLineId, CONSTANT_ROLE ) )
288                             {
289                                 listAdminRoles.add( strValue.substring( nSeparatorIndex + 1 ) );
290                             }
291                             else
292                                 if ( StringUtils.equalsIgnoreCase( strLineId, CONSTANT_WORKGROUP ) )
293                                 {
294                                     listAdminWorkgroups.add( strValue.substring( nSeparatorIndex + 1 ) );
295                                 }
296                                 else
297                                 {
298                                     int nAttributeId = Integer.parseInt( strLineId );
299 
300                                     String strAttributeValue = strValue.substring( nSeparatorIndex + 1 );
301                                     List<String> listValues = mapAttributesValues.get( nAttributeId );
302 
303                                     if ( listValues == null )
304                                     {
305                                         listValues = new ArrayList<String>( );
306                                     }
307 
308                                     listValues.add( strAttributeValue );
309                                     mapAttributesValues.put( nAttributeId, listValues );
310                                 }
311                     }
312                 }
313 
314                 nIndex++;
315             }
316 
317             // We create rights
318             for ( String strRight : listAdminRights )
319             {
320                 AdminUserHome.createRightForUser( user.getUserId( ), strRight );
321             }
322 
323             // We create roles
324             for ( String strRole : listAdminRoles )
325             {
326                 AdminUserHome.createRoleForUser( user.getUserId( ), strRole );
327             }
328 
329             // We create workgroups
330             for ( String strWorkgoup : listAdminWorkgroups )
331             {
332                 AdminWorkgroupHome.addUserForWorkgroup( user, strWorkgoup );
333             }
334 
335             List<IAttribute> listAttributes = _attributeService.getAllAttributesWithoutFields( locale );
336             Plugin pluginCore = PluginService.getCore( );
337 
338             // We save the attributes found
339             for ( IAttribute attribute : listAttributes )
340             {
341                 if ( attribute instanceof ISimpleValuesAttributes )
342                 {
343                     List<String> listValues = mapAttributesValues.get( attribute.getIdAttribute( ) );
344 
345                     if ( ( listValues != null ) && ( listValues.size( ) > 0 ) )
346                     {
347                         int nIdField = 0;
348                         boolean bCoreAttribute = ( attribute.getPlugin( ) == null )
349                                 || StringUtils.equals( pluginCore.getName( ), attribute.getPlugin( ).getName( ) );
350 
351                         for ( String strValue : listValues )
352                         {
353                             int nSeparatorIndex = strValue.indexOf( getAttributesSeparator( ) );
354 
355                             if ( nSeparatorIndex >= 0 )
356                             {
357                                 nIdField = 0;
358 
359                                 try
360                                 {
361                                     nIdField = Integer.parseInt( strValue.substring( 0, nSeparatorIndex ) );
362                                 }
363                                 catch( NumberFormatException e )
364                                 {
365                                     nIdField = 0;
366                                 }
367 
368                                 strValue = strValue.substring( nSeparatorIndex + 1 );
369                             }
370                             else
371                             {
372                                 nIdField = 0;
373                             }
374 
375                             String [ ] strValues = {
376                                 strValue
377                             };
378 
379                             try
380                             {
381                                 List<AdminUserField> listUserFields = ( (ISimpleValuesAttributes) attribute ).getUserFieldsData( strValues, user );
382 
383                                 for ( AdminUserField userField : listUserFields )
384                                 {
385                                     if ( userField != null )
386                                     {
387                                         userField.getAttributeField( ).setIdField( nIdField );
388                                         AdminUserFieldHome.create( userField );
389                                     }
390                                 }
391 
392                                 if ( !bCoreAttribute )
393                                 {
394                                     for ( AdminUserFieldListenerService adminUserFieldListenerService : SpringContextService
395                                             .getBeansOfType( AdminUserFieldListenerService.class ) )
396                                     {
397                                         adminUserFieldListenerService.doCreateUserFields( user, listUserFields, locale );
398                                     }
399                                 }
400                             }
401                             catch( Exception e )
402                             {
403                                 AppLogService.error( e.getMessage( ), e );
404 
405                                 String strErrorMessage = I18nService.getLocalizedString( MESSAGE_ERROR_IMPORTING_ATTRIBUTES, locale );
406                                 CSVMessageDescriptor error = new CSVMessageDescriptor( CSVMessageLevel.ERROR, nLineNumber, strErrorMessage );
407                                 listMessages.add( error );
408                             }
409                         }
410                     }
411                 }
412             }
413         }
414 
415         return listMessages;
416     }
417     
418     /**
419      * {@inheritDoc}
420      */
421     @Override
422     public String getImportFromFileTemplate( )
423     {
424         return TEMPLATE_WSSO_IMPORT_USERS_FROM_FILE;
425     }
426     
427     /**
428      * {@inheritDoc}
429      */
430     @Override
431     public int getNbMinColumns( )
432     {
433         return CONSTANT_MINIMUM_COLUMNS_PER_LINE;
434     }
435     
436     /**
437      * {@inheritDoc}
438      */
439     @Override
440     public String getAccessCode( String [ ] strLineDataArray )
441     {
442         return AdminUserHome.findUserByEmail( strLineDataArray [0] );
443     }
444     
445     /**
446      * {@inheritDoc}
447      */
448     @Override
449     public String getEmail( String [ ] strLineDataArray )
450     {
451         return strLineDataArray [0];
452     }
453 }