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.identitypicker.service;
35  
36  import fr.paris.lutece.api.user.User;
37  import fr.paris.lutece.plugins.identitypicker.business.IdentitySearchCriteria;
38  import fr.paris.lutece.plugins.identitypicker.business.Referential;
39  import fr.paris.lutece.plugins.identitypicker.business.Rules;
40  import fr.paris.lutece.plugins.identitystore.v3.web.rs.dto.common.AttributeTreatmentType;
41  import fr.paris.lutece.plugins.identitystore.v3.web.rs.dto.common.AuthorType;
42  import fr.paris.lutece.plugins.identitystore.v3.web.rs.dto.common.IdentityDto;
43  import fr.paris.lutece.plugins.identitystore.v3.web.rs.dto.common.RequestAuthor;
44  import fr.paris.lutece.plugins.identitystore.v3.web.rs.dto.common.ResponseDto;
45  import fr.paris.lutece.plugins.identitystore.v3.web.rs.dto.common.ResponseStatusType;
46  import fr.paris.lutece.plugins.identitystore.v3.web.rs.dto.contract.ServiceContractDto;
47  import fr.paris.lutece.plugins.identitystore.v3.web.rs.dto.referentiel.AttributeSearchResponse;
48  import fr.paris.lutece.plugins.identitystore.v3.web.rs.dto.referentiel.LevelSearchResponse;
49  import fr.paris.lutece.plugins.identitystore.v3.web.rs.dto.referentiel.ProcessusSearchResponse;
50  import fr.paris.lutece.plugins.identitystore.v3.web.rs.dto.search.IdentitySearchRequest;
51  import fr.paris.lutece.plugins.identitystore.v3.web.rs.dto.search.IdentitySearchResponse;
52  import fr.paris.lutece.plugins.identitystore.v3.web.rs.dto.search.SearchAttribute;
53  import fr.paris.lutece.plugins.identitystore.v3.web.rs.dto.search.SearchDto;
54  import fr.paris.lutece.plugins.identitystore.v3.web.rs.util.Constants;
55  import fr.paris.lutece.plugins.identitystore.v3.web.service.IdentityService;
56  import fr.paris.lutece.plugins.identitystore.v3.web.service.ReferentialService;
57  import fr.paris.lutece.plugins.identitystore.v3.web.service.ServiceContractServiceExtended;
58  import fr.paris.lutece.plugins.identitystore.web.exception.IdentityStoreException;
59  import fr.paris.lutece.portal.service.spring.SpringContextService;
60  import fr.paris.lutece.portal.service.util.AppLogService;
61  import fr.paris.lutece.portal.service.util.AppPropertiesService;
62  
63  import java.util.ArrayList;
64  import java.util.List;
65  
66  public class IdentityPickerService
67  {
68  
69      private static final String PROPERTY_DEFAULT_CLIENT_CODE = "identitypicker.default.client.code";
70      private static final String BEAN_IDENTITY_SERVICE = "identityService.rest.httpAccess";
71      private static final String BEAN_REFERENTIAL_SERVICE = "identity.ReferentialService";
72      private static final String BEAN_CONTRACT_SERVICE = "identity.serviceContractService";
73      private static final String ERROR_SEARCHING_IDENTITIES = "Error while searching identities: ";
74  
75      private static IdentityPickerService instance;
76      private final IdentityService identityService = SpringContextService.getBean( BEAN_IDENTITY_SERVICE );
77      private final String clientCode = AppPropertiesService.getProperty( PROPERTY_DEFAULT_CLIENT_CODE );
78  
79      private ReferentialService _referentialService;
80      private ServiceContractServiceExtended _serviceContract;
81  
82      /**
83       * Private constructor
84       */
85      private IdentityPickerService( )
86      {
87          _referentialService = SpringContextService.getBean( BEAN_REFERENTIAL_SERVICE );
88          _serviceContract = SpringContextService.getBean( BEAN_CONTRACT_SERVICE );
89      }
90  
91      /**
92       * Gets the singleton instance of the service.
93       * 
94       * @return The singleton instance of the service
95       */
96      public static IdentityPickerService getInstance( )
97      {
98          if ( instance == null )
99          {
100             instance = new IdentityPickerService( );
101 
102         }
103         return instance;
104     }
105 
106     /**
107      * Searches for identities based on the provided criteria.
108      * 
109      * @param criteria
110      *            The criteria to search for
111      * @return A list of identities matching the criteria
112      * @throws IdentityStoreException
113      *             If an error occurs while searching for identities
114      */
115     public List<IdentityDto> searchIdentities( IdentitySearchCriteria criteria, User luteceUser ) throws IdentityStoreException
116     {
117         IdentitySearchRequest searchRequest = createSearchRequest( criteria );
118         return doSearch( searchRequest, createRequestAuthor( luteceUser ) );
119     }
120 
121     /**
122      * Gets the identity with the provided customer ID.
123      * 
124      * @param customerId
125      *            The customer ID
126      * @param luteceUser
127      *            The user making the request
128      * @return The identity with the provided customer ID
129      * @throws IdentityStoreException
130      *             If an error occurs while fetching the identity
131      */
132     public IdentityDto getIdentity( String customerId, User luteceUser ) throws IdentityStoreException
133     {
134         try
135         {
136             IdentitySearchResponse response = identityService.getIdentity( customerId, clientCode, createRequestAuthor( luteceUser ) );
137             if ( isSuccess( response ) )
138             {
139                 return (IdentityDto) response.getIdentities( ).get( 0 );
140             }
141             else
142             {
143                 AppLogService.error( "Error while fetching identity: " + response.getStatus( ).getMessage( ) );
144                 return null;
145             }
146         }
147         catch( IdentityStoreException e )
148         {
149             AppLogService.error( "Error while fetching identity", e );
150             throw e;
151         }
152     }
153 
154     /**
155      * Gets the rules.
156      * 
157      * @param luteceUser
158      *            The user making the request
159      * @return The rules for the provided user
160      * @throws IdentityStoreException
161      *             If an error occurs while fetching the rules
162      */
163     public Rules getRules( User luteceUser ) throws IdentityStoreException
164     {
165         try
166         {
167             RequestAuthor author = createRequestAuthor( luteceUser );
168             ProcessusSearchResponse processList = _referentialService.getProcessList( clientCode, author );
169             LevelSearchResponse levelList = _referentialService.getLevelList( clientCode, author );
170             AttributeSearchResponse attributeKeyList = _referentialService.getAttributeKeyList( clientCode, author );
171             Referentialpicker/business/Referential.html#Referential">Referential referential = new Referential( processList, levelList, attributeKeyList );
172             ServiceContractDto contract = _serviceContract.getActiveServiceContract( clientCode, clientCode, createRequestAuthor( luteceUser ) )
173                     .getServiceContract( );
174 
175             return new Rules( referential, contract );
176         }
177         catch( IdentityStoreException e )
178         {
179             AppLogService.error( "Error while fetching referential data", e );
180             throw e;
181         }
182     }
183 
184     /**
185      * Searches for identities based on the provided criteria.
186      * 
187      * @param criteria
188      *            The criteria to search for
189      * @param author
190      *            The author of the request
191      * @return A list of identities matching the criteria
192      * @throws IdentityStoreException
193      *             If an error occurs while searching for identities
194      */
195     private IdentitySearchRequest createSearchRequest( IdentitySearchCriteria criteria )
196     {
197         IdentitySearchRequest searchRequest = new IdentitySearchRequest( );
198         SearchDto search = new SearchDto( );
199         List<SearchAttribute> attributes = new ArrayList<>( );
200 
201         if ( criteria.hasCommonEmail( ) )
202         {
203             attributes.add( new SearchAttribute( Constants.PARAM_COMMON_EMAIL, criteria.getCommonEmail( ), AttributeTreatmentType.STRICT ) );
204         }
205         else
206         {
207             attributes.add( new SearchAttribute( Constants.PARAM_FIRST_NAME, criteria.getFirstName( ), AttributeTreatmentType.APPROXIMATED ) );
208             attributes.add( new SearchAttribute( Constants.PARAM_COMMON_LASTNAME, criteria.getCommonLastName( ), AttributeTreatmentType.APPROXIMATED ) );
209             attributes.add( new SearchAttribute( Constants.PARAM_BIRTH_DATE, criteria.getBirthDate( ), AttributeTreatmentType.STRICT ) );
210         }
211 
212         search.setAttributes( attributes );
213         searchRequest.setSearch( search );
214         return searchRequest;
215     }
216 
217     /**
218      * Performs the search for identities based on the provided search request.
219      * 
220      * @param searchRequest
221      *            The search request
222      * @param author
223      *            The author of the request
224      * @return A list of identities matching the search request
225      * @throws IdentityStoreException
226      *             If an error occurs while searching for identities
227      */
228     private List<IdentityDto> doSearch( IdentitySearchRequest searchRequest, RequestAuthor author ) throws IdentityStoreException
229     {
230         try
231         {
232             IdentitySearchResponse searchResponse = identityService.searchIdentities( searchRequest, clientCode, author );
233             if ( isSuccess( searchResponse ) )
234             {
235                 return searchResponse.getIdentities( );
236             }
237             else
238             {
239                 AppLogService.error( ERROR_SEARCHING_IDENTITIES + searchResponse.getStatus( ).getMessage( ) );
240                 return new ArrayList<>( );
241             }
242         }
243         catch( IdentityStoreException e )
244         {
245             AppLogService.error( ERROR_SEARCHING_IDENTITIES, e );
246             throw e;
247         }
248     }
249 
250     /**
251      * Creates the author of the request.
252      * 
253      * @return The author of the request
254      */
255     private RequestAuthor createRequestAuthor( User luteceUser )
256     {
257         RequestAuthor author = new RequestAuthor( );
258         author.setName( luteceUser.getEmail( ) );
259         author.setType( AuthorType.application );
260         return author;
261     }
262 
263     /**
264      * Checks if the search response is successful.
265      * 
266      * @param searchResponse
267      *            The search response
268      * @return true if the search response is successful, false otherwise
269      */
270     private boolean isSuccess( final ResponseDto apiResponse )
271     {
272         return apiResponse != null && ( apiResponse.getStatus( ).getType( ) == ResponseStatusType.SUCCESS
273                 || apiResponse.getStatus( ).getType( ) == ResponseStatusType.INCOMPLETE_SUCCESS
274                 || apiResponse.getStatus( ).getType( ) == ResponseStatusType.OK );
275     }
276 }