From 40262bfc573489bc7fb31cc77803cd827f7d12c4 Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Tue, 2 Oct 2018 14:30:15 -0400 Subject: [PATCH 1/3] 4273 make common property search have main window as parent --- .../autopsy/commonfilesearch/CommonAttributePanel.java | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributePanel.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributePanel.java index ff83f062c8..3608ca7c4c 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributePanel.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributePanel.java @@ -79,11 +79,9 @@ final class CommonAttributePanel extends javax.swing.JDialog implements Observer "CommonAttributePanel.title=Common Property Panel", "CommonAttributePanel.exception=Unexpected Exception loading DataSources.", "CommonAttributePanel.frame.title=Find Common Properties", - "CommonAttributePanel.frame.msg=Find Common Properties", "CommonAttributePanel.intraCasePanel.title=Curren Case Options"}) CommonAttributePanel() { - super(new JFrame(Bundle.CommonAttributePanel_frame_title()), - Bundle.CommonAttributePanel_frame_msg(), true); + super(WindowManager.getDefault().getMainWindow(), Bundle.CommonAttributePanel_frame_title(), true); initComponents(); this.setLocationRelativeTo(WindowManager.getDefault().getMainWindow()); this.setupDataSources(); @@ -646,7 +644,7 @@ final class CommonAttributePanel extends javax.swing.JDialog implements Observer }// //GEN-END:initComponents private void formWindowClosed(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowClosed - SwingUtilities.windowForComponent(this).dispose(); + this.dispose(); }//GEN-LAST:event_formWindowClosed private void percentageThresholdCheckActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_percentageThresholdCheckActionPerformed @@ -671,7 +669,7 @@ final class CommonAttributePanel extends javax.swing.JDialog implements Observer private void searchButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_searchButtonActionPerformed search(); - SwingUtilities.windowForComponent(this).dispose(); + this.dispose(); }//GEN-LAST:event_searchButtonActionPerformed /** From d4fb2ec8cc0696fe919f2639838e03a68423059b Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Tue, 2 Oct 2018 16:08:58 -0400 Subject: [PATCH 2/3] 4273 - notify user when performing cr search with data sources that are not in CR --- .../ingestmodule/IngestModuleFactory.java | 2 +- .../CommonAttributePanel.java | 110 +++++++++++++++++- 2 files changed, 108 insertions(+), 4 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/IngestModuleFactory.java b/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/IngestModuleFactory.java index 2f732ac60f..fc5dcd9c81 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/IngestModuleFactory.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/IngestModuleFactory.java @@ -42,7 +42,7 @@ public class IngestModuleFactory extends IngestModuleFactoryAdapter { * * @return The module name. */ - static String getModuleName() { + public static String getModuleName() { return Bundle.IngestModuleFactory_ingestmodule_name(); } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributePanel.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributePanel.java index 3608ca7c4c..d9df698366 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributePanel.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributePanel.java @@ -30,22 +30,25 @@ import java.util.Observable; import java.util.Observer; import java.util.concurrent.ExecutionException; import java.util.logging.Level; -import javax.swing.JFrame; -import javax.swing.SwingUtilities; import javax.swing.SwingWorker; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import org.netbeans.api.progress.ProgressHandle; +import org.openide.DialogDisplayer; +import org.openide.NotifyDescriptor; import org.openide.explorer.ExplorerManager; import org.openide.nodes.Node; import org.openide.util.NbBundle; +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.CorrelationAttributeInstance; import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationCase; +import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationDataSource; import org.sleuthkit.autopsy.centralrepository.datamodel.EamDb; import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException; +import org.sleuthkit.autopsy.centralrepository.ingestmodule.IngestModuleFactory; import org.sleuthkit.autopsy.corecomponentinterfaces.DataResultViewer; import org.sleuthkit.autopsy.corecomponents.DataResultTopComponent; import org.sleuthkit.autopsy.corecomponents.DataResultViewerTable; @@ -54,6 +57,10 @@ import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil; import org.sleuthkit.autopsy.datamodel.EmptyNode; import org.sleuthkit.autopsy.directorytree.DataResultFilterNode; +import org.sleuthkit.datamodel.DataSource; +import org.sleuthkit.datamodel.IngestJobInfo; +import org.sleuthkit.datamodel.IngestModuleInfo; +import org.sleuthkit.datamodel.SleuthkitCase; import org.sleuthkit.datamodel.TskCoreException; /** @@ -668,10 +675,102 @@ final class CommonAttributePanel extends javax.swing.JDialog implements Observer }//GEN-LAST:event_intraCaseRadioActionPerformed private void searchButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_searchButtonActionPerformed - search(); + checkDataSourcesAndSearch(); this.dispose(); }//GEN-LAST:event_searchButtonActionPerformed + /** + * If the settings reflect that a inter-case search is being performed, + * checks that the data sources in the current case have been processed with + * Correlation Engine enabled and exist in the central repository. Promting + * the user as to whether they still want to perform the search in the case + * any data sources are unprocessed. If the settings reflect that a + * intra-case search is being performed, it just performs the search. + * + * Notes: - Does not check that the data sources were processed into the + * current central repository instead of another. - Does not check that the + * appropriate modules to make all correlation types available were run. - + * Does not check if the correlation engine was run with any of the + * correlation properties properties disabled. + */ + @Messages({"CommonAttributePanel.incompleteResults.introText=Results may be incomplete. Not all data sources in the current case were ingested into the current Central Repository. The following data sources have not been processed:", + "CommonAttributePanel.incompleteResults.continueText=\n\n Continue with search anyway?", + "CommonAttributePanel.incompleteResults.title=Search may be incomplete" + }) + private void checkDataSourcesAndSearch() { + new SwingWorker, Void>() { + //if the eamdb is enabled and an instance is able to be retrieved check if each data source has been processed into the cr + @Override + protected List doInBackground() throws Exception { + List unCorrelatedDataSources = new ArrayList<>(); + if (interCaseRadio.isSelected()) { + if (EamDb.isEnabled() && EamDb.getInstance() != null) { + HashMap dataSourceCorrelationMap = new HashMap<>(); //keep track of the status of all data sources that have been ingested + String correlationEngineModuleName = IngestModuleFactory.getModuleName(); + SleuthkitCase skCase = Case.getCurrentCaseThrows().getSleuthkitCase(); + List correlatedDataSources = EamDb.getInstance().getDataSources(); + List ingestJobs = skCase.getIngestJobs(); + for (IngestJobInfo jobInfo : ingestJobs) { + //get the data source for each ingest job + DataSource dataSource = skCase.getDataSource(jobInfo.getObjectId()); + String deviceID = dataSource.getDeviceId(); + //add its status as not_correlated for now if this is the first time the data source was processed + dataSourceCorrelationMap.putIfAbsent(dataSource, CorrelatedStatus.NOT_CORRELATED); + if (dataSourceCorrelationMap.get(dataSource) == CorrelatedStatus.NOT_CORRELATED) { + //if the datasource was previously processed we do not need to perform this check + for (CorrelationDataSource correlatedDataSource : correlatedDataSources) { + if (deviceID.equals(correlatedDataSource.getDeviceID())) { + //if the datasource exists in the central repository it may of been processed with the correlation engine + dataSourceCorrelationMap.put(dataSource, CorrelatedStatus.IN_CENTRAL_REPO); + break; + } + } + } + if (dataSourceCorrelationMap.get(dataSource) == CorrelatedStatus.IN_CENTRAL_REPO) { + //if the data source was in the central repository check if any of the modules run on it were the correlation engine + for (IngestModuleInfo ingestModuleInfo : jobInfo.getIngestModuleInfo()) { + if (correlationEngineModuleName.equals(ingestModuleInfo.getDisplayName())) { + dataSourceCorrelationMap.put(dataSource, CorrelatedStatus.CORRELATED); + break; + } + } + } + } + //convert the keys of the map which have not been correlated to a list + for (DataSource dataSource : dataSourceCorrelationMap.keySet()) { + if (dataSourceCorrelationMap.get(dataSource) != CorrelatedStatus.CORRELATED) { + unCorrelatedDataSources.add(dataSource.getName()); + } + } + } + } + return unCorrelatedDataSources; + } + + @Override + protected void done() { + super.done(); + try { + List unProcessedDataSources = get(); + boolean performSearch = true; + if (!unProcessedDataSources.isEmpty()) { + String warning = Bundle.CommonAttributePanel_incompleteResults_introText(); + warning = unProcessedDataSources.stream().map((dataSource) -> "\n - " + dataSource).reduce(warning, String::concat); + warning += Bundle.CommonAttributePanel_incompleteResults_continueText(); + //let user know which data sources in the current case were not processed into a central repository + NotifyDescriptor descriptor = new NotifyDescriptor.Confirmation(warning, Bundle.CommonAttributePanel_incompleteResults_title(), NotifyDescriptor.YES_NO_OPTION); + performSearch = DialogDisplayer.getDefault().notify(descriptor) == NotifyDescriptor.YES_OPTION; + } + if (performSearch) { + search(); + } + } catch (InterruptedException | ExecutionException ex) { + LOGGER.log(Level.SEVERE, "Unexpected exception while performing common property search", ex); //NON-NLS + } + } + }.execute(); + } + /** * Convert the text in the percentage threshold input box into an integer, * -1 is used when the string can not be converted to an integer. @@ -791,4 +890,9 @@ final class CommonAttributePanel extends javax.swing.JDialog implements Observer this.updateErrorTextAndSearchButton(); } + private enum CorrelatedStatus { + NOT_CORRELATED, + IN_CENTRAL_REPO, + CORRELATED + } } From eb4bdcd39fe64b747f9926f26eb00606f66428b7 Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Thu, 4 Oct 2018 15:04:47 -0400 Subject: [PATCH 3/3] 4273 adjust CommonAttributePanel regarding PR comments --- .../CommonAttributePanel.java | 78 ++++++++++--------- 1 file changed, 41 insertions(+), 37 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributePanel.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributePanel.java index d9df698366..31a10c96cb 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributePanel.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributePanel.java @@ -682,7 +682,7 @@ final class CommonAttributePanel extends javax.swing.JDialog implements Observer /** * If the settings reflect that a inter-case search is being performed, * checks that the data sources in the current case have been processed with - * Correlation Engine enabled and exist in the central repository. Promting + * Correlation Engine enabled and exist in the central repository. Prompting * the user as to whether they still want to perform the search in the case * any data sources are unprocessed. If the settings reflect that a * intra-case search is being performed, it just performs the search. @@ -699,51 +699,51 @@ final class CommonAttributePanel extends javax.swing.JDialog implements Observer }) private void checkDataSourcesAndSearch() { new SwingWorker, Void>() { - //if the eamdb is enabled and an instance is able to be retrieved check if each data source has been processed into the cr + @Override protected List doInBackground() throws Exception { List unCorrelatedDataSources = new ArrayList<>(); - if (interCaseRadio.isSelected()) { - if (EamDb.isEnabled() && EamDb.getInstance() != null) { - HashMap dataSourceCorrelationMap = new HashMap<>(); //keep track of the status of all data sources that have been ingested - String correlationEngineModuleName = IngestModuleFactory.getModuleName(); - SleuthkitCase skCase = Case.getCurrentCaseThrows().getSleuthkitCase(); - List correlatedDataSources = EamDb.getInstance().getDataSources(); - List ingestJobs = skCase.getIngestJobs(); - for (IngestJobInfo jobInfo : ingestJobs) { - //get the data source for each ingest job - DataSource dataSource = skCase.getDataSource(jobInfo.getObjectId()); - String deviceID = dataSource.getDeviceId(); - //add its status as not_correlated for now if this is the first time the data source was processed - dataSourceCorrelationMap.putIfAbsent(dataSource, CorrelatedStatus.NOT_CORRELATED); - if (dataSourceCorrelationMap.get(dataSource) == CorrelatedStatus.NOT_CORRELATED) { - //if the datasource was previously processed we do not need to perform this check - for (CorrelationDataSource correlatedDataSource : correlatedDataSources) { - if (deviceID.equals(correlatedDataSource.getDeviceID())) { - //if the datasource exists in the central repository it may of been processed with the correlation engine - dataSourceCorrelationMap.put(dataSource, CorrelatedStatus.IN_CENTRAL_REPO); - break; - } - } - } - if (dataSourceCorrelationMap.get(dataSource) == CorrelatedStatus.IN_CENTRAL_REPO) { - //if the data source was in the central repository check if any of the modules run on it were the correlation engine - for (IngestModuleInfo ingestModuleInfo : jobInfo.getIngestModuleInfo()) { - if (correlationEngineModuleName.equals(ingestModuleInfo.getDisplayName())) { - dataSourceCorrelationMap.put(dataSource, CorrelatedStatus.CORRELATED); - break; - } - } + if (!interCaseRadio.isSelected() || !EamDb.isEnabled() || EamDb.getInstance() == null) { + return unCorrelatedDataSources; + } + //if the eamdb is enabled and an instance is able to be retrieved check if each data source has been processed into the cr + HashMap dataSourceCorrelationMap = new HashMap<>(); //keep track of the status of all data sources that have been ingested + String correlationEngineModuleName = IngestModuleFactory.getModuleName(); + SleuthkitCase skCase = Case.getCurrentCaseThrows().getSleuthkitCase(); + List correlatedDataSources = EamDb.getInstance().getDataSources(); + List ingestJobs = skCase.getIngestJobs(); + for (IngestJobInfo jobInfo : ingestJobs) { + //get the data source for each ingest job + DataSource dataSource = skCase.getDataSource(jobInfo.getObjectId()); + String deviceID = dataSource.getDeviceId(); + //add its status as not_correlated for now if this is the first time the data source was processed + dataSourceCorrelationMap.putIfAbsent(dataSource, CorrelatedStatus.NOT_CORRELATED); + if (dataSourceCorrelationMap.get(dataSource) == CorrelatedStatus.NOT_CORRELATED) { + //if the datasource was previously processed we do not need to perform this check + for (CorrelationDataSource correlatedDataSource : correlatedDataSources) { + if (deviceID.equals(correlatedDataSource.getDeviceID())) { + //if the datasource exists in the central repository it may of been processed with the correlation engine + dataSourceCorrelationMap.put(dataSource, CorrelatedStatus.IN_CENTRAL_REPO); + break; } } - //convert the keys of the map which have not been correlated to a list - for (DataSource dataSource : dataSourceCorrelationMap.keySet()) { - if (dataSourceCorrelationMap.get(dataSource) != CorrelatedStatus.CORRELATED) { - unCorrelatedDataSources.add(dataSource.getName()); + } + if (dataSourceCorrelationMap.get(dataSource) == CorrelatedStatus.IN_CENTRAL_REPO) { + //if the data source was in the central repository check if any of the modules run on it were the correlation engine + for (IngestModuleInfo ingestModuleInfo : jobInfo.getIngestModuleInfo()) { + if (correlationEngineModuleName.equals(ingestModuleInfo.getDisplayName())) { + dataSourceCorrelationMap.put(dataSource, CorrelatedStatus.CORRELATED); + break; } } } } + //convert the keys of the map which have not been correlated to a list + for (DataSource dataSource : dataSourceCorrelationMap.keySet()) { + if (dataSourceCorrelationMap.get(dataSource) != CorrelatedStatus.CORRELATED) { + unCorrelatedDataSources.add(dataSource.getName()); + } + } return unCorrelatedDataSources; } @@ -890,6 +890,10 @@ final class CommonAttributePanel extends javax.swing.JDialog implements Observer this.updateErrorTextAndSearchButton(); } + /** + * Enum for keeping track of which data sources in the case have not been + * processed into the central repository. + */ private enum CorrelatedStatus { NOT_CORRELATED, IN_CENTRAL_REPO,