mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-17 18:17:43 +00:00
Merge pull request #7342 from eugene7646/view_by_mime_8091
Add View by MIME DTO/DAO (8091)
This commit is contained in:
commit
a42b4292ee
@ -43,7 +43,7 @@ import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.mainui.datamodel.DataArtifactSearchParam;
|
||||
import org.sleuthkit.autopsy.mainui.nodes.DataArtifactNode;
|
||||
import org.sleuthkit.autopsy.mainui.nodes.FileNode;
|
||||
import org.sleuthkit.autopsy.mainui.datamodel.FileTypeExtensionsSearchParam;
|
||||
import org.sleuthkit.autopsy.mainui.datamodel.FileTypeExtensionsSearchParams;
|
||||
import org.sleuthkit.autopsy.mainui.nodes.SearchResultRootNode;
|
||||
import org.sleuthkit.autopsy.mainui.datamodel.MainDAO;
|
||||
import org.sleuthkit.autopsy.mainui.datamodel.SearchResultsDTO;
|
||||
@ -386,7 +386,7 @@ public final class DataResultTopComponent extends TopComponent implements DataRe
|
||||
}
|
||||
|
||||
|
||||
public void displayFileExtensions(FileTypeExtensionsSearchParam fileExtensionsKey) {
|
||||
public void displayFileExtensions(FileTypeExtensionsSearchParams fileExtensionsKey) {
|
||||
try {
|
||||
displaySearchResults(threePanelDAO.getViewsDAO().getFilesByExtension(fileExtensionsKey));
|
||||
} catch (ExecutionException | IllegalArgumentException ex) {
|
||||
|
@ -18,7 +18,7 @@
|
||||
*/
|
||||
package org.sleuthkit.autopsy.datamodel;
|
||||
|
||||
import org.sleuthkit.autopsy.mainui.datamodel.FileTypeExtensionsSearchParam;
|
||||
import org.sleuthkit.autopsy.mainui.datamodel.FileTypeExtensionsSearchParams;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.util.Arrays;
|
||||
@ -350,10 +350,9 @@ public final class FileTypesByExtension implements AutopsyVisitableItem {
|
||||
FileExtensionNode(FileExtSearchFilter filter, SleuthkitCase skCase, FileTypesByExtObservable o) {
|
||||
super(typesRoot, Children.LEAF,
|
||||
Lookups.fixed(filter.getDisplayName(),
|
||||
new FileTypeExtensionsSearchParam(
|
||||
new FileTypeExtensionsSearchParams(
|
||||
filter,
|
||||
filteringDataSourceObjId() > 0 ? filteringDataSourceObjId() : null,
|
||||
!UserPreferences.hideKnownFilesInViewsTree())));
|
||||
filteringDataSourceObjId() > 0 ? filteringDataSourceObjId() : null)));
|
||||
|
||||
this.filter = filter;
|
||||
super.setName(filter.getDisplayName());
|
||||
|
@ -84,7 +84,7 @@ import org.sleuthkit.autopsy.datamodel.KeywordHits;
|
||||
import org.sleuthkit.autopsy.datamodel.AutopsyTreeChildFactory;
|
||||
import org.sleuthkit.autopsy.mainui.datamodel.DataArtifactSearchParam;
|
||||
import org.sleuthkit.autopsy.datamodel.DataArtifacts;
|
||||
import org.sleuthkit.autopsy.mainui.datamodel.FileTypeExtensionsSearchParam;
|
||||
import org.sleuthkit.autopsy.mainui.datamodel.FileTypeExtensionsSearchParams;
|
||||
import org.sleuthkit.autopsy.datamodel.OsAccounts;
|
||||
import org.sleuthkit.autopsy.datamodel.PersonNode;
|
||||
import org.sleuthkit.autopsy.datamodel.Tags;
|
||||
@ -872,7 +872,7 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat
|
||||
Node drfn = new DataResultFilterNode(originNode, DirectoryTreeTopComponent.this.em);
|
||||
// Create a TableFilterNode with knowledge of the node's type to allow for column order settings
|
||||
DataArtifactSearchParam dataArtifactKey = originNode.getLookup().lookup(DataArtifactSearchParam.class);
|
||||
FileTypeExtensionsSearchParam fileExtensionsKey = originNode.getLookup().lookup(FileTypeExtensionsSearchParam.class);
|
||||
FileTypeExtensionsSearchParams fileExtensionsKey = originNode.getLookup().lookup(FileTypeExtensionsSearchParams.class);
|
||||
if (dataArtifactKey != null) {
|
||||
dataResult.displayDataArtifact(dataArtifactKey);
|
||||
} else if (fileExtensionsKey != null) {
|
||||
|
@ -21,18 +21,18 @@ package org.sleuthkit.autopsy.mainui.datamodel;
|
||||
/**
|
||||
* Base implementation of search parameters to provide to a DAO.
|
||||
*/
|
||||
public class BaseSearchParam implements SearchParam {
|
||||
public class BaseSearchParams implements SearchParams {
|
||||
private final long startItem;
|
||||
private final Long maxResultsCount;
|
||||
|
||||
/**
|
||||
* Constructor that gets all results.
|
||||
*/
|
||||
public BaseSearchParam() {
|
||||
public BaseSearchParams() {
|
||||
this(0, null);
|
||||
}
|
||||
|
||||
public BaseSearchParam(long startItem, Long maxResultsCount) {
|
||||
public BaseSearchParams(long startItem, Long maxResultsCount) {
|
||||
this.startItem = startItem;
|
||||
this.maxResultsCount = maxResultsCount;
|
||||
}
|
@ -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
|
||||
|
@ -24,7 +24,7 @@ import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||
/**
|
||||
* Key for data artifact in order to retrieve data from DAO.
|
||||
*/
|
||||
public class DataArtifactSearchParam extends BaseSearchParam {
|
||||
public class DataArtifactSearchParam extends BaseSearchParams {
|
||||
private final BlackboardArtifact.Type artifactType;
|
||||
private final Long dataSourceId;
|
||||
|
||||
|
@ -23,25 +23,22 @@ import java.util.Objects;
|
||||
/**
|
||||
* Key for accessing data about file type extensions from the DAO.
|
||||
*/
|
||||
public class FileTypeExtensionsSearchParam extends BaseSearchParam {
|
||||
public class FileTypeExtensionsSearchParams extends BaseSearchParams {
|
||||
|
||||
private final FileExtSearchFilter filter;
|
||||
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 FileTypeExtensionsSearchParam(FileExtSearchFilter filter, Long dataSourceId, boolean showKnown) {
|
||||
public FileTypeExtensionsSearchParams(FileExtSearchFilter filter, Long dataSourceId) {
|
||||
this.filter = filter;
|
||||
this.dataSourceId = dataSourceId;
|
||||
this.knownShown = showKnown;
|
||||
}
|
||||
|
||||
public FileTypeExtensionsSearchParam(FileExtSearchFilter filter, Long dataSourceId, boolean knownShown, long startItem, Long maxResultsCount) {
|
||||
public FileTypeExtensionsSearchParams(FileExtSearchFilter filter, Long dataSourceId, long startItem, Long maxResultsCount) {
|
||||
super(startItem, maxResultsCount);
|
||||
this.filter = filter;
|
||||
this.dataSourceId = dataSourceId;
|
||||
this.knownShown = knownShown;
|
||||
}
|
||||
|
||||
public FileExtSearchFilter getFilter() {
|
||||
@ -52,16 +49,11 @@ public class FileTypeExtensionsSearchParam extends BaseSearchParam {
|
||||
return dataSourceId;
|
||||
}
|
||||
|
||||
public boolean isKnownShown() {
|
||||
return knownShown;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hash = 7;
|
||||
hash = 23 * hash + Objects.hashCode(this.filter);
|
||||
hash = 23 * hash + Objects.hashCode(this.dataSourceId);
|
||||
hash = 23 * hash + (this.knownShown ? 1 : 0);
|
||||
return hash;
|
||||
}
|
||||
|
||||
@ -76,10 +68,7 @@ public class FileTypeExtensionsSearchParam extends BaseSearchParam {
|
||||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
final FileTypeExtensionsSearchParam other = (FileTypeExtensionsSearchParam) obj;
|
||||
if (this.knownShown != other.knownShown) {
|
||||
return false;
|
||||
}
|
||||
final FileTypeExtensionsSearchParams other = (FileTypeExtensionsSearchParams) obj;
|
||||
if (!Objects.equals(this.filter, other.filter)) {
|
||||
return false;
|
||||
}
|
@ -0,0 +1,80 @@
|
||||
/*
|
||||
* 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 FileTypeMimeSearchParams extends BaseSearchParams {
|
||||
|
||||
private final String mimeType;
|
||||
private final Long dataSourceId;
|
||||
|
||||
// @@@ TODO: Remove shownKnown from constructors and have DAO figure it out.
|
||||
public FileTypeMimeSearchParams(String mimeType, Long dataSourceId, boolean showKnown) {
|
||||
this.mimeType = mimeType;
|
||||
this.dataSourceId = dataSourceId;
|
||||
}
|
||||
|
||||
public FileTypeMimeSearchParams(String mimeType, Long dataSourceId, boolean knownShown, long startItem, Long maxResultsCount) {
|
||||
super(startItem, maxResultsCount);
|
||||
this.mimeType = mimeType;
|
||||
this.dataSourceId = dataSourceId;
|
||||
}
|
||||
|
||||
public String getMimeType() {
|
||||
return mimeType;
|
||||
}
|
||||
|
||||
public Long getDataSourceId() {
|
||||
return dataSourceId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hash = 7;
|
||||
hash = 23 * hash + Objects.hashCode(this.mimeType);
|
||||
hash = 23 * hash + Objects.hashCode(this.dataSourceId);
|
||||
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 FileTypeMimeSearchParams other = (FileTypeMimeSearchParams) obj;
|
||||
if (!(this.mimeType.equals(other.mimeType))) {
|
||||
return false;
|
||||
}
|
||||
if (!Objects.equals(this.dataSourceId, other.dataSourceId)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
@ -21,7 +21,7 @@ package org.sleuthkit.autopsy.mainui.datamodel;
|
||||
/**
|
||||
* Describes parameters to provide to the DAO for fetching data.
|
||||
*/
|
||||
public interface SearchParam {
|
||||
public interface SearchParams {
|
||||
|
||||
long getStartItem();
|
||||
|
@ -28,9 +28,12 @@ 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.hideKnownFilesInViewsTree;
|
||||
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;
|
||||
@ -150,18 +153,30 @@ public class ViewsDAO {
|
||||
return Case.getCurrentCaseThrows().getSleuthkitCase();
|
||||
}
|
||||
|
||||
private final Cache<FileTypeExtensionsSearchParam, SearchResultsDTO> fileTypeByExtensionCache = CacheBuilder.newBuilder().maximumSize(1000).build();
|
||||
private final Cache<FileTypeExtensionsSearchParams, SearchResultsDTO> fileTypeByExtensionCache = CacheBuilder.newBuilder().maximumSize(1000).build();
|
||||
private final Cache<FileTypeMimeSearchParams, SearchResultsDTO> fileTypeByMimeCache = CacheBuilder.newBuilder().maximumSize(1000).build();
|
||||
|
||||
public SearchResultsDTO getFilesByExtension(FileTypeExtensionsSearchParam key) throws ExecutionException, IllegalArgumentException {
|
||||
public SearchResultsDTO getFilesByExtension(FileTypeExtensionsSearchParams 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 fileTypeByExtensionCache.get(key, () -> fetchFileViewFiles(key.getFilter(), key.getDataSourceId(), key.isKnownShown()));
|
||||
return fileTypeByExtensionCache.get(key, () -> fetchExtensionSearchResultsDTOs(key.getFilter(), key.getDataSourceId()));
|
||||
}
|
||||
|
||||
public SearchResultsDTO getFilesByMime(FileTypeMimeSearchParams key) throws ExecutionException, IllegalArgumentException {
|
||||
if (key.getMimeType() == 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.getMimeType(), key.getDataSourceId()));
|
||||
}
|
||||
|
||||
|
||||
// private ViewFileTableSearchResultsDTO fetchFilesForTable(ViewFileCacheKey cacheKey) throws NoCurrentCaseException, TskCoreException {
|
||||
//
|
||||
// }
|
||||
@ -176,10 +191,10 @@ public class ViewsDAO {
|
||||
// ViewFileCacheKey cacheKey = new ViewFileCacheKey(artType, dataSourceId);
|
||||
// return dataArtifactCache.get(cacheKey, () -> fetchFilesForTable(cacheKey));
|
||||
// }
|
||||
private Map<Integer, Long> fetchFileViewCounts(List<FileExtSearchFilter> filters, Long dataSourceId, boolean showKnown) throws NoCurrentCaseException, TskCoreException {
|
||||
private Map<Integer, Long> fetchFileViewCounts(List<FileExtSearchFilter> filters, Long dataSourceId) throws NoCurrentCaseException, TskCoreException {
|
||||
Map<Integer, Long> counts = new HashMap<>();
|
||||
for (FileExtSearchFilter filter : filters) {
|
||||
String whereClause = getFileWhereStatement(filter, dataSourceId, showKnown);
|
||||
String whereClause = getFileExtensionWhereStatement(filter, dataSourceId);
|
||||
long count = getCase().countFilesWhere(whereClause);
|
||||
counts.put(filter.getId(), count);
|
||||
}
|
||||
@ -187,9 +202,9 @@ public class ViewsDAO {
|
||||
return counts;
|
||||
}
|
||||
|
||||
private String getFileWhereStatement(FileExtSearchFilter filter, Long dataSourceId, boolean showKnown) {
|
||||
private String getFileExtensionWhereStatement(FileExtSearchFilter filter, Long dataSourceId) {
|
||||
String whereClause = "(dir_type = " + TskData.TSK_FS_NAME_TYPE_ENUM.REG.getValue() + ")"
|
||||
+ (showKnown
|
||||
+ (hideKnownFilesInViewsTree()
|
||||
? " "
|
||||
: " AND (known IS NULL OR known != " + TskData.FileKnown.KNOWN.getFileKnownValue() + ")")
|
||||
+ (dataSourceId != null && dataSourceId > 0
|
||||
@ -202,8 +217,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) {
|
||||
|
||||
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 : " ")
|
||||
+ (hideKnownFilesInViewsTree() ? (" AND (known IS NULL OR known != " + TskData.FileKnown.KNOWN.getFileKnownValue() + ")") : "")
|
||||
+ " AND mime_type = '" + mimeType + "'";
|
||||
|
||||
return whereClause;
|
||||
}
|
||||
|
||||
private SearchResultsDTO fetchExtensionSearchResultsDTOs(FileExtSearchFilter filter, Long dataSourceId) throws NoCurrentCaseException, TskCoreException {
|
||||
String whereStatement = getFileExtensionWhereStatement(filter, dataSourceId);
|
||||
return fetchFileViewFiles(whereStatement, filter.getDisplayName());
|
||||
}
|
||||
|
||||
@NbBundle.Messages({"FileTypesByMimeType.name.text=By MIME Type"})
|
||||
private SearchResultsDTO fetchMimeSearchResultsDTOs(String mimeType, Long dataSourceId) throws NoCurrentCaseException, TskCoreException {
|
||||
String whereStatement = getFileMimeWhereStatement(mimeType, dataSourceId);
|
||||
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 +303,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);
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user