First cut

This commit is contained in:
Eugene Livis 2021-10-13 16:12:38 -04:00
parent ab021cb834
commit dee30d6099
3 changed files with 142 additions and 6 deletions

View File

@ -16,6 +16,7 @@ FileExtRootFilter_documents_displayName=Documents
FileExtRootFilter_executable_displayName=Executable
FileExtRootFilter_image_displayName=Images
FileExtRootFilter_video_displayName=Video
FileTypesByMimeType.name.text=By MIME Type
ThreePanelDataArtifactDAO.dataArtifact.columnKeys.comment.description=Comment
ThreePanelDataArtifactDAO.dataArtifact.columnKeys.comment.displayName=C
ThreePanelDataArtifactDAO.dataArtifact.columnKeys.comment.name=Comment

View File

@ -0,0 +1,92 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2021 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.mainui.datamodel;
import java.util.Objects;
/**
* Key for accessing data about file MIME type from the DAO.
*/
public class FileTypeMimeSearchParam extends BaseSearchParam {
private final String mimeType;
private final Long dataSourceId;
private final boolean knownShown;
// TODO: This should ideally take in some kind of ENUM once we redo the tree.
// this assumes that filters implicitly or explicitly implement hashCode and equals to work
public FileTypeMimeSearchParam(String mimeType, Long dataSourceId, boolean showKnown) {
this.mimeType = mimeType;
this.dataSourceId = dataSourceId;
this.knownShown = showKnown;
}
public FileTypeMimeSearchParam(String mimeType, Long dataSourceId, boolean knownShown, long startItem, Long maxResultsCount) {
super(startItem, maxResultsCount);
this.mimeType = mimeType;
this.dataSourceId = dataSourceId;
this.knownShown = knownShown;
}
public String getFilter() {
return mimeType;
}
public Long getDataSourceId() {
return dataSourceId;
}
public boolean isKnownShown() {
return knownShown;
}
@Override
public int hashCode() {
int hash = 7;
hash = 23 * hash + Objects.hashCode(this.mimeType);
hash = 23 * hash + Objects.hashCode(this.dataSourceId);
hash = 23 * hash + (this.knownShown ? 1 : 0);
return hash;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final FileTypeMimeSearchParam other = (FileTypeMimeSearchParam) obj;
if (this.knownShown != other.knownShown) {
return false;
}
if (!(this.mimeType.equals(other.mimeType))) {
return false;
}
if (!Objects.equals(this.dataSourceId, other.dataSourceId)) {
return false;
}
return true;
}
}

View File

