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.file.implementation;
35
36 import fr.paris.lutece.portal.service.file.ExpiredLinkException;
37 import fr.paris.lutece.portal.service.file.FileService;
38 import static fr.paris.lutece.portal.service.file.FileService.PARAMETER_VALIDITY_TIME;
39 import fr.paris.lutece.portal.service.file.IFileDownloadUrlService;
40 import fr.paris.lutece.portal.service.security.RsaService;
41 import fr.paris.lutece.portal.service.util.AppLogService;
42 import fr.paris.lutece.portal.service.util.AppPathService;
43 import fr.paris.lutece.util.url.UrlItem;
44 import java.security.GeneralSecurityException;
45 import java.sql.Timestamp;
46 import java.time.LocalDateTime;
47 import java.util.HashMap;
48 import java.util.Map;
49 import javax.servlet.http.HttpServletRequest;
50 import org.apache.commons.lang3.StringUtils;
51
52
53
54
55
56
57 public class DefaultFileDownloadService implements IFileDownloadUrlService
58 {
59 private static final long serialVersionUID = 1L;
60
61
62 protected static final String URL_FO = "jsp/site/file/download";
63 protected static final String URL_BO = "jsp/admin/file/download";
64 private static final String SERVICE_NAME = "DefaultFileDownloadService";
65 private static final String DEFAULT_SEPARATOR = "/";
66
67 private String _separator = DEFAULT_SEPARATOR;
68
69
70 public static final String KEY_LINK_VALIDITY_TIME = "link_validity_time";
71
72 public String getSeparator( )
73 {
74 return _separator;
75 }
76
77 public void setSeparator( String separator )
78 {
79 _separator = separator;
80 }
81
82
83
84
85
86
87
88
89
90 public static Map<String, String> buildAdditionnalDatas( String strFileId, String strResourceId, String strResourceType )
91 {
92 Map<String, String> map = new HashMap<>( );
93
94 map.put( FileService.PARAMETER_FILE_ID, strFileId );
95 map.put( FileService.PARAMETER_RESOURCE_ID, strResourceId );
96 map.put( FileService.PARAMETER_RESOURCE_TYPE, strResourceType );
97
98 return map;
99 }
100
101
102
103
104 @Override
105 public String getFileDownloadUrlFO( String strFileKey, String strFileStorageServiceProviderName )
106 {
107
108 return getFileDownloadUrlFO( strFileKey, null, strFileStorageServiceProviderName );
109 }
110
111
112
113
114 @Override
115 public String getFileDownloadUrlFO( String strFileKey, Map<String, String> additionnalData, String strFileStorageServiceProviderName )
116 {
117 StringBuilder sbUrl = new StringBuilder( );
118
119 sbUrl.append( AppPathService.getBaseUrl( null ) );
120 sbUrl.append( URL_FO );
121
122 if ( additionnalData == null )
123 {
124 additionnalData = new HashMap<>( );
125 }
126 additionnalData.put( FileService.PARAMETER_FILE_ID, strFileKey );
127
128 return getEncryptedUrl( sbUrl.toString( ), getDataToEncrypt( additionnalData ), strFileStorageServiceProviderName );
129 }
130
131
132
133
134 @Override
135 public String getFileDownloadUrlBO( String strFileKey, String strFileStorageServiceProviderName )
136 {
137 return getFileDownloadUrlBO( strFileKey, null, strFileStorageServiceProviderName );
138 }
139
140
141
142
143 @Override
144 public String getFileDownloadUrlBO( String strFileKey, Map<String, String> additionnalData, String strFileStorageServiceProviderName )
145 {
146
147 StringBuilder sbUrl = new StringBuilder( );
148
149 sbUrl.append( AppPathService.getBaseUrl( null ) );
150 sbUrl.append( URL_BO );
151
152 if ( additionnalData == null )
153 {
154 additionnalData = new HashMap<>( );
155 }
156 additionnalData.put( FileService.PARAMETER_FILE_ID, strFileKey );
157
158 return getEncryptedUrl( sbUrl.toString( ), getDataToEncrypt( additionnalData ), strFileStorageServiceProviderName );
159 }
160
161
162
163
164
165
166
167
168
169 protected String getEncryptedUrl( String strUrl, String dataToEncrypt, String strFileStorageServiceProviderName )
170 {
171 UrlItemil/url/UrlItem.html#UrlItem">UrlItem item = new UrlItem( strUrl );
172
173 try
174 {
175 String idEncrytped = RsaService.encryptRsa( dataToEncrypt );
176
177 item.addParameter( FileService.PARAMETER_PROVIDER, strFileStorageServiceProviderName );
178 item.addParameter( FileService.PARAMETER_DATA, idEncrytped );
179
180 return item.getUrlWithEntity( );
181 }
182 catch( GeneralSecurityException e )
183 {
184 AppLogService.error( e.getMessage( ), e );
185 return null;
186 }
187 }
188
189
190
191
192 @Override
193 public String getName( )
194 {
195 return SERVICE_NAME;
196 }
197
198
199
200
201
202
203
204 private String getDataToEncrypt( Map<String, String> additionnalData )
205 {
206 StringBuilder sb = new StringBuilder( );
207 sb.append( StringUtils.defaultIfEmpty( additionnalData.get( FileService.PARAMETER_FILE_ID ), "" ) ).append( _separator );
208 sb.append( StringUtils.defaultIfEmpty( additionnalData.get( FileService.PARAMETER_RESOURCE_ID ), "" ) ).append( _separator );
209 sb.append( StringUtils.defaultIfEmpty( additionnalData.get( FileService.PARAMETER_RESOURCE_TYPE ), "" ) ).append( _separator );
210 sb.append( calculateEndValidity( ) );
211
212 return sb.toString( );
213 }
214
215
216
217
218
219
220 protected long calculateEndValidity( )
221 {
222 LocalDateTime endValidity = LocalDateTime.MAX;
223 if ( getValidityTime( ) > 0 )
224 {
225 endValidity = LocalDateTime.now( ).plusMinutes( LINK_VALIDITY_TIME );
226 }
227 return Timestamp.valueOf( endValidity ).getTime( );
228 }
229
230
231
232
233 @Override
234 public Map<String, String> getRequestDataBO( HttpServletRequest request )
235 {
236 String strEncryptedData = request.getParameter( FileService.PARAMETER_DATA );
237
238 try
239 {
240 String strDecryptedData = RsaService.decryptRsa( strEncryptedData );
241 return getDecryptedData( strDecryptedData );
242 }
243 catch( GeneralSecurityException e )
244 {
245 AppLogService.error( e.getMessage( ), e );
246 return null;
247 }
248 }
249
250
251
252
253 @Override
254 public Map<String, String> getRequestDataFO( HttpServletRequest request )
255 {
256 String strEncryptedData = request.getParameter( FileService.PARAMETER_DATA );
257
258 try
259 {
260 String strDecryptedData = RsaService.decryptRsa( strEncryptedData );
261 return getDecryptedData( strDecryptedData );
262 }
263 catch( GeneralSecurityException e )
264 {
265 AppLogService.error( e.getMessage( ), e );
266 return null;
267 }
268 }
269
270
271
272
273
274
275
276 protected Map<String, String> getDecryptedData( String strData )
277 {
278 String [ ] data = strData.split( _separator );
279 Map<String, String> fileData = buildAdditionnalDatas( data [0], data [1], data [2] );
280 fileData.put( PARAMETER_VALIDITY_TIME, data [3] );
281
282 return fileData;
283 }
284
285
286
287
288 @Override
289 public void checkLinkValidity( Map<String, String> fileData ) throws ExpiredLinkException
290 {
291 LocalDateTime validityTime = new Timestamp( Long.parseLong( fileData.get( FileService.PARAMETER_VALIDITY_TIME ) ) ).toLocalDateTime( );
292
293 if ( LocalDateTime.now( ).isAfter( validityTime ) )
294 {
295 throw new ExpiredLinkException( "Link expired on : " + validityTime.toString( ) );
296 }
297 }
298 }