001
014
015 package com.liferay.portlet.documentlibrary.store;
016
017 import com.liferay.portal.kernel.bean.BeanReference;
018 import com.liferay.portal.kernel.exception.PortalException;
019 import com.liferay.portal.kernel.exception.SystemException;
020 import com.liferay.portal.kernel.io.ByteArrayFileInputStream;
021 import com.liferay.portal.kernel.search.BooleanClauseOccur;
022 import com.liferay.portal.kernel.search.BooleanQuery;
023 import com.liferay.portal.kernel.search.BooleanQueryFactoryUtil;
024 import com.liferay.portal.kernel.search.Field;
025 import com.liferay.portal.kernel.search.Hits;
026 import com.liferay.portal.kernel.search.Indexer;
027 import com.liferay.portal.kernel.search.IndexerRegistryUtil;
028 import com.liferay.portal.kernel.search.SearchContext;
029 import com.liferay.portal.kernel.search.SearchEngineUtil;
030 import com.liferay.portal.kernel.search.TermQuery;
031 import com.liferay.portal.kernel.search.TermQueryFactoryUtil;
032 import com.liferay.portal.kernel.util.FileUtil;
033 import com.liferay.portal.kernel.util.PropsKeys;
034 import com.liferay.portal.kernel.util.StringPool;
035 import com.liferay.portal.kernel.util.StringUtil;
036 import com.liferay.portal.kernel.util.TempFileUtil;
037 import com.liferay.portal.kernel.util.Validator;
038 import com.liferay.portal.model.Group;
039 import com.liferay.portal.security.permission.ActionKeys;
040 import com.liferay.portal.security.permission.PermissionChecker;
041 import com.liferay.portal.security.permission.PermissionThreadLocal;
042 import com.liferay.portal.service.GroupLocalService;
043 import com.liferay.portal.util.PrefsPropsUtil;
044 import com.liferay.portal.util.PropsValues;
045 import com.liferay.portlet.documentlibrary.DirectoryNameException;
046 import com.liferay.portlet.documentlibrary.FileExtensionException;
047 import com.liferay.portlet.documentlibrary.FileNameException;
048 import com.liferay.portlet.documentlibrary.FileSizeException;
049 import com.liferay.portlet.documentlibrary.SourceFileNameException;
050 import com.liferay.portlet.documentlibrary.antivirus.AntivirusScannerUtil;
051 import com.liferay.portlet.documentlibrary.model.DLFileEntryConstants;
052 import com.liferay.portlet.documentlibrary.model.DLFolderConstants;
053 import com.liferay.portlet.documentlibrary.service.permission.DLFolderPermission;
054
055 import java.io.File;
056 import java.io.IOException;
057 import java.io.InputStream;
058
059
064 public class DLStoreImpl implements DLStore {
065
066 @Override
067 public void addDirectory(long companyId, long repositoryId, String dirName)
068 throws PortalException, SystemException {
069
070 if (!isValidName(dirName) || dirName.equals("/")) {
071 throw new DirectoryNameException(dirName);
072 }
073
074 store.addDirectory(companyId, repositoryId, dirName);
075 }
076
077 @Override
078 public void addFile(
079 long companyId, long repositoryId, String fileName,
080 boolean validateFileExtension, byte[] bytes)
081 throws PortalException, SystemException {
082
083 validate(fileName, validateFileExtension, bytes);
084
085 if (PropsValues.DL_STORE_ANTIVIRUS_ENABLED) {
086 AntivirusScannerUtil.scan(bytes);
087 }
088
089 store.addFile(companyId, repositoryId, fileName, bytes);
090 }
091
092 @Override
093 public void addFile(
094 long companyId, long repositoryId, String fileName,
095 boolean validateFileExtension, File file)
096 throws PortalException, SystemException {
097
098 validate(fileName, validateFileExtension, file);
099
100 if (PropsValues.DL_STORE_ANTIVIRUS_ENABLED) {
101 AntivirusScannerUtil.scan(file);
102 }
103
104 store.addFile(companyId, repositoryId, fileName, file);
105 }
106
107 @Override
108 public void addFile(
109 long companyId, long repositoryId, String fileName,
110 boolean validateFileExtension, InputStream is)
111 throws PortalException, SystemException {
112
113 if (is instanceof ByteArrayFileInputStream) {
114 ByteArrayFileInputStream byteArrayFileInputStream =
115 (ByteArrayFileInputStream)is;
116
117 File file = byteArrayFileInputStream.getFile();
118
119 addFile(
120 companyId, repositoryId, fileName, validateFileExtension, file);
121
122 return;
123 }
124
125 validate(fileName, validateFileExtension, is);
126
127 if (!PropsValues.DL_STORE_ANTIVIRUS_ENABLED ||
128 !AntivirusScannerUtil.isActive()) {
129
130 store.addFile(companyId, repositoryId, fileName, is);
131 }
132 else {
133 File tempFile = null;
134
135 try {
136 if (is.markSupported()) {
137 is.mark(is.available() + 1);
138
139 AntivirusScannerUtil.scan(is);
140
141 is.reset();
142
143 store.addFile(companyId, repositoryId, fileName, is);
144 }
145 else {
146 tempFile = FileUtil.createTempFile();
147
148 FileUtil.write(tempFile, is);
149
150 AntivirusScannerUtil.scan(tempFile);
151
152 store.addFile(companyId, repositoryId, fileName, tempFile);
153 }
154 }
155 catch (IOException ioe) {
156 throw new SystemException(
157 "Unable to scan file " + fileName, ioe);
158 }
159 finally {
160 if (tempFile != null) {
161 tempFile.delete();
162 }
163 }
164 }
165 }
166
167 @Override
168 public void addFile(
169 long companyId, long repositoryId, String fileName, byte[] bytes)
170 throws PortalException, SystemException {
171
172 addFile(companyId, repositoryId, fileName, true, bytes);
173 }
174
175 @Override
176 public void addFile(
177 long companyId, long repositoryId, String fileName, File file)
178 throws PortalException, SystemException {
179
180 addFile(companyId, repositoryId, fileName, true, file);
181 }
182
183 @Override
184 public void addFile(
185 long companyId, long repositoryId, String fileName, InputStream is)
186 throws PortalException, SystemException {
187
188 addFile(companyId, repositoryId, fileName, true, is);
189 }
190
191 @Override
192 public void checkRoot(long companyId) throws SystemException {
193 store.checkRoot(companyId);
194 }
195
196 @Override
197 public void copyFileVersion(
198 long companyId, long repositoryId, String fileName,
199 String fromVersionLabel, String toVersionLabel)
200 throws PortalException, SystemException {
201
202 store.copyFileVersion(
203 companyId, repositoryId, fileName, fromVersionLabel,
204 toVersionLabel);
205 }
206
207 @Override
208 public void deleteDirectory(
209 long companyId, long repositoryId, String dirName)
210 throws PortalException, SystemException {
211
212 store.deleteDirectory(companyId, repositoryId, dirName);
213 }
214
215 @Override
216 public void deleteFile(long companyId, long repositoryId, String fileName)
217 throws PortalException, SystemException {
218
219 validate(fileName, false);
220
221 store.deleteFile(companyId, repositoryId, fileName);
222 }
223
224 @Override
225 public void deleteFile(
226 long companyId, long repositoryId, String fileName,
227 String versionLabel)
228 throws PortalException, SystemException {
229
230 validate(fileName, false);
231
232 store.deleteFile(companyId, repositoryId, fileName, versionLabel);
233 }
234
235 @Override
236 public File getFile(long companyId, long repositoryId, String fileName)
237 throws PortalException, SystemException {
238
239 validate(fileName, false);
240
241 return store.getFile(companyId, repositoryId, fileName);
242 }
243
244 @Override
245 public File getFile(
246 long companyId, long repositoryId, String fileName,
247 String versionLabel)
248 throws PortalException, SystemException {
249
250 validate(fileName, false);
251
252 return store.getFile(companyId, repositoryId, fileName, versionLabel);
253 }
254
255 @Override
256 public byte[] getFileAsBytes(
257 long companyId, long repositoryId, String fileName)
258 throws PortalException, SystemException {
259
260 validate(fileName, false);
261
262 return store.getFileAsBytes(companyId, repositoryId, fileName);
263 }
264
265 @Override
266 public byte[] getFileAsBytes(
267 long companyId, long repositoryId, String fileName,
268 String versionLabel)
269 throws PortalException, SystemException {
270
271 validate(fileName, false);
272
273 return store.getFileAsBytes(
274 companyId, repositoryId, fileName, versionLabel);
275 }
276
277 @Override
278 public InputStream getFileAsStream(
279 long companyId, long repositoryId, String fileName)
280 throws PortalException, SystemException {
281
282 validate(fileName, false);
283
284 return store.getFileAsStream(companyId, repositoryId, fileName);
285 }
286
287 @Override
288 public InputStream getFileAsStream(
289 long companyId, long repositoryId, String fileName,
290 String versionLabel)
291 throws PortalException, SystemException {
292
293 validate(fileName, false);
294
295 return store.getFileAsStream(
296 companyId, repositoryId, fileName, versionLabel);
297 }
298
299 @Override
300 public String[] getFileNames(
301 long companyId, long repositoryId, String dirName)
302 throws PortalException, SystemException {
303
304 if (!isValidName(dirName)) {
305 throw new DirectoryNameException(dirName);
306 }
307
308 return store.getFileNames(companyId, repositoryId, dirName);
309 }
310
311 @Override
312 public long getFileSize(long companyId, long repositoryId, String fileName)
313 throws PortalException, SystemException {
314
315 validate(fileName, false);
316
317 return store.getFileSize(companyId, repositoryId, fileName);
318 }
319
320 @Override
321 public boolean hasDirectory(
322 long companyId, long repositoryId, String dirName)
323 throws PortalException, SystemException {
324
325 if (!isValidName(dirName)) {
326 throw new DirectoryNameException(dirName);
327 }
328
329 return store.hasDirectory(companyId, repositoryId, dirName);
330 }
331
332 @Override
333 public boolean hasFile(long companyId, long repositoryId, String fileName)
334 throws PortalException, SystemException {
335
336 validate(fileName, false);
337
338 return store.hasFile(companyId, repositoryId, fileName);
339 }
340
341 @Override
342 public boolean hasFile(
343 long companyId, long repositoryId, String fileName,
344 String versionLabel)
345 throws PortalException, SystemException {
346
347 validate(fileName, false);
348
349 return store.hasFile(companyId, repositoryId, fileName, versionLabel);
350 }
351
352 @Override
353 public void move(String srcDir, String destDir) throws SystemException {
354 store.move(srcDir, destDir);
355 }
356
357 public Hits search(
358 long companyId, long userId, String portletId, long groupId,
359 long[] repositoryIds, String keywords, int start, int end)
360 throws SystemException {
361
362 try {
363 SearchContext searchContext = new SearchContext();
364
365 searchContext.setCompanyId(companyId);
366 searchContext.setEnd(end);
367 searchContext.setEntryClassNames(
368 new String[] {DLFileEntryConstants.getClassName()});
369 searchContext.setGroupIds(new long[] {groupId});
370
371 Indexer indexer = IndexerRegistryUtil.getIndexer(
372 DLFileEntryConstants.getClassName());
373
374 searchContext.setSearchEngineId(indexer.getSearchEngineId());
375
376 searchContext.setStart(start);
377 searchContext.setUserId(userId);
378
379 BooleanQuery contextQuery = BooleanQueryFactoryUtil.create(
380 searchContext);
381
382 contextQuery.addRequiredTerm(Field.PORTLET_ID, portletId);
383
384 if (groupId > 0) {
385 Group group = groupLocalService.getGroup(groupId);
386
387 if (group.isLayout()) {
388 contextQuery.addRequiredTerm(Field.SCOPE_GROUP_ID, groupId);
389
390 groupId = group.getParentGroupId();
391 }
392
393 contextQuery.addRequiredTerm(Field.GROUP_ID, groupId);
394 }
395
396 if ((repositoryIds != null) && (repositoryIds.length > 0)) {
397 BooleanQuery repositoryIdsQuery =
398 BooleanQueryFactoryUtil.create(searchContext);
399
400 for (long repositoryId : repositoryIds) {
401 try {
402 if (userId > 0) {
403 PermissionChecker permissionChecker =
404 PermissionThreadLocal.getPermissionChecker();
405
406 DLFolderPermission.check(
407 permissionChecker, groupId, repositoryId,
408 ActionKeys.VIEW);
409 }
410
411 if (repositoryId ==
412 DLFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
413
414 repositoryId = groupId;
415 }
416
417 TermQuery termQuery = TermQueryFactoryUtil.create(
418 searchContext, "repositoryId", repositoryId);
419
420 repositoryIdsQuery.add(
421 termQuery, BooleanClauseOccur.SHOULD);
422 }
423 catch (Exception e) {
424 }
425 }
426
427 contextQuery.add(repositoryIdsQuery, BooleanClauseOccur.MUST);
428 }
429
430 BooleanQuery searchQuery = BooleanQueryFactoryUtil.create(
431 searchContext);
432
433 searchQuery.addTerms(_KEYWORDS_FIELDS, keywords);
434
435 BooleanQuery fullQuery = BooleanQueryFactoryUtil.create(
436 searchContext);
437
438 fullQuery.add(contextQuery, BooleanClauseOccur.MUST);
439
440 if (searchQuery.clauses().size() > 0) {
441 fullQuery.add(searchQuery, BooleanClauseOccur.MUST);
442 }
443
444 return SearchEngineUtil.search(searchContext, fullQuery);
445 }
446 catch (Exception e) {
447 throw new SystemException(e);
448 }
449 }
450
451 @Override
452 public void updateFile(
453 long companyId, long repositoryId, long newRepositoryId,
454 String fileName)
455 throws PortalException, SystemException {
456
457 store.updateFile(companyId, repositoryId, newRepositoryId, fileName);
458 }
459
460 @Override
461 public void updateFile(
462 long companyId, long repositoryId, String fileName,
463 String newFileName)
464 throws PortalException, SystemException {
465
466 store.updateFile(companyId, repositoryId, fileName, newFileName);
467 }
468
469 @Override
470 public void updateFile(
471 long companyId, long repositoryId, String fileName,
472 String fileExtension, boolean validateFileExtension,
473 String versionLabel, String sourceFileName, File file)
474 throws PortalException, SystemException {
475
476 validate(
477 fileName, fileExtension, sourceFileName, validateFileExtension,
478 file);
479
480 if (PropsValues.DL_STORE_ANTIVIRUS_ENABLED) {
481 AntivirusScannerUtil.scan(file);
482 }
483
484 store.updateFile(companyId, repositoryId, fileName, versionLabel, file);
485 }
486
487 @Override
488 public void updateFile(
489 long companyId, long repositoryId, String fileName,
490 String fileExtension, boolean validateFileExtension,
491 String versionLabel, String sourceFileName, InputStream is)
492 throws PortalException, SystemException {
493
494 if (is instanceof ByteArrayFileInputStream) {
495 ByteArrayFileInputStream byteArrayFileInputStream =
496 (ByteArrayFileInputStream)is;
497
498 File file = byteArrayFileInputStream.getFile();
499
500 updateFile(
501 companyId, repositoryId, fileName, fileExtension,
502 validateFileExtension, versionLabel, sourceFileName, file);
503
504 return;
505 }
506
507 validate(
508 fileName, fileExtension, sourceFileName, validateFileExtension, is);
509
510 if (!PropsValues.DL_STORE_ANTIVIRUS_ENABLED ||
511 !AntivirusScannerUtil.isActive()) {
512
513 store.updateFile(
514 companyId, repositoryId, fileName, versionLabel, is);
515 }
516 else {
517 File tempFile = null;
518
519 try {
520 if (is.markSupported()) {
521 is.mark(is.available() + 1);
522
523 AntivirusScannerUtil.scan(is);
524
525 is.reset();
526
527 store.updateFile(
528 companyId, repositoryId, fileName, versionLabel, is);
529 }
530 else {
531 tempFile = FileUtil.createTempFile();
532
533 FileUtil.write(tempFile, is);
534
535 AntivirusScannerUtil.scan(tempFile);
536
537 store.updateFile(
538 companyId, repositoryId, fileName, versionLabel,
539 tempFile);
540 }
541 }
542 catch (IOException ioe) {
543 throw new SystemException(
544 "Unable to scan file " + fileName, ioe);
545 }
546 finally {
547 if (tempFile != null) {
548 tempFile.delete();
549 }
550 }
551 }
552 }
553
554 @Override
555 public void updateFileVersion(
556 long companyId, long repositoryId, String fileName,
557 String fromVersionLabel, String toVersionLabel)
558 throws PortalException, SystemException {
559
560 store.updateFileVersion(
561 companyId, repositoryId, fileName, fromVersionLabel,
562 toVersionLabel);
563 }
564
565 @Override
566 public void validate(String fileName, boolean validateFileExtension)
567 throws PortalException, SystemException {
568
569 if (!isValidName(fileName)) {
570 throw new FileNameException(fileName);
571 }
572
573 if (fileName.endsWith(TempFileUtil.SUFFIX_TEMP_FILE_NAME)) {
574 fileName = StringUtil.replaceLast(
575 fileName, TempFileUtil.SUFFIX_TEMP_FILE_NAME, StringPool.BLANK);
576 }
577
578 if (validateFileExtension) {
579 boolean validFileExtension = false;
580
581 String[] fileExtensions = PrefsPropsUtil.getStringArray(
582 PropsKeys.DL_FILE_EXTENSIONS, StringPool.COMMA);
583
584 for (String fileExtension : fileExtensions) {
585 if (StringPool.STAR.equals(fileExtension) ||
586 StringUtil.endsWith(fileName, fileExtension)) {
587
588 validFileExtension = true;
589
590 break;
591 }
592 }
593
594 if (!validFileExtension) {
595 throw new FileExtensionException(fileName);
596 }
597 }
598 }
599
600 @Override
601 public void validate(
602 String fileName, boolean validateFileExtension, byte[] bytes)
603 throws PortalException, SystemException {
604
605 validate(fileName, validateFileExtension);
606
607 if ((PrefsPropsUtil.getLong(PropsKeys.DL_FILE_MAX_SIZE) > 0) &&
608 ((bytes == null) ||
609 (bytes.length >
610 PrefsPropsUtil.getLong(PropsKeys.DL_FILE_MAX_SIZE)))) {
611
612 throw new FileSizeException(fileName);
613 }
614 }
615
616 @Override
617 public void validate(
618 String fileName, boolean validateFileExtension, File file)
619 throws PortalException, SystemException {
620
621 validate(fileName, validateFileExtension);
622
623 if ((PrefsPropsUtil.getLong(PropsKeys.DL_FILE_MAX_SIZE) > 0) &&
624 ((file == null) ||
625 (file.length() >
626 PrefsPropsUtil.getLong(PropsKeys.DL_FILE_MAX_SIZE)))) {
627
628 throw new FileSizeException(fileName);
629 }
630 }
631
632 @Override
633 public void validate(
634 String fileName, boolean validateFileExtension, InputStream is)
635 throws PortalException, SystemException {
636
637 validate(fileName, validateFileExtension);
638
639
640
641 try {
642 if ((is == null) ||
643 ((PrefsPropsUtil.getLong(PropsKeys.DL_FILE_MAX_SIZE) > 0) &&
644 (is.available() >
645 PrefsPropsUtil.getLong(PropsKeys.DL_FILE_MAX_SIZE)))) {
646
647 throw new FileSizeException(fileName);
648 }
649 }
650 catch (IOException ioe) {
651 throw new FileSizeException(ioe.getMessage());
652 }
653 }
654
655 @Override
656 public void validate(
657 String fileName, String fileExtension, String sourceFileName,
658 boolean validateFileExtension, File file)
659 throws PortalException, SystemException {
660
661 validate(
662 fileName, fileExtension, sourceFileName, validateFileExtension);
663
664 if ((file != null) &&
665 (PrefsPropsUtil.getLong(PropsKeys.DL_FILE_MAX_SIZE) > 0) &&
666 (file.length() >
667 PrefsPropsUtil.getLong(PropsKeys.DL_FILE_MAX_SIZE))) {
668
669 throw new FileSizeException(fileName);
670 }
671 }
672
673 @Override
674 public void validate(
675 String fileName, String fileExtension, String sourceFileName,
676 boolean validateFileExtension, InputStream is)
677 throws PortalException, SystemException {
678
679 validate(
680 fileName, fileExtension, sourceFileName, validateFileExtension);
681
682 try {
683 if ((is != null) &&
684 (PrefsPropsUtil.getLong(PropsKeys.DL_FILE_MAX_SIZE) > 0) &&
685 (is.available() >
686 PrefsPropsUtil.getLong(PropsKeys.DL_FILE_MAX_SIZE))) {
687
688 throw new FileSizeException(fileName);
689 }
690 }
691 catch (IOException ioe) {
692 throw new FileSizeException(ioe.getMessage());
693 }
694 }
695
696 protected boolean isValidName(String name) {
697 if ((name == null) ||
698 name.contains("\\") ||
699 name.contains("\\\\") ||
700 name.contains("
701 name.contains(":") ||
702 name.contains("*") ||
703 name.contains("?") ||
704 name.contains("\"") ||
705 name.contains("<") ||
706 name.contains(">") ||
707 name.contains("|") ||
708 name.contains("[") ||
709 name.contains("]") ||
710 name.contains("../") ||
711 name.contains("/..")) {
712
713 return false;
714 }
715
716 return true;
717 }
718
719 protected void validate(
720 String fileName, String fileExtension, String sourceFileName,
721 boolean validateFileExtension)
722 throws PortalException, SystemException {
723
724 String sourceFileExtension = FileUtil.getExtension(sourceFileName);
725
726 if (Validator.isNotNull(sourceFileName) &&
727 PropsValues.DL_FILE_EXTENSIONS_STRICT_CHECK &&
728 !fileExtension.equals(sourceFileExtension)) {
729
730 throw new SourceFileNameException(sourceFileExtension);
731 }
732
733 validate(fileName, validateFileExtension);
734 }
735
736 @BeanReference(type = GroupLocalService.class)
737 protected GroupLocalService groupLocalService;
738
739 @BeanReference(type = Store.class)
740 protected Store store;
741
742 private static final String[] _KEYWORDS_FIELDS = {
743 Field.ASSET_TAG_NAMES, Field.CONTENT, Field.PROPERTIES
744 };
745
746 }