@ -28,9 +28,11 @@ import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.stream.Collectors;
import org.apache.commons.lang3.StringUtils;
import org.openide.util.NbBundle;
import org.openide.util.NbBundle.Messages;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
import static org.sleuthkit.autopsy.core.UserPreferences.hideSlackFilesInViewsTree;
import org.sleuthkit.autopsy.coreutils.TimeZoneUtils;
import org.sleuthkit.autopsy.datamodel.FileTypeExtensions;
import org.sleuthkit.autopsy.mainui.datamodel.FileRowDTO.ExtensionMediaType;
@ -151,6 +153,7 @@ public class ViewsDAO {
}
private final Cache<FileTypeExtensionsSearchParam, SearchResultsDTO> fileTypeByExtensionCache = CacheBuilder.newBuilder().maximumSize(1000).build();
private final Cache<FileTypeMimeSearchParam, SearchResultsDTO> fileTypeByMimeCache = CacheBuilder.newBuilder().maximumSize(1000).build();
public SearchResultsDTO getFilesByExtension(FileTypeExtensionsSearchParam key) throws ExecutionException, IllegalArgumentException {
if (key.getFilter() == null) {
@ -159,9 +162,20 @@ public class ViewsDAO {
throw new IllegalArgumentException("Data source id must be greater than 0 or null");
}
return fileTypeByExtensionCache.get(key, () -> fetchFileViewFiles(key.getFilter(), key.getDataSourceId(), key.isKnownShown()));
return fileTypeByExtensionCache.get(key, () -> fetchExtensionSearchResultsDTOs(key.getFilter(), key.getDataSourceId(), key.isKnownShown()));
}
public SearchResultsDTO getFilesByMime(FileTypeMimeSearchParam key) throws ExecutionException, IllegalArgumentException {
if (key.getFilter() == null) {
throw new IllegalArgumentException("Must have non-null filter");
} else if (key.getDataSourceId() != null && key.getDataSourceId() <= 0) {
throw new IllegalArgumentException("Data source id must be greater than 0 or null");
}
return fileTypeByMimeCache.get(key, () -> fetchMimeSearchResultsDTOs(key.getFilter(), key.getDataSourceId(), key.isKnownShown()));
}
// private ViewFileTableSearchResultsDTO fetchFilesForTable(ViewFileCacheKey cacheKey) throws NoCurrentCaseException, TskCoreException {
//
// }
@ -179,7 +193,7 @@ public class ViewsDAO {
private Map<Integer, Long> fetchFileViewCounts(List<FileExtSearchFilter> filters, Long dataSourceId, boolean showKnown) throws NoCurrentCaseException, TskCoreException {
Map<Integer, Long> counts = new HashMap<>();
for (FileExtSearchFilter filter : filters) {
String whereClause = getFileWhereStatement(filter, dataSourceId, showKnown);
String whereClause = getFileExtensionWhereStatement(filter, dataSourceId, showKnown);
long count = getCase().countFilesWhere(whereClause);
counts.put(filter.getId(), count);
}
@ -187,7 +201,7 @@ public class ViewsDAO {
return counts;
}
private String getFileWhereStatement(FileExtSearchFilter filter, Long dataSourceId, boolean showKnown) {
private String getFileExtensionWhereStatement(FileExtSearchFilter filter, Long dataSourceId, boolean showKnown) {
String whereClause = "(dir_type = " + TskData.TSK_FS_NAME_TYPE_ENUM.REG.getValue() + ")"
+ (showKnown
? " "
@ -202,8 +216,37 @@ public class ViewsDAO {
return whereClause;
}
private SearchResultsDTO fetchFileViewFiles(FileExtSearchFilter filter, Long dataSourceId, boolean showKnown) throws NoCurrentCaseException, TskCoreException {
String whereStatement = getFileWhereStatement(filter, dataSourceId, showKnown);
private String getFileMimeWhereStatement(String mimeType, Long dataSourceId, boolean showKnown) {
String whereClause = "(dir_type = " + TskData.TSK_FS_NAME_TYPE_ENUM.REG.getValue() + ")"
+ " AND (type IN ("
+ TskData.TSK_DB_FILES_TYPE_ENUM.FS.ordinal() + ","
+ TskData.TSK_DB_FILES_TYPE_ENUM.CARVED.ordinal() + ","
+ TskData.TSK_DB_FILES_TYPE_ENUM.DERIVED.ordinal() + ","
+ TskData.TSK_DB_FILES_TYPE_ENUM.LAYOUT_FILE.ordinal() + ","
+ TskData.TSK_DB_FILES_TYPE_ENUM.LOCAL.ordinal()
+ (hideSlackFilesInViewsTree() ? "" : ("," + TskData.TSK_DB_FILES_TYPE_ENUM.SLACK.ordinal()))
+ "))"
+ ((dataSourceId > 0) ? " AND data_source_obj_id = " + dataSourceId : " ")
+ (showKnown ? (" AND (known IS NULL OR known != " + TskData.FileKnown.KNOWN.getFileKnownValue() + ")") : "")
+ " AND mime_type = '" + mimeType + "'";
return whereClause;
}
private SearchResultsDTO fetchExtensionSearchResultsDTOs(FileExtSearchFilter filter, Long dataSourceId, boolean showKnown) throws NoCurrentCaseException, TskCoreException {
String whereStatement = getFileExtensionWhereStatement(filter, dataSourceId, showKnown);
return fetchFileViewFiles(whereStatement, filter.getDisplayName());
}
@NbBundle.Messages({"FileTypesByMimeType.name.text=By MIME Type"})
private SearchResultsDTO fetchMimeSearchResultsDTOs(String mimeType, Long dataSourceId, boolean showKnown) throws NoCurrentCaseException, TskCoreException {
String whereStatement = getFileMimeWhereStatement(mimeType, dataSourceId, showKnown);
final String MIME_TYPE_DISPLAY_NAME = Bundle.FileTypesByMimeType_name_text();
return fetchFileViewFiles(whereStatement, MIME_TYPE_DISPLAY_NAME);
}
private SearchResultsDTO fetchFileViewFiles(String whereStatement, String displayName) throws NoCurrentCaseException, TskCoreException {
List<AbstractFile> files = getCase().findAllFilesWhere(whereStatement);
List<RowDTO> fileRows = new ArrayList<>();
@ -259,7 +302,7 @@ public class ViewsDAO {
cellValues));
}
return new BaseSearchResultsDTO(FILE_VIEW_EXT_TYPE_ID, filter.getDisplayName(), FILE_COLUMNS, fileRows);
return new BaseSearchResultsDTO(FILE_VIEW_EXT_TYPE_ID, displayName, FILE_COLUMNS, fileRows);
}
}