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.identitystore.web;
35  
36  import fr.paris.lutece.plugins.identitystore.business.attribute.AttributeKey;
37  import fr.paris.lutece.plugins.identitystore.business.attribute.AttributeKeyHome;
38  import fr.paris.lutece.plugins.identitystore.business.rules.search.IdentitySearchRule;
39  import fr.paris.lutece.plugins.identitystore.business.rules.search.IdentitySearchRuleHome;
40  import fr.paris.lutece.plugins.identitystore.business.rules.search.SearchRuleType;
41  import fr.paris.lutece.portal.service.admin.AccessDeniedException;
42  import fr.paris.lutece.portal.service.message.AdminMessage;
43  import fr.paris.lutece.portal.service.message.AdminMessageService;
44  import fr.paris.lutece.portal.service.security.SecurityTokenService;
45  import fr.paris.lutece.portal.service.util.AppException;
46  import fr.paris.lutece.portal.util.mvc.admin.annotations.Controller;
47  import fr.paris.lutece.portal.util.mvc.commons.annotations.Action;
48  import fr.paris.lutece.portal.util.mvc.commons.annotations.View;
49  import fr.paris.lutece.util.html.AbstractPaginator;
50  import fr.paris.lutece.util.url.UrlItem;
51  
52  import javax.servlet.http.HttpServletRequest;
53  import java.util.ArrayList;
54  import java.util.Arrays;
55  import java.util.List;
56  import java.util.Map;
57  import java.util.stream.Collectors;
58  
59  /**
60   * This class provides the user interface to manage IdentitySearchRule features ( manage, create, modify, remove )
61   */
62  @Controller( controllerJsp = "ManageIdentitySearchRules.jsp", controllerPath = "jsp/admin/plugins/identitystore/", right = "IDENTITYSTORE_IDENTITY_SEARCH_RULES_MANAGEMENT" )
63  public class IdentitySearchRuleJspBean extends ManageIdentitiesJspBean
64  {
65  
66      // Templates
67      private static final String TEMPLATE_MANAGE_IDENTITYSEARCHRULES = "/admin/plugins/identitystore/manage_identitysearchrules.html";
68      private static final String TEMPLATE_CREATE_IDENTITYSEARCHRULE = "/admin/plugins/identitystore/create_identitysearchrule.html";
69      private static final String TEMPLATE_MODIFY_IDENTITYSEARCHRULE = "/admin/plugins/identitystore/create_identitysearchrule.html";
70  
71      // Properties for page titles
72      private static final String PROPERTY_PAGE_TITLE_MANAGE_IDENTITYSEARCHRULES = "identitystore.manage_identitysearchrules.pageTitle";
73      private static final String PROPERTY_PAGE_TITLE_MODIFY_IDENTITYSEARCHRULE = "identitystore.modify_identitysearchrule.pageTitle";
74      private static final String PROPERTY_PAGE_TITLE_CREATE_IDENTITYSEARCHRULE = "identitystore.create_identitysearchrule.pageTitle";
75  
76      // Markers
77      private static final String MARK_IDENTITYSEARCHRULE_LIST = "identitysearchrule_list";
78      private static final String MARK_IDENTITYSEARCHRULE = "identitysearchrule";
79      private static final String MARK_ACTION = "action";
80      private static final String MARK_AVAILABLE_ATTRIBUTES = "available_attributes";
81      private static final String MARK_AVAILABLE_RULE_TYPES = "available_rule_types";
82      private static final String MARK_SELECTED_ATTRIBUTES = "rule_attributes";
83  
84      private static final String JSP_MANAGE_IDENTITYSEARCHRULES = "jsp/admin/plugins/identitystore/ManageIdentitySearchRules.jsp";
85  
86      // Views
87      private static final String VIEW_MANAGE_IDENTITYSEARCHRULES = "manageIdentitySearchRules";
88      private static final String VIEW_CREATE_IDENTITYSEARCHRULE = "createIdentitySearchRule";
89      private static final String VIEW_MODIFY_IDENTITYSEARCHRULE = "modifyIdentitySearchRule";
90  
91      // Actions
92      private static final String ACTION_CREATE_IDENTITYSEARCHRULE = "createIdentitySearchRule";
93      private static final String ACTION_MODIFY_IDENTITYSEARCHRULE = "modifyIdentitySearchRule";
94      private static final String ACTION_REMOVE_IDENTITYSEARCHRULE = "removeIdentitySearchRule";
95      private static final String ACTION_CONFIRM_REMOVE_IDENTITYSEARCHRULE = "confirmRemoveIdentitySearchRule";
96  
97      // Parameters
98      private static final String PARAMETER_ID_IDENTITYSEARCHRULE = "id";
99      private static final String PARAMETER_SELECTED_TYPE = "selected_type";
100     private static final String PARAMETER_SELECTED_ATTRIBUTES = "selected_attributes";
101 
102     // Errors
103     private static final String ERROR_RESOURCE_NOT_FOUND = "Resource not found";
104 
105     // Properties
106     private static final String MESSAGE_CONFIRM_REMOVE_IDENTITYSEARCHRULE = "identitystore.message.confirmRemoveIdentitySearchRule";
107 
108     // Infos
109     private static final String INFO_IDENTITYSEARCHRULE_CREATED = "identitystore.info.identitysearchrule.created";
110     private static final String INFO_IDENTITYSEARCHRULE_UPDATED = "identitystore.info.identitysearchrule.updated";
111     private static final String INFO_IDENTITYSEARCHRULE_REMOVED = "identitystore.info.identitysearchrule.removed";
112 
113     // Session variable to store working values
114     private IdentitySearchRule _identitySearchRule;
115     private final List<IdentitySearchRule> _listIdentitySearchRules = new ArrayList<>( );
116 
117     /**
118      * Build the Manage View
119      *
120      * @param request
121      *            The HTTP request
122      * @return The page
123      */
124     @View( value = VIEW_MANAGE_IDENTITYSEARCHRULES, defaultView = true )
125     public String getManageIdentitySearchRules( final HttpServletRequest request )
126     {
127         _identitySearchRule = null;
128         _listIdentitySearchRules.clear( );
129 
130         if ( request.getParameter( AbstractPaginator.PARAMETER_PAGE_INDEX ) == null || _listIdentitySearchRules.isEmpty( ) )
131         {
132             _listIdentitySearchRules.addAll( IdentitySearchRuleHome.findAll( ) );
133         }
134 
135         final Map<String, Object> model = getPaginatedListModel( request, MARK_IDENTITYSEARCHRULE_LIST, _listIdentitySearchRules,
136                 JSP_MANAGE_IDENTITYSEARCHRULES );
137         return getPage( PROPERTY_PAGE_TITLE_MANAGE_IDENTITYSEARCHRULES, TEMPLATE_MANAGE_IDENTITYSEARCHRULES, model );
138     }
139 
140     /**
141      * Returns the form to create an identity search rule
142      *
143      * @param request
144      *            The Http request
145      * @return the html code of the identity search rule form
146      */
147     @View( VIEW_CREATE_IDENTITYSEARCHRULE )
148     public String getCreateDuplicateRule( HttpServletRequest request )
149     {
150         final Map<String, Object> model = getModel( );
151 
152         if ( _identitySearchRule == null )
153         {
154             _identitySearchRule = new IdentitySearchRule( );
155         }
156 
157         model.put( MARK_IDENTITYSEARCHRULE, _identitySearchRule );
158         model.put( MARK_SELECTED_ATTRIBUTES, new ArrayList<>( ) );
159         model.put( MARK_AVAILABLE_RULE_TYPES, SearchRuleType.values( ) );
160         model.put( MARK_ACTION, "action_createIdentitySearchRule" );
161         model.put( MARK_AVAILABLE_ATTRIBUTES, AttributeKeyHome.getAttributeKeysList( false ) );
162         model.put( SecurityTokenService.MARK_TOKEN, SecurityTokenService.getInstance( ).getToken( request, ACTION_CREATE_IDENTITYSEARCHRULE ) );
163 
164         return getPage( PROPERTY_PAGE_TITLE_CREATE_IDENTITYSEARCHRULE, TEMPLATE_CREATE_IDENTITYSEARCHRULE, model );
165     }
166 
167     /**
168      * Process the data capture form of a new identity search rule
169      *
170      * @param request
171      *            The Http Request
172      * @return The Jsp URL of the process result
173      * @throws AccessDeniedException
174      */
175     @Action( ACTION_CREATE_IDENTITYSEARCHRULE )
176     public String doCreateIdentitySearchRule( final HttpServletRequest request ) throws AccessDeniedException
177     {
178         _identitySearchRule.setType( SearchRuleType.valueOf( request.getParameter( PARAMETER_SELECTED_TYPE ) ) );
179         _identitySearchRule.getAttributes( ).addAll( this.extractAttributeKeys( request ) );
180 
181         if ( !SecurityTokenService.getInstance( ).validate( request, ACTION_CREATE_IDENTITYSEARCHRULE ) )
182         {
183             throw new AccessDeniedException( "Invalid security token" );
184         }
185 
186         // Check constraints
187         if ( _identitySearchRule.getType( ) == null || _identitySearchRule.getAttributes( ).isEmpty( ) )
188         {
189             return redirect( request, VIEW_CREATE_IDENTITYSEARCHRULE );
190         }
191 
192         try
193         {
194             IdentitySearchRuleHome.create( _identitySearchRule );
195         }
196         catch( final Exception e )
197         {
198             addError( e.getMessage( ) );
199             return redirectView( request, VIEW_CREATE_IDENTITYSEARCHRULE );
200         }
201 
202         addInfo( INFO_IDENTITYSEARCHRULE_CREATED, getLocale( ) );
203         _listIdentitySearchRules.clear( );
204         _identitySearchRule = null;
205 
206         return redirectView( request, VIEW_MANAGE_IDENTITYSEARCHRULES );
207     }
208 
209     private List<AttributeKey> extractAttributeKeys( final HttpServletRequest request )
210     {
211         final String [ ] selectedAttributes = request.getParameterValues( PARAMETER_SELECTED_ATTRIBUTES );
212         if ( selectedAttributes != null )
213         {
214             return Arrays.stream( selectedAttributes ).map( key -> AttributeKeyHome.findByKey( key, false ) ).collect( Collectors.toList( ) );
215         }
216         return new ArrayList<>( );
217     }
218 
219     /**
220      * Manages the removal form of an identity search rule whose identifier is in the http request
221      *
222      * @param request
223      *            The Http request
224      * @return the html code to confirm
225      */
226     @Action( ACTION_CONFIRM_REMOVE_IDENTITYSEARCHRULE )
227     public String getConfirmRemoveIdentitySearchRule( final HttpServletRequest request )
228     {
229         int nId = Integer.parseInt( request.getParameter( PARAMETER_ID_IDENTITYSEARCHRULE ) );
230         UrlItem url = new UrlItem( getActionUrl( ACTION_REMOVE_IDENTITYSEARCHRULE ) );
231         url.addParameter( PARAMETER_ID_IDENTITYSEARCHRULE, nId );
232 
233         String strMessageUrl = AdminMessageService.getMessageUrl( request, MESSAGE_CONFIRM_REMOVE_IDENTITYSEARCHRULE, url.getUrl( ),
234                 AdminMessage.TYPE_CONFIRMATION );
235 
236         return redirect( request, strMessageUrl );
237     }
238 
239     /**
240      * Handles the removal form of an identity search rule
241      *
242      * @param request
243      *            The Http request
244      * @return the jsp URL to display the form to manage identity search rules
245      */
246     @Action( ACTION_REMOVE_IDENTITYSEARCHRULE )
247     public String doRemoveIdentitySearchRule( final HttpServletRequest request )
248     {
249         int nId = Integer.parseInt( request.getParameter( PARAMETER_ID_IDENTITYSEARCHRULE ) );
250         IdentitySearchRuleHome.delete( nId );
251         addInfo( INFO_IDENTITYSEARCHRULE_REMOVED, getLocale( ) );
252         _listIdentitySearchRules.clear( );
253 
254         return redirectView( request, VIEW_MANAGE_IDENTITYSEARCHRULES );
255     }
256 
257     /**
258      * Returns the form to update info about an identity search rule
259      *
260      * @param request
261      *            The Http request
262      * @return The HTML form to update info
263      */
264     @View( VIEW_MODIFY_IDENTITYSEARCHRULE )
265     public String getModifyIdentitySearchRule( final HttpServletRequest request )
266     {
267         int nId = Integer.parseInt( request.getParameter( PARAMETER_ID_IDENTITYSEARCHRULE ) );
268 
269         if ( _identitySearchRule == null || ( _identitySearchRule.getId( ) != nId ) )
270         {
271             _identitySearchRule = IdentitySearchRuleHome.find( nId );
272             if ( _identitySearchRule == null )
273             {
274                 throw new AppException( ERROR_RESOURCE_NOT_FOUND );
275             }
276         }
277 
278         final Map<String, Object> model = getModel( );
279 
280         model.put( MARK_IDENTITYSEARCHRULE, _identitySearchRule );
281         model.put( MARK_SELECTED_ATTRIBUTES, _identitySearchRule.getAttributes( ).stream( ).map( AttributeKey::getKeyName ).collect( Collectors.toList( ) ) );
282         model.put( MARK_AVAILABLE_RULE_TYPES, SearchRuleType.values( ) );
283         model.put( MARK_ACTION, "action_modifyIdentitySearchRule" );
284         model.put( MARK_AVAILABLE_ATTRIBUTES, AttributeKeyHome.getAttributeKeysList( false ) );
285         model.put( SecurityTokenService.MARK_TOKEN, SecurityTokenService.getInstance( ).getToken( request, ACTION_MODIFY_IDENTITYSEARCHRULE ) );
286 
287         return getPage( PROPERTY_PAGE_TITLE_MODIFY_IDENTITYSEARCHRULE, TEMPLATE_MODIFY_IDENTITYSEARCHRULE, model );
288     }
289 
290     /**
291      * Process the change form of an identity search rule
292      *
293      * @param request
294      *            The Http request
295      * @return The Jsp URL of the process result
296      * @throws AccessDeniedException
297      */
298     @Action( ACTION_MODIFY_IDENTITYSEARCHRULE )
299     public String doModifyIdentitySearchRule( final HttpServletRequest request ) throws AccessDeniedException
300     {
301         _identitySearchRule.setType( SearchRuleType.valueOf( request.getParameter( PARAMETER_SELECTED_TYPE ) ) );
302         _identitySearchRule.getAttributes( ).clear( );
303         _identitySearchRule.getAttributes( ).addAll( this.extractAttributeKeys( request ) );
304 
305         if ( !SecurityTokenService.getInstance( ).validate( request, ACTION_MODIFY_IDENTITYSEARCHRULE ) )
306         {
307             throw new AccessDeniedException( "Invalid security token" );
308         }
309 
310         // Check constraints
311         if ( _identitySearchRule.getType( ) == null || _identitySearchRule.getAttributes( ).isEmpty( ) )
312         {
313             return redirect( request, VIEW_MODIFY_IDENTITYSEARCHRULE, PARAMETER_ID_IDENTITYSEARCHRULE, _identitySearchRule.getId( ) );
314         }
315 
316         try
317         {
318             IdentitySearchRuleHome.update( _identitySearchRule );
319         }
320         catch( final Exception e )
321         {
322             addError( e.getMessage( ) );
323             return redirect( request, VIEW_MODIFY_IDENTITYSEARCHRULE, PARAMETER_ID_IDENTITYSEARCHRULE, _identitySearchRule.getId( ) );
324         }
325 
326         addInfo( INFO_IDENTITYSEARCHRULE_UPDATED, getLocale( ) );
327         _listIdentitySearchRules.clear( );
328         _identitySearchRule = null;
329 
330         return redirectView( request, VIEW_MANAGE_IDENTITYSEARCHRULES );
331     }
332 
333 }