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.html.EncodingService;
51  import fr.paris.lutece.portal.service.i18n.I18nService;
52  import fr.paris.lutece.portal.service.security.ISecurityTokenService;
53  import fr.paris.lutece.portal.service.security.LuteceUser;
54  import fr.paris.lutece.portal.service.security.SecurityService;
55  import fr.paris.lutece.portal.service.security.SecurityTokenService;
56  import fr.paris.lutece.portal.service.security.UserNotSignedException;
57  import fr.paris.lutece.portal.service.site.properties.SitePropertiesGroup;
58  import fr.paris.lutece.portal.service.spring.SpringContextService;
59  import fr.paris.lutece.portal.service.util.AppLogService;
60  import fr.paris.lutece.portal.service.util.AppPropertiesService;
61  import fr.paris.lutece.portal.util.mvc.commons.annotations.Action;
62  import fr.paris.lutece.portal.util.mvc.commons.annotations.View;
63  import fr.paris.lutece.portal.util.mvc.xpage.MVCApplication;
64  import fr.paris.lutece.portal.util.mvc.xpage.annotations.Controller;
65  import fr.paris.lutece.portal.web.xpages.XPage;
66  import fr.paris.lutece.util.url.UrlItem;
67  import fr.paris.lutece.util.ReferenceItem;
68  import fr.paris.lutece.util.ReferenceList;
69  
70  /**
71   * EditIdentity application
72   */
73  @Controller( xpageName = "editIdentity", pageTitleI18nKey = "module.mydashboard.identity.xpage.getIdentity.pageTitle", pagePathI18nKey = "module.mydashboard.identity.xpage.getIdentity.pagePath" )
74  public class EditIdentityXPage extends MVCApplication
75  {
76      /**
77       * 
78       */
79      private static final long serialVersionUID = 1L;
80      
81      private static final String VIEW_GET_EDIT_IDENTITY_INFORMATIONS           = "getEditIdentityInformations";
82      private static final String VIEW_GET_EDIT_IDENTITY_COORDINATES            = "getEditIdentityCoordinates";
83      
84      private static final String ACTION_DO_MODIFY_IDENTITY_INFORMATIONS        = "doModifyIdentityInformations";
85      private static final String ACTION_DO_MODIFY_IDENTITY_COORDINATES         = "doModifyIdentityCoordinates";
86      private static final String ACTION_TYPE_MODIFY_ACCOUNT                    = "modifyAccount";
87      
88      private static final String TEMPLATE_GET_VIEW_MODIFY_IDENTITY             = "skin/plugins/mydashboard/modules/identity/modify_identity.html";
89          
90      private static final String MARK_PAGE_TITLE                               = "pageTitle";
91      private static final String MARK_IDENTITY                                 = "identity";
92      private static final String MARK_GENDER_LIST                              = "genderlist";
93      private static final String MARK_EDIT_INFORMATIONS                        = "editInformations";
94      private static final String MARK_EDIT_COORDINATES                         = "editCoordinates";
95      private static final String MARK_ACTION_NAME                              = "actionName";
96      private static final String MARK_TOKEN                                    = "token";
97      private static final String MARK_BUTTON_VALIDATE                          = "btnValidate";
98      private static final String MARK_MYDASHBOARD_SITE_PROPERTIES              = "mydashboard_site_properties";
99      
100     private static final String SPLIT_PATTERN                                 = ";";
101  
102     private static final String MESSAGE_COORDINATES_PAGE_TITLE = "module.mydashboard.identity.xpage.edit_identity.coordinates.page.title";
103     private static final String MESSAGE_COORDINATES_BTN_VALIDATE = "module.mydashboard.identity.xpage.edit_identity.coordinates.validate.button";
104     private static final String MESSAGE_IDENTITY_INFOS_PAGE_TITLE = "module.mydashboard.identity.xpage.edit_identity.identity.infos.page.title";
105     private static final String MESSAGE_IDENTITY_INFOS_BTN_VALIDATE = "module.mydashboard.identity.xpage.edit_identity.identity.infos.validate.button";
106     
107     private static final String PROPERTY_REDIRECT_URL_CERTIFY_EMAIL_ACTION    = AppPropertiesService.getProperty( "mydashboard.identity.certify_email.action");
108     
109     private static final String PROPERTY_REDIRECT_MODIFY_ACCOUNT_PAGE         = AppPropertiesService.getProperty( "mydashboard.identity.suspicious.modify_account.redirect.page" );
110     private static final String PROPERTY_REDIRECT_MODIFY_ACCOUNT_VIEW         = AppPropertiesService.getProperty( "mydashboard.identity.suspicious.modify_account.redirect.view" );
111 
112     private static final String URL_SUSPICION_IDENTITY_COMPLETION  = "Portal.jsp?page=mydashboardIdentity&view=completeIdentity&origin=" + Constants.ORIGIN_ACTION_MODIFY_ACCOUNT;
113 
114     private DashboardIdentity   _dashboardIdentity;
115     private ISecurityTokenService _securityTokenService = SecurityTokenService.getInstance( );
116     private SitePropertiesGroup _dashboardPropertiesGroup = ( SitePropertiesGroup ) SpringContextService.getBean( "mydashboard-identity.sitePropertiesGroup" );
117     private ReferenceList       _lstGenderList;
118     
119     /**
120      * Constructor
121      */
122     public EditIdentityXPage( )
123     {
124         super( );
125         
126         _lstGenderList = new ReferenceList( );
127 
128         int i = 0;
129 
130         for ( String sItem : Constants.PROPERTY_KEY_GENDER_LIST.split( SPLIT_PATTERN ) )
131         {
132             ReferenceItem refItm = new ReferenceItem( );
133             refItm.setName( sItem );
134             refItm.setCode( String.valueOf( i ) );
135             _lstGenderList.add( refItm );
136             i++;
137         }
138     }
139     
140     /**
141      * Get the edit identity of the informations user view
142      *
143      * @param request
144      *            The request, with the user logged in
145      * @return The XPage to edit the identity of the user
146      * @throws UserNotSignedException
147      *             If the user is not logged in
148      */
149     @View( value = VIEW_GET_EDIT_IDENTITY_INFORMATIONS, defaultView = true )
150     public XPage getEditIdentityInformations( HttpServletRequest request ) throws UserNotSignedException
151     {
152         LuteceUser luteceUser = SecurityService.isAuthenticationEnable( ) ? SecurityService.getInstance( ).getRegisteredUser( request ) : null;
153 
154         if ( luteceUser == null )
155         {
156             throw new UserNotSignedException( );
157         }
158         
159         IdentityDto identity = DashboardIdentityUtils.getInstance( ).getIdentity( luteceUser.getName( ) );
160         _dashboardIdentity = DashboardIdentityUtils.getInstance( ).convertToDashboardIdentity( identity );
161         
162         Map<String, Object> model = getModel( );
163         
164         model.put( MARK_MYDASHBOARD_SITE_PROPERTIES, DatastoreService.getDataByPrefix( _dashboardPropertiesGroup.getDatastoreKeysPrefix( ) ).toMap( ) );
165         model.put( MARK_PAGE_TITLE, I18nService.getLocalizedString( MESSAGE_IDENTITY_INFOS_PAGE_TITLE, request.getLocale( ) ) );
166         model.put( MARK_IDENTITY, _dashboardIdentity );
167         model.put( MARK_GENDER_LIST, _lstGenderList );
168         model.put( MARK_EDIT_INFORMATIONS, true);
169         model.put( MARK_ACTION_NAME, "jsp/site/Portal.jsp?page=editIdentity&action=doModifyIdentityInformations" );
170         model.put( MARK_TOKEN, _securityTokenService.getToken( request, ACTION_DO_MODIFY_IDENTITY_INFORMATIONS ) );
171         model.put( MARK_BUTTON_VALIDATE, I18nService.getLocalizedString( MESSAGE_IDENTITY_INFOS_BTN_VALIDATE, request.getLocale( ) ) );
172         
173         addMessage( request, model );
174         
175         return getXPage( TEMPLATE_GET_VIEW_MODIFY_IDENTITY, request.getLocale( ), model );
176     }
177     
178     private void addMessage( HttpServletRequest request, Map<String, Object> model )
179     {
180         String strErrorMessageInSession = DashboardIdentityUtils.getInstance( ).getMessageInSession( true, true, request );
181         String stInfoMessageInSession = DashboardIdentityUtils.getInstance( ).getMessageInSession( false, true, request );
182         
183         if( StringUtils.isNotEmpty( strErrorMessageInSession ) )
184         {
185             addError( strErrorMessageInSession, request.getLocale( ) );
186             fillCommons( model );
187         }
188         if( StringUtils.isNotEmpty( stInfoMessageInSession ) )
189         {
190             addInfo( stInfoMessageInSession, request.getLocale( ) );
191             fillCommons( model );
192         }
193     }
194     
195     /**
196      * Get the edit identity of the coordinates user view
197      *
198      * @param request
199      *            The request, with the user logged in
200      * @return The XPage to edit the identity of the user
201      * @throws UserNotSignedException
202      *             If the user is not logged in
203      */
204     @View( value = VIEW_GET_EDIT_IDENTITY_COORDINATES )
205     public XPage getEditIdentityCoordinates( HttpServletRequest request ) throws UserNotSignedException
206     {
207         LuteceUser luteceUser = SecurityService.isAuthenticationEnable( ) ? SecurityService.getInstance( ).getRegisteredUser( request ) : null;
208 
209         if ( luteceUser == null )
210         {
211             throw new UserNotSignedException( );
212         }
213         
214         if ( ( _dashboardIdentity == null ) || ( _dashboardIdentity.getConnectionId( ) == null ) || !_dashboardIdentity.getConnectionId( ).getValue( ).equals( luteceUser.getName( ) ) )
215         {
216             IdentityDto identity = DashboardIdentityUtils.getInstance( ).getIdentity( luteceUser.getName( ) );
217             _dashboardIdentity = DashboardIdentityUtils.getInstance( ).convertToDashboardIdentity( identity );
218         }
219         
220         Map<String, Object> model = getModel( );
221         model.put( MARK_MYDASHBOARD_SITE_PROPERTIES, DatastoreService.getDataByPrefix( _dashboardPropertiesGroup.getDatastoreKeysPrefix( ) ).toMap( ) );
222         model.put( MARK_PAGE_TITLE, I18nService.getLocalizedString( MESSAGE_COORDINATES_PAGE_TITLE, request.getLocale( ) ) );
223         model.put( MARK_IDENTITY, _dashboardIdentity );
224         model.put( MARK_EDIT_COORDINATES, true);
225         model.put( MARK_ACTION_NAME, "jsp/site/Portal.jsp?page=editIdentity&action=doModifyIdentityCoordinates" );
226         model.put( MARK_TOKEN, _securityTokenService.getToken( request, ACTION_DO_MODIFY_IDENTITY_COORDINATES ) );
227         model.put( MARK_BUTTON_VALIDATE, I18nService.getLocalizedString( MESSAGE_COORDINATES_BTN_VALIDATE, request.getLocale( ) ) );
228         
229         return getXPage( TEMPLATE_GET_VIEW_MODIFY_IDENTITY, request.getLocale( ), model );
230     }
231     
232     /**
233      * Do the modification of the user identity informations
234      *
235      * @param request
236      *            The request
237      * @return The next view to redirect to
238      * @throws UserNotSignedException
239      *             If the user has not signed in
240      * @throws AccessDeniedException 
241      */
242     @Action( ACTION_DO_MODIFY_IDENTITY_INFORMATIONS )
243     public XPage doModifyIdentityInformations( HttpServletRequest request ) throws UserNotSignedException, AccessDeniedException
244     {
245         // CSRF Token control
246         if ( !_securityTokenService.validate( request, ACTION_DO_MODIFY_IDENTITY_INFORMATIONS ) )
247         {
248             throw new AccessDeniedException( Constants.MESSAGE_ERROR_TOKEN  );
249         }
250         
251         LuteceUser luteceUser = SecurityService.isAuthenticationEnable( ) ? SecurityService.getInstance( ).getRegisteredUser( request ) : null;
252 
253         if ( luteceUser == null )
254         {
255             throw new UserNotSignedException( );
256         }
257         
258         // fill dashboardIdentity from submitted form
259         DashboardIdentityService.getInstance( ).populateDashboardIdentity( _dashboardIdentity, request );
260         _dashboardIdentity.getGender().setMandatory( true );
261         _dashboardIdentity.getLastName().setMandatory( true );
262         _dashboardIdentity.getFirstname().setMandatory( true );
263         _dashboardIdentity.getBirthdate().setMandatory( true );
264         
265         Map<String, String> hashErros = DashboardIdentityService.getInstance( ).checkDashboardIdentityFields( _dashboardIdentity, request, false, AttributeCategory.IDENTITY_INDORMATIONS );
266         if ( !hashErros.isEmpty( ) )
267         {
268             hashErros.forEach( ( x, y ) -> addError( y ) );
269             return redirectView( request, VIEW_GET_EDIT_IDENTITY_INFORMATIONS );
270         }
271         
272         //Suspicious identity
273         if( DashboardIdentityService.getInstance( ).existSuspiciousIdentities( _dashboardIdentity,DashboardIdentityUtils.getInstance( ).getAllSuspiciousIdentityRules( ) ) )
274         {
275             DashboardIdentityUtils.getInstance( ).setCurrentDashboardIdentityInSession( request, _dashboardIdentity );
276             DashboardIdentityUtils.getInstance( ).setRedirectUrlAfterCompletionInSession( PROPERTY_REDIRECT_MODIFY_ACCOUNT_PAGE, PROPERTY_REDIRECT_MODIFY_ACCOUNT_VIEW, request );
277             
278             return redirect( request, new UrlItem( URL_SUSPICION_IDENTITY_COMPLETION ).getUrl( ) );            
279         }
280         
281         try
282         {
283             DashboardIdentityService.getInstance( ).updateDashboardIdentity( _dashboardIdentity, false, AttributeCategory.IDENTITY_INDORMATIONS );
284         }
285         catch ( Exception appEx )
286         {
287 
288             AppLogService.error( "An error appear during updating Identity informations for  user guid {} ", _dashboardIdentity.getConnectionId( ), appEx );
289 
290             addError( Constants.MESSAGE_ERROR_UPDATE_IDENTITY, request.getLocale( ) );
291 
292             return redirectView( request, VIEW_GET_EDIT_IDENTITY_INFORMATIONS );
293         }
294         
295         // reint dashboard and check identity informations
296         _dashboardIdentity = null;
297 
298         addInfo( Constants.MESSAGE_INFO_IDENTITY_UPDATED, request.getLocale( ) );
299 
300         return redirectView( request, VIEW_GET_EDIT_IDENTITY_INFORMATIONS );
301     }
302     
303     /**
304      * Do the modification of the user identity coordinates
305      *
306      * @param request
307      *            The request
308      * @return The next view to redirect to
309      * @throws UserNotSignedException
310      *             If the user has not signed in
311      * @throws AccessDeniedException 
312      */
313     @Action( ACTION_DO_MODIFY_IDENTITY_COORDINATES )
314     public XPage doModifyIdentityCoordinates( HttpServletRequest request ) throws UserNotSignedException, AccessDeniedException
315     {
316         // CSRF Token control
317         if ( !_securityTokenService.validate( request, ACTION_DO_MODIFY_IDENTITY_COORDINATES ) )
318         {
319             throw new AccessDeniedException( Constants.MESSAGE_ERROR_TOKEN  );
320         }
321         
322         LuteceUser luteceUser = SecurityService.isAuthenticationEnable( ) ? SecurityService.getInstance( ).getRegisteredUser( request ) : null;
323 
324         if ( luteceUser == null )
325         {
326             throw new UserNotSignedException( );
327         }
328         
329         // fill dashboardIdentity from submitted form
330         DashboardIdentityService.getInstance( ).populateDashboardIdentity( _dashboardIdentity, request );
331         
332         Map<String, String> hashErros = DashboardIdentityService.getInstance( ).checkDashboardIdentityFields( _dashboardIdentity, request, false );
333         if ( !hashErros.isEmpty( ) )
334         {
335             hashErros.forEach( ( x, y ) -> addError( y ) );
336             return redirectView( request, VIEW_GET_EDIT_IDENTITY_COORDINATES );
337         }
338         
339         try
340         {
341             DashboardIdentityService.getInstance( ).updateDashboardIdentity( _dashboardIdentity, false, AttributeCategory.COORDINATES_INFORMATIONS );
342         }
343         catch ( Exception appEx )
344         {
345 
346             AppLogService.error( "An error appear during updating Identity coordinates for  user guid {} ", _dashboardIdentity.getConnectionId( ), appEx );
347 
348             addError( Constants.MESSAGE_ERROR_UPDATE_IDENTITY, request.getLocale( ) );
349 
350             return redirectView( request, VIEW_GET_EDIT_IDENTITY_COORDINATES );
351         }
352         
353         IdentityDto identityFromRic = DashboardIdentityUtils.getInstance( ).getIdentity( luteceUser.getName( ) );
354         DashboardIdentity dashboardIdentityFromRic = DashboardIdentityUtils.getInstance( ).convertToDashboardIdentity( identityFromRic );
355         
356         if ( !_dashboardIdentity.getEmail( ).getValue( ).equals( dashboardIdentityFromRic.getEmail( ).getValue( ) ) )
357         {
358             String strEncodeEmail =  EncodingService.encodeUrl( _dashboardIdentity.getEmail( ).getValue( ) );
359                     
360             return redirect( request, PROPERTY_REDIRECT_URL_CERTIFY_EMAIL_ACTION + "&email=" + strEncodeEmail + "&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 }