SystemJspBean.java

  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.system;

  35. import java.io.File;
  36. import java.io.FileInputStream;
  37. import java.io.FileNotFoundException;
  38. import java.io.IOException;
  39. import java.io.Serializable;
  40. import java.util.ArrayList;
  41. import java.util.Collection;
  42. import java.util.Collections;
  43. import java.util.Date;
  44. import java.util.HashMap;
  45. import java.util.List;
  46. import java.util.Map;

  47. import javax.servlet.ServletContext;
  48. import javax.servlet.http.HttpServletRequest;

  49. import fr.paris.lutece.portal.service.admin.AccessDeniedException;
  50. import fr.paris.lutece.portal.service.admin.AdminUserService;
  51. import fr.paris.lutece.portal.service.datastore.DatastoreService;
  52. import fr.paris.lutece.portal.service.datastore.LocalizedData;
  53. import fr.paris.lutece.portal.service.datastore.LocalizedDataGroup;
  54. import fr.paris.lutece.portal.service.i18n.I18nService;
  55. import fr.paris.lutece.portal.service.security.SecurityTokenService;
  56. import fr.paris.lutece.portal.service.site.properties.SitePropertiesService;
  57. import fr.paris.lutece.portal.service.template.AppTemplateService;
  58. import fr.paris.lutece.portal.service.util.AppPathService;
  59. import fr.paris.lutece.portal.service.util.AppPropertiesService;
  60. import fr.paris.lutece.portal.web.admin.AdminFeaturesPageJspBean;
  61. import fr.paris.lutece.util.html.HtmlTemplate;
  62. import fr.paris.lutece.util.http.SecurityUtil;

  63. /**
  64.  * This class provides the user interface to manage system features ( manage logs, view system files, ... ).
  65.  */
  66. public class SystemJspBean extends AdminFeaturesPageJspBean
  67. {
  68.     // Right
  69.     public static final String RIGHT_PROPERTIES_MANAGEMENT = "CORE_PROPERTIES_MANAGEMENT";
  70.     public static final String RIGHT_LOGS_VISUALISATION = "CORE_LOGS_VISUALISATION";

  71.     // Jsp definition
  72.     public static final String JSP_MANAGE_PROPERTIES = "ManageProperties.jsp";

  73.     /** serial id */
  74.     private static final long serialVersionUID = 3770485521087669430L;

  75.     // Markers
  76.     private static final String MARK_FILES_LIST = "files_list";
  77.     private static final String MARK_FILES_SYSTEM_DIRECTORY = "files_system_directory";
  78.     private static final String MARK_FILES_SYSTEM_NAME = "file_system_name";
  79.     private static final String MARK_FILE_SYSTEM_DATA = "file_system_data";
  80.     private static final String MARK_PROPERTIES_GROUPS_LIST = "groups_list";

  81.     // Template Files path
  82.     private static final String TEMPLATE_MANAGE_FILES_SYSTEM = "admin/system/manage_files_system.html";
  83.     private static final String TEMPLATE_VIEW_FILES_SYSTEM = "admin/system/view_files_system.html";
  84.     private static final String TEMPLATE_VIEW_FILE = "admin/system/view_file.html";

  85.     private static final String TEMPLATE_MODIFY_PROPERTIES = "admin/system/modify_properties.html";

  86.     // Parameters
  87.     private static final String PARAMETER_FILE = "file";
  88.     private static final String PARAMETER_DIRECTORY = "directory";
  89.     private static final String PARAMETER_DIR = "dir";

  90.     // Properties file definition
  91.     private static final String PROPERTY_FILES_SYSTEM_LIST = "system.list";
  92.     private static final String PROPERTY_TITLE_MANAGE_FILES_SYSTEM = "portal.system.manage_files_system.pageTitle";
  93.     private static final String PROPERTY_FILE_DESCRIPTION = "portal.system.manage_files_system.description.";
  94.     private static final String PROPERTY_FILE_NAME = "portal.system.manage_files_system.name.";
  95.     private static final String PROPERTY_TITLE_VIEW_FILES_SYSTEM = "portal.system.view_files_system.pageTitle";
  96.     private static final String PROPERTY_TITLE_VIEW_FILE = "portal.system.view_file.pageTitle";
  97.     private static final String MARK_WEBAPP_URL = "webapp_url";
  98.     private static final String MARK_LOCALE = "locale";

  99.     /**
  100.      * Returns ViewLogs page
  101.      *
  102.      * @param request
  103.      *            The HTTP request.
  104.      * @return The HTML code
  105.      */
  106.     public String getManageFilesSystem( HttpServletRequest request )
  107.     {
  108.         setPageTitleProperty( PROPERTY_TITLE_MANAGE_FILES_SYSTEM );
  109.         ArrayList<SystemFile> list = new ArrayList<>( );

  110.         for ( String strDirectory : getDirectories( ) )
  111.         {
  112.             SystemFile file = new SystemFile( );
  113.             file.setName( I18nService.getLocalizedString( PROPERTY_FILE_NAME + strDirectory, request.getLocale( ) ) );
  114.             file.setDescription( I18nService.getLocalizedString( PROPERTY_FILE_DESCRIPTION + strDirectory, request.getLocale( ) ) );
  115.             file.setDirectory( AppPropertiesService.getProperty( "system." + strDirectory + ".directory" ) );
  116.             list.add( file );
  117.         }

  118.         Map<String, Collection<SystemFile>> model = new HashMap<>( );
  119.         model.put( MARK_FILES_LIST, list );

  120.         HtmlTemplate template = AppTemplateService.getTemplate( TEMPLATE_MANAGE_FILES_SYSTEM, getLocale( ), model );

  121.         return getAdminPage( template.getHtml( ) );
  122.     }

  123.     /**
  124.      * Get directory list
  125.      *
  126.      * @param request
  127.      *            The request
  128.      * @return The html code
  129.      */
  130.     public String getManageFilesSystemDir( HttpServletRequest request )
  131.     {
  132.         setPageTitleProperty( PROPERTY_TITLE_VIEW_FILES_SYSTEM );
  133.         String strDir = request.getParameter( PARAMETER_DIR );

  134.         if ( !isValidDirectoryPath( strDir ) )
  135.         {
  136.             return getManageFilesSystem( request );
  137.         }

  138.         String strDirectory = AppPathService.getWebAppPath( ) + strDir;
  139.         File directory = new File( strDirectory );
  140.         ArrayList<SystemFile> listFiles = new ArrayList<>( );
  141.         for ( File file : directory.listFiles( ) )
  142.         {
  143.             SystemFile sFile = new SystemFile( );
  144.             sFile.setName( file.getName( ) );
  145.             sFile.setDirectory( strDir );
  146.             sFile.setSize( (int) ( file.length( ) / 1000 ) + 1 );
  147.             sFile.setDate( new Date( file.lastModified( ) ) );
  148.             listFiles.add( sFile );
  149.         }
  150.         Collections.sort( listFiles );

  151.         Map<String, Serializable> model = new HashMap<>( );
  152.         model.put( MARK_FILES_LIST, listFiles );
  153.         model.put( MARK_FILES_SYSTEM_DIRECTORY, strDir );

  154.         HtmlTemplate template = AppTemplateService.getTemplate( TEMPLATE_VIEW_FILES_SYSTEM, getLocale( ), model );

  155.         return getAdminPage( template.getHtml( ) );
  156.     }

  157.     // //////////////////////////////////////////////////////////////////////////
  158.     // Methods to display a system file
  159.     /**
  160.      * Returns a FileView page
  161.      *
  162.      * @param request
  163.      *            The HTTP request.
  164.      * @return The HTML code
  165.      */
  166.     public String getFileView( HttpServletRequest request )
  167.     {
  168.         Map<String, Object> model = new HashMap<>( );
  169.         setPageTitleProperty( PROPERTY_TITLE_VIEW_FILE );

  170.         String strFileData;
  171.         String strFile = request.getParameter( PARAMETER_FILE );
  172.         String strDirectory = request.getParameter( PARAMETER_DIRECTORY );

  173.         if ( strFile == null )
  174.         {
  175.             strFileData = "ERROR : No file selected !";
  176.         }
  177.         else
  178.             if ( !isValidDirectoryPath( strDirectory ) )
  179.             {
  180.                 strFileData = "ERROR : Invalid directory !";
  181.             }
  182.             else
  183.             {
  184.                 String strFilePath = AppPathService.getWebAppPath( );

  185.                 if ( strFilePath != null && !SecurityUtil.containsPathManipulationChars( request, strFile ) )
  186.                 {
  187.                     strFileData = getFileData( strFilePath + strDirectory + strFile );
  188.                 }
  189.                 else
  190.                 {
  191.                     strFileData = "ERROR : " + strFile + " not found !";
  192.                 }
  193.             }

  194.         model.put( MARK_FILES_SYSTEM_NAME, strDirectory + strFile );
  195.         model.put( MARK_FILE_SYSTEM_DATA, strFileData );
  196.         model.put( MARK_FILES_SYSTEM_DIRECTORY, strDirectory );

  197.         HtmlTemplate template = AppTemplateService.getTemplate( TEMPLATE_VIEW_FILE, getLocale( ), model );

  198.         return getAdminPage( template.getHtml( ) );
  199.     }

  200.     /**
  201.      * Returns the form to update info about the webmaster.properties
  202.      *
  203.      * @param request
  204.      *            The Http request
  205.      * @return The HTML form to update info
  206.      */
  207.     public String getManageProperties( HttpServletRequest request )
  208.     {
  209.         Map<String, Object> model = new HashMap<>( );
  210.         model.put( MARK_PROPERTIES_GROUPS_LIST, SitePropertiesService.getGroups( getLocale( ) ) );
  211.         model.put( MARK_WEBAPP_URL, AppPathService.getBaseUrl( request ) );
  212.         model.put( MARK_LOCALE, getLocale( ).getLanguage( ) );
  213.         model.put( SecurityTokenService.MARK_TOKEN, SecurityTokenService.getInstance( ).getToken( request, TEMPLATE_MODIFY_PROPERTIES ) );

  214.         HtmlTemplate templateList = AppTemplateService.getTemplate( TEMPLATE_MODIFY_PROPERTIES, getLocale( ), model );

  215.         return getAdminPage( templateList.getHtml( ) );
  216.     }

  217.     /**
  218.      * Process the change form of the webmaster.properties
  219.      *
  220.      * @param request
  221.      *            The Http request
  222.      * @param context
  223.      *            The context
  224.      * @return The Jsp URL of the process result
  225.      * @throws AccessDeniedException
  226.      *             if the security token is invalid
  227.      */
  228.     public static String doModifyProperties( HttpServletRequest request, ServletContext context ) throws AccessDeniedException
  229.     {
  230.         if ( !SecurityTokenService.getInstance( ).validate( request, TEMPLATE_MODIFY_PROPERTIES ) )
  231.         {
  232.             throw new AccessDeniedException( ERROR_INVALID_TOKEN );
  233.         }
  234.         List<LocalizedDataGroup> groups = SitePropertiesService.getGroups( AdminUserService.getAdminUser( request ).getLocale( ) );

  235.         for ( LocalizedDataGroup group : groups )
  236.         {
  237.             List<LocalizedData> datas = group.getLocalizedDataList( );

  238.             for ( LocalizedData data : datas )
  239.             {
  240.                 String strValue = request.getParameter( data.getKey( ) );

  241.                 if ( ( strValue != null ) && !data.getValue( ).equals( strValue ) )
  242.                 {
  243.                     DatastoreService.setDataValue( data.getKey( ), strValue );
  244.                 }
  245.             }
  246.         }

  247.         // if the operation occurred well, redirects towards the view of the Properties
  248.         return JSP_MANAGE_PROPERTIES;
  249.     }

  250.     // /////////////////////////////////////////////////////////////////////////////
  251.     // Private Implementation
  252.     /**
  253.      * Returns the content of a file.
  254.      *
  255.      * @param strFilePath
  256.      *            The file Path
  257.      * @return The content of the file.
  258.      */
  259.     private static String getFileData( String strFilePath )
  260.     {
  261.         StringBuilder sbData = new StringBuilder( );

  262.         try ( FileInputStream fis = new FileInputStream( strFilePath ) )
  263.         {
  264.             int chr = 0;

  265.             while ( chr != -1 )
  266.             {
  267.                 chr = fis.read( );
  268.                 sbData.append( (char) chr );
  269.             }

  270.             // we delete the end of file character
  271.             sbData.setLength( sbData.length( ) - 1 );
  272.         }
  273.         catch( FileNotFoundException e )
  274.         {
  275.             sbData.append( "ERROR : File " ).append( strFilePath ).append( " not found" );
  276.         }
  277.         catch( IOException e )
  278.         {
  279.             sbData.append( "ERROR : Error reading the file : " ).append( strFilePath );
  280.         }
  281.         return sbData.toString( );
  282.     }

  283.     /**
  284.      * Returns all authorized directories
  285.      *
  286.      * @return a directories array
  287.      */
  288.     private String [ ] getDirectories( )
  289.     {
  290.         String strDirectories = AppPropertiesService.getProperty( PROPERTY_FILES_SYSTEM_LIST );
  291.         return strDirectories.split( "," );
  292.     }

  293.     /**
  294.      * Checks if a given path is among the authorized list
  295.      *
  296.      * @param strPath
  297.      *            The path to check
  298.      * @return true if authorized
  299.      */
  300.     private boolean isValidDirectoryPath( String strPath )
  301.     {
  302.         for ( String strFileSystemName : getDirectories( ) )
  303.         {
  304.             String strDirectoryPath = AppPropertiesService.getProperty( "system." + strFileSystemName + ".directory" );

  305.             if ( strDirectoryPath.equals( strPath ) )
  306.             {
  307.                 return true;
  308.             }
  309.         }
  310.         return false;
  311.     }

  312. }