package com.constellio.app.modules.es.connectors.smb.service; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.List; import org.apache.commons.lang.StringUtils; import com.constellio.app.modules.es.connectors.smb.security.WindowsPermissions; import com.constellio.app.modules.es.connectors.smb.security.WindowsPermissionsFactory; import com.constellio.app.modules.es.connectors.smb.service.SmbFileDTO.SmbFileDTOStatus; import com.constellio.app.modules.es.connectors.spi.ConnectorLogger; import com.constellio.app.modules.es.services.ESSchemasRecordsServices; import com.constellio.data.utils.TimeProvider; import com.constellio.model.entities.records.ParsedContent; import com.constellio.model.services.parser.FileParser; import com.constellio.model.services.parser.FileParserException; import jcifs.smb.SmbFile; public class SmbFileDTOSimpleBuilder { private static final long MAX_FILE_SIZE_IN_BYTES = 10737418240L; private static final String ERROR_TOO_BIG = "File exceeds maximum size (in bytes): " + MAX_FILE_SIZE_IN_BYTES; private final ConnectorLogger logger; private final ESSchemasRecordsServices es; private final WindowsPermissionsFactory permissionsFactory; public SmbFileDTOSimpleBuilder(ConnectorLogger logger, ESSchemasRecordsServices es, WindowsPermissionsFactory permissionsFactory) { this.logger = logger; this.es = es; this.permissionsFactory = permissionsFactory; } public SmbFileDTO build(SmbFile smbFile, boolean withContent) { SmbFileDTO smbFileDTO = new SmbFileDTO(); InputStream inputStream = null; String url = null; try { smbFileDTO.setStatus(SmbFileDTOStatus.FULL_DTO); smbFileDTO.setLastFetchAttempt(TimeProvider.getLocalDateTime()); url = smbFile.getCanonicalPath(); smbFileDTO.setUrl(url); if (!smbFile.exists()) { smbFileDTO.setStatus(SmbFileDTOStatus.DELETE_DTO); } else { smbFileDTO.setCreateTime(smbFile.createTime()); smbFileDTO.setLastModified(smbFile.getLastModified()); WindowsPermissions windowsPermissions = getWindowsPermissions(smbFile); windowsPermissions.process(); if (!StringUtils.isBlank(windowsPermissions.getErrors())) { throw new IOException(windowsPermissions.getErrors()); } List<String> allowTokens = prependedTokenListOrNullOnEmptyList(windowsPermissions.getAllowTokenDocument()); smbFileDTO.setAllowTokens(allowTokens); List<String> denyTokens = prependedTokenListOrNullOnEmptyList(windowsPermissions.getDenyTokenDocument()); smbFileDTO.setDenyTokens(denyTokens); List<String> allowShareTokens = prependedTokenListOrNullOnEmptyList(windowsPermissions.getAllowTokenShare()); smbFileDTO.setAllowShareTokens(allowShareTokens); List<String> denyShareTokens = prependedTokenListOrNullOnEmptyList(windowsPermissions.getDenyTokenShare()); smbFileDTO.setDenyShareTokens(denyShareTokens); smbFileDTO.setPermissionsHash(windowsPermissions.getPermissionsHash()); smbFileDTO.setIsFile(smbFile.isFile()); smbFileDTO.setIsDirectory(smbFile.isDirectory()); if (smbFileDTO.isFile()) { smbFileDTO.setExtension(StringUtils.defaultIfBlank(StringUtils.substringAfterLast(smbFile.getName(), "."), "")); smbFileDTO.setName(smbFile.getName()); smbFileDTO.setLength(smbFile.length()); if (withContent) { if (smbFileDTO.getLength() > 0 && smbFileDTO.getLength() <= MAX_FILE_SIZE_IN_BYTES) { inputStream = smbFile.getInputStream(); try { ParsedContent parsedContent = updateParsedContent(smbFileDTO, inputStream); smbFileDTO.setLanguage(parsedContent.getLanguage()); } catch (Throwable t) { smbFileDTO.setParsedContent(""); smbFileDTO.setLanguage(""); } } else { if (smbFileDTO.getLength() > MAX_FILE_SIZE_IN_BYTES) { smbFileDTO.setErrorMessage(ERROR_TOO_BIG); smbFileDTO.setStatus(SmbFileDTOStatus.FAILED_DTO); } else { smbFileDTO.setParsedContent(""); smbFileDTO.setLanguage(""); } } } } else { String folderNameWithoutTrailingSlash = StringUtils.removeEnd(smbFile.getName(), "/"); smbFileDTO.setName(folderNameWithoutTrailingSlash); smbFileDTO.setLength(0); smbFileDTO.setParsedContent(""); smbFileDTO.setLanguage(""); } } } catch (IOException e) { logger.error(new SmbLoggedException(url, e)); smbFileDTO.setStatus(SmbFileDTOStatus.FAILED_DTO); smbFileDTO.setErrorMessage(e.getMessage()); } catch (Throwable t) { logger.errorUnexpected(t); smbFileDTO.setStatus(SmbFileDTOStatus.FAILED_DTO); smbFileDTO.setErrorMessage(t.getMessage()); } finally { es.getIOServices() .closeQuietly(inputStream); } return smbFileDTO; } protected WindowsPermissions getWindowsPermissions(SmbFile smbFile) { return permissionsFactory.newWindowsPermissions(smbFile); } private List<String> prependedTokenListOrNullOnEmptyList(List<String> initialList) { if (initialList == null || initialList.isEmpty() || initialList.contains("DEAD_AUTHORITY")) { return null; } else { return prependReadAndAuthorizationTypeToAllSids(initialList); } } private List<String> prependReadAndAuthorizationTypeToAllSids(List<String> initialSids) { String read = "r"; String authorizationType = "ad"; if (initialSids != null) { List<String> modifiedSids = new ArrayList<String>(); for (String sid : initialSids) { modifiedSids.add(read + "," + authorizationType + "," + sid); } return modifiedSids; } else { return null; } } private ParsedContent updateParsedContent(SmbFileDTO smbFileDTO, InputStream inputStream) throws FileParserException { FileParser fileParser = es.getModelLayerFactory() .newFileParser(); ParsedContent parsedContent = fileParser.parse(inputStream, true); smbFileDTO.setParsedContent(parsedContent.getParsedContent()); return parsedContent; } }