View Javadoc
1   /*
2    * Copyright (c) 2002-2024, City of Paris
3    * All rights reserved.
4    *
5    * Redistribution and use in source and binary forms, with or without
6    * modification, are permitted provided that the following conditions
7    * are met:
8    *
9    *  1. Redistributions of source code must retain the above copyright notice
10   *     and the following disclaimer.
11   *
12   *  2. Redistributions in binary form must reproduce the above copyright notice
13   *     and the following disclaimer in the documentation and/or other materials
14   *     provided with the distribution.
15   *
16   *  3. Neither the name of 'Mairie de Paris' nor 'Lutece' nor the names of its
17   *     contributors may be used to endorse or promote products derived from
18   *     this software without specific prior written permission.
19   *
20   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23   * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
24   * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25   * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26   * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27   * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28   * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30   * POSSIBILITY OF SUCH DAMAGE.
31   *
32   * License 1.0
33   */
34  package fr.paris.lutece.plugins.mydashboard.modules.identity.web;
35  
36  import java.util.Map;
37  
38  import javax.servlet.http.HttpServletRequest;
39  
40  import org.apache.commons.lang3.StringUtils;
41  
42  import fr.paris.lutece.plugins.identitystore.v3.web.rs.dto.common.IdentityDto;
43  import fr.paris.lutece.plugins.mydashboard.modules.identity.business.AttributeCategory;
44  import fr.paris.lutece.plugins.mydashboard.modules.identity.business.DashboardIdentity;
45  import fr.paris.lutece.plugins.mydashboard.modules.identity.service.DashboardIdentityService;
46  import fr.paris.lutece.plugins.mydashboard.modules.identity.util.Constants;
47  import fr.paris.lutece.plugins.mydashboard.modules.identity.util.DashboardIdentityUtils;
48  import fr.paris.lutece.portal.service.admin.AccessDeniedException;
49  import fr.paris.lutece.portal.service.datastore.DatastoreService;
50  import fr.paris.lutece.portal.service.i18n.I18nService;
51  import fr.paris.lutece.portal.service.security.ISecurityTokenService;
52  import fr.paris.lutece.portal.service.security.LuteceUser;
53  import fr.paris.lutece.portal.service.security.SecurityService;
54  import fr.paris.lutece.portal.service.security.SecurityTokenService;
55  import fr.paris.lutece.portal.service.security.UserNotSignedException;
56  import fr.paris.lutece.portal.service.site.properties.SitePropertiesGroup;
57  import fr.paris.lutece.portal.service.spring.SpringContextService;
58  import fr.paris.lutece.portal.service.util.AppLogService;
59  import fr.paris.lutece.portal.service.util.AppPropertiesService;
60  import fr.paris.lutece.portal.util.mvc.commons.annotations.Action;
61  import fr.paris.lutece.portal.util.mvc.commons.annotations.View;
62  import fr.paris.lutece.portal.util.mvc.xpage.MVCApplication;
63  import fr.paris.lutece.portal.util.mvc.xpage.annotations.Controller;
64  import fr.paris.lutece.portal.web.xpages.XPage;
65  import fr.paris.lutece.util.url.UrlItem;
66  import fr.paris.lutece.util.ReferenceItem;
67  import fr.paris.lutece.util.ReferenceList;
68  
69  /**
70   * EditIdentity application
71   */
72  @Controller( xpageName = "editIdentity", pageTitleI18nKey = "module.mydashboard.identity.xpage.getIdentity.pageTitle", pagePathI18nKey = "module.mydashboard.identity.xpage.getIdentity.pagePath" )
73  public class EditIdentityXPage extends MVCApplication
74  {
75      /**
76       * 
77       */
78      private static final long serialVersionUID = 1L;
79      
80      private static final String VIEW_GET_EDIT_IDENTITY_INFORMATIONS           = "getEditIdentityInformations";
81      private static final String VIEW_GET_EDIT_IDENTITY_COORDINATES            = "getEditIdentityCoordinates";
82      
83      private static final String ACTION_DO_MODIFY_IDENTITY_INFORMATIONS        = "doModifyIdentityInformations";
84      private static final String ACTION_DO_MODIFY_IDENTITY_COORDINATES         = "doModifyIdentityCoordinates";
85      private static final String ACTION_TYPE_MODIFY_ACCOUNT                    = "modifyAccount";
86      
87      private static final String TEMPLATE_GET_VIEW_MODIFY_IDENTITY             = "skin/plugins/mydashboard/modules/identity/modify_identity.html";
88          
89      private static final String MARK_PAGE_TITLE                               = "pageTitle";
90      private static final String MARK_IDENTITY                                 = "identity";
91      private static final String MARK_GENDER_LIST                              = "genderlist";
92      private static final String MARK_EDIT_INFORMATIONS                        = "editInformations";
93      private static final String MARK_EDIT_COORDINATES                         = "editCoordinates";
94      private static final String MARK_ACTION_NAME                              = "actionName";
95      private static final String MARK_TOKEN                                    = "token";
96      private static final String MARK_BUTTON_VALIDATE                          = "btnValidate";
97      private static final String MARK_MYDASHBOARD_SITE_PROPERTIES              = "mydashboard_site_properties";
98      
99      private static final String SPLIT_PATTERN                                 = ";";
100  
101     private static final String MESSAGE_COORDINATES_PAGE_TITLE = "module.mydashboard.identity.xpage.edit_identity.coordinates.page.title";
102     private static final String MESSAGE_COORDINATES_BTN_VALIDATE = "module.mydashboard.identity.xpage.edit_identity.coordinates.validate.button";
103     private static final String MESSAGE_IDENTITY_INFOS_PAGE_TITLE = "module.mydashboard.identity.xpage.edit_identity.identity.infos.page.title";
104     private static final String MESSAGE_IDENTITY_INFOS_BTN_VALIDATE = "module.mydashboard.identity.xpage.edit_identity.identity.infos.validate.button";
105     
106     private static final String PROPERTY_REDIRECT_URL_CERTIFY_EMAIL_ACTION    = AppPropertiesService.getProperty( "mydashboard.identity.certify_email.action");
107     
108     private static final String PROPERTY_REDIRECT_MODIFY_ACCOUNT_PAGE         = AppPropertiesService.getProperty( "mydashboard.identity.suspicious.modify_account.redirect.page" );
109     private static final String PROPERTY_REDIRECT_MODIFY_ACCOUNT_VIEW         = AppPropertiesService.getProperty( "mydashboard.identity.suspicious.modify_account.redirect.view" );
110 
111     private static final String URL_SUSPICION_IDENTITY_COMPLETION  = "Portal.jsp?page=mydashboardIdentity&view=completeIdentity&origin=" + Constants.ORIGIN_ACTION_MODIFY_ACCOUNT;
112 
113     private DashboardIdentity   _dashboardIdentity;
114     private ISecurityTokenService _securityTokenService = SecurityTokenService.getInstance( );
115     private SitePropertiesGroup _dashboardPropertiesGroup = ( SitePropertiesGroup ) SpringContextService.getBean( "mydashboard-identity.sitePropertiesGroup" );
116     private ReferenceList       _lstGenderList;
117     
118     /**
119      * Constructor
120      */
121     public EditIdentityXPage( )
122     {
123         super( );
124         
125         _lstGenderList = new ReferenceList( );
126 
127         int i = 0;
128 
129         for ( String sItem : Constants.PROPERTY_KEY_GENDER_LIST.split( SPLIT_PATTERN ) )
130         {
131             ReferenceItem refItm = new ReferenceItem( );
132             refItm.setName( sItem );
133             refItm.setCode( String.valueOf( i ) );
134             _lstGenderList.add( refItm );
135             i++;
136         }
137     }
138     
139     /**
140      * Get the edit identity of the informations user view
141      *
142      * @param request
143      *            The request, with the user logged in
144      * @return The XPage to edit the identity of the user
145      * @throws UserNotSignedException
146      *             If the user is not logged in
147      */
148     @View( value = VIEW_GET_EDIT_IDENTITY_INFORMATIONS, defaultView = true )
149     public XPage getEditIdentityInformations( HttpServletRequest request ) throws UserNotSignedException
150     {
151         LuteceUser luteceUser = SecurityService.isAuthenticationEnable( ) ? SecurityService.getInstance( ).getRegisteredUser( request ) : null;
152 
153         if ( luteceUser == null )
154         {
155             throw new UserNotSignedException( );
156         }
157         
158         if ( ( _dashboardIdentity == null ) || ( _dashboardIdentity.getConnectionId( ) == null ) || !_dashboardIdentity.getConnectionId( ).getValue( ).equals( luteceUser.getName( ) ) )
159         {
160             IdentityDto identity = DashboardIdentityUtils.getInstance( ).getIdentity( luteceUser.getName( ) );
161             _dashboardIdentity = DashboardIdentityUtils.getInstance( ).convertToDashboardIdentity( identity );
162         }        
163         
164         Map<String, Object> model = getModel( );
165         
166         model.put( MARK_MYDASHBOARD_SITE_PROPERTIES, DatastoreService.getDataByPrefix( _dashboardPropertiesGroup.getDatastoreKeysPrefix( ) ).toMap( ) );
167         model.put( MARK_PAGE_TITLE, I18nService.getLocalizedString( MESSAGE_IDENTITY_INFOS_PAGE_TITLE, request.getLocale( ) ) );
168         model.put( MARK_IDENTITY, _dashboardIdentity );
169         model.put( MARK_GENDER_LIST, _lstGenderList );
170         model.put( MARK_EDIT_INFORMATIONS, true);
171         model.put( MARK_ACTION_NAME, "jsp/site/Portal.jsp?page=editIdentity&action=doModifyIdentityInformations" );
172         model.put( MARK_TOKEN, _securityTokenService.getToken( request, ACTION_DO_MODIFY_IDENTITY_INFORMATIONS ) );
173         model.put( MARK_BUTTON_VALIDATE, I18nService.getLocalizedString( MESSAGE_IDENTITY_INFOS_BTN_VALIDATE, request.getLocale( ) ) );
174         
175         addMessage( request, model );
176         
177         return getXPage( TEMPLATE_GET_VIEW_MODIFY_IDENTITY, request.getLocale( ), model );
178     }
179     
180     private void addMessage( HttpServletRequest request, Map<String, Object> model )
181     {
182         String strErrorMessageInSession = DashboardIdentityUtils.getInstance( ).getMessageInSession( true, true, request );
183         String stInfoMessageInSession = DashboardIdentityUtils.getInstance( ).getMessageInSession( false, true, request );
184         
185         if( StringUtils.isNotEmpty( strErrorMessageInSession ) )
186         {
187             addError( strErrorMessageInSession, request.getLocale( ) );
188             fillCommons( model );
189         }
190         if( StringUtils.isNotEmpty( stInfoMessageInSession ) )
191         {
192             addInfo( stInfoMessageInSession, request.getLocale( ) );
193             fillCommons( model );
194         }
195     }
196     
197     /**
198      * Get the edit identity of the coordinates user view
199      *
200      * @param request
201      *            The request, with the user logged in
202      * @return The XPage to edit the identity of the user
203      * @throws UserNotSignedException
204      *             If the user is not logged in
205      */
206     @View( value = VIEW_GET_EDIT_IDENTITY_COORDINATES )
207     public XPage getEditIdentityCoordinates( HttpServletRequest request ) throws UserNotSignedException
208     {
209         LuteceUser luteceUser = SecurityService.isAuthenticationEnable( ) ? SecurityService.getInstance( ).getRegisteredUser( request ) : null;
210 
211         if ( luteceUser == null )
212         {
213             throw new UserNotSignedException( );
214         }
215         
216         if ( ( _dashboardIdentity == null ) || ( _dashboardIdentity.getConnectionId( ) == null ) || !_dashboardIdentity.getConnectionId( ).getValue( ).equals( luteceUser.getName( ) ) )
217         {
218             IdentityDto identity = DashboardIdentityUtils.getInstance( ).getIdentity( luteceUser.getName( ) );
219             _dashboardIdentity = DashboardIdentityUtils.getInstance( ).convertToDashboardIdentity( identity );
220         }
221         
222         Map<String, Object> model = getModel( );
223         model.put( MARK_MYDASHBOARD_SITE_PROPERTIES, DatastoreService.getDataByPrefix( _dashboardPropertiesGroup.getDatastoreKeysPrefix( ) ).toMap( ) );
224         model.put( MARK_PAGE_TITLE, I18nService.getLocalizedString( MESSAGE_COORDINATES_PAGE_TITLE, request.getLocale( ) ) );
225         model.put( MARK_IDENTITY, _dashboardIdentity );
226         model.put( MARK_EDIT_COORDINATES, true);
227         model.put( MARK_ACTION_NAME, "jsp/site/Portal.jsp?page=editIdentity&action=doModifyIdentityCoordinates" );
228         model.put( MARK_TOKEN, _securityTokenService.getToken( request, ACTION_DO_MODIFY_IDENTITY_COORDINATES ) );
229         model.put( MARK_BUTTON_VALIDATE, I18nService.getLocalizedString( MESSAGE_COORDINATES_BTN_VALIDATE, request.getLocale( ) ) );
230         
231         return getXPage( TEMPLATE_GET_VIEW_MODIFY_IDENTITY, request.getLocale( ), model );
232     }
233     
234     /**
235      * Do the modification of the user identity informations
236      *
237      * @param request
238      *            The request
239      * @return The next view to redirect to
240      * @throws UserNotSignedException
241      *             If the user has not signed in
242      * @throws AccessDeniedException 
243      */
244     @Action( ACTION_DO_MODIFY_IDENTITY_INFORMATIONS )
245     public XPage doModifyIdentityInformations( HttpServletRequest request ) throws UserNotSignedException, AccessDeniedException
246     {
247         // CSRF Token control
248         if ( !_securityTokenService.validate( request, ACTION_DO_MODIFY_IDENTITY_INFORMATIONS ) )
249         {
250             throw new AccessDeniedException( Constants.MESSAGE_ERROR_TOKEN  );
251         }
252         
253         LuteceUser luteceUser = SecurityService.isAuthenticationEnable( ) ? SecurityService.getInstance( ).getRegisteredUser( request ) : null;
254 
255         if ( luteceUser == null )
256         {
257             throw new UserNotSignedException( );
258         }
259         
260         // fill dashboardIdentity from submitted form
261         DashboardIdentityService.getInstance( ).populateDashboardIdentity( _dashboardIdentity, request );
262         _dashboardIdentity.getGender().setMandatory( true );
263         _dashboardIdentity.getLastName().setMandatory( true );
264         _dashboardIdentity.getFirstname().setMandatory( true );
265         _dashboardIdentity.getBirthdate().setMandatory( true );
266         
267         Map<String, String> hashErros = DashboardIdentityService.getInstance( ).checkDashboardIdentityFields( _dashboardIdentity, request, false, AttributeCategory.IDENTITY_INDORMATIONS );
268         if ( !hashErros.isEmpty( ) )
269         {
270             hashErros.forEach( ( x, y ) -> addError( y ) );
271             return redirectView( request, VIEW_GET_EDIT_IDENTITY_INFORMATIONS );
272         }
273         
274         //Suspicious identity
275         if( DashboardIdentityService.getInstance( ).existSuspiciousIdentities( _dashboardIdentity,DashboardIdentityUtils.getInstance( ).getAllSuspiciousIdentityRules( ) ) )
276         {
277             DashboardIdentityUtils.getInstance( ).setCurrentDashboardIdentityInSession( request, _dashboardIdentity );
278             DashboardIdentityUtils.getInstance( ).setRedirectUrlAfterCompletionInSession( PROPERTY_REDIRECT_MODIFY_ACCOUNT_PAGE, PROPERTY_REDIRECT_MODIFY_ACCOUNT_VIEW, request );
279             
280             return redirect( request, new UrlItem( URL_SUSPICION_IDENTITY_COMPLETION ).getUrl( ) );            
281         }
282         
283         try
284         {
285             DashboardIdentityService.getInstance( ).updateDashboardIdentity( _dashboardIdentity, false, AttributeCategory.IDENTITY_INDORMATIONS );
286         }
287         catch ( Exception appEx )
288         {
289 
290             AppLogService.error( "An error appear during updating Identity informations for  user guid {} ", _dashboardIdentity.getConnectionId( ), appEx );
291 
292             addError( Constants.MESSAGE_ERROR_UPDATE_IDENTITY, request.getLocale( ) );
293 
294             return redirectView( request, VIEW_GET_EDIT_IDENTITY_INFORMATIONS );
295         }
296         
297         // reint dashboard and check identity informations
298         _dashboardIdentity = null;
299 
300         addInfo( Constants.MESSAGE_INFO_IDENTITY_UPDATED, request.getLocale( ) );
301 
302         return redirectView( request, VIEW_GET_EDIT_IDENTITY_INFORMATIONS );
303     }
304     
305     /**
306      * Do the modification of the user identity coordinates
307      *
308      * @param request
309      *            The request
310      * @return The next view to redirect to
311      * @throws UserNotSignedException
312      *             If the user has not signed in
313      * @throws AccessDeniedException 
314      */
315     @Action( ACTION_DO_MODIFY_IDENTITY_COORDINATES )
316     public XPage doModifyIdentityCoordinates( HttpServletRequest request ) throws UserNotSignedException, AccessDeniedException
317     {
318         // CSRF Token control
319         if ( !_securityTokenService.validate( request, ACTION_DO_MODIFY_IDENTITY_COORDINATES ) )
320         {
321             throw new AccessDeniedException( Constants.MESSAGE_ERROR_TOKEN  );
322         }
323         
324         LuteceUser luteceUser = SecurityService.isAuthenticationEnable( ) ? SecurityService.getInstance( ).getRegisteredUser( request ) : null;
325 
326         if ( luteceUser == null )
327         {
328             throw new UserNotSignedException( );
329         }
330         
331         // fill dashboardIdentity from submitted form
332         DashboardIdentityService.getInstance( ).populateDashboardIdentity( _dashboardIdentity, request );
333         
334         Map<String, String> hashErros = DashboardIdentityService.getInstance( ).checkDashboardIdentityFields( _dashboardIdentity, request, false );
335         if ( !hashErros.isEmpty( ) )
336         {
337             hashErros.forEach( ( x, y ) -> addError( y ) );
338             return redirectView( request, VIEW_GET_EDIT_IDENTITY_COORDINATES );
339         }
340         
341         try
342         {
343             DashboardIdentityService.getInstance( ).updateDashboardIdentity( _dashboardIdentity, false, AttributeCategory.COORDINATES_INFORMATIONS );
344         }
345         catch ( Exception appEx )
346         {
347 
348             AppLogService.error( "An error appear during updating Identity coordinates for  user guid {} ", _dashboardIdentity.getConnectionId( ), appEx );
349 
350             addError( Constants.MESSAGE_ERROR_UPDATE_IDENTITY, request.getLocale( ) );
351 
352             return redirectView( request, VIEW_GET_EDIT_IDENTITY_COORDINATES );
353         }
354         
355         IdentityDto identityFromRic = DashboardIdentityUtils.getInstance( ).getIdentity( luteceUser.getName( ) );
356         DashboardIdentity dashboardIdentityFromRic = DashboardIdentityUtils.getInstance( ).convertToDashboardIdentity( identityFromRic );
357         
358         if ( !_dashboardIdentity.getEmail( ).getValue( ).equals( dashboardIdentityFromRic.getEmail( ).getValue( ) ) )
359         {
360             return redirect( request, PROPERTY_REDIRECT_URL_CERTIFY_EMAIL_ACTION + "&email=" + _dashboardIdentity.getEmail( ).getValue( ) + "&token=" + _securityTokenService.getToken( request, ACTION_TYPE_MODIFY_ACCOUNT ) );
361         }
362         
363         // reint dashboard and check identity informations
364         _dashboardIdentity = null;
365 
366         addInfo( Constants.MESSAGE_INFO_IDENTITY_UPDATED, request.getLocale( ) );
367 
368         return redirectView( request, VIEW_GET_EDIT_IDENTITY_COORDINATES );
369     }
370 }