From 5cb61589aa13174b62b258fe8124c069616ce8bc Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Tue, 21 Jul 2020 11:43:34 -0400 Subject: [PATCH 1/4] 6590 refresh discovery filters when opened --- .../autopsy/discovery/DiscoveryDialog.java | 101 +++++++++++++++++- 1 file changed, 99 insertions(+), 2 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/discovery/DiscoveryDialog.java b/Core/src/org/sleuthkit/autopsy/discovery/DiscoveryDialog.java index 33f69712f0..655efc04c0 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/DiscoveryDialog.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/DiscoveryDialog.java @@ -23,6 +23,7 @@ import java.awt.Color; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.EnumSet; +import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.logging.Level; @@ -30,12 +31,18 @@ import org.apache.commons.lang.StringUtils; import org.openide.util.NbBundle.Messages; import org.openide.windows.WindowManager; import org.sleuthkit.autopsy.casemodule.Case; +import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoException; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.discovery.FileGroup.GroupSortingAlgorithm; import org.sleuthkit.autopsy.discovery.FileSearch.GroupingAttributeType; import org.sleuthkit.autopsy.discovery.FileSorter.SortingMethod; +import org.sleuthkit.autopsy.ingest.IngestManager; +import org.sleuthkit.autopsy.ingest.ModuleDataEvent; +import org.sleuthkit.datamodel.BlackboardArtifact; +import org.sleuthkit.datamodel.BlackboardAttribute; +import org.sleuthkit.datamodel.TskCoreException; /** * Dialog for displaying the controls and filters for configuration of a @@ -45,6 +52,7 @@ final class DiscoveryDialog extends javax.swing.JDialog { private static final Set CASE_EVENTS_OF_INTEREST = EnumSet.of(Case.Events.CURRENT_CASE, Case.Events.DATA_SOURCE_ADDED, Case.Events.DATA_SOURCE_DELETED); + private static final Set INGEST_MODULE_EVENTS_OF_INTEREST = EnumSet.of(IngestManager.IngestModuleEvent.DATA_ADDED); private static final long serialVersionUID = 1L; private final static Logger logger = Logger.getLogger(DiscoveryDialog.class.getName()); private ImageFilterPanel imageFilterPanel = null; @@ -54,8 +62,12 @@ final class DiscoveryDialog extends javax.swing.JDialog { private static final Color UNSELECTED_COLOR = new Color(240, 240, 240); private SearchWorker searchWorker = null; private static DiscoveryDialog discDialog; + private static volatile boolean shouldUpdate = false; private FileSearchData.FileType fileType = FileSearchData.FileType.IMAGE; private final PropertyChangeListener listener; + private final Set objectsDetected = new HashSet<>(); + private final Set interestingItems = new HashSet<>(); + private final Set hashSets = new HashSet<>(); /** * Get the Discovery dialog instance. @@ -66,6 +78,10 @@ final class DiscoveryDialog extends javax.swing.JDialog { if (discDialog == null) { discDialog = new DiscoveryDialog(); } + if (shouldUpdate) { + discDialog.updateSearchSettings(); + shouldUpdate = false; + } return discDialog; } @@ -89,6 +105,7 @@ final class DiscoveryDialog extends javax.swing.JDialog { } updateSearchSettings(); Case.addEventTypeSubscriber(CASE_EVENTS_OF_INTEREST, this.new CasePropertyChangeListener()); + IngestManager.getInstance().addIngestModuleEventListener(INGEST_MODULE_EVENTS_OF_INTEREST, this.new ModuleChangeListener()); } /** @@ -531,7 +548,8 @@ final class DiscoveryDialog extends javax.swing.JDialog { * The adjust the controls to reflect whether the settings are valid based * on the error. * - * @param error The error message to display, empty string if there is no error. + * @param error The error message to display, empty string if there is no + * error. */ private void setValid(String error) { if (StringUtils.isBlank(error)) { @@ -575,7 +593,7 @@ final class DiscoveryDialog extends javax.swing.JDialog { case DATA_SOURCE_ADDED: //fallthrough case DATA_SOURCE_DELETED: - updateSearchSettings(); + shouldUpdate = true; break; default: //do nothing if the event is not one of the above events. @@ -583,4 +601,83 @@ final class DiscoveryDialog extends javax.swing.JDialog { } } } + + /** + * PropertyChangeListener to listen to ingest module events that may modify + * the filters available. + */ + private class ModuleChangeListener implements PropertyChangeListener { + + @Override + @SuppressWarnings("fallthrough") + public void propertyChange(PropertyChangeEvent evt) { + if (!shouldUpdate) { + String eventType = evt.getPropertyName(); + if (eventType.equals(IngestManager.IngestModuleEvent.DATA_ADDED.toString())) { + /** + * Checking for a current case is a stop gap measure until a + * different way of handling the closing of cases is worked + * out. Currently, remote events may be received for a case + * that is already closed. + */ + try { + Case.getCurrentCaseThrows(); + /** + * Even with the check above, it is still possible that + * the case will be closed in a different thread before + * this code executes. If that happens, it is possible + * for the event to have a null oldValue. + */ + ModuleDataEvent eventData = (ModuleDataEvent) evt.getOldValue(); + if (null != eventData) { + if (eventData.getBlackboardArtifactType().getTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_OBJECT_DETECTED.getTypeID() && eventData.getArtifacts() != null) { + shouldUpdate = shouldUpdateFilters(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DESCRIPTION.getTypeID(), eventData, objectsDetected); + } else if (eventData.getBlackboardArtifactType().getTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_HASHSET_HIT.getTypeID()) { + shouldUpdate = shouldUpdateFilters(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME.getTypeID(), eventData, hashSets); + } else if (eventData.getBlackboardArtifactType().getTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT.getTypeID() + || eventData.getBlackboardArtifactType().getTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_ARTIFACT_HIT.getTypeID()) { + shouldUpdate = shouldUpdateFilters(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME.getTypeID(), eventData, interestingItems); + } + + } + } catch (NoCurrentCaseException notUsed) { + // Case is closed, do nothing. + } catch (TskCoreException ex) { + logger.log(Level.WARNING, "Unable to determine if discovery UI should be updated", ex); + } + } + } + } + + /** + * Helper method to determine if the artifact in the eventData + * represents a new value for the filter. + * + * @param attributeTypeId The attribute id of the attribute which + * contains the value for the filter. + * @param eventData The event which contains the artifacts. + * @param filterSetToCheck The set of current values for the relevant + * filter. + * + * @return True if the value is a new value for the filter, false + * otherwise. + * + * @throws TskCoreException Thrown because the attributes were unable to + * be retrieved for one of the artifacts in the + * eventData. + */ + private boolean shouldUpdateFilters(int attributeTypeId, ModuleDataEvent eventData, Set filterSetToCheck) throws TskCoreException { + for (BlackboardArtifact artifact : eventData.getArtifacts()) { + if (artifact.getAttributes() != null) { + for (BlackboardAttribute attr : artifact.getAttributes()) { + if (attr.getAttributeType().getTypeID() == attributeTypeId && !filterSetToCheck.contains(attr)) { + filterSetToCheck.add(attr); + return true; + } + } + } + } + return false; + } + } } From 424bb3d8bc833a442314bb57ecd6c2c63f5c6685 Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Tue, 21 Jul 2020 12:04:36 -0400 Subject: [PATCH 2/4] 6561 perform fewer repaints farther appart in order to reduce load on AWT --- .../org/sleuthkit/autopsy/discovery/DiscoveryTopComponent.java | 2 +- Core/src/org/sleuthkit/autopsy/discovery/SwingAnimator.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/discovery/DiscoveryTopComponent.java b/Core/src/org/sleuthkit/autopsy/discovery/DiscoveryTopComponent.java index 526207981c..8fac68a8cc 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/DiscoveryTopComponent.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/DiscoveryTopComponent.java @@ -52,7 +52,7 @@ public final class DiscoveryTopComponent extends TopComponent { private final ResultsPanel resultsPanel; private int dividerLocation = -1; - private static final int ANIMATION_INCREMENT = 10; + private static final int ANIMATION_INCREMENT = 30; private static final int RESULTS_AREA_SMALL_SIZE = 250; private SwingAnimator animator = null; diff --git a/Core/src/org/sleuthkit/autopsy/discovery/SwingAnimator.java b/Core/src/org/sleuthkit/autopsy/discovery/SwingAnimator.java index eb5ba0d26f..2dac8559bb 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/SwingAnimator.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/SwingAnimator.java @@ -39,7 +39,7 @@ final class SwingAnimator { private Timer timer = null; //duration in milliseconds betweeen each firing of the Timer - private static final int INITIAL_TIMING = 10; + private static final int INITIAL_TIMING = 30; private int timing = INITIAL_TIMING; /** From 49b66dc969d9fee189313e7cdf3ee1073336bb6e Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Tue, 21 Jul 2020 12:41:17 -0400 Subject: [PATCH 3/4] 6606 change default settings and search --- .../autopsy/discovery/DiscoveryDialog.java | 16 +++++++++++----- .../autopsy/discovery/DocumentFilterPanel.java | 6 ++++-- .../autopsy/discovery/ImageFilterPanel.java | 4 ++-- .../autopsy/discovery/VideoFilterPanel.java | 6 ++++-- 4 files changed, 21 insertions(+), 11 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/discovery/DiscoveryDialog.java b/Core/src/org/sleuthkit/autopsy/discovery/DiscoveryDialog.java index 33f69712f0..3da1edd030 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/DiscoveryDialog.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/DiscoveryDialog.java @@ -34,15 +34,18 @@ import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoException; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.discovery.FileGroup.GroupSortingAlgorithm; +import static org.sleuthkit.autopsy.discovery.FileGroup.GroupSortingAlgorithm.BY_GROUP_NAME; import org.sleuthkit.autopsy.discovery.FileSearch.GroupingAttributeType; +import static org.sleuthkit.autopsy.discovery.FileSearch.GroupingAttributeType.PARENT_PATH; import org.sleuthkit.autopsy.discovery.FileSorter.SortingMethod; +import static org.sleuthkit.autopsy.discovery.FileSorter.SortingMethod.BY_FILE_SIZE; /** * Dialog for displaying the controls and filters for configuration of a * Discovery search. */ final class DiscoveryDialog extends javax.swing.JDialog { - + private static final Set CASE_EVENTS_OF_INTEREST = EnumSet.of(Case.Events.CURRENT_CASE, Case.Events.DATA_SOURCE_ADDED, Case.Events.DATA_SOURCE_DELETED); private static final long serialVersionUID = 1L; @@ -116,6 +119,7 @@ final class DiscoveryDialog extends javax.swing.JDialog { add(imageFilterPanel, CENTER); imageFilterPanel.addPropertyChangeListener(listener); updateComboBoxes(); + groupSortingComboBox.setSelectedItem(BY_GROUP_NAME); pack(); repaint(); } @@ -129,6 +133,7 @@ final class DiscoveryDialog extends javax.swing.JDialog { for (FileSearch.GroupingAttributeType type : FileSearch.GroupingAttributeType.getOptionsForGrouping()) { addTypeToGroupByComboBox(type); } + groupByCombobox.setSelectedItem(PARENT_PATH); orderByCombobox.removeAllItems(); // Set up the file order list for (FileSorter.SortingMethod method : FileSorter.SortingMethod.getOptionsForOrdering()) { @@ -136,7 +141,7 @@ final class DiscoveryDialog extends javax.swing.JDialog { orderByCombobox.addItem(method); } } - groupSortingComboBox.setSelectedIndex(0); + orderByCombobox.setSelectedItem(BY_FILE_SIZE); } /** @@ -512,7 +517,7 @@ final class DiscoveryDialog extends javax.swing.JDialog { tc.toFront(); tc.requestActive(); }//GEN-LAST:event_searchButtonActionPerformed - + @Override public void dispose() { setVisible(false); @@ -531,7 +536,8 @@ final class DiscoveryDialog extends javax.swing.JDialog { * The adjust the controls to reflect whether the settings are valid based * on the error. * - * @param error The error message to display, empty string if there is no error. + * @param error The error message to display, empty string if there is no + * error. */ private void setValid(String error) { if (StringUtils.isBlank(error)) { @@ -560,7 +566,7 @@ final class DiscoveryDialog extends javax.swing.JDialog { * filters available. */ private class CasePropertyChangeListener implements PropertyChangeListener { - + @Override @SuppressWarnings("fallthrough") public void propertyChange(PropertyChangeEvent evt) { diff --git a/Core/src/org/sleuthkit/autopsy/discovery/DocumentFilterPanel.java b/Core/src/org/sleuthkit/autopsy/discovery/DocumentFilterPanel.java index 216a3c12b3..fcd26fed08 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/DocumentFilterPanel.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/DocumentFilterPanel.java @@ -34,13 +34,15 @@ final class DocumentFilterPanel extends AbstractFiltersPanel { DocumentFilterPanel() { super(); initComponents(); - addFilter(new SizeFilterPanel(FileSearchData.FileType.DOCUMENTS), false, null, 0); + SizeFilterPanel sizeFilterPanel = new SizeFilterPanel(FILE_TYPE); + int[] sizeIndicesSelected = {3, 4, 5}; + addFilter(sizeFilterPanel, true, sizeIndicesSelected, 0); addFilter(new DataSourceFilterPanel(), false, null, 0); int[] pastOccurrencesIndices; if (!CentralRepository.isEnabled()) { pastOccurrencesIndices = new int[]{0}; } else { - pastOccurrencesIndices = new int[]{1, 2, 3, 4, 5, 6, 7}; + pastOccurrencesIndices = new int[]{2, 3, 4}; } addFilter(new PastOccurrencesFilterPanel(), true, pastOccurrencesIndices, 0); addFilter(new HashSetFilterPanel(), false, null, 1); diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ImageFilterPanel.java b/Core/src/org/sleuthkit/autopsy/discovery/ImageFilterPanel.java index 8eec6dd60f..dfe8a9de31 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/ImageFilterPanel.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ImageFilterPanel.java @@ -35,14 +35,14 @@ final class ImageFilterPanel extends AbstractFiltersPanel { super(); initComponents(); SizeFilterPanel sizeFilterPanel = new SizeFilterPanel(FILE_TYPE); - int[] sizeIndicesSelected = {1, 2, 3, 4, 5}; + int[] sizeIndicesSelected = {3, 4, 5}; addFilter(sizeFilterPanel, true, sizeIndicesSelected, 0); addFilter(new DataSourceFilterPanel(), false, null, 0); int[] pastOccurrencesIndices; if (!CentralRepository.isEnabled()) { pastOccurrencesIndices = new int[]{0}; } else { - pastOccurrencesIndices = new int[]{1, 2, 3, 4, 5, 6, 7}; + pastOccurrencesIndices = new int[]{2, 3, 4}; } addFilter(new PastOccurrencesFilterPanel(), true, pastOccurrencesIndices, 0); addFilter(new UserCreatedFilterPanel(), false, null, 1); diff --git a/Core/src/org/sleuthkit/autopsy/discovery/VideoFilterPanel.java b/Core/src/org/sleuthkit/autopsy/discovery/VideoFilterPanel.java index 4f2684339b..97cd8e818d 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/VideoFilterPanel.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/VideoFilterPanel.java @@ -34,13 +34,15 @@ final class VideoFilterPanel extends AbstractFiltersPanel { VideoFilterPanel() { super(); initComponents(); - addFilter(new SizeFilterPanel(FileSearchData.FileType.VIDEO), false, null, 0); + SizeFilterPanel sizeFilterPanel = new SizeFilterPanel(FILE_TYPE); + int[] sizeIndicesSelected = {3, 4, 5}; + addFilter(sizeFilterPanel, true, sizeIndicesSelected, 0); addFilter(new DataSourceFilterPanel(), false, null, 0); int[] pastOccurrencesIndices; if (!CentralRepository.isEnabled()) { pastOccurrencesIndices = new int[]{0}; } else { - pastOccurrencesIndices = new int[]{1, 2, 3, 4, 5, 6, 7}; + pastOccurrencesIndices = new int[]{2, 3, 4}; } addFilter(new PastOccurrencesFilterPanel(), true, pastOccurrencesIndices, 0); addFilter(new UserCreatedFilterPanel(), false, null, 1); From a6c7b5985bca1cc9d5b6f01f6e071f76c8182fe1 Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Tue, 21 Jul 2020 16:00:44 -0400 Subject: [PATCH 4/4] 6606-Fix default sorting values --- .../org/sleuthkit/autopsy/discovery/DiscoveryDialog.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/discovery/DiscoveryDialog.java b/Core/src/org/sleuthkit/autopsy/discovery/DiscoveryDialog.java index 3da1edd030..216eb3d21e 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/DiscoveryDialog.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/DiscoveryDialog.java @@ -34,11 +34,11 @@ import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoException; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.discovery.FileGroup.GroupSortingAlgorithm; -import static org.sleuthkit.autopsy.discovery.FileGroup.GroupSortingAlgorithm.BY_GROUP_NAME; +import static org.sleuthkit.autopsy.discovery.FileGroup.GroupSortingAlgorithm.BY_GROUP_SIZE; import org.sleuthkit.autopsy.discovery.FileSearch.GroupingAttributeType; import static org.sleuthkit.autopsy.discovery.FileSearch.GroupingAttributeType.PARENT_PATH; import org.sleuthkit.autopsy.discovery.FileSorter.SortingMethod; -import static org.sleuthkit.autopsy.discovery.FileSorter.SortingMethod.BY_FILE_SIZE; +import static org.sleuthkit.autopsy.discovery.FileSorter.SortingMethod.BY_FILE_NAME; /** * Dialog for displaying the controls and filters for configuration of a @@ -119,7 +119,7 @@ final class DiscoveryDialog extends javax.swing.JDialog { add(imageFilterPanel, CENTER); imageFilterPanel.addPropertyChangeListener(listener); updateComboBoxes(); - groupSortingComboBox.setSelectedItem(BY_GROUP_NAME); + groupSortingComboBox.setSelectedItem(BY_GROUP_SIZE); pack(); repaint(); } @@ -141,7 +141,7 @@ final class DiscoveryDialog extends javax.swing.JDialog { orderByCombobox.addItem(method); } } - orderByCombobox.setSelectedItem(BY_FILE_SIZE); + orderByCombobox.setSelectedItem(BY_FILE_NAME); } /**