View Javadoc
1   /*
2    * Copyright (c) 2002-2019, Mairie de 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   
35  package fr.paris.lutece.plugins.managelogs.web;
36  
37  import fr.paris.lutece.plugins.managelogs.util.ManageLogsUtil;
38  import fr.paris.lutece.portal.service.util.AppLogService;
39  import fr.paris.lutece.portal.service.util.AppPathService;
40  import fr.paris.lutece.portal.service.util.AppPropertiesService;
41  import fr.paris.lutece.portal.util.mvc.admin.MVCAdminJspBean;
42  
43  import java.nio.file.AccessDeniedException;
44  import java.nio.file.Path;
45  import java.nio.file.Paths;
46  import java.util.ArrayList;
47  import java.util.List;
48  
49  /**
50   * ManageLogsProperties JSP Bean abstract class for JSP Bean
51   */
52  public abstract class AbstractManageLogsPropertiesJspBean extends MVCAdminJspBean
53  {
54      //Constants
55      protected static final String SLASH = "/";
56      protected static final String EMPTY = "";
57  
58      // Rights
59      public static final String RIGHT_MANAGELOGSPROPERTIES = "MANAGELOGS_MANAGEMENT";
60      
61      // Properties
62  
63      protected static final String TMP_LOG_PATH = AppPropertiesService.getProperty( "managelogs.tmp.log.path", "WEB-INF/conf/override/" );
64      protected static final String TMP_LOG_FILE_NAME = AppPropertiesService.getProperty( "managelogs.tmp.log.filename", "tmp_log.properties" );
65      protected static final String TMP_LOG_PATH_ABSOLUTE = getAbsolutePath( TMP_LOG_PATH );
66      protected static final String TMP_LOG_ABSOLUTE = TMP_LOG_PATH_ABSOLUTE + ( TMP_LOG_PATH_ABSOLUTE.endsWith( SLASH ) ? EMPTY : SLASH ) + TMP_LOG_FILE_NAME;
67  
68      protected static final String LUTECE_LOG_PATH = AppPropertiesService.getProperty( "managelogs.lutece.log.path", "WEB-INF/conf/" );
69      protected static final String LUTECE_LOG_FILE = AppPropertiesService.getProperty( "managelogs.lutecec.log.file", "config.properties" );
70  
71      protected static final String ALTERNATE_LOG_CONF_FILE_ABSOLUTE = getAbsolutePath( LUTECE_LOG_PATH + ( LUTECE_LOG_PATH.endsWith( SLASH ) ? EMPTY : SLASH ) + "override/" + "log.properties" );
72      protected static final String LUTECE_CONF_FILE_ABSOLUTE = getAbsolutePath( LUTECE_LOG_PATH + ( LUTECE_LOG_PATH.endsWith( SLASH ) ? EMPTY : SLASH ) + LUTECE_LOG_FILE );
73  
74      protected static final boolean APP_SERVER_MULTI_WEBAPP = AppPropertiesService.getPropertyBoolean( "managelogs.is.multi.webapp", false );
75  
76      private static List<String> _listLogFoldersAllowed = new ArrayList<>(  );
77  
78      static
79      {
80          // add path
81          String strListFoldersRelative = AppPropertiesService.getProperty( "managelogs.limit.folder" );
82          if ( strListFoldersRelative != null )
83          {
84              String[] arrFoldersRelative = strListFoldersRelative.split( ";" );
85              for ( String relativeFolder : arrFoldersRelative )
86              {
87                  if ( !ManageLogsUtil.isNullOrEmptyWithTrim( relativeFolder ) )
88                  {
89                      _listLogFoldersAllowed.add( getAbsolutePath( relativeFolder ) );
90                  }
91              }
92          }
93      }
94  
95  
96      /**
97       * return absolute path from a path
98       * @param strPath the path
99       * @return the absolute path
100      */
101     protected static String getAbsolutePath( String strPath )
102     {
103         Path path = Paths.get( strPath );
104         if ( path.isAbsolute( ) )
105         {
106             return strPath;
107         }
108         else
109         {
110             // relative
111             return AppPathService.getAbsolutePathFromRelativePath( ( strPath.startsWith( SLASH ) ? EMPTY : SLASH ) + strPath );
112         }
113     }
114 
115     /**
116      * get log files from configuration and check if parent folder is accessible  and in allowed folder
117      * @param lines lines from configuration file
118      * @return list of files in the log properties
119      */
120     protected static List<String> getFilesFromConfiguration( List<String> lines, boolean throwExceptionOnInaccessibleFile ) throws AccessDeniedException
121     {
122         if ( lines == null )
123         {
124             return new ArrayList<>(  );
125         }
126 
127         List<String> listConfiguredFiles = new ArrayList<>(  );
128         for ( String line : lines )
129         {
130             // check if line is valid (key=value) and not comment
131             if ( !ManageLogsUtil.isNullOrEmptyWithTrim( line ) && !line.trim( ).startsWith( "#" ) && line.split( "=" ).length == 2 && line.contains( ".File=" ) )
132             {
133                 String fileName = line.split( "=" )[ 1 ];
134                 String strParentAbsoluteDirectory = Paths.get( getAbsolutePath( fileName.replaceAll( "\r", EMPTY ) ) ).getParent( ).toString( );
135                 if ( isLogFileAccessible( strParentAbsoluteDirectory ) )
136                 {
137                     listConfiguredFiles.add( fileName );
138                 }
139                 else
140                 {
141                     AppLogService.debug( "File " + fileName + " inaccessible" );
142                     if ( throwExceptionOnInaccessibleFile )
143                     {
144                         throw new AccessDeniedException( "Folder " + strParentAbsoluteDirectory + " is denied (check 'limit.folder' configuration" );
145                     }
146                 }
147             }
148         }
149 
150         return listConfiguredFiles;
151     }
152 
153     /**
154      * Return true if file is accessible and within allowed log folder
155      * @param file the file to check
156      * @return the check result
157      */
158     protected static boolean isLogFileAccessible( String file )
159     {
160         if ( ManageLogsUtil.isNullOrEmptyWithTrim( file ) )
161         {
162             return false;
163         }
164 
165         boolean bIsFileOK = false;
166 
167         // check if the file is in an allowed folder (or sub-folder)
168         for ( String strValidFolder : _listLogFoldersAllowed )
169         {
170             if ( !ManageLogsUtil.isNullOrEmptyWithTrim( strValidFolder ) &&  Paths.get( file.trim() ).startsWith( Paths.get( strValidFolder.trim() ) ) )
171             {
172                 bIsFileOK = true;
173                 break;
174             }
175         }
176 
177         return  bIsFileOK && ManageLogsUtil.isFileReadable( file );
178     }
179 
180 }