View Javadoc
1   /*
2    * Copyright (c) 2002-2022, 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.portal.web.style;
35  
36  import java.io.File;
37  import java.io.FileOutputStream;
38  import java.io.IOException;
39  import java.util.HashMap;
40  import java.util.Map;
41  
42  import javax.servlet.http.HttpServletRequest;
43  
44  import org.apache.commons.fileupload.FileItem;
45  import org.apache.commons.lang3.StringUtils;
46  
47  import fr.paris.lutece.portal.business.style.PageTemplate;
48  import fr.paris.lutece.portal.business.style.PageTemplateHome;
49  import fr.paris.lutece.portal.service.admin.AccessDeniedException;
50  import fr.paris.lutece.portal.service.fileupload.FileUploadService;
51  import fr.paris.lutece.portal.service.message.AdminMessage;
52  import fr.paris.lutece.portal.service.message.AdminMessageService;
53  import fr.paris.lutece.portal.service.security.SecurityTokenService;
54  import fr.paris.lutece.portal.service.template.AppTemplateService;
55  import fr.paris.lutece.portal.service.util.AppLogService;
56  import fr.paris.lutece.portal.service.util.AppPathService;
57  import fr.paris.lutece.portal.service.util.AppPropertiesService;
58  import fr.paris.lutece.portal.web.admin.AdminFeaturesPageJspBean;
59  import fr.paris.lutece.portal.web.constants.Messages;
60  import fr.paris.lutece.portal.web.constants.Parameters;
61  import fr.paris.lutece.portal.web.upload.MultipartHttpServletRequest;
62  import fr.paris.lutece.util.file.FileUtil;
63  import fr.paris.lutece.util.html.HtmlTemplate;
64  
65  /**
66   * This class provides the user interface to manage page templates features ( manage, create, modify, remove)
67   */
68  public class PageTemplatesJspBean extends AdminFeaturesPageJspBean
69  {
70      // Right
71      /**
72       * Right to manage page templates
73       */
74      public static final String RIGHT_MANAGE_PAGE_TEMPLATES = "CORE_PAGE_TEMPLATE_MANAGEMENT";
75  
76      /**
77       * Serial version UID
78       */
79      private static final long serialVersionUID = -142214702397662732L;
80  
81      // Properties for page titles
82      private static final String PROPERTY_PAGE_TITLE_PAGE_TEMPLATE_LIST = "portal.style.manage_page_templates.pageTitle";
83      private static final String PROPERTY_PAGE_TITLE_CREATE_PAGE_TEMPLATE = "portal.style.create_page_template.pageTitle";
84      private static final String PROPERTY_PAGE_TITLE_MODIFY_PAGE_TEMPLATE = "portal.style.modify_page_template.pageTitle";
85  
86      // Markers
87      private static final String MARK_PAGE_TEMPLATES_LIST = "page_templates_list";
88      private static final String MARK_PAGE_TEMPLATE = "page_template";
89  
90      // Templates files path
91      private static final String TEMPLATE_PAGE_TEMPLATES = "admin/style/manage_page_templates.html";
92      private static final String TEMPLATE_CREATE_PAGE_TEMPLATE = "admin/style/create_page_template.html";
93      private static final String TEMPLATE_MODIFY_PAGE_TEMPLATE = "admin/style/modify_page_template.html";
94  
95      // Properties
96      private static final String PROPERTY_PATH_TEMPLATE = "path.templates";
97      private static final String PROPERTY_PATH_FILE_PAGE_TEMPLATE = "path.file.page.template";
98      private static final String PROPERTY_PATH_IMAGE_PAGE_TEMPLATE = "path.image.page.template";
99  
100     // Messages
101     private static final String MESSAGE_CONFIRM_DELETE_PAGE_TEMPLATE = "portal.style.message.pageTemplateConfirmDelete";
102     private static final String MESSAGE_PAGE_TEMPLATE_IS_USED = "portal.style.message.pageTemplateIsUsed";
103     private static final String MESSAGE_WRONG_IMAGE_EXTENSION = "portal.util.message.wrongImageExtention";
104     private static final String MESSAGE_WRONG_HTML_EXTENSION = "portal.util.message.wrongHtmlExtention";
105 
106     // Parameters
107     private static final String PARAMETER_PAGE_TEMPLATE_FILE = "page_template_file";
108     private static final String PARAMETER_PAGE_TEMPLATE_PICTURE = "page_template_picture";
109     private static final String PARAMETER_PAGE_TEMPLATE_UPDATE_IMAGE = "update_image";
110     private static final String PARAMETER_PAGE_TEMPLATE_UPDATE_FILE = "update_file";
111     private static final String PATH_IMAGE_PAGE_TEMPLATE = AppPathService.getPath( PROPERTY_PATH_IMAGE_PAGE_TEMPLATE ) + File.separator;
112     private static final String PATH_TEMPLATE = AppPathService.getPath( PROPERTY_PATH_TEMPLATE ) + File.separator
113             + AppPropertiesService.getProperty( PROPERTY_PATH_FILE_PAGE_TEMPLATE );
114 
115     // JSP
116     private static final String JSP_DO_REMOVE_PAGE_TEMPLATE = "jsp/admin/style/DoRemovePageTemplate.jsp";
117 
118     /**
119      * Returns the list of page templates
120      *
121      * @param request
122      *            The Http request
123      * @return the html code for display the page templates list
124      */
125     public String getManagePageTemplate( HttpServletRequest request )
126     {
127         setPageTitleProperty( PROPERTY_PAGE_TITLE_PAGE_TEMPLATE_LIST );
128 
129         HashMap<String, Object> model = new HashMap<>( );
130         model.put( MARK_PAGE_TEMPLATES_LIST, PageTemplateHome.getPageTemplatesList( ) );
131 
132         HtmlTemplate template = AppTemplateService.getTemplate( TEMPLATE_PAGE_TEMPLATES, getLocale( ), model );
133 
134         return getAdminPage( template.getHtml( ) );
135     }
136 
137     /**
138      * Returns the page template form of creation
139      *
140      * @param request
141      *            The Http request
142      * @return the html code of the page template
143      */
144     public String getCreatePageTemplate( HttpServletRequest request )
145     {
146         setPageTitleProperty( PROPERTY_PAGE_TITLE_CREATE_PAGE_TEMPLATE );
147 
148         HashMap<String, Object> model = new HashMap<>( );
149         model.put( SecurityTokenService.MARK_TOKEN, SecurityTokenService.getInstance( ).getToken( request, TEMPLATE_CREATE_PAGE_TEMPLATE ) );
150 
151         HtmlTemplate template = AppTemplateService.getTemplate( TEMPLATE_CREATE_PAGE_TEMPLATE, getLocale( ), model );
152 
153         return getAdminPage( template.getHtml( ) );
154     }
155 
156     /**
157      * Processes the creation form of a new page template by recovering the parameters in the http request
158      *
159      * @param request
160      *            the http request
161      * @return The Jsp URL of the process result
162      * @throws AccessDeniedException
163      *             if the security token is invalid
164      */
165     public String doCreatePageTemplate( HttpServletRequest request ) throws AccessDeniedException
166     {
167         PageTemplateyle/PageTemplate.html#PageTemplate">PageTemplate pageTemplate = new PageTemplate( );
168 
169         MultipartHttpServletRequestce/portal/web/upload/MultipartHttpServletRequest.html#MultipartHttpServletRequest">MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
170 
171         String strDescription = multipartRequest.getParameter( Parameters.PAGE_TEMPLATE_DESCRIPTION );
172 
173         // Mandatory fields
174         if ( StringUtils.isEmpty( strDescription ) )
175         {
176             return AdminMessageService.getMessageUrl( request, Messages.MANDATORY_FIELDS, AdminMessage.TYPE_STOP );
177         }
178 
179         FileItem fileTemplate = multipartRequest.getFile( PARAMETER_PAGE_TEMPLATE_FILE );
180         FileItem filePicture = multipartRequest.getFile( PARAMETER_PAGE_TEMPLATE_PICTURE );
181 
182         String strFileName = FileUploadService.getFileNameOnly( fileTemplate );
183         String strPictureName = FileUploadService.getFileNameOnly( filePicture );
184 
185         if ( StringUtils.isEmpty( strFileName ) || StringUtils.isEmpty( strPictureName ) )
186         {
187             return AdminMessageService.getMessageUrl( request, Messages.MANDATORY_FILE, AdminMessage.TYPE_STOP );
188         }
189 
190         if ( !( FileUtil.hasHtmlExtension( strFileName ) || FileUtil.hasFreemarkerExtension( strFileName ) ) )
191         {
192             return AdminMessageService.getMessageUrl( request, MESSAGE_WRONG_HTML_EXTENSION, AdminMessage.TYPE_STOP );
193         }
194 
195         if ( !FileUtil.hasImageExtension( strPictureName ) )
196         {
197             return AdminMessageService.getMessageUrl( request, MESSAGE_WRONG_IMAGE_EXTENSION, AdminMessage.TYPE_STOP );
198         }
199 
200         if ( !SecurityTokenService.getInstance( ).validate( multipartRequest, TEMPLATE_CREATE_PAGE_TEMPLATE ) )
201         {
202             throw new AccessDeniedException( ERROR_INVALID_TOKEN );
203         }
204 
205         pageTemplate.setFile( AppPropertiesService.getProperty( PROPERTY_PATH_FILE_PAGE_TEMPLATE ) + strFileName );
206         writeTemplateFile( strFileName, PATH_TEMPLATE, fileTemplate );
207 
208         pageTemplate.setPicture( strPictureName );
209 
210         writeTemplateFile( strPictureName, PATH_IMAGE_PAGE_TEMPLATE, filePicture );
211 
212         pageTemplate.setDescription( strDescription );
213         PageTemplateHome.create( pageTemplate );
214 
215         // If the process is successful, redirects towards the theme view
216         return getHomeUrl( request );
217     }
218 
219     /**
220      * Returns the page template form of update
221      *
222      * @param request
223      *            The Http request
224      * @return the html code of the page template form
225      */
226     public String getModifyPageTemplate( HttpServletRequest request )
227     {
228         setPageTitleProperty( PROPERTY_PAGE_TITLE_MODIFY_PAGE_TEMPLATE );
229 
230         String strId = request.getParameter( Parameters.PAGE_TEMPLATE_ID );
231 
232         HashMap<String, Object> model = new HashMap<>( );
233         model.put( MARK_PAGE_TEMPLATE, PageTemplateHome.findByPrimaryKey( Integer.parseInt( strId ) ) );
234         model.put( SecurityTokenService.MARK_TOKEN, SecurityTokenService.getInstance( ).getToken( request, TEMPLATE_MODIFY_PAGE_TEMPLATE ) );
235 
236         HtmlTemplate template = AppTemplateService.getTemplate( TEMPLATE_MODIFY_PAGE_TEMPLATE, getLocale( ), model );
237 
238         return getAdminPage( template.getHtml( ) );
239     }
240 
241     /**
242      * Processes the updating form of a page template whose new parameters are stored in the http request
243      *
244      * @param request
245      *            The http request
246      * @return The Jsp URL of the process result
247      * @throws AccessDeniedException
248      *             if the security token is invalid
249      */
250     public String doModifyPageTemplate( HttpServletRequest request ) throws AccessDeniedException
251     {
252         MultipartHttpServletRequestce/portal/web/upload/MultipartHttpServletRequest.html#MultipartHttpServletRequest">MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
253 
254         String strId = multipartRequest.getParameter( Parameters.PAGE_TEMPLATE_ID );
255         String strDescription = multipartRequest.getParameter( Parameters.PAGE_TEMPLATE_DESCRIPTION );
256         String strUpdatePicture = multipartRequest.getParameter( PARAMETER_PAGE_TEMPLATE_UPDATE_IMAGE );
257         String strUpdateFile = multipartRequest.getParameter( PARAMETER_PAGE_TEMPLATE_UPDATE_FILE );
258 
259         PageTemplate pageTemplate = PageTemplateHome.findByPrimaryKey( Integer.parseInt( strId ) );
260 
261         boolean bUpdateFile = false;
262         boolean bUpdatePicture = false;
263         FileItem fileTemplate = multipartRequest.getFile( PARAMETER_PAGE_TEMPLATE_FILE );
264         String strFileName = FileUploadService.getFileNameOnly( fileTemplate );
265         FileItem filePicture = multipartRequest.getFile( PARAMETER_PAGE_TEMPLATE_PICTURE );
266         String strPictureName = FileUploadService.getFileNameOnly( filePicture );
267 
268         boolean bHasError = false;
269 
270         if ( strUpdateFile != null )
271         {
272             if ( StringUtils.isEmpty( strFileName ) )
273             {
274                 bHasError = true;
275             }
276             else
277                 if ( !( FileUtil.hasHtmlExtension( strFileName ) || FileUtil.hasFreemarkerExtension( strFileName ) ) )
278                 {
279                     return AdminMessageService.getMessageUrl( request, MESSAGE_WRONG_HTML_EXTENSION, AdminMessage.TYPE_STOP );
280                 }
281 
282             bUpdateFile = true;
283         }
284 
285         if ( strUpdatePicture != null )
286         {
287             if ( StringUtils.isEmpty( strPictureName ) )
288             {
289                 bHasError = true;
290             }
291             else
292                 if ( !FileUtil.hasImageExtension( strPictureName ) )
293                 {
294                     return AdminMessageService.getMessageUrl( request, MESSAGE_WRONG_IMAGE_EXTENSION, AdminMessage.TYPE_STOP );
295                 }
296 
297             bUpdatePicture = true;
298         }
299 
300         if ( bHasError || StringUtils.isEmpty( strDescription ) )
301         {
302             return AdminMessageService.getMessageUrl( request, Messages.MANDATORY_FILE, AdminMessage.TYPE_STOP );
303         }
304 
305         if ( !SecurityTokenService.getInstance( ).validate( multipartRequest, TEMPLATE_MODIFY_PAGE_TEMPLATE ) )
306         {
307             throw new AccessDeniedException( ERROR_INVALID_TOKEN );
308         }
309 
310         if ( bUpdateFile )
311         {
312             FileUtil.deleteFile( new File( AppPathService.getPath( PROPERTY_PATH_TEMPLATE ), pageTemplate.getFile( ) ) );
313             pageTemplate.setFile( AppPropertiesService.getProperty( PROPERTY_PATH_FILE_PAGE_TEMPLATE ) + strFileName );
314 
315             writeTemplateFile( strFileName, PATH_TEMPLATE, fileTemplate );
316         }
317 
318         if ( bUpdatePicture )
319         {
320             FileUtil.deleteFile( new File( PATH_IMAGE_PAGE_TEMPLATE, pageTemplate.getPicture( ) ) );
321             pageTemplate.setPicture( strPictureName );
322 
323             writeTemplateFile( strPictureName, PATH_IMAGE_PAGE_TEMPLATE, filePicture );
324         }
325 
326         pageTemplate.setDescription( strDescription );
327         PageTemplateHome.update( pageTemplate );
328 
329         // If the process is successful, redirects towards the page template management
330         // page
331         return getHomeUrl( request );
332     }
333 
334     /**
335      * Returns the confirm of removing the page_template whose identifier is in the http request
336      * 
337      * @param request
338      *            The Http request
339      * @return the html code for the remove confirmation page
340      */
341     public String getConfirmRemovePageTemplate( HttpServletRequest request )
342     {
343         String strId = request.getParameter( Parameters.PAGE_TEMPLATE_ID );
344         int nId = Integer.parseInt( strId );
345 
346         boolean bIsUsed = PageTemplateHome.checkStylePageTemplateIsUsed( nId );
347 
348         if ( !bIsUsed )
349         {
350             return AdminMessageService.getMessageUrl( request, MESSAGE_PAGE_TEMPLATE_IS_USED, AdminMessage.TYPE_STOP );
351         }
352 
353         PageTemplate pageTemplate = PageTemplateHome.findByPrimaryKey( Integer.parseInt( strId ) );
354         String strPathPageTemplateFile = AppPathService.getPath( PROPERTY_PATH_TEMPLATE ) + File.separator + pageTemplate.getFile( );
355         String strPathPictureFile = PATH_IMAGE_PAGE_TEMPLATE + pageTemplate.getPicture( );
356         Object [ ] args = {
357                 strPathPageTemplateFile, strPathPictureFile
358         };
359 
360         Map<String, Object> parameters = new HashMap<>( );
361         parameters.put( Parameters.PAGE_TEMPLATE_ID, strId );
362         parameters.put( SecurityTokenService.PARAMETER_TOKEN, SecurityTokenService.getInstance( ).getToken( request, JSP_DO_REMOVE_PAGE_TEMPLATE ) );
363         return AdminMessageService.getMessageUrl( request, MESSAGE_CONFIRM_DELETE_PAGE_TEMPLATE, args, null, JSP_DO_REMOVE_PAGE_TEMPLATE, null,
364                 AdminMessage.TYPE_CONFIRMATION, parameters );
365     }
366 
367     /**
368      * Processes the deletion of a page template
369      * 
370      * @param request
371      *            the http request
372      * @return The Jsp URL of the process result
373      * @throws AccessDeniedException
374      *             if the security token is invalid
375      */
376     public String doRemovePageTemplate( HttpServletRequest request ) throws AccessDeniedException
377     {
378         if ( !SecurityTokenService.getInstance( ).validate( request, JSP_DO_REMOVE_PAGE_TEMPLATE ) )
379         {
380             throw new AccessDeniedException( ERROR_INVALID_TOKEN );
381         }
382 
383         String strId = request.getParameter( Parameters.PAGE_TEMPLATE_ID );
384         int nId = Integer.parseInt( strId );
385 
386         // Delete files associated
387         PageTemplate pageTemplate = PageTemplateHome.findByPrimaryKey( Integer.parseInt( strId ) );
388 
389         File filePageTemplateToDelete = new File( AppPathService.getPath( PROPERTY_PATH_TEMPLATE ), pageTemplate.getFile( ) );
390         FileUtil.deleteFile( filePageTemplateToDelete );
391 
392         File filePictureToDelete = new File( PATH_IMAGE_PAGE_TEMPLATE, pageTemplate.getPicture( ) );
393         FileUtil.deleteFile( filePictureToDelete );
394 
395         PageTemplateHome.remove( nId );
396 
397         return getHomeUrl( request );
398     }
399 
400     // ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
401     // private methods
402 
403     /**
404      * Write the templates files (html and image)
405      *
406      * @param strFileName
407      *            The name of the file
408      * @param strPath
409      *            The path of the file
410      * @param fileItem
411      *            The fileItem object which contains the new file
412      */
413     private void writeTemplateFile( String strFileName, String strPath, FileItem fileItem )
414     {
415         File file = new File( strPath + strFileName );
416         FileUtil.deleteFile( file );
417 
418         try ( FileOutputStream fosFile = new FileOutputStream( file ) )
419         {
420             fosFile.write( fileItem.get( ) );
421         }
422         catch( IOException e )
423         {
424             AppLogService.error( e.getMessage( ), e );
425         }
426     }
427 }