1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 package fr.paris.lutece.portal.service.security.impl;
35
36 import java.io.UnsupportedEncodingException;
37 import java.security.MessageDigest;
38 import java.security.NoSuchAlgorithmException;
39
40 import com.fasterxml.jackson.core.JsonProcessingException;
41 import com.fasterxml.jackson.databind.ObjectMapper;
42 import fr.paris.lutece.api.user.User;
43 import fr.paris.lutece.portal.service.security.AccessLoggerConstants;
44 import fr.paris.lutece.portal.service.util.AppPropertiesService;
45 import fr.paris.lutece.portal.service.security.IAccessLogger;
46
47 import java.text.MessageFormat;
48 import org.apache.logging.log4j.Level;
49 import org.apache.logging.log4j.LogManager;
50 import org.apache.logging.log4j.Logger;
51
52
53
54
55
56
57
58
59
60
61
62
63
64 public final class DefaultAccessLogger implements IAccessLogger
65 {
66
67 private static final String CONSTANT_HASH_ENCODING = "UTF-8";
68 private static final String CONSTANT_HASH_DIGEST = "MD5";
69 private static final String PROPERTY_ADD_HASH_TO_LOGS = "accessLogger.defaultAccessLogger.addHashToLogs";
70 private static final String PROPERTY_ACCESSLOG_MESSAGE_FORMAT = "accessLogger.defaultAccessLogger.messageFormat";
71 private static final String PROPERTY_ACCESSLOG_MESSAGE_FORMAT_SEPARATOR = "accessLogger.defaultAccessLogger.messageFormatSeparator";
72
73 private static final String DEFAULT_ACCESSLOG_MESSAGE_FORMAT = "|{0}|{1}|{2}|{3}|{4}|{5}|";
74 private static final String DEFAULT_ACCESSLOG_MESSAGE_FORMAT_SEPARATOR = "|";
75
76 private static final String ERROR_MSG = "ERROR : unable to create json from data";
77
78 private final boolean _bAddHashToLogs = AppPropertiesService.getPropertyBoolean( PROPERTY_ADD_HASH_TO_LOGS, false );
79 private final String _messageFormat = AppPropertiesService.getProperty( PROPERTY_ACCESSLOG_MESSAGE_FORMAT, DEFAULT_ACCESSLOG_MESSAGE_FORMAT );
80 private final String _messageFormatSeparator = AppPropertiesService.getProperty( PROPERTY_ACCESSLOG_MESSAGE_FORMAT_SEPARATOR,
81 DEFAULT_ACCESSLOG_MESSAGE_FORMAT_SEPARATOR );
82
83 public static final String DEFAULT_LOGGER_ACCESS_LOG = "lutece.accessLogger";
84 private static Logger _defaultLogger = LogManager.getLogger( DEFAULT_LOGGER_ACCESS_LOG );
85
86
87
88
89 @Override
90 public void info( String strEventType, String strAppEventCode, User connectedUser, Object data, String specificOrigin )
91 {
92 Logger logger = getLogger( specificOrigin );
93
94 if ( logger.isInfoEnabled( ) )
95 {
96 String strAppId = AppPropertiesService.getProperty( AccessLoggerConstants.PROPERTY_SITE_CODE, "?" );
97 String logMessage = getLogMessage( strAppId, strEventType, strAppEventCode, ( connectedUser != null ? connectedUser.getAccessCode( ) : "null" ),
98 data );
99
100 logger.info( logMessage );
101 }
102 }
103
104
105
106
107 @Override
108 public void debug( String strEventType, String strAppEventCode, User connectedUser, Object data, String specificOrigin )
109 {
110 Logger logger = getLogger( specificOrigin );
111
112 if ( logger.isDebugEnabled( ) )
113 {
114 String strAppId = AppPropertiesService.getProperty( AccessLoggerConstants.PROPERTY_SITE_CODE, "?" );
115 String logMessage = getLogMessage( strAppId, strEventType, strAppEventCode, ( connectedUser != null ? connectedUser.getAccessCode( ) : "null" ),
116 data );
117
118 logger.debug( logMessage );
119 }
120 }
121
122
123
124
125 @Override
126 public void trace( String strEventType, String strAppEventCode, User connectedUser, Object data, String specificOrigin )
127 {
128 Logger logger = getLogger( specificOrigin );
129
130 if ( logger.isTraceEnabled( ) )
131 {
132 String strAppId = AppPropertiesService.getProperty( AccessLoggerConstants.PROPERTY_SITE_CODE, "?" );
133 String logMessage = getLogMessage( strAppId, strEventType, strAppEventCode, ( connectedUser != null ? connectedUser.getAccessCode( ) : "null" ),
134 data );
135
136 logger.trace( logMessage );
137 }
138 }
139
140
141
142
143 @Override
144 public void warn( String strEventType, String strAppEventCode, User connectedUser, Object data, String specificOrigin )
145 {
146 Logger logger = getLogger( specificOrigin );
147
148 if ( logger.isEnabled( Level.WARN ) )
149 {
150 String strAppId = AppPropertiesService.getProperty( AccessLoggerConstants.PROPERTY_SITE_CODE, "?" );
151 String logMessage = getLogMessage( strAppId, strEventType, strAppEventCode, ( connectedUser != null ? connectedUser.getAccessCode( ) : "null" ),
152 data );
153
154 logger.warn( logMessage );
155 }
156 }
157
158
159
160
161
162
163
164
165
166
167 private String getLogMessage( String strAppId, String strEventType, String strAppEventCode, String strConnectedUserLogin, Object data )
168 {
169
170 String jsonData = "";
171
172 if ( data != null )
173 {
174 ObjectMapper obj = new ObjectMapper( );
175
176 try
177 {
178 jsonData = obj.writeValueAsString( data );
179 }
180 catch( JsonProcessingException e )
181 {
182 jsonData = ERROR_MSG;
183 }
184 }
185
186 return getLogMessage( strAppId, strEventType, strAppEventCode, strConnectedUserLogin, jsonData, isAddHashToLogs( ) );
187 }
188
189
190
191
192
193
194
195
196
197
198 private String getLogMessage( String strAppId, String strEventType, String strAppEventCode, String strConnectedUserLogin, String strData,
199 boolean isAddHashToLogs )
200 {
201
202 String strHash = "";
203
204 if ( isAddHashToLogs )
205 {
206 strHash = getHash( MessageFormat.format( _messageFormat, "", strAppId, strEventType, strAppEventCode, strConnectedUserLogin, strData ) );
207 }
208
209 return MessageFormat.format( _messageFormat, strHash, strAppId, strEventType, strAppEventCode, strConnectedUserLogin, strData );
210 }
211
212
213
214
215
216
217
218
219
220
221 private static String getHash( String message )
222 {
223
224 byte [ ] byteChaine;
225 try
226 {
227 byteChaine = message.getBytes( CONSTANT_HASH_ENCODING );
228 MessageDigest md = MessageDigest.getInstance( CONSTANT_HASH_DIGEST );
229 byte [ ] hash = md.digest( byteChaine );
230
231
232 StringBuilder sb = new StringBuilder( 2 * hash.length );
233 for ( byte b : hash )
234 {
235 sb.append( String.format( "%02x", b & 0xff ) );
236 }
237
238 return sb.toString( );
239
240 }
241 catch( UnsupportedEncodingException | NoSuchAlgorithmException e )
242 {
243 return "Hash ERROR : " + e.getLocalizedMessage( );
244 }
245
246 }
247
248
249
250
251
252
253
254
255 public boolean verifyMessageHash( String message )
256 {
257 try
258 {
259
260 int idx = message.indexOf( _messageFormatSeparator, message.indexOf( DEFAULT_LOGGER_ACCESS_LOG ) );
261 String hash = message.substring( idx + 1, idx + 33 );
262 String data = "||" + message.substring( idx + 34 );
263
264 return ( hash != null && ( hash.equals( "" ) || hash.equals( getHash( data ) ) ) );
265
266 }
267 catch( StringIndexOutOfBoundsException e )
268 {
269
270 return false;
271 }
272 }
273
274
275
276
277
278
279 public boolean isAddHashToLogs( )
280 {
281 return _bAddHashToLogs;
282 }
283
284
285
286
287
288
289
290 private Logger getLogger( String specificOrigin )
291 {
292 if ( specificOrigin != null && !"".equals( specificOrigin ) )
293 {
294 return LogManager.getLogger( DEFAULT_LOGGER_ACCESS_LOG + "." + specificOrigin );
295 }
296
297 return _defaultLogger;
298
299 }
300 }