View Javadoc
1   /*
2    * Copyright (c) 2002-2023, 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.broadcastproxy.web;
35  
36  import java.io.BufferedReader;
37  import java.io.IOException;
38  import java.util.ArrayList;
39  import java.util.List;
40  
41  import javax.servlet.http.HttpServletRequest;
42  
43  import org.apache.commons.collections.CollectionUtils;
44  import org.apache.commons.lang3.StringUtils;
45  import org.json.simple.JSONObject;
46  
47  import com.fasterxml.jackson.databind.JsonNode;
48  import com.fasterxml.jackson.databind.ObjectMapper;
49  
50  import fr.paris.lutece.plugins.broadcastproxy.service.BroadcastCacheService;
51  import fr.paris.lutece.plugins.broadcastproxy.service.BroadcastService;
52  import fr.paris.lutece.portal.service.i18n.I18nService;
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.util.AppLogService;
56  import fr.paris.lutece.portal.service.util.AppPropertiesService;
57  import fr.paris.lutece.portal.util.mvc.commons.annotations.Action;
58  import fr.paris.lutece.portal.util.mvc.xpage.MVCApplication;
59  import fr.paris.lutece.portal.util.mvc.xpage.annotations.Controller;
60  import fr.paris.lutece.portal.web.l10n.LocaleService;
61  import fr.paris.lutece.portal.web.xpages.XPage;
62  import fr.paris.lutece.util.json.ErrorJsonResponse;
63  import fr.paris.lutece.util.json.JsonResponse;
64  import fr.paris.lutece.util.json.JsonUtil;
65  
66  /**
67   * MyLuteceParisConnectXPage
68   *
69   */
70  @Controller( xpageName = BroadcastproxyXPage.PAGE_BROADCAST_MYDASHBOARD, pageTitleI18nKey = "broadcastproxy.xpage.pageTitle", pagePathI18nKey = "broadcastproxy.xpage.pagePathLabel" )
71  public class BroadcastproxyXPage extends MVCApplication
72  {
73      /**
74       * Name of this application
75       */
76      public static final String PAGE_BROADCAST_MYDASHBOARD = "broadcastproxyMyDashboard";
77      private static final long serialVersionUID = -4316691400124512414L;
78  
79      private static final String KEY_USER_INFO_MAIL = "broadcastproxy.userInfoKeys.mail";
80  
81      private static final String ACTION_UPDATE_USER_SUBSCRIPTIONS = "updateUserSubscriptions";
82      private static final String ACTION_GET_USER_SUBSCRIPTIONS = "getUserSubscriptions";
83  
84      private static final String PROPERTY_MSG_ERROR_GET_USER_SUBSCRIPTIONS = "broadcastproxy.msg.ERROR_GET_USER_SUBSCRIPTIONS";
85      private static final String PROPERTY_ACCOUNT_ID = AppPropertiesService.getProperty( "dolist.CONSTANTE_ACCOUNT_ID" );
86      private static final String PROPERTY_ACCOUNT_ADDROND_PREFIX = "dolist.CONSTANTE_ACCOUNT_ID_";
87      
88      private static final String JSON_NODE_ACCOUNT = "account";
89      
90      /**
91       * Check if the current (front) user is authenticated
92       * 
93       * @param request
94       *            The request
95       * @return true if authenticated
96       */
97      private String getMailUserAuthenticated( HttpServletRequest request )
98      {
99          LuteceUser user = null;
100 
101         if ( SecurityService.isAuthenticationEnable( ) )
102         {
103             user = SecurityService.getInstance( ).getRegisteredUser( request );
104             if ( user != null )
105             {
106                 String userMail = user.getEmail( );
107                 if ( StringUtils.isBlank( userMail ) )
108                 {
109                     String mailUserInfoKey = AppPropertiesService.getProperty( KEY_USER_INFO_MAIL );
110                     if ( !StringUtils.isBlank( mailUserInfoKey ) )
111                     {
112                         userMail = user.getUserInfo( mailUserInfoKey );
113                     }
114                 }
115                 return userMail;
116             }
117             else
118             {
119                 return null;
120             }
121         }
122         else
123         {
124             return null;
125         }
126     }
127 
128     /**
129      * Do get user subscriptions using the AJAX mode
130      * 
131      * @param request
132      *            The request
133      * @return
134      */
135     @SuppressWarnings( "unchecked" )
136     @Action( ACTION_GET_USER_SUBSCRIPTIONS )
137     public XPage doGetUserSubscriptions( HttpServletRequest request )
138     {
139         String mailUser = getMailUserAuthenticated( request );
140         String strUserSubscriptionIds = BroadcastCacheService.getInstance( ).getUserSubscriptionIds( mailUser )  ;
141         if ( StringUtils.isBlank( mailUser ) )
142         {
143             return responseJSON( JsonUtil.buildJsonResponse( new ErrorJsonResponse( "User not authentified." ) ) );
144         }
145 
146         try
147         {        
148             if( StringUtils.isEmpty( strUserSubscriptionIds ) )
149             {                     
150                 //Retrieve user subscriptions
151                 List<JSONObject> listUserSubscriptionIds = new ArrayList<>( );
152                 JSONObject newsletters = new JSONObject( );
153                 newsletters.put( "newsletters", BroadcastService.getInstance( ).getUserSubscriptionIds( mailUser, PROPERTY_ACCOUNT_ID ) );
154                 
155                 listUserSubscriptionIds.add( newsletters );
156                 
157                 loadUserArrondissementSubscription( mailUser, listUserSubscriptionIds );
158                 
159                 strUserSubscriptionIds = listUserSubscriptionIds.toString( );
160                 
161                 if ( StringUtils.isEmpty( strUserSubscriptionIds ) )
162                 {
163                 	String returnedMsg = "Vos newsletters sont momentanément indisponibles.";
164                 	return responseJSON( JsonUtil.buildJsonResponse( new ErrorJsonResponse( returnedMsg ) ) );
165                 }
166                 
167                 //Add to cache
168                 BroadcastCacheService.getInstance( ).addUserSubscription( mailUser, strUserSubscriptionIds );
169             }
170         }
171         catch( Exception e )
172         {
173             addInfo( I18nService.getLocalizedString( PROPERTY_MSG_ERROR_GET_USER_SUBSCRIPTIONS, LocaleService.getDefault( ) ) );
174             AppLogService.error( e.getMessage( ) );
175             return responseJSON( JsonUtil.buildJsonResponse( new ErrorJsonResponse( e.getMessage( ) ) ) );
176         }
177 
178         XPage xpage = responseJSON( JsonUtil.buildJsonResponse( new JsonResponse( strUserSubscriptionIds ) ) );
179 
180         return xpage;
181     }
182 
183     @SuppressWarnings( "unchecked" )
184     private void loadUserArrondissementSubscription( String mailUser, List<JSONObject> listUserSubscriptionIds )
185     {
186         // Retrieve user subscriptions by arrondissement
187         List<String> listAccountIds = AppPropertiesService.getKeys( PROPERTY_ACCOUNT_ADDROND_PREFIX );
188         List<JSONObject> jsonArrondissementList = new ArrayList<>( );
189         for ( String strAccountKey : listAccountIds )
190         {
191             String strAccountId = AppPropertiesService.getProperty( strAccountKey );
192             if ( StringUtils.isNotEmpty( strAccountId ) )
193             {
194                 List<JSONObject> listUserSubscriptionArrond = BroadcastService.getInstance( ).getUserSubscriptionIds( mailUser, strAccountId );
195 
196                 JSONObject jsonArrondissement = new JSONObject( );
197                 jsonArrondissement.put( "name", strAccountKey.replace( PROPERTY_ACCOUNT_ADDROND_PREFIX, StringUtils.EMPTY ) );
198                 jsonArrondissement.put( "subscription", CollectionUtils.isNotEmpty( listUserSubscriptionArrond ) );
199 
200                 jsonArrondissementList.add( jsonArrondissement );
201             }
202         }
203         JSONObject arrondissements = new JSONObject( );
204         arrondissements.put( "arrondissements", jsonArrondissementList );
205         listUserSubscriptionIds.add( arrondissements );
206     }
207 
208     /**
209      * Do update user subscriptions using the AJAX mode
210      * 
211      * json data should be like : { "userSubscriptions": {"typeName": "ALERT", "groupName": "Alertes", "subscriptionsList": [ {"id": "", "active": true} ] } }
212      * 
213      * IF there is not "groupName" (exemple for newsletter), do ["groupName": "NONE"]
214      * 
215      * @param request
216      *            The request
217      * @return
218      */
219     @Action( ACTION_UPDATE_USER_SUBSCRIPTIONS )
220     public XPage doUpdateUserSubscriptions( HttpServletRequest request )
221     {
222 
223         String mailUser = getMailUserAuthenticated( request );
224         
225         if ( StringUtils.isBlank( mailUser ) )
226             return responseJSON( JsonUtil.buildJsonResponse( new ErrorJsonResponse( "User not authentified." ) ) );
227 
228         String strJson;
229         try
230         {
231             StringBuilder sb = new StringBuilder( );
232             String line = null;
233             
234             BufferedReader reader = request.getReader( );
235             while ( ( line = reader.readLine( ) ) != null )
236                 sb.append( line );
237 
238             strJson = sb.toString( );
239             
240         }
241         catch( IOException e )
242         {
243             return responseJSON( JsonUtil.buildJsonResponse( new ErrorJsonResponse( "An error occured while receiving the response" ) ) );
244         }
245 
246         if ( updateSubscriptions( strJson, mailUser ) )
247         {
248             responseJSON( JsonUtil.buildJsonResponse( new ErrorJsonResponse( "An error occured while receiving the response" ) ) );
249         }
250         
251         //Remove cache after update subscription
252         BroadcastCacheService.getInstance( ).removeUserSubscription( mailUser );
253         
254         return responseJSON( JsonUtil.buildJsonResponse( new JsonResponse( "ok" ) ) );
255     }
256 
257     /**
258      * update Subscriptions
259      * 
260      * @param jsonResponse
261      * @param userId
262      * @return true if successful
263      */
264     private boolean updateSubscriptions( String jsonResponse, String userId )
265     {
266         try
267         {
268             JsonNode jsonNodes = new ObjectMapper( ).readTree( jsonResponse );
269             String strAccount = jsonNodes.get( JSON_NODE_ACCOUNT ).asText( );
270             
271             if ( StringUtils.isNotEmpty( strAccount ) && !strAccount.equals( "default" )  )
272             {
273                 String strAccountId = AppPropertiesService.getProperty( PROPERTY_ACCOUNT_ADDROND_PREFIX + strAccount  ) ;               
274                 BroadcastService.getInstance( ).updateArrondissementSubscribtions( userId, jsonResponse, strAccountId );
275             }
276             else
277             {
278                 // update subscriptions by feed type
279                 BroadcastService.getInstance( ).updateSubscribtions( userId, jsonResponse, PROPERTY_ACCOUNT_ID );               
280             }
281         }
282         catch( Exception e )
283         {
284             AppLogService.error( "An error occured while updating subscriptions : " + e.getMessage( ) );
285             return false;
286         }
287 
288         return true;
289     }
290 
291 }