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