1   /**
2    * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
3    *
4    * This library is free software; you can redistribute it and/or modify it under
5    * the terms of the GNU Lesser General Public License as published by the Free
6    * Software Foundation; either version 2.1 of the License, or (at your option)
7    * any later version.
8    *
9    * This library is distributed in the hope that it will be useful, but WITHOUT
10   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11   * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
12   * details.
13   */
14  
15  package com.liferay.documentlibrary.util;
16  
17  import com.liferay.portal.kernel.exception.PortalException;
18  import com.liferay.portal.kernel.exception.SystemException;
19  import com.liferay.portal.kernel.search.SearchException;
20  import com.liferay.portal.kernel.util.FileUtil;
21  import com.liferay.portal.service.ServiceContext;
22  import com.liferay.portlet.documentlibrary.model.DLFileEntryConstants;
23  
24  import java.io.File;
25  import java.io.InputStream;
26  
27  import java.util.Date;
28  
29  /**
30   * <a href="SafeFileNameHookWrapper.java.html"><b><i>View Source</i></b></a>
31   *
32   * @author Brian Wing Shun Chan
33   */
34  public class SafeFileNameHookWrapper implements Hook {
35  
36      public SafeFileNameHookWrapper(Hook hook) {
37          _hook = hook;
38      }
39  
40      public void addDirectory(long companyId, long repositoryId, String dirName)
41          throws PortalException, SystemException {
42  
43          String safeDirName = FileUtil.encodeSafeFileName(dirName);
44  
45          if (!safeDirName.equals(dirName)) {
46              try {
47                  _hook.move(dirName, safeDirName);
48              }
49              catch (Exception e) {
50              }
51          }
52  
53          _hook.addDirectory(companyId, repositoryId, safeDirName);
54      }
55  
56      public void addFile(
57              long companyId, String portletId, long groupId, long repositoryId,
58              String fileName, long fileEntryId, String properties,
59              Date modifiedDate, ServiceContext serviceContext, byte[] bytes)
60          throws PortalException, SystemException {
61  
62          String safeFileName = FileUtil.encodeSafeFileName(fileName);
63  
64          renameUnsafeFile(
65              companyId, portletId, groupId, repositoryId, fileName,
66              safeFileName);
67  
68          _hook.addFile(
69              companyId, portletId, groupId, repositoryId, safeFileName,
70              fileEntryId, properties, modifiedDate, serviceContext, bytes);
71      }
72  
73      public void addFile(
74              long companyId, String portletId, long groupId, long repositoryId,
75              String fileName, long fileEntryId, String properties,
76              Date modifiedDate, ServiceContext serviceContext, File file)
77          throws PortalException, SystemException {
78  
79          String safeFileName = FileUtil.encodeSafeFileName(fileName);
80  
81          renameUnsafeFile(
82              companyId, portletId, groupId, repositoryId, fileName,
83              safeFileName);
84  
85          _hook.addFile(
86              companyId, portletId, groupId, repositoryId, safeFileName,
87              fileEntryId, properties, modifiedDate, serviceContext, file);
88      }
89  
90      public void addFile(
91              long companyId, String portletId, long groupId, long repositoryId,
92              String fileName, long fileEntryId, String properties,
93              Date modifiedDate, ServiceContext serviceContext, InputStream is)
94          throws PortalException, SystemException {
95  
96          String safeFileName = FileUtil.encodeSafeFileName(fileName);
97  
98          renameUnsafeFile(
99              companyId, portletId, groupId, repositoryId, fileName,
100             safeFileName);
101 
102         _hook.addFile(
103             companyId, portletId, groupId, repositoryId, safeFileName,
104             fileEntryId, properties, modifiedDate, serviceContext, is);
105     }
106 
107     public void checkRoot(long companyId) throws SystemException {
108         _hook.checkRoot(companyId);
109     }
110 
111     public void deleteDirectory(
112             long companyId, String portletId, long repositoryId, String dirName)
113         throws PortalException, SystemException {
114 
115         String safeDirName = FileUtil.encodeSafeFileName(dirName);
116 
117         if (!safeDirName.equals(dirName)) {
118             try {
119                 _hook.deleteDirectory(
120                     companyId, portletId, repositoryId, dirName);
121 
122                 return;
123             }
124             catch (Exception e) {
125             }
126         }
127 
128         _hook.deleteDirectory(companyId, portletId, repositoryId, safeDirName);
129     }
130 
131     public void deleteFile(
132             long companyId, String portletId, long repositoryId,
133             String fileName)
134         throws PortalException, SystemException {
135 
136         String safeFileName = FileUtil.encodeSafeFileName(fileName);
137 
138         if (!safeFileName.equals(fileName) &&
139             _hook.hasFile(
140                 companyId, repositoryId, fileName,
141                 DLFileEntryConstants.DEFAULT_VERSION)) {
142 
143             _hook.deleteFile(companyId, portletId, repositoryId, fileName);
144 
145             return;
146         }
147 
148         _hook.deleteFile(companyId, portletId, repositoryId, safeFileName);
149     }
150 
151     public void deleteFile(
152             long companyId, String portletId, long repositoryId,
153             String fileName, String versionNumber)
154         throws PortalException, SystemException {
155 
156         String safeFileName = FileUtil.encodeSafeFileName(fileName);
157 
158         if (!safeFileName.equals(fileName) &&
159             _hook.hasFile(
160                 companyId, repositoryId, fileName, versionNumber)) {
161 
162             _hook.deleteFile(
163                 companyId, portletId, repositoryId, fileName, versionNumber);
164 
165             return;
166         }
167 
168         _hook.deleteFile(
169             companyId, portletId, repositoryId, safeFileName, versionNumber);
170     }
171 
172     public byte[] getFile(long companyId, long repositoryId, String fileName)
173         throws PortalException, SystemException {
174 
175         String safeFileName = FileUtil.encodeSafeFileName(fileName);
176 
177         if (!safeFileName.equals(fileName) &&
178             _hook.hasFile(
179                 companyId, repositoryId, fileName,
180                 DLFileEntryConstants.DEFAULT_VERSION)) {
181 
182             return _hook.getFile(companyId, repositoryId, fileName);
183         }
184 
185         return _hook.getFile(companyId, repositoryId, safeFileName);
186     }
187 
188     public byte[] getFile(
189             long companyId, long repositoryId, String fileName,
190             String versionNumber)
191         throws PortalException, SystemException {
192 
193         String safeFileName = FileUtil.encodeSafeFileName(fileName);
194 
195         if (!safeFileName.equals(fileName) &&
196             _hook.hasFile(companyId, repositoryId, fileName, versionNumber)) {
197 
198             return _hook.getFile(
199                 companyId, repositoryId, fileName, versionNumber);
200         }
201 
202         return _hook.getFile(
203             companyId, repositoryId, safeFileName, versionNumber);
204     }
205 
206     public InputStream getFileAsStream(
207             long companyId, long repositoryId, String fileName)
208         throws PortalException, SystemException {
209 
210         String safeFileName = FileUtil.encodeSafeFileName(fileName);
211 
212         if (!safeFileName.equals(fileName) &&
213             _hook.hasFile(
214                 companyId, repositoryId, fileName,
215                 DLFileEntryConstants.DEFAULT_VERSION)) {
216 
217             return _hook.getFileAsStream(companyId, repositoryId, fileName);
218         }
219 
220         return _hook.getFileAsStream(companyId, repositoryId, safeFileName);
221     }
222 
223     public InputStream getFileAsStream(
224             long companyId, long repositoryId, String fileName,
225             String versionNumber)
226         throws PortalException, SystemException {
227 
228         String safeFileName = FileUtil.encodeSafeFileName(fileName);
229 
230         if (!safeFileName.equals(fileName) &&
231             _hook.hasFile(
232                 companyId, repositoryId, fileName, versionNumber)) {
233 
234             return _hook.getFileAsStream(
235                 companyId, repositoryId, fileName, versionNumber);
236         }
237 
238         return _hook.getFileAsStream(
239             companyId, repositoryId, safeFileName, versionNumber);
240     }
241 
242     public String[] getFileNames(
243             long companyId, long repositoryId, String dirName)
244         throws PortalException, SystemException {
245 
246         String safeDirName = FileUtil.encodeSafeFileName(dirName);
247 
248         if (!safeDirName.equals(dirName)) {
249             try {
250                 _hook.move(dirName, safeDirName);
251             }
252             catch (Exception e) {
253             }
254         }
255 
256         String[] fileNames = _hook.getFileNames(
257             companyId, repositoryId, safeDirName);
258 
259         String[] decodedFileNames = new String[fileNames.length];
260 
261         for (int i = 0; i < fileNames.length; i++) {
262             decodedFileNames[i] = FileUtil.decodeSafeFileName(fileNames[i]);
263         }
264 
265         return decodedFileNames;
266     }
267 
268     public long getFileSize(
269             long companyId, long repositoryId, String fileName)
270         throws PortalException, SystemException {
271 
272         String safeFileName = FileUtil.encodeSafeFileName(fileName);
273 
274         if (!safeFileName.equals(fileName) &&
275             _hook.hasFile(
276                 companyId, repositoryId, fileName,
277                 DLFileEntryConstants.DEFAULT_VERSION)) {
278 
279             return _hook.getFileSize(companyId, repositoryId, fileName);
280         }
281 
282         return _hook.getFileSize(companyId, repositoryId, safeFileName);
283     }
284 
285     public boolean hasFile(
286             long companyId, long repositoryId, String fileName,
287             String versionNumber)
288         throws PortalException, SystemException {
289 
290         String safeFileName = FileUtil.encodeSafeFileName(fileName);
291 
292         if (!safeFileName.equals(fileName) &&
293             _hook.hasFile(companyId, repositoryId, fileName, versionNumber)) {
294 
295             return true;
296         }
297 
298         return _hook.hasFile(
299             companyId, repositoryId, safeFileName, versionNumber);
300     }
301 
302     public void move(String srcDir, String destDir) throws SystemException {
303         _hook.move(srcDir, destDir);
304     }
305 
306     public void reindex(String[] ids) throws SearchException {
307         _hook.reindex(ids);
308     }
309 
310     public void updateFile(
311             long companyId, String portletId, long groupId, long repositoryId,
312             long newRepositoryId, String fileName, long fileEntryId)
313         throws PortalException, SystemException {
314 
315         String safeFileName = FileUtil.encodeSafeFileName(fileName);
316 
317         renameUnsafeFile(
318             companyId, portletId, groupId, repositoryId, fileName,
319             safeFileName);
320 
321         _hook.updateFile(
322             companyId, portletId, groupId, repositoryId, newRepositoryId,
323             safeFileName, fileEntryId);
324     }
325 
326     public void updateFile(
327             long companyId, String portletId, long groupId, long repositoryId,
328             String fileName, String newFileName, boolean reindex)
329         throws PortalException, SystemException {
330 
331         String safeFileName = FileUtil.encodeSafeFileName(fileName);
332         String safeNewFileName = FileUtil.encodeSafeFileName(newFileName);
333 
334         if (!safeFileName.equals(fileName)) {
335             if (_hook.hasFile(
336                     companyId, repositoryId, fileName,
337                     DLFileEntryConstants.DEFAULT_VERSION)) {
338 
339                 safeFileName = fileName;
340             }
341         }
342 
343         _hook.updateFile(
344             companyId, portletId, groupId, repositoryId, safeFileName,
345             safeNewFileName, reindex);
346     }
347 
348     public void updateFile(
349             long companyId, String portletId, long groupId, long repositoryId,
350             String fileName, String versionNumber, String sourceFileName,
351             long fileEntryId, String properties, Date modifiedDate,
352             ServiceContext serviceContext, byte[] bytes)
353         throws PortalException, SystemException {
354 
355         String safeFileName = FileUtil.encodeSafeFileName(fileName);
356         String safeSourceFileName = FileUtil.encodeSafeFileName(sourceFileName);
357 
358         renameUnsafeFile(
359             companyId, portletId, groupId, repositoryId, fileName,
360             safeFileName);
361         renameUnsafeFile(
362             companyId, portletId, groupId, repositoryId, sourceFileName,
363             safeSourceFileName);
364 
365         _hook.updateFile(
366             companyId, portletId, groupId, repositoryId, safeFileName,
367             versionNumber, safeSourceFileName, fileEntryId, properties,
368             modifiedDate, serviceContext, bytes);
369     }
370 
371     public void updateFile(
372             long companyId, String portletId, long groupId, long repositoryId,
373             String fileName, String versionNumber, String sourceFileName,
374             long fileEntryId, String properties, Date modifiedDate,
375             ServiceContext serviceContext, File file)
376         throws PortalException, SystemException {
377 
378         String safeFileName = FileUtil.encodeSafeFileName(fileName);
379         String safeSourceFileName = FileUtil.encodeSafeFileName(sourceFileName);
380 
381         renameUnsafeFile(
382             companyId, portletId, groupId, repositoryId, fileName,
383             safeFileName);
384         renameUnsafeFile(
385             companyId, portletId, groupId, repositoryId, sourceFileName,
386             safeSourceFileName);
387 
388         _hook.updateFile(
389             companyId, portletId, groupId, repositoryId, safeFileName,
390             versionNumber, safeSourceFileName, fileEntryId, properties,
391             modifiedDate, serviceContext, file);
392     }
393 
394     public void updateFile(
395             long companyId, String portletId, long groupId, long repositoryId,
396             String fileName, String versionNumber, String sourceFileName,
397             long fileEntryId, String properties, Date modifiedDate,
398             ServiceContext serviceContext, InputStream is)
399         throws PortalException, SystemException {
400 
401         String safeFileName = FileUtil.encodeSafeFileName(fileName);
402         String safeSourceFileName = FileUtil.encodeSafeFileName(sourceFileName);
403 
404         renameUnsafeFile(
405             companyId, portletId, groupId, repositoryId, fileName,
406             safeFileName);
407         renameUnsafeFile(
408             companyId, portletId, groupId, repositoryId, sourceFileName,
409             safeSourceFileName);
410 
411         _hook.updateFile(
412             companyId, portletId, groupId, repositoryId, safeFileName,
413             versionNumber, safeSourceFileName, fileEntryId, properties,
414             modifiedDate, serviceContext, is);
415     }
416 
417     protected void renameUnsafeFile(
418             long companyId, String portletId, long groupId, long repositoryId,
419             String fileName, String safeFileName)
420         throws PortalException, SystemException {
421 
422         if (!safeFileName.equals(fileName)) {
423             if (_hook.hasFile(
424                     companyId, repositoryId, fileName,
425                     DLFileEntryConstants.DEFAULT_VERSION)) {
426 
427                 _hook.updateFile(
428                     companyId, portletId, groupId, repositoryId, fileName,
429                     safeFileName, true);
430             }
431         }
432     }
433 
434     private Hook _hook;
435 
436 }