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.plugins.accesslogger.service;
35
36 import java.io.UnsupportedEncodingException;
37 import java.security.MessageDigest;
38 import java.security.NoSuchAlgorithmException;
39
40 import org.apache.log4j.Logger;
41
42 import com.fasterxml.jackson.core.JsonProcessingException;
43 import com.fasterxml.jackson.databind.ObjectMapper;
44 import fr.paris.lutece.portal.service.util.AppPropertiesService;
45
46 import java.text.MessageFormat;
47
48
49
50
51 public final class DefaultAccessLogger implements IAccessLogger
52 {
53
54 private static final String CONSTANT_HASH_ENCODING = "UTF-8";
55 private static final String CONSTANT_HASH_DIGEST = "MD5";
56 private static final String PROPERTY_ADD_HASH_TO_LOGS = "portal.defaultAccessLogger.addHashToLogs";
57 private static final String PROPERTY_ACCESSLOG_MESSAGE_FORMAT = "portal.defaultAccessLogger.messageFormat";
58 private static final String PROPERTY_ACCESSLOG_MESSAGE_FORMAT_SEPARATOR = "portal.defaultAccessLogger.messageFormatSeparator";
59
60 private static final String DEFAULT_ACCESSLOG_MESSAGE_FORMAT = "|{0}|{1}|{2}|{3}|{4}|{5}|{6}|";
61 private static final String DEFAULT_ACCESSLOG_MESSAGE_FORMAT_SEPARATOR = "|";
62
63 private final boolean _bAddHashToLogs = AppPropertiesService.getPropertyBoolean( PROPERTY_ADD_HASH_TO_LOGS, false );
64 private final String _messageFormat = AppPropertiesService.getProperty( PROPERTY_ACCESSLOG_MESSAGE_FORMAT, DEFAULT_ACCESSLOG_MESSAGE_FORMAT );
65 private final String _messageFormatSeparator = AppPropertiesService.getProperty( PROPERTY_ACCESSLOG_MESSAGE_FORMAT_SEPARATOR,
66 DEFAULT_ACCESSLOG_MESSAGE_FORMAT_SEPARATOR );
67 private static Logger _logger = Logger.getLogger( LOGGER_ACCESS_LOG );
68 private static final String ERROR_MSG = "ERROR : unable to create json from data";
69
70
71
72
73
74
75
76
77
78
79 public void info( String strEventType, String strAppEventCode, String strConnectedUserLogin, Object data )
80 {
81 if ( _logger.isInfoEnabled( ) )
82 {
83 String strAppId = AppPropertiesService.getProperty( IAccessLogger.PROPERTY_SITE_CODE, "?" );
84 String logMessage = getLogMessage( strAppId, strEventType, strAppEventCode, strConnectedUserLogin, data );
85
86 _logger.info( logMessage );
87 }
88 }
89
90
91
92
93
94
95
96
97
98
99 public void debug( String strEventType, String strAppEventCode, String strConnectedUserLogin, Object data )
100 {
101 if ( _logger.isDebugEnabled( ) )
102 {
103 String strAppId = AppPropertiesService.getProperty( PROPERTY_SITE_CODE, "?" );
104 String logMessage = getLogMessage( strAppId, strEventType, strAppEventCode, strConnectedUserLogin, data );
105
106 _logger.debug( logMessage );
107 }
108 }
109
110
111
112
113
114
115
116
117
118 public void trace( String strEventType, String strAppEventCode, String strConnectedUserLogin, Object data )
119 {
120 if ( _logger.isTraceEnabled( ) )
121 {
122 String strAppId = AppPropertiesService.getProperty( PROPERTY_SITE_CODE, "?" );
123 String logMessage = getLogMessage( strAppId, strEventType, strAppEventCode, strConnectedUserLogin, data );
124
125 _logger.trace( logMessage );
126 }
127 }
128
129
130
131
132
133
134
135
136
137
138 private String getLogMessage( String strAppId, String strEventType, String strAppEventCode, String strConnectedUserLogin, Object data )
139 {
140
141 String jsonData = "";
142
143 if ( data != null )
144 {
145 ObjectMapper obj = new ObjectMapper( );
146
147 try
148 {
149 jsonData = obj.writeValueAsString( data );
150 }
151 catch( JsonProcessingException e )
152 {
153 jsonData = ERROR_MSG;
154 }
155 }
156
157 return getLogMessage( strAppId, strEventType, strAppEventCode, strConnectedUserLogin, jsonData, isAddHashToLogs( ) );
158 }
159
160
161
162
163
164
165
166
167
168
169 private String getLogMessage( String strAppId, String strEventType, String strAppEventCode, String strConnectedUserLogin, String strData,
170 boolean isAddHashToLogs )
171 {
172
173 String strHash = "";
174
175 if ( isAddHashToLogs )
176 {
177 strHash = getHash( MessageFormat.format( _messageFormat, "", strAppId, strEventType, strAppEventCode, strConnectedUserLogin, strData ) );
178 }
179
180 return MessageFormat.format( _messageFormat, strHash, strAppId, strEventType, strAppEventCode, strConnectedUserLogin, strData, strHash );
181 }
182
183
184
185
186
187
188
189
190
191
192 private static String getHash( String message )
193 {
194
195 byte [ ] byteChaine;
196 try
197 {
198 byteChaine = message.getBytes( CONSTANT_HASH_ENCODING );
199 MessageDigest md = MessageDigest.getInstance( CONSTANT_HASH_DIGEST );
200 byte [ ] hash = md.digest( byteChaine );
201
202
203 StringBuilder sb = new StringBuilder( 2 * hash.length );
204 for ( byte b : hash )
205 {
206 sb.append( String.format( "%02x", b & 0xff ) );
207 }
208
209 return sb.toString( );
210
211 }
212 catch( UnsupportedEncodingException | NoSuchAlgorithmException e )
213 {
214 return "Hash ERROR : " + e.getLocalizedMessage( );
215 }
216
217 }
218
219
220
221
222
223
224
225
226 public boolean verifyMessageHash( String message )
227 {
228 try
229 {
230
231 int idx = message.indexOf( _messageFormatSeparator, message.indexOf( LOGGER_ACCESS_LOG ) );
232 String hash = message.substring( idx + 1, idx + 33 );
233 String data = message.substring( idx + 34 );
234
235 return ( hash != null && ( hash.equals( "" ) || hash.equals( getHash( data ) ) ) );
236
237 }
238 catch( StringIndexOutOfBoundsException e )
239 {
240
241 return false;
242 }
243 }
244
245
246
247
248
249
250 public boolean isAddHashToLogs( )
251 {
252 return _bAddHashToLogs;
253 }
254
255 }