From 344bdbb304f52c138fa3461bc7619ced70e0d4a5 Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Mon, 30 Apr 2018 08:31:36 -0600 Subject: [PATCH 001/287] first pass at ui --- .../commonfilesearch/Bundle.properties | 12 +- .../commonfilesearch/CommonFilesPanel.form | 192 ++++++++++++++---- .../commonfilesearch/CommonFilesPanel.java | 162 +++++++++++---- 3 files changed, 281 insertions(+), 85 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/Bundle.properties b/Core/src/org/sleuthkit/autopsy/commonfilesearch/Bundle.properties index 72ddffb748..e9ba24bc1e 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/Bundle.properties @@ -1,15 +1,21 @@ CommonFilesPanel.searchButton.text=Search -CommonFilesPanel.withinDataSourceRadioButton.text=At least one instance of a given MD5 must appear in the data source selected below: -CommonFilesPanel.allDataSourcesRadioButton.text=Files can be in any data source +CommonFilesPanel.withinDataSourceRadioButton.text=At least one match must appear in the data source selected below: +CommonFilesPanel.allDataSourcesRadioButton.text=Matches may be from any data source CommonFilesPanel.cancelButton.text=Cancel CommonFilesPanel.cancelButton.actionCommand=Cancel CommonFilesPanel.selectedFileCategoriesButton.text=Match on the following file categories: CommonFilesPanel.selectedFileCategoriesButton.toolTipText=Select from the options below... CommonFilesPanel.pictureVideoCheckbox.text=Pictures and Videos CommonFilesPanel.documentsCheckbox.text=Documents -CommonFilesPanel.commonFilesSearchLabel.text=Find duplicate files in the current case. CommonFilesPanel.allFileCategoriesRadioButton.toolTipText=No filtering applied to results... CommonFilesPanel.allFileCategoriesRadioButton.text=Match on all file types CommonFilesPanel.text=Indicate which data sources to consider while searching for duplicates: CommonFilesPanel.categoriesLabel.text=Indicate which file types to include in results: CommonFilesPanel.errorText.text=In order to search, you must select a file category. +CommonFilesPanel.commonFilesSearchLabel1.text=Find Common Files. +CommonFilesPanel.jRadioButton1.text=jRadioButton1 +CommonFilesPanel.jRadioButton2.text=Correlate amongst external cases (compares files in current case with Central Repo) +CommonFilesPanel.intraCaseRadio.label=Correlate within current case only +CommonFilesPanel.interCaseRadio.label=Correlate amongst all known cases (uses Central Repo) +CommonFilesPanel.anCentralRepoCaseRadio.text_1=Matches may be from any Central Repo case +CommonFilesPanel.specificCentralRepoCaseRadio.text_1=Matches must be from the following Central Repo case: diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.form b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.form index c9d08c0536..c617d77864 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.form +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.form @@ -6,6 +6,10 @@ + + + + @@ -23,45 +27,77 @@ - - - - - - - - - - - + + - - - - + + - - + + + + + + + + + + + + + + + + + + - - - - + + + + + + + + + + + + + + + + + + - - + + + + + + - + + + + + + + + + + @@ -69,16 +105,24 @@ - - - + + + - + + + + + + + + + @@ -94,6 +138,7 @@ + @@ -116,7 +161,6 @@ - @@ -154,14 +198,6 @@ - - - - - - - - @@ -231,14 +267,6 @@ - - - - - - - - @@ -257,5 +285,79 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java index cfcdf7003b..73c2e7a7ed 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java @@ -330,19 +330,25 @@ public final class CommonFilesPanel extends javax.swing.JPanel { dataSourcesButtonGroup = new javax.swing.ButtonGroup(); fileTypeFilterButtonGroup = new javax.swing.ButtonGroup(); + interIntraButtonGroup = new javax.swing.ButtonGroup(); + caseSelectionButtonGroup = new javax.swing.ButtonGroup(); searchButton = new javax.swing.JButton(); allDataSourcesRadioButton = new javax.swing.JRadioButton(); withinDataSourceRadioButton = new javax.swing.JRadioButton(); selectDataSourceComboBox = new javax.swing.JComboBox<>(); - commonFilesSearchLabel = new javax.swing.JLabel(); cancelButton = new javax.swing.JButton(); allFileCategoriesRadioButton = new javax.swing.JRadioButton(); selectedFileCategoriesButton = new javax.swing.JRadioButton(); pictureVideoCheckbox = new javax.swing.JCheckBox(); documentsCheckbox = new javax.swing.JCheckBox(); - dataSourceLabel = new javax.swing.JLabel(); categoriesLabel = new javax.swing.JLabel(); errorText = new javax.swing.JLabel(); + commonFilesSearchLabel1 = new javax.swing.JLabel(); + intraCaseRadio = new javax.swing.JRadioButton(); + interCaseRadio = new javax.swing.JRadioButton(); + anCentralRepoCaseRadio = new javax.swing.JRadioButton(); + specificCentralRepoCaseRadio = new javax.swing.JRadioButton(); + caseComboBox = new javax.swing.JComboBox<>(); org.openide.awt.Mnemonics.setLocalizedText(searchButton, org.openide.util.NbBundle.getMessage(CommonFilesPanel.class, "CommonFilesPanel.searchButton.text")); // NOI18N searchButton.setEnabled(false); @@ -354,7 +360,6 @@ public final class CommonFilesPanel extends javax.swing.JPanel { }); dataSourcesButtonGroup.add(allDataSourcesRadioButton); - allDataSourcesRadioButton.setSelected(true); org.openide.awt.Mnemonics.setLocalizedText(allDataSourcesRadioButton, org.openide.util.NbBundle.getMessage(CommonFilesPanel.class, "CommonFilesPanel.allDataSourcesRadioButton.text")); // NOI18N allDataSourcesRadioButton.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); allDataSourcesRadioButton.addActionListener(new java.awt.event.ActionListener() { @@ -380,9 +385,6 @@ public final class CommonFilesPanel extends javax.swing.JPanel { } }); - org.openide.awt.Mnemonics.setLocalizedText(commonFilesSearchLabel, org.openide.util.NbBundle.getMessage(CommonFilesPanel.class, "CommonFilesPanel.commonFilesSearchLabel.text")); // NOI18N - commonFilesSearchLabel.setFocusable(false); - org.openide.awt.Mnemonics.setLocalizedText(cancelButton, org.openide.util.NbBundle.getMessage(CommonFilesPanel.class, "CommonFilesPanel.cancelButton.text")); // NOI18N cancelButton.setActionCommand(org.openide.util.NbBundle.getMessage(CommonFilesPanel.class, "CommonFilesPanel.cancelButton.actionCommand")); // NOI18N cancelButton.setHorizontalTextPosition(javax.swing.SwingConstants.LEADING); @@ -427,65 +429,123 @@ public final class CommonFilesPanel extends javax.swing.JPanel { } }); - org.openide.awt.Mnemonics.setLocalizedText(dataSourceLabel, org.openide.util.NbBundle.getMessage(CommonFilesPanel.class, "CommonFilesPanel.text")); // NOI18N - dataSourceLabel.setName(""); // NOI18N - org.openide.awt.Mnemonics.setLocalizedText(categoriesLabel, org.openide.util.NbBundle.getMessage(CommonFilesPanel.class, "CommonFilesPanel.categoriesLabel.text")); // NOI18N categoriesLabel.setName(""); // NOI18N errorText.setForeground(new java.awt.Color(255, 0, 0)); org.openide.awt.Mnemonics.setLocalizedText(errorText, org.openide.util.NbBundle.getMessage(CommonFilesPanel.class, "CommonFilesPanel.errorText.text")); // NOI18N + org.openide.awt.Mnemonics.setLocalizedText(commonFilesSearchLabel1, org.openide.util.NbBundle.getMessage(CommonFilesPanel.class, "CommonFilesPanel.commonFilesSearchLabel1.text")); // NOI18N + commonFilesSearchLabel1.setFocusable(false); + + interIntraButtonGroup.add(intraCaseRadio); + intraCaseRadio.setSelected(true); + intraCaseRadio.setLabel(org.openide.util.NbBundle.getMessage(CommonFilesPanel.class, "CommonFilesPanel.intraCaseRadio.label")); // NOI18N + intraCaseRadio.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + intraCaseRadioActionPerformed(evt); + } + }); + + interIntraButtonGroup.add(interCaseRadio); + org.openide.awt.Mnemonics.setLocalizedText(interCaseRadio, org.openide.util.NbBundle.getMessage(CommonFilesPanel.class, "CommonFilesPanel.jRadioButton2.text")); // NOI18N + interCaseRadio.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + interCaseRadioActionPerformed(evt); + } + }); + + caseSelectionButtonGroup.add(anCentralRepoCaseRadio); + anCentralRepoCaseRadio.setSelected(true); + org.openide.awt.Mnemonics.setLocalizedText(anCentralRepoCaseRadio, org.openide.util.NbBundle.getMessage(CommonFilesPanel.class, "CommonFilesPanel.anCentralRepoCaseRadio.text_1")); // NOI18N + anCentralRepoCaseRadio.setEnabled(false); + + caseSelectionButtonGroup.add(specificCentralRepoCaseRadio); + org.openide.awt.Mnemonics.setLocalizedText(specificCentralRepoCaseRadio, org.openide.util.NbBundle.getMessage(CommonFilesPanel.class, "CommonFilesPanel.specificCentralRepoCaseRadio.text_1")); // NOI18N + specificCentralRepoCaseRadio.setEnabled(false); + + caseComboBox.setModel(new javax.swing.DefaultComboBoxModel<>(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" })); + caseComboBox.setEnabled(false); + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() - .addContainerGap() - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() - .addComponent(errorText) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(searchButton) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(cancelButton) - .addContainerGap()) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(categoriesLabel) - .addComponent(commonFilesSearchLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(dataSourceLabel) .addGroup(layout.createSequentialGroup() - .addGap(6, 6, 6) + .addContainerGap() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(commonFilesSearchLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addGroup(layout.createSequentialGroup() - .addGap(29, 29, 29) - .addComponent(selectDataSourceComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 261, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addComponent(withinDataSourceRadioButton) - .addComponent(allDataSourcesRadioButton) - .addComponent(allFileCategoriesRadioButton) - .addComponent(selectedFileCategoriesButton) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(categoriesLabel) + .addGroup(layout.createSequentialGroup() + .addGap(6, 6, 6) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(allFileCategoriesRadioButton) + .addComponent(selectedFileCategoriesButton) + .addGroup(layout.createSequentialGroup() + .addGap(21, 21, 21) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(pictureVideoCheckbox) + .addComponent(documentsCheckbox)))))) + .addGap(277, 277, 277)) + .addComponent(intraCaseRadio) .addGroup(layout.createSequentialGroup() .addGap(21, 21, 21) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(pictureVideoCheckbox) - .addComponent(documentsCheckbox)))))) - .addGap(19, 19, 19)))) + .addComponent(withinDataSourceRadioButton) + .addComponent(allDataSourcesRadioButton))))) + .addGroup(layout.createSequentialGroup() + .addGap(47, 47, 47) + .addComponent(selectDataSourceComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 261, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(interCaseRadio) + .addGroup(layout.createSequentialGroup() + .addGap(21, 21, 21) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(anCentralRepoCaseRadio) + .addComponent(specificCentralRepoCaseRadio) + .addGroup(layout.createSequentialGroup() + .addGap(21, 21, 21) + .addComponent(caseComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 261, javax.swing.GroupLayout.PREFERRED_SIZE))))))) + .addGap(0, 0, Short.MAX_VALUE)) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addGap(0, 0, Short.MAX_VALUE) + .addComponent(errorText) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(searchButton) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(cancelButton))) + .addContainerGap()) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() .addContainerGap() - .addComponent(commonFilesSearchLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(commonFilesSearchLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addGap(18, 18, 18) - .addComponent(dataSourceLabel) + .addComponent(intraCaseRadio) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(allDataSourcesRadioButton) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(withinDataSourceRadioButton) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(selectDataSourceComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGap(18, 18, 18) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(interCaseRadio) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(anCentralRepoCaseRadio) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(specificCentralRepoCaseRadio) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(caseComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(categoriesLabel) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(selectedFileCategoriesButton) @@ -499,7 +559,8 @@ public final class CommonFilesPanel extends javax.swing.JPanel { .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(cancelButton) .addComponent(searchButton) - .addComponent(errorText))) + .addComponent(errorText)) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); }// //GEN-END:initComponents @@ -548,6 +609,27 @@ public final class CommonFilesPanel extends javax.swing.JPanel { this.toggleErrorTextAndSearchBox(); }//GEN-LAST:event_documentsCheckboxActionPerformed + private void intraCaseRadioActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_intraCaseRadioActionPerformed + this.allDataSourcesRadioButton.setEnabled(true); + this.withinDataSourceRadioButton.setEnabled(true); + this.selectDataSourceComboBox.setEnabled(true); + + this.anCentralRepoCaseRadio.setEnabled(false); + this.specificCentralRepoCaseRadio.setEnabled(false); + this.caseComboBox.setEnabled(false); + }//GEN-LAST:event_intraCaseRadioActionPerformed + + private void interCaseRadioActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_interCaseRadioActionPerformed + this.anCentralRepoCaseRadio.setEnabled(true); + this.specificCentralRepoCaseRadio.setEnabled(true); + this.caseComboBox.setEnabled(true); + + this.allDataSourcesRadioButton.setEnabled(false); + this.withinDataSourceRadioButton.setEnabled(false); + this.selectDataSourceComboBox.setEnabled(false); + + }//GEN-LAST:event_interCaseRadioActionPerformed + private void toggleErrorTextAndSearchBox() { if (!this.pictureVideoCheckbox.isSelected() && !this.documentsCheckbox.isSelected() && !this.allFileCategoriesRadioButton.isSelected()) { this.searchButton.setEnabled(false); @@ -590,18 +672,24 @@ public final class CommonFilesPanel extends javax.swing.JPanel { // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JRadioButton allDataSourcesRadioButton; private javax.swing.JRadioButton allFileCategoriesRadioButton; + private javax.swing.JRadioButton anCentralRepoCaseRadio; private javax.swing.JButton cancelButton; + private javax.swing.JComboBox caseComboBox; + private javax.swing.ButtonGroup caseSelectionButtonGroup; private javax.swing.JLabel categoriesLabel; - private javax.swing.JLabel commonFilesSearchLabel; - private javax.swing.JLabel dataSourceLabel; + private javax.swing.JLabel commonFilesSearchLabel1; private javax.swing.ButtonGroup dataSourcesButtonGroup; private javax.swing.JCheckBox documentsCheckbox; private javax.swing.JLabel errorText; private javax.swing.ButtonGroup fileTypeFilterButtonGroup; + private javax.swing.JRadioButton interCaseRadio; + private javax.swing.ButtonGroup interIntraButtonGroup; + private javax.swing.JRadioButton intraCaseRadio; private javax.swing.JCheckBox pictureVideoCheckbox; private javax.swing.JButton searchButton; private javax.swing.JComboBox selectDataSourceComboBox; private javax.swing.JRadioButton selectedFileCategoriesButton; + private javax.swing.JRadioButton specificCentralRepoCaseRadio; private javax.swing.JRadioButton withinDataSourceRadioButton; // End of variables declaration//GEN-END:variables } From 204b24f0c25ae840b57cc071d9b79d77f4951ff1 Mon Sep 17 00:00:00 2001 From: Andrew Ziehl Date: Mon, 7 May 2018 20:17:54 -0700 Subject: [PATCH 002/287] WIP intercase correlation changes. Needs abstraction and some refactoring. Also need a new class based on CorrelationAttributeInstance, which includes the value (md5) returned from the EamDB as part of the query results. --- .../datamodel/AbstractSqlEamDb.java | 76 +++++++++++++++++++ .../centralrepository/datamodel/EamDb.java | 13 +++- .../datamodel/PostgresEamDb.java | 1 + .../datamodel/SqliteEamDb.java | 19 +++++ .../CommonFilesMetadataBuilder.java | 56 ++++++++++++++ 5 files changed, 164 insertions(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java index a6e078f565..d521332b4c 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java @@ -647,6 +647,82 @@ public abstract class AbstractSqlEamDb implements EamDb { return artifactInstances; } + /** + * TODO, shares code with getArtifactInstancesByTypeValue, refactor and abstract + * Retrieves eamArtiifact instances from the database that match the given + * list of MD5 values; + * + * @param correlationCase Case id to search on + * @param values List of ArtifactInstance MD5 values to find matches of. + * + * @return List of artifact instances for a given list of MD5 values + */ + public List getArtifactInstancesByCaseValues(CorrelationCase correlationCase, List values) throws EamDbException { + CorrelationAttribute.Type aType = CorrelationAttribute.getDefaultCorrelationTypes().get(0); // Files type + if(aType == null) { + throw new EamDbException("Correlation Type is null"); + } + boolean singleCase = false; + if (correlationCase != null) { + singleCase = false; + } + Connection conn = connect(); + + List artifactInstances = new ArrayList<>(); + + CorrelationAttributeInstance artifactInstance; + PreparedStatement preparedStatement = null; + ResultSet resultSet = null; + + String valuesString = ""; + StringBuilder valuesFilter = new StringBuilder(values.size()); + if (!values.isEmpty()) { + for (String value : values) { + valuesFilter.append("'").append(value).append("',"); + } + valuesString = valuesFilter.toString().substring(0, valuesFilter.length() - 1); + } + + String tableName = EamDbUtil.correlationTypeToInstanceTableName(aType); + StringBuilder sql = new StringBuilder(9); + sql.append("SELECT cases.case_name, cases.case_uid, data_sources.name, device_id, file_path, known_status, comment, data_sources.case_id, value FROM "); + sql.append(tableName); + sql.append(" LEFT JOIN cases ON "); + sql.append(tableName); + sql.append(".case_id=cases.id"); + sql.append(" LEFT JOIN data_sources ON "); + sql.append(tableName); + sql.append(".data_source_id=data_sources.id"); + sql.append(" WHERE value IN (?)"); + if(singleCase) { + sql.append(" AND "); + sql.append(tableName); + sql.append(".case_id = ?"); + } + + try { + preparedStatement = conn.prepareStatement(sql.toString()); + preparedStatement.setString(1, valuesString); + if(singleCase) { + preparedStatement.setString(2, String.valueOf(correlationCase.getID())); + } + + resultSet = preparedStatement.executeQuery(); + while (resultSet.next()) { + artifactInstance = getEamArtifactInstanceFromResultSet(resultSet); + artifactInstances.add(artifactInstance); + } + } catch (SQLException ex) { + throw new EamDbException("Error getting artifact instances by artifactType and artifactValue.", ex); // NON-NLS + } finally { + EamDbUtil.closePreparedStatement(preparedStatement); + EamDbUtil.closeResultSet(resultSet); + EamDbUtil.closeConnection(conn); + } + + return artifactInstances; + } + /** * Retrieves eamArtifact instances from the database that are associated * with the aType and filePath diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDb.java index 2b05cb1d70..0ffd8c508b 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDb.java @@ -178,7 +178,7 @@ public interface EamDb { * @return List of cases */ List getCases() throws EamDbException; - + /** * Creates new Data Source in the database * @@ -223,6 +223,17 @@ public interface EamDb { */ List getArtifactInstancesByTypeValue(CorrelationAttribute.Type aType, String value) throws EamDbException; + /** + * Retrieves eamArtiifact instances from the database that match the given + * list of MD5 values; + * + * @param correlationCase Case id to search on + * @param values List of ArtifactInstance MD5 values to find matches of. + * + * @return List of artifact instances for a given list of MD5 values + */ + List getArtifactInstancesByCaseValues(CorrelationCase correlationCase, List values) throws EamDbException; + /** * Retrieves eamArtifact instances from the database that are associated * with the aType and filePath diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresEamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresEamDb.java index 46d579ad87..af57e6afa9 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresEamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresEamDb.java @@ -21,6 +21,7 @@ package org.sleuthkit.autopsy.centralrepository.datamodel; import java.sql.Connection; import java.sql.SQLException; import java.sql.Statement; +import java.util.List; import java.util.concurrent.TimeUnit; import java.util.logging.Level; import org.apache.commons.dbcp2.BasicDataSource; diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java index d9d1ea2fa3..4ff827a68e 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java @@ -419,6 +419,25 @@ public class SqliteEamDb extends AbstractSqlEamDb { } } + + /** + * Retrieves eamArtiifact instances from the database that match the given + * list of MD5 values; + * + * @param correlationCase Case id to search on + * @param values List of ArtifactInstance MD5 values to find matches of. + * + * @return List of artifact instances for a given list of MD5 values + */ + public List getArtifactInstancesByCaseValues(CorrelationCase correlationCase, List values) throws EamDbException { + try{ + acquireSharedLock(); + return super.getArtifactInstancesByCaseValues(correlationCase, values); + } finally { + releaseSharedLock(); + } + } + /** * Retrieves eamArtifact instances from the database that are associated * with the aType and filePath diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesMetadataBuilder.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesMetadataBuilder.java index 8abab90380..0888c5c129 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesMetadataBuilder.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesMetadataBuilder.java @@ -22,16 +22,24 @@ package org.sleuthkit.autopsy.commonfilesearch; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.logging.Level; import java.util.stream.Collectors; import java.util.stream.Stream; import org.openide.util.NbBundle; 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.EamDb; +import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException; +import static org.sleuthkit.autopsy.timeline.datamodel.eventtype.ArtifactEventType.LOGGER; import org.sleuthkit.datamodel.HashUtility; import org.sleuthkit.datamodel.SleuthkitCase; import org.sleuthkit.datamodel.SleuthkitCase.CaseDbQuery; @@ -201,6 +209,54 @@ abstract class CommonFilesMetadataBuilder { return new CommonFilesMetadata(commonFiles); } + + /** + * TODO Refactor, abstract shared code above + * @param correlationCase Optionally null, otherwise a case, or could be a CR case ID + * @return + * @throws TskCoreException + * @throws NoCurrentCaseException + * @throws SQLException + * @throws EamDbException + */ + public CommonFilesMetadata findEamDbCommonFiles(CorrelationCase correlationCase) throws TskCoreException, NoCurrentCaseException, SQLException, EamDbException { + + List values = Arrays.asList((String[]) this.findCommonFiles().getMetadata().keySet().toArray()); + + Map commonFiles = new HashMap<>(); + + try { + + EamDb dbManager = EamDb.getInstance(); + Collection artifactInstances = dbManager.getArtifactInstancesByCaseValues(correlationCase, values).stream() + .collect(Collectors.toList()); + + for (CorrelationAttributeInstance instance : artifactInstances) { + Long objectId = 1L; // instance.getID(); ID is currently private + String md5 = ""; // instance.getValue(); Currently not a member of COrrelationAttributeInstance .. since before we were looking up one at a time. + String dataSource = instance.getCorrelationDataSource().getName(); + + if (md5 == null || HashUtility.isNoDataMd5(md5)) { + continue; + } + + if (commonFiles.containsKey(md5)) { + final Md5Metadata md5Metadata = commonFiles.get(md5); + md5Metadata.addFileInstanceMetadata(new FileInstanceMetadata(objectId, dataSource)); + } else { + final List fileInstances = new ArrayList<>(); + fileInstances.add(new FileInstanceMetadata(objectId, dataSource)); + Md5Metadata md5Metadata = new Md5Metadata(md5, fileInstances); + commonFiles.put(md5, md5Metadata); + } + } + + } catch (EamDbException ex) { + LOGGER.log(Level.SEVERE, "Error getting artifact instances from database.", ex); // NON-NLS + } + return new CommonFilesMetadata(commonFiles); + + } /** * Should be used by subclasses, in their From 87b16c25bd1a3805d6d44b3e6422c8cbeaccea98 Mon Sep 17 00:00:00 2001 From: Andrew Ziehl Date: Mon, 7 May 2018 21:23:55 -0700 Subject: [PATCH 003/287] Add CorrelationAttributeCommonInstance which maintains md5 for common files search. Modify lookup to produce new type, continue WIP MetadatBuilder method. --- .../datamodel/AbstractSqlEamDb.java | 227 ++++---- .../CorrelationAttributeCommonInstance.java | 46 ++ .../centralrepository/datamodel/EamDb.java | 2 +- .../datamodel/SqliteEamDb.java | 515 +++++++++--------- .../CommonFilesMetadataBuilder.java | 20 +- 5 files changed, 446 insertions(+), 364 deletions(-) create mode 100644 Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeCommonInstance.java diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java index d521332b4c..d23ba2ca58 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java @@ -178,7 +178,7 @@ public abstract class AbstractSqlEamDb implements EamDb { */ @Override public synchronized CorrelationCase newCase(CorrelationCase eamCase) throws EamDbException { - + // check if there is already an existing CorrelationCase for this Case CorrelationCase cRCase = getCaseByUUID(eamCase.getCaseUUID()); if (cRCase != null) { @@ -279,10 +279,10 @@ public abstract class AbstractSqlEamDb implements EamDb { */ @Override public void updateCase(CorrelationCase eamCase) throws EamDbException { - if(eamCase == null) { + if (eamCase == null) { throw new EamDbException("CorrelationCase argument is null"); } - + Connection conn = connect(); PreparedStatement preparedStatement = null; @@ -457,10 +457,10 @@ public abstract class AbstractSqlEamDb implements EamDb { */ @Override public CorrelationDataSource getDataSource(CorrelationCase correlationCase, String dataSourceDeviceId) throws EamDbException { - if(correlationCase == null) { + if (correlationCase == null) { throw new EamDbException("CorrelationCase argument is null"); } - + Connection conn = connect(); CorrelationDataSource eamDataSourceResult = null; @@ -530,16 +530,16 @@ public abstract class AbstractSqlEamDb implements EamDb { */ @Override public void addArtifact(CorrelationAttribute eamArtifact) throws EamDbException { - if(eamArtifact == null) { + if (eamArtifact == null) { throw new EamDbException("CorrelationAttribute is null"); } - if(eamArtifact.getCorrelationType() == null) { + if (eamArtifact.getCorrelationType() == null) { throw new EamDbException("Correlation type is null"); } - if(eamArtifact.getCorrelationValue() == null) { + if (eamArtifact.getCorrelationValue() == null) { throw new EamDbException("Correlation value is null"); } - + Connection conn = connect(); List eamInstances = eamArtifact.getInstances(); @@ -554,21 +554,21 @@ public abstract class AbstractSqlEamDb implements EamDb { sql.append("VALUES ((SELECT id FROM cases WHERE case_uid=? LIMIT 1), "); sql.append("(SELECT id FROM data_sources WHERE device_id=? AND case_id=? LIMIT 1), ?, ?, ?, ?) "); sql.append(getConflictClause()); - + try { preparedStatement = conn.prepareStatement(sql.toString()); for (CorrelationAttributeInstance eamInstance : eamInstances) { if (!eamArtifact.getCorrelationValue().isEmpty()) { - if(eamInstance.getCorrelationCase() == null) { + if (eamInstance.getCorrelationCase() == null) { throw new EamDbException("CorrelationAttributeInstance has null case"); } - if(eamInstance.getCorrelationDataSource() == null) { + if (eamInstance.getCorrelationDataSource() == null) { throw new EamDbException("CorrelationAttributeInstance has null data source"); } - if(eamInstance.getKnownStatus() == null) { + if (eamInstance.getKnownStatus() == null) { throw new EamDbException("CorrelationAttributeInstance has null known status"); } - + preparedStatement.setString(1, eamInstance.getCorrelationCase().getCaseUUID()); preparedStatement.setString(2, eamInstance.getCorrelationDataSource().getDeviceID()); preparedStatement.setInt(3, eamInstance.getCorrelationDataSource().getCaseID()); @@ -605,7 +605,7 @@ public abstract class AbstractSqlEamDb implements EamDb { */ @Override public List getArtifactInstancesByTypeValue(CorrelationAttribute.Type aType, String value) throws EamDbException { - if(aType == null) { + if (aType == null) { throw new EamDbException("Correlation type is null"); } Connection conn = connect(); @@ -648,18 +648,19 @@ public abstract class AbstractSqlEamDb implements EamDb { } /** - * TODO, shares code with getArtifactInstancesByTypeValue, refactor and abstract - * Retrieves eamArtiifact instances from the database that match the given - * list of MD5 values; - * - * @param correlationCase Case id to search on + * TODO, shares code with getArtifactInstancesByTypeValue, refactor and + * abstract Retrieves eamArtiifact instances from the database that match + * the given list of MD5 values; + * + * @param correlationCase Case id to search on * @param values List of ArtifactInstance MD5 values to find matches of. - * + * * @return List of artifact instances for a given list of MD5 values */ - public List getArtifactInstancesByCaseValues(CorrelationCase correlationCase, List values) throws EamDbException { - CorrelationAttribute.Type aType = CorrelationAttribute.getDefaultCorrelationTypes().get(0); // Files type - if(aType == null) { + @Override + public List getArtifactInstancesByCaseValues(CorrelationCase correlationCase, List values) throws EamDbException { + CorrelationAttribute.Type aType = CorrelationAttribute.getDefaultCorrelationTypes().get(0); // Files type + if (aType == null) { throw new EamDbException("Correlation Type is null"); } boolean singleCase = false; @@ -668,12 +669,12 @@ public abstract class AbstractSqlEamDb implements EamDb { } Connection conn = connect(); - List artifactInstances = new ArrayList<>(); + List artifactInstances = new ArrayList<>(); - CorrelationAttributeInstance artifactInstance; + CorrelationAttributeCommonInstance artifactInstance; PreparedStatement preparedStatement = null; ResultSet resultSet = null; - + String valuesString = ""; StringBuilder valuesFilter = new StringBuilder(values.size()); if (!values.isEmpty()) { @@ -694,7 +695,7 @@ public abstract class AbstractSqlEamDb implements EamDb { sql.append(tableName); sql.append(".data_source_id=data_sources.id"); sql.append(" WHERE value IN (?)"); - if(singleCase) { + if (singleCase) { sql.append(" AND "); sql.append(tableName); sql.append(".case_id = ?"); @@ -703,13 +704,13 @@ public abstract class AbstractSqlEamDb implements EamDb { try { preparedStatement = conn.prepareStatement(sql.toString()); preparedStatement.setString(1, valuesString); - if(singleCase) { + if (singleCase) { preparedStatement.setString(2, String.valueOf(correlationCase.getID())); } - + resultSet = preparedStatement.executeQuery(); while (resultSet.next()) { - artifactInstance = getEamArtifactInstanceFromResultSet(resultSet); + artifactInstance = getCommonEamArtifactInstanceFromResultSet(resultSet); artifactInstances.add(artifactInstance); } } catch (SQLException ex) { @@ -721,8 +722,8 @@ public abstract class AbstractSqlEamDb implements EamDb { } return artifactInstances; - } - + } + /** * Retrieves eamArtifact instances from the database that are associated * with the aType and filePath @@ -736,10 +737,10 @@ public abstract class AbstractSqlEamDb implements EamDb { */ @Override public List getArtifactInstancesByPath(CorrelationAttribute.Type aType, String filePath) throws EamDbException { - if(aType == null) { + if (aType == null) { throw new EamDbException("Correlation type is null"); } - if(filePath == null) { + if (filePath == null) { throw new EamDbException("Correlation value is null"); } Connection conn = connect(); @@ -793,13 +794,13 @@ public abstract class AbstractSqlEamDb implements EamDb { */ @Override public Long getCountArtifactInstancesByTypeValue(CorrelationAttribute.Type aType, String value) throws EamDbException { - if(aType == null) { + if (aType == null) { throw new EamDbException("Correlation type is null"); } - if(value == null) { + if (value == null) { throw new EamDbException("Correlation value is null"); } - + Connection conn = connect(); Long instanceCount = 0L; @@ -852,10 +853,10 @@ public abstract class AbstractSqlEamDb implements EamDb { */ @Override public Long getCountUniqueCaseDataSourceTuplesHavingTypeValue(CorrelationAttribute.Type aType, String value) throws EamDbException { - if(aType == null) { + if (aType == null) { throw new EamDbException("Correlation type is null"); } - + Connection conn = connect(); Long instanceCount = 0L; @@ -977,10 +978,10 @@ public abstract class AbstractSqlEamDb implements EamDb { @Override public void prepareBulkArtifact(CorrelationAttribute eamArtifact) throws EamDbException { - if(eamArtifact.getCorrelationType() == null) { + if (eamArtifact.getCorrelationType() == null) { throw new EamDbException("Correlation type is null"); } - + synchronized (bulkArtifacts) { bulkArtifacts.get(eamArtifact.getCorrelationType().getDbTableName()).add(eamArtifact); bulkArtifactsCount++; @@ -1034,17 +1035,17 @@ public abstract class AbstractSqlEamDb implements EamDb { for (CorrelationAttributeInstance eamInstance : eamInstances) { if (!eamArtifact.getCorrelationValue().isEmpty()) { - - if(eamInstance.getCorrelationCase() == null) { + + if (eamInstance.getCorrelationCase() == null) { throw new EamDbException("Correlation attribute instance has null case"); } - if(eamInstance.getCorrelationDataSource() == null) { + if (eamInstance.getCorrelationDataSource() == null) { throw new EamDbException("Correlation attribute instance has null data source"); } - if(eamInstance.getKnownStatus()== null) { + if (eamInstance.getKnownStatus() == null) { throw new EamDbException("Correlation attribute instance has null known known status"); } - + bulkPs.setString(1, eamInstance.getCorrelationCase().getCaseUUID()); bulkPs.setString(2, eamInstance.getCorrelationDataSource().getDeviceID()); bulkPs.setInt(3, eamInstance.getCorrelationDataSource().getCaseID()); @@ -1081,16 +1082,16 @@ public abstract class AbstractSqlEamDb implements EamDb { */ @Override public void bulkInsertCases(List cases) throws EamDbException { - if(cases == null) { + if (cases == null) { throw new EamDbException("cases argument is null"); } - + if (cases.isEmpty()) { return; } Connection conn = connect(); - + int counter = 0; PreparedStatement bulkPs = null; try { @@ -1157,38 +1158,38 @@ public abstract class AbstractSqlEamDb implements EamDb { } /** - * Sets an eamArtifact instance to the given knownStatus. - * knownStatus should be BAD if the file has been tagged with a notable tag and - * UNKNOWN otherwise. If eamArtifact - * exists, it is updated. If eamArtifact does not exist it is added with the - * given status. + * Sets an eamArtifact instance to the given knownStatus. knownStatus should + * be BAD if the file has been tagged with a notable tag and UNKNOWN + * otherwise. If eamArtifact exists, it is updated. If eamArtifact does not + * exist it is added with the given status. * * @param eamArtifact Artifact containing exactly one (1) ArtifactInstance. - * @param knownStatus The status to change the artifact to. Should never be KNOWN + * @param knownStatus The status to change the artifact to. Should never be + * KNOWN */ @Override public void setArtifactInstanceKnownStatus(CorrelationAttribute eamArtifact, TskData.FileKnown knownStatus) throws EamDbException { - if(eamArtifact == null) { + if (eamArtifact == null) { throw new EamDbException("Correlation attribute is null"); } - if(knownStatus == null) { + if (knownStatus == null) { throw new EamDbException("Known status is null"); } if (1 != eamArtifact.getInstances().size()) { throw new EamDbException("Error: Artifact must have exactly one (1) Artifact Instance to set as notable."); // NON-NLS } - + List eamInstances = eamArtifact.getInstances(); CorrelationAttributeInstance eamInstance = eamInstances.get(0); - if(eamInstance.getCorrelationCase() == null) { + if (eamInstance.getCorrelationCase() == null) { throw new EamDbException("Correlation case is null"); } - if(eamInstance.getCorrelationDataSource() == null) { + if (eamInstance.getCorrelationDataSource() == null) { throw new EamDbException("Correlation data source is null"); } - - Connection conn = connect(); + + Connection conn = connect(); PreparedStatement preparedUpdate = null; PreparedStatement preparedQuery = null; @@ -1272,10 +1273,10 @@ public abstract class AbstractSqlEamDb implements EamDb { */ @Override public List getArtifactInstancesKnownBad(CorrelationAttribute.Type aType, String value) throws EamDbException { - if(aType == null) { + if (aType == null) { throw new EamDbException("Correlation type is null"); } - + Connection conn = connect(); List artifactInstances = new ArrayList<>(); @@ -1326,10 +1327,10 @@ public abstract class AbstractSqlEamDb implements EamDb { */ @Override public Long getCountArtifactInstancesKnownBad(CorrelationAttribute.Type aType, String value) throws EamDbException { - if(aType == null) { + if (aType == null) { throw new EamDbException("Correlation type is null"); } - + Connection conn = connect(); Long badInstances = 0L; @@ -1374,10 +1375,10 @@ public abstract class AbstractSqlEamDb implements EamDb { */ @Override public List getListCasesHavingArtifactInstancesKnownBad(CorrelationAttribute.Type aType, String value) throws EamDbException { - if(aType == null) { + if (aType == null) { throw new EamDbException("Correlation type is null"); } - + Connection conn = connect(); Collection caseNames = new LinkedHashSet<>(); @@ -1494,7 +1495,7 @@ public abstract class AbstractSqlEamDb implements EamDb { @Override public boolean referenceSetIsValid(int referenceSetID, String setName, String version) throws EamDbException { EamGlobalSet refSet = this.getReferenceSetByID(referenceSetID); - if(refSet == null) { + if (refSet == null) { return false; } @@ -1563,7 +1564,7 @@ public abstract class AbstractSqlEamDb implements EamDb { */ @Override public boolean isArtifactKnownBadByReference(CorrelationAttribute.Type aType, String value) throws EamDbException { - if(aType == null) { + if (aType == null) { throw new EamDbException("null correlation type"); } @@ -1608,10 +1609,10 @@ public abstract class AbstractSqlEamDb implements EamDb { */ @Override public long newOrganization(EamOrganization eamOrg) throws EamDbException { - if(eamOrg == null) { + if (eamOrg == null) { throw new EamDbException("EamOrganization is null"); } - + Connection conn = connect(); ResultSet generatedKeys = null; PreparedStatement preparedStatement = null; @@ -1718,7 +1719,7 @@ public abstract class AbstractSqlEamDb implements EamDb { public EamOrganization getReferenceSetOrganization(int referenceSetID) throws EamDbException { EamGlobalSet globalSet = getReferenceSetByID(referenceSetID); - if(globalSet == null) { + if (globalSet == null) { throw new EamDbException("Reference set with ID " + referenceSetID + " not found"); } return (getOrganizationByID(globalSet.getOrgID())); @@ -1734,10 +1735,10 @@ public abstract class AbstractSqlEamDb implements EamDb { */ @Override public void updateOrganization(EamOrganization updatedOrganization) throws EamDbException { - if(updatedOrganization == null) { + if (updatedOrganization == null) { throw new EamDbException("null updatedOrganization"); } - + Connection conn = connect(); PreparedStatement preparedStatement = null; String sql = "UPDATE organizations SET org_name = ?, poc_name = ?, poc_email = ?, poc_phone = ? WHERE id = ?"; @@ -1762,10 +1763,10 @@ public abstract class AbstractSqlEamDb implements EamDb { "AbstractSqlEamDb.deleteOrganization.errorDeleting.message=Error executing query when attempting to delete organization by id."}) @Override public void deleteOrganization(EamOrganization organizationToDelete) throws EamDbException { - if(organizationToDelete == null) { + if (organizationToDelete == null) { throw new EamDbException("Organization to delete is null"); } - + Connection conn = connect(); PreparedStatement checkIfUsedStatement = null; ResultSet resultSet = null; @@ -1805,18 +1806,18 @@ public abstract class AbstractSqlEamDb implements EamDb { */ @Override public int newReferenceSet(EamGlobalSet eamGlobalSet) throws EamDbException { - if(eamGlobalSet == null){ + if (eamGlobalSet == null) { throw new EamDbException("EamGlobalSet argument is null"); } - - if(eamGlobalSet.getFileKnownStatus() == null){ + + if (eamGlobalSet.getFileKnownStatus() == null) { throw new EamDbException("File known status on the EamGlobalSet is null"); } - - if(eamGlobalSet.getType() == null){ + + if (eamGlobalSet.getType() == null) { throw new EamDbException("Type on the EamGlobalSet is null"); } - + Connection conn = connect(); PreparedStatement preparedStatement1 = null; @@ -1879,7 +1880,7 @@ public abstract class AbstractSqlEamDb implements EamDb { preparedStatement1 = conn.prepareStatement(sql1); preparedStatement1.setInt(1, referenceSetID); resultSet = preparedStatement1.executeQuery(); - if(resultSet.next()) { + if (resultSet.next()) { return getEamGlobalSetFromResultSet(resultSet); } else { return null; @@ -1898,18 +1899,18 @@ public abstract class AbstractSqlEamDb implements EamDb { * Get all reference sets * * @param correlationType Type of sets to return - * + * * @return List of all reference sets in the central repository * * @throws EamDbException */ @Override public List getAllReferenceSets(CorrelationAttribute.Type correlationType) throws EamDbException { - - if(correlationType == null){ + + if (correlationType == null) { throw new EamDbException("Correlation type is null"); } - + List results = new ArrayList<>(); Connection conn = connect(); @@ -1944,13 +1945,13 @@ public abstract class AbstractSqlEamDb implements EamDb { */ @Override public void addReferenceInstance(EamGlobalFileInstance eamGlobalFileInstance, CorrelationAttribute.Type correlationType) throws EamDbException { - if(eamGlobalFileInstance.getKnownStatus() == null){ + if (eamGlobalFileInstance.getKnownStatus() == null) { throw new EamDbException("known status of EamGlobalFileInstance is null"); } - if(correlationType == null){ + if (correlationType == null) { throw new EamDbException("Correlation type is null"); } - + Connection conn = connect(); PreparedStatement preparedStatement = null; @@ -2015,10 +2016,10 @@ public abstract class AbstractSqlEamDb implements EamDb { */ @Override public void bulkInsertReferenceTypeEntries(Set globalInstances, CorrelationAttribute.Type contentType) throws EamDbException { - if(contentType == null) { + if (contentType == null) { throw new EamDbException("Null correlation type"); } - if(globalInstances == null) { + if (globalInstances == null) { throw new EamDbException("Null set of EamGlobalFileInstance"); } @@ -2035,10 +2036,10 @@ public abstract class AbstractSqlEamDb implements EamDb { bulkPs = conn.prepareStatement(String.format(sql, EamDbUtil.correlationTypeToReferenceTableName(contentType))); for (EamGlobalFileInstance globalInstance : globalInstances) { - if(globalInstance.getKnownStatus() == null){ + if (globalInstance.getKnownStatus() == null) { throw new EamDbException("EamGlobalFileInstance with value " + globalInstance.getMD5Hash() + " has null known status"); } - + bulkPs.setInt(1, globalInstance.getGlobalSetID()); bulkPs.setString(2, globalInstance.getMD5Hash()); bulkPs.setByte(3, globalInstance.getKnownStatus().getFileKnownValue()); @@ -2073,10 +2074,10 @@ public abstract class AbstractSqlEamDb implements EamDb { */ @Override public List getReferenceInstancesByTypeValue(CorrelationAttribute.Type aType, String aValue) throws EamDbException { - if(aType == null) { + if (aType == null) { throw new EamDbException("correlation type is null"); } - + Connection conn = connect(); List globalFileInstances = new ArrayList<>(); @@ -2116,7 +2117,7 @@ public abstract class AbstractSqlEamDb implements EamDb { if (newType == null) { throw new EamDbException("null correlation type"); } - + Connection conn = connect(); PreparedStatement preparedStatement = null; @@ -2321,7 +2322,7 @@ public abstract class AbstractSqlEamDb implements EamDb { preparedStatement = conn.prepareStatement(sql); preparedStatement.setInt(1, typeId); resultSet = preparedStatement.executeQuery(); - if(resultSet.next()) { + if (resultSet.next()) { aType = getCorrelationTypeFromResultSet(resultSet); return aType; } else { @@ -2432,6 +2433,32 @@ public abstract class AbstractSqlEamDb implements EamDb { return eamArtifactInstance; } + /** + * Convert a ResultSet to a Common EamArtifactInstance object + * + * @param resultSet A resultSet with a set of values to create a + * EamArtifactInstance object. + * + * @return fully populated EamArtifactInstance, or null + * + * @throws SQLException when an expected column name is not in the resultSet + */ + private CorrelationAttributeCommonInstance getCommonEamArtifactInstanceFromResultSet(ResultSet resultSet) throws SQLException, EamDbException { + if (null == resultSet) { + return null; + } + CorrelationAttributeCommonInstance eamArtifactInstance = new CorrelationAttributeCommonInstance( + new CorrelationCase(resultSet.getInt("case_id"), resultSet.getString("case_uid"), resultSet.getString("case_name")), + new CorrelationDataSource(-1, resultSet.getInt("case_id"), resultSet.getString("device_id"), resultSet.getString("name")), + resultSet.getString("file_path"), + resultSet.getString("comment"), + TskData.FileKnown.valueOf(resultSet.getByte("known_status")), + resultSet.getString("value") + ); + + return eamArtifactInstance; + } + private EamOrganization getEamOrganizationFromResultSet(ResultSet resultSet) throws SQLException { if (null == resultSet) { return null; diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeCommonInstance.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeCommonInstance.java new file mode 100644 index 0000000000..ff03b23f5b --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeCommonInstance.java @@ -0,0 +1,46 @@ +/* + * Central Repository + * + * Copyright 2015-2017 Basis Technology Corp. + * Contact: carrier sleuthkit 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.centralrepository.datamodel; + +import org.sleuthkit.datamodel.TskData; + + +/** + * Common Files Search usage which extends CorrelationAttributeInstance + * by adding the MD5 value to match on for the results table. + */ +public class CorrelationAttributeCommonInstance extends CorrelationAttributeInstance { + + private static final long serialVersionUID = 1L; + + /** + * The common MD5 value + */ + private final String value; + + public CorrelationAttributeCommonInstance(CorrelationCase eamCase, CorrelationDataSource eamDataSource, String filePath, String comment, TskData.FileKnown knownStatus, String value) throws EamDbException { + super(eamCase, eamDataSource, filePath, comment, knownStatus); + this.value = value; + } + + public String getValue() { + return value; + } + +} diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDb.java index 0ffd8c508b..24af255eea 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDb.java @@ -232,7 +232,7 @@ public interface EamDb { * * @return List of artifact instances for a given list of MD5 values */ - List getArtifactInstancesByCaseValues(CorrelationCase correlationCase, List values) throws EamDbException; + List getArtifactInstancesByCaseValues(CorrelationCase correlationCase, List values) throws EamDbException; /** * Retrieves eamArtifact instances from the database that are associated diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java index 4ff827a68e..0917cedc60 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java @@ -34,9 +34,9 @@ import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.coordinationservice.CoordinationService; /** - * Sqlite implementation of the Central Repository database. - * All methods in AbstractSqlEamDb that read or write to the database should - * be overriden here and use appropriate locking. + * Sqlite implementation of the Central Repository database. All methods in + * AbstractSqlEamDb that read or write to the database should be overriden here + * and use appropriate locking. */ public class SqliteEamDb extends AbstractSqlEamDb { @@ -47,17 +47,18 @@ public class SqliteEamDb extends AbstractSqlEamDb { private BasicDataSource connectionPool = null; private final SqliteEamDbSettings dbSettings; - + // While the Sqlite database should only be used for single users, it is still // possible for multiple threads to attempt to write to the database simultaneously. private final ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock(true); /** * Get the singleton instance of SqliteEamDb - * + * * @return the singleton instance of SqliteEamDb - * - * @throws EamDbException if one or more default correlation type(s) have an invalid db table name. + * + * @throws EamDbException if one or more default correlation type(s) have an + * invalid db table name. */ public synchronized static SqliteEamDb getInstance() throws EamDbException { if (instance == null) { @@ -68,9 +69,9 @@ public class SqliteEamDb extends AbstractSqlEamDb { } /** - * - * @throws EamDbException if the AbstractSqlEamDb class has one or more default - * correlation type(s) having an invalid db table name. + * + * @throws EamDbException if the AbstractSqlEamDb class has one or more + * default correlation type(s) having an invalid db table name. */ private SqliteEamDb() throws EamDbException { dbSettings = new SqliteEamDbSettings(); @@ -80,7 +81,7 @@ public class SqliteEamDb extends AbstractSqlEamDb { @Override public void shutdownConnections() throws EamDbException { try { - synchronized(this) { + synchronized (this) { if (null != connectionPool) { connectionPool.close(); connectionPool = null; // force it to be re-created on next connect() @@ -90,7 +91,7 @@ public class SqliteEamDb extends AbstractSqlEamDb { throw new EamDbException("Failed to close existing database connections.", ex); // NON-NLS } } - + @Override public void updateSettings() { synchronized (this) { @@ -108,9 +109,9 @@ public class SqliteEamDb extends AbstractSqlEamDb { @Override public void reset() throws EamDbException { - try{ + try { acquireExclusiveLock(); - + Connection conn = connect(); try { @@ -151,11 +152,11 @@ public class SqliteEamDb extends AbstractSqlEamDb { * */ private void setupConnectionPool() throws EamDbException { - + if (dbSettings.dbFileExists() == false) { throw new EamDbException("Central repository database missing"); } - + connectionPool = new BasicDataSource(); connectionPool.setDriverClassName(dbSettings.getDriver()); connectionPool.setUrl(dbSettings.getConnectionURL()); @@ -201,25 +202,24 @@ public class SqliteEamDb extends AbstractSqlEamDb { return ""; } - /** * Add a new name/value pair in the db_info table. * - * @param name Key to set + * @param name Key to set * @param value Value to set * * @throws EamDbException */ @Override public void newDbInfo(String name, String value) throws EamDbException { - try{ + try { acquireExclusiveLock(); super.newDbInfo(name, value); } finally { releaseExclusiveLock(); } } - + /** * Get the value for the given name from the name/value db_info table. * @@ -231,47 +231,47 @@ public class SqliteEamDb extends AbstractSqlEamDb { */ @Override public String getDbInfo(String name) throws EamDbException { - try{ + try { acquireSharedLock(); return super.getDbInfo(name); } finally { releaseSharedLock(); - } + } } - + /** * Update the value for a name in the name/value db_info table. * - * @param name Name to find + * @param name Name to find * @param value Value to assign to name. * * @throws EamDbException */ @Override public void updateDbInfo(String name, String value) throws EamDbException { - try{ + try { acquireExclusiveLock(); super.updateDbInfo(name, value); } finally { releaseExclusiveLock(); - } + } } - - /** + + /** * Creates new Case in the database from the given case - * + * * @param autopsyCase The case to add */ @Override public CorrelationCase newCase(Case autopsyCase) throws EamDbException { - try{ + try { acquireExclusiveLock(); return super.newCase(autopsyCase); } finally { releaseExclusiveLock(); - } - } - + } + } + /** * Creates new Case in the database * @@ -281,14 +281,14 @@ public class SqliteEamDb extends AbstractSqlEamDb { */ @Override public CorrelationCase newCase(CorrelationCase eamCase) throws EamDbException { - try{ + try { acquireExclusiveLock(); return super.newCase(eamCase); } finally { releaseExclusiveLock(); - } + } } - + /** * Updates an existing Case in the database * @@ -296,14 +296,14 @@ public class SqliteEamDb extends AbstractSqlEamDb { */ @Override public void updateCase(CorrelationCase eamCase) throws EamDbException { - try{ + try { acquireExclusiveLock(); super.updateCase(eamCase); } finally { releaseExclusiveLock(); - } - } - + } + } + /** * Retrieves Case details based on Case UUID * @@ -313,14 +313,14 @@ public class SqliteEamDb extends AbstractSqlEamDb { */ @Override public CorrelationCase getCaseByUUID(String caseUUID) throws EamDbException { - try{ + try { acquireSharedLock(); return super.getCaseByUUID(caseUUID); } finally { releaseSharedLock(); - } - } - + } + } + /** * Retrieves cases that are in DB. * @@ -328,14 +328,14 @@ public class SqliteEamDb extends AbstractSqlEamDb { */ @Override public List getCases() throws EamDbException { - try{ + try { acquireSharedLock(); return super.getCases(); } finally { releaseSharedLock(); - } - } - + } + } + /** * Creates new Data Source in the database * @@ -343,32 +343,33 @@ public class SqliteEamDb extends AbstractSqlEamDb { */ @Override public void newDataSource(CorrelationDataSource eamDataSource) throws EamDbException { - try{ + try { acquireExclusiveLock(); super.newDataSource(eamDataSource); } finally { releaseExclusiveLock(); - } - } - + } + } + /** * Retrieves Data Source details based on data source device ID * - * @param correlationCase the current CorrelationCase used for ensuring uniqueness of DataSource + * @param correlationCase the current CorrelationCase used for ensuring + * uniqueness of DataSource * @param dataSourceDeviceId the data source device ID number * * @return The data source */ @Override public CorrelationDataSource getDataSource(CorrelationCase correlationCase, String dataSourceDeviceId) throws EamDbException { - try{ + try { acquireSharedLock(); return super.getDataSource(correlationCase, dataSourceDeviceId); } finally { releaseSharedLock(); - } - } - + } + } + /** * Return a list of data sources in the DB * @@ -376,14 +377,14 @@ public class SqliteEamDb extends AbstractSqlEamDb { */ @Override public List getDataSources() throws EamDbException { - try{ + try { acquireSharedLock(); return super.getDataSources(); } finally { releaseSharedLock(); - } - } - + } + } + /** * Inserts new Artifact(s) into the database. Should add associated Case and * Data Source first. @@ -392,57 +393,57 @@ public class SqliteEamDb extends AbstractSqlEamDb { */ @Override public void addArtifact(CorrelationAttribute eamArtifact) throws EamDbException { - try{ + try { acquireExclusiveLock(); super.addArtifact(eamArtifact); } finally { releaseExclusiveLock(); - } - } - + } + } + /** * Retrieves eamArtifact instances from the database that are associated * with the eamArtifactType and eamArtifactValue of the given eamArtifact. * - * @param aType The type of the artifact - * @param value The correlation value + * @param aType The type of the artifact + * @param value The correlation value * * @return List of artifact instances for a given type/value */ @Override public List getArtifactInstancesByTypeValue(CorrelationAttribute.Type aType, String value) throws EamDbException { - try{ + try { acquireSharedLock(); return super.getArtifactInstancesByTypeValue(aType, value); } finally { releaseSharedLock(); - } - } - - + } + } + /** * Retrieves eamArtiifact instances from the database that match the given * list of MD5 values; - * - * @param correlationCase Case id to search on + * + * @param correlationCase Case id to search on * @param values List of ArtifactInstance MD5 values to find matches of. - * + * * @return List of artifact instances for a given list of MD5 values */ - public List getArtifactInstancesByCaseValues(CorrelationCase correlationCase, List values) throws EamDbException { - try{ + @Override + public List getArtifactInstancesByCaseValues(CorrelationCase correlationCase, List values) throws EamDbException { + try { acquireSharedLock(); return super.getArtifactInstancesByCaseValues(correlationCase, values); } finally { releaseSharedLock(); - } - } - + } + } + /** * Retrieves eamArtifact instances from the database that are associated * with the aType and filePath * - * @param aType EamArtifact.Type to search for + * @param aType EamArtifact.Type to search for * @param filePath File path to search for * * @return List of 0 or more EamArtifactInstances @@ -451,14 +452,14 @@ public class SqliteEamDb extends AbstractSqlEamDb { */ @Override public List getArtifactInstancesByPath(CorrelationAttribute.Type aType, String filePath) throws EamDbException { - try{ + try { acquireSharedLock(); return super.getArtifactInstancesByPath(aType, filePath); } finally { releaseSharedLock(); - } - } - + } + } + /** * Retrieves number of artifact instances in the database that are * associated with the ArtifactType and artifactValue of the given artifact. @@ -467,29 +468,29 @@ public class SqliteEamDb extends AbstractSqlEamDb { * @param value The value to search for * * @return Number of artifact instances having ArtifactType and - * ArtifactValue. - * @throws EamDbException + * ArtifactValue. + * @throws EamDbException */ @Override public Long getCountArtifactInstancesByTypeValue(CorrelationAttribute.Type aType, String value) throws EamDbException { - try{ + try { acquireSharedLock(); return super.getCountArtifactInstancesByTypeValue(aType, value); } finally { releaseSharedLock(); - } + } } - + @Override public int getFrequencyPercentage(CorrelationAttribute corAttr) throws EamDbException { - try{ + try { acquireSharedLock(); return super.getFrequencyPercentage(corAttr); } finally { releaseSharedLock(); - } - } - + } + } + /** * Retrieves number of unique caseDisplayName / dataSource tuples in the * database that are associated with the artifactType and artifactValue of @@ -503,112 +504,111 @@ public class SqliteEamDb extends AbstractSqlEamDb { */ @Override public Long getCountUniqueCaseDataSourceTuplesHavingTypeValue(CorrelationAttribute.Type aType, String value) throws EamDbException { - try{ + try { acquireSharedLock(); return super.getCountUniqueCaseDataSourceTuplesHavingTypeValue(aType, value); } finally { releaseSharedLock(); - } - } - + } + } @Override public Long getCountUniqueDataSources() throws EamDbException { - try{ + try { acquireSharedLock(); return super.getCountUniqueDataSources(); } finally { releaseSharedLock(); - } - } - + } + } + /** * Retrieves number of eamArtifact instances in the database that are * associated with the caseDisplayName and dataSource of the given * eamArtifact instance. * - * @param caseUUID Case ID to search for + * @param caseUUID Case ID to search for * @param dataSourceID Data source ID to search for * * @return Number of artifact instances having caseDisplayName and - * dataSource + * dataSource */ @Override public Long getCountArtifactInstancesByCaseDataSource(String caseUUID, String dataSourceID) throws EamDbException { - try{ + try { acquireSharedLock(); return super.getCountArtifactInstancesByCaseDataSource(caseUUID, dataSourceID); } finally { releaseSharedLock(); - } - } - + } + } + /** * Executes a bulk insert of the eamArtifacts added from the * prepareBulkArtifact() method */ @Override public void bulkInsertArtifacts() throws EamDbException { - try{ + try { acquireExclusiveLock(); super.bulkInsertArtifacts(); } finally { releaseExclusiveLock(); - } - } - + } + } + /** * Executes a bulk insert of the cases */ @Override public void bulkInsertCases(List cases) throws EamDbException { - try{ + try { acquireExclusiveLock(); super.bulkInsertCases(cases); } finally { releaseExclusiveLock(); - } - } - + } + } + /** - * Sets an eamArtifact instance to the given knownStatus. - * knownStatus should be BAD if the file has been tagged with a notable tag and - * UNKNOWN otherwise. If eamArtifact - * exists, it is updated. If eamArtifact does not exist it is added with the - * given status. + * Sets an eamArtifact instance to the given knownStatus. knownStatus should + * be BAD if the file has been tagged with a notable tag and UNKNOWN + * otherwise. If eamArtifact exists, it is updated. If eamArtifact does not + * exist it is added with the given status. * * @param eamArtifact Artifact containing exactly one (1) ArtifactInstance. - * @param knownStatus The status to change the artifact to. Should never be KNOWN + * @param knownStatus The status to change the artifact to. Should never be + * KNOWN */ @Override public void setArtifactInstanceKnownStatus(CorrelationAttribute eamArtifact, TskData.FileKnown knownStatus) throws EamDbException { - try{ + try { acquireExclusiveLock(); super.setArtifactInstanceKnownStatus(eamArtifact, knownStatus); } finally { releaseExclusiveLock(); - } - } - + } + } + /** * Gets list of matching eamArtifact instances that have knownStatus = * "Bad". * * @param aType EamArtifact.Type to search for * @param value Value to search for - * + * * @return List with 0 or more matching eamArtifact instances. */ @Override public List getArtifactInstancesKnownBad(CorrelationAttribute.Type aType, String value) throws EamDbException { - try{ + try { acquireSharedLock(); return super.getArtifactInstancesKnownBad(aType, value); } finally { releaseSharedLock(); - } - } - + } + } + /** * Count matching eamArtifacts instances that have knownStatus = "Bad". * @@ -619,14 +619,14 @@ public class SqliteEamDb extends AbstractSqlEamDb { */ @Override public Long getCountArtifactInstancesKnownBad(CorrelationAttribute.Type aType, String value) throws EamDbException { - try{ + try { acquireSharedLock(); return super.getCountArtifactInstancesKnownBad(aType, value); } finally { releaseSharedLock(); - } - } - + } + } + /** * Gets list of distinct case display names, where each case has 1+ Artifact * Instance matching eamArtifact with knownStatus = "Bad". @@ -635,37 +635,39 @@ public class SqliteEamDb extends AbstractSqlEamDb { * @param value Value to search for * * @return List of cases containing this artifact with instances marked as - * bad + * bad * * @throws EamDbException */ @Override public List getListCasesHavingArtifactInstancesKnownBad(CorrelationAttribute.Type aType, String value) throws EamDbException { - try{ + try { acquireSharedLock(); return super.getListCasesHavingArtifactInstancesKnownBad(aType, value); } finally { releaseSharedLock(); - } - } - + } + } + /** * Remove a reference set and all values contained in it. + * * @param referenceSetID - * @throws EamDbException + * @throws EamDbException */ @Override - public void deleteReferenceSet(int referenceSetID) throws EamDbException{ - try{ + public void deleteReferenceSet(int referenceSetID) throws EamDbException { + try { acquireExclusiveLock(); super.deleteReferenceSet(referenceSetID); } finally { releaseExclusiveLock(); - } - } - + } + } + /** * Check if the given hash is in a specific reference set + * * @param value * @param referenceSetID * @param correlationTypeID @@ -673,32 +675,34 @@ public class SqliteEamDb extends AbstractSqlEamDb { */ @Override public boolean isValueInReferenceSet(String value, int referenceSetID, int correlationTypeID) throws EamDbException { - try{ + try { acquireSharedLock(); return super.isValueInReferenceSet(value, referenceSetID, correlationTypeID); } finally { releaseSharedLock(); - } + } } - + /** - * Check whether a reference set with the given name/version is in the central repo. - * Used to check for name collisions when creating reference sets. + * Check whether a reference set with the given name/version is in the + * central repo. Used to check for name collisions when creating reference + * sets. + * * @param referenceSetName * @param version * @return true if a matching set is found - * @throws EamDbException + * @throws EamDbException */ @Override public boolean referenceSetExists(String referenceSetName, String version) throws EamDbException { - try{ + try { acquireSharedLock(); return super.referenceSetExists(referenceSetName, version); } finally { releaseSharedLock(); - } + } } - + /** * Is the artifact known as bad according to the reference entries? * @@ -708,34 +712,34 @@ public class SqliteEamDb extends AbstractSqlEamDb { * @return Global known status of the artifact */ @Override - public boolean isArtifactKnownBadByReference(CorrelationAttribute.Type aType, String value) throws EamDbException { - try{ + public boolean isArtifactKnownBadByReference(CorrelationAttribute.Type aType, String value) throws EamDbException { + try { acquireSharedLock(); return super.isArtifactKnownBadByReference(aType, value); } finally { releaseSharedLock(); - } + } } - + /** * Add a new organization * * @return the Organization ID of the newly created organization. - * + * * @param eamOrg The organization to add * * @throws EamDbException */ @Override public long newOrganization(EamOrganization eamOrg) throws EamDbException { - try{ + try { acquireExclusiveLock(); return super.newOrganization(eamOrg); } finally { releaseExclusiveLock(); - } - } - + } + } + /** * Get all organizations * @@ -745,14 +749,14 @@ public class SqliteEamDb extends AbstractSqlEamDb { */ @Override public List getOrganizations() throws EamDbException { - try{ + try { acquireSharedLock(); return super.getOrganizations(); } finally { releaseSharedLock(); - } - } - + } + } + /** * Get an organization having the given ID * @@ -764,33 +768,34 @@ public class SqliteEamDb extends AbstractSqlEamDb { */ @Override public EamOrganization getOrganizationByID(int orgID) throws EamDbException { - try{ + try { acquireSharedLock(); return super.getOrganizationByID(orgID); } finally { releaseSharedLock(); - } - } - + } + } + @Override public void updateOrganization(EamOrganization updatedOrganization) throws EamDbException { - try{ + try { acquireExclusiveLock(); super.updateOrganization(updatedOrganization); } finally { releaseExclusiveLock(); - } + } } - + @Override public void deleteOrganization(EamOrganization organizationToDelete) throws EamDbException { - try{ + try { acquireExclusiveLock(); super.deleteOrganization(organizationToDelete); } finally { releaseExclusiveLock(); - } + } } + /** * Add a new Global Set * @@ -802,14 +807,14 @@ public class SqliteEamDb extends AbstractSqlEamDb { */ @Override public int newReferenceSet(EamGlobalSet eamGlobalSet) throws EamDbException { - try{ + try { acquireExclusiveLock(); return super.newReferenceSet(eamGlobalSet); } finally { releaseExclusiveLock(); - } - } - + } + } + /** * Get a reference set by ID * @@ -821,52 +826,51 @@ public class SqliteEamDb extends AbstractSqlEamDb { */ @Override public EamGlobalSet getReferenceSetByID(int referenceSetID) throws EamDbException { - try{ + try { acquireSharedLock(); return super.getReferenceSetByID(referenceSetID); } finally { releaseSharedLock(); - } - } - + } + } + /** * Get all reference sets * * @param correlationType Type of sets to return - * + * * @return List of all reference sets in the central repository * * @throws EamDbException */ @Override public List getAllReferenceSets(CorrelationAttribute.Type correlationType) throws EamDbException { - try{ + try { acquireSharedLock(); return super.getAllReferenceSets(correlationType); } finally { releaseSharedLock(); - } + } } - + /** * Add a new reference instance * * @param eamGlobalFileInstance The reference instance to add - * @param correlationType Correlation Type that this Reference - * Instance is + * @param correlationType Correlation Type that this Reference Instance is * * @throws EamDbException */ @Override public void addReferenceInstance(EamGlobalFileInstance eamGlobalFileInstance, CorrelationAttribute.Type correlationType) throws EamDbException { - try{ + try { acquireExclusiveLock(); super.addReferenceInstance(eamGlobalFileInstance, correlationType); } finally { releaseExclusiveLock(); - } - } - + } + } + /** * Insert the bulk collection of Reference Type Instances * @@ -874,18 +878,18 @@ public class SqliteEamDb extends AbstractSqlEamDb { */ @Override public void bulkInsertReferenceTypeEntries(Set globalInstances, CorrelationAttribute.Type contentType) throws EamDbException { - try{ + try { acquireExclusiveLock(); super.bulkInsertReferenceTypeEntries(globalInstances, contentType); } finally { releaseExclusiveLock(); - } - } - + } + } + /** * Get all reference entries having a given correlation type and value * - * @param aType Type to use for matching + * @param aType Type to use for matching * @param aValue Value to use for matching * * @return List of all global file instances with a type and value @@ -894,14 +898,14 @@ public class SqliteEamDb extends AbstractSqlEamDb { */ @Override public List getReferenceInstancesByTypeValue(CorrelationAttribute.Type aType, String aValue) throws EamDbException { - try{ + try { acquireSharedLock(); return super.getReferenceInstancesByTypeValue(aType, aValue); } finally { releaseSharedLock(); - } - } - + } + } + /** * Add a new EamArtifact.Type to the db. * @@ -913,71 +917,71 @@ public class SqliteEamDb extends AbstractSqlEamDb { */ @Override public int newCorrelationType(CorrelationAttribute.Type newType) throws EamDbException { - try{ + try { acquireExclusiveLock(); return super.newCorrelationType(newType); } finally { releaseExclusiveLock(); - } - } - + } + } + /** * Get the list of EamArtifact.Type's that will be used to correlate * artifacts. * * @return List of EamArtifact.Type's. If none are defined in the database, - * the default list will be returned. + * the default list will be returned. * * @throws EamDbException */ @Override public List getDefinedCorrelationTypes() throws EamDbException { - try{ + try { acquireSharedLock(); return super.getDefinedCorrelationTypes(); } finally { releaseSharedLock(); - } - } - + } + } + /** * Get the list of enabled EamArtifact.Type's that will be used to correlate * artifacts. * * @return List of enabled EamArtifact.Type's. If none are defined in the - * database, the default list will be returned. + * database, the default list will be returned. * * @throws EamDbException */ @Override public List getEnabledCorrelationTypes() throws EamDbException { - try{ + try { acquireSharedLock(); return super.getEnabledCorrelationTypes(); } finally { releaseSharedLock(); - } - } - + } + } + /** * Get the list of supported EamArtifact.Type's that can be used to * correlate artifacts. * * @return List of supported EamArtifact.Type's. If none are defined in the - * database, the default list will be returned. + * database, the default list will be returned. * * @throws EamDbException */ @Override public List getSupportedCorrelationTypes() throws EamDbException { - try{ + try { acquireSharedLock(); return super.getSupportedCorrelationTypes(); } finally { releaseSharedLock(); - } - } - + } + } + /** * Update a EamArtifact.Type. * @@ -987,14 +991,14 @@ public class SqliteEamDb extends AbstractSqlEamDb { */ @Override public void updateCorrelationType(CorrelationAttribute.Type aType) throws EamDbException { - try{ + try { acquireExclusiveLock(); super.updateCorrelationType(aType); } finally { releaseExclusiveLock(); - } - } - + } + } + /** * Get the EamArtifact.Type that has the given Type.Id. * @@ -1006,73 +1010,76 @@ public class SqliteEamDb extends AbstractSqlEamDb { */ @Override public CorrelationAttribute.Type getCorrelationTypeById(int typeId) throws EamDbException { - try{ + try { acquireSharedLock(); return super.getCorrelationTypeById(typeId); } finally { releaseSharedLock(); - } - } - + } + } + /** * Upgrade the schema of the database (if needed) - * @throws EamDbException + * + * @throws EamDbException */ @Override public void upgradeSchema() throws EamDbException, SQLException { - try{ + try { acquireExclusiveLock(); super.upgradeSchema(); } finally { releaseExclusiveLock(); - } + } } - + /** - * Gets an exclusive lock (if applicable). - * Will return the lock if successful, null if unsuccessful because locking - * isn't supported, and throw an exception if we should have been able to get the - * lock but failed (meaning the database is in use). + * Gets an exclusive lock (if applicable). Will return the lock if + * successful, null if unsuccessful because locking isn't supported, and + * throw an exception if we should have been able to get the lock but failed + * (meaning the database is in use). + * * @return the lock, or null if locking is not supported - * @throws EamDbException if the coordination service is running but we fail to get the lock + * @throws EamDbException if the coordination service is running but we fail + * to get the lock */ @Override - public CoordinationService.Lock getExclusiveMultiUserDbLock() throws EamDbException{ + public CoordinationService.Lock getExclusiveMultiUserDbLock() throws EamDbException { // Multiple users are not supported for SQLite return null; } - + /** - * Acquire the lock that provides exclusive access to the case database. - * Call this method in a try block with a call to - * the lock release method in an associated finally block. + * Acquire the lock that provides exclusive access to the case database. + * Call this method in a try block with a call to the lock release method in + * an associated finally block. */ private void acquireExclusiveLock() { rwLock.writeLock().lock(); } /** - * Release the lock that provides exclusive access to the database. - * This method should always be called in the finally - * block of a try block in which the lock was acquired. + * Release the lock that provides exclusive access to the database. This + * method should always be called in the finally block of a try block in + * which the lock was acquired. */ private void releaseExclusiveLock() { rwLock.writeLock().unlock(); } /** - * Acquire the lock that provides shared access to the case database. - * Call this method in a try block with a call to the - * lock release method in an associated finally block. + * Acquire the lock that provides shared access to the case database. Call + * this method in a try block with a call to the lock release method in an + * associated finally block. */ private void acquireSharedLock() { rwLock.readLock().lock(); } /** - * Release the lock that provides shared access to the database. - * This method should always be called in the finally block - * of a try block in which the lock was acquired. + * Release the lock that provides shared access to the database. This method + * should always be called in the finally block of a try block in which the + * lock was acquired. */ private void releaseSharedLock() { rwLock.readLock().unlock(); diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesMetadataBuilder.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesMetadataBuilder.java index 0888c5c129..11b9520171 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesMetadataBuilder.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesMetadataBuilder.java @@ -35,6 +35,7 @@ import java.util.stream.Stream; import org.openide.util.NbBundle; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; +import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeCommonInstance; import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance; import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationCase; import org.sleuthkit.autopsy.centralrepository.datamodel.EamDb; @@ -220,28 +221,29 @@ abstract class CommonFilesMetadataBuilder { * @throws EamDbException */ public CommonFilesMetadata findEamDbCommonFiles(CorrelationCase correlationCase) throws TskCoreException, NoCurrentCaseException, SQLException, EamDbException { - - List values = Arrays.asList((String[]) this.findCommonFiles().getMetadata().keySet().toArray()); - - Map commonFiles = new HashMap<>(); + CommonFilesMetadata metaData = this.findCommonFiles(); // TODO, have another method which returns ALL md5/objectIds nstead of current query of count > 2 + Map commonFiles = metaData.getMetadata(); + List values = Arrays.asList((String[]) commonFiles.keySet().toArray()); try { EamDb dbManager = EamDb.getInstance(); - Collection artifactInstances = dbManager.getArtifactInstancesByCaseValues(correlationCase, values).stream() + Collection artifactInstances = dbManager.getArtifactInstancesByCaseValues(correlationCase, values).stream() .collect(Collectors.toList()); - for (CorrelationAttributeInstance instance : artifactInstances) { - Long objectId = 1L; // instance.getID(); ID is currently private - String md5 = ""; // instance.getValue(); Currently not a member of COrrelationAttributeInstance .. since before we were looking up one at a time. + + for (CorrelationAttributeCommonInstance instance : artifactInstances) { + Long objectId = 1L; //TODO, need to retrieve ALL (even count < 2) AbstractFiles from this case to us for objectId for CR matches; + String md5 = instance.getValue(); String dataSource = instance.getCorrelationDataSource().getName(); if (md5 == null || HashUtility.isNoDataMd5(md5)) { continue; } - + // TODO Build a 3rd list which contains instances which are in commonFiles map, use current case objectId if (commonFiles.containsKey(md5)) { final Md5Metadata md5Metadata = commonFiles.get(md5); + //TODO should FIleInstanceMetadata carry Knownstatus from CR instances? md5Metadata.addFileInstanceMetadata(new FileInstanceMetadata(objectId, dataSource)); } else { final List fileInstances = new ArrayList<>(); From 5e40c87a94ce4f38b29fccaf426af81ae3544dbe Mon Sep 17 00:00:00 2001 From: Andrew Ziehl Date: Mon, 7 May 2018 21:43:17 -0700 Subject: [PATCH 004/287] Extend CommonFilesMetadataBuilder to query for all filtered md5s, add dead else case to Panel for when UI logic triggers CR common files lookup. --- .../datamodel/AbstractSqlEamDb.java | 9 ++- ...lDataSourcesEamDbCommonFilesAlgorithm.java | 58 +++++++++++++++++++ .../CommonFilesMetadataBuilder.java | 7 ++- .../commonfilesearch/CommonFilesPanel.form | 21 +++---- .../commonfilesearch/CommonFilesPanel.java | 3 + 5 files changed, 77 insertions(+), 21 deletions(-) create mode 100644 Core/src/org/sleuthkit/autopsy/commonfilesearch/AllDataSourcesEamDbCommonFilesAlgorithm.java diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java index d23ba2ca58..91b3dda535 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java @@ -648,11 +648,10 @@ public abstract class AbstractSqlEamDb implements EamDb { } /** - * TODO, shares code with getArtifactInstancesByTypeValue, refactor and - * abstract Retrieves eamArtiifact instances from the database that match - * the given list of MD5 values; + * Retrieves eamArtiifact instances from the database that match + * the given list of MD5 values and optionally filters by given case. * - * @param correlationCase Case id to search on + * @param correlationCase Case id to search on, if null, searches all cases * @param values List of ArtifactInstance MD5 values to find matches of. * * @return List of artifact instances for a given list of MD5 values @@ -704,7 +703,7 @@ public abstract class AbstractSqlEamDb implements EamDb { try { preparedStatement = conn.prepareStatement(sql.toString()); preparedStatement.setString(1, valuesString); - if (singleCase) { + if (singleCase && correlationCase != null) { preparedStatement.setString(2, String.valueOf(correlationCase.getID())); } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllDataSourcesEamDbCommonFilesAlgorithm.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllDataSourcesEamDbCommonFilesAlgorithm.java new file mode 100644 index 0000000000..ea52971f20 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllDataSourcesEamDbCommonFilesAlgorithm.java @@ -0,0 +1,58 @@ +/* + * + * Autopsy Forensic Browser + * + * Copyright 2018 Basis Technology Corp. + * Contact: carrier sleuthkit 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.commonfilesearch; + +import java.util.Map; +import static org.sleuthkit.autopsy.commonfilesearch.CommonFilesMetadataBuilder.SELECT_PREFIX; + + +/** + * Provides logic for selecting common files from all data sources for all files to source for EamDB query. + */ +public class AllDataSourcesEamDbCommonFilesAlgorithm extends CommonFilesMetadataBuilder { + + private static final String WHERE_CLAUSE = "%s md5 in (select md5 from tsk_files where (known != 1 OR known IS NULL)%s GROUP BY md5) order by md5"; //NON-NLS + + /** + * Implements the algorithm for getting common files across all data + * sources. + * + * @param dataSourceIdMap a map of obj_id to datasource name + * @param filterByMediaMimeType match only on files whose mime types can be broadly categorized as media types + * @param filterByDocMimeType match only on files whose mime types can be broadly categorized as document types + */ + AllDataSourcesEamDbCommonFilesAlgorithm(Map dataSourceIdMap, boolean filterByMediaMimeType, boolean filterByDocMimeType) { + super(dataSourceIdMap, filterByMediaMimeType, filterByDocMimeType); + + } + + @Override + protected String buildSqlSelectStatement() { + Object[] args = new String[]{SELECT_PREFIX, determineMimeTypeFilter()}; + return String.format(WHERE_CLAUSE, args); + } + + @Override + protected String buildTabTitle() { + final String buildCategorySelectionString = this.buildCategorySelectionString(); + final String titleTemplate = Bundle.CommonFilesMetadataBuilder_buildTabTitle_titleEamDb(); + return String.format(titleTemplate, new Object[]{buildCategorySelectionString}); + } +} diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesMetadataBuilder.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesMetadataBuilder.java index 11b9520171..ea9e022ee4 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesMetadataBuilder.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesMetadataBuilder.java @@ -212,7 +212,7 @@ abstract class CommonFilesMetadataBuilder { } /** - * TODO Refactor, abstract shared code above + * TODO Refactor, abstract shared code above, call this method via new AllDataSourcesEamDbCommonFilesAlgorithm Class * @param correlationCase Optionally null, otherwise a case, or could be a CR case ID * @return * @throws TskCoreException @@ -221,7 +221,7 @@ abstract class CommonFilesMetadataBuilder { * @throws EamDbException */ public CommonFilesMetadata findEamDbCommonFiles(CorrelationCase correlationCase) throws TskCoreException, NoCurrentCaseException, SQLException, EamDbException { - CommonFilesMetadata metaData = this.findCommonFiles(); // TODO, have another method which returns ALL md5/objectIds nstead of current query of count > 2 + CommonFilesMetadata metaData = this.findCommonFiles(); Map commonFiles = metaData.getMetadata(); List values = Arrays.asList((String[]) commonFiles.keySet().toArray()); @@ -293,7 +293,8 @@ abstract class CommonFilesMetadataBuilder { @NbBundle.Messages({ "CommonFilesMetadataBuilder.buildTabTitle.titleAll=Common Files (All Data Sources, %s)", - "CommonFilesMetadataBuilder.buildTabTitle.titleSingle=Common Files (Match Within Data Source: %s, %s)" + "CommonFilesMetadataBuilder.buildTabTitle.titleSingle=Common Files (Match Within Data Source: %s, %s)", + "CommonFilesMetadataBuilder.buildTabTitle.titleEamDb=Common Files (Central Repository Source(s), %s)", }) protected abstract String buildTabTitle(); diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.form b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.form index c617d77864..8c82dd1626 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.form +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.form @@ -34,25 +34,20 @@ + + - + + - + - - - - - - - - - + + - @@ -86,7 +81,7 @@ - + diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java index 73c2e7a7ed..014e962931 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java @@ -267,6 +267,9 @@ public final class CommonFilesPanel extends javax.swing.JPanel { builder = new SingleDataSource(dataSourceId, CommonFilesPanel.this.dataSourceMap, filterByMedia, filterByDocuments); setTitleForSingleSource(dataSourceId); + } else if(false) { + // TODO, is CR cases, add option chosen CorrelationCase ID lookup + builder = new AllDataSourcesEamDbCommonFilesAlgorithm(CommonFilesPanel.this.dataSourceMap, filterByMedia, filterByDocuments); } this.tabTitle = builder.buildTabTitle(); From d3de276cfc7286bafdd49a7b921680aa3e9f746e Mon Sep 17 00:00:00 2001 From: Andrew Ziehl Date: Mon, 7 May 2018 21:55:47 -0700 Subject: [PATCH 005/287] Comment out Panel call to CR matches builder. Build metadata list of only intercase matches. --- .../CommonFilesMetadataBuilder.java | 29 ++++++++++++------- .../commonfilesearch/CommonFilesPanel.java | 6 ++-- 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesMetadataBuilder.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesMetadataBuilder.java index ea9e022ee4..6bee5f2242 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesMetadataBuilder.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesMetadataBuilder.java @@ -225,6 +225,7 @@ abstract class CommonFilesMetadataBuilder { Map commonFiles = metaData.getMetadata(); List values = Arrays.asList((String[]) commonFiles.keySet().toArray()); + Map interCaseCommonFiles = metaData.getMetadata(); try { EamDb dbManager = EamDb.getInstance(); @@ -233,30 +234,38 @@ abstract class CommonFilesMetadataBuilder { for (CorrelationAttributeCommonInstance instance : artifactInstances) { - Long objectId = 1L; //TODO, need to retrieve ALL (even count < 2) AbstractFiles from this case to us for objectId for CR matches; + //Long objectId = 1L; //TODO, need to retrieve ALL (even count < 2) AbstractFiles from this case to us for objectId for CR matches; String md5 = instance.getValue(); String dataSource = instance.getCorrelationDataSource().getName(); if (md5 == null || HashUtility.isNoDataMd5(md5)) { continue; } - // TODO Build a 3rd list which contains instances which are in commonFiles map, use current case objectId + //Builds a 3rd list which contains instances which are in commonFiles map, uses current case objectId if (commonFiles.containsKey(md5)) { - final Md5Metadata md5Metadata = commonFiles.get(md5); - //TODO should FIleInstanceMetadata carry Knownstatus from CR instances? - md5Metadata.addFileInstanceMetadata(new FileInstanceMetadata(objectId, dataSource)); + // TODO sloppy, but we don't *have* all the information for the rows in the CR, so what do we do? + Long objectId = commonFiles.get(md5).getMetadata().iterator().next().getObjectId(); + if(interCaseCommonFiles.containsKey(md5)) { + //Add to intercase metaData + final Md5Metadata md5Metadata = interCaseCommonFiles.get(md5); + md5Metadata.addFileInstanceMetadata(new FileInstanceMetadata(objectId, dataSource)); + + } else { + // Create new intercase metadata + final Md5Metadata md5Metadata = commonFiles.get(md5); + md5Metadata.addFileInstanceMetadata(new FileInstanceMetadata(objectId, dataSource)); + interCaseCommonFiles.put(md5, md5Metadata); + } } else { - final List fileInstances = new ArrayList<>(); - fileInstances.add(new FileInstanceMetadata(objectId, dataSource)); - Md5Metadata md5Metadata = new Md5Metadata(md5, fileInstances); - commonFiles.put(md5, md5Metadata); + // TODO This should never happen. All current case files with potential matches are in comonFiles Map. } } } catch (EamDbException ex) { LOGGER.log(Level.SEVERE, "Error getting artifact instances from database.", ex); // NON-NLS } - return new CommonFilesMetadata(commonFiles); + // Builds intercase-only matches metadata + return new CommonFilesMetadata(interCaseCommonFiles); } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java index 014e962931..a33c215040 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java @@ -267,10 +267,10 @@ public final class CommonFilesPanel extends javax.swing.JPanel { builder = new SingleDataSource(dataSourceId, CommonFilesPanel.this.dataSourceMap, filterByMedia, filterByDocuments); setTitleForSingleSource(dataSourceId); - } else if(false) { + }// else if(false) { // TODO, is CR cases, add option chosen CorrelationCase ID lookup - builder = new AllDataSourcesEamDbCommonFilesAlgorithm(CommonFilesPanel.this.dataSourceMap, filterByMedia, filterByDocuments); - } + // builder = new AllDataSourcesEamDbCommonFilesAlgorithm(CommonFilesPanel.this.dataSourceMap, filterByMedia, filterByDocuments); + //} this.tabTitle = builder.buildTabTitle(); From 48daecf1ece839d4918a5157cfdecd4fc06dff36 Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Tue, 15 May 2018 09:19:32 -0600 Subject: [PATCH 006/287] unused import --- .../org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java | 1 - 1 file changed, 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java index 26939ff840..50e7de91a9 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java @@ -42,7 +42,6 @@ import org.sleuthkit.autopsy.corecomponents.TableFilterNode; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil; import org.sleuthkit.autopsy.directorytree.DataResultFilterNode; -import org.sleuthkit.autopsy.directorytree.DirectoryTreeTopComponent; import org.sleuthkit.datamodel.SleuthkitCase; import org.sleuthkit.datamodel.SleuthkitCase.CaseDbQuery; import org.sleuthkit.datamodel.TskCoreException; From 6ad28c19688d4d3a56dfc7a4bf97d231a8f8cce7 Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Tue, 15 May 2018 15:54:20 -0600 Subject: [PATCH 007/287] intercase and intracase panel stubs --- .../commonfilesearch/Bundle.properties | 8 +- .../commonfilesearch/CommonFilesPanel.form | 178 ++-------- .../commonfilesearch/CommonFilesPanel.java | 323 +++--------------- .../commonfilesearch/InterCasePanel.form | 82 +++++ .../commonfilesearch/InterCasePanel.java | 91 +++++ .../commonfilesearch/IntraCasePanel.form | 95 ++++++ .../commonfilesearch/IntraCasePanel.java | 317 +++++++++++++++++ 7 files changed, 660 insertions(+), 434 deletions(-) create mode 100644 Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.form create mode 100644 Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.java create mode 100644 Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCasePanel.form create mode 100644 Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCasePanel.java diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/Bundle.properties b/Core/src/org/sleuthkit/autopsy/commonfilesearch/Bundle.properties index e9ba24bc1e..f3ac99e12d 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/Bundle.properties @@ -1,6 +1,4 @@ CommonFilesPanel.searchButton.text=Search -CommonFilesPanel.withinDataSourceRadioButton.text=At least one match must appear in the data source selected below: -CommonFilesPanel.allDataSourcesRadioButton.text=Matches may be from any data source CommonFilesPanel.cancelButton.text=Cancel CommonFilesPanel.cancelButton.actionCommand=Cancel CommonFilesPanel.selectedFileCategoriesButton.text=Match on the following file categories: @@ -17,5 +15,7 @@ CommonFilesPanel.jRadioButton1.text=jRadioButton1 CommonFilesPanel.jRadioButton2.text=Correlate amongst external cases (compares files in current case with Central Repo) CommonFilesPanel.intraCaseRadio.label=Correlate within current case only CommonFilesPanel.interCaseRadio.label=Correlate amongst all known cases (uses Central Repo) -CommonFilesPanel.anCentralRepoCaseRadio.text_1=Matches may be from any Central Repo case -CommonFilesPanel.specificCentralRepoCaseRadio.text_1=Matches must be from the following Central Repo case: +IntraCasePanel.allDataSourcesRadioButton.text=Matches may be from any data source +IntraCasePanel.withinDataSourceRadioButton.text=At least one match must appear in the data source selected below: +InterCasePanel.anCentralRepoCaseRadio.text=Matches may be from any Central Repo case +InterCasePanel.specificCentralRepoCaseRadio.text=Matches must be from the following Central Repo case: diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.form b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.form index 8c82dd1626..4dd238ee8a 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.form +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.form @@ -28,61 +28,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -91,6 +36,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -104,20 +77,10 @@ - - - - - - - + - - - - @@ -127,7 +90,7 @@ - + @@ -151,48 +114,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -315,44 +236,7 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java index 50e7de91a9..737c9c2684 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java @@ -18,6 +18,7 @@ */ package org.sleuthkit.autopsy.commonfilesearch; +import java.awt.event.ActionEvent; import java.io.File; import java.sql.ResultSet; import java.sql.SQLException; @@ -57,9 +58,6 @@ public final class CommonFilesPanel extends javax.swing.JPanel { private static final Long NO_DATA_SOURCE_SELECTED = -1L; - private ComboBoxModel dataSourcesList = new DataSourceComboBoxModel(); - private Map dataSourceMap; - private static final Logger LOGGER = Logger.getLogger(CommonFilesPanel.class.getName()); private boolean singleDataSource = false; private String selectedDataSource = ""; @@ -74,140 +72,10 @@ public final class CommonFilesPanel extends javax.swing.JPanel { "CommonFilesPanel.exception=Unexpected Exception loading DataSources."}) public CommonFilesPanel() { initComponents(); - - this.setupDataSources(); this.errorText.setVisible(false); } - /** - * Sets up the data sources dropdown and returns the data sources map for - * future usage. - * - * @return a mapping of data source ids to data source names - */ - @NbBundle.Messages({ - "CommonFilesPanel.buildDataSourceMap.done.tskCoreException=Unable to run query against DB.", - "CommonFilesPanel.buildDataSourceMap.done.noCurrentCaseException=Unable to open case file.", - "CommonFilesPanel.buildDataSourceMap.done.exception=Unexpected exception building data sources map.", - "CommonFilesPanel.buildDataSourceMap.done.interupted=Something went wrong building the Common Files Search dialog box.", - "CommonFilesPanel.buildDataSourceMap.done.sqlException=Unable to query db for data sources.", - "CommonFilesPanel.buildDataSourcesMap.updateUi.noDataSources=No data sources were found."}) - private void setupDataSources() { - - new SwingWorker, Void>() { - - private static final String SELECT_DATA_SOURCES_LOGICAL = "select obj_id, name from tsk_files where obj_id in (SELECT obj_id FROM tsk_objects WHERE obj_id in (select obj_id from data_source_info))"; - - private static final String SELECT_DATA_SOURCES_IMAGE = "select obj_id, name from tsk_image_names where obj_id in (SELECT obj_id FROM tsk_objects WHERE obj_id in (select obj_id from data_source_info))"; - - private void updateUi() { - - String[] dataSourcesNames = new String[CommonFilesPanel.this.dataSourceMap.size()]; - - //only enable all this stuff if we actually have datasources - if (dataSourcesNames.length > 0) { - dataSourcesNames = CommonFilesPanel.this.dataSourceMap.values().toArray(dataSourcesNames); - CommonFilesPanel.this.dataSourcesList = new DataSourceComboBoxModel(dataSourcesNames); - CommonFilesPanel.this.selectDataSourceComboBox.setModel(CommonFilesPanel.this.dataSourcesList); - - boolean multipleDataSources = this.caseHasMultipleSources(); - CommonFilesPanel.this.allDataSourcesRadioButton.setEnabled(multipleDataSources); - CommonFilesPanel.this.allDataSourcesRadioButton.setSelected(multipleDataSources); - - if (!multipleDataSources) { - CommonFilesPanel.this.withinDataSourceRadioButton.setSelected(true); - withinDataSourceSelected(true); - } - - CommonFilesPanel.this.searchButton.setEnabled(true); - } else { - MessageNotifyUtil.Message.info(Bundle.CommonFilesPanel_buildDataSourcesMap_updateUi_noDataSources()); - CommonFilesPanel.this.cancelButtonActionPerformed(null); - } - } - - private boolean caseHasMultipleSources() { - return CommonFilesPanel.this.dataSourceMap.size() >= 2; - } - - private void loadLogicalSources(SleuthkitCase tskDb, Map dataSouceMap) throws TskCoreException, SQLException { - //try block releases resources - exceptions are handled in done() - try ( - CaseDbQuery query = tskDb.executeQuery(SELECT_DATA_SOURCES_LOGICAL); - ResultSet resultSet = query.getResultSet()) { - while (resultSet.next()) { - Long objectId = resultSet.getLong(1); - String dataSourceName = resultSet.getString(2); - dataSouceMap.put(objectId, dataSourceName); - } - } - } - - private void loadImageSources(SleuthkitCase tskDb, Map dataSouceMap) throws SQLException, TskCoreException { - //try block releases resources - exceptions are handled in done() - try ( - CaseDbQuery query = tskDb.executeQuery(SELECT_DATA_SOURCES_IMAGE); - ResultSet resultSet = query.getResultSet()) { - - while (resultSet.next()) { - Long objectId = resultSet.getLong(1); - String dataSourceName = resultSet.getString(2); - File image = new File(dataSourceName); - String dataSourceNameTrimmed = image.getName(); - dataSouceMap.put(objectId, dataSourceNameTrimmed); - } - } - } - - @Override - protected Map doInBackground() throws NoCurrentCaseException, TskCoreException, SQLException { - - Map dataSouceMap = new HashMap<>(); - - Case currentCase = Case.getCurrentCaseThrows(); - SleuthkitCase tskDb = currentCase.getSleuthkitCase(); - - loadLogicalSources(tskDb, dataSouceMap); - - loadImageSources(tskDb, dataSouceMap); - - return dataSouceMap; - } - - @Override - protected void done() { - - try { - CommonFilesPanel.this.dataSourceMap = this.get(); - - updateUi(); - - } catch (InterruptedException ex) { - LOGGER.log(Level.SEVERE, "Interrupted while building Common Files Search dialog.", ex); - MessageNotifyUtil.Message.error(Bundle.CommonFilesPanel_buildDataSourceMap_done_interupted()); - } catch (ExecutionException ex) { - String errorMessage; - Throwable inner = ex.getCause(); - if (inner instanceof TskCoreException) { - LOGGER.log(Level.SEVERE, "Failed to load data sources from database.", ex); - errorMessage = Bundle.CommonFilesPanel_buildDataSourceMap_done_tskCoreException(); - } else if (inner instanceof NoCurrentCaseException) { - LOGGER.log(Level.SEVERE, "Current case has been closed.", ex); - errorMessage = Bundle.CommonFilesPanel_buildDataSourceMap_done_noCurrentCaseException(); - } else if (inner instanceof SQLException) { - LOGGER.log(Level.SEVERE, "Unable to query db for data sources.", ex); - errorMessage = Bundle.CommonFilesPanel_buildDataSourceMap_done_sqlException(); - } else { - LOGGER.log(Level.SEVERE, "Unexpected exception while building Common Files Search dialog panel.", ex); - errorMessage = Bundle.CommonFilesPanel_buildDataSourceMap_done_exception(); - } - MessageNotifyUtil.Message.error(errorMessage); - } - } - }.execute(); - } - @NbBundle.Messages({ "CommonFilesPanel.search.results.titleAll=Common Files (All Data Sources)", "CommonFilesPanel.search.results.titleSingle=Common Files (Match Within Data Source: %s)", @@ -230,7 +98,7 @@ public final class CommonFilesPanel extends javax.swing.JPanel { private void setTitleForSingleSource(Long dataSourceId) { final String CommonFilesPanel_search_results_titleSingle = Bundle.CommonFilesPanel_search_results_titleSingle(); - final Object[] dataSourceName = new Object[]{dataSourceMap.get(dataSourceId)}; + final Object[] dataSourceName = new Object[]{CommonFilesPanel.this.intraCasePanel.getDataSourceMap().get(dataSourceId)}; this.tabTitle = String.format(CommonFilesPanel_search_results_titleSingle, dataSourceName); } @@ -238,7 +106,7 @@ public final class CommonFilesPanel extends javax.swing.JPanel { private Long determineDataSourceId() { Long selectedObjId = CommonFilesPanel.NO_DATA_SOURCE_SELECTED; if (CommonFilesPanel.this.singleDataSource) { - for (Entry dataSource : CommonFilesPanel.this.dataSourceMap.entrySet()) { + for (Entry dataSource : CommonFilesPanel.this.intraCasePanel.getDataSourceMap().entrySet()) { if (dataSource.getValue().equals(CommonFilesPanel.this.selectedDataSource)) { selectedObjId = dataSource.getKey(); break; @@ -265,11 +133,11 @@ public final class CommonFilesPanel extends javax.swing.JPanel { } } if (dataSourceId == CommonFilesPanel.NO_DATA_SOURCE_SELECTED) { - builder = new AllDataSourcesCommonFilesAlgorithm(CommonFilesPanel.this.dataSourceMap, filterByMedia, filterByDocuments); + builder = new AllDataSourcesCommonFilesAlgorithm(CommonFilesPanel.this.intraCasePanel.getDataSourceMap(), filterByMedia, filterByDocuments); setTitleForAllDataSources(); } else { - builder = new SingleDataSource(dataSourceId, CommonFilesPanel.this.dataSourceMap, filterByMedia, filterByDocuments); + builder = new SingleDataSource(dataSourceId, CommonFilesPanel.this.intraCasePanel.getDataSourceMap(), filterByMedia, filterByDocuments); setTitleForSingleSource(dataSourceId); }// else if(false) { @@ -343,9 +211,6 @@ public final class CommonFilesPanel extends javax.swing.JPanel { interIntraButtonGroup = new javax.swing.ButtonGroup(); caseSelectionButtonGroup = new javax.swing.ButtonGroup(); searchButton = new javax.swing.JButton(); - allDataSourcesRadioButton = new javax.swing.JRadioButton(); - withinDataSourceRadioButton = new javax.swing.JRadioButton(); - selectDataSourceComboBox = new javax.swing.JComboBox<>(); cancelButton = new javax.swing.JButton(); allFileCategoriesRadioButton = new javax.swing.JRadioButton(); selectedFileCategoriesButton = new javax.swing.JRadioButton(); @@ -356,9 +221,7 @@ public final class CommonFilesPanel extends javax.swing.JPanel { commonFilesSearchLabel1 = new javax.swing.JLabel(); intraCaseRadio = new javax.swing.JRadioButton(); interCaseRadio = new javax.swing.JRadioButton(); - anCentralRepoCaseRadio = new javax.swing.JRadioButton(); - specificCentralRepoCaseRadio = new javax.swing.JRadioButton(); - caseComboBox = new javax.swing.JComboBox<>(); + intraCasePanel = new org.sleuthkit.autopsy.commonfilesearch.IntraCasePanel(); org.openide.awt.Mnemonics.setLocalizedText(searchButton, org.openide.util.NbBundle.getMessage(CommonFilesPanel.class, "CommonFilesPanel.searchButton.text")); // NOI18N searchButton.setEnabled(false); @@ -369,32 +232,6 @@ public final class CommonFilesPanel extends javax.swing.JPanel { } }); - dataSourcesButtonGroup.add(allDataSourcesRadioButton); - org.openide.awt.Mnemonics.setLocalizedText(allDataSourcesRadioButton, org.openide.util.NbBundle.getMessage(CommonFilesPanel.class, "CommonFilesPanel.allDataSourcesRadioButton.text")); // NOI18N - allDataSourcesRadioButton.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); - allDataSourcesRadioButton.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - allDataSourcesRadioButtonActionPerformed(evt); - } - }); - - dataSourcesButtonGroup.add(withinDataSourceRadioButton); - org.openide.awt.Mnemonics.setLocalizedText(withinDataSourceRadioButton, org.openide.util.NbBundle.getMessage(CommonFilesPanel.class, "CommonFilesPanel.withinDataSourceRadioButton.text")); // NOI18N - withinDataSourceRadioButton.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); - withinDataSourceRadioButton.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - withinDataSourceRadioButtonActionPerformed(evt); - } - }); - - selectDataSourceComboBox.setModel(dataSourcesList); - selectDataSourceComboBox.setEnabled(false); - selectDataSourceComboBox.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - selectDataSourceComboBoxActionPerformed(evt); - } - }); - org.openide.awt.Mnemonics.setLocalizedText(cancelButton, org.openide.util.NbBundle.getMessage(CommonFilesPanel.class, "CommonFilesPanel.cancelButton.text")); // NOI18N cancelButton.setActionCommand(org.openide.util.NbBundle.getMessage(CommonFilesPanel.class, "CommonFilesPanel.cancelButton.actionCommand")); // NOI18N cancelButton.setHorizontalTextPosition(javax.swing.SwingConstants.LEADING); @@ -465,73 +302,40 @@ public final class CommonFilesPanel extends javax.swing.JPanel { } }); - caseSelectionButtonGroup.add(anCentralRepoCaseRadio); - anCentralRepoCaseRadio.setSelected(true); - org.openide.awt.Mnemonics.setLocalizedText(anCentralRepoCaseRadio, org.openide.util.NbBundle.getMessage(CommonFilesPanel.class, "CommonFilesPanel.anCentralRepoCaseRadio.text_1")); // NOI18N - anCentralRepoCaseRadio.setEnabled(false); - - caseSelectionButtonGroup.add(specificCentralRepoCaseRadio); - org.openide.awt.Mnemonics.setLocalizedText(specificCentralRepoCaseRadio, org.openide.util.NbBundle.getMessage(CommonFilesPanel.class, "CommonFilesPanel.specificCentralRepoCaseRadio.text_1")); // NOI18N - specificCentralRepoCaseRadio.setEnabled(false); - - caseComboBox.setModel(new javax.swing.DefaultComboBoxModel<>(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" })); - caseComboBox.setEnabled(false); - javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addContainerGap() - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(commonFilesSearchLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGroup(layout.createSequentialGroup() - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(categoriesLabel) - .addGroup(layout.createSequentialGroup() - .addGap(6, 6, 6) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(allFileCategoriesRadioButton) - .addComponent(selectedFileCategoriesButton) - .addGroup(layout.createSequentialGroup() - .addGap(21, 21, 21) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(pictureVideoCheckbox) - .addComponent(documentsCheckbox)))))) - .addGap(277, 277, 277)) - .addComponent(intraCaseRadio) - .addGroup(layout.createSequentialGroup() - .addGap(21, 21, 21) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(withinDataSourceRadioButton) - .addComponent(allDataSourcesRadioButton))))) - .addGroup(layout.createSequentialGroup() - .addGap(47, 47, 47) - .addComponent(selectDataSourceComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 261, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addGroup(layout.createSequentialGroup() - .addContainerGap() - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(interCaseRadio) - .addGroup(layout.createSequentialGroup() - .addGap(21, 21, 21) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(anCentralRepoCaseRadio) - .addComponent(specificCentralRepoCaseRadio) - .addGroup(layout.createSequentialGroup() - .addGap(21, 21, 21) - .addComponent(caseComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 261, javax.swing.GroupLayout.PREFERRED_SIZE))))))) - .addGap(0, 0, Short.MAX_VALUE)) .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() .addGap(0, 0, Short.MAX_VALUE) .addComponent(errorText) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(searchButton) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(cancelButton))) + .addComponent(cancelButton)) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(commonFilesSearchLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(categoriesLabel) + .addGroup(layout.createSequentialGroup() + .addGap(6, 6, 6) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(allFileCategoriesRadioButton) + .addComponent(selectedFileCategoriesButton) + .addGroup(layout.createSequentialGroup() + .addGap(21, 21, 21) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(pictureVideoCheckbox) + .addComponent(documentsCheckbox))))) + .addComponent(intraCaseRadio) + .addGroup(layout.createSequentialGroup() + .addGap(21, 21, 21) + .addComponent(intraCasePanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(interCaseRadio)) + .addGap(0, 13, Short.MAX_VALUE))) .addContainerGap()) ); layout.setVerticalGroup( @@ -542,20 +346,10 @@ public final class CommonFilesPanel extends javax.swing.JPanel { .addGap(18, 18, 18) .addComponent(intraCaseRadio) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(allDataSourcesRadioButton) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(withinDataSourceRadioButton) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(selectDataSourceComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(interCaseRadio) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(anCentralRepoCaseRadio) + .addComponent(intraCasePanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(specificCentralRepoCaseRadio) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(caseComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(categoriesLabel) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(selectedFileCategoriesButton) @@ -565,7 +359,7 @@ public final class CommonFilesPanel extends javax.swing.JPanel { .addComponent(documentsCheckbox) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(allFileCategoriesRadioButton) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(cancelButton) .addComponent(searchButton) @@ -579,24 +373,6 @@ public final class CommonFilesPanel extends javax.swing.JPanel { SwingUtilities.windowForComponent(this).dispose(); }//GEN-LAST:event_searchButtonActionPerformed - private void allDataSourcesRadioButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_allDataSourcesRadioButtonActionPerformed - selectDataSourceComboBox.setEnabled(!allDataSourcesRadioButton.isSelected()); - singleDataSource = false; - }//GEN-LAST:event_allDataSourcesRadioButtonActionPerformed - - private void selectDataSourceComboBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_selectDataSourceComboBoxActionPerformed - final Object selectedItem = selectDataSourceComboBox.getSelectedItem(); - if (selectedItem != null) { - selectedDataSource = selectedItem.toString(); - } else { - selectedDataSource = ""; - } - }//GEN-LAST:event_selectDataSourceComboBoxActionPerformed - - private void withinDataSourceRadioButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_withinDataSourceRadioButtonActionPerformed - withinDataSourceSelected(withinDataSourceRadioButton.isSelected()); - }//GEN-LAST:event_withinDataSourceRadioButtonActionPerformed - private void cancelButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cancelButtonActionPerformed SwingUtilities.windowForComponent(this).dispose(); }//GEN-LAST:event_cancelButtonActionPerformed @@ -619,24 +395,14 @@ public final class CommonFilesPanel extends javax.swing.JPanel { }//GEN-LAST:event_documentsCheckboxActionPerformed private void intraCaseRadioActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_intraCaseRadioActionPerformed - this.allDataSourcesRadioButton.setEnabled(true); - this.withinDataSourceRadioButton.setEnabled(true); - this.selectDataSourceComboBox.setEnabled(true); - - this.anCentralRepoCaseRadio.setEnabled(false); - this.specificCentralRepoCaseRadio.setEnabled(false); - this.caseComboBox.setEnabled(false); + this.intraCasePanel.setVisible(true); + + //TODO disable intercase panel }//GEN-LAST:event_intraCaseRadioActionPerformed private void interCaseRadioActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_interCaseRadioActionPerformed - this.anCentralRepoCaseRadio.setEnabled(true); - this.specificCentralRepoCaseRadio.setEnabled(true); - this.caseComboBox.setEnabled(true); - - this.allDataSourcesRadioButton.setEnabled(false); - this.withinDataSourceRadioButton.setEnabled(false); - this.selectDataSourceComboBox.setEnabled(false); - + this.intraCasePanel.setVisible(false); + //TODO enable intercase panel }//GEN-LAST:event_interCaseRadioActionPerformed private void toggleErrorTextAndSearchBox() { @@ -649,14 +415,6 @@ public final class CommonFilesPanel extends javax.swing.JPanel { } } - private void withinDataSourceSelected(boolean selected) { - selectDataSourceComboBox.setEnabled(selected); - if (selectDataSourceComboBox.isEnabled()) { - selectDataSourceComboBox.setSelectedIndex(0); - singleDataSource = true; - } - } - private void manageCheckBoxState() { if (this.allFileCategoriesRadioButton.isSelected()) { @@ -681,11 +439,8 @@ public final class CommonFilesPanel extends javax.swing.JPanel { } // Variables declaration - do not modify//GEN-BEGIN:variables - private javax.swing.JRadioButton allDataSourcesRadioButton; private javax.swing.JRadioButton allFileCategoriesRadioButton; - private javax.swing.JRadioButton anCentralRepoCaseRadio; private javax.swing.JButton cancelButton; - private javax.swing.JComboBox caseComboBox; private javax.swing.ButtonGroup caseSelectionButtonGroup; private javax.swing.JLabel categoriesLabel; private javax.swing.JLabel commonFilesSearchLabel1; @@ -695,12 +450,14 @@ public final class CommonFilesPanel extends javax.swing.JPanel { private javax.swing.ButtonGroup fileTypeFilterButtonGroup; private javax.swing.JRadioButton interCaseRadio; private javax.swing.ButtonGroup interIntraButtonGroup; + private org.sleuthkit.autopsy.commonfilesearch.IntraCasePanel intraCasePanel; private javax.swing.JRadioButton intraCaseRadio; private javax.swing.JCheckBox pictureVideoCheckbox; private javax.swing.JButton searchButton; - private javax.swing.JComboBox selectDataSourceComboBox; private javax.swing.JRadioButton selectedFileCategoriesButton; - private javax.swing.JRadioButton specificCentralRepoCaseRadio; - private javax.swing.JRadioButton withinDataSourceRadioButton; // End of variables declaration//GEN-END:variables + + void setSearchButtonEnabled(boolean b) { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.form b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.form new file mode 100644 index 0000000000..e6324a61ab --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.form @@ -0,0 +1,82 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.java new file mode 100644 index 0000000000..90f8eafce0 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.java @@ -0,0 +1,91 @@ +/* + * + * Autopsy Forensic Browser + * + * Copyright 2018 Basis Technology Corp. + * Contact: carrier sleuthkit 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.commonfilesearch; + +/** + * + * @author bsweeney + */ +public class InterCasePanel extends javax.swing.JPanel { + + /** + * Creates new form InterCasePanel + */ + public InterCasePanel() { + initComponents(); + } + + /** + * This method is called from within the constructor to initialize the form. + * WARNING: Do NOT modify this code. The content of this method is always + * regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // //GEN-BEGIN:initComponents + private void initComponents() { + + anCentralRepoCaseRadio = new javax.swing.JRadioButton(); + specificCentralRepoCaseRadio = new javax.swing.JRadioButton(); + caseComboBox = new javax.swing.JComboBox<>(); + + anCentralRepoCaseRadio.setSelected(true); + org.openide.awt.Mnemonics.setLocalizedText(anCentralRepoCaseRadio, org.openide.util.NbBundle.getMessage(InterCasePanel.class, "InterCasePanel.anCentralRepoCaseRadio.text")); // NOI18N + anCentralRepoCaseRadio.setEnabled(false); + + org.openide.awt.Mnemonics.setLocalizedText(specificCentralRepoCaseRadio, org.openide.util.NbBundle.getMessage(InterCasePanel.class, "InterCasePanel.specificCentralRepoCaseRadio.text")); // NOI18N + specificCentralRepoCaseRadio.setEnabled(false); + + caseComboBox.setModel(new javax.swing.DefaultComboBoxModel<>(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" })); + caseComboBox.setEnabled(false); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(anCentralRepoCaseRadio) + .addComponent(specificCentralRepoCaseRadio) + .addGroup(layout.createSequentialGroup() + .addGap(21, 21, 21) + .addComponent(caseComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 261, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addComponent(anCentralRepoCaseRadio) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(specificCentralRepoCaseRadio) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(caseComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + }// //GEN-END:initComponents + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JRadioButton anCentralRepoCaseRadio; + private javax.swing.JComboBox caseComboBox; + private javax.swing.JRadioButton specificCentralRepoCaseRadio; + // End of variables declaration//GEN-END:variables +} diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCasePanel.form b/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCasePanel.form new file mode 100644 index 0000000000..b8e270890a --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCasePanel.form @@ -0,0 +1,95 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCasePanel.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCasePanel.java new file mode 100644 index 0000000000..a8dae34abd --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCasePanel.java @@ -0,0 +1,317 @@ +/* + * + * Autopsy Forensic Browser + * + * Copyright 2018 Basis Technology Corp. + * Contact: carrier sleuthkit 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.commonfilesearch; + +import java.io.File; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.ExecutionException; +import java.util.logging.Level; +import javax.swing.ComboBoxModel; +import javax.swing.SwingUtilities; +import javax.swing.SwingWorker; +import org.openide.util.NbBundle; +import org.sleuthkit.autopsy.casemodule.Case; +import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; +import org.sleuthkit.autopsy.coreutils.Logger; +import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil; +import org.sleuthkit.datamodel.SleuthkitCase; +import org.sleuthkit.datamodel.TskCoreException; + +/** + * + * @author bsweeney + */ +public class IntraCasePanel extends javax.swing.JPanel { + + private static final long serialVersionUID = 1L; + + private static final Logger LOGGER = Logger.getLogger(CommonFilesPanel.class.getName()); + + private boolean singleDataSource; + private String selectedDataSource; + private ComboBoxModel dataSourcesList = new DataSourceComboBoxModel(); + private Map dataSourceMap; + private CommonFilesPanel parent; + + /** + * Creates new form IntraCasePanel + */ + public IntraCasePanel() { + initComponents(); + + this.setupDataSources(); + } + + public void setParent(CommonFilesPanel parent){ + this.parent = parent; + } + + public void setDataSourceList(){ + //TODO + } + + public boolean isSingleDataSource(){ + return this.singleDataSource; + } + + public String getSelectedDataSource(){ + if(this.singleDataSource && this.selectedDataSource != null){ + return selectedDataSource; + } else { + return ""; + } + } + + public Map getDataSourceMap(){ + return this.dataSourceMap; + } + + /** + * Sets up the data sources dropdown and returns the data sources map for + * future usage. + * + * @return a mapping of data source ids to data source names + */ + @NbBundle.Messages({ + "IntraCasePanel.setupDataSources.done.tskCoreException=Unable to run query against DB.", + "IntraCasePanel.setupDataSources.done.noCurrentCaseException=Unable to open case file.", + "IntraCasePanel.setupDataSources.done.exception=Unexpected exception building data sources map.", + "IntraCasePanel.setupDataSources.done.interupted=Something went wrong building the Common Files Search dialog box.", + "IntraCasePanel.setupDataSources.done.sqlException=Unable to query db for data sources.", + "IntraCasePanel.setupDataSources.updateUi.noDataSources=No data sources were found."}) + private void setupDataSources() { + + new SwingWorker, Void>() { + + private static final String SELECT_DATA_SOURCES_LOGICAL = "select obj_id, name from tsk_files where obj_id in (SELECT obj_id FROM tsk_objects WHERE obj_id in (select obj_id from data_source_info))"; + + private static final String SELECT_DATA_SOURCES_IMAGE = "select obj_id, name from tsk_image_names where obj_id in (SELECT obj_id FROM tsk_objects WHERE obj_id in (select obj_id from data_source_info))"; + + private void updateUi() { + + String[] dataSourcesNames = new String[IntraCasePanel.this.dataSourceMap.size()]; + + //only enable all this stuff if we actually have datasources + if (dataSourcesNames.length > 0) { + dataSourcesNames = IntraCasePanel.this.dataSourceMap.values().toArray(dataSourcesNames); + //TODO use setter on intra case panel + IntraCasePanel.this.dataSourcesList = new DataSourceComboBoxModel(dataSourcesNames); + IntraCasePanel.this.selectDataSourceComboBox.setModel(IntraCasePanel.this.dataSourcesList); + + boolean multipleDataSources = this.caseHasMultipleSources(); + IntraCasePanel.this.allDataSourcesRadioButton.setEnabled(multipleDataSources); + IntraCasePanel.this.allDataSourcesRadioButton.setSelected(multipleDataSources); + + if (!multipleDataSources) { + IntraCasePanel.this.withinDataSourceRadioButton.setSelected(true); + withinDataSourceSelected(true); + } + + IntraCasePanel.this.parent.setSearchButtonEnabled(true); + } else { + MessageNotifyUtil.Message.info(Bundle.IntraCasePanel_setupDataSources_updateUi_noDataSources()); + SwingUtilities.windowForComponent(IntraCasePanel.this.parent).dispose(); + } + } + + private boolean caseHasMultipleSources() { + return IntraCasePanel.this.dataSourceMap.size() >= 2; + } + + private void loadLogicalSources(SleuthkitCase tskDb, Map dataSouceMap) throws TskCoreException, SQLException { + //try block releases resources - exceptions are handled in done() + try ( + SleuthkitCase.CaseDbQuery query = tskDb.executeQuery(SELECT_DATA_SOURCES_LOGICAL); + ResultSet resultSet = query.getResultSet()) { + while (resultSet.next()) { + Long objectId = resultSet.getLong(1); + String dataSourceName = resultSet.getString(2); + dataSouceMap.put(objectId, dataSourceName); + } + } + } + + private void loadImageSources(SleuthkitCase tskDb, Map dataSouceMap) throws SQLException, TskCoreException { + //try block releases resources - exceptions are handled in done() + try ( + SleuthkitCase.CaseDbQuery query = tskDb.executeQuery(SELECT_DATA_SOURCES_IMAGE); + ResultSet resultSet = query.getResultSet()) { + + while (resultSet.next()) { + Long objectId = resultSet.getLong(1); + String dataSourceName = resultSet.getString(2); + File image = new File(dataSourceName); + String dataSourceNameTrimmed = image.getName(); + dataSouceMap.put(objectId, dataSourceNameTrimmed); + } + } + } + + @Override + protected Map doInBackground() throws NoCurrentCaseException, TskCoreException, SQLException { + + Map dataSouceMap = new HashMap<>(); + + Case currentCase = Case.getCurrentCaseThrows(); + SleuthkitCase tskDb = currentCase.getSleuthkitCase(); + + loadLogicalSources(tskDb, dataSouceMap); + + loadImageSources(tskDb, dataSouceMap); + + return dataSouceMap; + } + + @Override + protected void done() { + + try { + IntraCasePanel.this.dataSourceMap = this.get(); + + updateUi(); + + } catch (InterruptedException ex) { + LOGGER.log(Level.SEVERE, "Interrupted while building Common Files Search dialog.", ex); + MessageNotifyUtil.Message.error(Bundle.IntraCasePanel_setupDataSources_done_interupted()); + } catch (ExecutionException ex) { + String errorMessage; + Throwable inner = ex.getCause(); + if (inner instanceof TskCoreException) { + LOGGER.log(Level.SEVERE, "Failed to load data sources from database.", ex); + errorMessage = Bundle.IntraCasePanel_setupDataSources_done_tskCoreException(); + } else if (inner instanceof NoCurrentCaseException) { + LOGGER.log(Level.SEVERE, "Current case has been closed.", ex); + errorMessage = Bundle.IntraCasePanel_setupDataSources_done_noCurrentCaseException(); + } else if (inner instanceof SQLException) { + LOGGER.log(Level.SEVERE, "Unable to query db for data sources.", ex); + errorMessage = Bundle.IntraCasePanel_setupDataSources_done_sqlException(); + } else { + LOGGER.log(Level.SEVERE, "Unexpected exception while building Common Files Search dialog panel.", ex); + errorMessage = Bundle.IntraCasePanel_setupDataSources_done_exception(); + } + MessageNotifyUtil.Message.error(errorMessage); + } + } + }.execute(); + } + + /** + * This method is called from within the constructor to initialize the form. + * WARNING: Do NOT modify this code. The content of this method is always + * regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // //GEN-BEGIN:initComponents + private void initComponents() { + + buttonGroup = new javax.swing.ButtonGroup(); + allDataSourcesRadioButton = new javax.swing.JRadioButton(); + withinDataSourceRadioButton = new javax.swing.JRadioButton(); + selectDataSourceComboBox = new javax.swing.JComboBox<>(); + + buttonGroup.add(allDataSourcesRadioButton); + org.openide.awt.Mnemonics.setLocalizedText(allDataSourcesRadioButton, org.openide.util.NbBundle.getMessage(IntraCasePanel.class, "IntraCasePanel.allDataSourcesRadioButton.text")); // NOI18N + allDataSourcesRadioButton.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); + allDataSourcesRadioButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + allDataSourcesRadioButtonActionPerformed(evt); + } + }); + + buttonGroup.add(withinDataSourceRadioButton); + org.openide.awt.Mnemonics.setLocalizedText(withinDataSourceRadioButton, org.openide.util.NbBundle.getMessage(IntraCasePanel.class, "IntraCasePanel.withinDataSourceRadioButton.text")); // NOI18N + withinDataSourceRadioButton.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); + withinDataSourceRadioButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + withinDataSourceRadioButtonActionPerformed(evt); + } + }); + + selectDataSourceComboBox.setModel(dataSourcesList); + selectDataSourceComboBox.setEnabled(false); + selectDataSourceComboBox.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + selectDataSourceComboBoxActionPerformed(evt); + } + }); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(withinDataSourceRadioButton) + .addComponent(allDataSourcesRadioButton) + .addGroup(layout.createSequentialGroup() + .addGap(20, 20, 20) + .addComponent(selectDataSourceComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 261, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addComponent(allDataSourcesRadioButton) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(withinDataSourceRadioButton) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(selectDataSourceComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + }// //GEN-END:initComponents + + private void allDataSourcesRadioButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_allDataSourcesRadioButtonActionPerformed + selectDataSourceComboBox.setEnabled(!allDataSourcesRadioButton.isSelected()); + singleDataSource = false; + }//GEN-LAST:event_allDataSourcesRadioButtonActionPerformed + + private void withinDataSourceRadioButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_withinDataSourceRadioButtonActionPerformed + withinDataSourceSelected(withinDataSourceRadioButton.isSelected()); + }//GEN-LAST:event_withinDataSourceRadioButtonActionPerformed + + private void selectDataSourceComboBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_selectDataSourceComboBoxActionPerformed + final Object selectedItem = selectDataSourceComboBox.getSelectedItem(); + if (selectedItem != null) { + selectedDataSource = selectedItem.toString(); + } else { + selectedDataSource = ""; + } + }//GEN-LAST:event_selectDataSourceComboBoxActionPerformed + + private void withinDataSourceSelected(boolean selected) { + selectDataSourceComboBox.setEnabled(selected); + if (selectDataSourceComboBox.isEnabled()) { + selectDataSourceComboBox.setSelectedIndex(0); + singleDataSource = true; + } + } + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JRadioButton allDataSourcesRadioButton; + private javax.swing.ButtonGroup buttonGroup; + private javax.swing.JComboBox selectDataSourceComboBox; + private javax.swing.JRadioButton withinDataSourceRadioButton; + // End of variables declaration//GEN-END:variables +} From 93b64437dc3797b20a51dcfa96c0eed7065e0aef Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Tue, 15 May 2018 18:31:26 -0600 Subject: [PATCH 008/287] intra case panel wired in --- .../autopsy/commonfilesearch/CommonFilesPanel.form | 4 ---- .../autopsy/commonfilesearch/CommonFilesPanel.java | 11 +++++------ .../autopsy/commonfilesearch/IntraCasePanel.java | 5 ----- 3 files changed, 5 insertions(+), 15 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.form b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.form index 4dd238ee8a..8dee7b57fd 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.form +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.form @@ -2,14 +2,10 @@
- - - - diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java index 737c9c2684..ed3542461d 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java @@ -73,6 +73,9 @@ public final class CommonFilesPanel extends javax.swing.JPanel { public CommonFilesPanel() { initComponents(); + this.intraCasePanel.setParent(this); + //TODO set parent for intercase panel + this.errorText.setVisible(false); } @@ -206,10 +209,8 @@ public final class CommonFilesPanel extends javax.swing.JPanel { // //GEN-BEGIN:initComponents private void initComponents() { - dataSourcesButtonGroup = new javax.swing.ButtonGroup(); fileTypeFilterButtonGroup = new javax.swing.ButtonGroup(); interIntraButtonGroup = new javax.swing.ButtonGroup(); - caseSelectionButtonGroup = new javax.swing.ButtonGroup(); searchButton = new javax.swing.JButton(); cancelButton = new javax.swing.JButton(); allFileCategoriesRadioButton = new javax.swing.JRadioButton(); @@ -441,10 +442,8 @@ public final class CommonFilesPanel extends javax.swing.JPanel { // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JRadioButton allFileCategoriesRadioButton; private javax.swing.JButton cancelButton; - private javax.swing.ButtonGroup caseSelectionButtonGroup; private javax.swing.JLabel categoriesLabel; private javax.swing.JLabel commonFilesSearchLabel1; - private javax.swing.ButtonGroup dataSourcesButtonGroup; private javax.swing.JCheckBox documentsCheckbox; private javax.swing.JLabel errorText; private javax.swing.ButtonGroup fileTypeFilterButtonGroup; @@ -457,7 +456,7 @@ public final class CommonFilesPanel extends javax.swing.JPanel { private javax.swing.JRadioButton selectedFileCategoriesButton; // End of variables declaration//GEN-END:variables - void setSearchButtonEnabled(boolean b) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + void setSearchButtonEnabled(boolean enabled) { + this.searchButton.setEnabled(enabled); } } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCasePanel.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCasePanel.java index a8dae34abd..12f0bb5a34 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCasePanel.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCasePanel.java @@ -66,10 +66,6 @@ public class IntraCasePanel extends javax.swing.JPanel { this.parent = parent; } - public void setDataSourceList(){ - //TODO - } - public boolean isSingleDataSource(){ return this.singleDataSource; } @@ -114,7 +110,6 @@ public class IntraCasePanel extends javax.swing.JPanel { //only enable all this stuff if we actually have datasources if (dataSourcesNames.length > 0) { dataSourcesNames = IntraCasePanel.this.dataSourceMap.values().toArray(dataSourcesNames); - //TODO use setter on intra case panel IntraCasePanel.this.dataSourcesList = new DataSourceComboBoxModel(dataSourcesNames); IntraCasePanel.this.selectDataSourceComboBox.setModel(IntraCasePanel.this.dataSourcesList); From 9091ed7748a11bcce41e170a7bb8c381e3fbb46a Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Tue, 15 May 2018 19:27:36 -0600 Subject: [PATCH 009/287] intercase panel wired in partially --- .../commonfilesearch/CommonFilesPanel.form | 106 +++++++++++------- .../commonfilesearch/CommonFilesPanel.java | 88 ++++++++------- .../commonfilesearch/InterCasePanel.form | 13 ++- .../commonfilesearch/InterCasePanel.java | 7 +- 4 files changed, 126 insertions(+), 88 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.form b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.form index 8dee7b57fd..0892974a83 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.form +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.form @@ -6,6 +6,8 @@ + + @@ -23,45 +25,39 @@ + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -74,25 +70,31 @@ - - + + - - - - - - - - + + + + + + + + + + + + + + - + @@ -232,7 +234,25 @@ - - + + + + + + + + + + + + + + + + + + + + diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java index ed3542461d..85247f5a01 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java @@ -211,6 +211,7 @@ public final class CommonFilesPanel extends javax.swing.JPanel { fileTypeFilterButtonGroup = new javax.swing.ButtonGroup(); interIntraButtonGroup = new javax.swing.ButtonGroup(); + interCasePanel1 = new org.sleuthkit.autopsy.commonfilesearch.InterCasePanel(); searchButton = new javax.swing.JButton(); cancelButton = new javax.swing.JButton(); allFileCategoriesRadioButton = new javax.swing.JRadioButton(); @@ -222,6 +223,8 @@ public final class CommonFilesPanel extends javax.swing.JPanel { commonFilesSearchLabel1 = new javax.swing.JLabel(); intraCaseRadio = new javax.swing.JRadioButton(); interCaseRadio = new javax.swing.JRadioButton(); + layoutPanel = new java.awt.Panel(); + interCasePanel = new org.sleuthkit.autopsy.commonfilesearch.InterCasePanel(); intraCasePanel = new org.sleuthkit.autopsy.commonfilesearch.IntraCasePanel(); org.openide.awt.Mnemonics.setLocalizedText(searchButton, org.openide.util.NbBundle.getMessage(CommonFilesPanel.class, "CommonFilesPanel.searchButton.text")); // NOI18N @@ -303,41 +306,41 @@ public final class CommonFilesPanel extends javax.swing.JPanel { } }); + layoutPanel.setLayout(new java.awt.CardLayout()); + layoutPanel.add(interCasePanel, "card2"); + layoutPanel.add(intraCasePanel, "card3"); + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() + .addContainerGap() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(commonFilesSearchLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(categoriesLabel) + .addComponent(intraCaseRadio) + .addComponent(interCaseRadio) + .addGroup(layout.createSequentialGroup() + .addGap(10, 10, 10) + .addComponent(layoutPanel, javax.swing.GroupLayout.PREFERRED_SIZE, 364, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(layout.createSequentialGroup() + .addGap(6, 6, 6) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(allFileCategoriesRadioButton) + .addComponent(selectedFileCategoriesButton) + .addGroup(layout.createSequentialGroup() + .addGap(21, 21, 21) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(pictureVideoCheckbox) + .addComponent(documentsCheckbox))))) .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() - .addGap(0, 0, Short.MAX_VALUE) .addComponent(errorText) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(searchButton) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(cancelButton)) - .addGroup(layout.createSequentialGroup() - .addContainerGap() - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(commonFilesSearchLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(categoriesLabel) - .addGroup(layout.createSequentialGroup() - .addGap(6, 6, 6) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(allFileCategoriesRadioButton) - .addComponent(selectedFileCategoriesButton) - .addGroup(layout.createSequentialGroup() - .addGap(21, 21, 21) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(pictureVideoCheckbox) - .addComponent(documentsCheckbox))))) - .addComponent(intraCaseRadio) - .addGroup(layout.createSequentialGroup() - .addGap(21, 21, 21) - .addComponent(intraCasePanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addComponent(interCaseRadio)) - .addGap(0, 13, Short.MAX_VALUE))) - .addContainerGap()) + .addComponent(cancelButton))) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) @@ -348,24 +351,27 @@ public final class CommonFilesPanel extends javax.swing.JPanel { .addComponent(intraCaseRadio) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(interCaseRadio) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(intraCasePanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(0, 0, 0) + .addComponent(layoutPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(categoriesLabel) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(selectedFileCategoriesButton) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(pictureVideoCheckbox) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(documentsCheckbox) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(allFileCategoriesRadioButton) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addGap(80, 80, 80) + .addComponent(allFileCategoriesRadioButton)) + .addGroup(layout.createSequentialGroup() + .addComponent(selectedFileCategoriesButton) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(pictureVideoCheckbox) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(documentsCheckbox))) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(cancelButton) .addComponent(searchButton) .addComponent(errorText)) - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addContainerGap()) ); }// //GEN-END:initComponents @@ -396,14 +402,15 @@ public final class CommonFilesPanel extends javax.swing.JPanel { }//GEN-LAST:event_documentsCheckboxActionPerformed private void intraCaseRadioActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_intraCaseRadioActionPerformed - this.intraCasePanel.setVisible(true); - - //TODO disable intercase panel + ((java.awt.CardLayout)this.layoutPanel.getLayout()).first(this.layoutPanel); +// this.intraCasePanel.setVisible(true); +// this.interCasePanel.setVisible(false); }//GEN-LAST:event_intraCaseRadioActionPerformed private void interCaseRadioActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_interCaseRadioActionPerformed - this.intraCasePanel.setVisible(false); - //TODO enable intercase panel + ((java.awt.CardLayout)this.layoutPanel.getLayout()).last(this.layoutPanel); +// this.intraCasePanel.setVisible(false); +// this.interCasePanel.setVisible(true); }//GEN-LAST:event_interCaseRadioActionPerformed private void toggleErrorTextAndSearchBox() { @@ -447,10 +454,13 @@ public final class CommonFilesPanel extends javax.swing.JPanel { private javax.swing.JCheckBox documentsCheckbox; private javax.swing.JLabel errorText; private javax.swing.ButtonGroup fileTypeFilterButtonGroup; + private org.sleuthkit.autopsy.commonfilesearch.InterCasePanel interCasePanel; + private org.sleuthkit.autopsy.commonfilesearch.InterCasePanel interCasePanel1; private javax.swing.JRadioButton interCaseRadio; private javax.swing.ButtonGroup interIntraButtonGroup; private org.sleuthkit.autopsy.commonfilesearch.IntraCasePanel intraCasePanel; private javax.swing.JRadioButton intraCaseRadio; + private java.awt.Panel layoutPanel; private javax.swing.JCheckBox pictureVideoCheckbox; private javax.swing.JButton searchButton; private javax.swing.JRadioButton selectedFileCategoriesButton; diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.form b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.form index e6324a61ab..adb18f764c 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.form +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.form @@ -1,6 +1,10 @@
+ + + + @@ -47,19 +51,23 @@ + + + - + + + - @@ -72,7 +80,6 @@ - diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.java index 90f8eafce0..13067a8551 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.java @@ -41,19 +41,19 @@ public class InterCasePanel extends javax.swing.JPanel { // //GEN-BEGIN:initComponents private void initComponents() { + buttonGroup = new javax.swing.ButtonGroup(); anCentralRepoCaseRadio = new javax.swing.JRadioButton(); specificCentralRepoCaseRadio = new javax.swing.JRadioButton(); caseComboBox = new javax.swing.JComboBox<>(); + buttonGroup.add(anCentralRepoCaseRadio); anCentralRepoCaseRadio.setSelected(true); org.openide.awt.Mnemonics.setLocalizedText(anCentralRepoCaseRadio, org.openide.util.NbBundle.getMessage(InterCasePanel.class, "InterCasePanel.anCentralRepoCaseRadio.text")); // NOI18N - anCentralRepoCaseRadio.setEnabled(false); + buttonGroup.add(specificCentralRepoCaseRadio); org.openide.awt.Mnemonics.setLocalizedText(specificCentralRepoCaseRadio, org.openide.util.NbBundle.getMessage(InterCasePanel.class, "InterCasePanel.specificCentralRepoCaseRadio.text")); // NOI18N - specificCentralRepoCaseRadio.setEnabled(false); caseComboBox.setModel(new javax.swing.DefaultComboBoxModel<>(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" })); - caseComboBox.setEnabled(false); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); @@ -85,6 +85,7 @@ public class InterCasePanel extends javax.swing.JPanel { // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JRadioButton anCentralRepoCaseRadio; + private javax.swing.ButtonGroup buttonGroup; private javax.swing.JComboBox caseComboBox; private javax.swing.JRadioButton specificCentralRepoCaseRadio; // End of variables declaration//GEN-END:variables From 0058d690660614a0af246ea3c9fe478d44a929cb Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Tue, 15 May 2018 19:31:40 -0600 Subject: [PATCH 010/287] more ui stuff --- .../commonfilesearch/CommonFilesPanel.java | 8 ++------ .../commonfilesearch/InterCasePanel.form | 7 +++++++ .../commonfilesearch/InterCasePanel.java | 19 +++++++++++++++++++ 3 files changed, 28 insertions(+), 6 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java index 85247f5a01..e8960df89f 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java @@ -402,15 +402,11 @@ public final class CommonFilesPanel extends javax.swing.JPanel { }//GEN-LAST:event_documentsCheckboxActionPerformed private void intraCaseRadioActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_intraCaseRadioActionPerformed - ((java.awt.CardLayout)this.layoutPanel.getLayout()).first(this.layoutPanel); -// this.intraCasePanel.setVisible(true); -// this.interCasePanel.setVisible(false); + ((java.awt.CardLayout)this.layoutPanel.getLayout()).last(this.layoutPanel); }//GEN-LAST:event_intraCaseRadioActionPerformed private void interCaseRadioActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_interCaseRadioActionPerformed - ((java.awt.CardLayout)this.layoutPanel.getLayout()).last(this.layoutPanel); -// this.intraCasePanel.setVisible(false); -// this.interCasePanel.setVisible(true); + ((java.awt.CardLayout)this.layoutPanel.getLayout()).first(this.layoutPanel); }//GEN-LAST:event_interCaseRadioActionPerformed private void toggleErrorTextAndSearchBox() { diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.form b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.form index adb18f764c..6e93e118cf 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.form +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.form @@ -59,6 +59,9 @@ + + + @@ -69,6 +72,9 @@ + + + @@ -80,6 +86,7 @@ + diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.java index 13067a8551..1d82c0974f 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.java @@ -49,11 +49,22 @@ public class InterCasePanel extends javax.swing.JPanel { buttonGroup.add(anCentralRepoCaseRadio); anCentralRepoCaseRadio.setSelected(true); org.openide.awt.Mnemonics.setLocalizedText(anCentralRepoCaseRadio, org.openide.util.NbBundle.getMessage(InterCasePanel.class, "InterCasePanel.anCentralRepoCaseRadio.text")); // NOI18N + anCentralRepoCaseRadio.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + anCentralRepoCaseRadioActionPerformed(evt); + } + }); buttonGroup.add(specificCentralRepoCaseRadio); org.openide.awt.Mnemonics.setLocalizedText(specificCentralRepoCaseRadio, org.openide.util.NbBundle.getMessage(InterCasePanel.class, "InterCasePanel.specificCentralRepoCaseRadio.text")); // NOI18N + specificCentralRepoCaseRadio.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + specificCentralRepoCaseRadioActionPerformed(evt); + } + }); caseComboBox.setModel(new javax.swing.DefaultComboBoxModel<>(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" })); + caseComboBox.setEnabled(false); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); @@ -82,6 +93,14 @@ public class InterCasePanel extends javax.swing.JPanel { ); }// //GEN-END:initComponents + private void specificCentralRepoCaseRadioActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_specificCentralRepoCaseRadioActionPerformed + this.caseComboBox.setEnabled(true); + }//GEN-LAST:event_specificCentralRepoCaseRadioActionPerformed + + private void anCentralRepoCaseRadioActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_anCentralRepoCaseRadioActionPerformed + this.caseComboBox.setEnabled(false); + }//GEN-LAST:event_anCentralRepoCaseRadioActionPerformed + // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JRadioButton anCentralRepoCaseRadio; From 4ae16a67277198c731d28e96ce36cad74747f1e4 Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Tue, 15 May 2018 19:33:41 -0600 Subject: [PATCH 011/287] default selections changed --- .../sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.form | 2 +- .../sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.form b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.form index 0892974a83..f3a8f62f65 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.form +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.form @@ -212,7 +212,6 @@ - @@ -226,6 +225,7 @@ + diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java index e8960df89f..2a9eb5b70b 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java @@ -290,7 +290,6 @@ public final class CommonFilesPanel extends javax.swing.JPanel { commonFilesSearchLabel1.setFocusable(false); interIntraButtonGroup.add(intraCaseRadio); - intraCaseRadio.setSelected(true); intraCaseRadio.setLabel(org.openide.util.NbBundle.getMessage(CommonFilesPanel.class, "CommonFilesPanel.intraCaseRadio.label")); // NOI18N intraCaseRadio.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { @@ -299,6 +298,7 @@ public final class CommonFilesPanel extends javax.swing.JPanel { }); interIntraButtonGroup.add(interCaseRadio); + interCaseRadio.setSelected(true); org.openide.awt.Mnemonics.setLocalizedText(interCaseRadio, org.openide.util.NbBundle.getMessage(CommonFilesPanel.class, "CommonFilesPanel.jRadioButton2.text")); // NOI18N interCaseRadio.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { From 3f215ea582298173cacf76a9b53b58a397d7c867 Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Tue, 15 May 2018 19:39:44 -0600 Subject: [PATCH 012/287] more wiring --- .../autopsy/commonfilesearch/CommonFilesPanel.java | 2 +- .../sleuthkit/autopsy/commonfilesearch/InterCasePanel.java | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java index 2a9eb5b70b..44372186b7 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java @@ -74,7 +74,7 @@ public final class CommonFilesPanel extends javax.swing.JPanel { initComponents(); this.intraCasePanel.setParent(this); - //TODO set parent for intercase panel + this.interCasePanel.setParent(this) this.errorText.setVisible(false); } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.java index 1d82c0974f..8e4d69e268 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.java @@ -25,6 +25,8 @@ package org.sleuthkit.autopsy.commonfilesearch; */ public class InterCasePanel extends javax.swing.JPanel { + private CommonFilesPanel parent; + /** * Creates new form InterCasePanel */ @@ -108,4 +110,8 @@ public class InterCasePanel extends javax.swing.JPanel { private javax.swing.JComboBox caseComboBox; private javax.swing.JRadioButton specificCentralRepoCaseRadio; // End of variables declaration//GEN-END:variables + + void setParent(CommonFilesPanel parent) { + this.parent = parent; + } } From 2b5f315cf782e13b5e37dea802d278c605539ee0 Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Thu, 17 May 2018 09:58:27 -0600 Subject: [PATCH 013/287] moved swingworkers to commonfilespanel so we can avoid a race condition while initializing the components --- .../commonfilesearch/CommonFilesPanel.form | 2 - .../commonfilesearch/CommonFilesPanel.java | 207 +++++++++++++++++- .../commonfilesearch/InterCasePanel.form | 9 +- .../commonfilesearch/InterCasePanel.java | 69 +++++- .../commonfilesearch/IntraCasePanel.java | 149 ++----------- 5 files changed, 289 insertions(+), 147 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.form b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.form index f3a8f62f65..b0f7e26095 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.form +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.form @@ -6,8 +6,6 @@ - - diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java index 44372186b7..c17e334cde 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java @@ -25,6 +25,7 @@ import java.sql.SQLException; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.concurrent.ExecutionException; @@ -36,6 +37,8 @@ import org.openide.explorer.ExplorerManager; import org.openide.util.NbBundle; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; +import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationDataSource; +import org.sleuthkit.autopsy.centralrepository.datamodel.EamDb; import org.sleuthkit.autopsy.corecomponentinterfaces.DataResultViewer; import org.sleuthkit.autopsy.corecomponents.DataResultTopComponent; import org.sleuthkit.autopsy.corecomponents.DataResultViewerTable; @@ -73,10 +76,13 @@ public final class CommonFilesPanel extends javax.swing.JPanel { public CommonFilesPanel() { initComponents(); - this.intraCasePanel.setParent(this); - this.interCasePanel.setParent(this) - this.errorText.setVisible(false); + + this.intraCasePanel.setParent(this); + this.interCasePanel.setParent(this); + + this.setupDataSources(); + this.setupCases(); } @NbBundle.Messages({ @@ -199,7 +205,200 @@ public final class CommonFilesPanel extends javax.swing.JPanel { } }.execute(); } + + /** + * Sets up the data sources dropdown and returns the data sources map for + * future usage. + * + * @return a mapping of data source ids to data source names + */ + @NbBundle.Messages({ + "CommonFilesPanel.setupDataSources.done.tskCoreException=Unable to run query against DB.", + "CommonFilesPanel.setupDataSources.done.noCurrentCaseException=Unable to open case file.", + "CommonFilesPanel.setupDataSources.done.exception=Unexpected exception building data sources map.", + "CommonFilesPanel.setupDataSources.done.interupted=Something went wrong building the Common Files Search dialog box.", + "CommonFilesPanel.setupDataSources.done.sqlException=Unable to query db for data sources.", + "CommonFilesPanel.setupDataSources.updateUi.noDataSources=No data sources were found."}) + private void setupDataSources() { + new SwingWorker, Void>() { + + private static final String SELECT_DATA_SOURCES_LOGICAL = "select obj_id, name from tsk_files where obj_id in (SELECT obj_id FROM tsk_objects WHERE obj_id in (select obj_id from data_source_info))"; + + private static final String SELECT_DATA_SOURCES_IMAGE = "select obj_id, name from tsk_image_names where obj_id in (SELECT obj_id FROM tsk_objects WHERE obj_id in (select obj_id from data_source_info))"; + + private void updateUi() { + + final Map dataSourceMap = CommonFilesPanel.this.intraCasePanel.getDataSourceMap(); + + String[] dataSourcesNames = new String[dataSourceMap.size()]; + + //only enable all this stuff if we actually have datasources + if (dataSourcesNames.length > 0) { + dataSourcesNames = dataSourceMap.values().toArray(dataSourcesNames); + CommonFilesPanel.this.intraCasePanel.setDataModel(new DataSourceComboBoxModel(dataSourcesNames)); + + boolean multipleDataSources = this.caseHasMultipleSources(); + CommonFilesPanel.this.intraCasePanel.rigForMultipleDataSources(multipleDataSources); + + //TODO this should be attached to the intra/inter radio buttons + CommonFilesPanel.this.setSearchButtonEnabled(true); + } else { + //TODO error message only? +// MessageNotifyUtil.Message.info(Bundle.IntraCasePanel_setupDataSources_updateUi_noDataSources()); +// SwingUtilities.windowForComponent(IntraCasePanel.this.parent).dispose(); + } + } + + private boolean caseHasMultipleSources() { + return CommonFilesPanel.this.intraCasePanel.getDataSourceMap().size() >= 2; + } + + private void loadLogicalSources(SleuthkitCase tskDb, Map dataSouceMap) throws TskCoreException, SQLException { + //try block releases resources - exceptions are handled in done() + try ( + SleuthkitCase.CaseDbQuery query = tskDb.executeQuery(SELECT_DATA_SOURCES_LOGICAL); + ResultSet resultSet = query.getResultSet()) { + while (resultSet.next()) { + Long objectId = resultSet.getLong(1); + String dataSourceName = resultSet.getString(2); + dataSouceMap.put(objectId, dataSourceName); + } + } + } + + private void loadImageSources(SleuthkitCase tskDb, Map dataSouceMap) throws SQLException, TskCoreException { + //try block releases resources - exceptions are handled in done() + try ( + SleuthkitCase.CaseDbQuery query = tskDb.executeQuery(SELECT_DATA_SOURCES_IMAGE); + ResultSet resultSet = query.getResultSet()) { + + while (resultSet.next()) { + Long objectId = resultSet.getLong(1); + String dataSourceName = resultSet.getString(2); + File image = new File(dataSourceName); + String dataSourceNameTrimmed = image.getName(); + dataSouceMap.put(objectId, dataSourceNameTrimmed); + } + } + } + + @Override + protected Map doInBackground() throws NoCurrentCaseException, TskCoreException, SQLException { + + Map dataSourceMap = new HashMap<>(); + + Case currentCase = Case.getCurrentCaseThrows(); + SleuthkitCase tskDb = currentCase.getSleuthkitCase(); + + loadLogicalSources(tskDb, dataSourceMap); + + loadImageSources(tskDb, dataSourceMap); + + return dataSourceMap; + } + + @Override + protected void done() { + + try { + CommonFilesPanel.this.intraCasePanel.setDataSourceMap(this.get()); + + updateUi(); + + } catch (InterruptedException ex) { + LOGGER.log(Level.SEVERE, "Interrupted while building Common Files Search dialog.", ex); + MessageNotifyUtil.Message.error(Bundle.CommonFilesPanel_setupDataSources_done_interupted()); + } catch (ExecutionException ex) { + String errorMessage; + Throwable inner = ex.getCause(); + if (inner instanceof TskCoreException) { + LOGGER.log(Level.SEVERE, "Failed to load data sources from database.", ex); + errorMessage = Bundle.CommonFilesPanel_setupDataSources_done_tskCoreException(); + } else if (inner instanceof NoCurrentCaseException) { + LOGGER.log(Level.SEVERE, "Current case has been closed.", ex); + errorMessage = Bundle.CommonFilesPanel_setupDataSources_done_noCurrentCaseException(); + } else if (inner instanceof SQLException) { + LOGGER.log(Level.SEVERE, "Unable to query db for data sources.", ex); + errorMessage = Bundle.CommonFilesPanel_setupDataSources_done_sqlException(); + } else { + LOGGER.log(Level.SEVERE, "Unexpected exception while building Common Files Search dialog panel.", ex); + errorMessage = Bundle.CommonFilesPanel_setupDataSources_done_exception(); + } + MessageNotifyUtil.Message.error(errorMessage); + } + } + }.execute(); + } + + @NbBundle.Messages({ + "CommonFilesPanel.setupCases.done.interruptedException=Something went wrong building the Common Files Search dialog box.", + "CommonFilesPanel.setupCases.done.exeutionException=Unexpected exception building data sources map."}) + private void setupCases(){ + + new SwingWorker, Void>(){ + + private void updateUi(){ + + final Map caseMap = CommonFilesPanel.this.interCasePanel.getCaseMap(); + + String[] caseNames = new String[caseMap.size()]; + + if(caseNames.length > 0){ + caseNames = caseMap.values().toArray(caseNames); + CommonFilesPanel.this.interCasePanel.setCaseList(new DataSourceComboBoxModel(caseNames)); + + boolean multipleCases = this.centralRepoHasMultipleCases(); + CommonFilesPanel.this.interCasePanel.rigForMultipleCases(multipleCases); + + //TODO need something more specific + //InterCasePanel.this.parent.setSearchButtonEnabled(true); + } else { + //TODO need something more specific + } + + } + + private Map mapDataSources(List dataSources) { + Map casemap = new HashMap<>(); + + for (CorrelationDataSource source : dataSources){ + casemap.put(source.getCaseID(), source.getName()); + } + + return casemap; + } + + @Override + protected Map doInBackground() throws Exception { + + List dataSources = EamDb.getInstance().getDataSources(); + + Map caseMap = mapDataSources(dataSources); + + return caseMap; + } + + @Override + protected void done(){ + try{ + CommonFilesPanel.this.interCasePanel.setCaseMap(this.get()); + this.updateUi(); + } catch (InterruptedException ex) { + LOGGER.log(Level.SEVERE, "Interrupted while building Common Files Search dialog.", ex); + MessageNotifyUtil.Message.error(Bundle.CommonFilesPanel_setupCases_done_interruptedException()); + } catch (ExecutionException ex) { + LOGGER.log(Level.SEVERE, "Unexpected exception while building Common Files Search dialog.", ex); + MessageNotifyUtil.Message.error(Bundle.CommonFilesPanel_setupCases_done_exeutionException()); + } + } + + private boolean centralRepoHasMultipleCases() { + return CommonFilesPanel.this.interCasePanel.centralRepoHasMultipleCases(); + } + + }.execute(); + } /** * This method is called from within the constructor to initialize the form. * WARNING: Do NOT modify this code. The content of this method is always @@ -211,7 +410,6 @@ public final class CommonFilesPanel extends javax.swing.JPanel { fileTypeFilterButtonGroup = new javax.swing.ButtonGroup(); interIntraButtonGroup = new javax.swing.ButtonGroup(); - interCasePanel1 = new org.sleuthkit.autopsy.commonfilesearch.InterCasePanel(); searchButton = new javax.swing.JButton(); cancelButton = new javax.swing.JButton(); allFileCategoriesRadioButton = new javax.swing.JRadioButton(); @@ -451,7 +649,6 @@ public final class CommonFilesPanel extends javax.swing.JPanel { private javax.swing.JLabel errorText; private javax.swing.ButtonGroup fileTypeFilterButtonGroup; private org.sleuthkit.autopsy.commonfilesearch.InterCasePanel interCasePanel; - private org.sleuthkit.autopsy.commonfilesearch.InterCasePanel interCasePanel1; private javax.swing.JRadioButton interCaseRadio; private javax.swing.ButtonGroup interIntraButtonGroup; private org.sleuthkit.autopsy.commonfilesearch.IntraCasePanel intraCasePanel; diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.form b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.form index 6e93e118cf..f8060a7df3 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.form +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.form @@ -78,13 +78,8 @@ - - - - - - - + + diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.java index 8e4d69e268..e2da707594 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.java @@ -19,12 +19,36 @@ */ package org.sleuthkit.autopsy.commonfilesearch; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ExecutionException; +import java.util.logging.Level; +import javax.swing.ComboBoxModel; +import javax.swing.SwingWorker; +import org.openide.util.Exceptions; +import org.openide.util.NbBundle; +import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationDataSource; +import org.sleuthkit.autopsy.centralrepository.datamodel.EamDb; +import org.sleuthkit.autopsy.coreutils.Logger; +import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil; + /** * * @author bsweeney */ public class InterCasePanel extends javax.swing.JPanel { - + + private static final long serialVersionUID = 1L; + + private static final Logger LOGGER = Logger.getLogger(InterCasePanel.class.getName()); + + private String selectedCase; + private boolean singleCase; + + private ComboBoxModel casesList = new DataSourceComboBoxModel(); + private Map caseMap; + private CommonFilesPanel parent; /** @@ -33,7 +57,21 @@ public class InterCasePanel extends javax.swing.JPanel { public InterCasePanel() { initComponents(); } + + + private void specificCaseSelected(boolean selected) { + this.specificCentralRepoCaseRadio.setEnabled(selected); + if (this.specificCentralRepoCaseRadio.isEnabled()) { + this.caseComboBox.setSelectedIndex(0); + this.singleCase = true; + } + } + + void setParent(CommonFilesPanel parent) { + this.parent = parent; + } + /** * This method is called from within the constructor to initialize the form. * WARNING: Do NOT modify this code. The content of this method is always @@ -65,7 +103,7 @@ public class InterCasePanel extends javax.swing.JPanel { } }); - caseComboBox.setModel(new javax.swing.DefaultComboBoxModel<>(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" })); + caseComboBox.setModel(casesList); caseComboBox.setEnabled(false); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); @@ -111,7 +149,30 @@ public class InterCasePanel extends javax.swing.JPanel { private javax.swing.JRadioButton specificCentralRepoCaseRadio; // End of variables declaration//GEN-END:variables - void setParent(CommonFilesPanel parent) { - this.parent = parent; + Map getCaseMap() { + return this.caseMap; + } + + void setCaseList(DataSourceComboBoxModel dataSourceComboBoxModel) { + this.casesList = dataSourceComboBoxModel; + this.caseComboBox.setModel(dataSourceComboBoxModel); + } + + void rigForMultipleCases(boolean multipleCases) { + this.anCentralRepoCaseRadio.setEnabled(multipleCases); + this.anCentralRepoCaseRadio.setEnabled(multipleCases); + + if(!multipleCases){ + this.specificCentralRepoCaseRadio.setSelected(true); + this.specificCaseSelected(true); + } + } + + void setCaseMap(Map caseMap) { + this.caseMap = caseMap; + } + + boolean centralRepoHasMultipleCases() { + return this.caseMap.size() >= 2; } } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCasePanel.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCasePanel.java index 12f0bb5a34..420e68dd6e 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCasePanel.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCasePanel.java @@ -58,8 +58,6 @@ public class IntraCasePanel extends javax.swing.JPanel { */ public IntraCasePanel() { initComponents(); - - this.setupDataSources(); } public void setParent(CommonFilesPanel parent){ @@ -82,133 +80,7 @@ public class IntraCasePanel extends javax.swing.JPanel { return this.dataSourceMap; } - /** - * Sets up the data sources dropdown and returns the data sources map for - * future usage. - * - * @return a mapping of data source ids to data source names - */ - @NbBundle.Messages({ - "IntraCasePanel.setupDataSources.done.tskCoreException=Unable to run query against DB.", - "IntraCasePanel.setupDataSources.done.noCurrentCaseException=Unable to open case file.", - "IntraCasePanel.setupDataSources.done.exception=Unexpected exception building data sources map.", - "IntraCasePanel.setupDataSources.done.interupted=Something went wrong building the Common Files Search dialog box.", - "IntraCasePanel.setupDataSources.done.sqlException=Unable to query db for data sources.", - "IntraCasePanel.setupDataSources.updateUi.noDataSources=No data sources were found."}) - private void setupDataSources() { - - new SwingWorker, Void>() { - - private static final String SELECT_DATA_SOURCES_LOGICAL = "select obj_id, name from tsk_files where obj_id in (SELECT obj_id FROM tsk_objects WHERE obj_id in (select obj_id from data_source_info))"; - - private static final String SELECT_DATA_SOURCES_IMAGE = "select obj_id, name from tsk_image_names where obj_id in (SELECT obj_id FROM tsk_objects WHERE obj_id in (select obj_id from data_source_info))"; - - private void updateUi() { - - String[] dataSourcesNames = new String[IntraCasePanel.this.dataSourceMap.size()]; - - //only enable all this stuff if we actually have datasources - if (dataSourcesNames.length > 0) { - dataSourcesNames = IntraCasePanel.this.dataSourceMap.values().toArray(dataSourcesNames); - IntraCasePanel.this.dataSourcesList = new DataSourceComboBoxModel(dataSourcesNames); - IntraCasePanel.this.selectDataSourceComboBox.setModel(IntraCasePanel.this.dataSourcesList); - - boolean multipleDataSources = this.caseHasMultipleSources(); - IntraCasePanel.this.allDataSourcesRadioButton.setEnabled(multipleDataSources); - IntraCasePanel.this.allDataSourcesRadioButton.setSelected(multipleDataSources); - - if (!multipleDataSources) { - IntraCasePanel.this.withinDataSourceRadioButton.setSelected(true); - withinDataSourceSelected(true); - } - - IntraCasePanel.this.parent.setSearchButtonEnabled(true); - } else { - MessageNotifyUtil.Message.info(Bundle.IntraCasePanel_setupDataSources_updateUi_noDataSources()); - SwingUtilities.windowForComponent(IntraCasePanel.this.parent).dispose(); - } - } - - private boolean caseHasMultipleSources() { - return IntraCasePanel.this.dataSourceMap.size() >= 2; - } - - private void loadLogicalSources(SleuthkitCase tskDb, Map dataSouceMap) throws TskCoreException, SQLException { - //try block releases resources - exceptions are handled in done() - try ( - SleuthkitCase.CaseDbQuery query = tskDb.executeQuery(SELECT_DATA_SOURCES_LOGICAL); - ResultSet resultSet = query.getResultSet()) { - while (resultSet.next()) { - Long objectId = resultSet.getLong(1); - String dataSourceName = resultSet.getString(2); - dataSouceMap.put(objectId, dataSourceName); - } - } - } - - private void loadImageSources(SleuthkitCase tskDb, Map dataSouceMap) throws SQLException, TskCoreException { - //try block releases resources - exceptions are handled in done() - try ( - SleuthkitCase.CaseDbQuery query = tskDb.executeQuery(SELECT_DATA_SOURCES_IMAGE); - ResultSet resultSet = query.getResultSet()) { - - while (resultSet.next()) { - Long objectId = resultSet.getLong(1); - String dataSourceName = resultSet.getString(2); - File image = new File(dataSourceName); - String dataSourceNameTrimmed = image.getName(); - dataSouceMap.put(objectId, dataSourceNameTrimmed); - } - } - } - - @Override - protected Map doInBackground() throws NoCurrentCaseException, TskCoreException, SQLException { - - Map dataSouceMap = new HashMap<>(); - - Case currentCase = Case.getCurrentCaseThrows(); - SleuthkitCase tskDb = currentCase.getSleuthkitCase(); - - loadLogicalSources(tskDb, dataSouceMap); - - loadImageSources(tskDb, dataSouceMap); - - return dataSouceMap; - } - - @Override - protected void done() { - - try { - IntraCasePanel.this.dataSourceMap = this.get(); - - updateUi(); - - } catch (InterruptedException ex) { - LOGGER.log(Level.SEVERE, "Interrupted while building Common Files Search dialog.", ex); - MessageNotifyUtil.Message.error(Bundle.IntraCasePanel_setupDataSources_done_interupted()); - } catch (ExecutionException ex) { - String errorMessage; - Throwable inner = ex.getCause(); - if (inner instanceof TskCoreException) { - LOGGER.log(Level.SEVERE, "Failed to load data sources from database.", ex); - errorMessage = Bundle.IntraCasePanel_setupDataSources_done_tskCoreException(); - } else if (inner instanceof NoCurrentCaseException) { - LOGGER.log(Level.SEVERE, "Current case has been closed.", ex); - errorMessage = Bundle.IntraCasePanel_setupDataSources_done_noCurrentCaseException(); - } else if (inner instanceof SQLException) { - LOGGER.log(Level.SEVERE, "Unable to query db for data sources.", ex); - errorMessage = Bundle.IntraCasePanel_setupDataSources_done_sqlException(); - } else { - LOGGER.log(Level.SEVERE, "Unexpected exception while building Common Files Search dialog panel.", ex); - errorMessage = Bundle.IntraCasePanel_setupDataSources_done_exception(); - } - MessageNotifyUtil.Message.error(errorMessage); - } - } - }.execute(); - } + /** * This method is called from within the constructor to initialize the form. @@ -309,4 +181,23 @@ public class IntraCasePanel extends javax.swing.JPanel { private javax.swing.JComboBox selectDataSourceComboBox; private javax.swing.JRadioButton withinDataSourceRadioButton; // End of variables declaration//GEN-END:variables + + void setDataModel(DataSourceComboBoxModel dataSourceComboBoxModel) { + this.dataSourcesList = dataSourceComboBoxModel; + this.selectDataSourceComboBox.setModel(dataSourcesList); + } + + void rigForMultipleDataSources(boolean multipleDataSources) { + this.allDataSourcesRadioButton.setEnabled(multipleDataSources); + this.allDataSourcesRadioButton.setSelected(multipleDataSources); + + if(!multipleDataSources){ + this.withinDataSourceRadioButton.setSelected(true); + this.withinDataSourceSelected(true); + } + } + + void setDataSourceMap(Map dataSourceMap) { + this.dataSourceMap = dataSourceMap; + } } From ee6837d5d410951e434cd9000f9f3c4537dfd462 Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Thu, 17 May 2018 12:20:02 -0600 Subject: [PATCH 014/287] correllation cases loaded instead of data sources --- .../autopsy/commonfilesearch/CommonFilesPanel.java | 11 ++++++----- .../autopsy/commonfilesearch/InterCasePanel.java | 2 -- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java index c17e334cde..9fae239a88 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java @@ -37,6 +37,7 @@ import org.openide.explorer.ExplorerManager; import org.openide.util.NbBundle; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; +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.corecomponentinterfaces.DataResultViewer; @@ -210,7 +211,7 @@ public final class CommonFilesPanel extends javax.swing.JPanel { * Sets up the data sources dropdown and returns the data sources map for * future usage. * - * @return a mapping of data source ids to data source names + * @return a mapping of data correlationCase ids to data correlationCase names */ @NbBundle.Messages({ "CommonFilesPanel.setupDataSources.done.tskCoreException=Unable to run query against DB.", @@ -359,11 +360,11 @@ public final class CommonFilesPanel extends javax.swing.JPanel { } - private Map mapDataSources(List dataSources) { + private Map mapDataSources(List cases) { Map casemap = new HashMap<>(); - for (CorrelationDataSource source : dataSources){ - casemap.put(source.getCaseID(), source.getName()); + for (CorrelationCase correlationCase : cases){ + casemap.put(correlationCase.getID(), correlationCase.getDisplayName()); } return casemap; @@ -372,7 +373,7 @@ public final class CommonFilesPanel extends javax.swing.JPanel { @Override protected Map doInBackground() throws Exception { - List dataSources = EamDb.getInstance().getDataSources(); + List dataSources = EamDb.getInstance().getCases(); Map caseMap = mapDataSources(dataSources); diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.java index e2da707594..667fa1ba56 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.java @@ -57,8 +57,6 @@ public class InterCasePanel extends javax.swing.JPanel { public InterCasePanel() { initComponents(); } - - private void specificCaseSelected(boolean selected) { this.specificCentralRepoCaseRadio.setEnabled(selected); From ed15f81a97c4e31cd455a404658827fc82e953cd Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Fri, 18 May 2018 12:31:41 -0600 Subject: [PATCH 015/287] error messages --- .../commonfilesearch/Bundle.properties | 2 +- .../commonfilesearch/CommonFilesPanel.java | 47 ++++++++++++++++- .../commonfilesearch/InterCasePanel.form | 10 ++-- .../commonfilesearch/InterCasePanel.java | 50 ++++++++++++++----- .../commonfilesearch/IntraCasePanel.java | 17 +++++++ 5 files changed, 106 insertions(+), 20 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/Bundle.properties b/Core/src/org/sleuthkit/autopsy/commonfilesearch/Bundle.properties index f3ac99e12d..1de1c35a7d 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/Bundle.properties @@ -17,5 +17,5 @@ CommonFilesPanel.intraCaseRadio.label=Correlate within current case only CommonFilesPanel.interCaseRadio.label=Correlate amongst all known cases (uses Central Repo) IntraCasePanel.allDataSourcesRadioButton.text=Matches may be from any data source IntraCasePanel.withinDataSourceRadioButton.text=At least one match must appear in the data source selected below: -InterCasePanel.anCentralRepoCaseRadio.text=Matches may be from any Central Repo case InterCasePanel.specificCentralRepoCaseRadio.text=Matches must be from the following Central Repo case: +InterCasePanel.anyCentralRepoCaseRadio.text=Matches may be from any Central Repo case diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java index 9fae239a88..8f85b3c4c0 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java @@ -304,7 +304,6 @@ public final class CommonFilesPanel extends javax.swing.JPanel { try { CommonFilesPanel.this.intraCasePanel.setDataSourceMap(this.get()); - updateUi(); } catch (InterruptedException ex) { @@ -602,12 +601,36 @@ public final class CommonFilesPanel extends javax.swing.JPanel { private void intraCaseRadioActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_intraCaseRadioActionPerformed ((java.awt.CardLayout)this.layoutPanel.getLayout()).last(this.layoutPanel); + handleIntraCaseSearchCriteriaChanged(); }//GEN-LAST:event_intraCaseRadioActionPerformed + public void handleIntraCaseSearchCriteriaChanged() { + if(this.areIntraCaseSearchCriteriaMet()){ + this.searchButton.setEnabled(true); + this.hideErrorMessages(); + } else { + this.searchButton.setEnabled(false); + this.hideErrorMessages(); + this.showIntraCaseErrorMessage(); + } + } + private void interCaseRadioActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_interCaseRadioActionPerformed ((java.awt.CardLayout)this.layoutPanel.getLayout()).first(this.layoutPanel); + handleInterCaseSearchCriteriaChanged(); }//GEN-LAST:event_interCaseRadioActionPerformed + public void handleInterCaseSearchCriteriaChanged() { + if(this.areInterCaseSearchCriteriaMet()){ + this.searchButton.setEnabled(true); + this.hideErrorMessages(); + } else { + this.searchButton.setEnabled(false); + this.hideErrorMessages(); + this.showInterCaseErrorMessage(); + } + } + private void toggleErrorTextAndSearchBox() { if (!this.pictureVideoCheckbox.isSelected() && !this.documentsCheckbox.isSelected() && !this.allFileCategoriesRadioButton.isSelected()) { this.searchButton.setEnabled(false); @@ -663,4 +686,26 @@ public final class CommonFilesPanel extends javax.swing.JPanel { void setSearchButtonEnabled(boolean enabled) { this.searchButton.setEnabled(enabled); } + + private boolean areIntraCaseSearchCriteriaMet() { + return this.intraCasePanel.areSearchCriteriaMet(); + } + + private boolean areInterCaseSearchCriteriaMet() { + return this.interCasePanel.areSearchCriteriaMet(); + } + + private void hideErrorMessages() { + this.errorText.setVisible(false); + } + + private void showIntraCaseErrorMessage() { + this.errorText.setText(Bundle.CommonFilesPanel_showIntraCaseErrorMessage_message()); + this.errorText.setVisible(true); + } + + private void showInterCaseErrorMessage() { + this.errorText.setText(this.interCasePanel.getErrorMessage()); + this.errorText.setVisible(true); + } } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.form b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.form index f8060a7df3..daa29800f6 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.form +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.form @@ -23,7 +23,7 @@ - + @@ -38,7 +38,7 @@ - + @@ -49,18 +49,18 @@ - + - + - + diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.java index 667fa1ba56..d7da1d7a85 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.java @@ -51,11 +51,14 @@ public class InterCasePanel extends javax.swing.JPanel { private CommonFilesPanel parent; + private String errorMessage; + /** * Creates new form InterCasePanel */ public InterCasePanel() { initComponents(); + this.errorMessage = ""; } private void specificCaseSelected(boolean selected) { @@ -70,6 +73,10 @@ public class InterCasePanel extends javax.swing.JPanel { this.parent = parent; } + String getErrorMessage(){ + return this.errorMessage; + } + /** * This method is called from within the constructor to initialize the form. * WARNING: Do NOT modify this code. The content of this method is always @@ -80,16 +87,16 @@ public class InterCasePanel extends javax.swing.JPanel { private void initComponents() { buttonGroup = new javax.swing.ButtonGroup(); - anCentralRepoCaseRadio = new javax.swing.JRadioButton(); + anyCentralRepoCaseRadio = new javax.swing.JRadioButton(); specificCentralRepoCaseRadio = new javax.swing.JRadioButton(); caseComboBox = new javax.swing.JComboBox<>(); - buttonGroup.add(anCentralRepoCaseRadio); - anCentralRepoCaseRadio.setSelected(true); - org.openide.awt.Mnemonics.setLocalizedText(anCentralRepoCaseRadio, org.openide.util.NbBundle.getMessage(InterCasePanel.class, "InterCasePanel.anCentralRepoCaseRadio.text")); // NOI18N - anCentralRepoCaseRadio.addActionListener(new java.awt.event.ActionListener() { + buttonGroup.add(anyCentralRepoCaseRadio); + anyCentralRepoCaseRadio.setSelected(true); + org.openide.awt.Mnemonics.setLocalizedText(anyCentralRepoCaseRadio, org.openide.util.NbBundle.getMessage(InterCasePanel.class, "InterCasePanel.anyCentralRepoCaseRadio.text")); // NOI18N + anyCentralRepoCaseRadio.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { - anCentralRepoCaseRadioActionPerformed(evt); + anyCentralRepoCaseRadioActionPerformed(evt); } }); @@ -111,7 +118,7 @@ public class InterCasePanel extends javax.swing.JPanel { .addGroup(layout.createSequentialGroup() .addContainerGap() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(anCentralRepoCaseRadio) + .addComponent(anyCentralRepoCaseRadio) .addComponent(specificCentralRepoCaseRadio) .addGroup(layout.createSequentialGroup() .addGap(21, 21, 21) @@ -122,7 +129,7 @@ public class InterCasePanel extends javax.swing.JPanel { layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addContainerGap() - .addComponent(anCentralRepoCaseRadio) + .addComponent(anyCentralRepoCaseRadio) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(specificCentralRepoCaseRadio) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) @@ -133,15 +140,20 @@ public class InterCasePanel extends javax.swing.JPanel { private void specificCentralRepoCaseRadioActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_specificCentralRepoCaseRadioActionPerformed this.caseComboBox.setEnabled(true); + if(this.caseComboBox.getSelectedItem() == null){ + this.caseComboBox.setSelectedIndex(0); + } + this.parent.handleInterCaseSearchCriteriaChanged(); }//GEN-LAST:event_specificCentralRepoCaseRadioActionPerformed - private void anCentralRepoCaseRadioActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_anCentralRepoCaseRadioActionPerformed + private void anyCentralRepoCaseRadioActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_anyCentralRepoCaseRadioActionPerformed this.caseComboBox.setEnabled(false); - }//GEN-LAST:event_anCentralRepoCaseRadioActionPerformed + this.parent.handleInterCaseSearchCriteriaChanged(); + }//GEN-LAST:event_anyCentralRepoCaseRadioActionPerformed // Variables declaration - do not modify//GEN-BEGIN:variables - private javax.swing.JRadioButton anCentralRepoCaseRadio; + private javax.swing.JRadioButton anyCentralRepoCaseRadio; private javax.swing.ButtonGroup buttonGroup; private javax.swing.JComboBox caseComboBox; private javax.swing.JRadioButton specificCentralRepoCaseRadio; @@ -157,8 +169,8 @@ public class InterCasePanel extends javax.swing.JPanel { } void rigForMultipleCases(boolean multipleCases) { - this.anCentralRepoCaseRadio.setEnabled(multipleCases); - this.anCentralRepoCaseRadio.setEnabled(multipleCases); + this.anyCentralRepoCaseRadio.setEnabled(multipleCases); + this.anyCentralRepoCaseRadio.setEnabled(multipleCases); if(!multipleCases){ this.specificCentralRepoCaseRadio.setSelected(true); @@ -173,4 +185,16 @@ public class InterCasePanel extends javax.swing.JPanel { boolean centralRepoHasMultipleCases() { return this.caseMap.size() >= 2; } + + @NbBundle.Messages({ + "CommonFilesPanel.showInterCaseErrorMessage.message=Cannot run intercase correlation search: no cases in Central Repository." + }) + boolean areSearchCriteriaMet() { + if(this.caseMap.isEmpty()){ + this.errorMessage = Bundle.CommonFilesPanel_showInterCaseErrorMessage_message(); + return false; + } else { + return true; + } + } } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCasePanel.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCasePanel.java index 420e68dd6e..9edd3b4a68 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCasePanel.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCasePanel.java @@ -52,12 +52,15 @@ public class IntraCasePanel extends javax.swing.JPanel { private ComboBoxModel dataSourcesList = new DataSourceComboBoxModel(); private Map dataSourceMap; private CommonFilesPanel parent; + + private String errorMessage; /** * Creates new form IntraCasePanel */ public IntraCasePanel() { initComponents(); + this.errorMessage = ""; } public void setParent(CommonFilesPanel parent){ @@ -152,10 +155,12 @@ public class IntraCasePanel extends javax.swing.JPanel { private void allDataSourcesRadioButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_allDataSourcesRadioButtonActionPerformed selectDataSourceComboBox.setEnabled(!allDataSourcesRadioButton.isSelected()); singleDataSource = false; + this.parent.handleIntraCaseSearchCriteriaChanged(); }//GEN-LAST:event_allDataSourcesRadioButtonActionPerformed private void withinDataSourceRadioButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_withinDataSourceRadioButtonActionPerformed withinDataSourceSelected(withinDataSourceRadioButton.isSelected()); + this.parent.handleIntraCaseSearchCriteriaChanged(); }//GEN-LAST:event_withinDataSourceRadioButtonActionPerformed private void selectDataSourceComboBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_selectDataSourceComboBoxActionPerformed @@ -200,4 +205,16 @@ public class IntraCasePanel extends javax.swing.JPanel { void setDataSourceMap(Map dataSourceMap) { this.dataSourceMap = dataSourceMap; } + + @NbBundle.Messages({ + "IntraCasePanel.areSearchCriteriaMet.message=Cannot run intra-case correlation search." + }) + boolean areSearchCriteriaMet() { + if(this.dataSourceMap.isEmpty()){ + this.errorMessage = Bundle.IntraCasePanel_areSearchCriteriaMet_message(); + return false; + } else { + return true; + } + } } From 7eba5902116aee178146575d364caf24cde6bf48 Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Fri, 18 May 2018 17:04:01 -0600 Subject: [PATCH 016/287] action enabled for conditions which consider eamdb as well --- .../commonfilesearch/CommonFilesSearchAction.java | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesSearchAction.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesSearchAction.java index e470fd16bc..c2db78e338 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesSearchAction.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesSearchAction.java @@ -19,10 +19,14 @@ package org.sleuthkit.autopsy.commonfilesearch; import java.awt.event.ActionEvent; +import java.util.logging.Level; +import java.util.logging.Logger; import org.openide.util.HelpCtx; import org.openide.util.NbBundle; import org.openide.util.actions.CallableSystemAction; import org.sleuthkit.autopsy.casemodule.Case; +import org.sleuthkit.autopsy.centralrepository.datamodel.EamDb; +import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException; import org.sleuthkit.autopsy.core.Installer; /** @@ -30,6 +34,8 @@ import org.sleuthkit.autopsy.core.Installer; */ final public class CommonFilesSearchAction extends CallableSystemAction { + private static final Logger LOGGER = Logger.getLogger(CommonFilesSearchAction.class.getName()); + private static CommonFilesSearchAction instance = null; private static final long serialVersionUID = 1L; @@ -40,7 +46,14 @@ final public class CommonFilesSearchAction extends CallableSystemAction { @Override public boolean isEnabled(){ - return super.isEnabled() && Case.isCaseOpen() && Installer.isJavaFxInited(); + boolean isEamDbAvailable = false; + try { + isEamDbAvailable = EamDb.isEnabled() && !EamDb.getInstance().getCases().isEmpty(); + } catch (EamDbException ex) { + LOGGER.log(Level.WARNING, "Error accessing EamDb", ex); + } + + return super.isEnabled() && Installer.isJavaFxInited()&& Case.isCaseOpen() || isEamDbAvailable; } public static synchronized CommonFilesSearchAction getDefault() { From 048148b2bd5709fa911ddacccbe9d7778e781591 Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Fri, 18 May 2018 17:07:02 -0600 Subject: [PATCH 017/287] error messages --- .../org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.java index d7da1d7a85..5a6677acf5 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.java @@ -187,7 +187,7 @@ public class InterCasePanel extends javax.swing.JPanel { } @NbBundle.Messages({ - "CommonFilesPanel.showInterCaseErrorMessage.message=Cannot run intercase correlation search: no cases in Central Repository." + "InterCasePanel.showInterCaseErrorMessage.message=Cannot run intercase correlation search: no cases in Central Repository." }) boolean areSearchCriteriaMet() { if(this.caseMap.isEmpty()){ From 245fbfe6708292c037e2275eacd23e7a3bb8dff3 Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Fri, 18 May 2018 17:31:06 -0600 Subject: [PATCH 018/287] layout and wording on dialog box --- .../commonfilesearch/Bundle.properties | 3 +- .../commonfilesearch/CommonFilesPanel.form | 116 ++++++++++-------- .../commonfilesearch/CommonFilesPanel.java | 83 ++++++++----- 3 files changed, 118 insertions(+), 84 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/Bundle.properties b/Core/src/org/sleuthkit/autopsy/commonfilesearch/Bundle.properties index 1de1c35a7d..17a8d84922 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/Bundle.properties @@ -10,7 +10,6 @@ CommonFilesPanel.allFileCategoriesRadioButton.text=Match on all file types CommonFilesPanel.text=Indicate which data sources to consider while searching for duplicates: CommonFilesPanel.categoriesLabel.text=Indicate which file types to include in results: CommonFilesPanel.errorText.text=In order to search, you must select a file category. -CommonFilesPanel.commonFilesSearchLabel1.text=Find Common Files. CommonFilesPanel.jRadioButton1.text=jRadioButton1 CommonFilesPanel.jRadioButton2.text=Correlate amongst external cases (compares files in current case with Central Repo) CommonFilesPanel.intraCaseRadio.label=Correlate within current case only @@ -19,3 +18,5 @@ IntraCasePanel.allDataSourcesRadioButton.text=Matches may be from any data sourc IntraCasePanel.withinDataSourceRadioButton.text=At least one match must appear in the data source selected below: InterCasePanel.specificCentralRepoCaseRadio.text=Matches must be from the following Central Repo case: InterCasePanel.anyCentralRepoCaseRadio.text=Matches may be from any Central Repo case +CommonFilesPanel.commonFilesSearchLabel1.text=Find common files to correlate data soures or cases. +CommonFilesPanel.commonFilesSearchLabel2.text=Scope of Search diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.form b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.form index b0f7e26095..bb5cc306ba 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.form +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.form @@ -6,6 +6,8 @@ + + @@ -25,74 +27,94 @@ - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + - - - - - - - - + + + + + + + + + + - + - @@ -235,22 +257,16 @@ - - - - - - - - - - - - - - - - + + + + + + + + + + diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java index 8f85b3c4c0..66bf4c9af4 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java @@ -410,6 +410,7 @@ public final class CommonFilesPanel extends javax.swing.JPanel { fileTypeFilterButtonGroup = new javax.swing.ButtonGroup(); interIntraButtonGroup = new javax.swing.ButtonGroup(); + interCasePanel = new org.sleuthkit.autopsy.commonfilesearch.InterCasePanel(); searchButton = new javax.swing.JButton(); cancelButton = new javax.swing.JButton(); allFileCategoriesRadioButton = new javax.swing.JRadioButton(); @@ -422,7 +423,7 @@ public final class CommonFilesPanel extends javax.swing.JPanel { intraCaseRadio = new javax.swing.JRadioButton(); interCaseRadio = new javax.swing.JRadioButton(); layoutPanel = new java.awt.Panel(); - interCasePanel = new org.sleuthkit.autopsy.commonfilesearch.InterCasePanel(); + commonFilesSearchLabel2 = new javax.swing.JLabel(); intraCasePanel = new org.sleuthkit.autopsy.commonfilesearch.IntraCasePanel(); org.openide.awt.Mnemonics.setLocalizedText(searchButton, org.openide.util.NbBundle.getMessage(CommonFilesPanel.class, "CommonFilesPanel.searchButton.text")); // NOI18N @@ -505,8 +506,9 @@ public final class CommonFilesPanel extends javax.swing.JPanel { }); layoutPanel.setLayout(new java.awt.CardLayout()); - layoutPanel.add(interCasePanel, "card2"); - layoutPanel.add(intraCasePanel, "card3"); + + org.openide.awt.Mnemonics.setLocalizedText(commonFilesSearchLabel2, org.openide.util.NbBundle.getMessage(CommonFilesPanel.class, "CommonFilesPanel.commonFilesSearchLabel2.text")); // NOI18N + commonFilesSearchLabel2.setFocusable(false); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); @@ -515,61 +517,75 @@ public final class CommonFilesPanel extends javax.swing.JPanel { .addGroup(layout.createSequentialGroup() .addContainerGap() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(commonFilesSearchLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(categoriesLabel) - .addComponent(intraCaseRadio) - .addComponent(interCaseRadio) - .addGroup(layout.createSequentialGroup() - .addGap(10, 10, 10) - .addComponent(layoutPanel, javax.swing.GroupLayout.PREFERRED_SIZE, 364, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addGroup(layout.createSequentialGroup() - .addGap(6, 6, 6) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(allFileCategoriesRadioButton) - .addComponent(selectedFileCategoriesButton) - .addGroup(layout.createSequentialGroup() - .addGap(21, 21, 21) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(pictureVideoCheckbox) - .addComponent(documentsCheckbox))))) .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addGap(0, 0, Short.MAX_VALUE) .addComponent(errorText) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(searchButton) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(cancelButton))) - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addComponent(cancelButton)) + .addGroup(layout.createSequentialGroup() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(commonFilesSearchLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGroup(layout.createSequentialGroup() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addGap(20, 20, 20) + .addComponent(intraCasePanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(categoriesLabel) + .addGroup(layout.createSequentialGroup() + .addGap(6, 6, 6) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(selectedFileCategoriesButton) + .addGroup(layout.createSequentialGroup() + .addGap(21, 21, 21) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(documentsCheckbox) + .addComponent(pictureVideoCheckbox))) + .addComponent(allFileCategoriesRadioButton)))) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(layoutPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(commonFilesSearchLabel2) + .addGroup(layout.createSequentialGroup() + .addGap(6, 6, 6) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(interCaseRadio) + .addComponent(intraCaseRadio)))) + .addContainerGap(10, Short.MAX_VALUE)))) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() - .addContainerGap() + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(commonFilesSearchLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addGap(18, 18, 18) + .addComponent(commonFilesSearchLabel2) + .addGap(2, 2, 2) .addComponent(intraCaseRadio) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(interCaseRadio) - .addGap(0, 0, 0) - .addComponent(layoutPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(categoriesLabel) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() - .addGap(80, 80, 80) - .addComponent(allFileCategoriesRadioButton)) + .addGap(37, 37, 37) + .addComponent(layoutPanel, javax.swing.GroupLayout.PREFERRED_SIZE, 142, javax.swing.GroupLayout.PREFERRED_SIZE)) .addGroup(layout.createSequentialGroup() + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(intraCasePanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(categoriesLabel) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(selectedFileCategoriesButton) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(pictureVideoCheckbox) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(documentsCheckbox))) + .addComponent(documentsCheckbox) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(allFileCategoriesRadioButton))) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(cancelButton) .addComponent(searchButton) - .addComponent(errorText)) - .addContainerGap()) + .addComponent(errorText))) ); }// //GEN-END:initComponents @@ -669,6 +685,7 @@ public final class CommonFilesPanel extends javax.swing.JPanel { private javax.swing.JButton cancelButton; private javax.swing.JLabel categoriesLabel; private javax.swing.JLabel commonFilesSearchLabel1; + private javax.swing.JLabel commonFilesSearchLabel2; private javax.swing.JCheckBox documentsCheckbox; private javax.swing.JLabel errorText; private javax.swing.ButtonGroup fileTypeFilterButtonGroup; From 45c8a443c147dbcf320ee9f874cbc798d24741cf Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Fri, 18 May 2018 20:41:39 -0600 Subject: [PATCH 019/287] checking various conditions to see what searches we can support --- .../commonfilesearch/CommonFilesPanel.java | 115 +++++++++++------- .../CommonFilesSearchAction.java | 14 ++- 2 files changed, 77 insertions(+), 52 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java index 66bf4c9af4..8a8c6463ee 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java @@ -40,6 +40,7 @@ import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; 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.corecomponentinterfaces.DataResultViewer; import org.sleuthkit.autopsy.corecomponents.DataResultTopComponent; import org.sleuthkit.autopsy.corecomponents.DataResultViewerTable; @@ -76,14 +77,34 @@ public final class CommonFilesPanel extends javax.swing.JPanel { "CommonFilesPanel.exception=Unexpected Exception loading DataSources."}) public CommonFilesPanel() { initComponents(); - + this.errorText.setVisible(false); - + this.intraCasePanel.setParent(this); this.interCasePanel.setParent(this); - + this.setupDataSources(); - this.setupCases(); + + if(CommonFilesPanel.isEamDbAvailable()){ + this.setupCases(); + } else{ + this.disableIntercaseSearch(); + } + } + + private void disableIntercaseSearch(){ + this.intraCaseRadio.setSelected(true); + this.interCaseRadio.setEnabled(false); + } + + public static boolean isEamDbAvailable() { + boolean isEamDbAvailable = false; + try { + isEamDbAvailable = EamDb.isEnabled() && !EamDb.getInstance().getCases().isEmpty(); + } catch (EamDbException ex) { + LOGGER.log(Level.WARNING, "Error accessing EamDb", ex); + } + return isEamDbAvailable; } @NbBundle.Messages({ @@ -151,8 +172,8 @@ public final class CommonFilesPanel extends javax.swing.JPanel { setTitleForSingleSource(dataSourceId); }// else if(false) { - // TODO, is CR cases, add option chosen CorrelationCase ID lookup - // builder = new AllDataSourcesEamDbCommonFilesAlgorithm(CommonFilesPanel.this.dataSourceMap, filterByMedia, filterByDocuments); + // TODO, is CR cases, add option chosen CorrelationCase ID lookup + // builder = new AllDataSourcesEamDbCommonFilesAlgorithm(CommonFilesPanel.this.dataSourceMap, filterByMedia, filterByDocuments); //} this.tabTitle = builder.buildTabTitle(); @@ -176,10 +197,10 @@ public final class CommonFilesPanel extends javax.swing.JPanel { TableFilterNode tableFilterWithDescendantsNode = new TableFilterNode(dataResultFilterNode); DataResultViewerTable table = new DataResultViewerTable(); - + Collection viewers = new ArrayList<>(1); viewers.add(table); - + DataResultTopComponent.createInstance(tabTitle, pathText, tableFilterWithDescendantsNode, metadata.size(), viewers); } catch (InterruptedException ex) { @@ -206,17 +227,18 @@ public final class CommonFilesPanel extends javax.swing.JPanel { } }.execute(); } - + /** * Sets up the data sources dropdown and returns the data sources map for * future usage. * - * @return a mapping of data correlationCase ids to data correlationCase names + * @return a mapping of data correlationCase ids to data correlationCase + * names */ @NbBundle.Messages({ "CommonFilesPanel.setupDataSources.done.tskCoreException=Unable to run query against DB.", "CommonFilesPanel.setupDataSources.done.noCurrentCaseException=Unable to open case file.", - "CommonFilesPanel.setupDataSources.done.exception=Unexpected exception building data sources map.", + "CommonFilesPanel.setupDataSources.done.exception=Unexpected exception loading data sources.", "CommonFilesPanel.setupDataSources.done.interupted=Something went wrong building the Common Files Search dialog box.", "CommonFilesPanel.setupDataSources.done.sqlException=Unable to query db for data sources.", "CommonFilesPanel.setupDataSources.updateUi.noDataSources=No data sources were found."}) @@ -229,7 +251,7 @@ public final class CommonFilesPanel extends javax.swing.JPanel { private static final String SELECT_DATA_SOURCES_IMAGE = "select obj_id, name from tsk_image_names where obj_id in (SELECT obj_id FROM tsk_objects WHERE obj_id in (select obj_id from data_source_info))"; private void updateUi() { - + final Map dataSourceMap = CommonFilesPanel.this.intraCasePanel.getDataSourceMap(); String[] dataSourcesNames = new String[dataSourceMap.size()]; @@ -273,7 +295,7 @@ public final class CommonFilesPanel extends javax.swing.JPanel { try ( SleuthkitCase.CaseDbQuery query = tskDb.executeQuery(SELECT_DATA_SOURCES_IMAGE); ResultSet resultSet = query.getResultSet()) { - + while (resultSet.next()) { Long objectId = resultSet.getLong(1); String dataSourceName = resultSet.getString(2); @@ -333,56 +355,54 @@ public final class CommonFilesPanel extends javax.swing.JPanel { @NbBundle.Messages({ "CommonFilesPanel.setupCases.done.interruptedException=Something went wrong building the Common Files Search dialog box.", - "CommonFilesPanel.setupCases.done.exeutionException=Unexpected exception building data sources map."}) - private void setupCases(){ - - new SwingWorker, Void>(){ - - private void updateUi(){ - + "CommonFilesPanel.setupCases.done.exeutionException=Unexpected exception loading cases."}) + private void setupCases() { + + new SwingWorker, Void>() { + + private void updateUi() { + final Map caseMap = CommonFilesPanel.this.interCasePanel.getCaseMap(); - + String[] caseNames = new String[caseMap.size()]; - - if(caseNames.length > 0){ + + if (caseNames.length > 0) { caseNames = caseMap.values().toArray(caseNames); CommonFilesPanel.this.interCasePanel.setCaseList(new DataSourceComboBoxModel(caseNames)); - + boolean multipleCases = this.centralRepoHasMultipleCases(); CommonFilesPanel.this.interCasePanel.rigForMultipleCases(multipleCases); - - //TODO need something more specific - //InterCasePanel.this.parent.setSearchButtonEnabled(true); + } else { - //TODO need something more specific + CommonFilesPanel.this.disableIntercaseSearch(); } - } - + private Map mapDataSources(List cases) { Map casemap = new HashMap<>(); - - for (CorrelationCase correlationCase : cases){ + + for (CorrelationCase correlationCase : cases) { casemap.put(correlationCase.getID(), correlationCase.getDisplayName()); } - + return casemap; } - + @Override protected Map doInBackground() throws Exception { - + List dataSources = EamDb.getInstance().getCases(); - + Map caseMap = mapDataSources(dataSources); - + return caseMap; } - + @Override - protected void done(){ - try{ - CommonFilesPanel.this.interCasePanel.setCaseMap(this.get()); + protected void done() { + try { + Map cases = this.get(); + CommonFilesPanel.this.interCasePanel.setCaseMap(cases); this.updateUi(); } catch (InterruptedException ex) { LOGGER.log(Level.SEVERE, "Interrupted while building Common Files Search dialog.", ex); @@ -396,9 +416,10 @@ public final class CommonFilesPanel extends javax.swing.JPanel { private boolean centralRepoHasMultipleCases() { return CommonFilesPanel.this.interCasePanel.centralRepoHasMultipleCases(); } - + }.execute(); } + /** * This method is called from within the constructor to initialize the form. * WARNING: Do NOT modify this code. The content of this method is always @@ -616,12 +637,12 @@ public final class CommonFilesPanel extends javax.swing.JPanel { }//GEN-LAST:event_documentsCheckboxActionPerformed private void intraCaseRadioActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_intraCaseRadioActionPerformed - ((java.awt.CardLayout)this.layoutPanel.getLayout()).last(this.layoutPanel); + ((java.awt.CardLayout) this.layoutPanel.getLayout()).last(this.layoutPanel); handleIntraCaseSearchCriteriaChanged(); }//GEN-LAST:event_intraCaseRadioActionPerformed public void handleIntraCaseSearchCriteriaChanged() { - if(this.areIntraCaseSearchCriteriaMet()){ + if (this.areIntraCaseSearchCriteriaMet()) { this.searchButton.setEnabled(true); this.hideErrorMessages(); } else { @@ -632,12 +653,12 @@ public final class CommonFilesPanel extends javax.swing.JPanel { } private void interCaseRadioActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_interCaseRadioActionPerformed - ((java.awt.CardLayout)this.layoutPanel.getLayout()).first(this.layoutPanel); + ((java.awt.CardLayout) this.layoutPanel.getLayout()).first(this.layoutPanel); handleInterCaseSearchCriteriaChanged(); }//GEN-LAST:event_interCaseRadioActionPerformed public void handleInterCaseSearchCriteriaChanged() { - if(this.areInterCaseSearchCriteriaMet()){ + if (this.areInterCaseSearchCriteriaMet()) { this.searchButton.setEnabled(true); this.hideErrorMessages(); } else { @@ -675,7 +696,7 @@ public final class CommonFilesPanel extends javax.swing.JPanel { this.pictureVideoCheckbox.setEnabled(true); this.documentsCheckbox.setEnabled(true); - + this.toggleErrorTextAndSearchBox(); } } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesSearchAction.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesSearchAction.java index c2db78e338..bc5bc6514d 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesSearchAction.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesSearchAction.java @@ -21,6 +21,7 @@ package org.sleuthkit.autopsy.commonfilesearch; import java.awt.event.ActionEvent; import java.util.logging.Level; import java.util.logging.Logger; +import org.openide.util.Exceptions; import org.openide.util.HelpCtx; import org.openide.util.NbBundle; import org.openide.util.actions.CallableSystemAction; @@ -28,6 +29,7 @@ import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.centralrepository.datamodel.EamDb; import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException; import org.sleuthkit.autopsy.core.Installer; +import org.sleuthkit.datamodel.TskCoreException; /** * Encapsulates a menu action which triggers the common files search dialog. @@ -46,14 +48,16 @@ final public class CommonFilesSearchAction extends CallableSystemAction { @Override public boolean isEnabled(){ - boolean isEamDbAvailable = false; + boolean isEamDbAvailable = CommonFilesPanel.isEamDbAvailable(); + + boolean isMultiDataSourceCase = false; try { - isEamDbAvailable = EamDb.isEnabled() && !EamDb.getInstance().getCases().isEmpty(); - } catch (EamDbException ex) { - LOGGER.log(Level.WARNING, "Error accessing EamDb", ex); + isMultiDataSourceCase = Case.isCaseOpen() && !Case.getCurrentCase().getDataSources().isEmpty(); + } catch (TskCoreException ex) { + Exceptions.printStackTrace(ex); } - return super.isEnabled() && Installer.isJavaFxInited()&& Case.isCaseOpen() || isEamDbAvailable; + return super.isEnabled() && Installer.isJavaFxInited() && (isMultiDataSourceCase || isEamDbAvailable); } public static synchronized CommonFilesSearchAction getDefault() { From fd84929d5f53fdfeca5bdee718ef54db4c499962 Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Sat, 19 May 2018 15:20:51 -0600 Subject: [PATCH 020/287] layout tweaks --- .../commonfilesearch/CommonFilesPanel.form | 110 ++++++++---------- .../commonfilesearch/CommonFilesPanel.java | 74 +++++------- .../commonfilesearch/InterCasePanel.form | 7 +- .../commonfilesearch/InterCasePanel.java | 7 +- 4 files changed, 87 insertions(+), 111 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.form b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.form index bb5cc306ba..d7f753fe16 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.form +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.form @@ -6,8 +6,6 @@
- - @@ -38,41 +36,27 @@ - - - - - - - - - - - - - - - - - - - - - - - - - + - + + + + + + + + + + + - +
@@ -81,7 +65,7 @@ - + @@ -89,26 +73,18 @@ - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + @@ -120,6 +96,14 @@ + + + + + + + + @@ -257,16 +241,22 @@ + + + + + + + + + + + + + + + + - - - - - - - - - - diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java index 8a8c6463ee..bc448f8a16 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java @@ -431,7 +431,7 @@ public final class CommonFilesPanel extends javax.swing.JPanel { fileTypeFilterButtonGroup = new javax.swing.ButtonGroup(); interIntraButtonGroup = new javax.swing.ButtonGroup(); - interCasePanel = new org.sleuthkit.autopsy.commonfilesearch.InterCasePanel(); + commonFilesSearchLabel2 = new javax.swing.JLabel(); searchButton = new javax.swing.JButton(); cancelButton = new javax.swing.JButton(); allFileCategoriesRadioButton = new javax.swing.JRadioButton(); @@ -444,8 +444,11 @@ public final class CommonFilesPanel extends javax.swing.JPanel { intraCaseRadio = new javax.swing.JRadioButton(); interCaseRadio = new javax.swing.JRadioButton(); layoutPanel = new java.awt.Panel(); - commonFilesSearchLabel2 = new javax.swing.JLabel(); intraCasePanel = new org.sleuthkit.autopsy.commonfilesearch.IntraCasePanel(); + interCasePanel = new org.sleuthkit.autopsy.commonfilesearch.InterCasePanel(); + + org.openide.awt.Mnemonics.setLocalizedText(commonFilesSearchLabel2, org.openide.util.NbBundle.getMessage(CommonFilesPanel.class, "CommonFilesPanel.commonFilesSearchLabel2.text")); // NOI18N + commonFilesSearchLabel2.setFocusable(false); org.openide.awt.Mnemonics.setLocalizedText(searchButton, org.openide.util.NbBundle.getMessage(CommonFilesPanel.class, "CommonFilesPanel.searchButton.text")); // NOI18N searchButton.setEnabled(false); @@ -527,9 +530,8 @@ public final class CommonFilesPanel extends javax.swing.JPanel { }); layoutPanel.setLayout(new java.awt.CardLayout()); - - org.openide.awt.Mnemonics.setLocalizedText(commonFilesSearchLabel2, org.openide.util.NbBundle.getMessage(CommonFilesPanel.class, "CommonFilesPanel.commonFilesSearchLabel2.text")); // NOI18N - commonFilesSearchLabel2.setFocusable(false); + layoutPanel.add(intraCasePanel, "card3"); + layoutPanel.add(interCasePanel, "card2"); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); @@ -548,36 +550,27 @@ public final class CommonFilesPanel extends javax.swing.JPanel { .addGroup(layout.createSequentialGroup() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(commonFilesSearchLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGroup(layout.createSequentialGroup() - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addGap(20, 20, 20) - .addComponent(intraCasePanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addComponent(categoriesLabel) - .addGroup(layout.createSequentialGroup() - .addGap(6, 6, 6) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(selectedFileCategoriesButton) - .addGroup(layout.createSequentialGroup() - .addGap(21, 21, 21) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(documentsCheckbox) - .addComponent(pictureVideoCheckbox))) - .addComponent(allFileCategoriesRadioButton)))) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(layoutPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(categoriesLabel) .addComponent(commonFilesSearchLabel2) .addGroup(layout.createSequentialGroup() .addGap(6, 6, 6) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addGap(21, 21, 21) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(documentsCheckbox) + .addComponent(pictureVideoCheckbox))) + .addComponent(allFileCategoriesRadioButton) + .addComponent(selectedFileCategoriesButton) .addComponent(interCaseRadio) - .addComponent(intraCaseRadio)))) - .addContainerGap(10, Short.MAX_VALUE)))) + .addComponent(intraCaseRadio))) + .addComponent(layoutPanel, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, 507, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addContainerGap() .addComponent(commonFilesSearchLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addGap(18, 18, 18) .addComponent(commonFilesSearchLabel2) @@ -585,23 +578,18 @@ public final class CommonFilesPanel extends javax.swing.JPanel { .addComponent(intraCaseRadio) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(interCaseRadio) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addGap(37, 37, 37) - .addComponent(layoutPanel, javax.swing.GroupLayout.PREFERRED_SIZE, 142, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addGroup(layout.createSequentialGroup() - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(intraCasePanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(categoriesLabel) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(selectedFileCategoriesButton) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(pictureVideoCheckbox) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(documentsCheckbox) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(allFileCategoriesRadioButton))) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(layoutPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(0, 0, 0) + .addComponent(categoriesLabel) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(selectedFileCategoriesButton) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(pictureVideoCheckbox) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(documentsCheckbox) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(allFileCategoriesRadioButton) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(cancelButton) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.form b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.form index daa29800f6..a336fbba3c 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.form +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.form @@ -20,15 +20,15 @@ - + - + @@ -37,13 +37,12 @@ - - + diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.java index 5a6677acf5..2886ee941c 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.java @@ -119,22 +119,21 @@ public class InterCasePanel extends javax.swing.JPanel { .addContainerGap() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(anyCentralRepoCaseRadio) - .addComponent(specificCentralRepoCaseRadio) .addGroup(layout.createSequentialGroup() .addGap(21, 21, 21) - .addComponent(caseComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 261, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addComponent(caseComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 261, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(specificCentralRepoCaseRadio)) .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() - .addContainerGap() .addComponent(anyCentralRepoCaseRadio) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(specificCentralRepoCaseRadio) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(caseComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addContainerGap(35, Short.MAX_VALUE)) ); }// //GEN-END:initComponents From cbf1f4566c7dd77a67e91b8929ce60f880d3f712 Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Sun, 20 May 2018 08:36:06 -0600 Subject: [PATCH 021/287] default radio buttons and card layout toggling fixed --- .../commonfilesearch/CommonFilesPanel.form | 39 +++++++++--------- .../commonfilesearch/CommonFilesPanel.java | 40 +++++++++---------- .../commonfilesearch/InterCasePanel.form | 7 ++-- .../commonfilesearch/InterCasePanel.java | 5 +-- .../commonfilesearch/IntraCasePanel.form | 16 ++++---- .../commonfilesearch/IntraCasePanel.java | 18 +++++---- 6 files changed, 62 insertions(+), 63 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.form b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.form index d7f753fe16..eca1312b65 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.form +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.form @@ -33,30 +33,28 @@ + + + + - - - - - + + - - - - - - - - - - - + + - + + + + + + + + - @@ -73,7 +71,7 @@ - + @@ -151,7 +149,6 @@ - @@ -216,6 +213,7 @@ + @@ -229,7 +227,6 @@ - diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java index bc448f8a16..03dc5da13e 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java @@ -478,7 +478,6 @@ public final class CommonFilesPanel extends javax.swing.JPanel { }); fileTypeFilterButtonGroup.add(selectedFileCategoriesButton); - selectedFileCategoriesButton.setSelected(true); org.openide.awt.Mnemonics.setLocalizedText(selectedFileCategoriesButton, org.openide.util.NbBundle.getMessage(CommonFilesPanel.class, "CommonFilesPanel.selectedFileCategoriesButton.text")); // NOI18N selectedFileCategoriesButton.setToolTipText(org.openide.util.NbBundle.getMessage(CommonFilesPanel.class, "CommonFilesPanel.selectedFileCategoriesButton.toolTipText")); // NOI18N selectedFileCategoriesButton.addActionListener(new java.awt.event.ActionListener() { @@ -513,6 +512,7 @@ public final class CommonFilesPanel extends javax.swing.JPanel { commonFilesSearchLabel1.setFocusable(false); interIntraButtonGroup.add(intraCaseRadio); + intraCaseRadio.setSelected(true); intraCaseRadio.setLabel(org.openide.util.NbBundle.getMessage(CommonFilesPanel.class, "CommonFilesPanel.intraCaseRadio.label")); // NOI18N intraCaseRadio.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { @@ -521,7 +521,6 @@ public final class CommonFilesPanel extends javax.swing.JPanel { }); interIntraButtonGroup.add(interCaseRadio); - interCaseRadio.setSelected(true); org.openide.awt.Mnemonics.setLocalizedText(interCaseRadio, org.openide.util.NbBundle.getMessage(CommonFilesPanel.class, "CommonFilesPanel.jRadioButton2.text")); // NOI18N interCaseRadio.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { @@ -547,25 +546,24 @@ public final class CommonFilesPanel extends javax.swing.JPanel { .addComponent(searchButton) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(cancelButton)) + .addComponent(commonFilesSearchLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(categoriesLabel) + .addComponent(commonFilesSearchLabel2) .addGroup(layout.createSequentialGroup() + .addGap(6, 6, 6) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(commonFilesSearchLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(categoriesLabel) - .addComponent(commonFilesSearchLabel2) .addGroup(layout.createSequentialGroup() - .addGap(6, 6, 6) + .addGap(21, 21, 21) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addGap(21, 21, 21) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(documentsCheckbox) - .addComponent(pictureVideoCheckbox))) - .addComponent(allFileCategoriesRadioButton) - .addComponent(selectedFileCategoriesButton) - .addComponent(interCaseRadio) - .addComponent(intraCaseRadio))) - .addComponent(layoutPanel, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, 507, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))) + .addComponent(documentsCheckbox) + .addComponent(pictureVideoCheckbox))) + .addComponent(allFileCategoriesRadioButton) + .addComponent(selectedFileCategoriesButton) + .addComponent(interCaseRadio) + .addComponent(intraCaseRadio) + .addGroup(layout.createSequentialGroup() + .addGap(10, 10, 10) + .addComponent(layoutPanel, javax.swing.GroupLayout.PREFERRED_SIZE, 507, javax.swing.GroupLayout.PREFERRED_SIZE)))))) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) @@ -578,7 +576,7 @@ public final class CommonFilesPanel extends javax.swing.JPanel { .addComponent(intraCaseRadio) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(interCaseRadio) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGap(0, 0, 0) .addComponent(layoutPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addGap(0, 0, 0) .addComponent(categoriesLabel) @@ -625,7 +623,7 @@ public final class CommonFilesPanel extends javax.swing.JPanel { }//GEN-LAST:event_documentsCheckboxActionPerformed private void intraCaseRadioActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_intraCaseRadioActionPerformed - ((java.awt.CardLayout) this.layoutPanel.getLayout()).last(this.layoutPanel); + ((java.awt.CardLayout) this.layoutPanel.getLayout()).first(this.layoutPanel); handleIntraCaseSearchCriteriaChanged(); }//GEN-LAST:event_intraCaseRadioActionPerformed @@ -641,7 +639,7 @@ public final class CommonFilesPanel extends javax.swing.JPanel { } private void interCaseRadioActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_interCaseRadioActionPerformed - ((java.awt.CardLayout) this.layoutPanel.getLayout()).first(this.layoutPanel); + ((java.awt.CardLayout) this.layoutPanel.getLayout()).last(this.layoutPanel); handleInterCaseSearchCriteriaChanged(); }//GEN-LAST:event_interCaseRadioActionPerformed @@ -726,7 +724,7 @@ public final class CommonFilesPanel extends javax.swing.JPanel { } private void showIntraCaseErrorMessage() { - this.errorText.setText(Bundle.CommonFilesPanel_showIntraCaseErrorMessage_message()); + this.errorText.setText(this.intraCasePanel.getErrorMessage()); this.errorText.setVisible(true); } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.form b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.form index a336fbba3c..8c62356803 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.form +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.form @@ -24,11 +24,11 @@ - - + + - + @@ -42,7 +42,6 @@ -
diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.java index 2886ee941c..7fba9bfb69 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.java @@ -132,8 +132,7 @@ public class InterCasePanel extends javax.swing.JPanel { .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(specificCentralRepoCaseRadio) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(caseComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addContainerGap(35, Short.MAX_VALUE)) + .addComponent(caseComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) ); }// //GEN-END:initComponents @@ -190,7 +189,7 @@ public class InterCasePanel extends javax.swing.JPanel { }) boolean areSearchCriteriaMet() { if(this.caseMap.isEmpty()){ - this.errorMessage = Bundle.CommonFilesPanel_showInterCaseErrorMessage_message(); + this.errorMessage = Bundle.InterCasePanel_showInterCaseErrorMessage_message(); return false; } else { return true; diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCasePanel.form b/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCasePanel.form index b8e270890a..7038ca5926 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCasePanel.form +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCasePanel.form @@ -20,13 +20,17 @@ - - + - - + + + + + + + - + @@ -37,13 +41,11 @@ - - diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCasePanel.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCasePanel.java index 9edd3b4a68..fd2d429895 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCasePanel.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCasePanel.java @@ -130,25 +130,25 @@ public class IntraCasePanel extends javax.swing.JPanel { layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() - .addContainerGap() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(withinDataSourceRadioButton) - .addComponent(allDataSourcesRadioButton) .addGroup(layout.createSequentialGroup() - .addGap(20, 20, 20) + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(allDataSourcesRadioButton) + .addComponent(withinDataSourceRadioButton))) + .addGroup(layout.createSequentialGroup() + .addGap(27, 27, 27) .addComponent(selectDataSourceComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 261, javax.swing.GroupLayout.PREFERRED_SIZE))) .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() - .addContainerGap() .addComponent(allDataSourcesRadioButton) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(withinDataSourceRadioButton) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(selectDataSourceComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addComponent(selectDataSourceComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) ); }// //GEN-END:initComponents @@ -217,4 +217,8 @@ public class IntraCasePanel extends javax.swing.JPanel { return true; } } + + String getErrorMessage() { + return this.errorMessage; + } } From 49636bcca18ac9b7324cc55068baf4e47c39add9 Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Sun, 20 May 2018 10:48:29 -0600 Subject: [PATCH 022/287] more layout tweaks --- .../commonfilesearch/Bundle.properties | 9 ++++--- .../commonfilesearch/CommonFilesPanel.form | 27 +++++++++---------- .../commonfilesearch/CommonFilesPanel.java | 19 +++++++------ 3 files changed, 27 insertions(+), 28 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/Bundle.properties b/Core/src/org/sleuthkit/autopsy/commonfilesearch/Bundle.properties index 17a8d84922..4e44ebd8d3 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/Bundle.properties @@ -1,17 +1,17 @@ CommonFilesPanel.searchButton.text=Search CommonFilesPanel.cancelButton.text=Cancel CommonFilesPanel.cancelButton.actionCommand=Cancel -CommonFilesPanel.selectedFileCategoriesButton.text=Match on the following file categories: +CommonFilesPanel.selectedFileCategoriesButton.text=Only the selected file types: CommonFilesPanel.selectedFileCategoriesButton.toolTipText=Select from the options below... CommonFilesPanel.pictureVideoCheckbox.text=Pictures and Videos CommonFilesPanel.documentsCheckbox.text=Documents CommonFilesPanel.allFileCategoriesRadioButton.toolTipText=No filtering applied to results... -CommonFilesPanel.allFileCategoriesRadioButton.text=Match on all file types +CommonFilesPanel.allFileCategoriesRadioButton.text=All file types CommonFilesPanel.text=Indicate which data sources to consider while searching for duplicates: -CommonFilesPanel.categoriesLabel.text=Indicate which file types to include in results: +CommonFilesPanel.categoriesLabel.text=File Types To Include: CommonFilesPanel.errorText.text=In order to search, you must select a file category. CommonFilesPanel.jRadioButton1.text=jRadioButton1 -CommonFilesPanel.jRadioButton2.text=Correlate amongst external cases (compares files in current case with Central Repo) +CommonFilesPanel.jRadioButton2.text=With previous cases in the Central Repository CommonFilesPanel.intraCaseRadio.label=Correlate within current case only CommonFilesPanel.interCaseRadio.label=Correlate amongst all known cases (uses Central Repo) IntraCasePanel.allDataSourcesRadioButton.text=Matches may be from any data source @@ -20,3 +20,4 @@ InterCasePanel.specificCentralRepoCaseRadio.text=Matches must be from the follow InterCasePanel.anyCentralRepoCaseRadio.text=Matches may be from any Central Repo case CommonFilesPanel.commonFilesSearchLabel1.text=Find common files to correlate data soures or cases. CommonFilesPanel.commonFilesSearchLabel2.text=Scope of Search +CommonFilesPanel.intraCaseRadio.text=Within current case diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.form b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.form index eca1312b65..d32724abe2 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.form +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.form @@ -23,16 +23,8 @@ - + - - - - - - - - @@ -50,9 +42,16 @@ - - - + + + + + + + + + + @@ -214,8 +213,8 @@ - - + + diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java index 03dc5da13e..5ebe4e37ba 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java @@ -513,7 +513,7 @@ public final class CommonFilesPanel extends javax.swing.JPanel { interIntraButtonGroup.add(intraCaseRadio); intraCaseRadio.setSelected(true); - intraCaseRadio.setLabel(org.openide.util.NbBundle.getMessage(CommonFilesPanel.class, "CommonFilesPanel.intraCaseRadio.label")); // NOI18N + org.openide.awt.Mnemonics.setLocalizedText(intraCaseRadio, org.openide.util.NbBundle.getMessage(CommonFilesPanel.class, "CommonFilesPanel.intraCaseRadio.text")); // NOI18N intraCaseRadio.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { intraCaseRadioActionPerformed(evt); @@ -537,15 +537,8 @@ public final class CommonFilesPanel extends javax.swing.JPanel { layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() - .addContainerGap() + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() - .addGap(0, 0, Short.MAX_VALUE) - .addComponent(errorText) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(searchButton) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(cancelButton)) .addComponent(commonFilesSearchLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(categoriesLabel) .addComponent(commonFilesSearchLabel2) @@ -563,7 +556,13 @@ public final class CommonFilesPanel extends javax.swing.JPanel { .addComponent(intraCaseRadio) .addGroup(layout.createSequentialGroup() .addGap(10, 10, 10) - .addComponent(layoutPanel, javax.swing.GroupLayout.PREFERRED_SIZE, 507, javax.swing.GroupLayout.PREFERRED_SIZE)))))) + .addComponent(layoutPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(layout.createSequentialGroup() + .addComponent(errorText) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(searchButton) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(cancelButton)))))) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) From 4b5d2df7f83c512a232234770c93001b8b2b08f5 Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Sun, 20 May 2018 14:20:28 -0600 Subject: [PATCH 023/287] wired metadatabuilders into search button and performed some minor refactors --- ...lDataSourcesEamDbCommonFilesAlgorithm.java | 97 ++++++++++++++++++- .../CommonFilesMetadataBuilder.java | 58 ----------- .../commonfilesearch/CommonFilesPanel.java | 66 +++++++------ .../commonfilesearch/InterCasePanel.java | 16 ++- .../commonfilesearch/IntraCasePanel.java | 12 ++- 5 files changed, 155 insertions(+), 94 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllDataSourcesEamDbCommonFilesAlgorithm.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllDataSourcesEamDbCommonFilesAlgorithm.java index ea52971f20..0700d4ae9e 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllDataSourcesEamDbCommonFilesAlgorithm.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllDataSourcesEamDbCommonFilesAlgorithm.java @@ -19,8 +19,22 @@ */ package org.sleuthkit.autopsy.commonfilesearch; +import java.sql.SQLException; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; import java.util.Map; +import java.util.logging.Level; +import java.util.stream.Collectors; +import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; +import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeCommonInstance; +import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationCase; +import org.sleuthkit.autopsy.centralrepository.datamodel.EamDb; +import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException; import static org.sleuthkit.autopsy.commonfilesearch.CommonFilesMetadataBuilder.SELECT_PREFIX; +import static org.sleuthkit.autopsy.timeline.datamodel.eventtype.ArtifactEventType.LOGGER; +import org.sleuthkit.datamodel.HashUtility; +import org.sleuthkit.datamodel.TskCoreException; /** @@ -30,6 +44,8 @@ public class AllDataSourcesEamDbCommonFilesAlgorithm extends CommonFilesMetadat private static final String WHERE_CLAUSE = "%s md5 in (select md5 from tsk_files where (known != 1 OR known IS NULL)%s GROUP BY md5) order by md5"; //NON-NLS + private EamDb dbManager; + /** * Implements the algorithm for getting common files across all data * sources. @@ -38,9 +54,78 @@ public class AllDataSourcesEamDbCommonFilesAlgorithm extends CommonFilesMetadat * @param filterByMediaMimeType match only on files whose mime types can be broadly categorized as media types * @param filterByDocMimeType match only on files whose mime types can be broadly categorized as document types */ - AllDataSourcesEamDbCommonFilesAlgorithm(Map dataSourceIdMap, boolean filterByMediaMimeType, boolean filterByDocMimeType) { + AllDataSourcesEamDbCommonFilesAlgorithm(Map dataSourceIdMap, boolean filterByMediaMimeType, boolean filterByDocMimeType) throws EamDbException { super(dataSourceIdMap, filterByMediaMimeType, filterByDocMimeType); + dbManager = EamDb.getInstance(); + } + + public CommonFilesMetadata findEamDbCommonFiles() throws TskCoreException, NoCurrentCaseException, SQLException, EamDbException { + return this.findEamDbCommonFiles(null); + } + + public CommonFilesMetadata findEamDbCommonFiles(int correlationCaseId) throws TskCoreException, NoCurrentCaseException, SQLException, EamDbException, Exception { + + CorrelationCase cCase = this.getCorrelationCaseFromId(correlationCaseId); + + return this.findEamDbCommonFiles(cCase); + } + + /** + * TODO Refactor, abstract shared code above, call this method via new AllDataSourcesEamDbCommonFilesAlgorithm Class + * @param correlationCase Optionally null, otherwise a case, or could be a CR case ID + * @return + * @throws TskCoreException + * @throws NoCurrentCaseException + * @throws SQLException + * @throws EamDbException + */ + public CommonFilesMetadata findEamDbCommonFiles(CorrelationCase correlationCase) throws TskCoreException, NoCurrentCaseException, SQLException, EamDbException { + CommonFilesMetadata metaData = this.findCommonFiles(); + Map commonFiles = metaData.getMetadata(); + List values = Arrays.asList((String[]) commonFiles.keySet().toArray()); + + Map interCaseCommonFiles = metaData.getMetadata(); + try { + + Collection artifactInstances = dbManager.getArtifactInstancesByCaseValues(correlationCase, values).stream() + .collect(Collectors.toList()); + + + for (CorrelationAttributeCommonInstance instance : artifactInstances) { + //Long objectId = 1L; //TODO, need to retrieve ALL (even count < 2) AbstractFiles from this case to us for objectId for CR matches; + String md5 = instance.getValue(); + String dataSource = instance.getCorrelationDataSource().getName(); + + if (md5 == null || HashUtility.isNoDataMd5(md5)) { + continue; + } + //Builds a 3rd list which contains instances which are in commonFiles map, uses current case objectId + if (commonFiles.containsKey(md5)) { + // TODO sloppy, but we don't *have* all the information for the rows in the CR, so what do we do? + Long objectId = commonFiles.get(md5).getMetadata().iterator().next().getObjectId(); + if(interCaseCommonFiles.containsKey(md5)) { + //Add to intercase metaData + final Md5Metadata md5Metadata = interCaseCommonFiles.get(md5); + md5Metadata.addFileInstanceMetadata(new FileInstanceMetadata(objectId, dataSource)); + + } else { + // Create new intercase metadata + final Md5Metadata md5Metadata = commonFiles.get(md5); + md5Metadata.addFileInstanceMetadata(new FileInstanceMetadata(objectId, dataSource)); + interCaseCommonFiles.put(md5, md5Metadata); + } + } else { + // TODO This should never happen. All current case files with potential matches are in comonFiles Map. + } + } + + } catch (EamDbException ex) { + LOGGER.log(Level.SEVERE, "Error getting artifact instances from database.", ex); // NON-NLS + } + // Builds intercase-only matches metadata + return new CommonFilesMetadata(interCaseCommonFiles); + } @Override @@ -55,4 +140,14 @@ public class AllDataSourcesEamDbCommonFilesAlgorithm extends CommonFilesMetadat final String titleTemplate = Bundle.CommonFilesMetadataBuilder_buildTabTitle_titleEamDb(); return String.format(titleTemplate, new Object[]{buildCategorySelectionString}); } + + private CorrelationCase getCorrelationCaseFromId(int correlationCaseId) throws EamDbException, Exception { + //TODO is there a better way??? + for(CorrelationCase cCase : this.dbManager.getCases()){ + if(cCase.getID() == correlationCaseId){ + return cCase; + } + } + throw new Exception("Cannont locate case."); + } } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesMetadataBuilder.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesMetadataBuilder.java index 47f477d82a..7e031995e8 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesMetadataBuilder.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesMetadataBuilder.java @@ -210,64 +210,6 @@ abstract class CommonFilesMetadataBuilder { return new CommonFilesMetadata(commonFiles); } - - /** - * TODO Refactor, abstract shared code above, call this method via new AllDataSourcesEamDbCommonFilesAlgorithm Class - * @param correlationCase Optionally null, otherwise a case, or could be a CR case ID - * @return - * @throws TskCoreException - * @throws NoCurrentCaseException - * @throws SQLException - * @throws EamDbException - */ - public CommonFilesMetadata findEamDbCommonFiles(CorrelationCase correlationCase) throws TskCoreException, NoCurrentCaseException, SQLException, EamDbException { - CommonFilesMetadata metaData = this.findCommonFiles(); - Map commonFiles = metaData.getMetadata(); - List values = Arrays.asList((String[]) commonFiles.keySet().toArray()); - - Map interCaseCommonFiles = metaData.getMetadata(); - try { - - EamDb dbManager = EamDb.getInstance(); - Collection artifactInstances = dbManager.getArtifactInstancesByCaseValues(correlationCase, values).stream() - .collect(Collectors.toList()); - - - for (CorrelationAttributeCommonInstance instance : artifactInstances) { - //Long objectId = 1L; //TODO, need to retrieve ALL (even count < 2) AbstractFiles from this case to us for objectId for CR matches; - String md5 = instance.getValue(); - String dataSource = instance.getCorrelationDataSource().getName(); - - if (md5 == null || HashUtility.isNoDataMd5(md5)) { - continue; - } - //Builds a 3rd list which contains instances which are in commonFiles map, uses current case objectId - if (commonFiles.containsKey(md5)) { - // TODO sloppy, but we don't *have* all the information for the rows in the CR, so what do we do? - Long objectId = commonFiles.get(md5).getMetadata().iterator().next().getObjectId(); - if(interCaseCommonFiles.containsKey(md5)) { - //Add to intercase metaData - final Md5Metadata md5Metadata = interCaseCommonFiles.get(md5); - md5Metadata.addFileInstanceMetadata(new FileInstanceMetadata(objectId, dataSource)); - - } else { - // Create new intercase metadata - final Md5Metadata md5Metadata = commonFiles.get(md5); - md5Metadata.addFileInstanceMetadata(new FileInstanceMetadata(objectId, dataSource)); - interCaseCommonFiles.put(md5, md5Metadata); - } - } else { - // TODO This should never happen. All current case files with potential matches are in comonFiles Map. - } - } - - } catch (EamDbException ex) { - LOGGER.log(Level.SEVERE, "Error getting artifact instances from database.", ex); // NON-NLS - } - // Builds intercase-only matches metadata - return new CommonFilesMetadata(interCaseCommonFiles); - - } /** * Should be used by subclasses, in their diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java index 5ebe4e37ba..3700d9450b 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java @@ -85,14 +85,14 @@ public final class CommonFilesPanel extends javax.swing.JPanel { this.setupDataSources(); - if(CommonFilesPanel.isEamDbAvailable()){ - this.setupCases(); - } else{ + if (CommonFilesPanel.isEamDbAvailable()) { + this.setupCases(); + } else { this.disableIntercaseSearch(); - } + } } - - private void disableIntercaseSearch(){ + + private void disableIntercaseSearch() { this.intraCaseRadio.setSelected(true); this.interCaseRadio.setEnabled(false); } @@ -134,25 +134,23 @@ public final class CommonFilesPanel extends javax.swing.JPanel { this.tabTitle = String.format(CommonFilesPanel_search_results_titleSingle, dataSourceName); } - private Long determineDataSourceId() { - Long selectedObjId = CommonFilesPanel.NO_DATA_SOURCE_SELECTED; - if (CommonFilesPanel.this.singleDataSource) { - for (Entry dataSource : CommonFilesPanel.this.intraCasePanel.getDataSourceMap().entrySet()) { - if (dataSource.getValue().equals(CommonFilesPanel.this.selectedDataSource)) { - selectedObjId = dataSource.getKey(); - break; - } - } - } - return selectedObjId; + private void setTitleForAllCases() { + + } + + private void setTitleForSingleCase() { + } @Override @SuppressWarnings({"BoxedValueEquality", "NumberEquality"}) - protected CommonFilesMetadata doInBackground() throws TskCoreException, NoCurrentCaseException, SQLException { - Long dataSourceId = determineDataSourceId(); + protected CommonFilesMetadata doInBackground() throws TskCoreException, NoCurrentCaseException, SQLException, EamDbException { + Long dataSourceId = CommonFilesPanel.this.intraCasePanel.getSelectedDataSourceId(); + Integer caseId = CommonFilesPanel.this.interCasePanel.getSelectedCaseId(); CommonFilesMetadataBuilder builder; + CommonFilesMetadata metadata; + boolean filterByMedia = false; boolean filterByDocuments = false; if (selectedFileCategoriesButton.isSelected()) { @@ -163,23 +161,31 @@ public final class CommonFilesPanel extends javax.swing.JPanel { filterByDocuments = true; } } - if (dataSourceId == CommonFilesPanel.NO_DATA_SOURCE_SELECTED) { - builder = new AllDataSourcesCommonFilesAlgorithm(CommonFilesPanel.this.intraCasePanel.getDataSourceMap(), filterByMedia, filterByDocuments); - setTitleForAllDataSources(); + if (CommonFilesPanel.this.interCaseRadio.isSelected()) { + + builder = new AllDataSourcesEamDbCommonFilesAlgorithm(CommonFilesPanel.this.intraCasePanel.getDataSourceMap(), filterByMedia, filterByDocuments); + + if(caseId == InterCasePanel.NO_CASE_SELECTED){ + metadata = ((AllDataSourcesEamDbCommonFilesAlgorithm)builder).findEamDbCommonFiles(); + } else { + metadata = ((AllDataSourcesEamDbCommonFilesAlgorithm)builder).findEamDbCommonFiles(CommonFilesPanel.this.interCasePanel.getSelectedCaseId()); + } } else { - builder = new SingleDataSource(dataSourceId, CommonFilesPanel.this.intraCasePanel.getDataSourceMap(), filterByMedia, filterByDocuments); + if (dataSourceId == CommonFilesPanel.NO_DATA_SOURCE_SELECTED) { + builder = new AllDataSourcesCommonFilesAlgorithm(CommonFilesPanel.this.intraCasePanel.getDataSourceMap(), filterByMedia, filterByDocuments); - setTitleForSingleSource(dataSourceId); - }// else if(false) { - // TODO, is CR cases, add option chosen CorrelationCase ID lookup - // builder = new AllDataSourcesEamDbCommonFilesAlgorithm(CommonFilesPanel.this.dataSourceMap, filterByMedia, filterByDocuments); - //} + setTitleForAllDataSources(); + } else { + builder = new SingleDataSource(dataSourceId, CommonFilesPanel.this.intraCasePanel.getDataSourceMap(), filterByMedia, filterByDocuments); + setTitleForSingleSource(dataSourceId); + } + metadata = builder.findCommonFiles(); + } + this.tabTitle = builder.buildTabTitle(); - CommonFilesMetadata metadata = builder.findCommonFiles(); - return metadata; } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.java index 7fba9bfb69..fefbfb8908 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.java @@ -22,6 +22,7 @@ package org.sleuthkit.autopsy.commonfilesearch; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Map.Entry; import java.util.concurrent.ExecutionException; import java.util.logging.Level; import javax.swing.ComboBoxModel; @@ -40,12 +41,10 @@ import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil; public class InterCasePanel extends javax.swing.JPanel { private static final long serialVersionUID = 1L; + static final int NO_CASE_SELECTED = -1; private static final Logger LOGGER = Logger.getLogger(InterCasePanel.class.getName()); - private String selectedCase; - private boolean singleCase; - private ComboBoxModel casesList = new DataSourceComboBoxModel(); private Map caseMap; @@ -65,7 +64,6 @@ public class InterCasePanel extends javax.swing.JPanel { this.specificCentralRepoCaseRadio.setEnabled(selected); if (this.specificCentralRepoCaseRadio.isEnabled()) { this.caseComboBox.setSelectedIndex(0); - this.singleCase = true; } } @@ -183,6 +181,16 @@ public class InterCasePanel extends javax.swing.JPanel { boolean centralRepoHasMultipleCases() { return this.caseMap.size() >= 2; } + + Integer getSelectedCaseId(){ + for(Entry entry : this.caseMap.entrySet()){ + if(entry.getValue().equals(this.caseComboBox.getSelectedItem())){ + return entry.getKey(); + } + } + + return InterCasePanel.NO_CASE_SELECTED; + } @NbBundle.Messages({ "InterCasePanel.showInterCaseErrorMessage.message=Cannot run intercase correlation search: no cases in Central Repository." diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCasePanel.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCasePanel.java index fd2d429895..ee90532109 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCasePanel.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCasePanel.java @@ -24,6 +24,7 @@ import java.sql.ResultSet; import java.sql.SQLException; import java.util.HashMap; import java.util.Map; +import java.util.Map.Entry; import java.util.concurrent.ExecutionException; import java.util.logging.Level; import javax.swing.ComboBoxModel; @@ -44,6 +45,7 @@ import org.sleuthkit.datamodel.TskCoreException; public class IntraCasePanel extends javax.swing.JPanel { private static final long serialVersionUID = 1L; + static final long NO_DATA_SOURCE_SELECTED = -1; private static final Logger LOGGER = Logger.getLogger(CommonFilesPanel.class.getName()); @@ -83,7 +85,15 @@ public class IntraCasePanel extends javax.swing.JPanel { return this.dataSourceMap; } - + Long getSelectedDataSourceId(){ + for(Entry entry : this.dataSourceMap.entrySet()){ + if(entry.getValue().equals(this.selectDataSourceComboBox.getSelectedItem())){ + return entry.getKey(); + } + } + + return IntraCasePanel.NO_DATA_SOURCE_SELECTED; + } /** * This method is called from within the constructor to initialize the form. From 31a5e2f40e95fd2220278c2c69e267336ce4be02 Mon Sep 17 00:00:00 2001 From: Andrew Ziehl Date: Sun, 20 May 2018 13:21:58 -0700 Subject: [PATCH 024/287] Update EamDb query to utilize currentCase instead of list of md5s. --- .../datamodel/AbstractSqlEamDb.java | 19 +++++++------------ .../centralrepository/datamodel/EamDb.java | 2 +- .../datamodel/SqliteEamDb.java | 4 ++-- 3 files changed, 10 insertions(+), 15 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java index 91b3dda535..a0fed4ba99 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java @@ -657,7 +657,7 @@ public abstract class AbstractSqlEamDb implements EamDb { * @return List of artifact instances for a given list of MD5 values */ @Override - public List getArtifactInstancesByCaseValues(CorrelationCase correlationCase, List values) throws EamDbException { + public List getArtifactInstancesByCaseValues(CorrelationCase correlationCase, CorrelationCase currentCase) throws EamDbException { CorrelationAttribute.Type aType = CorrelationAttribute.getDefaultCorrelationTypes().get(0); // Files type if (aType == null) { throw new EamDbException("Correlation Type is null"); @@ -674,15 +674,6 @@ public abstract class AbstractSqlEamDb implements EamDb { PreparedStatement preparedStatement = null; ResultSet resultSet = null; - String valuesString = ""; - StringBuilder valuesFilter = new StringBuilder(values.size()); - if (!values.isEmpty()) { - for (String value : values) { - valuesFilter.append("'").append(value).append("',"); - } - valuesString = valuesFilter.toString().substring(0, valuesFilter.length() - 1); - } - String tableName = EamDbUtil.correlationTypeToInstanceTableName(aType); StringBuilder sql = new StringBuilder(9); sql.append("SELECT cases.case_name, cases.case_uid, data_sources.name, device_id, file_path, known_status, comment, data_sources.case_id, value FROM "); @@ -693,7 +684,11 @@ public abstract class AbstractSqlEamDb implements EamDb { sql.append(" LEFT JOIN data_sources ON "); sql.append(tableName); sql.append(".data_source_id=data_sources.id"); - sql.append(" WHERE value IN (?)"); + sql.append(" WHERE value IN (SELECT value FROM "); + sql.append(tableName); + sql.append(" WHERE "); + sql.append(tableName); + sql.append(".case_id= ?)"); if (singleCase) { sql.append(" AND "); sql.append(tableName); @@ -702,7 +697,7 @@ public abstract class AbstractSqlEamDb implements EamDb { try { preparedStatement = conn.prepareStatement(sql.toString()); - preparedStatement.setString(1, valuesString); + preparedStatement.setString(1, String.valueOf(currentCase.getID())); if (singleCase && correlationCase != null) { preparedStatement.setString(2, String.valueOf(correlationCase.getID())); } diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDb.java index 24af255eea..8daf5e23ef 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDb.java @@ -232,7 +232,7 @@ public interface EamDb { * * @return List of artifact instances for a given list of MD5 values */ - List getArtifactInstancesByCaseValues(CorrelationCase correlationCase, List values) throws EamDbException; + List getArtifactInstancesByCaseValues(CorrelationCase correlationCase, CorrelationCase currentCase) throws EamDbException; /** * Retrieves eamArtifact instances from the database that are associated diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java index 0917cedc60..de8ef06ac8 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java @@ -430,10 +430,10 @@ public class SqliteEamDb extends AbstractSqlEamDb { * @return List of artifact instances for a given list of MD5 values */ @Override - public List getArtifactInstancesByCaseValues(CorrelationCase correlationCase, List values) throws EamDbException { + public List getArtifactInstancesByCaseValues(CorrelationCase correlationCase, CorrelationCase currentCase) throws EamDbException { try { acquireSharedLock(); - return super.getArtifactInstancesByCaseValues(correlationCase, values); + return super.getArtifactInstancesByCaseValues(correlationCase, currentCase); } finally { releaseSharedLock(); } From a799aa1b1201c31db9c0ce149c51123797447435 Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Sun, 20 May 2018 14:47:31 -0600 Subject: [PATCH 025/287] missing exception declaration --- .../sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java index 3700d9450b..d7f06bb329 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java @@ -144,7 +144,7 @@ public final class CommonFilesPanel extends javax.swing.JPanel { @Override @SuppressWarnings({"BoxedValueEquality", "NumberEquality"}) - protected CommonFilesMetadata doInBackground() throws TskCoreException, NoCurrentCaseException, SQLException, EamDbException { + protected CommonFilesMetadata doInBackground() throws TskCoreException, NoCurrentCaseException, SQLException, EamDbException, Exception { Long dataSourceId = CommonFilesPanel.this.intraCasePanel.getSelectedDataSourceId(); Integer caseId = CommonFilesPanel.this.interCasePanel.getSelectedCaseId(); From df4ec0b17e50b30ec5499c471268b65518101296 Mon Sep 17 00:00:00 2001 From: Andrew Ziehl Date: Sun, 20 May 2018 13:48:09 -0700 Subject: [PATCH 026/287] Revert "Update EamDb query to utilize currentCase instead of list of md5s." This reverts commit 31a5e2f40e95fd2220278c2c69e267336ce4be02. --- .../datamodel/AbstractSqlEamDb.java | 21 ++++++++++++------- .../centralrepository/datamodel/EamDb.java | 2 +- .../datamodel/SqliteEamDb.java | 4 ++-- 3 files changed, 16 insertions(+), 11 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java index a0fed4ba99..acfef9d99e 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java @@ -657,14 +657,14 @@ public abstract class AbstractSqlEamDb implements EamDb { * @return List of artifact instances for a given list of MD5 values */ @Override - public List getArtifactInstancesByCaseValues(CorrelationCase correlationCase, CorrelationCase currentCase) throws EamDbException { + public List getArtifactInstancesByCaseValues(CorrelationCase correlationCase, List values) throws EamDbException { CorrelationAttribute.Type aType = CorrelationAttribute.getDefaultCorrelationTypes().get(0); // Files type if (aType == null) { throw new EamDbException("Correlation Type is null"); } boolean singleCase = false; if (correlationCase != null) { - singleCase = false; + singleCase = true; } Connection conn = connect(); @@ -674,6 +674,15 @@ public abstract class AbstractSqlEamDb implements EamDb { PreparedStatement preparedStatement = null; ResultSet resultSet = null; + String valuesString = ""; + StringBuilder valuesFilter = new StringBuilder(values.size()); + if (!values.isEmpty()) { + for (String value : values) { + valuesFilter.append("'").append(value).append("',"); + } + valuesString = valuesFilter.toString().substring(0, valuesFilter.length() - 1); + } + String tableName = EamDbUtil.correlationTypeToInstanceTableName(aType); StringBuilder sql = new StringBuilder(9); sql.append("SELECT cases.case_name, cases.case_uid, data_sources.name, device_id, file_path, known_status, comment, data_sources.case_id, value FROM "); @@ -684,11 +693,7 @@ public abstract class AbstractSqlEamDb implements EamDb { sql.append(" LEFT JOIN data_sources ON "); sql.append(tableName); sql.append(".data_source_id=data_sources.id"); - sql.append(" WHERE value IN (SELECT value FROM "); - sql.append(tableName); - sql.append(" WHERE "); - sql.append(tableName); - sql.append(".case_id= ?)"); + sql.append(" WHERE value IN (?)"); if (singleCase) { sql.append(" AND "); sql.append(tableName); @@ -697,7 +702,7 @@ public abstract class AbstractSqlEamDb implements EamDb { try { preparedStatement = conn.prepareStatement(sql.toString()); - preparedStatement.setString(1, String.valueOf(currentCase.getID())); + preparedStatement.setString(1, valuesString); if (singleCase && correlationCase != null) { preparedStatement.setString(2, String.valueOf(correlationCase.getID())); } diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDb.java index 8daf5e23ef..24af255eea 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDb.java @@ -232,7 +232,7 @@ public interface EamDb { * * @return List of artifact instances for a given list of MD5 values */ - List getArtifactInstancesByCaseValues(CorrelationCase correlationCase, CorrelationCase currentCase) throws EamDbException; + List getArtifactInstancesByCaseValues(CorrelationCase correlationCase, List values) throws EamDbException; /** * Retrieves eamArtifact instances from the database that are associated diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java index de8ef06ac8..0917cedc60 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java @@ -430,10 +430,10 @@ public class SqliteEamDb extends AbstractSqlEamDb { * @return List of artifact instances for a given list of MD5 values */ @Override - public List getArtifactInstancesByCaseValues(CorrelationCase correlationCase, CorrelationCase currentCase) throws EamDbException { + public List getArtifactInstancesByCaseValues(CorrelationCase correlationCase, List values) throws EamDbException { try { acquireSharedLock(); - return super.getArtifactInstancesByCaseValues(correlationCase, currentCase); + return super.getArtifactInstancesByCaseValues(correlationCase, values); } finally { releaseSharedLock(); } From 2eaf1f633eafd32563a53d88d62b24b195d3fdbe Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Sun, 20 May 2018 14:54:09 -0600 Subject: [PATCH 027/287] default checkbox got unset --- .../org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.form | 1 + .../org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java | 1 + 2 files changed, 2 insertions(+) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.form b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.form index d32724abe2..04ff5ba88b 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.form +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.form @@ -148,6 +148,7 @@ + diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java index d7f06bb329..319784b88f 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java @@ -484,6 +484,7 @@ public final class CommonFilesPanel extends javax.swing.JPanel { }); fileTypeFilterButtonGroup.add(selectedFileCategoriesButton); + selectedFileCategoriesButton.setSelected(true); org.openide.awt.Mnemonics.setLocalizedText(selectedFileCategoriesButton, org.openide.util.NbBundle.getMessage(CommonFilesPanel.class, "CommonFilesPanel.selectedFileCategoriesButton.text")); // NOI18N selectedFileCategoriesButton.setToolTipText(org.openide.util.NbBundle.getMessage(CommonFilesPanel.class, "CommonFilesPanel.selectedFileCategoriesButton.toolTipText")); // NOI18N selectedFileCategoriesButton.addActionListener(new java.awt.event.ActionListener() { From 81de68bd06fc1dd435d2af13dc660d122fbf3c8f Mon Sep 17 00:00:00 2001 From: Andrew Ziehl Date: Sun, 20 May 2018 14:41:04 -0700 Subject: [PATCH 028/287] Collection fixes instead of ArrayList conversion. --- .../centralrepository/datamodel/AbstractSqlEamDb.java | 7 ++++--- .../autopsy/centralrepository/datamodel/EamDb.java | 3 ++- .../autopsy/centralrepository/datamodel/SqliteEamDb.java | 3 ++- .../AllDataSourcesEamDbCommonFilesAlgorithm.java | 9 +++++---- 4 files changed, 13 insertions(+), 9 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java index acfef9d99e..b355093bfe 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java @@ -647,6 +647,7 @@ public abstract class AbstractSqlEamDb implements EamDb { return artifactInstances; } + /** * Retrieves eamArtiifact instances from the database that match * the given list of MD5 values and optionally filters by given case. @@ -657,7 +658,7 @@ public abstract class AbstractSqlEamDb implements EamDb { * @return List of artifact instances for a given list of MD5 values */ @Override - public List getArtifactInstancesByCaseValues(CorrelationCase correlationCase, List values) throws EamDbException { + public List getArtifactInstancesByCaseValues(CorrelationCase correlationCase, Collection values) throws EamDbException { CorrelationAttribute.Type aType = CorrelationAttribute.getDefaultCorrelationTypes().get(0); // Files type if (aType == null) { throw new EamDbException("Correlation Type is null"); @@ -681,8 +682,8 @@ public abstract class AbstractSqlEamDb implements EamDb { valuesFilter.append("'").append(value).append("',"); } valuesString = valuesFilter.toString().substring(0, valuesFilter.length() - 1); - } + } String tableName = EamDbUtil.correlationTypeToInstanceTableName(aType); StringBuilder sql = new StringBuilder(9); sql.append("SELECT cases.case_name, cases.case_uid, data_sources.name, device_id, file_path, known_status, comment, data_sources.case_id, value FROM "); @@ -697,7 +698,7 @@ public abstract class AbstractSqlEamDb implements EamDb { if (singleCase) { sql.append(" AND "); sql.append(tableName); - sql.append(".case_id = ?"); + sql.append(".case_id=?"); } try { diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDb.java index 24af255eea..15b234fc47 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDb.java @@ -19,6 +19,7 @@ package org.sleuthkit.autopsy.centralrepository.datamodel; import java.sql.SQLException; +import java.util.Collection; import java.util.List; import java.util.Set; import org.sleuthkit.datamodel.TskData; @@ -232,7 +233,7 @@ public interface EamDb { * * @return List of artifact instances for a given list of MD5 values */ - List getArtifactInstancesByCaseValues(CorrelationCase correlationCase, List values) throws EamDbException; + List getArtifactInstancesByCaseValues(CorrelationCase correlationCase, Collection values) throws EamDbException; /** * Retrieves eamArtifact instances from the database that are associated diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java index 0917cedc60..a1b8aaec1d 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java @@ -23,6 +23,7 @@ import java.sql.Connection; import java.sql.SQLException; import java.sql.Statement; import java.util.Arrays; +import java.util.Collection; import java.util.List; import java.util.Set; import java.util.concurrent.locks.ReentrantReadWriteLock; @@ -430,7 +431,7 @@ public class SqliteEamDb extends AbstractSqlEamDb { * @return List of artifact instances for a given list of MD5 values */ @Override - public List getArtifactInstancesByCaseValues(CorrelationCase correlationCase, List values) throws EamDbException { + public List getArtifactInstancesByCaseValues(CorrelationCase correlationCase, Collection values) throws EamDbException { try { acquireSharedLock(); return super.getArtifactInstancesByCaseValues(correlationCase, values); diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllDataSourcesEamDbCommonFilesAlgorithm.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllDataSourcesEamDbCommonFilesAlgorithm.java index 0700d4ae9e..9fa1206f6b 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllDataSourcesEamDbCommonFilesAlgorithm.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllDataSourcesEamDbCommonFilesAlgorithm.java @@ -22,6 +22,7 @@ package org.sleuthkit.autopsy.commonfilesearch; import java.sql.SQLException; import java.util.Arrays; import java.util.Collection; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.logging.Level; @@ -83,9 +84,9 @@ public class AllDataSourcesEamDbCommonFilesAlgorithm extends CommonFilesMetadat public CommonFilesMetadata findEamDbCommonFiles(CorrelationCase correlationCase) throws TskCoreException, NoCurrentCaseException, SQLException, EamDbException { CommonFilesMetadata metaData = this.findCommonFiles(); Map commonFiles = metaData.getMetadata(); - List values = Arrays.asList((String[]) commonFiles.keySet().toArray()); + Collection values = commonFiles.keySet(); - Map interCaseCommonFiles = metaData.getMetadata(); + Map interCaseCommonFiles = new HashMap<>(); try { Collection artifactInstances = dbManager.getArtifactInstancesByCaseValues(correlationCase, values).stream() @@ -93,9 +94,9 @@ public class AllDataSourcesEamDbCommonFilesAlgorithm extends CommonFilesMetadat for (CorrelationAttributeCommonInstance instance : artifactInstances) { - //Long objectId = 1L; //TODO, need to retrieve ALL (even count < 2) AbstractFiles from this case to us for objectId for CR matches; + String md5 = instance.getValue(); - String dataSource = instance.getCorrelationDataSource().getName(); + String dataSource = String.format(instance.getCorrelationCase().getDisplayName(), ": ", instance.getCorrelationDataSource().getName()); if (md5 == null || HashUtility.isNoDataMd5(md5)) { continue; From fc2b32f81d01f397d0390037bda67d0ebcb0a808 Mon Sep 17 00:00:00 2001 From: Andrew Ziehl Date: Sun, 20 May 2018 15:34:35 -0700 Subject: [PATCH 029/287] use setArray instead --- .../autopsy/centralrepository/datamodel/AbstractSqlEamDb.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java index b355093bfe..ebc8abcfcd 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java @@ -31,6 +31,7 @@ import java.sql.SQLException; import java.sql.Statement; import java.sql.Types; import java.time.LocalDate; +import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.Set; @@ -703,7 +704,7 @@ public abstract class AbstractSqlEamDb implements EamDb { try { preparedStatement = conn.prepareStatement(sql.toString()); - preparedStatement.setString(1, valuesString); + preparedStatement.setArray(1, conn.createArrayOf("text[]", values.toArray(new String[values.size()]))); //Collections.list(values.iterator()).toArray()); if (singleCase && correlationCase != null) { preparedStatement.setString(2, String.valueOf(correlationCase.getID())); } From 337c7b549e42573b1c6d8539f29ebbbe3d7ee047 Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Mon, 21 May 2018 09:14:42 -0600 Subject: [PATCH 030/287] statement built for multiple values of md5 --- .../datamodel/AbstractSqlEamDb.java | 21 ++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java index ebc8abcfcd..40d56d1830 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java @@ -673,7 +673,7 @@ public abstract class AbstractSqlEamDb implements EamDb { List artifactInstances = new ArrayList<>(); CorrelationAttributeCommonInstance artifactInstance; - PreparedStatement preparedStatement = null; + PreparedStatement preparedStatement = null; //TODO probably not appropriate for query with variable number of arguments ResultSet resultSet = null; String valuesString = ""; @@ -695,8 +695,15 @@ public abstract class AbstractSqlEamDb implements EamDb { sql.append(" LEFT JOIN data_sources ON "); sql.append(tableName); sql.append(".data_source_id=data_sources.id"); - sql.append(" WHERE value IN (?)"); - if (singleCase) { + sql.append(" WHERE value IN ("); + + for(int i = 0; i < values.size(); i++){ + sql.append("?,"); + } + sql.deleteCharAt(sql.length() - 1); + sql.append(")"); + + if (singleCase && correlationCase != null) { sql.append(" AND "); sql.append(tableName); sql.append(".case_id=?"); @@ -704,9 +711,13 @@ public abstract class AbstractSqlEamDb implements EamDb { try { preparedStatement = conn.prepareStatement(sql.toString()); - preparedStatement.setArray(1, conn.createArrayOf("text[]", values.toArray(new String[values.size()]))); //Collections.list(values.iterator()).toArray()); + int i = 1; + for (String value : values){ + preparedStatement.setString(i, value); + i++; + } if (singleCase && correlationCase != null) { - preparedStatement.setString(2, String.valueOf(correlationCase.getID())); + preparedStatement.setString(i, String.valueOf(correlationCase.getID())); } resultSet = preparedStatement.executeQuery(); From 40f813721d36ab52b9a783cb6b87bee842293f32 Mon Sep 17 00:00:00 2001 From: Andrew Ziehl Date: Mon, 21 May 2018 12:14:52 -0700 Subject: [PATCH 031/287] cleanup query unused code, fix case:datasource string. --- .../centralrepository/datamodel/AbstractSqlEamDb.java | 11 +---------- .../AllDataSourcesEamDbCommonFilesAlgorithm.java | 2 +- 2 files changed, 2 insertions(+), 11 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java index 40d56d1830..fcc8e2af64 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java @@ -673,18 +673,9 @@ public abstract class AbstractSqlEamDb implements EamDb { List artifactInstances = new ArrayList<>(); CorrelationAttributeCommonInstance artifactInstance; - PreparedStatement preparedStatement = null; //TODO probably not appropriate for query with variable number of arguments + PreparedStatement preparedStatement = null; ResultSet resultSet = null; - String valuesString = ""; - StringBuilder valuesFilter = new StringBuilder(values.size()); - if (!values.isEmpty()) { - for (String value : values) { - valuesFilter.append("'").append(value).append("',"); - } - valuesString = valuesFilter.toString().substring(0, valuesFilter.length() - 1); - - } String tableName = EamDbUtil.correlationTypeToInstanceTableName(aType); StringBuilder sql = new StringBuilder(9); sql.append("SELECT cases.case_name, cases.case_uid, data_sources.name, device_id, file_path, known_status, comment, data_sources.case_id, value FROM "); diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllDataSourcesEamDbCommonFilesAlgorithm.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllDataSourcesEamDbCommonFilesAlgorithm.java index 9fa1206f6b..75060d87de 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllDataSourcesEamDbCommonFilesAlgorithm.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllDataSourcesEamDbCommonFilesAlgorithm.java @@ -96,7 +96,7 @@ public class AllDataSourcesEamDbCommonFilesAlgorithm extends CommonFilesMetadat for (CorrelationAttributeCommonInstance instance : artifactInstances) { String md5 = instance.getValue(); - String dataSource = String.format(instance.getCorrelationCase().getDisplayName(), ": ", instance.getCorrelationDataSource().getName()); + String dataSource = String.format("%s: %s", instance.getCorrelationCase().getDisplayName(), instance.getCorrelationDataSource().getName()); if (md5 == null || HashUtility.isNoDataMd5(md5)) { continue; From 6dd5324ebf28d2703ee9fc817a02f17db2729be3 Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Mon, 21 May 2018 13:17:09 -0600 Subject: [PATCH 032/287] missing import --- .../org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java | 1 + 1 file changed, 1 insertion(+) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java index 2d264f2cca..2b2cf69d58 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java @@ -24,6 +24,7 @@ import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.Collection; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; From ada7ec2bc0d1a9ec3f95209457012f8377c94074 Mon Sep 17 00:00:00 2001 From: Andrew Ziehl Date: Mon, 21 May 2018 12:43:40 -0700 Subject: [PATCH 033/287] Polish and minor refactors --- .../datamodel/AbstractSqlEamDb.java | 2 +- ...lDataSourcesEamDbCommonFilesAlgorithm.java | 75 ++++++++++--------- 2 files changed, 39 insertions(+), 38 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java index fcc8e2af64..1558b97e01 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java @@ -677,7 +677,7 @@ public abstract class AbstractSqlEamDb implements EamDb { ResultSet resultSet = null; String tableName = EamDbUtil.correlationTypeToInstanceTableName(aType); - StringBuilder sql = new StringBuilder(9); + StringBuilder sql = new StringBuilder(10); sql.append("SELECT cases.case_name, cases.case_uid, data_sources.name, device_id, file_path, known_status, comment, data_sources.case_id, value FROM "); sql.append(tableName); sql.append(" LEFT JOIN cases ON "); diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllDataSourcesEamDbCommonFilesAlgorithm.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllDataSourcesEamDbCommonFilesAlgorithm.java index 75060d87de..be1aa66d91 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllDataSourcesEamDbCommonFilesAlgorithm.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllDataSourcesEamDbCommonFilesAlgorithm.java @@ -20,7 +20,7 @@ package org.sleuthkit.autopsy.commonfilesearch; import java.sql.SQLException; -import java.util.Arrays; +import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.List; @@ -45,7 +45,7 @@ public class AllDataSourcesEamDbCommonFilesAlgorithm extends CommonFilesMetadat private static final String WHERE_CLAUSE = "%s md5 in (select md5 from tsk_files where (known != 1 OR known IS NULL)%s GROUP BY md5) order by md5"; //NON-NLS - private EamDb dbManager; + private final EamDb dbManager; /** * Implements the algorithm for getting common files across all data @@ -61,11 +61,11 @@ public class AllDataSourcesEamDbCommonFilesAlgorithm extends CommonFilesMetadat dbManager = EamDb.getInstance(); } - public CommonFilesMetadata findEamDbCommonFiles() throws TskCoreException, NoCurrentCaseException, SQLException, EamDbException { + CommonFilesMetadata findEamDbCommonFiles() throws TskCoreException, NoCurrentCaseException, SQLException, EamDbException { return this.findEamDbCommonFiles(null); } - public CommonFilesMetadata findEamDbCommonFiles(int correlationCaseId) throws TskCoreException, NoCurrentCaseException, SQLException, EamDbException, Exception { + CommonFilesMetadata findEamDbCommonFiles(int correlationCaseId) throws TskCoreException, NoCurrentCaseException, SQLException, EamDbException, Exception { CorrelationCase cCase = this.getCorrelationCaseFromId(correlationCaseId); @@ -73,15 +73,14 @@ public class AllDataSourcesEamDbCommonFilesAlgorithm extends CommonFilesMetadat } /** - * TODO Refactor, abstract shared code above, call this method via new AllDataSourcesEamDbCommonFilesAlgorithm Class * @param correlationCase Optionally null, otherwise a case, or could be a CR case ID - * @return + * @return CommonFilesMetaData md5s to build Common Files search results. * @throws TskCoreException * @throws NoCurrentCaseException * @throws SQLException * @throws EamDbException */ - public CommonFilesMetadata findEamDbCommonFiles(CorrelationCase correlationCase) throws TskCoreException, NoCurrentCaseException, SQLException, EamDbException { + private CommonFilesMetadata findEamDbCommonFiles(CorrelationCase correlationCase) throws TskCoreException, NoCurrentCaseException, SQLException, EamDbException { CommonFilesMetadata metaData = this.findCommonFiles(); Map commonFiles = metaData.getMetadata(); Collection values = commonFiles.keySet(); @@ -90,36 +89,8 @@ public class AllDataSourcesEamDbCommonFilesAlgorithm extends CommonFilesMetadat try { Collection artifactInstances = dbManager.getArtifactInstancesByCaseValues(correlationCase, values).stream() - .collect(Collectors.toList()); - - - for (CorrelationAttributeCommonInstance instance : artifactInstances) { - - String md5 = instance.getValue(); - String dataSource = String.format("%s: %s", instance.getCorrelationCase().getDisplayName(), instance.getCorrelationDataSource().getName()); - - if (md5 == null || HashUtility.isNoDataMd5(md5)) { - continue; - } - //Builds a 3rd list which contains instances which are in commonFiles map, uses current case objectId - if (commonFiles.containsKey(md5)) { - // TODO sloppy, but we don't *have* all the information for the rows in the CR, so what do we do? - Long objectId = commonFiles.get(md5).getMetadata().iterator().next().getObjectId(); - if(interCaseCommonFiles.containsKey(md5)) { - //Add to intercase metaData - final Md5Metadata md5Metadata = interCaseCommonFiles.get(md5); - md5Metadata.addFileInstanceMetadata(new FileInstanceMetadata(objectId, dataSource)); - - } else { - // Create new intercase metadata - final Md5Metadata md5Metadata = commonFiles.get(md5); - md5Metadata.addFileInstanceMetadata(new FileInstanceMetadata(objectId, dataSource)); - interCaseCommonFiles.put(md5, md5Metadata); - } - } else { - // TODO This should never happen. All current case files with potential matches are in comonFiles Map. - } - } + .collect(Collectors.toList()); + gatherIntercaseResults(artifactInstances, commonFiles, interCaseCommonFiles); } catch (EamDbException ex) { LOGGER.log(Level.SEVERE, "Error getting artifact instances from database.", ex); // NON-NLS @@ -129,6 +100,36 @@ public class AllDataSourcesEamDbCommonFilesAlgorithm extends CommonFilesMetadat } + private void gatherIntercaseResults(Collection artifactInstances, Map commonFiles, Map interCaseCommonFiles) { + for (CorrelationAttributeCommonInstance instance : artifactInstances) { + + String md5 = instance.getValue(); + String dataSource = String.format("%s: %s", instance.getCorrelationCase().getDisplayName(), instance.getCorrelationDataSource().getName()); + + if (md5 == null || HashUtility.isNoDataMd5(md5)) { + continue; + } + //Builds a 3rd list which contains instances which are in commonFiles map, uses current case objectId + if (commonFiles.containsKey(md5)) { + // TODO sloppy, but we don't *have* all the information for the rows in the CR, so what do we do? + Long objectId = commonFiles.get(md5).getMetadata().iterator().next().getObjectId(); + if(interCaseCommonFiles.containsKey(md5)) { + //Add to intercase metaData + final Md5Metadata md5Metadata = interCaseCommonFiles.get(md5); + md5Metadata.addFileInstanceMetadata(new FileInstanceMetadata(objectId, dataSource)); + + } else { + final List fileInstances = new ArrayList<>(); + fileInstances.add(new FileInstanceMetadata(objectId, dataSource)); + Md5Metadata md5Metadata = new Md5Metadata(md5, fileInstances); + interCaseCommonFiles.put(md5, md5Metadata); + } + } else { + // TODO This should never happen. All current case files with potential matches are in comonFiles Map. + } + } + } + @Override protected String buildSqlSelectStatement() { Object[] args = new String[]{SELECT_PREFIX, determineMimeTypeFilter()}; From ef09215c24ada5880a933f4422cb93645dadfecc Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Tue, 22 May 2018 08:03:36 -0600 Subject: [PATCH 034/287] serialVersionUID --- .../contentviewer/DataContentViewerOtherCases.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/DataContentViewerOtherCases.java b/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/DataContentViewerOtherCases.java index ca9b0e2c06..dd41796f35 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/DataContentViewerOtherCases.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/DataContentViewerOtherCases.java @@ -74,6 +74,8 @@ import org.sleuthkit.datamodel.TskData; "DataContentViewerOtherCases.toolTip=Displays instances of the selected file/artifact from other occurrences.",}) public class DataContentViewerOtherCases extends javax.swing.JPanel implements DataContentViewer { + private static final long serialVersionUID = -1L; + private final static Logger LOGGER = Logger.getLogger(DataContentViewerOtherCases.class.getName()); private final DataContentViewerOtherCasesTableModel tableModel; From bb7846d6d1fbf6bb5de1ec1fc8a4743d3d5d56b2 Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Tue, 22 May 2018 08:35:30 -0600 Subject: [PATCH 035/287] comments cleanup --- .../AllDataSourcesEamDbCommonFilesAlgorithm.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllDataSourcesEamDbCommonFilesAlgorithm.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllDataSourcesEamDbCommonFilesAlgorithm.java index be1aa66d91..f7d48614f0 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllDataSourcesEamDbCommonFilesAlgorithm.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllDataSourcesEamDbCommonFilesAlgorithm.java @@ -111,7 +111,8 @@ public class AllDataSourcesEamDbCommonFilesAlgorithm extends CommonFilesMetadat } //Builds a 3rd list which contains instances which are in commonFiles map, uses current case objectId if (commonFiles.containsKey(md5)) { - // TODO sloppy, but we don't *have* all the information for the rows in the CR, so what do we do? + // we don't *have* all the information for the rows in the CR, + // so we need to consult the present case via the SleuthkitCase object Long objectId = commonFiles.get(md5).getMetadata().iterator().next().getObjectId(); if(interCaseCommonFiles.containsKey(md5)) { //Add to intercase metaData @@ -124,8 +125,6 @@ public class AllDataSourcesEamDbCommonFilesAlgorithm extends CommonFilesMetadat Md5Metadata md5Metadata = new Md5Metadata(md5, fileInstances); interCaseCommonFiles.put(md5, md5Metadata); } - } else { - // TODO This should never happen. All current case files with potential matches are in comonFiles Map. } } } @@ -144,7 +143,6 @@ public class AllDataSourcesEamDbCommonFilesAlgorithm extends CommonFilesMetadat } private CorrelationCase getCorrelationCaseFromId(int correlationCaseId) throws EamDbException, Exception { - //TODO is there a better way??? for(CorrelationCase cCase : this.dbManager.getCases()){ if(cCase.getID() == correlationCaseId){ return cCase; From 5d67211d51d5d47f757d9e5351eac5fa9851ef95 Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Tue, 22 May 2018 08:35:40 -0600 Subject: [PATCH 036/287] removed unused imports --- .../commonfilesearch/CommonFilesMetadataBuilder.java | 9 --------- 1 file changed, 9 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesMetadataBuilder.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesMetadataBuilder.java index 55f7b7ebb0..a9b1b4f350 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesMetadataBuilder.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesMetadataBuilder.java @@ -22,25 +22,16 @@ package org.sleuthkit.autopsy.commonfilesearch; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; -import java.util.logging.Level; import java.util.stream.Collectors; import java.util.stream.Stream; import org.openide.util.NbBundle; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; -import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeCommonInstance; -import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance; -import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationCase; -import org.sleuthkit.autopsy.centralrepository.datamodel.EamDb; -import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException; -import static org.sleuthkit.autopsy.timeline.datamodel.eventtype.ArtifactEventType.LOGGER; import org.sleuthkit.datamodel.HashUtility; import org.sleuthkit.datamodel.SleuthkitCase; import org.sleuthkit.datamodel.SleuthkitCase.CaseDbQuery; From d2274772cfaee81fb8d41acd0262fd29b5d37427 Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Tue, 22 May 2018 08:40:07 -0600 Subject: [PATCH 037/287] rename as per code quality standards --- .../sleuthkit/autopsy/commonfilesearch/CommonFilesNode.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesNode.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesNode.java index 677d6ba8b5..4f05c565a6 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesNode.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesNode.java @@ -83,8 +83,8 @@ final public class CommonFilesNode extends DisplayableItemNode { @Override protected Node createNodeForKey(String md5){ - Md5Metadata metadata = this.metadata.getMetadataForMd5(md5); - return new Md5Node(metadata); + Md5Metadata metadataForMd5 = this.metadata.getMetadataForMd5(md5); + return new Md5Node(metadataForMd5); } @Override From 14edbe10082e3b5d6e17b0f739c78068146ebda6 Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Tue, 22 May 2018 08:40:53 -0600 Subject: [PATCH 038/287] unused imports / better exception handling --- .../autopsy/commonfilesearch/CommonFilesSearchAction.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesSearchAction.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesSearchAction.java index bc5bc6514d..10b4890152 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesSearchAction.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesSearchAction.java @@ -26,8 +26,6 @@ import org.openide.util.HelpCtx; import org.openide.util.NbBundle; import org.openide.util.actions.CallableSystemAction; import org.sleuthkit.autopsy.casemodule.Case; -import org.sleuthkit.autopsy.centralrepository.datamodel.EamDb; -import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException; import org.sleuthkit.autopsy.core.Installer; import org.sleuthkit.datamodel.TskCoreException; @@ -54,7 +52,7 @@ final public class CommonFilesSearchAction extends CallableSystemAction { try { isMultiDataSourceCase = Case.isCaseOpen() && !Case.getCurrentCase().getDataSources().isEmpty(); } catch (TskCoreException ex) { - Exceptions.printStackTrace(ex); + LOGGER.log(Level.WARNING, "Exception determining whether or not CommonFilesSearch should be enabled.", ex); } return super.isEnabled() && Installer.isJavaFxInited() && (isMultiDataSourceCase || isEamDbAvailable); From bf460977b8697718f279a2784d0ae7b4c4a50322 Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Tue, 22 May 2018 08:41:38 -0600 Subject: [PATCH 039/287] more unused imports --- .../autopsy/commonfilesearch/CommonFilesSearchAction.java | 1 - 1 file changed, 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesSearchAction.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesSearchAction.java index 10b4890152..7b03fb550d 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesSearchAction.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesSearchAction.java @@ -21,7 +21,6 @@ package org.sleuthkit.autopsy.commonfilesearch; import java.awt.event.ActionEvent; import java.util.logging.Level; import java.util.logging.Logger; -import org.openide.util.Exceptions; import org.openide.util.HelpCtx; import org.openide.util.NbBundle; import org.openide.util.actions.CallableSystemAction; From 6684c492ae947b8fc41da7298aa8d441d12e1488 Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Tue, 22 May 2018 09:30:29 -0600 Subject: [PATCH 040/287] less accessible fields --- .../autopsy/commonfilesearch/DataSourceComboBoxModel.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/DataSourceComboBoxModel.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/DataSourceComboBoxModel.java index 657fedc53b..1b55e6bdc3 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/DataSourceComboBoxModel.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/DataSourceComboBoxModel.java @@ -30,7 +30,7 @@ public class DataSourceComboBoxModel extends AbstractListModel implement private static final long serialVersionUID = 1L; private final String[] dataSourceList; - String selection = null; + private String selection = null; /** * Use this to initialize the panel From 065f62a25ae5b74bd43331a4cbfe35621e23289d Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Tue, 22 May 2018 09:31:28 -0600 Subject: [PATCH 041/287] whitespace cleanup --- .../autopsy/commonfilesearch/FileInstanceMetadata.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/FileInstanceMetadata.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/FileInstanceMetadata.java index 0e53cc6992..369e6841c2 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/FileInstanceMetadata.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/FileInstanceMetadata.java @@ -51,6 +51,5 @@ final public class FileInstanceMetadata { */ public String getDataSourceName(){ return this.dataSourceName; - } - + } } From 5acd5541be2b2177f81fd3b69a2e55c0298e021f Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Tue, 22 May 2018 09:32:15 -0600 Subject: [PATCH 042/287] unused imports/fields, misc. code quality --- .../commonfilesearch/InterCasePanel.java | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.java index fefbfb8908..97fd21a7d3 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.java @@ -19,20 +19,11 @@ */ package org.sleuthkit.autopsy.commonfilesearch; -import java.util.HashMap; -import java.util.List; +import java.util.Collections; import java.util.Map; import java.util.Map.Entry; -import java.util.concurrent.ExecutionException; -import java.util.logging.Level; import javax.swing.ComboBoxModel; -import javax.swing.SwingWorker; -import org.openide.util.Exceptions; import org.openide.util.NbBundle; -import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationDataSource; -import org.sleuthkit.autopsy.centralrepository.datamodel.EamDb; -import org.sleuthkit.autopsy.coreutils.Logger; -import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil; /** * @@ -41,9 +32,8 @@ import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil; public class InterCasePanel extends javax.swing.JPanel { private static final long serialVersionUID = 1L; + static final int NO_CASE_SELECTED = -1; - - private static final Logger LOGGER = Logger.getLogger(InterCasePanel.class.getName()); private ComboBoxModel casesList = new DataSourceComboBoxModel(); private Map caseMap; @@ -156,7 +146,7 @@ public class InterCasePanel extends javax.swing.JPanel { // End of variables declaration//GEN-END:variables Map getCaseMap() { - return this.caseMap; + return Collections.unmodifiableMap(this.caseMap); } void setCaseList(DataSourceComboBoxModel dataSourceComboBoxModel) { @@ -175,7 +165,8 @@ public class InterCasePanel extends javax.swing.JPanel { } void setCaseMap(Map caseMap) { - this.caseMap = caseMap; + this.caseMap.clear(); + this.caseMap.putAll(caseMap); } boolean centralRepoHasMultipleCases() { From e937e5936baa58514d6904d4b02b991d0471c6ba Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Tue, 22 May 2018 09:32:49 -0600 Subject: [PATCH 043/287] unused imports --- .../autopsy/commonfilesearch/IntraCasePanel.java | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCasePanel.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCasePanel.java index ee90532109..d0b4d58daf 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCasePanel.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCasePanel.java @@ -19,24 +19,11 @@ */ package org.sleuthkit.autopsy.commonfilesearch; -import java.io.File; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; -import java.util.concurrent.ExecutionException; -import java.util.logging.Level; import javax.swing.ComboBoxModel; -import javax.swing.SwingUtilities; -import javax.swing.SwingWorker; import org.openide.util.NbBundle; -import org.sleuthkit.autopsy.casemodule.Case; -import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; import org.sleuthkit.autopsy.coreutils.Logger; -import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil; -import org.sleuthkit.datamodel.SleuthkitCase; -import org.sleuthkit.datamodel.TskCoreException; /** * From f7ffc2400742565e55cebd54428b2ac406cd0953 Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Tue, 22 May 2018 11:21:53 -0600 Subject: [PATCH 044/287] refactored for clarity --- .../AllCasesEamDbCommonFilesAlgorithm.java | 33 +++++++++ .../CommonFilesMetadataBuilder.java | 6 +- .../commonfilesearch/CommonFilesPanel.java | 11 +-- ...hm.java => EamDbCommonFilesAlgorithm.java} | 56 +++++++-------- .../commonfilesearch/InterCasePanel.java | 2 + .../SingleCaseEamDbCommonFilesAlgorithm.java | 70 +++++++++++++++++++ .../IngestedWithHashAndFileType.java | 18 ++--- .../IngestedWithNoFileTypes.java | 4 +- .../commonfilessearch/UningestedCases.java | 4 +- 9 files changed, 152 insertions(+), 52 deletions(-) create mode 100644 Core/src/org/sleuthkit/autopsy/commonfilesearch/AllCasesEamDbCommonFilesAlgorithm.java rename Core/src/org/sleuthkit/autopsy/commonfilesearch/{AllDataSourcesEamDbCommonFilesAlgorithm.java => EamDbCommonFilesAlgorithm.java} (75%) create mode 100644 Core/src/org/sleuthkit/autopsy/commonfilesearch/SingleCaseEamDbCommonFilesAlgorithm.java diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllCasesEamDbCommonFilesAlgorithm.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllCasesEamDbCommonFilesAlgorithm.java new file mode 100644 index 0000000000..c7a87f5b52 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllCasesEamDbCommonFilesAlgorithm.java @@ -0,0 +1,33 @@ +/* + * + * Autopsy Forensic Browser + * + * Copyright 2018 Basis Technology Corp. + * Contact: carrier sleuthkit 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.commonfilesearch; + +import java.util.Map; +import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException; + +/** + *TODO docs + */ +public class AllCasesEamDbCommonFilesAlgorithm extends EamDbCommonFilesAlgorithm { + + public AllCasesEamDbCommonFilesAlgorithm(Map dataSourceIdMap, boolean filterByMediaMimeType, boolean filterByDocMimeType) throws EamDbException { + super(dataSourceIdMap, filterByMediaMimeType, filterByDocMimeType); + } +} diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesMetadataBuilder.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesMetadataBuilder.java index a9b1b4f350..41c21f1dff 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesMetadataBuilder.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesMetadataBuilder.java @@ -40,7 +40,7 @@ import org.sleuthkit.datamodel.TskCoreException; /** * * Generates a List when - * findCommonFiles() is called, which organizes files by md5 to + * findFiles() is called, which organizes files by md5 to * prepare to display in viewer. * * This entire thing runs on a background thread where exceptions are handled. @@ -166,8 +166,8 @@ public abstract class CommonFilesMetadataBuilder { * @throws NoCurrentCaseException * @throws SQLException */ - public CommonFilesMetadata findCommonFiles() throws TskCoreException, NoCurrentCaseException, SQLException { - + public CommonFilesMetadata findFiles() throws TskCoreException, NoCurrentCaseException, SQLException, Exception { + //TODO do we need all those exceptions or can we differentiate when they are caught? Map commonFiles = new HashMap<>(); SleuthkitCase sleuthkitCase = Case.getCurrentCaseThrows().getSleuthkitCase(); diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java index 2b2cf69d58..52a533e796 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java @@ -163,12 +163,10 @@ public final class CommonFilesPanel extends javax.swing.JPanel { if (CommonFilesPanel.this.interCaseRadio.isSelected()) { - builder = new AllDataSourcesEamDbCommonFilesAlgorithm(CommonFilesPanel.this.intraCasePanel.getDataSourceMap(), filterByMedia, filterByDocuments); - if(caseId == InterCasePanel.NO_CASE_SELECTED){ - metadata = ((AllDataSourcesEamDbCommonFilesAlgorithm)builder).findEamDbCommonFiles(); + builder = new AllCasesEamDbCommonFilesAlgorithm(CommonFilesPanel.this.intraCasePanel.getDataSourceMap(), filterByMedia, filterByDocuments); } else { - metadata = ((AllDataSourcesEamDbCommonFilesAlgorithm)builder).findEamDbCommonFiles(CommonFilesPanel.this.interCasePanel.getSelectedCaseId()); + builder = new SingleCaseEamDbCommonFilesAlgorithm(caseId, CommonFilesPanel.this.intraCasePanel.getDataSourceMap(), filterByMedia, filterByDocuments); } } else { if (dataSourceId == CommonFilesPanel.NO_DATA_SOURCE_SELECTED) { @@ -180,9 +178,12 @@ public final class CommonFilesPanel extends javax.swing.JPanel { setTitleForSingleSource(dataSourceId); } - metadata = builder.findCommonFiles(); } + //TODO set title from one method rathe than two (or more) overloads + + metadata = builder.findFiles(); + this.tabTitle = builder.buildTabTitle(); return metadata; diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllDataSourcesEamDbCommonFilesAlgorithm.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbCommonFilesAlgorithm.java similarity index 75% rename from Core/src/org/sleuthkit/autopsy/commonfilesearch/AllDataSourcesEamDbCommonFilesAlgorithm.java rename to Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbCommonFilesAlgorithm.java index f7d48614f0..a51e47a836 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllDataSourcesEamDbCommonFilesAlgorithm.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbCommonFilesAlgorithm.java @@ -39,9 +39,9 @@ import org.sleuthkit.datamodel.TskCoreException; /** - * Provides logic for selecting common files from all data sources for all files to source for EamDB query. + * Provides logic for selecting common files from all data sources and all cases in the Central Repo. */ -public class AllDataSourcesEamDbCommonFilesAlgorithm extends CommonFilesMetadataBuilder { +public abstract class EamDbCommonFilesAlgorithm extends CommonFilesMetadataBuilder { private static final String WHERE_CLAUSE = "%s md5 in (select md5 from tsk_files where (known != 1 OR known IS NULL)%s GROUP BY md5) order by md5"; //NON-NLS @@ -49,55 +49,48 @@ public class AllDataSourcesEamDbCommonFilesAlgorithm extends CommonFilesMetadat /** * Implements the algorithm for getting common files across all data - * sources. + * sources and all cases. Can filter on mime types conjoined by logical AND. * * @param dataSourceIdMap a map of obj_id to datasource name * @param filterByMediaMimeType match only on files whose mime types can be broadly categorized as media types * @param filterByDocMimeType match only on files whose mime types can be broadly categorized as document types + * + * @throws EamDbException */ - AllDataSourcesEamDbCommonFilesAlgorithm(Map dataSourceIdMap, boolean filterByMediaMimeType, boolean filterByDocMimeType) throws EamDbException { + EamDbCommonFilesAlgorithm(Map dataSourceIdMap, boolean filterByMediaMimeType, boolean filterByDocMimeType) throws EamDbException { super(dataSourceIdMap, filterByMediaMimeType, filterByDocMimeType); dbManager = EamDb.getInstance(); } - CommonFilesMetadata findEamDbCommonFiles() throws TskCoreException, NoCurrentCaseException, SQLException, EamDbException { - return this.findEamDbCommonFiles(null); + @Override + public CommonFilesMetadata findFiles() throws TskCoreException, NoCurrentCaseException, SQLException, EamDbException, Exception { + return this.findFiles(null); } - CommonFilesMetadata findEamDbCommonFiles(int correlationCaseId) throws TskCoreException, NoCurrentCaseException, SQLException, EamDbException, Exception { - - CorrelationCase cCase = this.getCorrelationCaseFromId(correlationCaseId); - - return this.findEamDbCommonFiles(cCase); - } - - /** - * @param correlationCase Optionally null, otherwise a case, or could be a CR case ID - * @return CommonFilesMetaData md5s to build Common Files search results. - * @throws TskCoreException - * @throws NoCurrentCaseException - * @throws SQLException - * @throws EamDbException - */ - private CommonFilesMetadata findEamDbCommonFiles(CorrelationCase correlationCase) throws TskCoreException, NoCurrentCaseException, SQLException, EamDbException { - CommonFilesMetadata metaData = this.findCommonFiles(); - Map commonFiles = metaData.getMetadata(); - Collection values = commonFiles.keySet(); + protected CommonFilesMetadata findFiles(CorrelationCase correlationCase) throws TskCoreException, NoCurrentCaseException, SQLException, EamDbException, Exception { + Map currentCaseMetadata = getMetadataForCurrentCase(); + Collection values = currentCaseMetadata.keySet(); Map interCaseCommonFiles = new HashMap<>(); try { Collection artifactInstances = dbManager.getArtifactInstancesByCaseValues(correlationCase, values).stream() .collect(Collectors.toList()); - gatherIntercaseResults(artifactInstances, commonFiles, interCaseCommonFiles); + gatherIntercaseResults(artifactInstances, currentCaseMetadata, interCaseCommonFiles); } catch (EamDbException ex) { LOGGER.log(Level.SEVERE, "Error getting artifact instances from database.", ex); // NON-NLS } // Builds intercase-only matches metadata - return new CommonFilesMetadata(interCaseCommonFiles); - + return new CommonFilesMetadata(interCaseCommonFiles); + } + + private Map getMetadataForCurrentCase() throws NoCurrentCaseException, TskCoreException, SQLException, Exception { + //TODO see how we can clarify this + CommonFilesMetadata metaData = super.findFiles(); + Map commonFiles = metaData.getMetadata(); + return commonFiles; } private void gatherIntercaseResults(Collection artifactInstances, Map commonFiles, Map interCaseCommonFiles) { @@ -109,7 +102,7 @@ public class AllDataSourcesEamDbCommonFilesAlgorithm extends CommonFilesMetadat if (md5 == null || HashUtility.isNoDataMd5(md5)) { continue; } - //Builds a 3rd list which contains instances which are in commonFiles map, uses current case objectId + //Builds a 3rd list which contains instances which are in currentCaseMetadata map, uses current case objectId if (commonFiles.containsKey(md5)) { // we don't *have* all the information for the rows in the CR, // so we need to consult the present case via the SleuthkitCase object @@ -137,17 +130,18 @@ public class AllDataSourcesEamDbCommonFilesAlgorithm extends CommonFilesMetadat @Override protected String buildTabTitle() { + //TODO come back to this final String buildCategorySelectionString = this.buildCategorySelectionString(); final String titleTemplate = Bundle.CommonFilesMetadataBuilder_buildTabTitle_titleEamDb(); return String.format(titleTemplate, new Object[]{buildCategorySelectionString}); } - private CorrelationCase getCorrelationCaseFromId(int correlationCaseId) throws EamDbException, Exception { + protected CorrelationCase getCorrelationCaseFromId(int correlationCaseId) throws EamDbException, Exception { for(CorrelationCase cCase : this.dbManager.getCases()){ if(cCase.getID() == correlationCaseId){ return cCase; } } - throw new Exception("Cannont locate case."); + throw new Exception("Cannot locate case."); } } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.java index 97fd21a7d3..cb2ea0f946 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.java @@ -20,6 +20,7 @@ package org.sleuthkit.autopsy.commonfilesearch; import java.util.Collections; +import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; import javax.swing.ComboBoxModel; @@ -48,6 +49,7 @@ public class InterCasePanel extends javax.swing.JPanel { public InterCasePanel() { initComponents(); this.errorMessage = ""; + this.caseMap = new HashMap<>(); } private void specificCaseSelected(boolean selected) { diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/SingleCaseEamDbCommonFilesAlgorithm.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/SingleCaseEamDbCommonFilesAlgorithm.java new file mode 100644 index 0000000000..8aad5414a8 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/SingleCaseEamDbCommonFilesAlgorithm.java @@ -0,0 +1,70 @@ +/* + * + * Autopsy Forensic Browser + * + * Copyright 2018 Basis Technology Corp. + * Contact: carrier sleuthkit 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.commonfilesearch; + +import java.sql.SQLException; +import java.util.Map; +import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; +import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationCase; +import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException; +import org.sleuthkit.datamodel.TskCoreException; + +/** + * + * TODO + */ +public class SingleCaseEamDbCommonFilesAlgorithm extends EamDbCommonFilesAlgorithm { + + private final int corrleationCaseId; + + /** + * + * @param correlationCaseId + * @param dataSourceIdMap + * @param filterByMediaMimeType + * @param filterByDocMimeType + * @throws EamDbException + */ + public SingleCaseEamDbCommonFilesAlgorithm(int correlationCaseId, Map dataSourceIdMap, boolean filterByMediaMimeType, boolean filterByDocMimeType) throws EamDbException { + super(dataSourceIdMap, filterByMediaMimeType, filterByDocMimeType); + + this.corrleationCaseId = correlationCaseId; + } + + /** + * Collect metadata required to render the tree table where matches must + * occur in the case with the given ID. + * + * @param correlationCaseId id of case where matches must occur (no other matches will be shown) + * @return business object needed to populate tree table with results + * @throws TskCoreException + * @throws NoCurrentCaseException + * @throws SQLException + * @throws EamDbException + * @throws Exception + */ + @Override + public CommonFilesMetadata findFiles() throws TskCoreException, NoCurrentCaseException, SQLException, EamDbException, Exception { + + CorrelationCase cCase = this.getCorrelationCaseFromId(this.corrleationCaseId); + + return this.findFiles(cCase); + } +} diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileType.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileType.java index d4fc9f634d..1130ee8cb8 100644 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileType.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileType.java @@ -88,7 +88,7 @@ public class IngestedWithHashAndFileType extends AbstractIntraCaseCommonFilesSea Map dataSources = this.dataSourceLoader.getDataSourceMap(); CommonFilesMetadataBuilder allSourcesBuilder = new AllDataSourcesCommonFilesAlgorithm(dataSources, false, false); - CommonFilesMetadata metadata = allSourcesBuilder.findCommonFiles(); + CommonFilesMetadata metadata = allSourcesBuilder.findFiles(); Map objectIdToDataSource = mapFileInstancesToDataSources(metadata); @@ -129,7 +129,7 @@ public class IngestedWithHashAndFileType extends AbstractIntraCaseCommonFilesSea Map dataSources = this.dataSourceLoader.getDataSourceMap(); CommonFilesMetadataBuilder allSourcesBuilder = new AllDataSourcesCommonFilesAlgorithm(dataSources, true, false); - CommonFilesMetadata metadata = allSourcesBuilder.findCommonFiles(); + CommonFilesMetadata metadata = allSourcesBuilder.findFiles(); Map objectIdToDataSource = mapFileInstancesToDataSources(metadata); @@ -170,7 +170,7 @@ public class IngestedWithHashAndFileType extends AbstractIntraCaseCommonFilesSea Map dataSources = this.dataSourceLoader.getDataSourceMap(); CommonFilesMetadataBuilder allSourcesBuilder = new AllDataSourcesCommonFilesAlgorithm(dataSources, false, true); - CommonFilesMetadata metadata = allSourcesBuilder.findCommonFiles(); + CommonFilesMetadata metadata = allSourcesBuilder.findFiles(); Map objectIdToDataSource = mapFileInstancesToDataSources(metadata); @@ -214,7 +214,7 @@ public class IngestedWithHashAndFileType extends AbstractIntraCaseCommonFilesSea Long first = this.getDataSourceIdByIndex(0, dataSources); CommonFilesMetadataBuilder singleSourceBuilder = new SingleDataSource(first, dataSources, false, false); - CommonFilesMetadata metadata = singleSourceBuilder.findCommonFiles(); + CommonFilesMetadata metadata = singleSourceBuilder.findFiles(); Map objectIdToDataSource = mapFileInstancesToDataSources(metadata); @@ -257,7 +257,7 @@ public class IngestedWithHashAndFileType extends AbstractIntraCaseCommonFilesSea Long first = this.getDataSourceIdByIndex(0, dataSources); CommonFilesMetadataBuilder singleSourceBuilder = new SingleDataSource(first, dataSources, true, false); - CommonFilesMetadata metadata = singleSourceBuilder.findCommonFiles(); + CommonFilesMetadata metadata = singleSourceBuilder.findFiles(); Map objectIdToDataSource = mapFileInstancesToDataSources(metadata); @@ -300,7 +300,7 @@ public class IngestedWithHashAndFileType extends AbstractIntraCaseCommonFilesSea Long first = this.getDataSourceIdByIndex(0, dataSources); CommonFilesMetadataBuilder singleSourceBuilder = new SingleDataSource(first, dataSources, false, true); - CommonFilesMetadata metadata = singleSourceBuilder.findCommonFiles(); + CommonFilesMetadata metadata = singleSourceBuilder.findFiles(); Map objectIdToDataSource = mapFileInstancesToDataSources(metadata); @@ -342,7 +342,7 @@ public class IngestedWithHashAndFileType extends AbstractIntraCaseCommonFilesSea Long second = this.getDataSourceIdByIndex(1, dataSources); CommonFilesMetadataBuilder singleSourceBuilder = new SingleDataSource(second, dataSources, false, false); - CommonFilesMetadata metadata = singleSourceBuilder.findCommonFiles(); + CommonFilesMetadata metadata = singleSourceBuilder.findFiles(); Map objectIdToDataSource = mapFileInstancesToDataSources(metadata); @@ -383,7 +383,7 @@ public class IngestedWithHashAndFileType extends AbstractIntraCaseCommonFilesSea Long last = this.getDataSourceIdByIndex(3, dataSources); CommonFilesMetadataBuilder singleSourceBuilder = new SingleDataSource(last, dataSources, false, false); - CommonFilesMetadata metadata = singleSourceBuilder.findCommonFiles(); + CommonFilesMetadata metadata = singleSourceBuilder.findFiles(); Map objectIdToDataSource = mapFileInstancesToDataSources(metadata); @@ -424,7 +424,7 @@ public class IngestedWithHashAndFileType extends AbstractIntraCaseCommonFilesSea Long third = this.getDataSourceIdByIndex(2, dataSources); CommonFilesMetadataBuilder singleSourceBuilder = new SingleDataSource(third, dataSources, false, false); - CommonFilesMetadata metadata = singleSourceBuilder.findCommonFiles(); + CommonFilesMetadata metadata = singleSourceBuilder.findFiles(); Map objectIdToDataSource = mapFileInstancesToDataSources(metadata); diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithNoFileTypes.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithNoFileTypes.java index 24b614eb5b..1e6f73fb8f 100644 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithNoFileTypes.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithNoFileTypes.java @@ -95,7 +95,7 @@ public class IngestedWithNoFileTypes extends AbstractIntraCaseCommonFilesSearchT Map dataSources = this.dataSourceLoader.getDataSourceMap(); CommonFilesMetadataBuilder allSourcesBuilder = new AllDataSourcesCommonFilesAlgorithm(dataSources, true, false); - CommonFilesMetadata metadata = allSourcesBuilder.findCommonFiles(); + CommonFilesMetadata metadata = allSourcesBuilder.findFiles(); Map objectIdToDataSource = mapFileInstancesToDataSources(metadata); @@ -118,7 +118,7 @@ public class IngestedWithNoFileTypes extends AbstractIntraCaseCommonFilesSearchT Long third = this.getDataSourceIdByIndex(2, dataSources); CommonFilesMetadataBuilder singleSourceBuilder = new SingleDataSource(third, dataSources, true, false); - CommonFilesMetadata metadata = singleSourceBuilder.findCommonFiles(); + CommonFilesMetadata metadata = singleSourceBuilder.findFiles(); Map objectIdToDataSource = mapFileInstancesToDataSources(metadata); diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/UningestedCases.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/UningestedCases.java index 17ed02cd61..1215c2290a 100644 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/UningestedCases.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/UningestedCases.java @@ -64,7 +64,7 @@ public class UningestedCases extends AbstractIntraCaseCommonFilesSearchTest { Map dataSources = this.dataSourceLoader.getDataSourceMap(); CommonFilesMetadataBuilder allSourcesBuilder = new AllDataSourcesCommonFilesAlgorithm(dataSources, false, false); - CommonFilesMetadata metadata = allSourcesBuilder.findCommonFiles(); + CommonFilesMetadata metadata = allSourcesBuilder.findFiles(); int resultCount = metadata.size(); assertEquals(resultCount, 0); @@ -84,7 +84,7 @@ public class UningestedCases extends AbstractIntraCaseCommonFilesSearchTest { Long first = this.getDataSourceIdByIndex(0, dataSources); CommonFilesMetadataBuilder singleSourceBuilder = new SingleDataSource(first, dataSources, false, false); - CommonFilesMetadata metadata = singleSourceBuilder.findCommonFiles(); + CommonFilesMetadata metadata = singleSourceBuilder.findFiles(); int resultCount = metadata.size(); assertEquals(resultCount, 0); From d1456cd68c96e78b9fab496fc11e1cbf573341bd Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Tue, 22 May 2018 11:31:33 -0600 Subject: [PATCH 045/287] trivial code cleanup --- .../autopsy/centralrepository/datamodel/AbstractSqlEamDb.java | 1 - .../org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.java | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java index 1558b97e01..bfa5ce666f 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java @@ -31,7 +31,6 @@ import java.sql.SQLException; import java.sql.Statement; import java.sql.Types; import java.time.LocalDate; -import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.Set; diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.java index cb2ea0f946..940b1d5ba7 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.java @@ -37,7 +37,7 @@ public class InterCasePanel extends javax.swing.JPanel { static final int NO_CASE_SELECTED = -1; private ComboBoxModel casesList = new DataSourceComboBoxModel(); - private Map caseMap; + private final Map caseMap; private CommonFilesPanel parent; From d95f8c5352705aeacc4e6e6e1575ec19c903c56e Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Tue, 22 May 2018 15:00:52 -0600 Subject: [PATCH 046/287] exception handling catches up to metadatabuilders api change --- .../IngestedWithHashAndFileType.java | 18 +++++++++--------- .../IngestedWithNoFileTypes.java | 4 ++-- .../commonfilessearch/UningestedCases.java | 4 ++-- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileType.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileType.java index 1130ee8cb8..d1c26cb734 100644 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileType.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileType.java @@ -115,7 +115,7 @@ public class IngestedWithHashAndFileType extends AbstractIntraCaseCommonFilesSea assertTrue(fileExists(files, objectIdToDataSource, EMPTY, SET4, 0)); - } catch (NoCurrentCaseException | TskCoreException | SQLException ex) { + } catch (Exception ex) { Exceptions.printStackTrace(ex); Assert.fail(ex); } @@ -156,7 +156,7 @@ public class IngestedWithHashAndFileType extends AbstractIntraCaseCommonFilesSea assertTrue(fileExists(files, objectIdToDataSource, EMPTY, SET4, 0)); - } catch (NoCurrentCaseException | TskCoreException | SQLException ex) { + } catch (Exception ex) { Exceptions.printStackTrace(ex); Assert.fail(ex); } @@ -197,7 +197,7 @@ public class IngestedWithHashAndFileType extends AbstractIntraCaseCommonFilesSea assertTrue(fileExists(files, objectIdToDataSource, EMPTY, SET4, 0)); - } catch (NoCurrentCaseException | TskCoreException | SQLException ex) { + } catch (Exception ex) { Exceptions.printStackTrace(ex); Assert.fail(ex); } @@ -240,7 +240,7 @@ public class IngestedWithHashAndFileType extends AbstractIntraCaseCommonFilesSea assertTrue(fileExists(files, objectIdToDataSource, EMPTY, SET3, 0)); assertTrue(fileExists(files, objectIdToDataSource, EMPTY, SET4, 0)); - } catch (NoCurrentCaseException | TskCoreException | SQLException ex) { + } catch (Exception ex) { Exceptions.printStackTrace(ex); Assert.fail(ex); } @@ -283,7 +283,7 @@ public class IngestedWithHashAndFileType extends AbstractIntraCaseCommonFilesSea assertTrue(fileExists(files, objectIdToDataSource, EMPTY, SET3, 0)); assertTrue(fileExists(files, objectIdToDataSource, EMPTY, SET4, 0)); - } catch (NoCurrentCaseException | TskCoreException | SQLException ex) { + } catch (Exception ex) { Exceptions.printStackTrace(ex); Assert.fail(ex); } @@ -326,7 +326,7 @@ public class IngestedWithHashAndFileType extends AbstractIntraCaseCommonFilesSea assertTrue(fileExists(files, objectIdToDataSource, EMPTY, SET3, 0)); assertTrue(fileExists(files, objectIdToDataSource, EMPTY, SET4, 0)); - } catch (NoCurrentCaseException | TskCoreException | SQLException ex) { + } catch (Exception ex) { Exceptions.printStackTrace(ex); Assert.fail(ex); } @@ -368,7 +368,7 @@ public class IngestedWithHashAndFileType extends AbstractIntraCaseCommonFilesSea assertTrue(fileExists(files, objectIdToDataSource, EMPTY, SET3, 0)); assertTrue(fileExists(files, objectIdToDataSource, EMPTY, SET4, 0)); - } catch (NoCurrentCaseException | TskCoreException | SQLException ex) { + } catch (Exception ex) { Exceptions.printStackTrace(ex); Assert.fail(ex); } @@ -409,7 +409,7 @@ public class IngestedWithHashAndFileType extends AbstractIntraCaseCommonFilesSea assertTrue(fileExists(files, objectIdToDataSource, EMPTY, SET3, 0)); assertTrue(fileExists(files, objectIdToDataSource, EMPTY, SET4, 0)); - } catch (NoCurrentCaseException | TskCoreException | SQLException ex) { + } catch (Exception ex) { Exceptions.printStackTrace(ex); Assert.fail(ex); } @@ -450,7 +450,7 @@ public class IngestedWithHashAndFileType extends AbstractIntraCaseCommonFilesSea assertTrue(fileExists(files, objectIdToDataSource, EMPTY, SET3, 0)); assertTrue(fileExists(files, objectIdToDataSource, EMPTY, SET4, 0)); - } catch (NoCurrentCaseException | TskCoreException | SQLException ex) { + } catch (Exception ex) { Exceptions.printStackTrace(ex); Assert.fail(ex); } diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithNoFileTypes.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithNoFileTypes.java index 1e6f73fb8f..f2e96977d4 100644 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithNoFileTypes.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithNoFileTypes.java @@ -103,7 +103,7 @@ public class IngestedWithNoFileTypes extends AbstractIntraCaseCommonFilesSearchT assertTrue(files.isEmpty()); - } catch (NoCurrentCaseException | TskCoreException | SQLException ex) { + } catch (Exception ex) { Exceptions.printStackTrace(ex); } } @@ -126,7 +126,7 @@ public class IngestedWithNoFileTypes extends AbstractIntraCaseCommonFilesSearchT assertTrue(files.isEmpty()); - } catch (NoCurrentCaseException | TskCoreException | SQLException ex) { + } catch (Exception ex) { Exceptions.printStackTrace(ex); Assert.fail(ex); } diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/UningestedCases.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/UningestedCases.java index 1215c2290a..b00996a812 100644 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/UningestedCases.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/UningestedCases.java @@ -69,7 +69,7 @@ public class UningestedCases extends AbstractIntraCaseCommonFilesSearchTest { int resultCount = metadata.size(); assertEquals(resultCount, 0); - } catch (NoCurrentCaseException | TskCoreException | SQLException ex) { + } catch (Exception ex) { Exceptions.printStackTrace(ex); Assert.fail(ex); } @@ -89,7 +89,7 @@ public class UningestedCases extends AbstractIntraCaseCommonFilesSearchTest { int resultCount = metadata.size(); assertEquals(resultCount, 0); - } catch (NoCurrentCaseException | TskCoreException | SQLException ex) { + } catch (Exception ex) { Exceptions.printStackTrace(ex); Assert.fail(ex); } From e7bf655da250d81ffd8a125485dce8c2cb38e309 Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Wed, 23 May 2018 07:20:21 -0600 Subject: [PATCH 047/287] tests - wip --- ...bstractInterCaseCommonFilesSearchTest.java | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/AbstractInterCaseCommonFilesSearchTest.java diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/AbstractInterCaseCommonFilesSearchTest.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/AbstractInterCaseCommonFilesSearchTest.java new file mode 100644 index 0000000000..48a34ee352 --- /dev/null +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/AbstractInterCaseCommonFilesSearchTest.java @@ -0,0 +1,28 @@ +/* + * + * Autopsy Forensic Browser + * + * Copyright 2018 Basis Technology Corp. + * Contact: carrier sleuthkit 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.commonfilessearch; + +/** + * + * @author bsweeney + */ +public class AbstractInterCaseCommonFilesSearchTest { + +} From 9cfcaaa51c5c2afc2ab8a9597a44b342abf4c51f Mon Sep 17 00:00:00 2001 From: Andrew Ziehl Date: Wed, 23 May 2018 13:28:58 -0700 Subject: [PATCH 048/287] Add null check on values, add CR tests for new query method. --- .../datamodel/AbstractSqlEamDb.java | 92 ++++++++++--------- .../datamodel/CentralRepoDatamodelTest.java | 57 +++++++++++- 2 files changed, 105 insertions(+), 44 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java index bfa5ce666f..16d30c6d48 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java @@ -647,15 +647,19 @@ public abstract class AbstractSqlEamDb implements EamDb { return artifactInstances; } - /** - * Retrieves eamArtiifact instances from the database that match - * the given list of MD5 values and optionally filters by given case. + * Retrieves eamArtiifact instances from the database that match the given + * list of MD5 values and optionally filters by given case. * + * Warning: Does not benefit from PreparedStatement caching to since values will + * be variable in length + * * @param correlationCase Case id to search on, if null, searches all cases * @param values List of ArtifactInstance MD5 values to find matches of. * * @return List of artifact instances for a given list of MD5 values + * + * @throws EamDbException if EamDb is inaccessible. */ @Override public List getArtifactInstancesByCaseValues(CorrelationCase correlationCase, Collection values) throws EamDbException { @@ -674,53 +678,55 @@ public abstract class AbstractSqlEamDb implements EamDb { CorrelationAttributeCommonInstance artifactInstance; PreparedStatement preparedStatement = null; ResultSet resultSet = null; - - String tableName = EamDbUtil.correlationTypeToInstanceTableName(aType); - StringBuilder sql = new StringBuilder(10); - sql.append("SELECT cases.case_name, cases.case_uid, data_sources.name, device_id, file_path, known_status, comment, data_sources.case_id, value FROM "); - sql.append(tableName); - sql.append(" LEFT JOIN cases ON "); - sql.append(tableName); - sql.append(".case_id=cases.id"); - sql.append(" LEFT JOIN data_sources ON "); - sql.append(tableName); - sql.append(".data_source_id=data_sources.id"); - sql.append(" WHERE value IN ("); - - for(int i = 0; i < values.size(); i++){ - sql.append("?,"); - } - sql.deleteCharAt(sql.length() - 1); - sql.append(")"); - - if (singleCase && correlationCase != null) { - sql.append(" AND "); + if (values != null) { + String tableName = EamDbUtil.correlationTypeToInstanceTableName(aType); + StringBuilder sql = new StringBuilder(10); + sql.append("SELECT cases.case_name, cases.case_uid, data_sources.name, device_id, file_path, known_status, comment, data_sources.case_id, value FROM "); sql.append(tableName); - sql.append(".case_id=?"); - } + sql.append(" LEFT JOIN cases ON "); + sql.append(tableName); + sql.append(".case_id=cases.id"); + sql.append(" LEFT JOIN data_sources ON "); + sql.append(tableName); + sql.append(".data_source_id=data_sources.id"); + sql.append(" WHERE value IN ("); - try { - preparedStatement = conn.prepareStatement(sql.toString()); - int i = 1; - for (String value : values){ - preparedStatement.setString(i, value); - i++; + for (int i = 0; i < values.size(); i++) { + sql.append("?,"); } + sql.deleteCharAt(sql.length() - 1); + sql.append(")"); + if (singleCase && correlationCase != null) { - preparedStatement.setString(i, String.valueOf(correlationCase.getID())); + sql.append(" AND "); + sql.append(tableName); + sql.append(".case_id=?"); } - resultSet = preparedStatement.executeQuery(); - while (resultSet.next()) { - artifactInstance = getCommonEamArtifactInstanceFromResultSet(resultSet); - artifactInstances.add(artifactInstance); + try { + preparedStatement = conn.prepareStatement(sql.toString()); + int i = 1; + for (String value : values) { + preparedStatement.setString(i, value); + i++; + } + if (singleCase && correlationCase != null) { + preparedStatement.setString(i, String.valueOf(correlationCase.getID())); + } + + resultSet = preparedStatement.executeQuery(); + while (resultSet.next()) { + artifactInstance = getCommonEamArtifactInstanceFromResultSet(resultSet); + artifactInstances.add(artifactInstance); + } + + } catch (SQLException ex) { + throw new EamDbException("Error getting artifact instances by artifactType and artifactValue.", ex); // NON-NLS + } finally { + EamDbUtil.closePreparedStatement(preparedStatement); + EamDbUtil.closeResultSet(resultSet); + EamDbUtil.closeConnection(conn); } - } catch (SQLException ex) { - throw new EamDbException("Error getting artifact instances by artifactType and artifactValue.", ex); // NON-NLS - } finally { - EamDbUtil.closePreparedStatement(preparedStatement); - EamDbUtil.closeResultSet(resultSet); - EamDbUtil.closeConnection(conn); } return artifactInstances; diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDatamodelTest.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDatamodelTest.java index 99dbd9204d..055e9a8040 100644 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDatamodelTest.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDatamodelTest.java @@ -828,7 +828,7 @@ public class CentralRepoDatamodelTest extends TestCase { // This is the expected behavior } - // Test getting instances with expected resuls + // Test getting instances with expected results try { List instances = EamDb.getInstance().getArtifactInstancesByTypeValue(fileType, inAllDataSourcesHash); assertTrue("getArtifactInstancesByTypeValue returned " + instances.size() + " results - expected 3", instances.size() == 3); @@ -842,6 +842,50 @@ public class CentralRepoDatamodelTest extends TestCase { Exceptions.printStackTrace(ex); Assert.fail(ex); } + + // Test getting common instances with expected results + try { + List instances = EamDb.getInstance().getArtifactInstancesByCaseValues(null, Arrays.asList(inAllDataSourcesHash, inDataSource1twiceHash)); + assertTrue("getArtifactInstancesByCaseValues returned " + instances.size() + " results - expected 5", instances.size() == 5); + + // This test works because all the instances of this hash were set to the same path + for (CorrelationAttributeCommonInstance inst : instances) { + if(inst.getValue().equals(inAllDataSourcesHash)) { + assertTrue("getArtifactInstancesByCaseValues returned instance with unexpected path " + inst.getFilePath(), + inAllDataSourcesPath.equalsIgnoreCase(inst.getFilePath())); + } + else if(inst.getValue().equals(inDataSource1twiceHash)) { + assertTrue("getArtifactInstancesByCaseValues returned instance with unexpected path " + inst.getFilePath(), + inDataSource1twicePath1.equalsIgnoreCase(inst.getFilePath()) || inDataSource1twicePath2.equalsIgnoreCase(inst.getFilePath())); + } + } + } catch (EamDbException ex) { + Exceptions.printStackTrace(ex); + Assert.fail(ex); + } + + // Test getting instances expecting no results because they are not in the case + try { + CorrelationCase badCase = new CorrelationCase("badCaseUuid", "badCaseName"); + List instances = EamDb.getInstance().getArtifactInstancesByCaseValues(badCase, Arrays.asList(inAllDataSourcesHash, inDataSource1twiceHash)); + + assertTrue("getArtifactInstancesByTypeValue returned " + instances.size() + " results - expected 0", instances.isEmpty()); + } catch (EamDbException ex) { + Exceptions.printStackTrace(ex); + Assert.fail(ex); + } + + + // Test getting instances expecting no results because of bad hashes + try { + List instances = EamDb.getInstance().getArtifactInstancesByCaseValues(null, Arrays.asList("xyz", "123")); + + assertTrue("getArtifactInstancesByTypeValue returned " + instances.size() + " results - expected 0", instances.isEmpty()); + } catch (EamDbException ex) { + Exceptions.printStackTrace(ex); + Assert.fail(ex); + } + // Test getting instances expecting no results try { @@ -870,6 +914,17 @@ public class CentralRepoDatamodelTest extends TestCase { Exceptions.printStackTrace(ex); Assert.fail(ex); } + + // Test getting instances with null value + // Should just return nothing + try { + List instances = EamDb.getInstance().getArtifactInstancesByCaseValues(null, null); + + assertTrue("getArtifactInstancesByTypeValue returned non-empty list for null value", instances.isEmpty()); + } catch (EamDbException ex) { + Exceptions.printStackTrace(ex); + Assert.fail(ex); + } // Test getting instances with path that should produce results try { From 16a2b2770dce3c56521cafb109539beeea2be589 Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Thu, 24 May 2018 13:17:09 -0600 Subject: [PATCH 049/287] function with side effects turned into a pure function --- .../commonfilesearch/EamDbCommonFilesAlgorithm.java | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbCommonFilesAlgorithm.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbCommonFilesAlgorithm.java index a51e47a836..c09f6fc602 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbCommonFilesAlgorithm.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbCommonFilesAlgorithm.java @@ -72,12 +72,12 @@ public abstract class EamDbCommonFilesAlgorithm extends CommonFilesMetadataBuil Map currentCaseMetadata = getMetadataForCurrentCase(); Collection values = currentCaseMetadata.keySet(); - Map interCaseCommonFiles = new HashMap<>(); + Map interCaseCommonFiles = new HashMap<>(); try { Collection artifactInstances = dbManager.getArtifactInstancesByCaseValues(correlationCase, values).stream() .collect(Collectors.toList()); - gatherIntercaseResults(artifactInstances, currentCaseMetadata, interCaseCommonFiles); + interCaseCommonFiles = gatherIntercaseResults(artifactInstances, currentCaseMetadata); } catch (EamDbException ex) { LOGGER.log(Level.SEVERE, "Error getting artifact instances from database.", ex); // NON-NLS @@ -87,13 +87,16 @@ public abstract class EamDbCommonFilesAlgorithm extends CommonFilesMetadataBuil } private Map getMetadataForCurrentCase() throws NoCurrentCaseException, TskCoreException, SQLException, Exception { - //TODO see how we can clarify this + //we need the list of files in the present case so we can compare against the central repo CommonFilesMetadata metaData = super.findFiles(); Map commonFiles = metaData.getMetadata(); return commonFiles; } - private void gatherIntercaseResults(Collection artifactInstances, Map commonFiles, Map interCaseCommonFiles) { + private Map gatherIntercaseResults(Collection artifactInstances, Map commonFiles) { + + Map interCaseCommonFiles = new HashMap(); + for (CorrelationAttributeCommonInstance instance : artifactInstances) { String md5 = instance.getValue(); @@ -120,6 +123,8 @@ public abstract class EamDbCommonFilesAlgorithm extends CommonFilesMetadataBuil } } } + + return interCaseCommonFiles; } @Override From db341a9cb06a48edd46d511dd86d613f0099a900 Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Fri, 25 May 2018 08:40:07 -0600 Subject: [PATCH 050/287] code cleanup --- .../EamDbCommonFilesAlgorithm.java | 56 ++++++++++--------- 1 file changed, 29 insertions(+), 27 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbCommonFilesAlgorithm.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbCommonFilesAlgorithm.java index c09f6fc602..898da0c9ed 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbCommonFilesAlgorithm.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbCommonFilesAlgorithm.java @@ -37,24 +37,26 @@ import static org.sleuthkit.autopsy.timeline.datamodel.eventtype.ArtifactEventTy import org.sleuthkit.datamodel.HashUtility; import org.sleuthkit.datamodel.TskCoreException; - /** - * Provides logic for selecting common files from all data sources and all cases in the Central Repo. + * Provides logic for selecting common files from all data sources and all cases + * in the Central Repo. */ -public abstract class EamDbCommonFilesAlgorithm extends CommonFilesMetadataBuilder { +public abstract class EamDbCommonFilesAlgorithm extends CommonFilesMetadataBuilder { private static final String WHERE_CLAUSE = "%s md5 in (select md5 from tsk_files where (known != 1 OR known IS NULL)%s GROUP BY md5) order by md5"; //NON-NLS private final EamDb dbManager; - + /** - * Implements the algorithm for getting common files across all data - * sources and all cases. Can filter on mime types conjoined by logical AND. + * Implements the algorithm for getting common files across all data sources + * and all cases. Can filter on mime types conjoined by logical AND. * * @param dataSourceIdMap a map of obj_id to datasource name - * @param filterByMediaMimeType match only on files whose mime types can be broadly categorized as media types - * @param filterByDocMimeType match only on files whose mime types can be broadly categorized as document types - * + * @param filterByMediaMimeType match only on files whose mime types can be + * broadly categorized as media types + * @param filterByDocMimeType match only on files whose mime types can be + * broadly categorized as document types + * * @throws EamDbException */ EamDbCommonFilesAlgorithm(Map dataSourceIdMap, boolean filterByMediaMimeType, boolean filterByDocMimeType) throws EamDbException { @@ -62,46 +64,46 @@ public abstract class EamDbCommonFilesAlgorithm extends CommonFilesMetadataBuil dbManager = EamDb.getInstance(); } - + @Override public CommonFilesMetadata findFiles() throws TskCoreException, NoCurrentCaseException, SQLException, EamDbException, Exception { return this.findFiles(null); } - + protected CommonFilesMetadata findFiles(CorrelationCase correlationCase) throws TskCoreException, NoCurrentCaseException, SQLException, EamDbException, Exception { - Map currentCaseMetadata = getMetadataForCurrentCase(); + Map currentCaseMetadata = getMetadataForCurrentCase(); Collection values = currentCaseMetadata.keySet(); - + Map interCaseCommonFiles = new HashMap<>(); try { - + Collection artifactInstances = dbManager.getArtifactInstancesByCaseValues(correlationCase, values).stream() - .collect(Collectors.toList()); + .collect(Collectors.toList()); interCaseCommonFiles = gatherIntercaseResults(artifactInstances, currentCaseMetadata); - + } catch (EamDbException ex) { LOGGER.log(Level.SEVERE, "Error getting artifact instances from database.", ex); // NON-NLS - } + } // Builds intercase-only matches metadata - return new CommonFilesMetadata(interCaseCommonFiles); + return new CommonFilesMetadata(interCaseCommonFiles); } private Map getMetadataForCurrentCase() throws NoCurrentCaseException, TskCoreException, SQLException, Exception { //we need the list of files in the present case so we can compare against the central repo - CommonFilesMetadata metaData = super.findFiles(); - Map commonFiles = metaData.getMetadata(); + CommonFilesMetadata metaData = super.findFiles(); + Map commonFiles = metaData.getMetadata(); return commonFiles; } private Map gatherIntercaseResults(Collection artifactInstances, Map commonFiles) { - + Map interCaseCommonFiles = new HashMap(); - + for (CorrelationAttributeCommonInstance instance : artifactInstances) { - + String md5 = instance.getValue(); String dataSource = String.format("%s: %s", instance.getCorrelationCase().getDisplayName(), instance.getCorrelationDataSource().getName()); - + if (md5 == null || HashUtility.isNoDataMd5(md5)) { continue; } @@ -123,7 +125,7 @@ public abstract class EamDbCommonFilesAlgorithm extends CommonFilesMetadataBuil } } } - + return interCaseCommonFiles; } @@ -142,8 +144,8 @@ public abstract class EamDbCommonFilesAlgorithm extends CommonFilesMetadataBuil } protected CorrelationCase getCorrelationCaseFromId(int correlationCaseId) throws EamDbException, Exception { - for(CorrelationCase cCase : this.dbManager.getCases()){ - if(cCase.getID() == correlationCaseId){ + for (CorrelationCase cCase : this.dbManager.getCases()) { + if (cCase.getID() == correlationCaseId) { return cCase; } } From f7322e88d3501aa7049d8d524ee5123f2adb435b Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Fri, 25 May 2018 08:40:46 -0600 Subject: [PATCH 051/287] fixing sql statement - wip --- .../centralrepository/datamodel/AbstractSqlEamDb.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java index 2a5c3e320f..a6b0481e8a 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java @@ -677,6 +677,8 @@ public abstract class AbstractSqlEamDb implements EamDb { List artifactInstances = new ArrayList<>(); + // SELECT cases.case_name, cases.case_uid, data_sources.name, device_id, file_path, known_status, comment, data_sources.case_id, value FROM file_instances LEFT JOIN cases ON file_instances.case_id=cases.id LEFT JOIN data_sources ON file_instances.data_source_id=data_sources.id WHERE value IN (SELECT value FROM file_instances WHERE value IN ("59029becd7f830c0478aeb5e67cc3b20","d2b949c51cf3d5721699a6ea500eeba7","b90c8c8fb1c4687780002704b59585fe") GROUP BY value HAVING COUNT(*) > 1) ORDER BY value + CorrelationAttributeCommonInstance artifactInstance; PreparedStatement preparedStatement = null; ResultSet resultSet = null; @@ -691,19 +693,21 @@ public abstract class AbstractSqlEamDb implements EamDb { sql.append(" LEFT JOIN data_sources ON "); sql.append(tableName); sql.append(".data_source_id=data_sources.id"); - sql.append(" WHERE value IN ("); + sql.append(" WHERE value IN (SELECT value FROM file_instances WHERE value IN ("); for (int i = 0; i < values.size(); i++) { sql.append("?,"); } sql.deleteCharAt(sql.length() - 1); - sql.append(")"); + sql.append(")GROUP BY value HAVING COUNT(*) > 1) ORDER BY value"); if (singleCase && correlationCase != null) { sql.append(" AND "); sql.append(tableName); sql.append(".case_id=?"); } + + sql.append("GROUP BY value HAVING COUNT(*) > 1"); try { preparedStatement = conn.prepareStatement(sql.toString()); From 0249dac7179d63f83579992ff4572f04a8c0fdc3 Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Fri, 25 May 2018 12:43:07 -0600 Subject: [PATCH 052/287] group by clause added so that we dont get back instances that have no dupes just as long as they are in the current case --- .../autopsy/centralrepository/datamodel/AbstractSqlEamDb.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java index a6b0481e8a..dc1dd25139 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java @@ -699,7 +699,7 @@ public abstract class AbstractSqlEamDb implements EamDb { sql.append("?,"); } sql.deleteCharAt(sql.length() - 1); - sql.append(")GROUP BY value HAVING COUNT(*) > 1) ORDER BY value"); + sql.append(") GROUP BY value HAVING COUNT(*) > 1)"); if (singleCase && correlationCase != null) { sql.append(" AND "); @@ -707,7 +707,7 @@ public abstract class AbstractSqlEamDb implements EamDb { sql.append(".case_id=?"); } - sql.append("GROUP BY value HAVING COUNT(*) > 1"); + sql.append(" ORDER BY value, case_name, file_path"); try { preparedStatement = conn.prepareStatement(sql.toString()); From a5ca17f41f1df935c2be1d97edff647d9960f3f9 Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Sun, 27 May 2018 20:26:20 -0600 Subject: [PATCH 053/287] intercase test utils - wip --- ...bstractInterCaseCommonFilesSearchTest.java | 28 --- .../IngestedWithHashAndFileType.java | 1 - .../IngestedWithNoFileTypes.java | 1 - .../commonfilessearch/InterCaseTests.java | 54 +++++ .../commonfilessearch/InterCaseUtils.java | 185 ++++++++++++++++++ .../commonfilessearch/IntraCaseUtils.java | 8 +- .../commonfilessearch/UningestedCases.java | 3 - 7 files changed, 243 insertions(+), 37 deletions(-) delete mode 100644 Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/AbstractInterCaseCommonFilesSearchTest.java create mode 100644 Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/InterCaseTests.java create mode 100644 Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/InterCaseUtils.java diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/AbstractInterCaseCommonFilesSearchTest.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/AbstractInterCaseCommonFilesSearchTest.java deleted file mode 100644 index 48a34ee352..0000000000 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/AbstractInterCaseCommonFilesSearchTest.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * - * Autopsy Forensic Browser - * - * Copyright 2018 Basis Technology Corp. - * Contact: carrier sleuthkit 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.commonfilessearch; - -/** - * - * @author bsweeney - */ -public class AbstractInterCaseCommonFilesSearchTest { - -} diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileType.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileType.java index 4c7250752f..c44fe079ae 100644 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileType.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileType.java @@ -19,7 +19,6 @@ */ package org.sleuthkit.autopsy.commonfilessearch; -import java.sql.SQLException; import java.util.ArrayList; import java.util.List; import java.util.Map; diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithNoFileTypes.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithNoFileTypes.java index 77d0d9c090..6e90b856d3 100644 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithNoFileTypes.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithNoFileTypes.java @@ -19,7 +19,6 @@ */ package org.sleuthkit.autopsy.commonfilessearch; -import java.sql.SQLException; import java.util.ArrayList; import java.util.List; import java.util.Map; diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/InterCaseTests.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/InterCaseTests.java new file mode 100644 index 0000000000..81f6b00065 --- /dev/null +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/InterCaseTests.java @@ -0,0 +1,54 @@ +/* + * + * Autopsy Forensic Browser + * + * Copyright 2018 Basis Technology Corp. + * Contact: carrier sleuthkit 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.commonfilessearch; + +import junit.framework.Test; +import org.netbeans.junit.NbModuleSuite; +import org.netbeans.junit.NbTestCase; + +/** + * + * If I use the search all cases option: One node for Hash A (1_1_A.jpg, + * 1_2_A.jpg, 3_1_A.jpg) If I search for matches only in Case 1: One node for + * Hash A (1_1_A.jpg, 1_2_A.jpg, 3_1_A.jpg) If I search for matches only in Case + * 2: No matches If I only search in the current case (existing mode), allowing + * all data sources: One node for Hash C (3_1_C.jpg, 3_2_C.jpg) + * + * @author bsweeney + */ +public class InterCaseTests extends NbTestCase { + + public static Test suite() { + NbModuleSuite.Configuration conf = NbModuleSuite.createConfiguration(InterCaseTests.class). + clusters(".*"). + enableModules(".*"); + return conf.suite(); + } + + public InterCaseTests(String name) { + super(name); + } + + @Override + public void setUp(){ + + } + +} diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/InterCaseUtils.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/InterCaseUtils.java new file mode 100644 index 0000000000..e1b92de442 --- /dev/null +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/InterCaseUtils.java @@ -0,0 +1,185 @@ +/* + * + * Autopsy Forensic Browser + * + * Copyright 2018 Basis Technology Corp. + * Contact: carrier sleuthkit 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.commonfilessearch; + +import java.nio.file.Path; +import java.nio.file.Paths; +import org.netbeans.junit.NbTestCase; +import org.openide.util.Exceptions; +import org.sleuthkit.autopsy.casemodule.Case; +import org.sleuthkit.autopsy.casemodule.ImageDSProcessor; +import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbPlatformEnum; +import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbUtil; +import org.sleuthkit.autopsy.commonfilesearch.DataSourceLoader; +import org.sleuthkit.autopsy.ingest.IngestJobSettings; +import org.sleuthkit.autopsy.testutils.CaseUtils; +import org.sleuthkit.autopsy.testutils.IngestUtils; +import org.sleuthkit.datamodel.TskCoreException; + +/** + * Utilities for testing intercase correlation feature. + * + * Description of Test Data: + * (Note: files of the same name and extension are identical; + * files of the same name and differing extension are not identical.) + * + * Case 1 + * +Data Set 1 + * - Hash-0.dat [file of size 0] + * - Hash-A.jpg + * - Hash-A.pdf + * +Data Set2 + * - Hash-0.dat [file of size -0] + * - Hash-A.jpg + * - Hash-A.pdf + * Case 2 + * +Data Set 1 + * - Hash-A.jpg + * - Hash-A.pdf + * +Data Set 2 + * - Hash-A.jpg + * - Hash-A.pdf + * - Hash_D.doc + * Case 3 + * +Data Set 1 + * - Hash-A.jpg + * - Hash-A.pdf + * - Hash-C.jpg + * - Hash-C.pdf + * - Hash-D.jpg + * +Data Set 2 + * - Hash-C.jpg + * - Hash-C.pdf + * - Hash.D-doc + */ +public class InterCaseUtils { + + private static final String CASE_NAME = "InterCaseCommonFilesSearchTest"; + static final Path CASE_DIRECTORY_PATH = Paths.get(System.getProperty("java.io.tmpdir"), CASE_NAME); + + static final String CASE1 = "Case1"; + static final String CASE2 = "Case2"; + static final String CASE3 = "Case3"; + static final String CASE4 = "Case4"; + + final Path case1DataSet1Path; + final Path case1DataSet2Path; + final Path case2DataSet1Path; + final Path case2DataSet2Path; + final Path case3DataSet1Path; + final Path case3DataSet2Path; + + static final String HASH_0_DAT = "Hash-0.dat"; + static final String HASH_A_JPG = "Hash-A.jpg"; + static final String HASH_A_PDF = "Hash-A.pdf"; + static final String HASH_B_JPG = "Hash-B.jpg"; + static final String HASH_B_PDF = "Hash-B.pdf"; + static final String HASH_C_JPG = "Hash-C.jpg"; + static final String HASH_C_PDF = "Hash-C.pdf"; + static final String HASH_D_JPG = "Hash-D.jpg"; + static final String HASH_D_DOC = "Hash-D.doc"; + + static final String CASE1_DATASET_1 = "c1ds1.vhd"; + static final String CASE1_DATASET_2 = "c1ds2.vhd"; + static final String CASE2_DATASET_1 = "c2ds1.vhd"; + static final String CASE2_DATASET_2 = "c2ds2.vhd"; + static final String CASE3_DATASET_1 = "c3ds1.vhd"; + static final String CASE3_DATASET_2 = "c3ds2.vhd"; + + private final DataSourceLoader dataSourceLoader; + private final ImageDSProcessor imageDSProcessor; + + private Case caseReference; + + InterCaseUtils(NbTestCase testCase){ + + this.case1DataSet1Path = Paths.get(testCase.getDataDir().toString(), CASE1_DATASET_1); + this.case1DataSet2Path = Paths.get(testCase.getDataDir().toString(), CASE1_DATASET_2); + this.case2DataSet1Path = Paths.get(testCase.getDataDir().toString(), CASE1_DATASET_1); + this.case2DataSet2Path = Paths.get(testCase.getDataDir().toString(), CASE2_DATASET_2); + this.case3DataSet1Path = Paths.get(testCase.getDataDir().toString(), CASE3_DATASET_1); + this.case3DataSet2Path = Paths.get(testCase.getDataDir().toString(), CASE3_DATASET_2); + + this.dataSourceLoader = new DataSourceLoader(); + this.imageDSProcessor = new ImageDSProcessor(); + } + + void enableCentralRepo(){ + EamDbUtil.setUseCentralRepo(true); + EamDbPlatformEnum.setSelectedPlatform(EamDbPlatformEnum.SQLITE.name()); + EamDbPlatformEnum.saveSelectedPlatform(); + } + + /** + * Create a case and ingest each with the given settings. Null settings + * are permitted but IngestUtils will not be run. + * + * @param ingestJobSettings HashLookup FileType etc... + */ + void createCases(IngestJobSettings ingestJobSettings){ + + try { + this.createCase(CASE1, ingestJobSettings, false, new Path[]{}); + this.createCase(CASE2, ingestJobSettings, false, new Path[]{}); + this.createCase(CASE3, ingestJobSettings, false, new Path[]{}); + this.caseReference = this.createCase(CASE4, ingestJobSettings, true, new Path[]{}); + } catch (TskCoreException ex) { + Exceptions.printStackTrace(ex); + //TODO fail test + } + } + + private Case createCase(String caseName, IngestJobSettings ingestJobSettings, boolean keepAlive, Path... dataSetPaths) throws TskCoreException{ + + Case caze = CaseUtils.createAsCurrentCase(caseName); + for(Path dataSetPath : dataSetPaths){ + IngestUtils.addDataSource(this.imageDSProcessor, dataSetPath); + } + if(ingestJobSettings != null){ + IngestUtils.runIngestJob(caze.getDataSources(), ingestJobSettings); + } + if(keepAlive){ + return caze; + } else { + CaseUtils.closeCurrentCase(false); + return null; + } + } + + /** + * TODO some more cool verbiage + * Could be null if createCases has not yet been run. + * @return + */ + Case getCaseReference() throws Exception{ + if(this.caseReference == null){ + throw new Exception("Must run createCases(...) first."); + } else { + return this.caseReference; + } + } + + void tearDown(){ + //close cases + //delete case dirs + //delete central repo db + } + +} diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IntraCaseUtils.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IntraCaseUtils.java index 2a2a8bd7bf..4e23ecffa2 100644 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IntraCaseUtils.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IntraCaseUtils.java @@ -94,10 +94,10 @@ class IntraCaseUtils { private final String caseName; IntraCaseUtils(NbTestCase nbTestCase, String caseName){ - imagePath1 = Paths.get(nbTestCase.getDataDir().toString(), "commonfiles_image1_v1.vhd"); - imagePath2 = Paths.get(nbTestCase.getDataDir().toString(), "commonfiles_image2_v1.vhd"); - imagePath3 = Paths.get(nbTestCase.getDataDir().toString(), "commonfiles_image3_v1.vhd"); - imagePath4 = Paths.get(nbTestCase.getDataDir().toString(), "commonfiles_image4_v1.vhd"); + this.imagePath1 = Paths.get(nbTestCase.getDataDir().toString(), SET1); + this.imagePath2 = Paths.get(nbTestCase.getDataDir().toString(), SET2); + this.imagePath3 = Paths.get(nbTestCase.getDataDir().toString(), SET3); + this.imagePath4 = Paths.get(nbTestCase.getDataDir().toString(), SET4); this.dataSourceLoader = new DataSourceLoader(); diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/UningestedCases.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/UningestedCases.java index 1098c2ef9d..c0e12d2034 100644 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/UningestedCases.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/UningestedCases.java @@ -19,7 +19,6 @@ */ package org.sleuthkit.autopsy.commonfilessearch; -import java.sql.SQLException; import java.util.Map; import static junit.framework.Assert.assertEquals; import junit.framework.Test; @@ -27,14 +26,12 @@ import org.netbeans.junit.NbModuleSuite; import org.netbeans.junit.NbTestCase; import org.openide.util.Exceptions; import org.python.icu.impl.Assert; -import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; import org.sleuthkit.autopsy.commonfilesearch.AllDataSourcesCommonFilesAlgorithm; import org.sleuthkit.autopsy.commonfilesearch.CommonFilesMetadata; import org.sleuthkit.autopsy.commonfilesearch.CommonFilesMetadataBuilder; import org.sleuthkit.autopsy.commonfilesearch.SingleDataSource; import static org.sleuthkit.autopsy.commonfilessearch.IntraCaseUtils.SET1; import static org.sleuthkit.autopsy.commonfilessearch.IntraCaseUtils.getDataSourceIdByName; -import org.sleuthkit.datamodel.TskCoreException; /** * Test that cases which are created but have not run any ingest modules turn up From 8f645b97e91071d6d594a6811d8bd755596cc8e0 Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Mon, 28 May 2018 17:48:46 -0600 Subject: [PATCH 054/287] intercaseutils --- .../IngestedWithNoFileTypes.java | 2 +- .../commonfilessearch/InterCaseUtils.java | 133 +++++++++++++----- ...ts.java => NoCentralRepoEnabledTests.java} | 35 ++++- 3 files changed, 131 insertions(+), 39 deletions(-) rename Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/{InterCaseTests.java => NoCentralRepoEnabledTests.java} (60%) diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithNoFileTypes.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithNoFileTypes.java index 6e90b856d3..1333ac135f 100644 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithNoFileTypes.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithNoFileTypes.java @@ -76,7 +76,7 @@ public class IngestedWithNoFileTypes extends NbTestCase { ArrayList templates = new ArrayList<>(); templates.add(hashLookupTemplate); - IngestJobSettings ingestJobSettings = new IngestJobSettings(IngestedWithHashAndFileType.class.getCanonicalName(), IngestJobSettings.IngestType.FILES_ONLY, templates); + IngestJobSettings ingestJobSettings = new IngestJobSettings(IngestedWithNoFileTypes.class.getCanonicalName(), IngestJobSettings.IngestType.FILES_ONLY, templates); try { IngestUtils.runIngestJob(Case.getCurrentCaseThrows().getDataSources(), ingestJobSettings); diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/InterCaseUtils.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/InterCaseUtils.java index e1b92de442..ceb587ed8d 100644 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/InterCaseUtils.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/InterCaseUtils.java @@ -19,19 +19,30 @@ */ package org.sleuthkit.autopsy.commonfilessearch; +import java.io.IOException; import java.nio.file.Path; import java.nio.file.Paths; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Map; import org.netbeans.junit.NbTestCase; -import org.openide.util.Exceptions; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.ImageDSProcessor; +import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException; import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbPlatformEnum; import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbUtil; -import org.sleuthkit.autopsy.commonfilesearch.DataSourceLoader; +import org.sleuthkit.autopsy.centralrepository.datamodel.SqliteEamDbSettings; import org.sleuthkit.autopsy.ingest.IngestJobSettings; +import org.sleuthkit.autopsy.ingest.IngestJobSettings.IngestType; +import org.sleuthkit.autopsy.ingest.IngestModuleTemplate; +import org.sleuthkit.autopsy.modules.filetypeid.FileTypeIdModuleFactory; +import org.sleuthkit.autopsy.modules.hashdatabase.HashLookupModuleFactory; import org.sleuthkit.autopsy.testutils.CaseUtils; import org.sleuthkit.autopsy.testutils.IngestUtils; import org.sleuthkit.datamodel.TskCoreException; +import org.python.icu.impl.Assert; +import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; +import org.sleuthkit.autopsy.commonfilesearch.DataSourceLoader; /** * Utilities for testing intercase correlation feature. @@ -69,10 +80,11 @@ import org.sleuthkit.datamodel.TskCoreException; * - Hash-C.pdf * - Hash.D-doc */ -public class InterCaseUtils { +class InterCaseUtils { private static final String CASE_NAME = "InterCaseCommonFilesSearchTest"; - static final Path CASE_DIRECTORY_PATH = Paths.get(System.getProperty("java.io.tmpdir"), CASE_NAME); + private static final Path CASE_DIRECTORY_PATH = Paths.get(System.getProperty("java.io.tmpdir"), CASE_NAME); + private static final String CR_DB_NAME = "testcentralrepo.db"; static final String CASE1 = "Case1"; static final String CASE2 = "Case2"; @@ -103,10 +115,13 @@ public class InterCaseUtils { static final String CASE3_DATASET_1 = "c3ds1.vhd"; static final String CASE3_DATASET_2 = "c3ds2.vhd"; - private final DataSourceLoader dataSourceLoader; private final ImageDSProcessor imageDSProcessor; + + private final IngestJobSettings hashAndFileType; + private final IngestJobSettings hashAndNoFileType; + private DataSourceLoader dataSourceLoader; + - private Case caseReference; InterCaseUtils(NbTestCase testCase){ @@ -117,33 +132,93 @@ public class InterCaseUtils { this.case3DataSet1Path = Paths.get(testCase.getDataDir().toString(), CASE3_DATASET_1); this.case3DataSet2Path = Paths.get(testCase.getDataDir().toString(), CASE3_DATASET_2); - this.dataSourceLoader = new DataSourceLoader(); this.imageDSProcessor = new ImageDSProcessor(); + + final IngestModuleTemplate hashLookupTemplate = IngestUtils.getIngestModuleTemplate(new HashLookupModuleFactory()); + final IngestModuleTemplate mimeTypeLookupTemplate = IngestUtils.getIngestModuleTemplate(new FileTypeIdModuleFactory()); + + ArrayList hashAndMimeTemplate = new ArrayList<>(2); + hashAndMimeTemplate.add(hashLookupTemplate); + hashAndMimeTemplate.add(mimeTypeLookupTemplate); + + this.hashAndFileType = new IngestJobSettings(InterCaseUtils.class.getCanonicalName(), IngestType.FILES_ONLY, hashAndMimeTemplate); + + ArrayList hashAndNoMimeTemplate = new ArrayList<>(1); + hashAndNoMimeTemplate.add(hashLookupTemplate); + + this.hashAndNoFileType = new IngestJobSettings(InterCaseUtils.class.getCanonicalName(), IngestType.FILES_ONLY, hashAndNoMimeTemplate); + + this.dataSourceLoader = new DataSourceLoader(); + } + + Map getDataSourceMap() throws NoCurrentCaseException, TskCoreException, SQLException{ + return this.dataSourceLoader.getDataSourceMap(); + } + + IngestJobSettings getIngestSettingsForHashAndFileType(){ + return this.hashAndFileType; } - void enableCentralRepo(){ + IngestJobSettings getIngestSettingsForHashAndNoFileType(){ + return this.hashAndNoFileType; + } + + void enableCentralRepo() throws EamDbException{ + + SqliteEamDbSettings crSettings = new SqliteEamDbSettings(); + crSettings.setDbName(CR_DB_NAME); + crSettings.setDbDirectory(CASE_DIRECTORY_PATH.toString()); + if(!crSettings.dbDirectoryExists()){ + crSettings.createDbDirectory(); + } + EamDbUtil.setUseCentralRepo(true); EamDbPlatformEnum.setSelectedPlatform(EamDbPlatformEnum.SQLITE.name()); EamDbPlatformEnum.saveSelectedPlatform(); } /** - * Create a case and ingest each with the given settings. Null settings + * Create 3 cases and ingest each with the given settings. Null settings * are permitted but IngestUtils will not be run. * * @param ingestJobSettings HashLookup FileType etc... + * @param caseReferenceToStore */ - void createCases(IngestJobSettings ingestJobSettings){ + Case createCases(IngestJobSettings ingestJobSettings, String caseReferenceToStore) throws TskCoreException{ - try { - this.createCase(CASE1, ingestJobSettings, false, new Path[]{}); - this.createCase(CASE2, ingestJobSettings, false, new Path[]{}); - this.createCase(CASE3, ingestJobSettings, false, new Path[]{}); - this.caseReference = this.createCase(CASE4, ingestJobSettings, true, new Path[]{}); - } catch (TskCoreException ex) { - Exceptions.printStackTrace(ex); - //TODO fail test - } + Case currentCase = null; + + String[] cases = new String[]{ + CASE1, + CASE2, + CASE3}; + + Path[][] paths = { + {this.case1DataSet1Path, this.case1DataSet2Path}, + {this.case2DataSet1Path, this.case2DataSet2Path}, + {this.case3DataSet1Path, this.case3DataSet2Path}}; + + //iterate over the collecitons above, creating cases, and storing + // just one of them for future reference + for(int i = 0; i >= cases.length; i++){ + String caseName = cases[i]; + Path[] pathsForCase = paths[i]; + + if(caseName.equals(caseReferenceToStore)){ + //hang onto this caes and dont close it + currentCase = this.createCase(caseName, ingestJobSettings, true, pathsForCase); + } else { + //dont hang onto this case; close it + this.createCase(caseName, ingestJobSettings, false, pathsForCase); + } + } + + if(currentCase == null) { + Assert.fail(new IllegalArgumentException("caseReferenceToStore should be one of: CASE1, CASE2, CASE3")); + return null; + } else { + return currentCase; + } } private Case createCase(String caseName, IngestJobSettings ingestJobSettings, boolean keepAlive, Path... dataSetPaths) throws TskCoreException{ @@ -164,22 +239,12 @@ public class InterCaseUtils { } /** - * TODO some more cool verbiage - * Could be null if createCases has not yet been run. - * @return + * Close the currently open case, delete the case directory, + * delete the central repo db. */ - Case getCaseReference() throws Exception{ - if(this.caseReference == null){ - throw new Exception("Must run createCases(...) first."); - } else { - return this.caseReference; - } - } - - void tearDown(){ - //close cases - //delete case dirs - //delete central repo db + void tearDown() throws IOException{ + CaseUtils.closeCurrentCase(false); + CaseUtils.deleteCaseDir(CASE_DIRECTORY_PATH.toFile()); } } diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/InterCaseTests.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/NoCentralRepoEnabledTests.java similarity index 60% rename from Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/InterCaseTests.java rename to Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/NoCentralRepoEnabledTests.java index 81f6b00065..7f79c16a8a 100644 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/InterCaseTests.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/NoCentralRepoEnabledTests.java @@ -19,9 +19,14 @@ */ package org.sleuthkit.autopsy.commonfilessearch; +import java.io.IOException; import junit.framework.Test; import org.netbeans.junit.NbModuleSuite; import org.netbeans.junit.NbTestCase; +import org.openide.util.Exceptions; +import org.sleuthkit.datamodel.TskCoreException; +import org.python.icu.impl.Assert; +import org.sleuthkit.autopsy.casemodule.Case; /** * @@ -31,23 +36,45 @@ import org.netbeans.junit.NbTestCase; * 2: No matches If I only search in the current case (existing mode), allowing * all data sources: One node for Hash C (3_1_C.jpg, 3_2_C.jpg) * - * @author bsweeney */ -public class InterCaseTests extends NbTestCase { +public class NoCentralRepoEnabledTests extends NbTestCase { + private final InterCaseUtils utils; + private Case currentCase; + public static Test suite() { - NbModuleSuite.Configuration conf = NbModuleSuite.createConfiguration(InterCaseTests.class). + NbModuleSuite.Configuration conf = NbModuleSuite.createConfiguration(NoCentralRepoEnabledTests.class). clusters(".*"). enableModules(".*"); return conf.suite(); } - public InterCaseTests(String name) { + public NoCentralRepoEnabledTests(String name) { super(name); + this.utils = new InterCaseUtils(this); } @Override public void setUp(){ + try { + this.currentCase = this.utils.createCases(this.utils.getIngestSettingsForHashAndFileType(), InterCaseUtils.CASE1); + } catch (TskCoreException ex) { + Exceptions.printStackTrace(ex); + Assert.fail(ex); + } + } + + @Override + public void tearDown(){ + try { + this.utils.tearDown(); + } catch (IOException ex) { + Exceptions.printStackTrace(ex); + Assert.fail(ex); + } + } + + void testOne(){ } From 06c3577068d65ce5882ecb650af4a929b529e524 Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Mon, 28 May 2018 18:35:54 -0600 Subject: [PATCH 055/287] stubbed in test data file downloads --- Core/build.xml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Core/build.xml b/Core/build.xml index 98644b8cb3..eca218ed5f 100644 --- a/Core/build.xml +++ b/Core/build.xml @@ -100,6 +100,12 @@ + From f129cdc49fe538c1d1642073a456dce041886dca Mon Sep 17 00:00:00 2001 From: Andrew Ziehl Date: Tue, 29 May 2018 09:17:07 -0700 Subject: [PATCH 056/287] Fix for clicking on selected picture/doc filter radio which would previously uncheck the filter checkboxes. Moved error message display so it doesn't dump the search/cancel buttons over to the right of the panel. --- .../commonfilesearch/CommonFilesPanel.form | 22 +++++++++---- .../commonfilesearch/CommonFilesPanel.java | 32 +++++++++++-------- 2 files changed, 33 insertions(+), 21 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.form b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.form index 04ff5ba88b..11d5ad88d4 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.form +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.form @@ -23,19 +23,19 @@ - + - - - - + + + + @@ -46,14 +46,22 @@ + + + + + + + - - + + + diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java index 52a533e796..f8f6818024 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java @@ -502,32 +502,37 @@ public final class CommonFilesPanel extends javax.swing.JPanel { layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addContainerGap() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(commonFilesSearchLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(categoriesLabel) - .addComponent(commonFilesSearchLabel2) .addGroup(layout.createSequentialGroup() .addGap(6, 6, 6) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addGap(21, 21, 21) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(documentsCheckbox) - .addComponent(pictureVideoCheckbox))) + .addComponent(pictureVideoCheckbox) + .addGroup(layout.createSequentialGroup() + .addComponent(documentsCheckbox) + .addContainerGap()))) .addComponent(allFileCategoriesRadioButton) .addComponent(selectedFileCategoriesButton) .addComponent(interCaseRadio) .addComponent(intraCaseRadio) .addGroup(layout.createSequentialGroup() .addGap(10, 10, 10) - .addComponent(layoutPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(layoutPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))) + .addGroup(layout.createSequentialGroup() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(commonFilesSearchLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(categoriesLabel) + .addComponent(commonFilesSearchLabel2) .addGroup(layout.createSequentialGroup() - .addComponent(errorText) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(searchButton) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(cancelButton)))))) + .addComponent(cancelButton) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(errorText))) + .addContainerGap()))) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) @@ -630,11 +635,10 @@ public final class CommonFilesPanel extends javax.swing.JPanel { private void manageCheckBoxState() { + this.pictureViewCheckboxState = this.pictureVideoCheckbox.isSelected(); + this.documentsCheckboxState = this.documentsCheckbox.isSelected(); + if (this.allFileCategoriesRadioButton.isSelected()) { - - this.pictureViewCheckboxState = this.pictureVideoCheckbox.isSelected(); - this.documentsCheckboxState = this.documentsCheckbox.isSelected(); - this.pictureVideoCheckbox.setEnabled(false); this.documentsCheckbox.setEnabled(false); } From d4d6594b4fcaaed115599a7f96d678ecb4d10e7c Mon Sep 17 00:00:00 2001 From: Andrew Ziehl Date: Tue, 29 May 2018 09:39:21 -0700 Subject: [PATCH 057/287] Remove current case before getting datasources for common files case. --- .../sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java index f8f6818024..f691b9bde5 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java @@ -35,6 +35,7 @@ import javax.swing.SwingUtilities; import javax.swing.SwingWorker; import org.openide.explorer.ExplorerManager; import org.openide.util.NbBundle; +import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationCase; import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationDataSource; @@ -356,7 +357,7 @@ public final class CommonFilesPanel extends javax.swing.JPanel { protected Map doInBackground() throws Exception { List dataSources = EamDb.getInstance().getCases(); - + dataSources.remove(EamDb.getInstance().getCase(Case.getCurrentCase())); Map caseMap = mapDataSources(dataSources); return caseMap; From 13ca2ad8afe6db70d4db280c6ee63a4845f8eea3 Mon Sep 17 00:00:00 2001 From: Andrew Ziehl Date: Tue, 29 May 2018 10:00:29 -0700 Subject: [PATCH 058/287] Fix for removing current correlation case from common files data sources. --- .../autopsy/commonfilesearch/CommonFilesPanel.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java index f691b9bde5..1cc810e08c 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java @@ -343,11 +343,13 @@ public final class CommonFilesPanel extends javax.swing.JPanel { } } - private Map mapDataSources(List cases) { + private Map mapDataSources(List cases) throws Exception { Map casemap = new HashMap<>(); - + CorrelationCase currentCorCase = EamDb.getInstance().getCase(Case.getCurrentCase()); for (CorrelationCase correlationCase : cases) { - casemap.put(correlationCase.getID(), correlationCase.getDisplayName()); + if(currentCorCase.getID() != correlationCase.getID()) { // if not the current Case + casemap.put(correlationCase.getID(), correlationCase.getDisplayName()); + } } return casemap; @@ -357,7 +359,6 @@ public final class CommonFilesPanel extends javax.swing.JPanel { protected Map doInBackground() throws Exception { List dataSources = EamDb.getInstance().getCases(); - dataSources.remove(EamDb.getInstance().getCase(Case.getCurrentCase())); Map caseMap = mapDataSources(dataSources); return caseMap; From a8c16bb2f7df6ad6dba7d1004f936c809e6b9572 Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Tue, 29 May 2018 19:11:25 -0600 Subject: [PATCH 059/287] test code --- .../EamDbCommonFilesAlgorithm.java | 11 +- .../IngestedWithNoFileTypes.java | 1 + .../commonfilessearch/InterCaseUtils.java | 155 ++++++++++-------- .../commonfilessearch/IntraCaseUtils.java | 5 + .../NoCentralRepoEnabledTests.java | 36 +++- 5 files changed, 131 insertions(+), 77 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbCommonFilesAlgorithm.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbCommonFilesAlgorithm.java index 898da0c9ed..afed7d4758 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbCommonFilesAlgorithm.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbCommonFilesAlgorithm.java @@ -76,9 +76,14 @@ public abstract class EamDbCommonFilesAlgorithm extends CommonFilesMetadataBuild Map interCaseCommonFiles = new HashMap<>(); try { - - Collection artifactInstances = dbManager.getArtifactInstancesByCaseValues(correlationCase, values).stream() - .collect(Collectors.toList()); + Collection artifactInstances; + if(this.dbManager == null){ + artifactInstances = new ArrayList<>(0); + } else { + artifactInstances = dbManager.getArtifactInstancesByCaseValues(correlationCase, values).stream() + .collect(Collectors.toList()); + } + interCaseCommonFiles = gatherIntercaseResults(artifactInstances, currentCaseMetadata); } catch (EamDbException ex) { diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithNoFileTypes.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithNoFileTypes.java index 1333ac135f..8606843a28 100644 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithNoFileTypes.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithNoFileTypes.java @@ -110,6 +110,7 @@ public class IngestedWithNoFileTypes extends NbTestCase { } catch (Exception ex) { Exceptions.printStackTrace(ex); + Assert.fail(ex); } } diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/InterCaseUtils.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/InterCaseUtils.java index ceb587ed8d..e83e5cbe37 100644 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/InterCaseUtils.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/InterCaseUtils.java @@ -24,6 +24,8 @@ import java.nio.file.Path; import java.nio.file.Paths; import java.sql.SQLException; import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; import java.util.Map; import org.netbeans.junit.NbTestCase; import org.sleuthkit.autopsy.casemodule.Case; @@ -42,6 +44,8 @@ import org.sleuthkit.autopsy.testutils.IngestUtils; import org.sleuthkit.datamodel.TskCoreException; import org.python.icu.impl.Assert; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; +import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationCase; +import org.sleuthkit.autopsy.centralrepository.datamodel.EamDb; import org.sleuthkit.autopsy.commonfilesearch.DataSourceLoader; /** @@ -81,7 +85,7 @@ import org.sleuthkit.autopsy.commonfilesearch.DataSourceLoader; * - Hash.D-doc */ class InterCaseUtils { - + private static final String CASE_NAME = "InterCaseCommonFilesSearchTest"; private static final Path CASE_DIRECTORY_PATH = Paths.get(System.getProperty("java.io.tmpdir"), CASE_NAME); private static final String CR_DB_NAME = "testcentralrepo.db"; @@ -90,14 +94,14 @@ class InterCaseUtils { static final String CASE2 = "Case2"; static final String CASE3 = "Case3"; static final String CASE4 = "Case4"; - + final Path case1DataSet1Path; final Path case1DataSet2Path; final Path case2DataSet1Path; final Path case2DataSet2Path; final Path case3DataSet1Path; final Path case3DataSet2Path; - + static final String HASH_0_DAT = "Hash-0.dat"; static final String HASH_A_JPG = "Hash-A.jpg"; static final String HASH_A_PDF = "Hash-A.pdf"; @@ -107,144 +111,165 @@ class InterCaseUtils { static final String HASH_C_PDF = "Hash-C.pdf"; static final String HASH_D_JPG = "Hash-D.jpg"; static final String HASH_D_DOC = "Hash-D.doc"; - - static final String CASE1_DATASET_1 = "c1ds1.vhd"; - static final String CASE1_DATASET_2 = "c1ds2.vhd"; - static final String CASE2_DATASET_1 = "c2ds1.vhd"; - static final String CASE2_DATASET_2 = "c2ds2.vhd"; - static final String CASE3_DATASET_1 = "c3ds1.vhd"; - static final String CASE3_DATASET_2 = "c3ds2.vhd"; - + + static final String CASE1_DATASET_1 = "c1ds1_v1.vhd"; + static final String CASE1_DATASET_2 = "c1ds2_v1.vhd"; + static final String CASE2_DATASET_1 = "c2ds1_v1.vhd"; + static final String CASE2_DATASET_2 = "c2ds2_v1.vhd"; + static final String CASE3_DATASET_1 = "c3ds1_v1.vhd"; + static final String CASE3_DATASET_2 = "c3ds2_v1.vhd"; + private final ImageDSProcessor imageDSProcessor; - + private final IngestJobSettings hashAndFileType; private final IngestJobSettings hashAndNoFileType; - private DataSourceLoader dataSourceLoader; - - - - InterCaseUtils(NbTestCase testCase){ - + private final DataSourceLoader dataSourceLoader; + + InterCaseUtils(NbTestCase testCase) { + this.case1DataSet1Path = Paths.get(testCase.getDataDir().toString(), CASE1_DATASET_1); this.case1DataSet2Path = Paths.get(testCase.getDataDir().toString(), CASE1_DATASET_2); this.case2DataSet1Path = Paths.get(testCase.getDataDir().toString(), CASE1_DATASET_1); this.case2DataSet2Path = Paths.get(testCase.getDataDir().toString(), CASE2_DATASET_2); this.case3DataSet1Path = Paths.get(testCase.getDataDir().toString(), CASE3_DATASET_1); this.case3DataSet2Path = Paths.get(testCase.getDataDir().toString(), CASE3_DATASET_2); - + this.imageDSProcessor = new ImageDSProcessor(); - + final IngestModuleTemplate hashLookupTemplate = IngestUtils.getIngestModuleTemplate(new HashLookupModuleFactory()); final IngestModuleTemplate mimeTypeLookupTemplate = IngestUtils.getIngestModuleTemplate(new FileTypeIdModuleFactory()); - + ArrayList hashAndMimeTemplate = new ArrayList<>(2); hashAndMimeTemplate.add(hashLookupTemplate); hashAndMimeTemplate.add(mimeTypeLookupTemplate); - + this.hashAndFileType = new IngestJobSettings(InterCaseUtils.class.getCanonicalName(), IngestType.FILES_ONLY, hashAndMimeTemplate); - + ArrayList hashAndNoMimeTemplate = new ArrayList<>(1); hashAndNoMimeTemplate.add(hashLookupTemplate); - + this.hashAndNoFileType = new IngestJobSettings(InterCaseUtils.class.getCanonicalName(), IngestType.FILES_ONLY, hashAndNoMimeTemplate); - + this.dataSourceLoader = new DataSourceLoader(); } - - Map getDataSourceMap() throws NoCurrentCaseException, TskCoreException, SQLException{ + + Map getDataSourceMap() throws NoCurrentCaseException, TskCoreException, SQLException { return this.dataSourceLoader.getDataSourceMap(); } - - IngestJobSettings getIngestSettingsForHashAndFileType(){ + + Map getCaseMap() throws EamDbException { + + if (EamDb.isEnabled()) { + Map mapOfCaseIdsToCase = new HashMap<>(); + + for (CorrelationCase caze : EamDb.getInstance().getCases()) { + mapOfCaseIdsToCase.put(caze.getID(), caze.getDisplayName()); + } + return mapOfCaseIdsToCase; + } else { + //it is reasonable that this might happen... + // for example when we test the feature in the absence of an enabled eamdb + return new HashMap(0); + } + } + + IngestJobSettings getIngestSettingsForHashAndFileType() { return this.hashAndFileType; } - - IngestJobSettings getIngestSettingsForHashAndNoFileType(){ + + IngestJobSettings getIngestSettingsForHashAndNoFileType() { return this.hashAndNoFileType; } - - void enableCentralRepo() throws EamDbException{ - + + void enableCentralRepo() throws EamDbException { + SqliteEamDbSettings crSettings = new SqliteEamDbSettings(); crSettings.setDbName(CR_DB_NAME); crSettings.setDbDirectory(CASE_DIRECTORY_PATH.toString()); - if(!crSettings.dbDirectoryExists()){ + if (!crSettings.dbDirectoryExists()) { crSettings.createDbDirectory(); } - + EamDbUtil.setUseCentralRepo(true); EamDbPlatformEnum.setSelectedPlatform(EamDbPlatformEnum.SQLITE.name()); EamDbPlatformEnum.saveSelectedPlatform(); } - + /** - * Create 3 cases and ingest each with the given settings. Null settings - * are permitted but IngestUtils will not be run. - * + * Create 3 cases and ingest each with the given settings. Null settings are + * permitted but IngestUtils will not be run. + * * @param ingestJobSettings HashLookup FileType etc... - * @param caseReferenceToStore + * @param caseReferenceToStore */ - Case createCases(IngestJobSettings ingestJobSettings, String caseReferenceToStore) throws TskCoreException{ - + Case createCases(IngestJobSettings ingestJobSettings, String caseReferenceToStore) throws TskCoreException { + Case currentCase = null; - + String[] cases = new String[]{ - CASE1, - CASE2, + CASE1, + CASE2, CASE3}; - + Path[][] paths = { {this.case1DataSet1Path, this.case1DataSet2Path}, {this.case2DataSet1Path, this.case2DataSet2Path}, {this.case3DataSet1Path, this.case3DataSet2Path}}; + String lastCaseName = null; + Path[] lastPathsForCase = null; //iterate over the collecitons above, creating cases, and storing // just one of them for future reference - for(int i = 0; i >= cases.length; i++){ + for (int i = 0; i < cases.length; i++) { String caseName = cases[i]; Path[] pathsForCase = paths[i]; - if(caseName.equals(caseReferenceToStore)){ - //hang onto this caes and dont close it - currentCase = this.createCase(caseName, ingestJobSettings, true, pathsForCase); + if (caseName.equals(caseReferenceToStore)) { + //put aside and do this one last so we can hang onto the case + lastCaseName = caseName; + lastPathsForCase = pathsForCase; } else { //dont hang onto this case; close it this.createCase(caseName, ingestJobSettings, false, pathsForCase); } } - - if(currentCase == null) { + + if (lastCaseName != null && lastPathsForCase != null) { + //hang onto this caes and dont close it + currentCase = this.createCase(lastCaseName, ingestJobSettings, true, lastPathsForCase); + } + + if (currentCase == null) { Assert.fail(new IllegalArgumentException("caseReferenceToStore should be one of: CASE1, CASE2, CASE3")); return null; } else { return currentCase; } } - - private Case createCase(String caseName, IngestJobSettings ingestJobSettings, boolean keepAlive, Path... dataSetPaths) throws TskCoreException{ - + + private Case createCase(String caseName, IngestJobSettings ingestJobSettings, boolean keepAlive, Path... dataSetPaths) throws TskCoreException { + Case caze = CaseUtils.createAsCurrentCase(caseName); - for(Path dataSetPath : dataSetPaths){ + for (Path dataSetPath : dataSetPaths) { IngestUtils.addDataSource(this.imageDSProcessor, dataSetPath); } - if(ingestJobSettings != null){ + if (ingestJobSettings != null) { IngestUtils.runIngestJob(caze.getDataSources(), ingestJobSettings); } - if(keepAlive){ - return caze; + if (keepAlive) { + return caze; } else { CaseUtils.closeCurrentCase(false); return null; } } - + /** - * Close the currently open case, delete the case directory, - * delete the central repo db. + * Close the currently open case, delete the case directory, delete the + * central repo db. */ - void tearDown() throws IOException{ + void tearDown() throws IOException { CaseUtils.closeCurrentCase(false); CaseUtils.deleteCaseDir(CASE_DIRECTORY_PATH.toFile()); } - } diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IntraCaseUtils.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IntraCaseUtils.java index 4e23ecffa2..b6d27f078e 100644 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IntraCaseUtils.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IntraCaseUtils.java @@ -176,6 +176,11 @@ class IntraCaseUtils { return verifyFileExistanceAndCount(files, objectIdToDataSource, name, dataSource, 1); } + /** + * TODO + * @param metadata + * @return + */ static Map mapFileInstancesToDataSources(CommonFilesMetadata metadata) { Map instanceIdToDataSource = new HashMap<>(); diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/NoCentralRepoEnabledTests.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/NoCentralRepoEnabledTests.java index 7f79c16a8a..6db32eb4fa 100644 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/NoCentralRepoEnabledTests.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/NoCentralRepoEnabledTests.java @@ -20,6 +20,8 @@ package org.sleuthkit.autopsy.commonfilessearch; import java.io.IOException; +import java.sql.SQLException; +import java.util.Map; import junit.framework.Test; import org.netbeans.junit.NbModuleSuite; import org.netbeans.junit.NbTestCase; @@ -27,6 +29,12 @@ import org.openide.util.Exceptions; import org.sleuthkit.datamodel.TskCoreException; import org.python.icu.impl.Assert; import org.sleuthkit.autopsy.casemodule.Case; +import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; +import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException; +import org.sleuthkit.autopsy.commonfilesearch.AllCasesEamDbCommonFilesAlgorithm; +import org.sleuthkit.autopsy.commonfilesearch.CommonFilesMetadata; +import org.sleuthkit.autopsy.commonfilesearch.CommonFilesMetadataBuilder; +import org.sleuthkit.autopsy.commonfilesearch.SingleCaseEamDbCommonFilesAlgorithm; /** * @@ -41,7 +49,7 @@ public class NoCentralRepoEnabledTests extends NbTestCase { private final InterCaseUtils utils; private Case currentCase; - + public static Test suite() { NbModuleSuite.Configuration conf = NbModuleSuite.createConfiguration(NoCentralRepoEnabledTests.class). clusters(".*"). @@ -53,9 +61,9 @@ public class NoCentralRepoEnabledTests extends NbTestCase { super(name); this.utils = new InterCaseUtils(this); } - + @Override - public void setUp(){ + public void setUp() { try { this.currentCase = this.utils.createCases(this.utils.getIngestSettingsForHashAndFileType(), InterCaseUtils.CASE1); } catch (TskCoreException ex) { @@ -63,9 +71,9 @@ public class NoCentralRepoEnabledTests extends NbTestCase { Assert.fail(ex); } } - + @Override - public void tearDown(){ + public void tearDown() { try { this.utils.tearDown(); } catch (IOException ex) { @@ -73,9 +81,19 @@ public class NoCentralRepoEnabledTests extends NbTestCase { Assert.fail(ex); } } - - void testOne(){ - - } + public void testOne() { + try { + Map dataSources = this.utils.getDataSourceMap(); + + CommonFilesMetadataBuilder builder = new AllCasesEamDbCommonFilesAlgorithm(dataSources, false, false); + + CommonFilesMetadata metadata = builder.findFiles(); + + assertTrue("Should be no results.", metadata.size() == 0); + } catch (Exception ex) { + Exceptions.printStackTrace(ex); + Assert.fail(ex); + } + } } From 730d3075a26f0a138653f7ec4b80e46076212a84 Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Tue, 29 May 2018 20:02:56 -0600 Subject: [PATCH 060/287] some renames and cleanups and a new test stub --- ...stedWithHashAndFileTypeInterCaseTests.java | 69 +++++++++++++++++++ ...tedWithHashAndFileTypeIntraCaseTests.java} | 8 +-- ...ngestedWithNoFileTypesIntraCaseTests.java} | 8 +-- .../commonfilessearch/InterCaseUtils.java | 10 ++- ...> NoCentralRepoEnabledInterCaseTests.java} | 27 +++----- ...ava => UningestedCasesIntraCaseTests.java} | 6 +- 6 files changed, 96 insertions(+), 32 deletions(-) create mode 100644 Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileTypeInterCaseTests.java rename Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/{IngestedWithHashAndFileType.java => IngestedWithHashAndFileTypeIntraCaseTests.java} (98%) rename Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/{IngestedWithNoFileTypes.java => IngestedWithNoFileTypesIntraCaseTests.java} (93%) rename Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/{NoCentralRepoEnabledTests.java => NoCentralRepoEnabledInterCaseTests.java} (71%) rename Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/{UningestedCases.java => UningestedCasesIntraCaseTests.java} (95%) diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileTypeInterCaseTests.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileTypeInterCaseTests.java new file mode 100644 index 0000000000..7bd7b7ab74 --- /dev/null +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileTypeInterCaseTests.java @@ -0,0 +1,69 @@ +/* + * + * Autopsy Forensic Browser + * + * Copyright 2018 Basis Technology Corp. + * Contact: carrier sleuthkit 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.commonfilessearch; + +import junit.framework.Test; +import org.netbeans.junit.NbModuleSuite; +import org.netbeans.junit.NbTestCase; +import org.openide.util.Exceptions; +import org.python.icu.impl.Assert; +import org.sleuthkit.autopsy.casemodule.Case; +import org.sleuthkit.datamodel.TskCoreException; + +/** + * If I use the search all cases option: One node for Hash A (1_1_A.jpg, + * 1_2_A.jpg, 3_1_A.jpg) If I search for matches only in Case 1: One node for + * Hash A (1_1_A.jpg, 1_2_A.jpg, 3_1_A.jpg) If I search for matches only in Case + * 2: No matches If I only search in the current case (existing mode), allowing + * all data sources: One node for Hash C (3_1_C.jpg, 3_2_C.jpg) + */ +public class IngestedWithHashAndFileTypeInterCaseTests extends NbTestCase { + + private final InterCaseUtils utils; + + private Case currentCase; + + public static Test suite() { + NbModuleSuite.Configuration conf = NbModuleSuite.createConfiguration(IngestedWithHashAndFileTypeInterCaseTests.class). + clusters(".*"). + enableModules(".*"); + return conf.suite(); + } + + public IngestedWithHashAndFileTypeInterCaseTests(String name) { + super(name); + this.utils = new InterCaseUtils(this); + } + + @Override + public void setUp(){ + try { + this.currentCase = this.utils.createCases(this.utils.getIngestSettingsForHashAndFileType(), InterCaseUtils.CASE1); + } catch (TskCoreException ex) { + Exceptions.printStackTrace(ex); + Assert.fail(ex); + } + } + + @Override + public void tearDown(){ + this.utils.tearDown(); + } +} diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileType.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileTypeIntraCaseTests.java similarity index 98% rename from Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileType.java rename to Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileTypeIntraCaseTests.java index c44fe079ae..7bac039bc7 100644 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileType.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileTypeIntraCaseTests.java @@ -46,10 +46,10 @@ import org.sleuthkit.datamodel.TskCoreException; /** * Add set 1, set 2, set 3, and set 4 to case and ingest with hash algorithm. */ -public class IngestedWithHashAndFileType extends NbTestCase { +public class IngestedWithHashAndFileTypeIntraCaseTests extends NbTestCase { public static Test suite() { - NbModuleSuite.Configuration conf = NbModuleSuite.createConfiguration(IngestedWithHashAndFileType.class). + NbModuleSuite.Configuration conf = NbModuleSuite.createConfiguration(IngestedWithHashAndFileTypeIntraCaseTests.class). clusters(".*"). enableModules(".*"); return conf.suite(); @@ -57,7 +57,7 @@ public class IngestedWithHashAndFileType extends NbTestCase { private final IntraCaseUtils utils; - public IngestedWithHashAndFileType(String name) { + public IngestedWithHashAndFileTypeIntraCaseTests(String name) { super(name); this.utils = new IntraCaseUtils(this, "IngestedWithHashAndFileTypeTests"); @@ -74,7 +74,7 @@ public class IngestedWithHashAndFileType extends NbTestCase { templates.add(hashLookupTemplate); templates.add(mimeTypeLookupTemplate); - IngestJobSettings ingestJobSettings = new IngestJobSettings(IngestedWithHashAndFileType.class.getCanonicalName(), IngestType.FILES_ONLY, templates); + IngestJobSettings ingestJobSettings = new IngestJobSettings(IngestedWithHashAndFileTypeIntraCaseTests.class.getCanonicalName(), IngestType.FILES_ONLY, templates); try { IngestUtils.runIngestJob(Case.getCurrentCaseThrows().getDataSources(), ingestJobSettings); diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithNoFileTypes.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithNoFileTypesIntraCaseTests.java similarity index 93% rename from Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithNoFileTypes.java rename to Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithNoFileTypesIntraCaseTests.java index 8606843a28..4d14417efc 100644 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithNoFileTypes.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithNoFileTypesIntraCaseTests.java @@ -50,10 +50,10 @@ import org.sleuthkit.datamodel.TskCoreException; * Add images set 1, set 2, set 3, and set 4 to case. Do not run mime type * module. */ -public class IngestedWithNoFileTypes extends NbTestCase { +public class IngestedWithNoFileTypesIntraCaseTests extends NbTestCase { public static Test suite() { - NbModuleSuite.Configuration conf = NbModuleSuite.createConfiguration(IngestedWithNoFileTypes.class). + NbModuleSuite.Configuration conf = NbModuleSuite.createConfiguration(IngestedWithNoFileTypesIntraCaseTests.class). clusters(".*"). enableModules(".*"); return conf.suite(); @@ -61,7 +61,7 @@ public class IngestedWithNoFileTypes extends NbTestCase { private final IntraCaseUtils utils; - public IngestedWithNoFileTypes(String name) { + public IngestedWithNoFileTypesIntraCaseTests(String name) { super(name); this.utils = new IntraCaseUtils(this, "IngestedWithNoFileTypes"); @@ -76,7 +76,7 @@ public class IngestedWithNoFileTypes extends NbTestCase { ArrayList templates = new ArrayList<>(); templates.add(hashLookupTemplate); - IngestJobSettings ingestJobSettings = new IngestJobSettings(IngestedWithNoFileTypes.class.getCanonicalName(), IngestJobSettings.IngestType.FILES_ONLY, templates); + IngestJobSettings ingestJobSettings = new IngestJobSettings(IngestedWithNoFileTypesIntraCaseTests.class.getCanonicalName(), IngestJobSettings.IngestType.FILES_ONLY, templates); try { IngestUtils.runIngestJob(Case.getCurrentCaseThrows().getDataSources(), ingestJobSettings); diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/InterCaseUtils.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/InterCaseUtils.java index e83e5cbe37..ceeab33959 100644 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/InterCaseUtils.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/InterCaseUtils.java @@ -28,6 +28,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import org.netbeans.junit.NbTestCase; +import org.openide.util.Exceptions; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.ImageDSProcessor; import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException; @@ -268,8 +269,13 @@ class InterCaseUtils { * Close the currently open case, delete the case directory, delete the * central repo db. */ - void tearDown() throws IOException { + void tearDown() { CaseUtils.closeCurrentCase(false); - CaseUtils.deleteCaseDir(CASE_DIRECTORY_PATH.toFile()); + try { + CaseUtils.deleteCaseDir(CASE_DIRECTORY_PATH.toFile()); + } catch (IOException ex) { + Exceptions.printStackTrace(ex); + Assert.fail(ex); + } } } diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/NoCentralRepoEnabledTests.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/NoCentralRepoEnabledInterCaseTests.java similarity index 71% rename from Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/NoCentralRepoEnabledTests.java rename to Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/NoCentralRepoEnabledInterCaseTests.java index 6db32eb4fa..276229213a 100644 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/NoCentralRepoEnabledTests.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/NoCentralRepoEnabledInterCaseTests.java @@ -20,7 +20,6 @@ package org.sleuthkit.autopsy.commonfilessearch; import java.io.IOException; -import java.sql.SQLException; import java.util.Map; import junit.framework.Test; import org.netbeans.junit.NbModuleSuite; @@ -29,35 +28,30 @@ import org.openide.util.Exceptions; import org.sleuthkit.datamodel.TskCoreException; import org.python.icu.impl.Assert; import org.sleuthkit.autopsy.casemodule.Case; -import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; -import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException; import org.sleuthkit.autopsy.commonfilesearch.AllCasesEamDbCommonFilesAlgorithm; import org.sleuthkit.autopsy.commonfilesearch.CommonFilesMetadata; import org.sleuthkit.autopsy.commonfilesearch.CommonFilesMetadataBuilder; -import org.sleuthkit.autopsy.commonfilesearch.SingleCaseEamDbCommonFilesAlgorithm; /** * - * If I use the search all cases option: One node for Hash A (1_1_A.jpg, - * 1_2_A.jpg, 3_1_A.jpg) If I search for matches only in Case 1: One node for - * Hash A (1_1_A.jpg, 1_2_A.jpg, 3_1_A.jpg) If I search for matches only in Case - * 2: No matches If I only search in the current case (existing mode), allowing - * all data sources: One node for Hash C (3_1_C.jpg, 3_2_C.jpg) + * Just make sure nothing explodes when we run the feature in the absence of + * the Central Repo. This should be considered 'defensive' as it should not be + * possible to even run the feature if the CR is not available. * */ -public class NoCentralRepoEnabledTests extends NbTestCase { +public class NoCentralRepoEnabledInterCaseTests extends NbTestCase { private final InterCaseUtils utils; - private Case currentCase; + private Case currentCase; //TODO do we need this??? public static Test suite() { - NbModuleSuite.Configuration conf = NbModuleSuite.createConfiguration(NoCentralRepoEnabledTests.class). + NbModuleSuite.Configuration conf = NbModuleSuite.createConfiguration(NoCentralRepoEnabledInterCaseTests.class). clusters(".*"). enableModules(".*"); return conf.suite(); } - public NoCentralRepoEnabledTests(String name) { + public NoCentralRepoEnabledInterCaseTests(String name) { super(name); this.utils = new InterCaseUtils(this); } @@ -74,12 +68,7 @@ public class NoCentralRepoEnabledTests extends NbTestCase { @Override public void tearDown() { - try { - this.utils.tearDown(); - } catch (IOException ex) { - Exceptions.printStackTrace(ex); - Assert.fail(ex); - } + this.utils.tearDown(); } public void testOne() { diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/UningestedCases.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/UningestedCasesIntraCaseTests.java similarity index 95% rename from Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/UningestedCases.java rename to Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/UningestedCasesIntraCaseTests.java index c0e12d2034..2b68f4371e 100644 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/UningestedCases.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/UningestedCasesIntraCaseTests.java @@ -42,10 +42,10 @@ import static org.sleuthkit.autopsy.commonfilessearch.IntraCaseUtils.getDataSour * Add images set 1, set 2, set 3, and set 4 to case. Do not ingest. * */ -public class UningestedCases extends NbTestCase { +public class UningestedCasesIntraCaseTests extends NbTestCase { public static Test suite() { - NbModuleSuite.Configuration conf = NbModuleSuite.createConfiguration(UningestedCases.class). + NbModuleSuite.Configuration conf = NbModuleSuite.createConfiguration(UningestedCasesIntraCaseTests.class). clusters(".*"). enableModules(".*"); return conf.suite(); @@ -53,7 +53,7 @@ public class UningestedCases extends NbTestCase { private final IntraCaseUtils utils; - public UningestedCases(String name) { + public UningestedCasesIntraCaseTests(String name) { super(name); this.utils = new IntraCaseUtils(this, "UningestedCasesTests"); From 213301e545c2116c13afee9a10499f9d3d104283 Mon Sep 17 00:00:00 2001 From: Andrew Ziehl Date: Wed, 30 May 2018 12:26:12 -0700 Subject: [PATCH 061/287] Add progress handler to search to inform user Autopsy is busy, with 3 stages. --- .../commonfilesearch/CommonFilesPanel.java | 27 ++++++++++--------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java index 1cc810e08c..14fd28ab02 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java @@ -18,27 +18,22 @@ */ package org.sleuthkit.autopsy.commonfilesearch; -import java.awt.event.ActionEvent; -import java.io.File; -import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Map.Entry; import java.util.concurrent.ExecutionException; import java.util.logging.Level; -import javax.swing.ComboBoxModel; import javax.swing.SwingUtilities; import javax.swing.SwingWorker; +import org.netbeans.api.progress.ProgressHandle; import org.openide.explorer.ExplorerManager; import org.openide.util.NbBundle; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; 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.corecomponentinterfaces.DataResultViewer; @@ -48,8 +43,6 @@ import org.sleuthkit.autopsy.corecomponents.TableFilterNode; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil; import org.sleuthkit.autopsy.directorytree.DataResultFilterNode; -import org.sleuthkit.datamodel.SleuthkitCase; -import org.sleuthkit.datamodel.SleuthkitCase.CaseDbQuery; import org.sleuthkit.datamodel.TskCoreException; /** @@ -111,6 +104,9 @@ public final class CommonFilesPanel extends javax.swing.JPanel { "CommonFilesPanel.search.results.titleAll=Common Files (All Data Sources)", "CommonFilesPanel.search.results.titleSingle=Common Files (Match Within Data Source: %s)", "CommonFilesPanel.search.results.pathText=Common Files Search Results", + "CommonFilesPanel.search.done.searchProgress1=Gathering Common Files Search Results.", + "CommonFilesPanel.search.done.searchProgress2=Generating Common Files Search Results.", + "CommonFilesPanel.search.done.searchProgress3=Displaying Common Files Search Results.", "CommonFilesPanel.search.done.tskCoreException=Unable to run query against DB.", "CommonFilesPanel.search.done.noCurrentCaseException=Unable to open case file.", "CommonFilesPanel.search.done.exception=Unexpected exception running Common Files Search.", @@ -122,7 +118,8 @@ public final class CommonFilesPanel extends javax.swing.JPanel { new SwingWorker() { private String tabTitle; - + private ProgressHandle progress; + private void setTitleForAllDataSources() { this.tabTitle = Bundle.CommonFilesPanel_search_results_titleAll(); } @@ -145,6 +142,10 @@ public final class CommonFilesPanel extends javax.swing.JPanel { @Override @SuppressWarnings({"BoxedValueEquality", "NumberEquality"}) protected CommonFilesMetadata doInBackground() throws TskCoreException, NoCurrentCaseException, SQLException, EamDbException, Exception { + progress = ProgressHandle.createHandle(Bundle.CommonFilesPanel_search_done_searchProgress1()); + progress.start(); + progress.switchToIndeterminate(); + Long dataSourceId = CommonFilesPanel.this.intraCasePanel.getSelectedDataSourceId(); Integer caseId = CommonFilesPanel.this.interCasePanel.getSelectedCaseId(); @@ -194,8 +195,8 @@ public final class CommonFilesPanel extends javax.swing.JPanel { protected void done() { try { super.done(); - - CommonFilesMetadata metadata = get(); + progress.setDisplayName(Bundle.CommonFilesPanel_search_done_searchProgress2()); + CommonFilesMetadata metadata = get(); CommonFilesNode commonFilesNode = new CommonFilesNode(metadata); @@ -207,9 +208,9 @@ public final class CommonFilesPanel extends javax.swing.JPanel { Collection viewers = new ArrayList<>(1); viewers.add(table); - + progress.setDisplayName(Bundle.CommonFilesPanel_search_done_searchProgress3()); DataResultTopComponent.createInstance(tabTitle, pathText, tableFilterWithDescendantsNode, metadata.size(), viewers); - + progress.finish(); } catch (InterruptedException ex) { LOGGER.log(Level.SEVERE, "Interrupted while loading Common Files", ex); MessageNotifyUtil.Message.error(Bundle.CommonFilesPanel_search_done_interupted()); From 78d51d001ab8f3a48244def1186dfd667e13f200 Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Wed, 30 May 2018 15:50:05 -0600 Subject: [PATCH 062/287] had to initialize cr db and save settings --- .../sleuthkit/autopsy/commonfilessearch/InterCaseUtils.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/InterCaseUtils.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/InterCaseUtils.java index ceeab33959..bb606352dc 100644 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/InterCaseUtils.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/InterCaseUtils.java @@ -190,6 +190,11 @@ class InterCaseUtils { if (!crSettings.dbDirectoryExists()) { crSettings.createDbDirectory(); } + + crSettings.initializeDatabaseSchema(); + crSettings.insertDefaultDatabaseContent(); + + crSettings.saveSettings(); EamDbUtil.setUseCentralRepo(true); EamDbPlatformEnum.setSelectedPlatform(EamDbPlatformEnum.SQLITE.name()); From 3989cb44f23d55e6ce91a7b22543d46a347b58e8 Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Wed, 30 May 2018 15:50:47 -0600 Subject: [PATCH 063/287] test one stub --- ...stedWithHashAndFileTypeInterCaseTests.java | 48 ++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileTypeInterCaseTests.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileTypeInterCaseTests.java index 7bd7b7ab74..5506a0aa6a 100644 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileTypeInterCaseTests.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileTypeInterCaseTests.java @@ -19,12 +19,19 @@ */ package org.sleuthkit.autopsy.commonfilessearch; +import java.sql.SQLException; +import java.util.Map; import junit.framework.Test; import org.netbeans.junit.NbModuleSuite; import org.netbeans.junit.NbTestCase; import org.openide.util.Exceptions; import org.python.icu.impl.Assert; import org.sleuthkit.autopsy.casemodule.Case; +import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; +import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException; +import org.sleuthkit.autopsy.commonfilesearch.AllCasesEamDbCommonFilesAlgorithm; +import org.sleuthkit.autopsy.commonfilesearch.CommonFilesMetadata; +import org.sleuthkit.autopsy.commonfilesearch.CommonFilesMetadataBuilder; import org.sleuthkit.datamodel.TskCoreException; /** @@ -55,8 +62,9 @@ public class IngestedWithHashAndFileTypeInterCaseTests extends NbTestCase { @Override public void setUp(){ try { + this.utils.enableCentralRepo(); this.currentCase = this.utils.createCases(this.utils.getIngestSettingsForHashAndFileType(), InterCaseUtils.CASE1); - } catch (TskCoreException ex) { + } catch (Exception ex) { Exceptions.printStackTrace(ex); Assert.fail(ex); } @@ -66,4 +74,42 @@ public class IngestedWithHashAndFileTypeInterCaseTests extends NbTestCase { public void tearDown(){ this.utils.tearDown(); } + + /** + * Search All + * + * One node for Hash A (1_1_A.jpg, 1_2_A.jpg, 3_1_A.jpg) + */ + public void testOne() { + try { + Map dataSources = this.utils.getDataSourceMap(); + + CommonFilesMetadataBuilder builder = new AllCasesEamDbCommonFilesAlgorithm(dataSources, false, false); + + CommonFilesMetadata metadata = builder.findFiles(); + + assertTrue("", metadata.size() != 0); + + + } catch (Exception ex) { + Exceptions.printStackTrace(ex); + Assert.fail(ex); + } + + + } + + /** + * Case1 + */ + public void testTwo(){ + + } + + /** + * Case2 + */ + public void testThree(){ + + } } From 4c529e297300cf649bac2c5e4147401954319227 Mon Sep 17 00:00:00 2001 From: Andrew Ziehl Date: Wed, 30 May 2018 16:21:13 -0700 Subject: [PATCH 064/287] Fix for PreparedStatement limited to 32k ? variable replacements. --- .../datamodel/AbstractSqlEamDb.java | 21 +++++++++++-------- .../AllDataSourcesCommonFilesAlgorithm.java | 2 +- .../commonfilesearch/CommonFilesPanel.java | 2 +- 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java index dc1dd25139..151c729acd 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java @@ -693,11 +693,18 @@ public abstract class AbstractSqlEamDb implements EamDb { sql.append(" LEFT JOIN data_sources ON "); sql.append(tableName); sql.append(".data_source_id=data_sources.id"); - sql.append(" WHERE value IN (SELECT value FROM file_instances WHERE value IN ("); - - for (int i = 0; i < values.size(); i++) { - sql.append("?,"); + sql.append(" WHERE value IN (SELECT value FROM "); + sql.append(tableName); + sql.append(" WHERE value IN ("); + + // Note: PreparedStatement has a limit on ? variable replacement so instead query is built with values appended directly into the string + for (String value : values) { + sql.append("'"); + sql.append(value); + sql.append("',"); } + + sql.deleteCharAt(sql.length() - 1); sql.append(") GROUP BY value HAVING COUNT(*) > 1)"); @@ -707,15 +714,11 @@ public abstract class AbstractSqlEamDb implements EamDb { sql.append(".case_id=?"); } - sql.append(" ORDER BY value, case_name, file_path"); + sql.append(" ORDER BY value, cases.case_name, file_path"); try { preparedStatement = conn.prepareStatement(sql.toString()); int i = 1; - for (String value : values) { - preparedStatement.setString(i, value); - i++; - } if (singleCase && correlationCase != null) { preparedStatement.setString(i, String.valueOf(correlationCase.getID())); } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllDataSourcesCommonFilesAlgorithm.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllDataSourcesCommonFilesAlgorithm.java index 044241ccf5..548b4d4dbd 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllDataSourcesCommonFilesAlgorithm.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllDataSourcesCommonFilesAlgorithm.java @@ -26,7 +26,7 @@ import java.util.Map; */ final public class AllDataSourcesCommonFilesAlgorithm extends CommonFilesMetadataBuilder { - private static final String WHERE_CLAUSE = "%s md5 in (select md5 from tsk_files where (known != 1 OR known IS NULL)%s GROUP BY md5 HAVING COUNT(*) > 1) order by md5"; //NON-NLS + private static final String WHERE_CLAUSE = "%s md5 in (select md5 from tsk_files where (known != 1 OR known IS NULL)%s GROUP BY md5 HAVING COUNT(*) > 1) order by md5"; //NON-NLS /** * Implements the algorithm for getting common files across all data diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java index 14fd28ab02..dace725f5e 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java @@ -196,7 +196,7 @@ public final class CommonFilesPanel extends javax.swing.JPanel { try { super.done(); progress.setDisplayName(Bundle.CommonFilesPanel_search_done_searchProgress2()); - CommonFilesMetadata metadata = get(); + CommonFilesMetadata metadata = get(); CommonFilesNode commonFilesNode = new CommonFilesNode(metadata); From cf25790821b8a19d5eadeb2a651005b4e3c58bb2 Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Thu, 31 May 2018 09:29:27 -0600 Subject: [PATCH 065/287] fixed a logic error in tear down --- .../autopsy/commonfilessearch/InterCaseUtils.java | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/InterCaseUtils.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/InterCaseUtils.java index bb606352dc..1ec6b84c3f 100644 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/InterCaseUtils.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/InterCaseUtils.java @@ -19,6 +19,7 @@ */ package org.sleuthkit.autopsy.commonfilessearch; +import java.io.File; import java.io.IOException; import java.nio.file.Path; import java.nio.file.Paths; @@ -87,8 +88,7 @@ import org.sleuthkit.autopsy.commonfilesearch.DataSourceLoader; */ class InterCaseUtils { - private static final String CASE_NAME = "InterCaseCommonFilesSearchTest"; - private static final Path CASE_DIRECTORY_PATH = Paths.get(System.getProperty("java.io.tmpdir"), CASE_NAME); + private static final Path CASE_DIRECTORY_PATH = Paths.get(System.getProperty("java.io.tmpdir"), "InterCaseCommonFilesSearchTest"); private static final String CR_DB_NAME = "testcentralrepo.db"; static final String CASE1 = "Case1"; @@ -275,9 +275,15 @@ class InterCaseUtils { * central repo db. */ void tearDown() { + CaseUtils.closeCurrentCase(false); + + String[] cases = new String[]{CASE1,CASE2,CASE3}; + try { - CaseUtils.deleteCaseDir(CASE_DIRECTORY_PATH.toFile()); + for(String caze : cases){ + CaseUtils.deleteCaseDir(new File(caze)); + } } catch (IOException ex) { Exceptions.printStackTrace(ex); Assert.fail(ex); From 12ca0870caabd3d8d797030e710dbfa0a64b4d4b Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Thu, 31 May 2018 09:29:43 -0600 Subject: [PATCH 066/287] comments --- .../IngestedWithHashAndFileTypeInterCaseTests.java | 1 + 1 file changed, 1 insertion(+) diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileTypeInterCaseTests.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileTypeInterCaseTests.java index 5506a0aa6a..4d00253f0a 100644 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileTypeInterCaseTests.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileTypeInterCaseTests.java @@ -82,6 +82,7 @@ public class IngestedWithHashAndFileTypeInterCaseTests extends NbTestCase { */ public void testOne() { try { + //this is proabbly not needed and should be pulled out of the constructor if possible Map dataSources = this.utils.getDataSourceMap(); CommonFilesMetadataBuilder builder = new AllCasesEamDbCommonFilesAlgorithm(dataSources, false, false); From e82126e721703f216dee34b132c71e412dd882d6 Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Thu, 31 May 2018 11:38:46 -0600 Subject: [PATCH 067/287] clearTestDir added --- ...IngestedWithHashAndFileTypeInterCaseTests.java | 15 +-------------- .../autopsy/commonfilessearch/InterCaseUtils.java | 12 ++++++++++++ 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileTypeInterCaseTests.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileTypeInterCaseTests.java index 4d00253f0a..1b96c11a2a 100644 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileTypeInterCaseTests.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileTypeInterCaseTests.java @@ -61,6 +61,7 @@ public class IngestedWithHashAndFileTypeInterCaseTests extends NbTestCase { @Override public void setUp(){ + this.utils.clearTestDir(); try { this.utils.enableCentralRepo(); this.currentCase = this.utils.createCases(this.utils.getIngestSettingsForHashAndFileType(), InterCaseUtils.CASE1); @@ -98,19 +99,5 @@ public class IngestedWithHashAndFileTypeInterCaseTests extends NbTestCase { } - } - - /** - * Case1 - */ - public void testTwo(){ - - } - - /** - * Case2 - */ - public void testThree(){ - } } diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/InterCaseUtils.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/InterCaseUtils.java index 1ec6b84c3f..037c0f1796 100644 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/InterCaseUtils.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/InterCaseUtils.java @@ -28,6 +28,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import org.apache.commons.io.FileUtils; import org.netbeans.junit.NbTestCase; import org.openide.util.Exceptions; import org.sleuthkit.autopsy.casemodule.Case; @@ -154,6 +155,17 @@ class InterCaseUtils { this.dataSourceLoader = new DataSourceLoader(); } + void clearTestDir(){ + if(CASE_DIRECTORY_PATH.toFile().exists()){ + try{ + FileUtils.deleteDirectory(CASE_DIRECTORY_PATH.toFile()); + } catch(IOException ex){ + Assert.fail(ex); + } + } + CASE_DIRECTORY_PATH.toFile().exists(); + } + Map getDataSourceMap() throws NoCurrentCaseException, TskCoreException, SQLException { return this.dataSourceLoader.getDataSourceMap(); } From 12a443e379ea2c1c87200f451621d7c2baf2c714 Mon Sep 17 00:00:00 2001 From: Andrew Ziehl Date: Tue, 29 May 2018 09:39:21 -0700 Subject: [PATCH 068/287] Remove current case before getting datasources for common files case. # Conflicts: # Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java --- .../org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java | 1 + 1 file changed, 1 insertion(+) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java index 1cc810e08c..bf7a656aa3 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java @@ -359,6 +359,7 @@ public final class CommonFilesPanel extends javax.swing.JPanel { protected Map doInBackground() throws Exception { List dataSources = EamDb.getInstance().getCases(); + dataSources.remove(EamDb.getInstance().getCase(Case.getCurrentCase())); Map caseMap = mapDataSources(dataSources); return caseMap; From 0e7558706fe7cba4b598aec44f1b93055f8a5bc3 Mon Sep 17 00:00:00 2001 From: Andrew Ziehl Date: Tue, 29 May 2018 10:00:29 -0700 Subject: [PATCH 069/287] Fix for removing current correlation case from common files data sources. --- .../org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java | 1 - 1 file changed, 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java index bf7a656aa3..1cc810e08c 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java @@ -359,7 +359,6 @@ public final class CommonFilesPanel extends javax.swing.JPanel { protected Map doInBackground() throws Exception { List dataSources = EamDb.getInstance().getCases(); - dataSources.remove(EamDb.getInstance().getCase(Case.getCurrentCase())); Map caseMap = mapDataSources(dataSources); return caseMap; From a408f78f54bb72d2d880e4705306c61685492cbc Mon Sep 17 00:00:00 2001 From: Andrew Ziehl Date: Wed, 30 May 2018 16:21:13 -0700 Subject: [PATCH 070/287] Fix for PreparedStatement limited to 32k ? variable replacements. # Conflicts: # Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java --- .../datamodel/AbstractSqlEamDb.java | 21 +++++++++++-------- .../AllDataSourcesCommonFilesAlgorithm.java | 2 +- .../commonfilesearch/CommonFilesPanel.java | 2 ++ 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java index dc1dd25139..151c729acd 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java @@ -693,11 +693,18 @@ public abstract class AbstractSqlEamDb implements EamDb { sql.append(" LEFT JOIN data_sources ON "); sql.append(tableName); sql.append(".data_source_id=data_sources.id"); - sql.append(" WHERE value IN (SELECT value FROM file_instances WHERE value IN ("); - - for (int i = 0; i < values.size(); i++) { - sql.append("?,"); + sql.append(" WHERE value IN (SELECT value FROM "); + sql.append(tableName); + sql.append(" WHERE value IN ("); + + // Note: PreparedStatement has a limit on ? variable replacement so instead query is built with values appended directly into the string + for (String value : values) { + sql.append("'"); + sql.append(value); + sql.append("',"); } + + sql.deleteCharAt(sql.length() - 1); sql.append(") GROUP BY value HAVING COUNT(*) > 1)"); @@ -707,15 +714,11 @@ public abstract class AbstractSqlEamDb implements EamDb { sql.append(".case_id=?"); } - sql.append(" ORDER BY value, case_name, file_path"); + sql.append(" ORDER BY value, cases.case_name, file_path"); try { preparedStatement = conn.prepareStatement(sql.toString()); int i = 1; - for (String value : values) { - preparedStatement.setString(i, value); - i++; - } if (singleCase && correlationCase != null) { preparedStatement.setString(i, String.valueOf(correlationCase.getID())); } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllDataSourcesCommonFilesAlgorithm.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllDataSourcesCommonFilesAlgorithm.java index 044241ccf5..548b4d4dbd 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllDataSourcesCommonFilesAlgorithm.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllDataSourcesCommonFilesAlgorithm.java @@ -26,7 +26,7 @@ import java.util.Map; */ final public class AllDataSourcesCommonFilesAlgorithm extends CommonFilesMetadataBuilder { - private static final String WHERE_CLAUSE = "%s md5 in (select md5 from tsk_files where (known != 1 OR known IS NULL)%s GROUP BY md5 HAVING COUNT(*) > 1) order by md5"; //NON-NLS + private static final String WHERE_CLAUSE = "%s md5 in (select md5 from tsk_files where (known != 1 OR known IS NULL)%s GROUP BY md5 HAVING COUNT(*) > 1) order by md5"; //NON-NLS /** * Implements the algorithm for getting common files across all data diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java index 1cc810e08c..7ba63d24c7 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java @@ -194,6 +194,8 @@ public final class CommonFilesPanel extends javax.swing.JPanel { protected void done() { try { super.done(); + progress.setDisplayName(Bundle.CommonFilesPanel_search_done_searchProgress2()); + CommonFilesMetadata metadata = get(); CommonFilesMetadata metadata = get(); From 73256e3e77461c07134408105b5ec8dafcfa4105 Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Thu, 31 May 2018 12:22:16 -0600 Subject: [PATCH 071/287] Revert "Remove current case before getting datasources for common files case." This reverts commit 12a443e379ea2c1c87200f451621d7c2baf2c714. --- .../datamodel/AbstractSqlEamDb.java | 21 ++++++++----------- .../AllDataSourcesCommonFilesAlgorithm.java | 2 +- .../commonfilesearch/CommonFilesPanel.java | 2 -- 3 files changed, 10 insertions(+), 15 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java index 151c729acd..dc1dd25139 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java @@ -693,18 +693,11 @@ public abstract class AbstractSqlEamDb implements EamDb { sql.append(" LEFT JOIN data_sources ON "); sql.append(tableName); sql.append(".data_source_id=data_sources.id"); - sql.append(" WHERE value IN (SELECT value FROM "); - sql.append(tableName); - sql.append(" WHERE value IN ("); - - // Note: PreparedStatement has a limit on ? variable replacement so instead query is built with values appended directly into the string - for (String value : values) { - sql.append("'"); - sql.append(value); - sql.append("',"); - } - + sql.append(" WHERE value IN (SELECT value FROM file_instances WHERE value IN ("); + for (int i = 0; i < values.size(); i++) { + sql.append("?,"); + } sql.deleteCharAt(sql.length() - 1); sql.append(") GROUP BY value HAVING COUNT(*) > 1)"); @@ -714,11 +707,15 @@ public abstract class AbstractSqlEamDb implements EamDb { sql.append(".case_id=?"); } - sql.append(" ORDER BY value, cases.case_name, file_path"); + sql.append(" ORDER BY value, case_name, file_path"); try { preparedStatement = conn.prepareStatement(sql.toString()); int i = 1; + for (String value : values) { + preparedStatement.setString(i, value); + i++; + } if (singleCase && correlationCase != null) { preparedStatement.setString(i, String.valueOf(correlationCase.getID())); } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllDataSourcesCommonFilesAlgorithm.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllDataSourcesCommonFilesAlgorithm.java index 548b4d4dbd..044241ccf5 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllDataSourcesCommonFilesAlgorithm.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllDataSourcesCommonFilesAlgorithm.java @@ -26,7 +26,7 @@ import java.util.Map; */ final public class AllDataSourcesCommonFilesAlgorithm extends CommonFilesMetadataBuilder { - private static final String WHERE_CLAUSE = "%s md5 in (select md5 from tsk_files where (known != 1 OR known IS NULL)%s GROUP BY md5 HAVING COUNT(*) > 1) order by md5"; //NON-NLS + private static final String WHERE_CLAUSE = "%s md5 in (select md5 from tsk_files where (known != 1 OR known IS NULL)%s GROUP BY md5 HAVING COUNT(*) > 1) order by md5"; //NON-NLS /** * Implements the algorithm for getting common files across all data diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java index 7ba63d24c7..1cc810e08c 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java @@ -194,8 +194,6 @@ public final class CommonFilesPanel extends javax.swing.JPanel { protected void done() { try { super.done(); - progress.setDisplayName(Bundle.CommonFilesPanel_search_done_searchProgress2()); - CommonFilesMetadata metadata = get(); CommonFilesMetadata metadata = get(); From c78662885c64fd9240cb067ec5c862e766a5df19 Mon Sep 17 00:00:00 2001 From: Andrew Ziehl Date: Fri, 1 Jun 2018 10:01:33 -0700 Subject: [PATCH 072/287] Add or clause to CR query to include current case results so that result will have count > 1. Move values check so that query will return empty. --- .../datamodel/AbstractSqlEamDb.java | 116 +++++++++--------- .../centralrepository/datamodel/EamDb.java | 2 +- .../datamodel/SqliteEamDb.java | 5 +- .../EamDbCommonFilesAlgorithm.java | 11 +- 4 files changed, 70 insertions(+), 64 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java index 151c729acd..195a1ce547 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java @@ -653,18 +653,18 @@ public abstract class AbstractSqlEamDb implements EamDb { * Retrieves eamArtiifact instances from the database that match the given * list of MD5 values and optionally filters by given case. * - * Warning: Does not benefit from PreparedStatement caching to since values will - * be variable in length - * + * Warning: Does not benefit from PreparedStatement caching to since values + * will be variable in length + * * @param correlationCase Case id to search on, if null, searches all cases * @param values List of ArtifactInstance MD5 values to find matches of. * * @return List of artifact instances for a given list of MD5 values - * + * * @throws EamDbException if EamDb is inaccessible. */ @Override - public List getArtifactInstancesByCaseValues(CorrelationCase correlationCase, Collection values) throws EamDbException { + public List getArtifactInstancesByCaseValues(CorrelationCase correlationCase, Collection values, int currentCaseId) throws EamDbException { CorrelationAttribute.Type aType = CorrelationAttribute.getDefaultCorrelationTypes().get(0); // Files type if (aType == null) { throw new EamDbException("Correlation Type is null"); @@ -673,69 +673,73 @@ public abstract class AbstractSqlEamDb implements EamDb { if (correlationCase != null) { singleCase = true; } + if (values != null) { + values = new ArrayList(); + } Connection conn = connect(); List artifactInstances = new ArrayList<>(); // SELECT cases.case_name, cases.case_uid, data_sources.name, device_id, file_path, known_status, comment, data_sources.case_id, value FROM file_instances LEFT JOIN cases ON file_instances.case_id=cases.id LEFT JOIN data_sources ON file_instances.data_source_id=data_sources.id WHERE value IN (SELECT value FROM file_instances WHERE value IN ("59029becd7f830c0478aeb5e67cc3b20","d2b949c51cf3d5721699a6ea500eeba7","b90c8c8fb1c4687780002704b59585fe") GROUP BY value HAVING COUNT(*) > 1) ORDER BY value - CorrelationAttributeCommonInstance artifactInstance; PreparedStatement preparedStatement = null; ResultSet resultSet = null; - if (values != null) { - String tableName = EamDbUtil.correlationTypeToInstanceTableName(aType); - StringBuilder sql = new StringBuilder(10); - sql.append("SELECT cases.case_name, cases.case_uid, data_sources.name, device_id, file_path, known_status, comment, data_sources.case_id, value FROM "); - sql.append(tableName); - sql.append(" LEFT JOIN cases ON "); - sql.append(tableName); - sql.append(".case_id=cases.id"); - sql.append(" LEFT JOIN data_sources ON "); - sql.append(tableName); - sql.append(".data_source_id=data_sources.id"); - sql.append(" WHERE value IN (SELECT value FROM "); - sql.append(tableName); - sql.append(" WHERE value IN ("); - - // Note: PreparedStatement has a limit on ? variable replacement so instead query is built with values appended directly into the string - for (String value : values) { - sql.append("'"); - sql.append(value); - sql.append("',"); - } - - sql.deleteCharAt(sql.length() - 1); - sql.append(") GROUP BY value HAVING COUNT(*) > 1)"); + String tableName = EamDbUtil.correlationTypeToInstanceTableName(aType); + StringBuilder sql = new StringBuilder(10); + sql.append("SELECT cases.case_name, cases.case_uid, data_sources.name, device_id, file_path, known_status, comment, data_sources.case_id, value FROM "); + sql.append(tableName); + sql.append(" LEFT JOIN cases ON "); + sql.append(tableName); + sql.append(".case_id=cases.id"); + sql.append(" LEFT JOIN data_sources ON "); + sql.append(tableName); + sql.append(".data_source_id=data_sources.id"); + sql.append(" WHERE value IN (SELECT value FROM "); + sql.append(tableName); + sql.append(" WHERE value IN ("); + // Note: PreparedStatement has a limit on ? variable replacement so instead query is built with values appended directly into the string + for (String value : values) { + sql.append("'"); + sql.append(value); + sql.append("',"); + } + + sql.deleteCharAt(sql.length() - 1); + sql.append(") GROUP BY value HAVING COUNT(*) > 1)"); // + + if (singleCase && correlationCase != null) { + sql.append(" AND "); + sql.append(tableName); + sql.append(".case_id=?"); + sql.append(" OR "); + sql.append(tableName); + sql.append(".case_id=?"); + + } + + sql.append(" ORDER BY value, cases.case_name, file_path"); + + try { + preparedStatement = conn.prepareStatement(sql.toString()); if (singleCase && correlationCase != null) { - sql.append(" AND "); - sql.append(tableName); - sql.append(".case_id=?"); + preparedStatement.setInt(1, correlationCase.getID()); + preparedStatement.setInt(2, currentCaseId); } - - sql.append(" ORDER BY value, cases.case_name, file_path"); - try { - preparedStatement = conn.prepareStatement(sql.toString()); - int i = 1; - if (singleCase && correlationCase != null) { - preparedStatement.setString(i, String.valueOf(correlationCase.getID())); - } - - resultSet = preparedStatement.executeQuery(); - while (resultSet.next()) { - artifactInstance = getCommonEamArtifactInstanceFromResultSet(resultSet); - artifactInstances.add(artifactInstance); - } - - } catch (SQLException ex) { - throw new EamDbException("Error getting artifact instances by artifactType and artifactValue.", ex); // NON-NLS - } finally { - EamDbUtil.closePreparedStatement(preparedStatement); - EamDbUtil.closeResultSet(resultSet); - EamDbUtil.closeConnection(conn); + resultSet = preparedStatement.executeQuery(); + while (resultSet.next()) { + artifactInstance = getCommonEamArtifactInstanceFromResultSet(resultSet); + artifactInstances.add(artifactInstance); } + + } catch (SQLException ex) { + throw new EamDbException("Error getting artifact instances by artifactType and artifactValue.", ex); // NON-NLS + } finally { + EamDbUtil.closePreparedStatement(preparedStatement); + EamDbUtil.closeResultSet(resultSet); + EamDbUtil.closeConnection(conn); } return artifactInstances; @@ -1032,7 +1036,7 @@ public abstract class AbstractSqlEamDb implements EamDb { if (bulkArtifactsCount == 0) { return; } - + TimingMetric timingMetric = EnterpriseHealthMonitor.getTimingMetric("Correlation Engine: Bulk insert"); for (CorrelationAttribute.Type type : artifactTypes) { @@ -1084,7 +1088,7 @@ public abstract class AbstractSqlEamDb implements EamDb { bulkPs.executeBatch(); bulkArtifacts.get(type.getDbTableName()).clear(); } - + EnterpriseHealthMonitor.submitTimingMetric(timingMetric); // Reset state diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDb.java index 15b234fc47..5984e4d074 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDb.java @@ -233,7 +233,7 @@ public interface EamDb { * * @return List of artifact instances for a given list of MD5 values */ - List getArtifactInstancesByCaseValues(CorrelationCase correlationCase, Collection values) throws EamDbException; + List getArtifactInstancesByCaseValues(CorrelationCase correlationCase, Collection values, int currentCaseId) throws EamDbException; /** * Retrieves eamArtifact instances from the database that are associated diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java index a1b8aaec1d..2d181b4be3 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java @@ -18,7 +18,6 @@ */ package org.sleuthkit.autopsy.centralrepository.datamodel; -import java.io.File; import java.sql.Connection; import java.sql.SQLException; import java.sql.Statement; @@ -431,10 +430,10 @@ public class SqliteEamDb extends AbstractSqlEamDb { * @return List of artifact instances for a given list of MD5 values */ @Override - public List getArtifactInstancesByCaseValues(CorrelationCase correlationCase, Collection values) throws EamDbException { + public List getArtifactInstancesByCaseValues(CorrelationCase correlationCase, Collection values, int currentCaseId) throws EamDbException { try { acquireSharedLock(); - return super.getArtifactInstancesByCaseValues(correlationCase, values); + return super.getArtifactInstancesByCaseValues(correlationCase, values, currentCaseId); } finally { releaseSharedLock(); } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbCommonFilesAlgorithm.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbCommonFilesAlgorithm.java index 898da0c9ed..b137e15c30 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbCommonFilesAlgorithm.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbCommonFilesAlgorithm.java @@ -27,6 +27,7 @@ import java.util.List; import java.util.Map; import java.util.logging.Level; import java.util.stream.Collectors; +import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeCommonInstance; import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationCase; @@ -73,11 +74,13 @@ public abstract class EamDbCommonFilesAlgorithm extends CommonFilesMetadataBuild protected CommonFilesMetadata findFiles(CorrelationCase correlationCase) throws TskCoreException, NoCurrentCaseException, SQLException, EamDbException, Exception { Map currentCaseMetadata = getMetadataForCurrentCase(); Collection values = currentCaseMetadata.keySet(); - + int currentCaseId; Map interCaseCommonFiles = new HashMap<>(); try { - - Collection artifactInstances = dbManager.getArtifactInstancesByCaseValues(correlationCase, values).stream() + // Need to include current Cases results for specific case comparison + currentCaseId = dbManager.getCase(Case.getCurrentCase()).getID(); + + Collection artifactInstances = dbManager.getArtifactInstancesByCaseValues(correlationCase, values, currentCaseId).stream() .collect(Collectors.toList()); interCaseCommonFiles = gatherIntercaseResults(artifactInstances, currentCaseMetadata); @@ -97,7 +100,7 @@ public abstract class EamDbCommonFilesAlgorithm extends CommonFilesMetadataBuild private Map gatherIntercaseResults(Collection artifactInstances, Map commonFiles) { - Map interCaseCommonFiles = new HashMap(); + Map interCaseCommonFiles = new HashMap<>(); for (CorrelationAttributeCommonInstance instance : artifactInstances) { From 3f84ce30f571ae8c6999e481b5f9eb068cd34f43 Mon Sep 17 00:00:00 2001 From: Andrew Ziehl Date: Fri, 1 Jun 2018 10:10:34 -0700 Subject: [PATCH 073/287] fix for null values --- .../centralrepository/datamodel/AbstractSqlEamDb.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java index 195a1ce547..633b86df3c 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java @@ -673,7 +673,7 @@ public abstract class AbstractSqlEamDb implements EamDb { if (correlationCase != null) { singleCase = true; } - if (values != null) { + if (values == null) { values = new ArrayList(); } Connection conn = connect(); @@ -705,8 +705,9 @@ public abstract class AbstractSqlEamDb implements EamDb { sql.append(value); sql.append("',"); } - - sql.deleteCharAt(sql.length() - 1); + if (values != null) { + sql.deleteCharAt(sql.length() - 1); + } sql.append(") GROUP BY value HAVING COUNT(*) > 1)"); // if (singleCase && correlationCase != null) { From a7e69d8fb57da0cee85dbad5bb2db82c47812741 Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Fri, 1 Jun 2018 12:28:04 -0600 Subject: [PATCH 074/287] bug fixes for testing exceptions and notes --- .../datamodel/AbstractSqlEamDb.java | 116 +++++++++--------- .../centralrepository/datamodel/EamDb.java | 2 + .../datamodel/CentralRepoDatamodelTest.java | 8 +- 3 files changed, 65 insertions(+), 61 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java index 633b86df3c..2a1620e9b1 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java @@ -673,74 +673,76 @@ public abstract class AbstractSqlEamDb implements EamDb { if (correlationCase != null) { singleCase = true; } - if (values == null) { - values = new ArrayList(); - } - Connection conn = connect(); List artifactInstances = new ArrayList<>(); + + if (values != null && !values.isEmpty()) { + + //we can skip all this if there is nothing to search for + String tableName = EamDbUtil.correlationTypeToInstanceTableName(aType); + StringBuilder sql = new StringBuilder(10); + sql.append("SELECT cases.case_name, cases.case_uid, data_sources.name, device_id, file_path, known_status, comment, data_sources.case_id, value FROM "); + sql.append(tableName); + sql.append(" LEFT JOIN cases ON "); + sql.append(tableName); + sql.append(".case_id=cases.id"); + sql.append(" LEFT JOIN data_sources ON "); + sql.append(tableName); + sql.append(".data_source_id=data_sources.id"); + sql.append(" WHERE value IN (SELECT value FROM "); + sql.append(tableName); + sql.append(" WHERE value IN ("); - // SELECT cases.case_name, cases.case_uid, data_sources.name, device_id, file_path, known_status, comment, data_sources.case_id, value FROM file_instances LEFT JOIN cases ON file_instances.case_id=cases.id LEFT JOIN data_sources ON file_instances.data_source_id=data_sources.id WHERE value IN (SELECT value FROM file_instances WHERE value IN ("59029becd7f830c0478aeb5e67cc3b20","d2b949c51cf3d5721699a6ea500eeba7","b90c8c8fb1c4687780002704b59585fe") GROUP BY value HAVING COUNT(*) > 1) ORDER BY value - CorrelationAttributeCommonInstance artifactInstance; - PreparedStatement preparedStatement = null; - ResultSet resultSet = null; + // Note: PreparedStatement has a limit on ? variable replacement so instead query is built with values appended directly into the string + for (String value : values) { + sql.append("'"); + sql.append(value); + sql.append("',"); + } - String tableName = EamDbUtil.correlationTypeToInstanceTableName(aType); - StringBuilder sql = new StringBuilder(10); - sql.append("SELECT cases.case_name, cases.case_uid, data_sources.name, device_id, file_path, known_status, comment, data_sources.case_id, value FROM "); - sql.append(tableName); - sql.append(" LEFT JOIN cases ON "); - sql.append(tableName); - sql.append(".case_id=cases.id"); - sql.append(" LEFT JOIN data_sources ON "); - sql.append(tableName); - sql.append(".data_source_id=data_sources.id"); - sql.append(" WHERE value IN (SELECT value FROM "); - sql.append(tableName); - sql.append(" WHERE value IN ("); - - // Note: PreparedStatement has a limit on ? variable replacement so instead query is built with values appended directly into the string - for (String value : values) { - sql.append("'"); - sql.append(value); - sql.append("',"); - } - if (values != null) { sql.deleteCharAt(sql.length() - 1); - } - sql.append(") GROUP BY value HAVING COUNT(*) > 1)"); // - if (singleCase && correlationCase != null) { - sql.append(" AND "); - sql.append(tableName); - sql.append(".case_id=?"); - sql.append(" OR "); - sql.append(tableName); - sql.append(".case_id=?"); + sql.append(") GROUP BY value HAVING COUNT(*) > 1)"); // - } - - sql.append(" ORDER BY value, cases.case_name, file_path"); - - try { - preparedStatement = conn.prepareStatement(sql.toString()); if (singleCase && correlationCase != null) { - preparedStatement.setInt(1, correlationCase.getID()); - preparedStatement.setInt(2, currentCaseId); + sql.append(" AND "); + sql.append(tableName); + sql.append(".case_id=?"); + sql.append(" OR "); + sql.append(tableName); + sql.append(".case_id=?"); } + + //TODO shows extra results - possibly shows matches within current case - resultSet = preparedStatement.executeQuery(); - while (resultSet.next()) { - artifactInstance = getCommonEamArtifactInstanceFromResultSet(resultSet); - artifactInstances.add(artifactInstance); + sql.append(" ORDER BY value, cases.case_name, file_path"); + + Connection conn = connect(); + CorrelationAttributeCommonInstance artifactInstance; + PreparedStatement preparedStatement = null; + ResultSet resultSet = null; + + try { + + preparedStatement = conn.prepareStatement(sql.toString()); + if (singleCase && correlationCase != null) { + preparedStatement.setInt(1, correlationCase.getID()); + preparedStatement.setInt(2, currentCaseId); + } + + resultSet = preparedStatement.executeQuery(); + while (resultSet.next()) { + artifactInstance = getCommonEamArtifactInstanceFromResultSet(resultSet); + artifactInstances.add(artifactInstance); + } + + } catch (SQLException ex) { + throw new EamDbException("Error getting artifact instances by artifactType and artifactValue.", ex); // NON-NLS + } finally { + EamDbUtil.closePreparedStatement(preparedStatement); + EamDbUtil.closeResultSet(resultSet); + EamDbUtil.closeConnection(conn); } - - } catch (SQLException ex) { - throw new EamDbException("Error getting artifact instances by artifactType and artifactValue.", ex); // NON-NLS - } finally { - EamDbUtil.closePreparedStatement(preparedStatement); - EamDbUtil.closeResultSet(resultSet); - EamDbUtil.closeConnection(conn); } return artifactInstances; diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDb.java index 5984e4d074..db928b5acd 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDb.java @@ -230,8 +230,10 @@ public interface EamDb { * * @param correlationCase Case id to search on * @param values List of ArtifactInstance MD5 values to find matches of. + * @param currentCaseId current case * * @return List of artifact instances for a given list of MD5 values + * //TODO create an overload that omits the case params */ List getArtifactInstancesByCaseValues(CorrelationCase correlationCase, Collection values, int currentCaseId) throws EamDbException; diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDatamodelTest.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDatamodelTest.java index 055e9a8040..d41dac4e06 100755 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDatamodelTest.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDatamodelTest.java @@ -845,7 +845,7 @@ public class CentralRepoDatamodelTest extends TestCase { // Test getting common instances with expected results try { - List instances = EamDb.getInstance().getArtifactInstancesByCaseValues(null, Arrays.asList(inAllDataSourcesHash, inDataSource1twiceHash)); + List instances = EamDb.getInstance().getArtifactInstancesByCaseValues(null, Arrays.asList(inAllDataSourcesHash, inDataSource1twiceHash), -1); assertTrue("getArtifactInstancesByCaseValues returned " + instances.size() + " results - expected 5", instances.size() == 5); // This test works because all the instances of this hash were set to the same path @@ -867,7 +867,7 @@ public class CentralRepoDatamodelTest extends TestCase { // Test getting instances expecting no results because they are not in the case try { CorrelationCase badCase = new CorrelationCase("badCaseUuid", "badCaseName"); - List instances = EamDb.getInstance().getArtifactInstancesByCaseValues(badCase, Arrays.asList(inAllDataSourcesHash, inDataSource1twiceHash)); + List instances = EamDb.getInstance().getArtifactInstancesByCaseValues(badCase, Arrays.asList(inAllDataSourcesHash, inDataSource1twiceHash), 0); assertTrue("getArtifactInstancesByTypeValue returned " + instances.size() + " results - expected 0", instances.isEmpty()); } catch (EamDbException ex) { @@ -878,7 +878,7 @@ public class CentralRepoDatamodelTest extends TestCase { // Test getting instances expecting no results because of bad hashes try { - List instances = EamDb.getInstance().getArtifactInstancesByCaseValues(null, Arrays.asList("xyz", "123")); + List instances = EamDb.getInstance().getArtifactInstancesByCaseValues(null, Arrays.asList("xyz", "123"), -1); assertTrue("getArtifactInstancesByTypeValue returned " + instances.size() + " results - expected 0", instances.isEmpty()); } catch (EamDbException ex) { @@ -918,7 +918,7 @@ public class CentralRepoDatamodelTest extends TestCase { // Test getting instances with null value // Should just return nothing try { - List instances = EamDb.getInstance().getArtifactInstancesByCaseValues(null, null); + List instances = EamDb.getInstance().getArtifactInstancesByCaseValues(null, null, -1); assertTrue("getArtifactInstancesByTypeValue returned non-empty list for null value", instances.isEmpty()); } catch (EamDbException ex) { From 4c846f1353cd2221572f110708f19a93994946a8 Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Sat, 2 Jun 2018 16:14:44 -0600 Subject: [PATCH 075/287] comments --- .../commonfilesearch/AllCasesEamDbCommonFilesAlgorithm.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllCasesEamDbCommonFilesAlgorithm.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllCasesEamDbCommonFilesAlgorithm.java index c7a87f5b52..8aad1eb1bb 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllCasesEamDbCommonFilesAlgorithm.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllCasesEamDbCommonFilesAlgorithm.java @@ -23,7 +23,8 @@ import java.util.Map; import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException; /** - *TODO docs + * Algorithm which finds files anywhere in the Central Repo which also occur in + * present case. */ public class AllCasesEamDbCommonFilesAlgorithm extends EamDbCommonFilesAlgorithm { From 7ee79bb7988cf8ef54a6f53a61f9b75a0878084e Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Sat, 2 Jun 2018 18:07:20 -0600 Subject: [PATCH 076/287] api cleanup --- .../datamodel/AbstractSqlEamDb.java | 17 ++++++++++++++++- .../centralrepository/datamodel/EamDb.java | 13 +++++++++++-- .../datamodel/SqliteEamDb.java | 19 +++++++++++++++++++ .../datamodel/CentralRepoDatamodelTest.java | 6 +++--- ...stedWithHashAndFileTypeInterCaseTests.java | 2 -- 5 files changed, 49 insertions(+), 8 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java index 2a1620e9b1..da92e75412 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java @@ -650,7 +650,22 @@ public abstract class AbstractSqlEamDb implements EamDb { } /** - * Retrieves eamArtiifact instances from the database that match the given + * Retrieves eamArtifact instances from the database that match the given + * list of MD5 values; + * + * @param values MD5s to use as search keys + * @return matching files in the form of CorrelationAttributeCommonInstance + * @throws EamDbException + */ + public List getArtifactInstancesByCaseValues(Collection values) throws EamDbException { + //passing null and -1 here has the effect of making this case agnostic: + // rather than looking for instances that must appear in a certain case + // we accept instances occur in any case + return getArtifactInstancesByCaseValues(null, values, -1); + } + + /** + * Retrieves eamArtifact instances from the database that match the given * list of MD5 values and optionally filters by given case. * * Warning: Does not benefit from PreparedStatement caching to since values diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDb.java index db928b5acd..e80ed1e497 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDb.java @@ -232,11 +232,20 @@ public interface EamDb { * @param values List of ArtifactInstance MD5 values to find matches of. * @param currentCaseId current case * - * @return List of artifact instances for a given list of MD5 values - * //TODO create an overload that omits the case params + * @return matching files in the form of CorrelationAttributeCommonInstance */ List getArtifactInstancesByCaseValues(CorrelationCase correlationCase, Collection values, int currentCaseId) throws EamDbException; + /** + * Retrieves eamArtiifact instances from the database that match the given + * list of MD5 values; + * + * @param values MD5s to use as search keys + * @return matching files in the form of CorrelationAttributeCommonInstance + * @throws EamDbException + */ + List getArtifactInstancesByCaseValues(Collection values) throws EamDbException; + /** * Retrieves eamArtifact instances from the database that are associated * with the aType and filePath diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java index 2d181b4be3..a478a08532 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java @@ -419,6 +419,25 @@ public class SqliteEamDb extends AbstractSqlEamDb { releaseSharedLock(); } } + + /** + * Retrieves eamArtiifact instances from the database that match the given + * list of MD5 values; + * + * @param correlationCase Case id to search on + * @param values List of ArtifactInstance MD5 values to find matches of. + * + * @return List of artifact instances for a given list of MD5 values + */ + @Override + public List getArtifactInstancesByCaseValues(Collection values) throws EamDbException { + try { + acquireSharedLock(); + return super.getArtifactInstancesByCaseValues(null, values, -1); + } finally { + releaseSharedLock(); + } + } /** * Retrieves eamArtiifact instances from the database that match the given diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDatamodelTest.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDatamodelTest.java index d41dac4e06..2affee7ec4 100755 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDatamodelTest.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDatamodelTest.java @@ -845,7 +845,7 @@ public class CentralRepoDatamodelTest extends TestCase { // Test getting common instances with expected results try { - List instances = EamDb.getInstance().getArtifactInstancesByCaseValues(null, Arrays.asList(inAllDataSourcesHash, inDataSource1twiceHash), -1); + List instances = EamDb.getInstance().getArtifactInstancesByCaseValues(Arrays.asList(inAllDataSourcesHash, inDataSource1twiceHash)); assertTrue("getArtifactInstancesByCaseValues returned " + instances.size() + " results - expected 5", instances.size() == 5); // This test works because all the instances of this hash were set to the same path @@ -878,7 +878,7 @@ public class CentralRepoDatamodelTest extends TestCase { // Test getting instances expecting no results because of bad hashes try { - List instances = EamDb.getInstance().getArtifactInstancesByCaseValues(null, Arrays.asList("xyz", "123"), -1); + List instances = EamDb.getInstance().getArtifactInstancesByCaseValues(Arrays.asList("xyz", "123")); assertTrue("getArtifactInstancesByTypeValue returned " + instances.size() + " results - expected 0", instances.isEmpty()); } catch (EamDbException ex) { @@ -918,7 +918,7 @@ public class CentralRepoDatamodelTest extends TestCase { // Test getting instances with null value // Should just return nothing try { - List instances = EamDb.getInstance().getArtifactInstancesByCaseValues(null, null, -1); + List instances = EamDb.getInstance().getArtifactInstancesByCaseValues(null); assertTrue("getArtifactInstancesByTypeValue returned non-empty list for null value", instances.isEmpty()); } catch (EamDbException ex) { diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileTypeInterCaseTests.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileTypeInterCaseTests.java index 1b96c11a2a..17ddfae721 100644 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileTypeInterCaseTests.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileTypeInterCaseTests.java @@ -97,7 +97,5 @@ public class IngestedWithHashAndFileTypeInterCaseTests extends NbTestCase { Exceptions.printStackTrace(ex); Assert.fail(ex); } - - } } From ea8c8a46cda142e7adb59741468c94c402f914da Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Sat, 2 Jun 2018 20:00:04 -0600 Subject: [PATCH 077/287] stubbing out test helpers and refactoring naming for old tests --- .../EamDbCommonFilesAlgorithm.java | 4 + ...stedWithHashAndFileTypeInterCaseTests.java | 4 +- ...stedWithHashAndFileTypeIntraCaseTests.java | 288 +++++++++--------- .../commonfilessearch/InterCaseUtils.java | 15 +- .../commonfilessearch/IntraCaseUtils.java | 34 ++- 5 files changed, 179 insertions(+), 166 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbCommonFilesAlgorithm.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbCommonFilesAlgorithm.java index f013ff2321..5f683a2019 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbCommonFilesAlgorithm.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbCommonFilesAlgorithm.java @@ -43,6 +43,10 @@ import org.sleuthkit.datamodel.TskCoreException; * in the Central Repo. */ public abstract class EamDbCommonFilesAlgorithm extends CommonFilesMetadataBuilder { + //CONSIDER: we should create an interface which specifies the findFiles feature + // instead of an abstract class and then have two abstract classes: + // inter- and intra- which implement the interface and then 4 subclasses + // 2 for each abstract class: singlecase/allcase; singledatasource/all datasource private static final String WHERE_CLAUSE = "%s md5 in (select md5 from tsk_files where (known != 1 OR known IS NULL)%s GROUP BY md5) order by md5"; //NON-NLS diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileTypeInterCaseTests.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileTypeInterCaseTests.java index 17ddfae721..09b27675e8 100644 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileTypeInterCaseTests.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileTypeInterCaseTests.java @@ -90,7 +90,9 @@ public class IngestedWithHashAndFileTypeInterCaseTests extends NbTestCase { CommonFilesMetadata metadata = builder.findFiles(); - assertTrue("", metadata.size() != 0); + assertTrue("Results should not be empty", metadata.size() != 0); + + assertTrue("") } catch (Exception ex) { diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileTypeIntraCaseTests.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileTypeIntraCaseTests.java index 7bac039bc7..33504d3c5e 100644 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileTypeIntraCaseTests.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileTypeIntraCaseTests.java @@ -104,25 +104,25 @@ public class IngestedWithHashAndFileTypeIntraCaseTests extends NbTestCase { List files = IntraCaseUtils.getFiles(objectIdToDataSource.keySet()); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, IMG, SET1, 2)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, IMG, SET2, 1)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, IMG, SET3, 1)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, IMG, SET4, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET1, 2)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET2, 1)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET3, 1)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET4, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, DOC, SET1, 1)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, DOC, SET2, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, DOC, SET3, 1)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, DOC, SET4, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, DOC, SET1, 1)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, DOC, SET2, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, DOC, SET3, 1)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, DOC, SET4, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, PDF, SET1, 0)); - assertTrue(IntraCaseUtils.verifyFileExistanceAndCount(files, objectIdToDataSource, PDF, SET2, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, PDF, SET3, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, PDF, SET4, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET1, 0)); + assertTrue(IntraCaseUtils.verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET2, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET3, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET4, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, EMPTY, SET1, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, EMPTY, SET2, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, EMPTY, SET3, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, EMPTY, SET4, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET1, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET2, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET3, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET4, 0)); } catch (Exception ex) { Exceptions.printStackTrace(ex); @@ -145,25 +145,25 @@ public class IngestedWithHashAndFileTypeIntraCaseTests extends NbTestCase { List files = getFiles(objectIdToDataSource.keySet()); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, IMG, SET1, 2)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, IMG, SET2, 1)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, IMG, SET3, 1)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, IMG, SET4, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET1, 2)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET2, 1)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET3, 1)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET4, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, DOC, SET1, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, DOC, SET2, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, DOC, SET3, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, DOC, SET4, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, DOC, SET1, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, DOC, SET2, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, DOC, SET3, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, DOC, SET4, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, PDF, SET1, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, PDF, SET2, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, PDF, SET3, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, PDF, SET4, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET1, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET2, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET3, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET4, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, EMPTY, SET1, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, EMPTY, SET2, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, EMPTY, SET3, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, EMPTY, SET4, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET1, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET2, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET3, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET4, 0)); } catch (Exception ex) { Exceptions.printStackTrace(ex); @@ -186,25 +186,25 @@ public class IngestedWithHashAndFileTypeIntraCaseTests extends NbTestCase { List files = getFiles(objectIdToDataSource.keySet()); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, IMG, SET1, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, IMG, SET2, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, IMG, SET3, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, IMG, SET4, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET1, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET2, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET3, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET4, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, DOC, SET1, 1)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, DOC, SET2, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, DOC, SET3, 1)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, DOC, SET4, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, DOC, SET1, 1)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, DOC, SET2, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, DOC, SET3, 1)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, DOC, SET4, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, PDF, SET1, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, PDF, SET2, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, PDF, SET3, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, PDF, SET4, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET1, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET2, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET3, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET4, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, EMPTY, SET1, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, EMPTY, SET2, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, EMPTY, SET3, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, EMPTY, SET4, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET1, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET2, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET3, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET4, 0)); } catch (Exception ex) { Exceptions.printStackTrace(ex); @@ -228,25 +228,25 @@ public class IngestedWithHashAndFileTypeIntraCaseTests extends NbTestCase { List files = getFiles(objectIdToDataSource.keySet()); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, IMG, SET1, 2)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, IMG, SET2, 1)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, IMG, SET3, 1)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, IMG, SET4, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET1, 2)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET2, 1)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET3, 1)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET4, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, DOC, SET1, 1)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, DOC, SET2, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, DOC, SET3, 1)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, DOC, SET4, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, DOC, SET1, 1)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, DOC, SET2, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, DOC, SET3, 1)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, DOC, SET4, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, PDF, SET1, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, PDF, SET2, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, PDF, SET3, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, PDF, SET4, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET1, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET2, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET3, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET4, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, EMPTY, SET1, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, EMPTY, SET2, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, EMPTY, SET3, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, EMPTY, SET4, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET1, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET2, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET3, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET4, 0)); } catch (Exception ex) { Exceptions.printStackTrace(ex); @@ -270,25 +270,25 @@ public class IngestedWithHashAndFileTypeIntraCaseTests extends NbTestCase { List files = getFiles(objectIdToDataSource.keySet()); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, IMG, SET1, 2)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, IMG, SET2, 1)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, IMG, SET3, 1)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, IMG, SET4, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET1, 2)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET2, 1)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET3, 1)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET4, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, DOC, SET1, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, DOC, SET2, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, DOC, SET3, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, DOC, SET4, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, DOC, SET1, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, DOC, SET2, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, DOC, SET3, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, DOC, SET4, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, PDF, SET1, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, PDF, SET2, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, PDF, SET3, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, PDF, SET4, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET1, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET2, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET3, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET4, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, EMPTY, SET1, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, EMPTY, SET2, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, EMPTY, SET3, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, EMPTY, SET4, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET1, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET2, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET3, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET4, 0)); } catch (Exception ex) { Exceptions.printStackTrace(ex); @@ -312,25 +312,25 @@ public class IngestedWithHashAndFileTypeIntraCaseTests extends NbTestCase { List files = getFiles(objectIdToDataSource.keySet()); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, IMG, SET1, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, IMG, SET2, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, IMG, SET3, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, IMG, SET4, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET1, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET2, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET3, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET4, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, DOC, SET1, 1)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, DOC, SET2, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, DOC, SET3, 1)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, DOC, SET4, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, DOC, SET1, 1)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, DOC, SET2, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, DOC, SET3, 1)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, DOC, SET4, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, PDF, SET1, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, PDF, SET2, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, PDF, SET3, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, PDF, SET4, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET1, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET2, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET3, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET4, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, EMPTY, SET1, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, EMPTY, SET2, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, EMPTY, SET3, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, EMPTY, SET4, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET1, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET2, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET3, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET4, 0)); } catch (Exception ex) { Exceptions.printStackTrace(ex); @@ -354,25 +354,25 @@ public class IngestedWithHashAndFileTypeIntraCaseTests extends NbTestCase { List files = getFiles(objectIdToDataSource.keySet()); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, IMG, SET1, 2)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, IMG, SET2, 1)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, IMG, SET3, 1)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, IMG, SET4, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET1, 2)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET2, 1)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET3, 1)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET4, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, DOC, SET1, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, DOC, SET2, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, DOC, SET3, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, DOC, SET4, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, DOC, SET1, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, DOC, SET2, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, DOC, SET3, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, DOC, SET4, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, PDF, SET1, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, PDF, SET2, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, PDF, SET3, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, PDF, SET4, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET1, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET2, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET3, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET4, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, EMPTY, SET1, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, EMPTY, SET2, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, EMPTY, SET3, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, EMPTY, SET4, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET1, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET2, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET3, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET4, 0)); } catch (Exception ex) { Exceptions.printStackTrace(ex); @@ -395,25 +395,25 @@ public class IngestedWithHashAndFileTypeIntraCaseTests extends NbTestCase { List files = getFiles(objectIdToDataSource.keySet()); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, IMG, SET1, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, IMG, SET2, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, IMG, SET3, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, IMG, SET4, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET1, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET2, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET3, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET4, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, DOC, SET1, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, DOC, SET1, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, DOC, SET3, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, DOC, SET4, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, DOC, SET1, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, DOC, SET1, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, DOC, SET3, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, DOC, SET4, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, PDF, SET1, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, PDF, SET2, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, PDF, SET3, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, PDF, SET4, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET1, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET2, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET3, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET4, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, EMPTY, SET1, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, EMPTY, SET2, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, EMPTY, SET3, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, EMPTY, SET4, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET1, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET2, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET3, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET4, 0)); } catch (Exception ex) { Exceptions.printStackTrace(ex); @@ -436,25 +436,25 @@ public class IngestedWithHashAndFileTypeIntraCaseTests extends NbTestCase { List files = getFiles(objectIdToDataSource.keySet()); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, IMG, SET1, 2)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, IMG, SET2, 1)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, IMG, SET3, 1)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, IMG, SET4, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET1, 2)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET2, 1)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET3, 1)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET4, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, DOC, SET1, 1)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, DOC, SET2, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, DOC, SET3, 1)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, DOC, SET4, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, DOC, SET1, 1)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, DOC, SET2, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, DOC, SET3, 1)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, DOC, SET4, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, PDF, SET1, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, PDF, SET2, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, PDF, SET3, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, PDF, SET4, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET1, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET2, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET3, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET4, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, EMPTY, SET1, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, EMPTY, SET2, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, EMPTY, SET3, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, EMPTY, SET4, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET1, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET2, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET3, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET4, 0)); } catch (Exception ex) { Exceptions.printStackTrace(ex); diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/InterCaseUtils.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/InterCaseUtils.java index 3115c43299..a6709e4bf8 100644 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/InterCaseUtils.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/InterCaseUtils.java @@ -50,6 +50,7 @@ import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationCase; import org.sleuthkit.autopsy.centralrepository.datamodel.EamDb; import org.sleuthkit.autopsy.commonfilesearch.DataSourceLoader; +import org.sleuthkit.datamodel.AbstractFile; /** * Utilities for testing intercase correlation feature. @@ -60,11 +61,11 @@ import org.sleuthkit.autopsy.commonfilesearch.DataSourceLoader; * * Case 1 * +Data Set 1 - * - Hash-0.dat [file of size 0] + * - Hash-0.dat [file of size 0] * - Hash-A.jpg * - Hash-A.pdf * +Data Set2 - * - Hash-0.dat [file of size -0] + * - Hash-0.dat [file of size -0] * - Hash-A.jpg * - Hash-A.pdf * Case 2 @@ -79,11 +80,11 @@ import org.sleuthkit.autopsy.commonfilesearch.DataSourceLoader; * +Data Set 1 * - Hash-A.jpg * - Hash-A.pdf - * - Hash-C.jpg - * - Hash-C.pdf + * - Hash-C.jpg [we should never find these!] + * - Hash-C.pdf [we should never find these!] * - Hash-D.jpg * +Data Set 2 - * - Hash-C.jpg + * - Hash-C.jpg [we should never find these!] * - Hash-C.pdf * - Hash.D-doc */ @@ -284,6 +285,10 @@ class InterCaseUtils { return null; } } + + static boolean verifyInstanceExistanceAndCount(List searchDomain, Map objectIdToDataSourceMap, String fileName, String dataSource, String crCase, int instanceCount){ + return false; + } /** * Close the currently open case, delete the case directory, delete the diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IntraCaseUtils.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IntraCaseUtils.java index 9cb2eb0e8f..119c9eb5ed 100644 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IntraCaseUtils.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IntraCaseUtils.java @@ -133,32 +133,32 @@ class IntraCaseUtils { * Verify that the given file appears a precise number times in the given * data source. * - * @param files search domain - * @param objectIdToDataSource mapping of file ids to data source names - * @param name name of file to search for + * @param searchDomain search domain + * @param objectIdToDataSourceMap mapping of file ids to data source names + * @param fileName name of file to search for * @param dataSource name of data source where file should appear - * @param count number of appearances of the given file + * @param instanceCount number of appearances of the given file * @return true if a file with the given name exists the specified number - * of times in the given data source + * of times in the given data source */ - static boolean verifyFileExistanceAndCount(List files, Map objectIdToDataSource, String name, String dataSource, int count) { + static boolean verifyInstanceExistanceAndCount(List searchDomain, Map objectIdToDataSourceMap, String fileName, String dataSource, int instanceCount) { int tally = 0; - for (AbstractFile file : files) { + for (AbstractFile file : searchDomain) { Long objectId = file.getId(); - String fileName = file.getName(); + String name = file.getName(); - String dataSourceName = objectIdToDataSource.get(objectId); + String dataSourceName = objectIdToDataSourceMap.get(objectId); - if (fileName.equals(name) && dataSourceName.equals(dataSource)) { + if (name.equals(name) && dataSourceName.equals(dataSource)) { tally++; } } - return tally == count; + return tally == instanceCount; } /** @@ -172,14 +172,16 @@ class IntraCaseUtils { * @return true if a file with the given name exists once in the given data * source */ - static boolean verifySingularFileExistance(List files, Map objectIdToDataSource, String name, String dataSource) { - return verifyFileExistanceAndCount(files, objectIdToDataSource, name, dataSource, 1); + static boolean verifySingularInstanceExistance(List files, Map objectIdToDataSource, String name, String dataSource) { + return verifyInstanceExistanceAndCount(files, objectIdToDataSource, name, dataSource, 1); } /** - * TODO - * @param metadata - * @return + * Create a convenience lookup table mapping file instance object ids to + * the data source they appear in. + * + * @param metadata object returned by the code under test + * @return mapping of objectId to data source name */ static Map mapFileInstancesToDataSources(CommonFilesMetadata metadata) { Map instanceIdToDataSource = new HashMap<>(); From b91d0666318ea6bd7f8e9a078c040800766148a2 Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Sun, 3 Jun 2018 23:13:51 -0600 Subject: [PATCH 078/287] ensure that intercase search does not return matches for files which only appear in a single case (this would be an intra-case result) --- .../datamodel/AbstractSqlEamDb.java | 3 ++- .../EamDbCommonFilesAlgorithm.java | 27 +++++++++++++++---- .../autopsy/commonfilesearch/Md5Metadata.java | 21 +++++++++++++++ ...stedWithHashAndFileTypeInterCaseTests.java | 4 +-- .../commonfilessearch/InterCaseUtils.java | 21 +++++++++++++++ .../commonfilessearch/IntraCaseUtils.java | 1 + 6 files changed, 69 insertions(+), 8 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java index da92e75412..345543de22 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java @@ -728,7 +728,8 @@ public abstract class AbstractSqlEamDb implements EamDb { sql.append(".case_id=?"); } - //TODO shows extra results - possibly shows matches within current case + //TODO figure out how to replicate results obtained by functionality + // seen in EamDbCOmmonFilesAlgorithm.removeEntriesWithinOnlyOneCase sql.append(" ORDER BY value, cases.case_name, file_path"); diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbCommonFilesAlgorithm.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbCommonFilesAlgorithm.java index 5f683a2019..0a60b326f2 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbCommonFilesAlgorithm.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbCommonFilesAlgorithm.java @@ -114,7 +114,8 @@ public abstract class EamDbCommonFilesAlgorithm extends CommonFilesMetadataBuild for (CorrelationAttributeCommonInstance instance : artifactInstances) { String md5 = instance.getValue(); - String dataSource = String.format("%s: %s", instance.getCorrelationCase().getDisplayName(), instance.getCorrelationDataSource().getName()); + final String correlationCaseDisplayName = instance.getCorrelationCase().getDisplayName(); + String dataSource = String.format("%s: %s", correlationCaseDisplayName, instance.getCorrelationDataSource().getName()); if (md5 == null || HashUtility.isNoDataMd5(md5)) { continue; @@ -127,17 +128,19 @@ public abstract class EamDbCommonFilesAlgorithm extends CommonFilesMetadataBuild if(interCaseCommonFiles.containsKey(md5)) { //Add to intercase metaData final Md5Metadata md5Metadata = interCaseCommonFiles.get(md5); - md5Metadata.addFileInstanceMetadata(new FileInstanceMetadata(objectId, dataSource)); + md5Metadata.addFileInstanceMetadata(new FileInstanceMetadata(objectId, dataSource), correlationCaseDisplayName); } else { - final List fileInstances = new ArrayList<>(); - fileInstances.add(new FileInstanceMetadata(objectId, dataSource)); - Md5Metadata md5Metadata = new Md5Metadata(md5, fileInstances); + Md5Metadata md5Metadata = new Md5Metadata(md5); + md5Metadata.addFileInstanceMetadata(new FileInstanceMetadata(objectId, dataSource), correlationCaseDisplayName); interCaseCommonFiles.put(md5, md5Metadata); } } } + //ideally we would do this step via SQL in EamDb.getArtifactInstancesByCaseValues + removeEntriesWithinOnlyOneCase(interCaseCommonFiles); + return interCaseCommonFiles; } @@ -163,4 +166,18 @@ public abstract class EamDbCommonFilesAlgorithm extends CommonFilesMetadataBuild } throw new Exception("Cannot locate case."); } + + private void removeEntriesWithinOnlyOneCase(Map interCaseCommonFiles) { + Collection toRemove = new ArrayList<>(); + + for(Map.Entry entry : interCaseCommonFiles.entrySet()){ + if(!entry.getValue().isMultiDataSource()){ + toRemove.add(entry.getKey()); + } + } + + for(String bogusEntry : toRemove){ + interCaseCommonFiles.remove(bogusEntry); + } + } } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/Md5Metadata.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/Md5Metadata.java index 39c2cf8040..916d6950a8 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/Md5Metadata.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/Md5Metadata.java @@ -19,6 +19,7 @@ */ package org.sleuthkit.autopsy.commonfilesearch; +import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashSet; @@ -33,9 +34,18 @@ final public class Md5Metadata { private final String md5; private final List fileInstances; + private final Set distinctCases; + Md5Metadata(String md5, List fileInstances){ this.md5 = md5; this.fileInstances = fileInstances; + this.distinctCases = new HashSet<>(); + } + + Md5Metadata(String md5){ + this.md5 = md5; + this.fileInstances = new ArrayList<>(); + this.distinctCases = new HashSet<>(); } public String getMd5(){ @@ -46,6 +56,13 @@ final public class Md5Metadata { this.fileInstances.add(metadata); } + void addFileInstanceMetadata(FileInstanceMetadata metadata, String caseName){ + this.fileInstances.add(metadata); + if(!this.distinctCases.contains(caseName)){ + this.distinctCases.add(caseName); + } + } + public Collection getMetadata(){ return Collections.unmodifiableCollection(this.fileInstances); } @@ -65,4 +82,8 @@ final public class Md5Metadata { } return String.join(", ", sources); } + + boolean isMultiDataSource() { + return this.distinctCases.size() > 1; + } } diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileTypeInterCaseTests.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileTypeInterCaseTests.java index 09b27675e8..9538fe6549 100644 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileTypeInterCaseTests.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileTypeInterCaseTests.java @@ -64,7 +64,7 @@ public class IngestedWithHashAndFileTypeInterCaseTests extends NbTestCase { this.utils.clearTestDir(); try { this.utils.enableCentralRepo(); - this.currentCase = this.utils.createCases(this.utils.getIngestSettingsForHashAndFileType(), InterCaseUtils.CASE1); + this.currentCase = this.utils.createCases(this.utils.getIngestSettingsForHashAndFileType(), InterCaseUtils.CASE3); } catch (Exception ex) { Exceptions.printStackTrace(ex); Assert.fail(ex); @@ -92,7 +92,7 @@ public class IngestedWithHashAndFileTypeInterCaseTests extends NbTestCase { assertTrue("Results should not be empty", metadata.size() != 0); - assertTrue("") + //assertTrue("") } catch (Exception ex) { diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/InterCaseUtils.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/InterCaseUtils.java index a6709e4bf8..f3e3ba58f7 100644 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/InterCaseUtils.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/InterCaseUtils.java @@ -49,6 +49,7 @@ import org.python.icu.impl.Assert; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationCase; import org.sleuthkit.autopsy.centralrepository.datamodel.EamDb; +import org.sleuthkit.autopsy.commonfilesearch.CommonFilesMetadata; import org.sleuthkit.autopsy.commonfilesearch.DataSourceLoader; import org.sleuthkit.datamodel.AbstractFile; @@ -287,8 +288,28 @@ class InterCaseUtils { } static boolean verifyInstanceExistanceAndCount(List searchDomain, Map objectIdToDataSourceMap, String fileName, String dataSource, String crCase, int instanceCount){ + + int tally = 0; + + for(AbstractFile file : searchDomain){ + + Long objectId = file.getId(); + + String name = file.getName(); + + String dataSourceString = objectIdToDataSourceMap.get(objectId); + } + return false; } + + static Map mapFileInstancesToDataSource(CommonFilesMetadata metadata){ + return IntraCaseUtils.mapFileInstancesToDataSources(metadata); + } + +// static List getFiles(Set md5s){ +// +// } /** * Close the currently open case, delete the case directory, delete the diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IntraCaseUtils.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IntraCaseUtils.java index 119c9eb5ed..e372cf7af3 100644 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IntraCaseUtils.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IntraCaseUtils.java @@ -195,6 +195,7 @@ class IntraCaseUtils { return instanceIdToDataSource; } + static List getFiles(Set objectIds) { List files = new ArrayList<>(objectIds.size()); From fc6e3b2bbac1e7ee47a6e360b2d26a0ab2dae290 Mon Sep 17 00:00:00 2001 From: Andrew Ziehl Date: Mon, 4 Jun 2018 10:53:41 -0700 Subject: [PATCH 079/287] Fix for inter case case specific results also showing intra-case only matches from the CR. Now only displays results which are in both the current case and specific case. --- .../datamodel/AbstractSqlEamDb.java | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java index 633b86df3c..1a50f5797e 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java @@ -674,7 +674,7 @@ public abstract class AbstractSqlEamDb implements EamDb { singleCase = true; } if (values == null) { - values = new ArrayList(); + values = new ArrayList<>(); } Connection conn = connect(); @@ -705,19 +705,24 @@ public abstract class AbstractSqlEamDb implements EamDb { sql.append(value); sql.append("',"); } - if (values != null) { + if (values.size() > 0) { sql.deleteCharAt(sql.length() - 1); } - sql.append(") GROUP BY value HAVING COUNT(*) > 1)"); // + if (singleCase && correlationCase != null) { - sql.append(" AND "); + sql.append(") AND "); + sql.append(tableName); + sql.append(".case_id=?)"); // inner select checks for other case results + sql.append(" AND ("); sql.append(tableName); sql.append(".case_id=?"); sql.append(" OR "); sql.append(tableName); - sql.append(".case_id=?"); + sql.append(".case_id=?)"); + } else { + sql.append(") GROUP BY value HAVING COUNT(*) > 1)"); // } sql.append(" ORDER BY value, cases.case_name, file_path"); @@ -726,7 +731,8 @@ public abstract class AbstractSqlEamDb implements EamDb { preparedStatement = conn.prepareStatement(sql.toString()); if (singleCase && correlationCase != null) { preparedStatement.setInt(1, correlationCase.getID()); - preparedStatement.setInt(2, currentCaseId); + preparedStatement.setInt(2, correlationCase.getID()); + preparedStatement.setInt(3, currentCaseId); } resultSet = preparedStatement.executeQuery(); From 583b02de4091a746e9f3a309c36b02e93c53264d Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Mon, 4 Jun 2018 15:52:44 -0600 Subject: [PATCH 080/287] 1st pass to address bug where files not in the present case get the wrong name --- .../commonfilesearch/CommonFilesPanel.java | 12 -------- .../EamDbCommonFilesAlgorithm.java | 7 +++-- .../FileInstanceMetadata.java | 10 +++++++ .../autopsy/datamodel/FileInstanceNode.java | 28 +++++++++++++++++-- ...stedWithHashAndFileTypeIntraCaseTests.java | 2 +- .../commonfilessearch/InterCaseUtils.java | 17 +++++++---- 6 files changed, 53 insertions(+), 23 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java index dace725f5e..07464f138d 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java @@ -131,14 +131,6 @@ public final class CommonFilesPanel extends javax.swing.JPanel { this.tabTitle = String.format(CommonFilesPanel_search_results_titleSingle, dataSourceName); } - private void setTitleForAllCases() { - - } - - private void setTitleForSingleCase() { - - } - @Override @SuppressWarnings({"BoxedValueEquality", "NumberEquality"}) protected CommonFilesMetadata doInBackground() throws TskCoreException, NoCurrentCaseException, SQLException, EamDbException, Exception { @@ -270,10 +262,6 @@ public final class CommonFilesPanel extends javax.swing.JPanel { //TODO this should be attached to the intra/inter radio buttons CommonFilesPanel.this.setSearchButtonEnabled(true); - } else { - //TODO error message only? -// MessageNotifyUtil.Message.info(Bundle.IntraCasePanel_setupDataSources_updateUi_noDataSources()); -// SwingUtilities.windowForComponent(IntraCasePanel.this.parent).dispose(); } } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbCommonFilesAlgorithm.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbCommonFilesAlgorithm.java index 0a60b326f2..85453f3d66 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbCommonFilesAlgorithm.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbCommonFilesAlgorithm.java @@ -19,6 +19,7 @@ */ package org.sleuthkit.autopsy.commonfilesearch; +import java.io.File; import java.sql.SQLException; import java.util.ArrayList; import java.util.Collection; @@ -116,6 +117,8 @@ public abstract class EamDbCommonFilesAlgorithm extends CommonFilesMetadataBuild String md5 = instance.getValue(); final String correlationCaseDisplayName = instance.getCorrelationCase().getDisplayName(); String dataSource = String.format("%s: %s", correlationCaseDisplayName, instance.getCorrelationDataSource().getName()); + String path = instance.getFilePath(); + File file = new File(path); if (md5 == null || HashUtility.isNoDataMd5(md5)) { continue; @@ -128,11 +131,11 @@ public abstract class EamDbCommonFilesAlgorithm extends CommonFilesMetadataBuild if(interCaseCommonFiles.containsKey(md5)) { //Add to intercase metaData final Md5Metadata md5Metadata = interCaseCommonFiles.get(md5); - md5Metadata.addFileInstanceMetadata(new FileInstanceMetadata(objectId, dataSource), correlationCaseDisplayName); + md5Metadata.addFileInstanceMetadata(new FileInstanceMetadata(objectId, dataSource, file), correlationCaseDisplayName); } else { Md5Metadata md5Metadata = new Md5Metadata(md5); - md5Metadata.addFileInstanceMetadata(new FileInstanceMetadata(objectId, dataSource), correlationCaseDisplayName); + md5Metadata.addFileInstanceMetadata(new FileInstanceMetadata(objectId, dataSource, file), correlationCaseDisplayName); interCaseCommonFiles.put(md5, md5Metadata); } } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/FileInstanceMetadata.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/FileInstanceMetadata.java index 369e6841c2..9064624d05 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/FileInstanceMetadata.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/FileInstanceMetadata.java @@ -19,6 +19,8 @@ */ package org.sleuthkit.autopsy.commonfilesearch; +import java.io.File; + /** * Encapsulates data required to instantiate a FileInstanceNode. */ @@ -26,6 +28,7 @@ final public class FileInstanceMetadata { private final Long objectId; private final String dataSourceName; + private final File file; /** * Create meta data required to find an abstract file and build a FileInstanceNode. @@ -35,6 +38,13 @@ final public class FileInstanceMetadata { FileInstanceMetadata(Long objectId, String dataSourceName) { this.objectId = objectId; this.dataSourceName = dataSourceName; + this.file = null; + } + + FileInstanceMetadata(Long objectId, String dataSourceName, File file){ + this.objectId = objectId; + this.dataSourceName = dataSourceName; + this.file = file; } /** diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/FileInstanceNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/FileInstanceNode.java index dea5535a26..c4ea2fb979 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/FileInstanceNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/FileInstanceNode.java @@ -18,6 +18,7 @@ */ package org.sleuthkit.autopsy.datamodel; +import java.io.File; import java.util.LinkedHashMap; import java.util.Map; import org.apache.commons.lang3.StringUtils; @@ -32,12 +33,25 @@ import org.sleuthkit.datamodel.AbstractFile; public class FileInstanceNode extends FileNode { private final String dataSource; + private final File file; public FileInstanceNode(AbstractFile fsContent, String dataSource) { super(fsContent); this.content = fsContent; this.dataSource = dataSource; + this.file = null; } + + public FileInstanceNode(AbstractFile fsContent, String dataSource, File file){ + super(fsContent); + this.content = fsContent; + this.dataSource = dataSource; + this.file = file; + } + + //TODO add constructor with correlation attr instance + //TODO override getactions + //TODO use constructor overload that consumes a lookup and pass an instance of this (or a subclas of it) @Override public T accept(DisplayableItemNodeVisitor visitor) { @@ -52,6 +66,14 @@ public class FileInstanceNode extends FileNode { String getDataSource() { return this.dataSource; } + + boolean hasFile(){ + return this.file != null; + } + + File getFile(){ + return this.file; + } @Override protected Sheet createSheet() { @@ -87,8 +109,10 @@ public class FileInstanceNode extends FileNode { */ static private void fillPropertyMap(Map map, FileInstanceNode node) { - map.put(CommonFilePropertyType.File.toString(), node.getName()); - map.put(CommonFilePropertyType.ParentPath.toString(), node.getContent().getParentPath()); + //TODO rather than these ternary operators we should subclass FileInstanceNode or derive an interface + + map.put(CommonFilePropertyType.File.toString(), node.hasFile() ? node.getFile().getName() : node.getName()); + map.put(CommonFilePropertyType.ParentPath.toString(), node.hasFile() ? node.getFile().getParent() : node.getContent().getParentPath()); //TODO this appears to have a bug map.put(CommonFilePropertyType.HashsetHits.toString(), getHashSetHitsForFile(node.getContent())); map.put(CommonFilePropertyType.DataSource.toString(), node.getDataSource()); map.put(CommonFilePropertyType.MimeType.toString(), StringUtils.defaultString(node.content.getMIMEType())); diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileTypeIntraCaseTests.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileTypeIntraCaseTests.java index 33504d3c5e..e9e538c004 100644 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileTypeIntraCaseTests.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileTypeIntraCaseTests.java @@ -115,7 +115,7 @@ public class IngestedWithHashAndFileTypeIntraCaseTests extends NbTestCase { assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, DOC, SET4, 0)); assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET1, 0)); - assertTrue(IntraCaseUtils.verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET2, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET2, 0)); assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET3, 0)); assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET4, 0)); diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/InterCaseUtils.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/InterCaseUtils.java index f3e3ba58f7..4025563d2c 100644 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/InterCaseUtils.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/InterCaseUtils.java @@ -25,9 +25,11 @@ import java.nio.file.Path; import java.nio.file.Paths; import java.sql.SQLException; import java.util.ArrayList; +import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Map.Entry; import org.apache.commons.io.FileUtils; import org.netbeans.junit.NbTestCase; import org.openide.util.Exceptions; @@ -51,6 +53,8 @@ import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationCase; import org.sleuthkit.autopsy.centralrepository.datamodel.EamDb; import org.sleuthkit.autopsy.commonfilesearch.CommonFilesMetadata; import org.sleuthkit.autopsy.commonfilesearch.DataSourceLoader; +import org.sleuthkit.autopsy.commonfilesearch.FileInstanceMetadata; +import org.sleuthkit.autopsy.commonfilesearch.Md5Metadata; import org.sleuthkit.datamodel.AbstractFile; /** @@ -287,17 +291,18 @@ class InterCaseUtils { } } - static boolean verifyInstanceExistanceAndCount(List searchDomain, Map objectIdToDataSourceMap, String fileName, String dataSource, String crCase, int instanceCount){ + static boolean verifyInstanceExistanceAndCount(CommonFilesMetadata searchDomain, String fileName, String dataSource, String crCase, int instanceCount){ int tally = 0; - for(AbstractFile file : searchDomain){ + for(Map.Entry file : searchDomain.getMetadata().entrySet()){ - Long objectId = file.getId(); + Collection fileInstances = file.getValue().getMetadata(); - String name = file.getName(); - - String dataSourceString = objectIdToDataSourceMap.get(objectId); + for(FileInstanceMetadata fileInstance : fileInstances){ + + + } } return false; From ae9d90f91379c92972e24a11e10652296ffabfbf Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Mon, 4 Jun 2018 19:30:44 -0600 Subject: [PATCH 081/287] rename --- .../datamodel/AbstractSqlEamDb.java | 14 +++++++------- ...monInstance.java => CentralRepositoryFile.java} | 4 ++-- .../autopsy/centralrepository/datamodel/EamDb.java | 8 ++++---- .../centralrepository/datamodel/SqliteEamDb.java | 4 ++-- .../EamDbCommonFilesAlgorithm.java | 8 ++++---- .../datamodel/CentralRepoDatamodelTest.java | 10 +++++----- 6 files changed, 24 insertions(+), 24 deletions(-) rename Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/{CorrelationAttributeCommonInstance.java => CentralRepositoryFile.java} (80%) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java index 345543de22..4ee366a638 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java @@ -654,10 +654,10 @@ public abstract class AbstractSqlEamDb implements EamDb { * list of MD5 values; * * @param values MD5s to use as search keys - * @return matching files in the form of CorrelationAttributeCommonInstance + * @return matching files in the form of CentralRepositoryFile * @throws EamDbException */ - public List getArtifactInstancesByCaseValues(Collection values) throws EamDbException { + public List getArtifactInstancesByCaseValues(Collection values) throws EamDbException { //passing null and -1 here has the effect of making this case agnostic: // rather than looking for instances that must appear in a certain case // we accept instances occur in any case @@ -679,7 +679,7 @@ public abstract class AbstractSqlEamDb implements EamDb { * @throws EamDbException if EamDb is inaccessible. */ @Override - public List getArtifactInstancesByCaseValues(CorrelationCase correlationCase, Collection values, int currentCaseId) throws EamDbException { + public List getArtifactInstancesByCaseValues(CorrelationCase correlationCase, Collection values, int currentCaseId) throws EamDbException { CorrelationAttribute.Type aType = CorrelationAttribute.getDefaultCorrelationTypes().get(0); // Files type if (aType == null) { throw new EamDbException("Correlation Type is null"); @@ -689,7 +689,7 @@ public abstract class AbstractSqlEamDb implements EamDb { singleCase = true; } - List artifactInstances = new ArrayList<>(); + List artifactInstances = new ArrayList<>(); if (values != null && !values.isEmpty()) { @@ -734,7 +734,7 @@ public abstract class AbstractSqlEamDb implements EamDb { sql.append(" ORDER BY value, cases.case_name, file_path"); Connection conn = connect(); - CorrelationAttributeCommonInstance artifactInstance; + CentralRepositoryFile artifactInstance; PreparedStatement preparedStatement = null; ResultSet resultSet = null; @@ -2487,11 +2487,11 @@ public abstract class AbstractSqlEamDb implements EamDb { * * @throws SQLException when an expected column name is not in the resultSet */ - private CorrelationAttributeCommonInstance getCommonEamArtifactInstanceFromResultSet(ResultSet resultSet) throws SQLException, EamDbException { + private CentralRepositoryFile getCommonEamArtifactInstanceFromResultSet(ResultSet resultSet) throws SQLException, EamDbException { if (null == resultSet) { return null; } - CorrelationAttributeCommonInstance eamArtifactInstance = new CorrelationAttributeCommonInstance( + CentralRepositoryFile eamArtifactInstance = new CentralRepositoryFile( new CorrelationCase(resultSet.getInt("case_id"), resultSet.getString("case_uid"), resultSet.getString("case_name")), new CorrelationDataSource(-1, resultSet.getInt("case_id"), resultSet.getString("device_id"), resultSet.getString("name")), resultSet.getString("file_path"), diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeCommonInstance.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepositoryFile.java similarity index 80% rename from Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeCommonInstance.java rename to Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepositoryFile.java index ff03b23f5b..95af456038 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeCommonInstance.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepositoryFile.java @@ -25,7 +25,7 @@ import org.sleuthkit.datamodel.TskData; * Common Files Search usage which extends CorrelationAttributeInstance * by adding the MD5 value to match on for the results table. */ -public class CorrelationAttributeCommonInstance extends CorrelationAttributeInstance { +public class CentralRepositoryFile extends CorrelationAttributeInstance { private static final long serialVersionUID = 1L; @@ -34,7 +34,7 @@ public class CorrelationAttributeCommonInstance extends CorrelationAttributeInst */ private final String value; - public CorrelationAttributeCommonInstance(CorrelationCase eamCase, CorrelationDataSource eamDataSource, String filePath, String comment, TskData.FileKnown knownStatus, String value) throws EamDbException { + public CentralRepositoryFile(CorrelationCase eamCase, CorrelationDataSource eamDataSource, String filePath, String comment, TskData.FileKnown knownStatus, String value) throws EamDbException { super(eamCase, eamDataSource, filePath, comment, knownStatus); this.value = value; } diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDb.java index e80ed1e497..fc8b269270 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDb.java @@ -232,19 +232,19 @@ public interface EamDb { * @param values List of ArtifactInstance MD5 values to find matches of. * @param currentCaseId current case * - * @return matching files in the form of CorrelationAttributeCommonInstance + * @return matching files in the form of CentralRepositoryFile */ - List getArtifactInstancesByCaseValues(CorrelationCase correlationCase, Collection values, int currentCaseId) throws EamDbException; + List getArtifactInstancesByCaseValues(CorrelationCase correlationCase, Collection values, int currentCaseId) throws EamDbException; /** * Retrieves eamArtiifact instances from the database that match the given * list of MD5 values; * * @param values MD5s to use as search keys - * @return matching files in the form of CorrelationAttributeCommonInstance + * @return matching files in the form of CentralRepositoryFile * @throws EamDbException */ - List getArtifactInstancesByCaseValues(Collection values) throws EamDbException; + List getArtifactInstancesByCaseValues(Collection values) throws EamDbException; /** * Retrieves eamArtifact instances from the database that are associated diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java index a478a08532..dfbfc45b25 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java @@ -430,7 +430,7 @@ public class SqliteEamDb extends AbstractSqlEamDb { * @return List of artifact instances for a given list of MD5 values */ @Override - public List getArtifactInstancesByCaseValues(Collection values) throws EamDbException { + public List getArtifactInstancesByCaseValues(Collection values) throws EamDbException { try { acquireSharedLock(); return super.getArtifactInstancesByCaseValues(null, values, -1); @@ -449,7 +449,7 @@ public class SqliteEamDb extends AbstractSqlEamDb { * @return List of artifact instances for a given list of MD5 values */ @Override - public List getArtifactInstancesByCaseValues(CorrelationCase correlationCase, Collection values, int currentCaseId) throws EamDbException { + public List getArtifactInstancesByCaseValues(CorrelationCase correlationCase, Collection values, int currentCaseId) throws EamDbException { try { acquireSharedLock(); return super.getArtifactInstancesByCaseValues(correlationCase, values, currentCaseId); diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbCommonFilesAlgorithm.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbCommonFilesAlgorithm.java index 85453f3d66..a42ea26844 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbCommonFilesAlgorithm.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbCommonFilesAlgorithm.java @@ -30,7 +30,7 @@ import java.util.logging.Level; import java.util.stream.Collectors; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; -import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeCommonInstance; +import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepositoryFile; import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationCase; import org.sleuthkit.autopsy.centralrepository.datamodel.EamDb; import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException; @@ -84,7 +84,7 @@ public abstract class EamDbCommonFilesAlgorithm extends CommonFilesMetadataBuild try { // Need to include current Cases results for specific case comparison currentCaseId = dbManager.getCase(Case.getCurrentCase()).getID(); - Collection artifactInstances; + Collection artifactInstances; if(this.dbManager == null){ artifactInstances = new ArrayList<>(0); } else { @@ -108,11 +108,11 @@ public abstract class EamDbCommonFilesAlgorithm extends CommonFilesMetadataBuild return commonFiles; } - private Map gatherIntercaseResults(Collection artifactInstances, Map commonFiles) { + private Map gatherIntercaseResults(Collection artifactInstances, Map commonFiles) { Map interCaseCommonFiles = new HashMap<>(); - for (CorrelationAttributeCommonInstance instance : artifactInstances) { + for (CentralRepositoryFile instance : artifactInstances) { String md5 = instance.getValue(); final String correlationCaseDisplayName = instance.getCorrelationCase().getDisplayName(); diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDatamodelTest.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDatamodelTest.java index 2affee7ec4..8f2abdb655 100755 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDatamodelTest.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDatamodelTest.java @@ -845,11 +845,11 @@ public class CentralRepoDatamodelTest extends TestCase { // Test getting common instances with expected results try { - List instances = EamDb.getInstance().getArtifactInstancesByCaseValues(Arrays.asList(inAllDataSourcesHash, inDataSource1twiceHash)); + List instances = EamDb.getInstance().getArtifactInstancesByCaseValues(Arrays.asList(inAllDataSourcesHash, inDataSource1twiceHash)); assertTrue("getArtifactInstancesByCaseValues returned " + instances.size() + " results - expected 5", instances.size() == 5); // This test works because all the instances of this hash were set to the same path - for (CorrelationAttributeCommonInstance inst : instances) { + for (CentralRepositoryFile inst : instances) { if(inst.getValue().equals(inAllDataSourcesHash)) { assertTrue("getArtifactInstancesByCaseValues returned instance with unexpected path " + inst.getFilePath(), inAllDataSourcesPath.equalsIgnoreCase(inst.getFilePath())); @@ -867,7 +867,7 @@ public class CentralRepoDatamodelTest extends TestCase { // Test getting instances expecting no results because they are not in the case try { CorrelationCase badCase = new CorrelationCase("badCaseUuid", "badCaseName"); - List instances = EamDb.getInstance().getArtifactInstancesByCaseValues(badCase, Arrays.asList(inAllDataSourcesHash, inDataSource1twiceHash), 0); + List instances = EamDb.getInstance().getArtifactInstancesByCaseValues(badCase, Arrays.asList(inAllDataSourcesHash, inDataSource1twiceHash), 0); assertTrue("getArtifactInstancesByTypeValue returned " + instances.size() + " results - expected 0", instances.isEmpty()); } catch (EamDbException ex) { @@ -878,7 +878,7 @@ public class CentralRepoDatamodelTest extends TestCase { // Test getting instances expecting no results because of bad hashes try { - List instances = EamDb.getInstance().getArtifactInstancesByCaseValues(Arrays.asList("xyz", "123")); + List instances = EamDb.getInstance().getArtifactInstancesByCaseValues(Arrays.asList("xyz", "123")); assertTrue("getArtifactInstancesByTypeValue returned " + instances.size() + " results - expected 0", instances.isEmpty()); } catch (EamDbException ex) { @@ -918,7 +918,7 @@ public class CentralRepoDatamodelTest extends TestCase { // Test getting instances with null value // Should just return nothing try { - List instances = EamDb.getInstance().getArtifactInstancesByCaseValues(null); + List instances = EamDb.getInstance().getArtifactInstancesByCaseValues(null); assertTrue("getArtifactInstancesByTypeValue returned non-empty list for null value", instances.isEmpty()); } catch (EamDbException ex) { From b1f914e7567ff918d6e83465e66f073c7fbcbd25 Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Tue, 5 Jun 2018 15:00:28 -0600 Subject: [PATCH 082/287] starting rearchitect of intercase correlation --- .../EamDbCommonFilesAlgorithm.java | 2 + .../FileInstanceMetadata.java | 2 +- .../CentralRepositoryFileInstanceNode.java | 70 +++++++++++++++++++ .../datamodel/DisplayableItemNodeVisitor.java | 11 ++- .../sleuthkit/autopsy/datamodel/Md5Node.java | 4 +- ...ava => SleuthkitCaseFileInstanceNode.java} | 15 ++-- 6 files changed, 94 insertions(+), 10 deletions(-) create mode 100644 Core/src/org/sleuthkit/autopsy/datamodel/CentralRepositoryFileInstanceNode.java rename Core/src/org/sleuthkit/autopsy/datamodel/{FileInstanceNode.java => SleuthkitCaseFileInstanceNode.java} (89%) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbCommonFilesAlgorithm.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbCommonFilesAlgorithm.java index a42ea26844..72547d940f 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbCommonFilesAlgorithm.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbCommonFilesAlgorithm.java @@ -127,6 +127,8 @@ public abstract class EamDbCommonFilesAlgorithm extends CommonFilesMetadataBuild if (commonFiles.containsKey(md5)) { // we don't *have* all the information for the rows in the CR, // so we need to consult the present case via the SleuthkitCase object + + //TODO need to figure out if we have a CR instance or a SK resource and create as appropriate.... Long objectId = commonFiles.get(md5).getMetadata().iterator().next().getObjectId(); if(interCaseCommonFiles.containsKey(md5)) { //Add to intercase metaData diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/FileInstanceMetadata.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/FileInstanceMetadata.java index 9064624d05..bedeabb6d9 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/FileInstanceMetadata.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/FileInstanceMetadata.java @@ -24,7 +24,7 @@ import java.io.File; /** * Encapsulates data required to instantiate a FileInstanceNode. */ -final public class FileInstanceMetadata { +final public class FileInstanceMetadata { //TODO become abstract or interface private final Long objectId; private final String dataSourceName; diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/CentralRepositoryFileInstanceNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/CentralRepositoryFileInstanceNode.java new file mode 100644 index 0000000000..f3161db410 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/datamodel/CentralRepositoryFileInstanceNode.java @@ -0,0 +1,70 @@ +/* + * + * Autopsy Forensic Browser + * + * Copyright 2018 Basis Technology Corp. + * Contact: carrier sleuthkit 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.datamodel; + +import java.util.ArrayList; +import java.util.List; +import javax.swing.Action; +import org.openide.nodes.Children; +import org.openide.util.Lookup; +import org.openide.util.lookup.Lookups; +import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepositoryFile; +import org.sleuthkit.datamodel.AbstractFile; + +/** + * Used by the Common Files search feature to encapsulate instances of a given + * MD5s matched in the search. These nodes will be children of Md5Nodes. + * + * Use this type for files which are not in the current case, but from the + * Central Repo. Contrast with SleuthkitCase which should be used + * when the FileInstance was found in the case presently open in Autopsy. + */ +public class CentralRepositoryFileInstanceNode extends DisplayableItemNode { + + public CentralRepositoryFileInstanceNode(CentralRepositoryFile file, AbstractFile md5Reference) { + super(Children.LEAF, Lookups.fixed(file, md5Reference)); + } + + @Override + public Action[] getActions(boolean context){ + List actionsList = new ArrayList<>(); + + //TODO + + return actionsList.toArray(new Action[actionsList.size()]); + } + + @Override + public T accept(DisplayableItemNodeVisitor visitor) { + return visitor.visit(this); + } + + @Override + public boolean isLeafTypeNode() { + return true; + } + + @Override + public String getItemType() { + //objects of type FileNode will co-coccur in the treetable with objects + // of this type and they will need to provide the same key + return SleuthkitCaseFileInstanceNode.class.getName(); + } +} diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/DisplayableItemNodeVisitor.java b/Core/src/org/sleuthkit/autopsy/datamodel/DisplayableItemNodeVisitor.java index 6d90aa9b0e..504fd74e03 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/DisplayableItemNodeVisitor.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/DisplayableItemNodeVisitor.java @@ -114,9 +114,11 @@ public interface DisplayableItemNodeVisitor { T visit(CommonFilesNode cfn); - T visit(FileInstanceNode fin); + T visit(SleuthkitCaseFileInstanceNode fin); T visit(CommonFileChildNodeLoading cfcnl); + + T visit(CentralRepositoryFileInstanceNode crfin); /* * Tags @@ -187,7 +189,7 @@ public interface DisplayableItemNodeVisitor { protected abstract T defaultVisit(DisplayableItemNode c); @Override - public T visit(FileInstanceNode fin) { + public T visit(SleuthkitCaseFileInstanceNode fin) { return defaultVisit(fin); } @@ -205,6 +207,11 @@ public interface DisplayableItemNodeVisitor { public T visit(CommonFileChildNodeLoading cfcnl) { return defaultVisit(cfcnl); } + + @Override + public T visit(CentralRepositoryFileInstanceNode crfin){ + return defaultVisit(crfin); + } @Override public T visit(DirectoryNode dn) { diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/Md5Node.java b/Core/src/org/sleuthkit/autopsy/datamodel/Md5Node.java index 96de7eba36..87e1ed0272 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/Md5Node.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/Md5Node.java @@ -126,7 +126,7 @@ public class Md5Node extends DisplayableItemNode { } /** - * Child generator for FileInstanceNode of Md5Node. + * Child generator for SleuthkitCaseFileInstanceNode of Md5Node. */ static class FileInstanceNodeFactory extends ChildFactory { @@ -143,7 +143,7 @@ public class Md5Node extends DisplayableItemNode { SleuthkitCase tskDb = currentCase.getSleuthkitCase(); AbstractFile abstractFile = tskDb.findAllFilesWhere(String.format("obj_id in (%s)", file.getObjectId())).get(0); - return new FileInstanceNode(abstractFile, file.getDataSourceName()); + return new SleuthkitCaseFileInstanceNode(abstractFile, file.getDataSourceName()); } catch (NoCurrentCaseException ex) { LOGGER.log(Level.SEVERE, String.format("Unable to create node for file with obj_id: %s.", new Object[]{file.getObjectId()}), ex); } catch (TskCoreException ex) { diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/FileInstanceNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/SleuthkitCaseFileInstanceNode.java similarity index 89% rename from Core/src/org/sleuthkit/autopsy/datamodel/FileInstanceNode.java rename to Core/src/org/sleuthkit/autopsy/datamodel/SleuthkitCaseFileInstanceNode.java index c4ea2fb979..7bdb454bb2 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/FileInstanceNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/SleuthkitCaseFileInstanceNode.java @@ -29,20 +29,25 @@ import org.sleuthkit.datamodel.AbstractFile; /** * Used by the Common Files search feature to encapsulate instances of a given * MD5s matched in the search. These nodes will be children of Md5Nodes. + * + * Use this type for files which are in the current case. Contrast with + * CentralRepositoryFileInstanceNode which should be used when the + * FileInstance was found in some case not presently open in Autopsy, but present + * in the Central Repository. */ -public class FileInstanceNode extends FileNode { +public class SleuthkitCaseFileInstanceNode extends FileNode { private final String dataSource; private final File file; - public FileInstanceNode(AbstractFile fsContent, String dataSource) { + public SleuthkitCaseFileInstanceNode(AbstractFile fsContent, String dataSource) { super(fsContent); this.content = fsContent; this.dataSource = dataSource; this.file = null; } - public FileInstanceNode(AbstractFile fsContent, String dataSource, File file){ + public SleuthkitCaseFileInstanceNode(AbstractFile fsContent, String dataSource, File file){ super(fsContent); this.content = fsContent; this.dataSource = dataSource; @@ -107,9 +112,9 @@ public class FileInstanceNode extends FileNode { * put * @param node The item to get properties for. */ - static private void fillPropertyMap(Map map, FileInstanceNode node) { + static private void fillPropertyMap(Map map, SleuthkitCaseFileInstanceNode node) { - //TODO rather than these ternary operators we should subclass FileInstanceNode or derive an interface + //TODO rather than these ternary operators we should subclass SleuthkitCaseFileInstanceNode or derive an interface map.put(CommonFilePropertyType.File.toString(), node.hasFile() ? node.getFile().getName() : node.getName()); map.put(CommonFilePropertyType.ParentPath.toString(), node.hasFile() ? node.getFile().getParent() : node.getContent().getParentPath()); //TODO this appears to have a bug From 24f58029d2a11da3d5fad10cb1732ef815a4a6f1 Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Tue, 5 Jun 2018 20:12:48 -0600 Subject: [PATCH 083/287] stubbed out getactions on new type --- .../datamodel/CentralRepositoryFileInstanceNode.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/CentralRepositoryFileInstanceNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/CentralRepositoryFileInstanceNode.java index f3161db410..1969e00ec2 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/CentralRepositoryFileInstanceNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/CentralRepositoryFileInstanceNode.java @@ -20,10 +20,10 @@ package org.sleuthkit.autopsy.datamodel; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import javax.swing.Action; import org.openide.nodes.Children; -import org.openide.util.Lookup; import org.openide.util.lookup.Lookups; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepositoryFile; import org.sleuthkit.datamodel.AbstractFile; @@ -46,7 +46,8 @@ public class CentralRepositoryFileInstanceNode extends DisplayableItemNode { public Action[] getActions(boolean context){ List actionsList = new ArrayList<>(); - //TODO + actionsList.addAll(Arrays.asList(super.getActions(true))); + //TODO probably can support more than just this return actionsList.toArray(new Action[actionsList.size()]); } @@ -63,8 +64,8 @@ public class CentralRepositoryFileInstanceNode extends DisplayableItemNode { @Override public String getItemType() { - //objects of type FileNode will co-coccur in the treetable with objects + //objects of type FileNode will co-occur in the treetable with objects // of this type and they will need to provide the same key return SleuthkitCaseFileInstanceNode.class.getName(); - } + } } From 402c8bb45f224e40b6fde49c2487887ebce132e5 Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Tue, 5 Jun 2018 20:42:28 -0600 Subject: [PATCH 084/287] create sheet stuff added --- .../CentralRepositoryFileInstanceNode.java | 81 ++++++++++++++++++- .../SleuthkitCaseFileInstanceNode.java | 42 +++++----- 2 files changed, 97 insertions(+), 26 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/CentralRepositoryFileInstanceNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/CentralRepositoryFileInstanceNode.java index 1969e00ec2..90f9b2e190 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/CentralRepositoryFileInstanceNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/CentralRepositoryFileInstanceNode.java @@ -21,9 +21,13 @@ package org.sleuthkit.autopsy.datamodel; import java.util.ArrayList; import java.util.Arrays; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; import javax.swing.Action; import org.openide.nodes.Children; +import org.openide.nodes.Sheet; +import org.openide.util.NbBundle; import org.openide.util.lookup.Lookups; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepositoryFile; import org.sleuthkit.datamodel.AbstractFile; @@ -38,8 +42,16 @@ import org.sleuthkit.datamodel.AbstractFile; */ public class CentralRepositoryFileInstanceNode extends DisplayableItemNode { - public CentralRepositoryFileInstanceNode(CentralRepositoryFile file, AbstractFile md5Reference) { - super(Children.LEAF, Lookups.fixed(file, md5Reference)); + private CentralRepositoryFile content; + + //this may not be the same file, but at least it is identical, + // and we can use this to support certain actions in the tree table and content viewer + private AbstractFile md5Reference; + + public CentralRepositoryFileInstanceNode(CentralRepositoryFile content, AbstractFile md5Reference) { + super(Children.LEAF, Lookups.fixed(content, md5Reference)); + this.content = content; + this.md5Reference = md5Reference; } @Override @@ -68,4 +80,69 @@ public class CentralRepositoryFileInstanceNode extends DisplayableItemNode { // of this type and they will need to provide the same key return SleuthkitCaseFileInstanceNode.class.getName(); } + + @Override + protected Sheet createSheet(){ + Sheet sheet = new Sheet(); + Sheet.Set sheetSet = sheet.get(Sheet.PROPERTIES); + + if(sheetSet == null){ + sheetSet = Sheet.createPropertiesSet(); + sheet.put(sheetSet); + } + + Map map = new LinkedHashMap<>(); + fillPropertyMap(map, this); + + final String NO_DESCR = Bundle.AbstractFsContentNode_noDesc_text(); + for (CentralRepoFileInstancesPropertyType propType : CentralRepoFileInstancesPropertyType.values()) { + final String propString = propType.toString(); + final Object property = map.get(propString); + final NodeProperty nodeProperty = new NodeProperty<>(propString, propString, NO_DESCR, property); + sheetSet.put(nodeProperty); + } + + return sheet; + } + + private void fillPropertyMap(Map map, CentralRepositoryFileInstanceNode node) { + + map.put(CentralRepositoryFileInstanceNode.CentralRepoFileInstancesPropertyType.File.toString(), node.content.getFilePath()); + map.put(CentralRepositoryFileInstanceNode.CentralRepoFileInstancesPropertyType.ParentPath.toString(), node.content.getFilePath()); + map.put(CentralRepositoryFileInstanceNode.CentralRepoFileInstancesPropertyType.HashsetHits.toString(), ""); + map.put(CentralRepositoryFileInstanceNode.CentralRepoFileInstancesPropertyType.DataSource.toString(), node.content.getCorrelationDataSource().getName()); + map.put(CentralRepositoryFileInstanceNode.CentralRepoFileInstancesPropertyType.MimeType.toString(), ""); + } + + /** + * Encapsulates the columns to be displayed for reach row represented by an + * instance of this object. + */ + @NbBundle.Messages({ + "CentralRepoFileInstancesPropertyType.fileColLbl=File", + "CentralRepoFileInstancesPropertyType.pathColLbl=Parent Path", + "CentralRepoFileInstancesPropertyType.hashsetHitsColLbl=Hash Set Hits", + "CentralRepoFileInstancesPropertyType.dataSourceColLbl=Data Source", + "CentralRepoFileInstancesPropertyType.mimeTypeColLbl=MIME Type" + }) + public enum CentralRepoFileInstancesPropertyType { + + File(Bundle.CentralRepoFileInstancesPropertyType_fileColLbl()), + ParentPath(Bundle.CentralRepoFileInstancesPropertyType_pathColLbl()), + HashsetHits(Bundle.CentralRepoFileInstancesPropertyType_hashsetHitsColLbl()), + DataSource(Bundle.CentralRepoFileInstancesPropertyType_dataSourceColLbl()), + MimeType(Bundle.CentralRepoFileInstancesPropertyType_mimeTypeColLbl()); + + final private String displayString; + + private CentralRepoFileInstancesPropertyType(String displayString) { + this.displayString = displayString; + } + + @Override + public String toString() { + return displayString; + } + } + } diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/SleuthkitCaseFileInstanceNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/SleuthkitCaseFileInstanceNode.java index 7bdb454bb2..d513e00d7d 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/SleuthkitCaseFileInstanceNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/SleuthkitCaseFileInstanceNode.java @@ -53,10 +53,6 @@ public class SleuthkitCaseFileInstanceNode extends FileNode { this.dataSource = dataSource; this.file = file; } - - //TODO add constructor with correlation attr instance - //TODO override getactions - //TODO use constructor overload that consumes a lookup and pass an instance of this (or a subclas of it) @Override public T accept(DisplayableItemNodeVisitor visitor) { @@ -93,7 +89,7 @@ public class SleuthkitCaseFileInstanceNode extends FileNode { fillPropertyMap(map, this); final String NO_DESCR = Bundle.AbstractFsContentNode_noDesc_text(); - for (CommonFilePropertyType propType : CommonFilePropertyType.values()) { + for (SleuthkitCaseFileInstanceNode.SleuthkitCaseFileInstanceNodePropertyType propType : SleuthkitCaseFileInstanceNode.SleuthkitCaseFileInstanceNodePropertyType.values()) { final String propString = propType.toString(); final Object property = map.get(propString); final NodeProperty nodeProperty = new NodeProperty<>(propString, propString, NO_DESCR, property); @@ -114,13 +110,11 @@ public class SleuthkitCaseFileInstanceNode extends FileNode { */ static private void fillPropertyMap(Map map, SleuthkitCaseFileInstanceNode node) { - //TODO rather than these ternary operators we should subclass SleuthkitCaseFileInstanceNode or derive an interface - - map.put(CommonFilePropertyType.File.toString(), node.hasFile() ? node.getFile().getName() : node.getName()); - map.put(CommonFilePropertyType.ParentPath.toString(), node.hasFile() ? node.getFile().getParent() : node.getContent().getParentPath()); //TODO this appears to have a bug - map.put(CommonFilePropertyType.HashsetHits.toString(), getHashSetHitsForFile(node.getContent())); - map.put(CommonFilePropertyType.DataSource.toString(), node.getDataSource()); - map.put(CommonFilePropertyType.MimeType.toString(), StringUtils.defaultString(node.content.getMIMEType())); + map.put(SleuthkitCaseFileInstanceNode.SleuthkitCaseFileInstanceNodePropertyType.File.toString(), node.hasFile() ? node.getFile().getName() : node.getName()); + map.put(SleuthkitCaseFileInstanceNode.SleuthkitCaseFileInstanceNodePropertyType.ParentPath.toString(), node.hasFile() ? node.getFile().getParent() : node.getContent().getParentPath()); //TODO this appears to have a bug + map.put(SleuthkitCaseFileInstanceNode.SleuthkitCaseFileInstanceNodePropertyType.HashsetHits.toString(), getHashSetHitsForFile(node.getContent())); + map.put(SleuthkitCaseFileInstanceNode.SleuthkitCaseFileInstanceNodePropertyType.DataSource.toString(), node.getDataSource()); + map.put(SleuthkitCaseFileInstanceNode.SleuthkitCaseFileInstanceNodePropertyType.MimeType.toString(), StringUtils.defaultString(node.content.getMIMEType())); } /** @@ -128,23 +122,23 @@ public class SleuthkitCaseFileInstanceNode extends FileNode { * instance of this object. */ @NbBundle.Messages({ - "CommonFilePropertyType.fileColLbl=File", - "CommonFilePropertyType.pathColLbl=Parent Path", - "CommonFilePropertyType.hashsetHitsColLbl=Hash Set Hits", - "CommonFilePropertyType.dataSourceColLbl=Data Source", - "CommonFilePropertyType.mimeTypeColLbl=MIME Type" + "SleuthkitCaseFileInstanceNodePropertyType.fileColLbl=File", + "SleuthkitCaseFileInstanceNodePropertyType.pathColLbl=Parent Path", + "SleuthkitCaseFileInstanceNodePropertyType.hashsetHitsColLbl=Hash Set Hits", + "SleuthkitCaseFileInstanceNodePropertyType.dataSourceColLbl=Data Source", + "SleuthkitCaseFileInstanceNodePropertyType.mimeTypeColLbl=MIME Type" }) - public enum CommonFilePropertyType { + public enum SleuthkitCaseFileInstanceNodePropertyType { - File(Bundle.CommonFilePropertyType_fileColLbl()), - ParentPath(Bundle.CommonFilePropertyType_pathColLbl()), - HashsetHits(Bundle.CommonFilePropertyType_hashsetHitsColLbl()), - DataSource(Bundle.CommonFilePropertyType_dataSourceColLbl()), - MimeType(Bundle.CommonFilePropertyType_mimeTypeColLbl()); + File(Bundle.SleuthkitCaseFileInstanceNodePropertyType_fileColLbl()), + ParentPath(Bundle.SleuthkitCaseFileInstanceNodePropertyType_pathColLbl()), + HashsetHits(Bundle.SleuthkitCaseFileInstanceNodePropertyType_hashsetHitsColLbl()), + DataSource(Bundle.SleuthkitCaseFileInstanceNodePropertyType_dataSourceColLbl()), + MimeType(Bundle.SleuthkitCaseFileInstanceNodePropertyType_mimeTypeColLbl()); final private String displayString; - private CommonFilePropertyType(String displayString) { + private SleuthkitCaseFileInstanceNodePropertyType(String displayString) { this.displayString = displayString; } From 59d97f69b4f3babbed51723e7ffac71bfad20b02 Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Tue, 5 Jun 2018 20:50:20 -0600 Subject: [PATCH 085/287] comments --- .../datamodel/CentralRepositoryFileInstanceNode.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/CentralRepositoryFileInstanceNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/CentralRepositoryFileInstanceNode.java index 90f9b2e190..013a14f17b 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/CentralRepositoryFileInstanceNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/CentralRepositoryFileInstanceNode.java @@ -105,7 +105,14 @@ public class CentralRepositoryFileInstanceNode extends DisplayableItemNode { return sheet; } - private void fillPropertyMap(Map map, CentralRepositoryFileInstanceNode node) { + /** + * Fill map with CentralRepoFileInstance properties + * + * @param map map with preserved ordering, where property names/values are + * put + * @param node The item to get properties for. + */ + private static void fillPropertyMap(Map map, CentralRepositoryFileInstanceNode node) { map.put(CentralRepositoryFileInstanceNode.CentralRepoFileInstancesPropertyType.File.toString(), node.content.getFilePath()); map.put(CentralRepositoryFileInstanceNode.CentralRepoFileInstancesPropertyType.ParentPath.toString(), node.content.getFilePath()); From 732eb3133f4240388d08e969724ab198c7960a8d Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Tue, 5 Jun 2018 20:55:57 -0600 Subject: [PATCH 086/287] ziehl figured out how to do this sql server side so we can remove some now redundant code --- .../EamDbCommonFilesAlgorithm.java | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbCommonFilesAlgorithm.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbCommonFilesAlgorithm.java index 72547d940f..30640479b2 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbCommonFilesAlgorithm.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbCommonFilesAlgorithm.java @@ -142,9 +142,6 @@ public abstract class EamDbCommonFilesAlgorithm extends CommonFilesMetadataBuild } } } - - //ideally we would do this step via SQL in EamDb.getArtifactInstancesByCaseValues - removeEntriesWithinOnlyOneCase(interCaseCommonFiles); return interCaseCommonFiles; } @@ -171,18 +168,4 @@ public abstract class EamDbCommonFilesAlgorithm extends CommonFilesMetadataBuild } throw new Exception("Cannot locate case."); } - - private void removeEntriesWithinOnlyOneCase(Map interCaseCommonFiles) { - Collection toRemove = new ArrayList<>(); - - for(Map.Entry entry : interCaseCommonFiles.entrySet()){ - if(!entry.getValue().isMultiDataSource()){ - toRemove.add(entry.getKey()); - } - } - - for(String bogusEntry : toRemove){ - interCaseCommonFiles.remove(bogusEntry); - } - } } From e8718c61e8ab46204790c2f8cec5e46888882f0f Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Tue, 5 Jun 2018 22:47:41 -0600 Subject: [PATCH 087/287] more uneeded code --- .../autopsy/commonfilesearch/Md5Metadata.java | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/Md5Metadata.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/Md5Metadata.java index 916d6950a8..6f9e2472e7 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/Md5Metadata.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/Md5Metadata.java @@ -33,19 +33,15 @@ final public class Md5Metadata { private final String md5; private final List fileInstances; - - private final Set distinctCases; - + Md5Metadata(String md5, List fileInstances){ this.md5 = md5; this.fileInstances = fileInstances; - this.distinctCases = new HashSet<>(); } Md5Metadata(String md5){ this.md5 = md5; this.fileInstances = new ArrayList<>(); - this.distinctCases = new HashSet<>(); } public String getMd5(){ @@ -58,9 +54,6 @@ final public class Md5Metadata { void addFileInstanceMetadata(FileInstanceMetadata metadata, String caseName){ this.fileInstances.add(metadata); - if(!this.distinctCases.contains(caseName)){ - this.distinctCases.add(caseName); - } } public Collection getMetadata(){ @@ -82,8 +75,4 @@ final public class Md5Metadata { } return String.join(", ", sources); } - - boolean isMultiDataSource() { - return this.distinctCases.size() > 1; - } } From 2dc5ccb113868cb9ce8a2a6573c31d19e3591876 Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Tue, 5 Jun 2018 22:50:19 -0600 Subject: [PATCH 088/287] cleanup --- .../centralrepository/datamodel/CentralRepositoryFile.java | 3 +-- .../autopsy/commonfilesearch/EamDbCommonFilesAlgorithm.java | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepositoryFile.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepositoryFile.java index 95af456038..6fcc50b60a 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepositoryFile.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepositoryFile.java @@ -41,6 +41,5 @@ public class CentralRepositoryFile extends CorrelationAttributeInstance { public String getValue() { return value; - } - + } } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbCommonFilesAlgorithm.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbCommonFilesAlgorithm.java index 30640479b2..10baa5cdc0 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbCommonFilesAlgorithm.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbCommonFilesAlgorithm.java @@ -154,7 +154,6 @@ public abstract class EamDbCommonFilesAlgorithm extends CommonFilesMetadataBuild @Override protected String buildTabTitle() { - //TODO come back to this final String buildCategorySelectionString = this.buildCategorySelectionString(); final String titleTemplate = Bundle.CommonFilesMetadataBuilder_buildTabTitle_titleEamDb(); return String.format(titleTemplate, new Object[]{buildCategorySelectionString}); From 4c0984c6d28c4584c99c83ce5d7bbc11f261d4c6 Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Tue, 5 Jun 2018 23:42:20 -0600 Subject: [PATCH 089/287] wip - created new node type to support cr files being displayed in tree table --- .../EamDbCommonFilesAlgorithm.java | 7 ++-- .../FileInstanceMetadata.java | 26 +++++++++---- .../CentralRepositoryFileInstanceNode.java | 23 ++++++++---- .../sleuthkit/autopsy/datamodel/Md5Node.java | 37 ++++++++++++------- .../SleuthkitCaseFileInstanceNode.java | 22 +---------- 5 files changed, 65 insertions(+), 50 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbCommonFilesAlgorithm.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbCommonFilesAlgorithm.java index 10baa5cdc0..443f7d98b4 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbCommonFilesAlgorithm.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbCommonFilesAlgorithm.java @@ -118,7 +118,7 @@ public abstract class EamDbCommonFilesAlgorithm extends CommonFilesMetadataBuild final String correlationCaseDisplayName = instance.getCorrelationCase().getDisplayName(); String dataSource = String.format("%s: %s", correlationCaseDisplayName, instance.getCorrelationDataSource().getName()); String path = instance.getFilePath(); - File file = new File(path); + File filePath = new File(path); if (md5 == null || HashUtility.isNoDataMd5(md5)) { continue; @@ -128,16 +128,17 @@ public abstract class EamDbCommonFilesAlgorithm extends CommonFilesMetadataBuild // we don't *have* all the information for the rows in the CR, // so we need to consult the present case via the SleuthkitCase object + //TODO resume here!!! //TODO need to figure out if we have a CR instance or a SK resource and create as appropriate.... Long objectId = commonFiles.get(md5).getMetadata().iterator().next().getObjectId(); if(interCaseCommonFiles.containsKey(md5)) { //Add to intercase metaData final Md5Metadata md5Metadata = interCaseCommonFiles.get(md5); - md5Metadata.addFileInstanceMetadata(new FileInstanceMetadata(objectId, dataSource, file), correlationCaseDisplayName); + md5Metadata.addFileInstanceMetadata(new FileInstanceMetadata(objectId, dataSource), correlationCaseDisplayName); } else { Md5Metadata md5Metadata = new Md5Metadata(md5); - md5Metadata.addFileInstanceMetadata(new FileInstanceMetadata(objectId, dataSource, file), correlationCaseDisplayName); + md5Metadata.addFileInstanceMetadata(new FileInstanceMetadata(objectId, dataSource), correlationCaseDisplayName); interCaseCommonFiles.put(md5, md5Metadata); } } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/FileInstanceMetadata.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/FileInstanceMetadata.java index bedeabb6d9..f27dcafe48 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/FileInstanceMetadata.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/FileInstanceMetadata.java @@ -20,6 +20,8 @@ package org.sleuthkit.autopsy.commonfilesearch; import java.io.File; +import org.openide.nodes.Node; +import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepositoryFile; /** * Encapsulates data required to instantiate a FileInstanceNode. @@ -28,23 +30,25 @@ final public class FileInstanceMetadata { //TODO become abstract or interface private final Long objectId; private final String dataSourceName; - private final File file; + private final CentralRepositoryFile crFile; /** * Create meta data required to find an abstract file and build a FileInstanceNode. * @param objectId id of abstract file to find * @param dataSourceName name of datasource where the object is found */ - FileInstanceMetadata(Long objectId, String dataSourceName) { + FileInstanceMetadata (Long objectId, String dataSourceName) { this.objectId = objectId; this.dataSourceName = dataSourceName; - this.file = null; + this.crFile = null; } - FileInstanceMetadata(Long objectId, String dataSourceName, File file){ - this.objectId = objectId; - this.dataSourceName = dataSourceName; - this.file = file; + FileInstanceMetadata (CentralRepositoryFile crFile){ + //TODO should we actually just take an ID instead of the whole object + // like we've done previously, or is this ok? + this.objectId = null; + this.dataSourceName = null; + this.crFile = crFile; } /** @@ -62,4 +66,12 @@ final public class FileInstanceMetadata { //TODO become abstract or interface public String getDataSourceName(){ return this.dataSourceName; } + + public boolean isPresentInCurrentCase() { + return this.crFile != null; + } + + public CentralRepositoryFile getCentralRepoFileInstance() { + return this.crFile; + } } diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/CentralRepositoryFileInstanceNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/CentralRepositoryFileInstanceNode.java index 013a14f17b..dc3335aa44 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/CentralRepositoryFileInstanceNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/CentralRepositoryFileInstanceNode.java @@ -31,6 +31,7 @@ import org.openide.util.NbBundle; import org.openide.util.lookup.Lookups; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepositoryFile; import org.sleuthkit.datamodel.AbstractFile; +import org.sleuthkit.datamodel.Content; /** * Used by the Common Files search feature to encapsulate instances of a given @@ -42,18 +43,26 @@ import org.sleuthkit.datamodel.AbstractFile; */ public class CentralRepositoryFileInstanceNode extends DisplayableItemNode { - private CentralRepositoryFile content; + private final CentralRepositoryFile crFile; //this may not be the same file, but at least it is identical, - // and we can use this to support certain actions in the tree table and content viewer - private AbstractFile md5Reference; + // and we can use this to support certain actions in the tree table and crFile viewer + private final AbstractFile md5Reference; public CentralRepositoryFileInstanceNode(CentralRepositoryFile content, AbstractFile md5Reference) { super(Children.LEAF, Lookups.fixed(content, md5Reference)); - this.content = content; + this.crFile = content; this.md5Reference = md5Reference; } + public CentralRepositoryFile getCentralRepoFile(){ + return this.crFile; + } + + public Content getContent(){ + return this.md5Reference; + } + @Override public Action[] getActions(boolean context){ List actionsList = new ArrayList<>(); @@ -114,10 +123,10 @@ public class CentralRepositoryFileInstanceNode extends DisplayableItemNode { */ private static void fillPropertyMap(Map map, CentralRepositoryFileInstanceNode node) { - map.put(CentralRepositoryFileInstanceNode.CentralRepoFileInstancesPropertyType.File.toString(), node.content.getFilePath()); - map.put(CentralRepositoryFileInstanceNode.CentralRepoFileInstancesPropertyType.ParentPath.toString(), node.content.getFilePath()); + map.put(CentralRepositoryFileInstanceNode.CentralRepoFileInstancesPropertyType.File.toString(), node.crFile.getFilePath()); + map.put(CentralRepositoryFileInstanceNode.CentralRepoFileInstancesPropertyType.ParentPath.toString(), node.crFile.getFilePath()); map.put(CentralRepositoryFileInstanceNode.CentralRepoFileInstancesPropertyType.HashsetHits.toString(), ""); - map.put(CentralRepositoryFileInstanceNode.CentralRepoFileInstancesPropertyType.DataSource.toString(), node.content.getCorrelationDataSource().getName()); + map.put(CentralRepositoryFileInstanceNode.CentralRepoFileInstancesPropertyType.DataSource.toString(), node.crFile.getCorrelationDataSource().getName()); map.put(CentralRepositoryFileInstanceNode.CentralRepoFileInstancesPropertyType.MimeType.toString(), ""); } diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/Md5Node.java b/Core/src/org/sleuthkit/autopsy/datamodel/Md5Node.java index 87e1ed0272..4c7f5a497d 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/Md5Node.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/Md5Node.java @@ -31,6 +31,7 @@ import org.openide.util.NbBundle; import org.openide.util.lookup.Lookups; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; +import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepositoryFile; import org.sleuthkit.autopsy.commonfilesearch.FileInstanceMetadata; import org.sleuthkit.autopsy.commonfilesearch.Md5Metadata; import org.sleuthkit.autopsy.coreutils.Logger; @@ -40,14 +41,14 @@ import org.sleuthkit.datamodel.TskCoreException; /** * Represents a common files match - two or more files which appear to be the - * same file and appear as children of this node. This node will simply contain + * same file and appear as children of this node. This node will simply contain * the MD5 of the matched files, the data sources those files were found within, * and a count of the instances represented by the md5. */ public class Md5Node extends DisplayableItemNode { - - private static final Logger LOGGER = Logger.getLogger(Md5Node.class.getName()); - + + private static final Logger LOGGER = Logger.getLogger(Md5Node.class.getName()); + private final String md5Hash; private final int commonFileCount; private final String dataSources; @@ -56,7 +57,7 @@ public class Md5Node extends DisplayableItemNode { super(Children.create( new FileInstanceNodeFactory(data), true), Lookups.singleton(data.getMd5())); - + this.commonFileCount = data.size(); this.dataSources = String.join(", ", data.getDataSources()); this.md5Hash = data.getMd5(); @@ -126,7 +127,8 @@ public class Md5Node extends DisplayableItemNode { } /** - * Child generator for SleuthkitCaseFileInstanceNode of Md5Node. + * Child generator for SleuthkitCaseFileInstanceNode of + * Md5Node. */ static class FileInstanceNodeFactory extends ChildFactory { @@ -138,22 +140,31 @@ public class Md5Node extends DisplayableItemNode { @Override protected Node createNodeForKey(FileInstanceMetadata file) { + try { Case currentCase = Case.getCurrentCaseThrows(); SleuthkitCase tskDb = currentCase.getSleuthkitCase(); + AbstractFile abstractFile = tskDb.findAllFilesWhere(String.format("obj_id in (%s)", file.getObjectId())).get(0); - - return new SleuthkitCaseFileInstanceNode(abstractFile, file.getDataSourceName()); - } catch (NoCurrentCaseException ex) { - LOGGER.log(Level.SEVERE, String.format("Unable to create node for file with obj_id: %s.", new Object[]{file.getObjectId()}), ex); - } catch (TskCoreException ex) { - LOGGER.log(Level.SEVERE, String.format("Unable to create node for file with obj_id: %s.", new Object[]{file.getObjectId()}), ex); + + //TODO it would be an improvement to utilize some sort of polymorphism + // (interface with getNode is probably plenty) rather than this conditional + if (file.isPresentInCurrentCase()) { + return new SleuthkitCaseFileInstanceNode(abstractFile, file.getDataSourceName()); + } else { + CentralRepositoryFile crFile = file.getCentralRepoFileInstance(); + return new CentralRepositoryFileInstanceNode(crFile, abstractFile); + } + + } catch (NoCurrentCaseException | TskCoreException ex) { + LOGGER.log(Level.SEVERE, String.format("Unable to find AbstractFile for record with obj_id: %s. Node not created.", new Object[]{file.getObjectId()}), ex); } + return null; } @Override - protected boolean createKeys(List list) { + protected boolean createKeys(List list) { list.addAll(this.descendants.getMetadata()); return true; } diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/SleuthkitCaseFileInstanceNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/SleuthkitCaseFileInstanceNode.java index d513e00d7d..539e435743 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/SleuthkitCaseFileInstanceNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/SleuthkitCaseFileInstanceNode.java @@ -18,7 +18,6 @@ */ package org.sleuthkit.autopsy.datamodel; -import java.io.File; import java.util.LinkedHashMap; import java.util.Map; import org.apache.commons.lang3.StringUtils; @@ -38,20 +37,11 @@ import org.sleuthkit.datamodel.AbstractFile; public class SleuthkitCaseFileInstanceNode extends FileNode { private final String dataSource; - private final File file; public SleuthkitCaseFileInstanceNode(AbstractFile fsContent, String dataSource) { super(fsContent); this.content = fsContent; this.dataSource = dataSource; - this.file = null; - } - - public SleuthkitCaseFileInstanceNode(AbstractFile fsContent, String dataSource, File file){ - super(fsContent); - this.content = fsContent; - this.dataSource = dataSource; - this.file = file; } @Override @@ -67,14 +57,6 @@ public class SleuthkitCaseFileInstanceNode extends FileNode { String getDataSource() { return this.dataSource; } - - boolean hasFile(){ - return this.file != null; - } - - File getFile(){ - return this.file; - } @Override protected Sheet createSheet() { @@ -110,8 +92,8 @@ public class SleuthkitCaseFileInstanceNode extends FileNode { */ static private void fillPropertyMap(Map map, SleuthkitCaseFileInstanceNode node) { - map.put(SleuthkitCaseFileInstanceNode.SleuthkitCaseFileInstanceNodePropertyType.File.toString(), node.hasFile() ? node.getFile().getName() : node.getName()); - map.put(SleuthkitCaseFileInstanceNode.SleuthkitCaseFileInstanceNodePropertyType.ParentPath.toString(), node.hasFile() ? node.getFile().getParent() : node.getContent().getParentPath()); //TODO this appears to have a bug + map.put(SleuthkitCaseFileInstanceNode.SleuthkitCaseFileInstanceNodePropertyType.File.toString(), node.getName()); + map.put(SleuthkitCaseFileInstanceNode.SleuthkitCaseFileInstanceNodePropertyType.ParentPath.toString(), node.getContent().getParentPath()); map.put(SleuthkitCaseFileInstanceNode.SleuthkitCaseFileInstanceNodePropertyType.HashsetHits.toString(), getHashSetHitsForFile(node.getContent())); map.put(SleuthkitCaseFileInstanceNode.SleuthkitCaseFileInstanceNodePropertyType.DataSource.toString(), node.getDataSource()); map.put(SleuthkitCaseFileInstanceNode.SleuthkitCaseFileInstanceNodePropertyType.MimeType.toString(), StringUtils.defaultString(node.content.getMIMEType())); From 71ab71410c6fe8106add75facd9f0527b2de638e Mon Sep 17 00:00:00 2001 From: Andrew Ziehl Date: Wed, 6 Jun 2018 10:09:50 -0700 Subject: [PATCH 090/287] Move more of root node construction to background thread, to make common files search lazier --- .../commonfilesearch/CommonFilesPanel.form | 5 +---- .../commonfilesearch/CommonFilesPanel.java | 21 ++++++++++--------- 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.form b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.form index 11d5ad88d4..e51aedbef3 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.form +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.form @@ -32,10 +32,7 @@ - - - - + diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java index 07464f138d..c957548821 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java @@ -115,7 +115,7 @@ public final class CommonFilesPanel extends javax.swing.JPanel { private void search() { String pathText = Bundle.CommonFilesPanel_search_results_pathText(); - new SwingWorker() { + new SwingWorker() { private String tabTitle; private ProgressHandle progress; @@ -133,7 +133,7 @@ public final class CommonFilesPanel extends javax.swing.JPanel { @Override @SuppressWarnings({"BoxedValueEquality", "NumberEquality"}) - protected CommonFilesMetadata doInBackground() throws TskCoreException, NoCurrentCaseException, SQLException, EamDbException, Exception { + protected TableFilterNode doInBackground() throws TskCoreException, NoCurrentCaseException, SQLException, EamDbException, Exception { progress = ProgressHandle.createHandle(Bundle.CommonFilesPanel_search_done_searchProgress1()); progress.start(); progress.switchToIndeterminate(); @@ -180,7 +180,13 @@ public final class CommonFilesPanel extends javax.swing.JPanel { this.tabTitle = builder.buildTabTitle(); - return metadata; + CommonFilesNode commonFilesNode = new CommonFilesNode(metadata); + + DataResultFilterNode dataResultFilterNode = new DataResultFilterNode(commonFilesNode, ExplorerManager.find(CommonFilesPanel.this)); + + TableFilterNode tableFilterWithDescendantsNode = new TableFilterNode(dataResultFilterNode); + + return tableFilterWithDescendantsNode; } @Override @@ -188,20 +194,15 @@ public final class CommonFilesPanel extends javax.swing.JPanel { try { super.done(); progress.setDisplayName(Bundle.CommonFilesPanel_search_done_searchProgress2()); - CommonFilesMetadata metadata = get(); + TableFilterNode tableFilterWithDescendantsNode = get(); - CommonFilesNode commonFilesNode = new CommonFilesNode(metadata); - - DataResultFilterNode dataResultFilterNode = new DataResultFilterNode(commonFilesNode, ExplorerManager.find(CommonFilesPanel.this)); - - TableFilterNode tableFilterWithDescendantsNode = new TableFilterNode(dataResultFilterNode); DataResultViewerTable table = new DataResultViewerTable(); Collection viewers = new ArrayList<>(1); viewers.add(table); progress.setDisplayName(Bundle.CommonFilesPanel_search_done_searchProgress3()); - DataResultTopComponent.createInstance(tabTitle, pathText, tableFilterWithDescendantsNode, metadata.size(), viewers); + DataResultTopComponent.createInstance(tabTitle, pathText, tableFilterWithDescendantsNode, 0, viewers); progress.finish(); } catch (InterruptedException ex) { LOGGER.log(Level.SEVERE, "Interrupted while loading Common Files", ex); From 69b6eb14faa98ffce70aefb243b0b65ed3235e0c Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Wed, 6 Jun 2018 18:12:03 -0600 Subject: [PATCH 091/287] more progress --- ...ralRepositoryCaseFileInstanceMetadata.java | 46 ++++++ .../CommonFilesMetadataBuilder.java | 10 +- .../EamDbCommonFilesAlgorithm.java | 8 +- .../FileInstanceNodeGenerator.java | 132 ++++++++++++++++++ .../autopsy/commonfilesearch/Md5Metadata.java | 14 +- ...=> SleuthkitCaseFileInstanceMetadata.java} | 49 ++----- .../sleuthkit/autopsy/datamodel/Md5Node.java | 35 ++--- .../commonfilessearch/InterCaseUtils.java | 6 +- .../commonfilessearch/IntraCaseUtils.java | 4 +- 9 files changed, 221 insertions(+), 83 deletions(-) create mode 100644 Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepositoryCaseFileInstanceMetadata.java create mode 100644 Core/src/org/sleuthkit/autopsy/commonfilesearch/FileInstanceNodeGenerator.java rename Core/src/org/sleuthkit/autopsy/commonfilesearch/{FileInstanceMetadata.java => SleuthkitCaseFileInstanceMetadata.java} (50%) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepositoryCaseFileInstanceMetadata.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepositoryCaseFileInstanceMetadata.java new file mode 100644 index 0000000000..2f3a1158be --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepositoryCaseFileInstanceMetadata.java @@ -0,0 +1,46 @@ +/* + * + * Autopsy Forensic Browser + * + * Copyright 2018 Basis Technology Corp. + * Contact: carrier sleuthkit 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.commonfilesearch; + +import java.util.Map; +import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepositoryFile; +import org.sleuthkit.autopsy.datamodel.CentralRepositoryFileInstanceNode; +import org.sleuthkit.autopsy.datamodel.DisplayableItemNode; +import org.sleuthkit.datamodel.AbstractFile; + +/** + * Generates a DisplayableItmeNode using a CentralRepositoryFile. + */ +public class CentralRepositoryCaseFileInstanceMetadata extends FileInstanceNodeGenerator { + + private CentralRepositoryFile crFile; + + CentralRepositoryCaseFileInstanceMetadata(CentralRepositoryFile crFile, Long abstractFileReference, Map cachedFiles, String dataSource){ + super(abstractFileReference, cachedFiles, dataSource); + //TODO should we actually just take an ID instead of the whole object + // like we've done previously, or is this ok? + this.crFile = crFile; + } + + @Override + public DisplayableItemNode generateNode() { + return new CentralRepositoryFileInstanceNode(this.crFile, this.lookupOrCreateAbstractFile()); + } +} diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesMetadataBuilder.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesMetadataBuilder.java index 41c21f1dff..84333ba521 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesMetadataBuilder.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesMetadataBuilder.java @@ -32,6 +32,7 @@ import java.util.stream.Stream; import org.openide.util.NbBundle; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; +import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.HashUtility; import org.sleuthkit.datamodel.SleuthkitCase; import org.sleuthkit.datamodel.SleuthkitCase.CaseDbQuery; @@ -172,6 +173,8 @@ public abstract class CommonFilesMetadataBuilder { SleuthkitCase sleuthkitCase = Case.getCurrentCaseThrows().getSleuthkitCase(); String selectStatement = this.buildSqlSelectStatement(); + + Map fileCache = new HashMap<>(); try ( CaseDbQuery query = sleuthkitCase.executeQuery(selectStatement); @@ -189,11 +192,10 @@ public abstract class CommonFilesMetadataBuilder { if (commonFiles.containsKey(md5)) { final Md5Metadata md5Metadata = commonFiles.get(md5); - md5Metadata.addFileInstanceMetadata(new FileInstanceMetadata(objectId, dataSource)); + md5Metadata.addFileInstanceMetadata(new SleuthkitCaseFileInstanceMetadata(objectId, fileCache, dataSource)); } else { - final List fileInstances = new ArrayList<>(); - fileInstances.add(new FileInstanceMetadata(objectId, dataSource)); - Md5Metadata md5Metadata = new Md5Metadata(md5, fileInstances); + final Md5Metadata md5Metadata = new Md5Metadata(md5); + md5Metadata.addFileInstanceMetadata(new SleuthkitCaseFileInstanceMetadata(objectId, fileCache, dataSource)); commonFiles.put(md5, md5Metadata); } } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbCommonFilesAlgorithm.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbCommonFilesAlgorithm.java index 443f7d98b4..4fc7632919 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbCommonFilesAlgorithm.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbCommonFilesAlgorithm.java @@ -111,6 +111,7 @@ public abstract class EamDbCommonFilesAlgorithm extends CommonFilesMetadataBuild private Map gatherIntercaseResults(Collection artifactInstances, Map commonFiles) { Map interCaseCommonFiles = new HashMap<>(); + Map cachedFiles = new HashMap<>(); for (CentralRepositoryFile instance : artifactInstances) { @@ -130,15 +131,16 @@ public abstract class EamDbCommonFilesAlgorithm extends CommonFilesMetadataBuild //TODO resume here!!! //TODO need to figure out if we have a CR instance or a SK resource and create as appropriate.... - Long objectId = commonFiles.get(md5).getMetadata().iterator().next().getObjectId(); + Long objectId = commonFiles.get(md5).getMetadata().iterator().next().getIdenticalFileSleuthkitCaseObjectID(); + if(interCaseCommonFiles.containsKey(md5)) { //Add to intercase metaData final Md5Metadata md5Metadata = interCaseCommonFiles.get(md5); - md5Metadata.addFileInstanceMetadata(new FileInstanceMetadata(objectId, dataSource), correlationCaseDisplayName); + md5Metadata.addFileInstanceMetadata(new SleuthkitCaseFileInstanceMetadata(objectId, dataSource), correlationCaseDisplayName); } else { Md5Metadata md5Metadata = new Md5Metadata(md5); - md5Metadata.addFileInstanceMetadata(new FileInstanceMetadata(objectId, dataSource), correlationCaseDisplayName); + md5Metadata.addFileInstanceMetadata(new SleuthkitCaseFileInstanceMetadata(objectId, dataSource), correlationCaseDisplayName); interCaseCommonFiles.put(md5, md5Metadata); } } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/FileInstanceNodeGenerator.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/FileInstanceNodeGenerator.java new file mode 100644 index 0000000000..f4706332b7 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/FileInstanceNodeGenerator.java @@ -0,0 +1,132 @@ +/* + * + * Autopsy Forensic Browser + * + * Copyright 2018 Basis Technology Corp. + * Contact: carrier sleuthkit 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.commonfilesearch; + +import java.util.Map; +import java.util.logging.Level; +import org.openide.util.Exceptions; +import org.sleuthkit.autopsy.casemodule.Case; +import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; +import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepositoryFile; +import org.sleuthkit.autopsy.coreutils.Logger; +import org.sleuthkit.autopsy.datamodel.CentralRepositoryFileInstanceNode; +import org.sleuthkit.autopsy.datamodel.DisplayableItemNode; +import org.sleuthkit.autopsy.datamodel.SleuthkitCaseFileInstanceNode; +import org.sleuthkit.datamodel.AbstractFile; +import org.sleuthkit.datamodel.SleuthkitCase; +import org.sleuthkit.datamodel.TskCoreException; + +/** + * Defines types which can be used to get some sort of File Instance node (a + * child of the MD5Node) for use in the common files tree table. + */ +public abstract class FileInstanceNodeGenerator { + + private static final Logger LOGGER = Logger.getLogger(FileInstanceNodeGenerator.class.getName()); + protected Long abstractFileReference; + protected Map cachedFiles; + private String dataSource; + + public FileInstanceNodeGenerator(Long abstractFileReference, Map cachedFiles, String dataSource){ + this.abstractFileReference = abstractFileReference; + this.cachedFiles = cachedFiles; + this.dataSource = dataSource; + } + + /** + * Grab a cached instance of the AbstractFile or grab one from the + * SleuthkitCase. Use this in implementations of generateNode. + * + * @param objectId + * @param cachedFiles + * @return AbstractFile which is identical to the file instance generated by + * implementations of this object + */ + protected AbstractFile lookupOrCreateAbstractFile() { + if (this.cachedFiles.containsKey(this.abstractFileReference)) { + return this.cachedFiles.get(this.abstractFileReference); + } else { + AbstractFile file = FileInstanceNodeGenerator.loadFileFromSleuthkitCase(this.abstractFileReference); + this.cachedFiles.put(this.abstractFileReference, file); + return file; + } + } + + private static AbstractFile loadFileFromSleuthkitCase(Long objectId) { + + Case currentCase; + try { + currentCase = Case.getCurrentCaseThrows(); + + SleuthkitCase tskDb = currentCase.getSleuthkitCase(); + + AbstractFile abstractFile = tskDb.findAllFilesWhere(String.format("obj_id in (%s)", objectId)).get(0); + + return abstractFile; + + } catch (TskCoreException | NoCurrentCaseException ex) { + LOGGER.log(Level.SEVERE, String.format("Unable to find AbstractFile for record with obj_id: %s. Node not created.", new Object[]{objectId}), ex); + return null; + } + } + + private static AbstractFile lookupOrCreateAbstractFile(Long objectId, Map cachedFiles){ + if (cachedFiles.containsKey(objectId)) { + return cachedFiles.get(objectId); + } else { + AbstractFile file = FileInstanceNodeGenerator.loadFileFromSleuthkitCase(objectId); + cachedFiles.put(objectId, file); + return file; + } + } + + /** + * Create a node which is a child of the MD5Node, to be used to display a + * row in the tree table + * + * @return child row node + */ + public abstract DisplayableItemNode generateNode(); + + /** + * Get string name of the data source where this instance appears. + * + * @return + */ + public String getDataSource(){ + + /** + * Even though we could get this from the CR record or the AbstractFile, + * we want to avoid getting it from the AbstractFile because it would be an + * extra database roundtrip. + */ + return this.dataSource; + } + + public Long getIdenticalFileSleuthkitCaseObjectID(){ + return this.abstractFileReference; + } + + public static FileInstanceNodeGenerator createInstance(Long objectId, CentralRepositoryFile instance, Map cachedFiles){ + AbstractFile referenceFile = FileInstanceNodeGenerator.lookupOrCreateAbstractFile(objectId, cachedFiles); + + + } +} diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/Md5Metadata.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/Md5Metadata.java index 6f9e2472e7..2ab8db4ee3 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/Md5Metadata.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/Md5Metadata.java @@ -32,9 +32,9 @@ import java.util.Set; final public class Md5Metadata { private final String md5; - private final List fileInstances; + private final List fileInstances; - Md5Metadata(String md5, List fileInstances){ + Md5Metadata(String md5, List fileInstances){ this.md5 = md5; this.fileInstances = fileInstances; } @@ -48,15 +48,15 @@ final public class Md5Metadata { return this.md5; } - void addFileInstanceMetadata(FileInstanceMetadata metadata){ + void addFileInstanceMetadata(FileInstanceNodeGenerator metadata){ this.fileInstances.add(metadata); } - void addFileInstanceMetadata(FileInstanceMetadata metadata, String caseName){ + void addFileInstanceMetadata(SleuthkitCaseFileInstanceMetadata metadata, String caseName){ this.fileInstances.add(metadata); } - public Collection getMetadata(){ + public Collection getMetadata(){ return Collections.unmodifiableCollection(this.fileInstances); } @@ -70,8 +70,8 @@ final public class Md5Metadata { public String getDataSources() { Set sources = new HashSet<> (); - for(FileInstanceMetadata data : this.fileInstances){ - sources.add(data.getDataSourceName()); + for(FileInstanceNodeGenerator data : this.fileInstances){ + sources.add(data.getDataSource()); } return String.join(", ", sources); } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/FileInstanceMetadata.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/SleuthkitCaseFileInstanceMetadata.java similarity index 50% rename from Core/src/org/sleuthkit/autopsy/commonfilesearch/FileInstanceMetadata.java rename to Core/src/org/sleuthkit/autopsy/commonfilesearch/SleuthkitCaseFileInstanceMetadata.java index f27dcafe48..a1139aeb44 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/FileInstanceMetadata.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/SleuthkitCaseFileInstanceMetadata.java @@ -20,58 +20,29 @@ package org.sleuthkit.autopsy.commonfilesearch; import java.io.File; +import java.util.Map; import org.openide.nodes.Node; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepositoryFile; +import org.sleuthkit.autopsy.datamodel.DisplayableItemNode; +import org.sleuthkit.autopsy.datamodel.SleuthkitCaseFileInstanceNode; +import org.sleuthkit.datamodel.AbstractFile; /** * Encapsulates data required to instantiate a FileInstanceNode. */ -final public class FileInstanceMetadata { //TODO become abstract or interface - - private final Long objectId; - private final String dataSourceName; - private final CentralRepositoryFile crFile; +final public class SleuthkitCaseFileInstanceMetadata extends FileInstanceNodeGenerator { //TODO become abstract or interface /** * Create meta data required to find an abstract file and build a FileInstanceNode. * @param objectId id of abstract file to find * @param dataSourceName name of datasource where the object is found */ - FileInstanceMetadata (Long objectId, String dataSourceName) { - this.objectId = objectId; - this.dataSourceName = dataSourceName; - this.crFile = null; - } - - FileInstanceMetadata (CentralRepositoryFile crFile){ - //TODO should we actually just take an ID instead of the whole object - // like we've done previously, or is this ok? - this.objectId = null; - this.dataSourceName = null; - this.crFile = crFile; - } - - /** - * obj_id for the file represented by this object - * @return - */ - public Long getObjectId(){ - return this.objectId; - } - - /** - * Name of datasource where this instance was found. - * @return - */ - public String getDataSourceName(){ - return this.dataSourceName; + SleuthkitCaseFileInstanceMetadata (Long abstractFileReference, Map cachedFiles, String dataSource) { + super(abstractFileReference, cachedFiles, dataSource); } - public boolean isPresentInCurrentCase() { - return this.crFile != null; - } - - public CentralRepositoryFile getCentralRepoFileInstance() { - return this.crFile; + @Override + public DisplayableItemNode generateNode() { + return new SleuthkitCaseFileInstanceNode(this.lookupOrCreateAbstractFile(), this.getDataSource()); } } diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/Md5Node.java b/Core/src/org/sleuthkit/autopsy/datamodel/Md5Node.java index 4c7f5a497d..1287fd061f 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/Md5Node.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/Md5Node.java @@ -19,6 +19,7 @@ */ package org.sleuthkit.autopsy.datamodel; +import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -32,7 +33,8 @@ import org.openide.util.lookup.Lookups; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepositoryFile; -import org.sleuthkit.autopsy.commonfilesearch.FileInstanceMetadata; +import org.sleuthkit.autopsy.commonfilesearch.FileInstanceNodeGenerator; +import org.sleuthkit.autopsy.commonfilesearch.SleuthkitCaseFileInstanceMetadata; import org.sleuthkit.autopsy.commonfilesearch.Md5Metadata; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.datamodel.AbstractFile; @@ -130,41 +132,24 @@ public class Md5Node extends DisplayableItemNode { * Child generator for SleuthkitCaseFileInstanceNode of * Md5Node. */ - static class FileInstanceNodeFactory extends ChildFactory { + static class FileInstanceNodeFactory extends ChildFactory { + private Map cachedFiles; + private final Md5Metadata descendants; FileInstanceNodeFactory(Md5Metadata descendants) { this.descendants = descendants; + this.cachedFiles = new HashMap<>(); } @Override - protected Node createNodeForKey(FileInstanceMetadata file) { - - try { - Case currentCase = Case.getCurrentCaseThrows(); - SleuthkitCase tskDb = currentCase.getSleuthkitCase(); - - AbstractFile abstractFile = tskDb.findAllFilesWhere(String.format("obj_id in (%s)", file.getObjectId())).get(0); - - //TODO it would be an improvement to utilize some sort of polymorphism - // (interface with getNode is probably plenty) rather than this conditional - if (file.isPresentInCurrentCase()) { - return new SleuthkitCaseFileInstanceNode(abstractFile, file.getDataSourceName()); - } else { - CentralRepositoryFile crFile = file.getCentralRepoFileInstance(); - return new CentralRepositoryFileInstanceNode(crFile, abstractFile); - } - - } catch (NoCurrentCaseException | TskCoreException ex) { - LOGGER.log(Level.SEVERE, String.format("Unable to find AbstractFile for record with obj_id: %s. Node not created.", new Object[]{file.getObjectId()}), ex); - } - - return null; + protected Node createNodeForKey(FileInstanceNodeGenerator file) { + return file.generateNode(); } @Override - protected boolean createKeys(List list) { + protected boolean createKeys(List list) { list.addAll(this.descendants.getMetadata()); return true; } diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/InterCaseUtils.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/InterCaseUtils.java index 4025563d2c..ba8e9dccce 100644 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/InterCaseUtils.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/InterCaseUtils.java @@ -53,7 +53,7 @@ import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationCase; import org.sleuthkit.autopsy.centralrepository.datamodel.EamDb; import org.sleuthkit.autopsy.commonfilesearch.CommonFilesMetadata; import org.sleuthkit.autopsy.commonfilesearch.DataSourceLoader; -import org.sleuthkit.autopsy.commonfilesearch.FileInstanceMetadata; +import org.sleuthkit.autopsy.commonfilesearch.SleuthkitCaseFileInstanceMetadata; import org.sleuthkit.autopsy.commonfilesearch.Md5Metadata; import org.sleuthkit.datamodel.AbstractFile; @@ -297,9 +297,9 @@ class InterCaseUtils { for(Map.Entry file : searchDomain.getMetadata().entrySet()){ - Collection fileInstances = file.getValue().getMetadata(); + Collection fileInstances = file.getValue().getMetadata(); - for(FileInstanceMetadata fileInstance : fileInstances){ + for(SleuthkitCaseFileInstanceMetadata fileInstance : fileInstances){ } diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IntraCaseUtils.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IntraCaseUtils.java index e372cf7af3..10bd2e2fc4 100644 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IntraCaseUtils.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IntraCaseUtils.java @@ -36,7 +36,7 @@ import org.sleuthkit.autopsy.casemodule.ImageDSProcessor; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; import org.sleuthkit.autopsy.commonfilesearch.CommonFilesMetadata; import org.sleuthkit.autopsy.commonfilesearch.DataSourceLoader; -import org.sleuthkit.autopsy.commonfilesearch.FileInstanceMetadata; +import org.sleuthkit.autopsy.commonfilesearch.SleuthkitCaseFileInstanceMetadata; import org.sleuthkit.autopsy.commonfilesearch.Md5Metadata; import org.sleuthkit.autopsy.testutils.CaseUtils; import org.sleuthkit.autopsy.testutils.IngestUtils; @@ -187,7 +187,7 @@ class IntraCaseUtils { Map instanceIdToDataSource = new HashMap<>(); for (Map.Entry entry : metadata.getMetadata().entrySet()) { - for (FileInstanceMetadata md : entry.getValue().getMetadata()) { + for (SleuthkitCaseFileInstanceMetadata md : entry.getValue().getMetadata()) { instanceIdToDataSource.put(md.getObjectId(), md.getDataSourceName()); } } From fecfc8df709b96b27af6d089059d2f5e90c9a7ec Mon Sep 17 00:00:00 2001 From: Andrew Ziehl Date: Thu, 7 Jun 2018 08:56:33 -0700 Subject: [PATCH 092/287] Wrapper Child factory in callable to further delay execution. Still doesn't make Search lazy since DataResultFilterNode will gather all children and do lookups which triggers the children queries. --- .../sleuthkit/autopsy/datamodel/Md5Node.java | 26 ++++++++++++++++--- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/Md5Node.java b/Core/src/org/sleuthkit/autopsy/datamodel/Md5Node.java index 96de7eba36..38a3f78b64 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/Md5Node.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/Md5Node.java @@ -22,6 +22,7 @@ package org.sleuthkit.autopsy.datamodel; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.concurrent.Callable; import java.util.logging.Level; import org.openide.nodes.ChildFactory; import org.openide.nodes.Children; @@ -53,16 +54,33 @@ public class Md5Node extends DisplayableItemNode { private final String dataSources; public Md5Node(Md5Metadata data) { - super(Children.create( - new FileInstanceNodeFactory(data), true), - Lookups.singleton(data.getMd5())); - + super(Children.createLazy(new Md5ChildCallable(data)), Lookups.singleton(data.getMd5())); this.commonFileCount = data.size(); this.dataSources = String.join(", ", data.getDataSources()); this.md5Hash = data.getMd5(); this.setDisplayName(this.md5Hash); } + + private static class Md5ChildCallable implements Callable { + private final Md5Metadata key; + private Md5ChildCallable(Md5Metadata key) { + this.key = key; + } + @Override + public Children call() throws Exception { + //Check, somehow, that your key has children, + //e.g., create "hasChildren" on the object + //to look in the database to see whether + //the object has children; + //if it doesn't have children, return a leaf: + if (key.getMetadata().isEmpty()) { + return Children.LEAF; + } else { + return Children.create(new FileInstanceNodeFactory(key), true); + } + } + } int getCommonFileCount() { return this.commonFileCount; From 4c12a4b0cf369d5f218fe4987f2596f1c1f99155 Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Thu, 7 Jun 2018 18:39:21 -0600 Subject: [PATCH 093/287] more or less works - needs code quality cleanup, efficiency cleanup, some minor bugfixes, and testing --- ...ralRepositoryCaseFileInstanceMetadata.java | 5 +- .../EamDbCommonFilesAlgorithm.java | 39 ++++---- .../FileInstanceNodeGenerator.java | 88 ++++++++++++++----- .../autopsy/commonfilesearch/Md5Metadata.java | 2 +- 4 files changed, 96 insertions(+), 38 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepositoryCaseFileInstanceMetadata.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepositoryCaseFileInstanceMetadata.java index 2f3a1158be..6fb676c21d 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepositoryCaseFileInstanceMetadata.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepositoryCaseFileInstanceMetadata.java @@ -32,11 +32,12 @@ public class CentralRepositoryCaseFileInstanceMetadata extends FileInstanceNodeG private CentralRepositoryFile crFile; - CentralRepositoryCaseFileInstanceMetadata(CentralRepositoryFile crFile, Long abstractFileReference, Map cachedFiles, String dataSource){ - super(abstractFileReference, cachedFiles, dataSource); + CentralRepositoryCaseFileInstanceMetadata(CentralRepositoryFile crFile, Long abstractFileReference, Map cachedFiles){ + super(abstractFileReference, cachedFiles, null); //TODO should we actually just take an ID instead of the whole object // like we've done previously, or is this ok? this.crFile = crFile; + this.setDataSource(crFile.getCorrelationDataSource().getName()); } @Override diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbCommonFilesAlgorithm.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbCommonFilesAlgorithm.java index 4fc7632919..e46803a6ea 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbCommonFilesAlgorithm.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbCommonFilesAlgorithm.java @@ -24,10 +24,12 @@ import java.sql.SQLException; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; +import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.logging.Level; import java.util.stream.Collectors; +import org.openide.util.Exceptions; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepositoryFile; @@ -36,6 +38,7 @@ import org.sleuthkit.autopsy.centralrepository.datamodel.EamDb; import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException; import static org.sleuthkit.autopsy.commonfilesearch.CommonFilesMetadataBuilder.SELECT_PREFIX; import static org.sleuthkit.autopsy.timeline.datamodel.eventtype.ArtifactEventType.LOGGER; +import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.HashUtility; import org.sleuthkit.datamodel.TskCoreException; @@ -126,22 +129,28 @@ public abstract class EamDbCommonFilesAlgorithm extends CommonFilesMetadataBuild } //Builds a 3rd list which contains instances which are in currentCaseMetadata map, uses current case objectId if (commonFiles.containsKey(md5)) { - // we don't *have* all the information for the rows in the CR, - // so we need to consult the present case via the SleuthkitCase object - - //TODO resume here!!! - //TODO need to figure out if we have a CR instance or a SK resource and create as appropriate.... - Long objectId = commonFiles.get(md5).getMetadata().iterator().next().getIdenticalFileSleuthkitCaseObjectID(); - - if(interCaseCommonFiles.containsKey(md5)) { - //Add to intercase metaData - final Md5Metadata md5Metadata = interCaseCommonFiles.get(md5); - md5Metadata.addFileInstanceMetadata(new SleuthkitCaseFileInstanceMetadata(objectId, dataSource), correlationCaseDisplayName); + try { + // we don't *have* all the information for the rows in the CR, + // so we need to consult the present case via the SleuthkitCase object - } else { - Md5Metadata md5Metadata = new Md5Metadata(md5); - md5Metadata.addFileInstanceMetadata(new SleuthkitCaseFileInstanceMetadata(objectId, dataSource), correlationCaseDisplayName); - interCaseCommonFiles.put(md5, md5Metadata); + //TODO resume here!!! + //TODO need to figure out if we have a CR instance or a SK resource and create as appropriate.... + final Iterator identitcalFileInstanceMetadata = commonFiles.get(md5).getMetadata().iterator(); + + FileInstanceNodeGenerator nodeGenerator = FileInstanceNodeGenerator.createInstance(identitcalFileInstanceMetadata, instance, cachedFiles); + + if(interCaseCommonFiles.containsKey(md5)) { + //Add to intercase metaData + final Md5Metadata md5Metadata = interCaseCommonFiles.get(md5); + md5Metadata.addFileInstanceMetadata(nodeGenerator, correlationCaseDisplayName); + + } else { + Md5Metadata md5Metadata = new Md5Metadata(md5); + md5Metadata.addFileInstanceMetadata(nodeGenerator, correlationCaseDisplayName); + interCaseCommonFiles.put(md5, md5Metadata); + } + } catch (Exception ex) { + LOGGER.log(Level.WARNING, "Error getting artifact instances from database.", ex); // NON-NLS } } } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/FileInstanceNodeGenerator.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/FileInstanceNodeGenerator.java index f4706332b7..b99c64a9aa 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/FileInstanceNodeGenerator.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/FileInstanceNodeGenerator.java @@ -19,6 +19,9 @@ */ package org.sleuthkit.autopsy.commonfilesearch; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Iterator; import java.util.Map; import java.util.logging.Level; import org.openide.util.Exceptions; @@ -43,16 +46,16 @@ public abstract class FileInstanceNodeGenerator { protected Long abstractFileReference; protected Map cachedFiles; private String dataSource; - - public FileInstanceNodeGenerator(Long abstractFileReference, Map cachedFiles, String dataSource){ + + public FileInstanceNodeGenerator(Long abstractFileReference, Map cachedFiles, String dataSource) { this.abstractFileReference = abstractFileReference; this.cachedFiles = cachedFiles; this.dataSource = dataSource; } - + /** * Grab a cached instance of the AbstractFile or grab one from the - * SleuthkitCase. Use this in implementations of generateNode. + * SleuthkitCase. Use this in implementations of generateNode. * * @param objectId * @param cachedFiles @@ -70,24 +73,24 @@ public abstract class FileInstanceNodeGenerator { } private static AbstractFile loadFileFromSleuthkitCase(Long objectId) { - + Case currentCase; try { currentCase = Case.getCurrentCaseThrows(); - + SleuthkitCase tskDb = currentCase.getSleuthkitCase(); AbstractFile abstractFile = tskDb.findAllFilesWhere(String.format("obj_id in (%s)", objectId)).get(0); return abstractFile; - + } catch (TskCoreException | NoCurrentCaseException ex) { LOGGER.log(Level.SEVERE, String.format("Unable to find AbstractFile for record with obj_id: %s. Node not created.", new Object[]{objectId}), ex); return null; } } - - private static AbstractFile lookupOrCreateAbstractFile(Long objectId, Map cachedFiles){ + + private static AbstractFile lookupOrCreateAbstractFile(Long objectId, Map cachedFiles) { if (cachedFiles.containsKey(objectId)) { return cachedFiles.get(objectId); } else { @@ -104,29 +107,74 @@ public abstract class FileInstanceNodeGenerator { * @return child row node */ public abstract DisplayableItemNode generateNode(); + + /** + * + * @param dataSource + */ + protected void setDataSource(String dataSource){ + this.dataSource = dataSource; + } /** * Get string name of the data source where this instance appears. - * - * @return + * + * @return */ - public String getDataSource(){ - + public String getDataSource() { + /** * Even though we could get this from the CR record or the AbstractFile, - * we want to avoid getting it from the AbstractFile because it would be an - * extra database roundtrip. + * we want to avoid getting it from the AbstractFile because it would be + * an extra database roundtrip. */ return this.dataSource; } - - public Long getIdenticalFileSleuthkitCaseObjectID(){ + + public Long getIdenticalFileSleuthkitCaseObjectID() { return this.abstractFileReference; } - - public static FileInstanceNodeGenerator createInstance(Long objectId, CentralRepositoryFile instance, Map cachedFiles){ - AbstractFile referenceFile = FileInstanceNodeGenerator.lookupOrCreateAbstractFile(objectId, cachedFiles); + + public static FileInstanceNodeGenerator createInstance(Iterator identicalFileNodeGeneratorIterator, CentralRepositoryFile instance, Map cachedFiles) throws Exception { + + Long arbitraryIdenticalAbstractFileId = null; + while (identicalFileNodeGeneratorIterator.hasNext()) { + + FileInstanceNodeGenerator identicalFileNodeGenerator = identicalFileNodeGeneratorIterator.next(); + + final Long identicalFileSleuthkitCaseObjectID = identicalFileNodeGenerator.getIdenticalFileSleuthkitCaseObjectID(); + + final AbstractFile referenceFile = FileInstanceNodeGenerator.lookupOrCreateAbstractFile(identicalFileSleuthkitCaseObjectID, cachedFiles); + final Long referenceFileId = referenceFile.getId(); + arbitraryIdenticalAbstractFileId = referenceFileId; + + final String referenceFileDataSource = identicalFileNodeGenerator.getDataSource(); + + final String referenceCase = Case.getCurrentCase().getDisplayName(); + + final String referencePath = Paths.get(referenceFile.getParentPath(), referenceFile.getName()).toString(); + + final String instanceDataSource = instance.getCorrelationDataSource().getName(); + + final String instanceCase = instance.getCorrelationCase().getDisplayName(); + + final String instancePath = instance.getFilePath(); + + final boolean sameDataSource = referenceFileDataSource.equals(instanceDataSource); + final boolean sameCase = referenceCase.equals(instanceCase); + final boolean samePathAndName = referencePath.equals(instancePath); + + if(sameDataSource && sameCase && samePathAndName){ + return new SleuthkitCaseFileInstanceMetadata(referenceFile.getId(), cachedFiles, instanceDataSource); + } + } + if(arbitraryIdenticalAbstractFileId != null){ + return new CentralRepositoryCaseFileInstanceMetadata(instance, arbitraryIdenticalAbstractFileId, cachedFiles); + } else { + throw new Exception("Unable to get instance."); + } + } } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/Md5Metadata.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/Md5Metadata.java index 2ab8db4ee3..cd6376ddc8 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/Md5Metadata.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/Md5Metadata.java @@ -52,7 +52,7 @@ final public class Md5Metadata { this.fileInstances.add(metadata); } - void addFileInstanceMetadata(SleuthkitCaseFileInstanceMetadata metadata, String caseName){ + void addFileInstanceMetadata(FileInstanceNodeGenerator metadata, String caseName){ this.fileInstances.add(metadata); } From 82a94a17ab6e74c3d2f47f9a898c598ac57f6193 Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Fri, 8 Jun 2018 10:19:29 -0600 Subject: [PATCH 094/287] cleanup --- .../CentralRepositoryCaseFileInstanceMetadata.java | 2 +- .../autopsy/commonfilesearch/EamDbCommonFilesAlgorithm.java | 3 --- .../commonfilesearch/SleuthkitCaseFileInstanceMetadata.java | 2 +- 3 files changed, 2 insertions(+), 5 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepositoryCaseFileInstanceMetadata.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepositoryCaseFileInstanceMetadata.java index 6fb676c21d..75c069b382 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepositoryCaseFileInstanceMetadata.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepositoryCaseFileInstanceMetadata.java @@ -28,7 +28,7 @@ import org.sleuthkit.datamodel.AbstractFile; /** * Generates a DisplayableItmeNode using a CentralRepositoryFile. */ -public class CentralRepositoryCaseFileInstanceMetadata extends FileInstanceNodeGenerator { +final public class CentralRepositoryCaseFileInstanceMetadata extends FileInstanceNodeGenerator { private CentralRepositoryFile crFile; diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbCommonFilesAlgorithm.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbCommonFilesAlgorithm.java index e46803a6ea..1edc7d3907 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbCommonFilesAlgorithm.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbCommonFilesAlgorithm.java @@ -120,9 +120,6 @@ public abstract class EamDbCommonFilesAlgorithm extends CommonFilesMetadataBuild String md5 = instance.getValue(); final String correlationCaseDisplayName = instance.getCorrelationCase().getDisplayName(); - String dataSource = String.format("%s: %s", correlationCaseDisplayName, instance.getCorrelationDataSource().getName()); - String path = instance.getFilePath(); - File filePath = new File(path); if (md5 == null || HashUtility.isNoDataMd5(md5)) { continue; diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/SleuthkitCaseFileInstanceMetadata.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/SleuthkitCaseFileInstanceMetadata.java index a1139aeb44..d7e3250f05 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/SleuthkitCaseFileInstanceMetadata.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/SleuthkitCaseFileInstanceMetadata.java @@ -30,7 +30,7 @@ import org.sleuthkit.datamodel.AbstractFile; /** * Encapsulates data required to instantiate a FileInstanceNode. */ -final public class SleuthkitCaseFileInstanceMetadata extends FileInstanceNodeGenerator { //TODO become abstract or interface +final public class SleuthkitCaseFileInstanceMetadata extends FileInstanceNodeGenerator { /** * Create meta data required to find an abstract file and build a FileInstanceNode. From 69e49112324b07b104243cbfc5a2c172cc45aa95 Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Fri, 8 Jun 2018 10:20:46 -0600 Subject: [PATCH 095/287] removed an object from lookup (should prevent content viewer from triggeringon things from the CR) --- .../autopsy/datamodel/CentralRepositoryFileInstanceNode.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/CentralRepositoryFileInstanceNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/CentralRepositoryFileInstanceNode.java index dc3335aa44..09c0962d49 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/CentralRepositoryFileInstanceNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/CentralRepositoryFileInstanceNode.java @@ -50,7 +50,7 @@ public class CentralRepositoryFileInstanceNode extends DisplayableItemNode { private final AbstractFile md5Reference; public CentralRepositoryFileInstanceNode(CentralRepositoryFile content, AbstractFile md5Reference) { - super(Children.LEAF, Lookups.fixed(content, md5Reference)); + super(Children.LEAF, Lookups.fixed(content)); this.crFile = content; this.md5Reference = md5Reference; } From 789fd4f1d6d6ad745d6190b18d30c4290f5d3a95 Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Fri, 8 Jun 2018 14:52:31 -0600 Subject: [PATCH 096/287] need to manually set displayname --- .../CentralRepositoryFileInstanceNode.java | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/CentralRepositoryFileInstanceNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/CentralRepositoryFileInstanceNode.java index 09c0962d49..4db542cab7 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/CentralRepositoryFileInstanceNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/CentralRepositoryFileInstanceNode.java @@ -19,6 +19,7 @@ */ package org.sleuthkit.autopsy.datamodel; +import java.io.File; import java.util.ArrayList; import java.util.Arrays; import java.util.LinkedHashMap; @@ -51,7 +52,9 @@ public class CentralRepositoryFileInstanceNode extends DisplayableItemNode { public CentralRepositoryFileInstanceNode(CentralRepositoryFile content, AbstractFile md5Reference) { super(Children.LEAF, Lookups.fixed(content)); + this.crFile = content; + this.setDisplayName(new File(this.crFile.getFilePath()).getName()); this.md5Reference = md5Reference; } @@ -123,10 +126,18 @@ public class CentralRepositoryFileInstanceNode extends DisplayableItemNode { */ private static void fillPropertyMap(Map map, CentralRepositoryFileInstanceNode node) { - map.put(CentralRepositoryFileInstanceNode.CentralRepoFileInstancesPropertyType.File.toString(), node.crFile.getFilePath()); - map.put(CentralRepositoryFileInstanceNode.CentralRepoFileInstancesPropertyType.ParentPath.toString(), node.crFile.getFilePath()); + final CentralRepositoryFile centralRepoFile = node.getCentralRepoFile(); + + final String fullPath = centralRepoFile.getFilePath(); + final File file = new File(fullPath); + + final String name = file.getName(); + final String parent = file.getParent(); + + map.put(CentralRepositoryFileInstanceNode.CentralRepoFileInstancesPropertyType.File.toString(), name); + map.put(CentralRepositoryFileInstanceNode.CentralRepoFileInstancesPropertyType.ParentPath.toString(), parent); map.put(CentralRepositoryFileInstanceNode.CentralRepoFileInstancesPropertyType.HashsetHits.toString(), ""); - map.put(CentralRepositoryFileInstanceNode.CentralRepoFileInstancesPropertyType.DataSource.toString(), node.crFile.getCorrelationDataSource().getName()); + map.put(CentralRepositoryFileInstanceNode.CentralRepoFileInstancesPropertyType.DataSource.toString(), centralRepoFile.getCorrelationDataSource().getName()); map.put(CentralRepositoryFileInstanceNode.CentralRepoFileInstancesPropertyType.MimeType.toString(), ""); } From b9dfd3f9695d4d292ae8809444a70596750bcdae Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Fri, 8 Jun 2018 20:53:27 -0600 Subject: [PATCH 097/287] added data source back to CentralRepositoryCaseFileInstanceNode constructor --- ...ralRepositoryCaseFileInstanceMetadata.java | 6 +-- .../EamDbCommonFilesAlgorithm.java | 2 - .../FileInstanceNodeGenerator.java | 45 +++++++++---------- 3 files changed, 25 insertions(+), 28 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepositoryCaseFileInstanceMetadata.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepositoryCaseFileInstanceMetadata.java index 75c069b382..e611dc84b9 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepositoryCaseFileInstanceMetadata.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepositoryCaseFileInstanceMetadata.java @@ -32,12 +32,12 @@ final public class CentralRepositoryCaseFileInstanceMetadata extends FileInstanc private CentralRepositoryFile crFile; - CentralRepositoryCaseFileInstanceMetadata(CentralRepositoryFile crFile, Long abstractFileReference, Map cachedFiles){ - super(abstractFileReference, cachedFiles, null); + CentralRepositoryCaseFileInstanceMetadata(CentralRepositoryFile crFile, Long abstractFileReference, Map cachedFiles, String dataSource){ + super(abstractFileReference, cachedFiles, dataSource); //TODO should we actually just take an ID instead of the whole object // like we've done previously, or is this ok? this.crFile = crFile; - this.setDataSource(crFile.getCorrelationDataSource().getName()); + //this.setDataSource(crFile.getCorrelationDataSource().getName()); } @Override diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbCommonFilesAlgorithm.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbCommonFilesAlgorithm.java index 1edc7d3907..a1e8bbc63f 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbCommonFilesAlgorithm.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbCommonFilesAlgorithm.java @@ -130,8 +130,6 @@ public abstract class EamDbCommonFilesAlgorithm extends CommonFilesMetadataBuild // we don't *have* all the information for the rows in the CR, // so we need to consult the present case via the SleuthkitCase object - //TODO resume here!!! - //TODO need to figure out if we have a CR instance or a SK resource and create as appropriate.... final Iterator identitcalFileInstanceMetadata = commonFiles.get(md5).getMetadata().iterator(); FileInstanceNodeGenerator nodeGenerator = FileInstanceNodeGenerator.createInstance(identitcalFileInstanceMetadata, instance, cachedFiles); diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/FileInstanceNodeGenerator.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/FileInstanceNodeGenerator.java index b99c64a9aa..8880545dff 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/FileInstanceNodeGenerator.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/FileInstanceNodeGenerator.java @@ -109,13 +109,13 @@ public abstract class FileInstanceNodeGenerator { public abstract DisplayableItemNode generateNode(); /** - * - * @param dataSource + * + * @param dataSource */ - protected void setDataSource(String dataSource){ + protected void setDataSource(String dataSource) { this.dataSource = dataSource; } - + /** * Get string name of the data source where this instance appears. * @@ -138,43 +138,42 @@ public abstract class FileInstanceNodeGenerator { public static FileInstanceNodeGenerator createInstance(Iterator identicalFileNodeGeneratorIterator, CentralRepositoryFile instance, Map cachedFiles) throws Exception { Long arbitraryIdenticalAbstractFileId = null; - + + final String instanceDataSource = instance.getCorrelationDataSource().getName().toLowerCase(); + final String instanceCase = instance.getCorrelationCase().getDisplayName().toLowerCase(); + final String instancePath = instance.getFilePath().toLowerCase(); + while (identicalFileNodeGeneratorIterator.hasNext()) { - + FileInstanceNodeGenerator identicalFileNodeGenerator = identicalFileNodeGeneratorIterator.next(); - + final Long identicalFileSleuthkitCaseObjectID = identicalFileNodeGenerator.getIdenticalFileSleuthkitCaseObjectID(); final AbstractFile referenceFile = FileInstanceNodeGenerator.lookupOrCreateAbstractFile(identicalFileSleuthkitCaseObjectID, cachedFiles); final Long referenceFileId = referenceFile.getId(); arbitraryIdenticalAbstractFileId = referenceFileId; - final String referenceFileDataSource = identicalFileNodeGenerator.getDataSource(); + final String referenceFileDataSource = identicalFileNodeGenerator.getDataSource().toLowerCase(); - final String referenceCase = Case.getCurrentCase().getDisplayName(); + final String referenceCase = Case.getCurrentCase().getDisplayName().toLowerCase(); - final String referencePath = Paths.get(referenceFile.getParentPath(), referenceFile.getName()).toString(); + final String referencePath = Paths.get(referenceFile.getParentPath(), referenceFile.getName()).toString().toLowerCase(); - final String instanceDataSource = instance.getCorrelationDataSource().getName(); - - final String instanceCase = instance.getCorrelationCase().getDisplayName(); - - final String instancePath = instance.getFilePath(); - final boolean sameDataSource = referenceFileDataSource.equals(instanceDataSource); final boolean sameCase = referenceCase.equals(instanceCase); final boolean samePathAndName = referencePath.equals(instancePath); - - if(sameDataSource && sameCase && samePathAndName){ - return new SleuthkitCaseFileInstanceMetadata(referenceFile.getId(), cachedFiles, instanceDataSource); + + if (sameDataSource && sameCase && samePathAndName) { + String dataSource = String.format("%s: %s", referenceCase, referenceFileDataSource); + return new SleuthkitCaseFileInstanceMetadata(referenceFile.getId(), cachedFiles, dataSource); } } - - if(arbitraryIdenticalAbstractFileId != null){ - return new CentralRepositoryCaseFileInstanceMetadata(instance, arbitraryIdenticalAbstractFileId, cachedFiles); + + if (arbitraryIdenticalAbstractFileId != null) { + String dataSource = String.format("%s: %s", instanceCase, instanceDataSource); + return new CentralRepositoryCaseFileInstanceMetadata(instance, arbitraryIdenticalAbstractFileId, cachedFiles, dataSource); } else { throw new Exception("Unable to get instance."); } - } } From d9de5e7c02f6b0ef8ee62cf74370b53478620b34 Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Fri, 8 Jun 2018 21:11:31 -0600 Subject: [PATCH 098/287] correct decision making for creating central repo file or sleuthkitfile --- .../autopsy/commonfilesearch/FileInstanceNodeGenerator.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/FileInstanceNodeGenerator.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/FileInstanceNodeGenerator.java index 8880545dff..d40e103dd6 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/FileInstanceNodeGenerator.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/FileInstanceNodeGenerator.java @@ -157,7 +157,7 @@ public abstract class FileInstanceNodeGenerator { final String referenceCase = Case.getCurrentCase().getDisplayName().toLowerCase(); - final String referencePath = Paths.get(referenceFile.getParentPath(), referenceFile.getName()).toString().toLowerCase(); + final String referencePath = Paths.get(referenceFile.getParentPath(), referenceFile.getName()).toString().toLowerCase().replace("\\", "/"); final boolean sameDataSource = referenceFileDataSource.equals(instanceDataSource); final boolean sameCase = referenceCase.equals(instanceCase); From 81ef4bd6a553ce383970760cecb1b8d41a520c06 Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Sat, 9 Jun 2018 10:13:35 -0600 Subject: [PATCH 099/287] should be getting display name rather than calling tostring --- .../datamodel/CentralRepositoryFileInstanceNode.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/CentralRepositoryFileInstanceNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/CentralRepositoryFileInstanceNode.java index 4db542cab7..a47c9ef589 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/CentralRepositoryFileInstanceNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/CentralRepositoryFileInstanceNode.java @@ -134,10 +134,12 @@ public class CentralRepositoryFileInstanceNode extends DisplayableItemNode { final String name = file.getName(); final String parent = file.getParent(); + final String caseQualifiedDataSource = String.format("%s: %s", centralRepoFile.getCorrelationCase().getDisplayName(), centralRepoFile.getCorrelationDataSource().getName()); + map.put(CentralRepositoryFileInstanceNode.CentralRepoFileInstancesPropertyType.File.toString(), name); map.put(CentralRepositoryFileInstanceNode.CentralRepoFileInstancesPropertyType.ParentPath.toString(), parent); map.put(CentralRepositoryFileInstanceNode.CentralRepoFileInstancesPropertyType.HashsetHits.toString(), ""); - map.put(CentralRepositoryFileInstanceNode.CentralRepoFileInstancesPropertyType.DataSource.toString(), centralRepoFile.getCorrelationDataSource().getName()); + map.put(CentralRepositoryFileInstanceNode.CentralRepoFileInstancesPropertyType.DataSource.toString(), caseQualifiedDataSource); map.put(CentralRepositoryFileInstanceNode.CentralRepoFileInstancesPropertyType.MimeType.toString(), ""); } @@ -170,6 +172,5 @@ public class CentralRepositoryFileInstanceNode extends DisplayableItemNode { public String toString() { return displayString; } - } - + } } From 2180b5d11e0dbdb9c736a2d6efae77c94e27af7c Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Tue, 12 Jun 2018 11:48:37 -0600 Subject: [PATCH 100/287] roughed in case column --- .../autopsy/datamodel/CentralRepositoryFileInstanceNode.java | 5 +++++ Core/src/org/sleuthkit/autopsy/datamodel/Md5Node.java | 3 +++ .../autopsy/datamodel/SleuthkitCaseFileInstanceNode.java | 3 +++ 3 files changed, 11 insertions(+) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/CentralRepositoryFileInstanceNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/CentralRepositoryFileInstanceNode.java index a47c9ef589..6b5dd72810 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/CentralRepositoryFileInstanceNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/CentralRepositoryFileInstanceNode.java @@ -131,6 +131,8 @@ public class CentralRepositoryFileInstanceNode extends DisplayableItemNode { final String fullPath = centralRepoFile.getFilePath(); final File file = new File(fullPath); + final String caseName = centralRepoFile.getCorrelationCase().getDisplayName(); + final String name = file.getName(); final String parent = file.getParent(); @@ -139,6 +141,7 @@ public class CentralRepositoryFileInstanceNode extends DisplayableItemNode { map.put(CentralRepositoryFileInstanceNode.CentralRepoFileInstancesPropertyType.File.toString(), name); map.put(CentralRepositoryFileInstanceNode.CentralRepoFileInstancesPropertyType.ParentPath.toString(), parent); map.put(CentralRepositoryFileInstanceNode.CentralRepoFileInstancesPropertyType.HashsetHits.toString(), ""); + map.put(CentralRepositoryFileInstanceNode.CentralRepoFileInstancesPropertyType.Case.toString(), caseName); map.put(CentralRepositoryFileInstanceNode.CentralRepoFileInstancesPropertyType.DataSource.toString(), caseQualifiedDataSource); map.put(CentralRepositoryFileInstanceNode.CentralRepoFileInstancesPropertyType.MimeType.toString(), ""); } @@ -151,6 +154,7 @@ public class CentralRepositoryFileInstanceNode extends DisplayableItemNode { "CentralRepoFileInstancesPropertyType.fileColLbl=File", "CentralRepoFileInstancesPropertyType.pathColLbl=Parent Path", "CentralRepoFileInstancesPropertyType.hashsetHitsColLbl=Hash Set Hits", + "CentralRepoFileInstancesPropertyType.caseColLbl=Case", "CentralRepoFileInstancesPropertyType.dataSourceColLbl=Data Source", "CentralRepoFileInstancesPropertyType.mimeTypeColLbl=MIME Type" }) @@ -159,6 +163,7 @@ public class CentralRepositoryFileInstanceNode extends DisplayableItemNode { File(Bundle.CentralRepoFileInstancesPropertyType_fileColLbl()), ParentPath(Bundle.CentralRepoFileInstancesPropertyType_pathColLbl()), HashsetHits(Bundle.CentralRepoFileInstancesPropertyType_hashsetHitsColLbl()), + Case(Bundle.CentralRepoFileInstancesPropertyType_caseColLbl()), DataSource(Bundle.CentralRepoFileInstancesPropertyType_dataSourceColLbl()), MimeType(Bundle.CentralRepoFileInstancesPropertyType_mimeTypeColLbl()); diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/Md5Node.java b/Core/src/org/sleuthkit/autopsy/datamodel/Md5Node.java index b171354fb4..fe6c40bdff 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/Md5Node.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/Md5Node.java @@ -128,6 +128,7 @@ public class Md5Node extends DisplayableItemNode { static private void fillPropertyMap(Map map, Md5Node node) { map.put(CommonFileParentPropertyType.File.toString(), node.getMd5()); map.put(CommonFileParentPropertyType.InstanceCount.toString(), node.getCommonFileCount()); + map.put(CommonFileParentPropertyType.Case.toString(), "TODO"); map.put(CommonFileParentPropertyType.DataSource.toString(), node.getDataSources()); } @@ -176,11 +177,13 @@ public class Md5Node extends DisplayableItemNode { @NbBundle.Messages({ "CommonFileParentPropertyType.fileColLbl=File", "CommonFileParentPropertyType.instanceColLbl=Instance Count", + "CommonFileParentPropertyType.caseColLbl=Case", "CommonFileParentPropertyType.dataSourceColLbl=Data Source"}) public enum CommonFileParentPropertyType { File(Bundle.CommonFileParentPropertyType_fileColLbl()), InstanceCount(Bundle.CommonFileParentPropertyType_instanceColLbl()), + Case(Bundle.CommonFileParentPropertyType_caseColLbl()), DataSource(Bundle.CommonFileParentPropertyType_dataSourceColLbl()); final private String displayString; diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/SleuthkitCaseFileInstanceNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/SleuthkitCaseFileInstanceNode.java index 539e435743..5a3da91eff 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/SleuthkitCaseFileInstanceNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/SleuthkitCaseFileInstanceNode.java @@ -95,6 +95,7 @@ public class SleuthkitCaseFileInstanceNode extends FileNode { map.put(SleuthkitCaseFileInstanceNode.SleuthkitCaseFileInstanceNodePropertyType.File.toString(), node.getName()); map.put(SleuthkitCaseFileInstanceNode.SleuthkitCaseFileInstanceNodePropertyType.ParentPath.toString(), node.getContent().getParentPath()); map.put(SleuthkitCaseFileInstanceNode.SleuthkitCaseFileInstanceNodePropertyType.HashsetHits.toString(), getHashSetHitsForFile(node.getContent())); + map.put(SleuthkitCaseFileInstanceNode.SleuthkitCaseFileInstanceNodePropertyType.Case.toString(), "TODO"); map.put(SleuthkitCaseFileInstanceNode.SleuthkitCaseFileInstanceNodePropertyType.DataSource.toString(), node.getDataSource()); map.put(SleuthkitCaseFileInstanceNode.SleuthkitCaseFileInstanceNodePropertyType.MimeType.toString(), StringUtils.defaultString(node.content.getMIMEType())); } @@ -107,6 +108,7 @@ public class SleuthkitCaseFileInstanceNode extends FileNode { "SleuthkitCaseFileInstanceNodePropertyType.fileColLbl=File", "SleuthkitCaseFileInstanceNodePropertyType.pathColLbl=Parent Path", "SleuthkitCaseFileInstanceNodePropertyType.hashsetHitsColLbl=Hash Set Hits", + "SleuthkitCaseFileInstanceNodePropertyType.caseColLbl=Case", "SleuthkitCaseFileInstanceNodePropertyType.dataSourceColLbl=Data Source", "SleuthkitCaseFileInstanceNodePropertyType.mimeTypeColLbl=MIME Type" }) @@ -115,6 +117,7 @@ public class SleuthkitCaseFileInstanceNode extends FileNode { File(Bundle.SleuthkitCaseFileInstanceNodePropertyType_fileColLbl()), ParentPath(Bundle.SleuthkitCaseFileInstanceNodePropertyType_pathColLbl()), HashsetHits(Bundle.SleuthkitCaseFileInstanceNodePropertyType_hashsetHitsColLbl()), + Case(Bundle.SleuthkitCaseFileInstanceNodePropertyType_caseColLbl()), DataSource(Bundle.SleuthkitCaseFileInstanceNodePropertyType_dataSourceColLbl()), MimeType(Bundle.SleuthkitCaseFileInstanceNodePropertyType_mimeTypeColLbl()); From d938d286706cfcfda126cf4402ea4ae131659a10 Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Wed, 13 Jun 2018 10:23:45 -0600 Subject: [PATCH 101/287] added a case column, split cases and data sources between these columns. --- ...ralRepositoryCaseFileInstanceMetadata.java | 5 +- .../CommonFilesMetadataBuilder.java | 10 ++- .../FileInstanceNodeGenerator.java | 20 +++--- .../autopsy/commonfilesearch/Md5Metadata.java | 69 +++++++++++-------- .../SleuthkitCaseFileInstanceMetadata.java | 6 +- .../sleuthkit/autopsy/datamodel/Md5Node.java | 8 ++- .../SleuthkitCaseFileInstanceNode.java | 10 ++- 7 files changed, 75 insertions(+), 53 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepositoryCaseFileInstanceMetadata.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepositoryCaseFileInstanceMetadata.java index e611dc84b9..6eb4b20561 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepositoryCaseFileInstanceMetadata.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepositoryCaseFileInstanceMetadata.java @@ -32,12 +32,11 @@ final public class CentralRepositoryCaseFileInstanceMetadata extends FileInstanc private CentralRepositoryFile crFile; - CentralRepositoryCaseFileInstanceMetadata(CentralRepositoryFile crFile, Long abstractFileReference, Map cachedFiles, String dataSource){ - super(abstractFileReference, cachedFiles, dataSource); + CentralRepositoryCaseFileInstanceMetadata(CentralRepositoryFile crFile, Long abstractFileReference, Map cachedFiles, String dataSource, String caseName){ + super(abstractFileReference, cachedFiles, dataSource, caseName); //TODO should we actually just take an ID instead of the whole object // like we've done previously, or is this ok? this.crFile = crFile; - //this.setDataSource(crFile.getCorrelationDataSource().getName()); } @Override diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesMetadataBuilder.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesMetadataBuilder.java index 84333ba521..f8ca166d5d 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesMetadataBuilder.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesMetadataBuilder.java @@ -170,8 +170,12 @@ public abstract class CommonFilesMetadataBuilder { public CommonFilesMetadata findFiles() throws TskCoreException, NoCurrentCaseException, SQLException, Exception { //TODO do we need all those exceptions or can we differentiate when they are caught? Map commonFiles = new HashMap<>(); + + final Case currentCase = Case.getCurrentCaseThrows(); + final String caseName = currentCase.getDisplayName(); - SleuthkitCase sleuthkitCase = Case.getCurrentCaseThrows().getSleuthkitCase(); + SleuthkitCase sleuthkitCase = currentCase.getSleuthkitCase(); + String selectStatement = this.buildSqlSelectStatement(); Map fileCache = new HashMap<>(); @@ -192,10 +196,10 @@ public abstract class CommonFilesMetadataBuilder { if (commonFiles.containsKey(md5)) { final Md5Metadata md5Metadata = commonFiles.get(md5); - md5Metadata.addFileInstanceMetadata(new SleuthkitCaseFileInstanceMetadata(objectId, fileCache, dataSource)); + md5Metadata.addFileInstanceMetadata(new SleuthkitCaseFileInstanceMetadata(objectId, fileCache, dataSource, caseName)); } else { final Md5Metadata md5Metadata = new Md5Metadata(md5); - md5Metadata.addFileInstanceMetadata(new SleuthkitCaseFileInstanceMetadata(objectId, fileCache, dataSource)); + md5Metadata.addFileInstanceMetadata(new SleuthkitCaseFileInstanceMetadata(objectId, fileCache, dataSource, caseName)); commonFiles.put(md5, md5Metadata); } } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/FileInstanceNodeGenerator.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/FileInstanceNodeGenerator.java index d40e103dd6..d01ef89547 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/FileInstanceNodeGenerator.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/FileInstanceNodeGenerator.java @@ -45,11 +45,13 @@ public abstract class FileInstanceNodeGenerator { private static final Logger LOGGER = Logger.getLogger(FileInstanceNodeGenerator.class.getName()); protected Long abstractFileReference; protected Map cachedFiles; + private final String caseName; private String dataSource; - public FileInstanceNodeGenerator(Long abstractFileReference, Map cachedFiles, String dataSource) { + public FileInstanceNodeGenerator(Long abstractFileReference, Map cachedFiles, String dataSource, String caseName) { this.abstractFileReference = abstractFileReference; this.cachedFiles = cachedFiles; + this.caseName = caseName; this.dataSource = dataSource; } @@ -108,14 +110,10 @@ public abstract class FileInstanceNodeGenerator { */ public abstract DisplayableItemNode generateNode(); - /** - * - * @param dataSource - */ - protected void setDataSource(String dataSource) { - this.dataSource = dataSource; + public String getCaseName(){ + return this.caseName; } - + /** * Get string name of the data source where this instance appears. * @@ -164,14 +162,12 @@ public abstract class FileInstanceNodeGenerator { final boolean samePathAndName = referencePath.equals(instancePath); if (sameDataSource && sameCase && samePathAndName) { - String dataSource = String.format("%s: %s", referenceCase, referenceFileDataSource); - return new SleuthkitCaseFileInstanceMetadata(referenceFile.getId(), cachedFiles, dataSource); + return new SleuthkitCaseFileInstanceMetadata(referenceFile.getId(), cachedFiles, referenceFileDataSource, referenceCase); } } if (arbitraryIdenticalAbstractFileId != null) { - String dataSource = String.format("%s: %s", instanceCase, instanceDataSource); - return new CentralRepositoryCaseFileInstanceMetadata(instance, arbitraryIdenticalAbstractFileId, cachedFiles, dataSource); + return new CentralRepositoryCaseFileInstanceMetadata(instance, arbitraryIdenticalAbstractFileId, cachedFiles, instanceDataSource, instanceCase); } else { throw new Exception("Unable to get instance."); } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/Md5Metadata.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/Md5Metadata.java index cd6376ddc8..7d77971683 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/Md5Metadata.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/Md5Metadata.java @@ -25,54 +25,65 @@ import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; +import java.util.stream.Collector; +import java.util.stream.Collectors; /** * Encapsulates data required to instantiate an Md5Node. */ final public class Md5Metadata { - + private final String md5; private final List fileInstances; - - Md5Metadata(String md5, List fileInstances){ + + Md5Metadata(String md5, List fileInstances) { this.md5 = md5; this.fileInstances = fileInstances; } - - Md5Metadata(String md5){ + + Md5Metadata(String md5) { this.md5 = md5; this.fileInstances = new ArrayList<>(); } - - public String getMd5(){ + + public String getMd5() { return this.md5; } - - void addFileInstanceMetadata(FileInstanceNodeGenerator metadata){ - this.fileInstances.add(metadata); - } - - void addFileInstanceMetadata(FileInstanceNodeGenerator metadata, String caseName){ - this.fileInstances.add(metadata); - } - - public Collection getMetadata(){ - return Collections.unmodifiableCollection(this.fileInstances); - } - - /** - * How many distinct file instances exist for the MD5 represented by this object? - * @return number of instances - */ - public int size(){ - return this.fileInstances.size(); + + public String getCases() { + final String cases = this.fileInstances.stream().map(FileInstanceNodeGenerator::getCaseName).collect(Collectors.joining(", ")); + return cases; } public String getDataSources() { - Set sources = new HashSet<> (); - for(FileInstanceNodeGenerator data : this.fileInstances){ + Set sources = new HashSet<>(); + for (FileInstanceNodeGenerator data : this.fileInstances) { sources.add(data.getDataSource()); } - return String.join(", ", sources); + + final String dataSources = String.join(", ", sources); + return dataSources; + } + + void addFileInstanceMetadata(FileInstanceNodeGenerator metadata) { + this.fileInstances.add(metadata); + } + + void addFileInstanceMetadata(FileInstanceNodeGenerator metadata, String caseName) { + this.fileInstances.add(metadata); + } + + public Collection getMetadata() { + return Collections.unmodifiableCollection(this.fileInstances); + } + + /** + * How many distinct file instances exist for the MD5 represented by this + * object? + * + * @return number of instances + */ + public int size() { + return this.fileInstances.size(); } } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/SleuthkitCaseFileInstanceMetadata.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/SleuthkitCaseFileInstanceMetadata.java index d7e3250f05..dcd3645d8d 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/SleuthkitCaseFileInstanceMetadata.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/SleuthkitCaseFileInstanceMetadata.java @@ -37,12 +37,12 @@ final public class SleuthkitCaseFileInstanceMetadata extends FileInstanceNodeGen * @param objectId id of abstract file to find * @param dataSourceName name of datasource where the object is found */ - SleuthkitCaseFileInstanceMetadata (Long abstractFileReference, Map cachedFiles, String dataSource) { - super(abstractFileReference, cachedFiles, dataSource); + SleuthkitCaseFileInstanceMetadata (Long abstractFileReference, Map cachedFiles, String dataSource, String caseName) { + super(abstractFileReference, cachedFiles, dataSource, caseName); } @Override public DisplayableItemNode generateNode() { - return new SleuthkitCaseFileInstanceNode(this.lookupOrCreateAbstractFile(), this.getDataSource()); + return new SleuthkitCaseFileInstanceNode(this.lookupOrCreateAbstractFile(), this.getCaseName(), this.getDataSource()); } } diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/Md5Node.java b/Core/src/org/sleuthkit/autopsy/datamodel/Md5Node.java index fe6c40bdff..e571165874 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/Md5Node.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/Md5Node.java @@ -54,11 +54,13 @@ public class Md5Node extends DisplayableItemNode { private final String md5Hash; private final int commonFileCount; + private final String cases; private final String dataSources; public Md5Node(Md5Metadata data) { super(Children.createLazy(new Md5ChildCallable(data)), Lookups.singleton(data.getMd5())); this.commonFileCount = data.size(); + this.cases = data.getCases(); this.dataSources = String.join(", ", data.getDataSources()); this.md5Hash = data.getMd5(); @@ -88,6 +90,10 @@ public class Md5Node extends DisplayableItemNode { int getCommonFileCount() { return this.commonFileCount; } + + String getCases(){ + return this.cases; + } String getDataSources() { return this.dataSources; @@ -128,7 +134,7 @@ public class Md5Node extends DisplayableItemNode { static private void fillPropertyMap(Map map, Md5Node node) { map.put(CommonFileParentPropertyType.File.toString(), node.getMd5()); map.put(CommonFileParentPropertyType.InstanceCount.toString(), node.getCommonFileCount()); - map.put(CommonFileParentPropertyType.Case.toString(), "TODO"); + map.put(CommonFileParentPropertyType.Case.toString(), node.getCases()); map.put(CommonFileParentPropertyType.DataSource.toString(), node.getDataSources()); } diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/SleuthkitCaseFileInstanceNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/SleuthkitCaseFileInstanceNode.java index 5a3da91eff..a3222b5493 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/SleuthkitCaseFileInstanceNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/SleuthkitCaseFileInstanceNode.java @@ -36,11 +36,13 @@ import org.sleuthkit.datamodel.AbstractFile; */ public class SleuthkitCaseFileInstanceNode extends FileNode { + private final String caseName; private final String dataSource; - public SleuthkitCaseFileInstanceNode(AbstractFile fsContent, String dataSource) { + public SleuthkitCaseFileInstanceNode(AbstractFile fsContent, String caseName, String dataSource) { super(fsContent); this.content = fsContent; + this.caseName = caseName; this.dataSource = dataSource; } @@ -54,6 +56,10 @@ public class SleuthkitCaseFileInstanceNode extends FileNode { return this.content; } + String getCase(){ + return this.caseName; + } + String getDataSource() { return this.dataSource; } @@ -95,7 +101,7 @@ public class SleuthkitCaseFileInstanceNode extends FileNode { map.put(SleuthkitCaseFileInstanceNode.SleuthkitCaseFileInstanceNodePropertyType.File.toString(), node.getName()); map.put(SleuthkitCaseFileInstanceNode.SleuthkitCaseFileInstanceNodePropertyType.ParentPath.toString(), node.getContent().getParentPath()); map.put(SleuthkitCaseFileInstanceNode.SleuthkitCaseFileInstanceNodePropertyType.HashsetHits.toString(), getHashSetHitsForFile(node.getContent())); - map.put(SleuthkitCaseFileInstanceNode.SleuthkitCaseFileInstanceNodePropertyType.Case.toString(), "TODO"); + map.put(SleuthkitCaseFileInstanceNode.SleuthkitCaseFileInstanceNodePropertyType.Case.toString(), node.getCase()); map.put(SleuthkitCaseFileInstanceNode.SleuthkitCaseFileInstanceNodePropertyType.DataSource.toString(), node.getDataSource()); map.put(SleuthkitCaseFileInstanceNode.SleuthkitCaseFileInstanceNodePropertyType.MimeType.toString(), StringUtils.defaultString(node.content.getMIMEType())); } From c2eea78f65107f1932deadbaab6e27c19bf0ae4d Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Thu, 21 Jun 2018 17:15:14 -0600 Subject: [PATCH 102/287] merge problems - wip --- Core/src/org/sleuthkit/autopsy/datamodel/Md5Node.java | 4 ++-- .../autopsy/datamodel/SleuthkitCaseFileInstanceNode.java | 2 +- .../sleuthkit/autopsy/directorytree/DataResultFilterNode.java | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/Md5Node.java b/Core/src/org/sleuthkit/autopsy/datamodel/Md5Node.java index 8b56443b69..8c1f1c0ba1 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/Md5Node.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/Md5Node.java @@ -185,13 +185,13 @@ public class Md5Node extends DisplayableItemNode { } @Override - protected Node createNodeForKey(FileInstanceMetadata file) { + protected Node createNodeForKey(SleuthkitCaseFileInstanceMetadata file) { try { Case currentCase = Case.getCurrentCaseThrows(); SleuthkitCase tskDb = currentCase.getSleuthkitCase(); AbstractFile abstractFile = tskDb.findAllFilesWhere(String.format("obj_id in (%s)", file.getObjectId())).get(0); - return new FileInstanceNode(abstractFile, file.getDataSourceName()); + return new SleuthkitCaseFileInstanceNode(abstractFile, file.getDataSourceName()); } catch (NoCurrentCaseException | TskCoreException ex) { LOGGER.log(Level.SEVERE, String.format("Unable to create node for file with obj_id: %s.", new Object[]{file.getObjectId()}), ex); } diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/SleuthkitCaseFileInstanceNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/SleuthkitCaseFileInstanceNode.java index de90bbc650..8cb5916115 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/SleuthkitCaseFileInstanceNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/SleuthkitCaseFileInstanceNode.java @@ -46,7 +46,7 @@ public class SleuthkitCaseFileInstanceNode extends FileNode { * @param fsContent * @param dataSource */ - public FileInstanceNode(AbstractFile fsContent, String dataSource) { + public SleuthkitCaseFileInstanceNode(AbstractFile fsContent, String caseName, String dataSource) { super(fsContent); this.content = fsContent; this.caseName = caseName; diff --git a/Core/src/org/sleuthkit/autopsy/directorytree/DataResultFilterNode.java b/Core/src/org/sleuthkit/autopsy/directorytree/DataResultFilterNode.java index 7c0937c67e..ee94355707 100644 --- a/Core/src/org/sleuthkit/autopsy/directorytree/DataResultFilterNode.java +++ b/Core/src/org/sleuthkit/autopsy/directorytree/DataResultFilterNode.java @@ -51,7 +51,6 @@ import org.sleuthkit.autopsy.datamodel.DataModelActionsFactory; import org.sleuthkit.autopsy.datamodel.DirectoryNode; import org.sleuthkit.autopsy.datamodel.DisplayableItemNode; import org.sleuthkit.autopsy.datamodel.DisplayableItemNodeVisitor; -import org.sleuthkit.autopsy.datamodel.FileInstanceNode; import org.sleuthkit.autopsy.datamodel.FileNode; import org.sleuthkit.autopsy.datamodel.FileTypeExtensions; import org.sleuthkit.autopsy.datamodel.FileTypes.FileTypesNode; @@ -63,6 +62,7 @@ import org.sleuthkit.autopsy.datamodel.Md5Node; import org.sleuthkit.autopsy.datamodel.NodeSelectionInfo; import org.sleuthkit.autopsy.datamodel.Reports; import org.sleuthkit.autopsy.datamodel.SlackFileNode; +import org.sleuthkit.autopsy.datamodel.SleuthkitCaseFileInstanceNode; import org.sleuthkit.autopsy.datamodel.VirtualDirectoryNode; import static org.sleuthkit.autopsy.directorytree.Bundle.*; import org.sleuthkit.autopsy.modules.embeddedfileextractor.ExtractArchiveWithPasswordAction; @@ -540,7 +540,7 @@ public class DataResultFilterNode extends FilterNode { } @Override - public AbstractAction visit(FileInstanceNode fin){ + public AbstractAction visit(SleuthkitCaseFileInstanceNode fin){ return null; } From b9f7205eb0d31d122c1f9dbab31a951de43e8678 Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Fri, 22 Jun 2018 17:41:48 -0600 Subject: [PATCH 103/287] merge disentanglement episode II --- .../CommonFilesMetadataBuilder.java | 11 +++-- .../commonfilesearch/CommonFilesNode.java | 8 +--- .../commonfilesearch/CommonFilesPanel.java | 19 ++++----- .../CommonFilesSearchResultsViewerTable.java | 2 + .../EamDbCommonFilesAlgorithm.java | 42 +++++++++++++++---- .../CentralRepositoryFileInstanceNode.java | 6 +-- .../sleuthkit/autopsy/datamodel/Md5Node.java | 35 +--------------- .../SleuthkitCaseFileInstanceNode.java | 6 +-- 8 files changed, 61 insertions(+), 68 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesMetadataBuilder.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesMetadataBuilder.java index 3a0f1081b6..0108b4840e 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesMetadataBuilder.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesMetadataBuilder.java @@ -206,8 +206,14 @@ public abstract class CommonFilesMetadataBuilder { } } - Map> instanceCollatedCommonFiles = new TreeMap<>(); + Map> instanceCollatedCommonFiles = collatetMatchesByNumberOfInstances(commonFiles); + + return new CommonFilesMetadata(instanceCollatedCommonFiles); + } + protected static Map> collatetMatchesByNumberOfInstances(Map commonFiles) { + //collate matches by number of matching instances - doing this in sql doesnt seem efficient + Map> instanceCollatedCommonFiles = new TreeMap<>(); for(Md5Metadata md5Metadata : commonFiles.values()){ Integer size = md5Metadata.size(); @@ -219,8 +225,7 @@ public abstract class CommonFilesMetadataBuilder { instanceCollatedCommonFiles.put(size, value); } } - - return new CommonFilesMetadata(instanceCollatedCommonFiles); + return instanceCollatedCommonFiles; } /** diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesNode.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesNode.java index 401f5df6a6..168b7e933b 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesNode.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesNode.java @@ -75,15 +75,9 @@ final public class CommonFilesNode extends DisplayableItemNode { InstanceCountNodeFactory(CommonFilesMetadata metadata){ this.metadata = metadata; } - - @Override - protected Node createNodeForKey(String md5){ - Md5Metadata metadataForMd5 = this.metadata.getMetadataForMd5(md5); - return new Md5Node(metadataForMd5); - } @Override - protected boolean createKeys(List list) { + protected boolean createKeys(List list) { list.addAll(this.metadata.getMetadata().keySet()); return true; } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java index 254c76f0a5..5bc7d7d122 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java @@ -114,7 +114,7 @@ public final class CommonFilesPanel extends javax.swing.JPanel { private void search() { String pathText = Bundle.CommonFilesPanel_search_results_pathText(); - new SwingWorker() { + new SwingWorker() { private String tabTitle; private ProgressHandle progress; @@ -132,12 +132,13 @@ public final class CommonFilesPanel extends javax.swing.JPanel { @Override @SuppressWarnings({"BoxedValueEquality", "NumberEquality"}) - protected CommonFilesMetadata doInBackground() throws TskCoreException, NoCurrentCaseException, SQLException, EamDbException { + protected CommonFilesMetadata doInBackground() throws TskCoreException, NoCurrentCaseException, SQLException, EamDbException, Exception { progress = ProgressHandle.createHandle(Bundle.CommonFilesPanel_search_done_searchProgressGathering()); progress.start(); progress.switchToIndeterminate(); - Long dataSourceId = determineDataSourceId(); + Long dataSourceId = CommonFilesPanel.this.intraCasePanel.getSelectedDataSourceId(); + Integer caseId = CommonFilesPanel.this.interCasePanel.getSelectedCaseId(); CommonFilesMetadataBuilder builder; CommonFilesMetadata metadata; @@ -178,19 +179,15 @@ public final class CommonFilesPanel extends javax.swing.JPanel { this.tabTitle = builder.buildTabTitle(); - CommonFilesNode commonFilesNode = new CommonFilesNode(metadata); - - DataResultFilterNode dataResultFilterNode = new DataResultFilterNode(commonFilesNode, ExplorerManager.find(CommonFilesPanel.this)); - - TableFilterNode tableFilterWithDescendantsNode = new TableFilterNode(dataResultFilterNode); - - return tableFilterWithDescendantsNode; + return metadata; } @Override protected void done() { try { super.done(); + + CommonFilesMetadata metadata = this.get(); CommonFilesNode commonFilesNode = new CommonFilesNode(metadata); @@ -203,9 +200,11 @@ public final class CommonFilesPanel extends javax.swing.JPanel { Collection viewers = new ArrayList<>(1); viewers.add(table); + progress.setDisplayName(Bundle.CommonFilesPanel_search_done_searchProgressDisplay()); DataResultTopComponent.createInstance(tabTitle, pathText, tableFilterWithDescendantsNode, metadata.size(), viewers); progress.finish(); + } catch (InterruptedException ex) { LOGGER.log(Level.SEVERE, "Interrupted while loading Common Files", ex); MessageNotifyUtil.Message.error(Bundle.CommonFilesPanel_search_done_interupted()); diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesSearchResultsViewerTable.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesSearchResultsViewerTable.java index f699900e8e..f326488178 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesSearchResultsViewerTable.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesSearchResultsViewerTable.java @@ -43,6 +43,7 @@ public class CommonFilesSearchResultsViewerTable extends DataResultViewerTable { Map map = new HashMap<>(); map.put(Bundle.CommonFilesSearchResultsViewerTable_matchColLbl(), 235); map.put(Bundle.CommonFilesSearchResultsViewerTable_pathColLbl(), 300); + map.put(Bundle.CommonFilesSearchResultsViewerTable_caseColLbl1(), 200); map.put(Bundle.CommonFilesSearchResultsViewerTable_dataSourceColLbl(), 200); map.put(Bundle.CommonFilesSearchResultsViewerTable_hashsetHitsColLbl(), 100); map.put(Bundle.CommonFilesSearchResultsViewerTable_mimeTypeColLbl(), 150); @@ -55,6 +56,7 @@ public class CommonFilesSearchResultsViewerTable extends DataResultViewerTable { "CommonFilesSearchResultsViewerTable.matchColLbl=Match", "CommonFilesSearchResultsViewerTable.pathColLbl=Parent Path", "CommonFilesSearchResultsViewerTable.hashsetHitsColLbl=Hash Set Hits", + "CommonFilesSearchResultsViewerTable.caseColLbl1=Case", "CommonFilesSearchResultsViewerTable.dataSourceColLbl=Data Source", "CommonFilesSearchResultsViewerTable.mimeTypeColLbl=MIME Type", "CommonFilesSearchResultsViewerTable.tagsColLbl1=Tags" diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbCommonFilesAlgorithm.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbCommonFilesAlgorithm.java index a1e8bbc63f..16122a9ab0 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbCommonFilesAlgorithm.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbCommonFilesAlgorithm.java @@ -27,6 +27,7 @@ import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.TreeMap; import java.util.logging.Level; import java.util.stream.Collectors; import org.openide.util.Exceptions; @@ -80,10 +81,11 @@ public abstract class EamDbCommonFilesAlgorithm extends CommonFilesMetadataBuild } protected CommonFilesMetadata findFiles(CorrelationCase correlationCase) throws TskCoreException, NoCurrentCaseException, SQLException, EamDbException, Exception { - Map currentCaseMetadata = getMetadataForCurrentCase(); - Collection values = currentCaseMetadata.keySet(); + Map> currentCaseMetadata = getMetadataForCurrentCase(); + Collection values = currentCaseMetadata.values().stream().flatMap(List::stream).collect(Collectors.toList()).stream().map(Md5Metadata::getMd5).collect(Collectors.toList()); + int currentCaseId; - Map interCaseCommonFiles = new HashMap<>(); + Map> interCaseCommonFiles = new HashMap<>(); try { // Need to include current Cases results for specific case comparison currentCaseId = dbManager.getCase(Case.getCurrentCase()).getID(); @@ -104,17 +106,25 @@ public abstract class EamDbCommonFilesAlgorithm extends CommonFilesMetadataBuild return new CommonFilesMetadata(interCaseCommonFiles); } - private Map getMetadataForCurrentCase() throws NoCurrentCaseException, TskCoreException, SQLException, Exception { + private Map> getMetadataForCurrentCase() throws NoCurrentCaseException, TskCoreException, SQLException, Exception { //we need the list of files in the present case so we can compare against the central repo CommonFilesMetadata metaData = super.findFiles(); - Map commonFiles = metaData.getMetadata(); + Map> commonFiles = metaData.getMetadata(); return commonFiles; } - private Map gatherIntercaseResults(Collection artifactInstances, Map commonFiles) { + /** + * @param artifactInstances all 'common files' in central repo + * @param commonFiles matches must ultimately have appeared in this collection + * @return collated map of instance counts to lists of matches + */ + private Map> gatherIntercaseResults(Collection artifactInstances, Map> commonFiles) { Map interCaseCommonFiles = new HashMap<>(); + Map cachedFiles = new HashMap<>(); + + Map flattenedCommonFiles = flatten(commonFiles); for (CentralRepositoryFile instance : artifactInstances) { @@ -125,12 +135,12 @@ public abstract class EamDbCommonFilesAlgorithm extends CommonFilesMetadataBuild continue; } //Builds a 3rd list which contains instances which are in currentCaseMetadata map, uses current case objectId - if (commonFiles.containsKey(md5)) { + if (flattenedCommonFiles.containsKey(md5)) { try { // we don't *have* all the information for the rows in the CR, // so we need to consult the present case via the SleuthkitCase object - final Iterator identitcalFileInstanceMetadata = commonFiles.get(md5).getMetadata().iterator(); + final Iterator identitcalFileInstanceMetadata = flattenedCommonFiles.get(md5).getMetadata().iterator(); FileInstanceNodeGenerator nodeGenerator = FileInstanceNodeGenerator.createInstance(identitcalFileInstanceMetadata, instance, cachedFiles); @@ -150,7 +160,9 @@ public abstract class EamDbCommonFilesAlgorithm extends CommonFilesMetadataBuild } } - return interCaseCommonFiles; + Map> instanceCollatedCommonFiles = collatetMatchesByNumberOfInstances(interCaseCommonFiles); + + return instanceCollatedCommonFiles; } @Override @@ -174,4 +186,16 @@ public abstract class EamDbCommonFilesAlgorithm extends CommonFilesMetadataBuild } throw new Exception("Cannot locate case."); } + + private Map flatten(Map> commonFiles) { + //This is obviously junk and will go away when we perform subsequent refactors + Map flattened = new HashMap<>(); + for(List list : commonFiles.values()){ + for(Md5Metadata md5 : list){ + flattened.put(md5.getMd5(), md5); + } + } + + return flattened; + } } diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/CentralRepositoryFileInstanceNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/CentralRepositoryFileInstanceNode.java index 6b5dd72810..ade1521a95 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/CentralRepositoryFileInstanceNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/CentralRepositoryFileInstanceNode.java @@ -138,7 +138,7 @@ public class CentralRepositoryFileInstanceNode extends DisplayableItemNode { final String caseQualifiedDataSource = String.format("%s: %s", centralRepoFile.getCorrelationCase().getDisplayName(), centralRepoFile.getCorrelationDataSource().getName()); - map.put(CentralRepositoryFileInstanceNode.CentralRepoFileInstancesPropertyType.File.toString(), name); + map.put(CentralRepositoryFileInstanceNode.CentralRepoFileInstancesPropertyType.Match.toString(), name); map.put(CentralRepositoryFileInstanceNode.CentralRepoFileInstancesPropertyType.ParentPath.toString(), parent); map.put(CentralRepositoryFileInstanceNode.CentralRepoFileInstancesPropertyType.HashsetHits.toString(), ""); map.put(CentralRepositoryFileInstanceNode.CentralRepoFileInstancesPropertyType.Case.toString(), caseName); @@ -151,7 +151,7 @@ public class CentralRepositoryFileInstanceNode extends DisplayableItemNode { * instance of this object. */ @NbBundle.Messages({ - "CentralRepoFileInstancesPropertyType.fileColLbl=File", + "CentralRepoFileInstancesPropertyType.matchColLbl=File", "CentralRepoFileInstancesPropertyType.pathColLbl=Parent Path", "CentralRepoFileInstancesPropertyType.hashsetHitsColLbl=Hash Set Hits", "CentralRepoFileInstancesPropertyType.caseColLbl=Case", @@ -160,7 +160,7 @@ public class CentralRepositoryFileInstanceNode extends DisplayableItemNode { }) public enum CentralRepoFileInstancesPropertyType { - File(Bundle.CentralRepoFileInstancesPropertyType_fileColLbl()), + Match(Bundle.CentralRepoFileInstancesPropertyType_matchColLbl()), ParentPath(Bundle.CentralRepoFileInstancesPropertyType_pathColLbl()), HashsetHits(Bundle.CentralRepoFileInstancesPropertyType_hashsetHitsColLbl()), Case(Bundle.CentralRepoFileInstancesPropertyType_caseColLbl()), diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/Md5Node.java b/Core/src/org/sleuthkit/autopsy/datamodel/Md5Node.java index 8c1f1c0ba1..14f6298188 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/Md5Node.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/Md5Node.java @@ -71,26 +71,6 @@ public class Md5Node extends DisplayableItemNode { this.setDisplayName(this.md5Hash); } - - private static class Md5ChildCallable implements Callable { - private final Md5Metadata key; - private Md5ChildCallable(Md5Metadata key) { - this.key = key; - } - @Override - public Children call() throws Exception { - //Check, somehow, that your key has children, - //e.g., create "hasChildren" on the object - //to look in the database to see whether - //the object has children; - //if it doesn't have children, return a leaf: - if (key.getMetadata().isEmpty()) { - return Children.LEAF; - } else { - return Children.create(new FileInstanceNodeFactory(key), true); - } - } - } /** * How many files are in common? This will be the number of children. @@ -185,17 +165,8 @@ public class Md5Node extends DisplayableItemNode { } @Override - protected Node createNodeForKey(SleuthkitCaseFileInstanceMetadata file) { - try { - Case currentCase = Case.getCurrentCaseThrows(); - SleuthkitCase tskDb = currentCase.getSleuthkitCase(); - AbstractFile abstractFile = tskDb.findAllFilesWhere(String.format("obj_id in (%s)", file.getObjectId())).get(0); - - return new SleuthkitCaseFileInstanceNode(abstractFile, file.getDataSourceName()); - } catch (NoCurrentCaseException | TskCoreException ex) { - LOGGER.log(Level.SEVERE, String.format("Unable to create node for file with obj_id: %s.", new Object[]{file.getObjectId()}), ex); - } - return null; + protected Node createNodeForKey(FileInstanceNodeGenerator file) { + return file.generateNode(); } @Override @@ -206,8 +177,6 @@ public class Md5Node extends DisplayableItemNode { } @NbBundle.Messages({ - "CommonFileParentPropertyType.fileColLbl=File", - "CommonFileParentPropertyType.instanceColLbl=Instance Count", "CommonFileParentPropertyType.caseColLbl=Case", "CommonFileParentPropertyType.dataSourceColLbl=Data Source"}) public enum CommonFileParentPropertyType { diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/SleuthkitCaseFileInstanceNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/SleuthkitCaseFileInstanceNode.java index 8cb5916115..9610fe1b49 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/SleuthkitCaseFileInstanceNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/SleuthkitCaseFileInstanceNode.java @@ -111,7 +111,7 @@ public class SleuthkitCaseFileInstanceNode extends FileNode { */ static private void fillPropertyMap(Map map, SleuthkitCaseFileInstanceNode node) { - map.put(SleuthkitCaseFileInstanceNode.SleuthkitCaseFileInstanceNodePropertyType.File.toString(), node.getName()); + map.put(SleuthkitCaseFileInstanceNode.SleuthkitCaseFileInstanceNodePropertyType.Match.toString(), node.getName()); map.put(SleuthkitCaseFileInstanceNode.SleuthkitCaseFileInstanceNodePropertyType.ParentPath.toString(), node.getContent().getParentPath()); map.put(SleuthkitCaseFileInstanceNode.SleuthkitCaseFileInstanceNodePropertyType.HashsetHits.toString(), getHashSetHitsForFile(node.getContent())); map.put(SleuthkitCaseFileInstanceNode.SleuthkitCaseFileInstanceNodePropertyType.Case.toString(), node.getCase()); @@ -124,7 +124,7 @@ public class SleuthkitCaseFileInstanceNode extends FileNode { * instance of this object. */ @NbBundle.Messages({ - "SleuthkitCaseFileInstanceNodePropertyType.fileColLbl=File", + "SleuthkitCaseFileInstanceNodePropertyType.matchColLbl=Match", "SleuthkitCaseFileInstanceNodePropertyType.pathColLbl=Parent Path", "SleuthkitCaseFileInstanceNodePropertyType.hashsetHitsColLbl=Hash Set Hits", "SleuthkitCaseFileInstanceNodePropertyType.caseColLbl=Case", @@ -133,7 +133,7 @@ public class SleuthkitCaseFileInstanceNode extends FileNode { }) public enum SleuthkitCaseFileInstanceNodePropertyType { - File(Bundle.SleuthkitCaseFileInstanceNodePropertyType_fileColLbl()), + Match(Bundle.SleuthkitCaseFileInstanceNodePropertyType_matchColLbl()), ParentPath(Bundle.SleuthkitCaseFileInstanceNodePropertyType_pathColLbl()), HashsetHits(Bundle.SleuthkitCaseFileInstanceNodePropertyType_hashsetHitsColLbl()), Case(Bundle.SleuthkitCaseFileInstanceNodePropertyType_caseColLbl()), From 01b7b327bd8ed4d8cd0f23b5dabb2bed16af16c5 Mon Sep 17 00:00:00 2001 From: Andrew Ziehl Date: Tue, 26 Jun 2018 14:33:14 -0700 Subject: [PATCH 104/287] Create implementation of InstanceCallback interface for new common files search query. --- .../datamodel/AbstractSqlEamDb.java | 49 +++++++++++++++++++ .../centralrepository/datamodel/EamDb.java | 9 ++++ .../datamodel/SqliteEamDb.java | 17 +++++++ .../EamDbAttributeInstanceValuesCallback.java | 40 +++++++++++++++ 4 files changed, 115 insertions(+) create mode 100644 Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbAttributeInstanceValuesCallback.java diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java index 59df6b7bbc..02d426149a 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java @@ -1777,6 +1777,55 @@ abstract class AbstractSqlEamDb implements EamDb { EamDbUtil.closeConnection(conn); } } + + /** + * Process the Artifact instance in the EamDb + * + * @param type EamArtifact.Type to search for + * @param correlationCase CorrelationCase to filter by + * @param instanceTableCallback callback to process the instance + * @throws EamDbException + */ + @Override + public void processCaseInstancesTable(CorrelationAttribute.Type type, CorrelationCase correlationCase, InstanceTableCallback instanceTableCallback) throws EamDbException { + if (type == null) { + throw new EamDbException("Correlation type is null"); + } + + if (instanceTableCallback == null) { + throw new EamDbException("Callback interface is null"); + } + + if(correlationCase == null) { + throw new EamDbException("Correlation Case is null"); + } + + Connection conn = connect(); + PreparedStatement preparedStatement = null; + ResultSet resultSet = null; + String tableName = EamDbUtil.correlationTypeToInstanceTableName(type); + StringBuilder sql = new StringBuilder(); + sql.append("SELECT value FROM "); + sql.append(tableName); + sql.append(" WHERE value IN (SELECT value FROM "); + sql.append(tableName); + sql.append(" WHERE case_id=? AND known_status !=?) GROUP BY value HAVING COUNT(DISTINCT case_id) > 1 ORDER BY value"); + + try { + preparedStatement = conn.prepareStatement(sql.toString()); + preparedStatement.setString(1, correlationCase.getCaseUUID()); + preparedStatement.setByte(2, TskData.FileKnown.KNOWN.getFileKnownValue()); + resultSet = preparedStatement.executeQuery(); + instanceTableCallback.process(resultSet); + } catch (SQLException ex) { + throw new EamDbException("Error getting all artifact instances from instances table", ex); + } finally { + EamDbUtil.closeStatement(preparedStatement); + EamDbUtil.closeResultSet(resultSet); + EamDbUtil.closeConnection(conn); + } + } + @Override public EamOrganization newOrganization(EamOrganization eamOrg) throws EamDbException { diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDb.java index 7ced4a1d7d..59e87ab023 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDb.java @@ -685,4 +685,13 @@ public interface EamDb { * @throws EamDbException */ void processInstanceTable(CorrelationAttribute.Type type, InstanceTableCallback instanceTableCallback) throws EamDbException; + + /** + * Process the Artifact md5s in the EamDb for matches of case files which are not known + * @param type EamArtifact.Type to search for + * @param correlationCase CorrelationCase to filter by + * @param instanceTableCallback callback to process the instance + * @throws EamDbException + */ + public void processCaseInstancesTable(CorrelationAttribute.Type type, CorrelationCase correlationCase, InstanceTableCallback instanceTableCallback) throws EamDbException; } diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java index 4a3ef36530..e9852f2d34 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java @@ -695,6 +695,23 @@ final class SqliteEamDb extends AbstractSqlEamDb { releaseSharedLock(); } } + /** + * Process the Artifact md5s in the EamDb for matches of case files which are not known + * @param type EamArtifact.Type to search for + * @param correlationCase CorrelationCase to filter by + * @param instanceTableCallback callback to process the instance + * @throws EamDbException + */ + @Override + public void processCaseInstancesTable(CorrelationAttribute.Type type, CorrelationCase correlationCase, InstanceTableCallback instanceTableCallback) throws EamDbException { + try { + acquireSharedLock(); + super.processCaseInstancesTable(type, correlationCase, instanceTableCallback); + } finally { + releaseSharedLock(); + } + } + /** * Check whether a reference set with the given name/version is in the central repo. * Used to check for name collisions when creating reference sets. diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbAttributeInstanceValuesCallback.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbAttributeInstanceValuesCallback.java new file mode 100644 index 0000000000..ab258695c6 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbAttributeInstanceValuesCallback.java @@ -0,0 +1,40 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package org.sleuthkit.autopsy.commonfilesearch; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import org.openide.util.Exceptions; +import org.sleuthkit.autopsy.centralrepository.datamodel.InstanceTableCallback; + +/** + * + * @author Andrrew + */ +public class EamDbAttributeInstanceValuesCallback implements InstanceTableCallback { + + List correlationValues = new ArrayList<>(); + + @Override + public void process(ResultSet resultSet) { + try { + while(resultSet.next()){ + correlationValues.add(InstanceTableCallback.getValue(resultSet)); + } + } catch (SQLException ex) { + Exceptions.printStackTrace(ex); + } + } + + public List getCorrelationValues() { + return Collections.unmodifiableList(correlationValues); + } + + + } \ No newline at end of file From 09f917f21f673595ffb895e1bdd8d2987aefb44b Mon Sep 17 00:00:00 2001 From: Andrew Ziehl Date: Tue, 26 Jun 2018 14:53:19 -0700 Subject: [PATCH 105/287] Add class to gather query results for the CommonFilesSearchPanel once wired up. --- .../EamDbAttributeInstanceValuesCallback.java | 40 --------- .../EamDbAttributeInstancesAlgorithm.java | 81 +++++++++++++++++++ 2 files changed, 81 insertions(+), 40 deletions(-) delete mode 100644 Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbAttributeInstanceValuesCallback.java create mode 100644 Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbAttributeInstancesAlgorithm.java diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbAttributeInstanceValuesCallback.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbAttributeInstanceValuesCallback.java deleted file mode 100644 index ab258695c6..0000000000 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbAttributeInstanceValuesCallback.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package org.sleuthkit.autopsy.commonfilesearch; - -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import org.openide.util.Exceptions; -import org.sleuthkit.autopsy.centralrepository.datamodel.InstanceTableCallback; - -/** - * - * @author Andrrew - */ -public class EamDbAttributeInstanceValuesCallback implements InstanceTableCallback { - - List correlationValues = new ArrayList<>(); - - @Override - public void process(ResultSet resultSet) { - try { - while(resultSet.next()){ - correlationValues.add(InstanceTableCallback.getValue(resultSet)); - } - } catch (SQLException ex) { - Exceptions.printStackTrace(ex); - } - } - - public List getCorrelationValues() { - return Collections.unmodifiableList(correlationValues); - } - - - } \ No newline at end of file diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbAttributeInstancesAlgorithm.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbAttributeInstancesAlgorithm.java new file mode 100644 index 0000000000..497c9981ff --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbAttributeInstancesAlgorithm.java @@ -0,0 +1,81 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2018 Basis Technology Corp. + * Contact: carrier sleuthkit 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.commonfilesearch; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.logging.Level; +import org.openide.util.Exceptions; +import org.sleuthkit.autopsy.casemodule.Case; +import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttribute; +import org.sleuthkit.autopsy.centralrepository.datamodel.EamDb; +import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException; +import org.sleuthkit.autopsy.centralrepository.datamodel.InstanceTableCallback; +import org.sleuthkit.autopsy.coreutils.Logger; + +/** + * Used to process and return CorrelationCase md5s from the EamDB for CommonFilesSearch. + */ +class EamDbAttributeInstancesAlgorithm { + + private static final Logger logger = Logger.getLogger(CommonFilesPanel.class.getName()); + + List getCorrelationCaseAttributeValues(Case currentCase) { + List intercaseCommonValues = new ArrayList<>(); + try { + EamDbAttributeInstancesCallback instancetableCallback = new EamDbAttributeInstancesCallback(); + EamDb DbManager = EamDb.getInstance(); + CorrelationAttribute.Type fileType = EamDb.getInstance().getCorrelationTypeById(CorrelationAttribute.FILES_TYPE_ID); + DbManager.processCaseInstancesTable(fileType, DbManager.getCase(currentCase), instancetableCallback); + + intercaseCommonValues = instancetableCallback.getCorrelationValues(); + } catch (EamDbException ex) { + logger.log(Level.SEVERE, "Error accessing EamDb processing CaseInstancesTable.", ex); + } + return intercaseCommonValues; + } + + /** + * Callback to use with processCaseInstancesTable which generates a list of + * md5s for common files search + */ + private class EamDbAttributeInstancesCallback implements InstanceTableCallback { + + List correlationValues = new ArrayList<>(); + + @Override + public void process(ResultSet resultSet) { + try { + while (resultSet.next()) { + correlationValues.add(InstanceTableCallback.getValue(resultSet)); + } + } catch (SQLException ex) { + Exceptions.printStackTrace(ex); + } + } + + public List getCorrelationValues() { + return Collections.unmodifiableList(correlationValues); + } + + } +} From 5caf2a2d1319905e9379cb1d0bd7b6e099d7375b Mon Sep 17 00:00:00 2001 From: Andrew Ziehl Date: Wed, 27 Jun 2018 08:39:49 -0700 Subject: [PATCH 106/287] Add OR known null case to algorithm --- .../autopsy/centralrepository/datamodel/AbstractSqlEamDb.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java index 02d426149a..dd43f1b6c2 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java @@ -1809,7 +1809,7 @@ abstract class AbstractSqlEamDb implements EamDb { sql.append(tableName); sql.append(" WHERE value IN (SELECT value FROM "); sql.append(tableName); - sql.append(" WHERE case_id=? AND known_status !=?) GROUP BY value HAVING COUNT(DISTINCT case_id) > 1 ORDER BY value"); + sql.append(" WHERE case_id=? AND (known_status !=? OR known_status IS NULL) GROUP BY value HAVING COUNT(DISTINCT case_id) > 1 ORDER BY value"); try { preparedStatement = conn.prepareStatement(sql.toString()); From 69e6f47d381d813833e256acba6c6f6707e2507b Mon Sep 17 00:00:00 2001 From: Andrew Ziehl Date: Wed, 27 Jun 2018 10:54:32 -0700 Subject: [PATCH 107/287] Added id, datasource_id to results. Still needs separate query which retrieves single row of instance table by id. --- .../datamodel/AbstractSqlEamDb.java | 2 +- .../EamDbAttributeInstancesAlgorithm.java | 41 ++++++++++++++----- 2 files changed, 31 insertions(+), 12 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java index dd43f1b6c2..898dd22d16 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java @@ -1805,7 +1805,7 @@ abstract class AbstractSqlEamDb implements EamDb { ResultSet resultSet = null; String tableName = EamDbUtil.correlationTypeToInstanceTableName(type); StringBuilder sql = new StringBuilder(); - sql.append("SELECT value FROM "); + sql.append("SELECT id,value, data_source_id FROM "); // TODO should this select * so any field is available? sql.append(tableName); sql.append(" WHERE value IN (SELECT value FROM "); sql.append(tableName); diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbAttributeInstancesAlgorithm.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbAttributeInstancesAlgorithm.java index 497c9981ff..73759acff4 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbAttributeInstancesAlgorithm.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbAttributeInstancesAlgorithm.java @@ -20,9 +20,9 @@ package org.sleuthkit.autopsy.commonfilesearch; import java.sql.ResultSet; import java.sql.SQLException; -import java.util.ArrayList; import java.util.Collections; -import java.util.List; +import java.util.HashMap; +import java.util.Map; import java.util.logging.Level; import org.openide.util.Exceptions; import org.sleuthkit.autopsy.casemodule.Case; @@ -38,20 +38,32 @@ import org.sleuthkit.autopsy.coreutils.Logger; class EamDbAttributeInstancesAlgorithm { private static final Logger logger = Logger.getLogger(CommonFilesPanel.class.getName()); - - List getCorrelationCaseAttributeValues(Case currentCase) { - List intercaseCommonValues = new ArrayList<>(); + + private final Map intercaseCommonValuesMap = new HashMap<>(); + private final Map intercaseCommonDatasourcesMap = new HashMap<>(); + + void processCorrelationCaseAttributeValues(Case currentCase) { + try { EamDbAttributeInstancesCallback instancetableCallback = new EamDbAttributeInstancesCallback(); EamDb DbManager = EamDb.getInstance(); CorrelationAttribute.Type fileType = EamDb.getInstance().getCorrelationTypeById(CorrelationAttribute.FILES_TYPE_ID); DbManager.processCaseInstancesTable(fileType, DbManager.getCase(currentCase), instancetableCallback); - intercaseCommonValues = instancetableCallback.getCorrelationValues(); + intercaseCommonValuesMap.putAll(instancetableCallback.getCorrelationIdValueMap()); + intercaseCommonDatasourcesMap.putAll(instancetableCallback.getCorrelationIdDatasourceMap()); } catch (EamDbException ex) { logger.log(Level.SEVERE, "Error accessing EamDb processing CaseInstancesTable.", ex); } - return intercaseCommonValues; + + } + + Map getIntercaseCommonValuesMap() { + return Collections.unmodifiableMap(intercaseCommonValuesMap); + } + + Map getIntercaseCommonDatasourcesMap() { + return Collections.unmodifiableMap(intercaseCommonDatasourcesMap); } /** @@ -60,21 +72,28 @@ class EamDbAttributeInstancesAlgorithm { */ private class EamDbAttributeInstancesCallback implements InstanceTableCallback { - List correlationValues = new ArrayList<>(); + private final Map correlationIdToValueMap = new HashMap<>(); + private final Map correlationIdToDatasourceMap = new HashMap<>(); @Override public void process(ResultSet resultSet) { try { while (resultSet.next()) { - correlationValues.add(InstanceTableCallback.getValue(resultSet)); + int resultId = InstanceTableCallback.getId(resultSet); + correlationIdToValueMap.put(resultId, InstanceTableCallback.getValue(resultSet)); + correlationIdToDatasourceMap.put(resultId, InstanceTableCallback.getValue(resultSet)); } } catch (SQLException ex) { Exceptions.printStackTrace(ex); } } - public List getCorrelationValues() { - return Collections.unmodifiableList(correlationValues); + Map getCorrelationIdValueMap() { + return Collections.unmodifiableMap(correlationIdToValueMap); + } + + Map getCorrelationIdDatasourceMap() { + return Collections.unmodifiableMap(correlationIdToDatasourceMap); } } From dba86cd11e70b8ce8651a2c14c5553d1024c1e55 Mon Sep 17 00:00:00 2001 From: Andrew Ziehl Date: Wed, 27 Jun 2018 12:01:30 -0700 Subject: [PATCH 108/287] added callback and wrapper to process single row of file instance table by id. --- .../datamodel/AbstractSqlEamDb.java | 40 ++++++++++ .../centralrepository/datamodel/EamDb.java | 12 ++- .../datamodel/SqliteEamDb.java | 19 +++++ .../EamDbAttributeInstancesAlgorithm.java | 75 ++++++++++++++++--- 4 files changed, 134 insertions(+), 12 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java index 898dd22d16..9a12af9666 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java @@ -1778,6 +1778,46 @@ abstract class AbstractSqlEamDb implements EamDb { } } + /** + * Process the Artifact instance in the EamDb + * + * @param type EamArtifact.Type to search for + * @param instanceTableCallback callback to process the instance + * @throws EamDbException + */ + @Override + public void processInstanceTableRow(CorrelationAttribute.Type type, int id, InstanceTableCallback instanceTableCallback) throws EamDbException { + if (type == null) { + throw new EamDbException("Correlation type is null"); + } + + if (instanceTableCallback == null) { + throw new EamDbException("Callback interface is null"); + } + + Connection conn = connect(); + PreparedStatement preparedStatement = null; + ResultSet resultSet = null; + String tableName = EamDbUtil.correlationTypeToInstanceTableName(type); + StringBuilder sql = new StringBuilder(); + sql.append("select * from "); + sql.append(tableName); + sql.append("WHERE id = ?"); + + try { + preparedStatement = conn.prepareStatement(sql.toString()); + preparedStatement.setInt(1, id); + resultSet = preparedStatement.executeQuery(); + instanceTableCallback.process(resultSet); + } catch (SQLException ex) { + throw new EamDbException("Error getting all artifact instances from instances table", ex); + } finally { + EamDbUtil.closeStatement(preparedStatement); + EamDbUtil.closeResultSet(resultSet); + EamDbUtil.closeConnection(conn); + } + } + /** * Process the Artifact instance in the EamDb * diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDb.java index 59e87ab023..287970d42f 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDb.java @@ -686,6 +686,16 @@ public interface EamDb { */ void processInstanceTable(CorrelationAttribute.Type type, InstanceTableCallback instanceTableCallback) throws EamDbException; + /** + * Process a single Artifact instance in the EamDb + * + * @param type EamArtifact.Type to search for + * @param id the id of the row to return + * @param instanceTableCallback callback to process the instance + * @throws EamDbException + */ + void processInstanceTableRow(CorrelationAttribute.Type type, int id, InstanceTableCallback instanceTableCallback) throws EamDbException; + /** * Process the Artifact md5s in the EamDb for matches of case files which are not known * @param type EamArtifact.Type to search for @@ -693,5 +703,5 @@ public interface EamDb { * @param instanceTableCallback callback to process the instance * @throws EamDbException */ - public void processCaseInstancesTable(CorrelationAttribute.Type type, CorrelationCase correlationCase, InstanceTableCallback instanceTableCallback) throws EamDbException; + void processCaseInstancesTable(CorrelationAttribute.Type type, CorrelationCase correlationCase, InstanceTableCallback instanceTableCallback) throws EamDbException; } diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java index e9852f2d34..3335d825f0 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java @@ -695,6 +695,25 @@ final class SqliteEamDb extends AbstractSqlEamDb { releaseSharedLock(); } } + + /** + * Process a single Artifact instance row in the EamDb + * + * @param type EamArtifact.Type to search for + * @param id the id of the row to return + * @param instanceTableCallback callback to process the instance + * @throws EamDbException + */ + @Override + public void processInstanceTableRow(CorrelationAttribute.Type type, int id, InstanceTableCallback instanceTableCallback) throws EamDbException { + try { + acquireSharedLock(); + super.processInstanceTableRow(type, id, instanceTableCallback); + } finally { + releaseSharedLock(); + } + } + /** * Process the Artifact md5s in the EamDb for matches of case files which are not known * @param type EamArtifact.Type to search for diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbAttributeInstancesAlgorithm.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbAttributeInstancesAlgorithm.java index 73759acff4..c492c43cfb 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbAttributeInstancesAlgorithm.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbAttributeInstancesAlgorithm.java @@ -27,27 +27,46 @@ import java.util.logging.Level; import org.openide.util.Exceptions; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttribute; +import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationCase; import org.sleuthkit.autopsy.centralrepository.datamodel.EamDb; import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException; import org.sleuthkit.autopsy.centralrepository.datamodel.InstanceTableCallback; import org.sleuthkit.autopsy.coreutils.Logger; /** - * Used to process and return CorrelationCase md5s from the EamDB for CommonFilesSearch. + * Used to process and return CorrelationCase md5s from the EamDB for + * CommonFilesSearch. */ class EamDbAttributeInstancesAlgorithm { private static final Logger logger = Logger.getLogger(CommonFilesPanel.class.getName()); + + private final Map intercaseCommonValuesMap = new HashMap<>(); + private final Map intercaseCommonDatasourcesMap = new HashMap<>(); - private final Map intercaseCommonValuesMap = new HashMap<>(); - private final Map intercaseCommonDatasourcesMap = new HashMap<>(); - - void processCorrelationCaseAttributeValues(Case currentCase) { + CorrelationAttribute processCorrelationCaseSingleAttribute(int attrbuteId) { + try { + EamDbAttributeInstanceRowCallback instancetableCallback = new EamDbAttributeInstanceRowCallback(); + EamDb DbManager = EamDb.getInstance(); + CorrelationAttribute.Type fileType = DbManager.getCorrelationTypeById(CorrelationAttribute.FILES_TYPE_ID); + DbManager.processInstanceTableRow(fileType, attrbuteId, instancetableCallback); + + return instancetableCallback.getCorrelationAttribute(); + + } catch (EamDbException ex) { + logger.log(Level.SEVERE, "Error accessing EamDb processing InstanceTable row.", ex); + } + + return null; + } + + void processCorrelationCaseAttributeValues(Case currentCase) { + try { EamDbAttributeInstancesCallback instancetableCallback = new EamDbAttributeInstancesCallback(); EamDb DbManager = EamDb.getInstance(); - CorrelationAttribute.Type fileType = EamDb.getInstance().getCorrelationTypeById(CorrelationAttribute.FILES_TYPE_ID); + CorrelationAttribute.Type fileType = DbManager.getCorrelationTypeById(CorrelationAttribute.FILES_TYPE_ID); DbManager.processCaseInstancesTable(fileType, DbManager.getCase(currentCase), instancetableCallback); intercaseCommonValuesMap.putAll(instancetableCallback.getCorrelationIdValueMap()); @@ -55,14 +74,14 @@ class EamDbAttributeInstancesAlgorithm { } catch (EamDbException ex) { logger.log(Level.SEVERE, "Error accessing EamDb processing CaseInstancesTable.", ex); } - + } - + Map getIntercaseCommonValuesMap() { return Collections.unmodifiableMap(intercaseCommonValuesMap); } - - Map getIntercaseCommonDatasourcesMap() { + + Map getIntercaseCommonDatasourcesMap() { return Collections.unmodifiableMap(intercaseCommonDatasourcesMap); } @@ -91,10 +110,44 @@ class EamDbAttributeInstancesAlgorithm { Map getCorrelationIdValueMap() { return Collections.unmodifiableMap(correlationIdToValueMap); } - + Map getCorrelationIdDatasourceMap() { return Collections.unmodifiableMap(correlationIdToDatasourceMap); } } + + /** + * Callback to use with processCaseInstancesTable which generates a list of + * md5s for common files search + */ + private class EamDbAttributeInstanceRowCallback implements InstanceTableCallback { + + CorrelationAttribute correlationAttribute = null; + + @Override + public void process(ResultSet resultSet) { + try { + EamDb DbManager = EamDb.getInstance(); + CorrelationAttribute.Type fileType = DbManager.getCorrelationTypeById(CorrelationAttribute.FILES_TYPE_ID); + + while (resultSet.next()) { + CorrelationCase correlationCase = DbManager.getCaseByUUID(String.valueOf(InstanceTableCallback.getCaseId(resultSet))); + correlationAttribute = DbManager.getCorrelationAttribute(fileType, + correlationCase, + DbManager.getDataSource(correlationCase, String.valueOf(InstanceTableCallback.getDataSourceId(resultSet))), + InstanceTableCallback.getValue(resultSet), + InstanceTableCallback.getFilePath(resultSet)); + + } + } catch (SQLException | EamDbException ex) { + Exceptions.printStackTrace(ex); + } + } + + CorrelationAttribute getCorrelationAttribute() { + return correlationAttribute; + } + + } } From dfe4a6f50e164642d31f936c2c815217cc93aed9 Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Wed, 27 Jun 2018 16:16:12 -0600 Subject: [PATCH 109/287] merge errors --- ...ralRepositoryCaseFileInstanceMetadata.java | 1 - .../CentralRepositoryFileInstanceNode.java | 79 +++------------ .../CommonFilesSearchResultsViewerTable.java | 3 +- .../FileInstanceNodeGenerator.java | 2 - .../autopsy/commonfilesearch/Md5Node.java | 1 + .../SleuthkitCaseFileInstanceMetadata.java | 1 - .../SleuthkitCaseFileInstanceNode.java | 95 +++++++++++++++++++ .../datamodel/CommonFileChildNodeLoading.java | 95 ------------------- .../datamodel/DisplayableItemNodeVisitor.java | 10 +- .../directorytree/DataResultFilterNode.java | 5 +- 10 files changed, 115 insertions(+), 177 deletions(-) rename Core/src/org/sleuthkit/autopsy/{datamodel => commonfilesearch}/CentralRepositoryFileInstanceNode.java (55%) create mode 100644 Core/src/org/sleuthkit/autopsy/commonfilesearch/SleuthkitCaseFileInstanceNode.java delete mode 100644 Core/src/org/sleuthkit/autopsy/datamodel/CommonFileChildNodeLoading.java diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepositoryCaseFileInstanceMetadata.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepositoryCaseFileInstanceMetadata.java index 6eb4b20561..94fbe9cfcb 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepositoryCaseFileInstanceMetadata.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepositoryCaseFileInstanceMetadata.java @@ -21,7 +21,6 @@ package org.sleuthkit.autopsy.commonfilesearch; import java.util.Map; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepositoryFile; -import org.sleuthkit.autopsy.datamodel.CentralRepositoryFileInstanceNode; import org.sleuthkit.autopsy.datamodel.DisplayableItemNode; import org.sleuthkit.datamodel.AbstractFile; diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/CentralRepositoryFileInstanceNode.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepositoryFileInstanceNode.java similarity index 55% rename from Core/src/org/sleuthkit/autopsy/datamodel/CentralRepositoryFileInstanceNode.java rename to Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepositoryFileInstanceNode.java index ade1521a95..96565bbd39 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/CentralRepositoryFileInstanceNode.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepositoryFileInstanceNode.java @@ -17,20 +17,20 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.sleuthkit.autopsy.datamodel; +package org.sleuthkit.autopsy.commonfilesearch; import java.io.File; import java.util.ArrayList; import java.util.Arrays; -import java.util.LinkedHashMap; import java.util.List; -import java.util.Map; import javax.swing.Action; import org.openide.nodes.Children; import org.openide.nodes.Sheet; -import org.openide.util.NbBundle; import org.openide.util.lookup.Lookups; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepositoryFile; +import org.sleuthkit.autopsy.datamodel.DisplayableItemNode; +import org.sleuthkit.autopsy.datamodel.DisplayableItemNodeVisitor; +import org.sleuthkit.autopsy.datamodel.NodeProperty; import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.Content; @@ -103,30 +103,7 @@ public class CentralRepositoryFileInstanceNode extends DisplayableItemNode { sheet.put(sheetSet); } - Map map = new LinkedHashMap<>(); - fillPropertyMap(map, this); - - final String NO_DESCR = Bundle.AbstractFsContentNode_noDesc_text(); - for (CentralRepoFileInstancesPropertyType propType : CentralRepoFileInstancesPropertyType.values()) { - final String propString = propType.toString(); - final Object property = map.get(propString); - final NodeProperty nodeProperty = new NodeProperty<>(propString, propString, NO_DESCR, property); - sheetSet.put(nodeProperty); - } - - return sheet; - } - - /** - * Fill map with CentralRepoFileInstance properties - * - * @param map map with preserved ordering, where property names/values are - * put - * @param node The item to get properties for. - */ - private static void fillPropertyMap(Map map, CentralRepositoryFileInstanceNode node) { - - final CentralRepositoryFile centralRepoFile = node.getCentralRepoFile(); + final CentralRepositoryFile centralRepoFile = this.getCentralRepoFile(); final String fullPath = centralRepoFile.getFilePath(); final File file = new File(fullPath); @@ -138,44 +115,14 @@ public class CentralRepositoryFileInstanceNode extends DisplayableItemNode { final String caseQualifiedDataSource = String.format("%s: %s", centralRepoFile.getCorrelationCase().getDisplayName(), centralRepoFile.getCorrelationDataSource().getName()); - map.put(CentralRepositoryFileInstanceNode.CentralRepoFileInstancesPropertyType.Match.toString(), name); - map.put(CentralRepositoryFileInstanceNode.CentralRepoFileInstancesPropertyType.ParentPath.toString(), parent); - map.put(CentralRepositoryFileInstanceNode.CentralRepoFileInstancesPropertyType.HashsetHits.toString(), ""); - map.put(CentralRepositoryFileInstanceNode.CentralRepoFileInstancesPropertyType.Case.toString(), caseName); - map.put(CentralRepositoryFileInstanceNode.CentralRepoFileInstancesPropertyType.DataSource.toString(), caseQualifiedDataSource); - map.put(CentralRepositoryFileInstanceNode.CentralRepoFileInstancesPropertyType.MimeType.toString(), ""); - } - - /** - * Encapsulates the columns to be displayed for reach row represented by an - * instance of this object. - */ - @NbBundle.Messages({ - "CentralRepoFileInstancesPropertyType.matchColLbl=File", - "CentralRepoFileInstancesPropertyType.pathColLbl=Parent Path", - "CentralRepoFileInstancesPropertyType.hashsetHitsColLbl=Hash Set Hits", - "CentralRepoFileInstancesPropertyType.caseColLbl=Case", - "CentralRepoFileInstancesPropertyType.dataSourceColLbl=Data Source", - "CentralRepoFileInstancesPropertyType.mimeTypeColLbl=MIME Type" - }) - public enum CentralRepoFileInstancesPropertyType { + final String NO_DESCR = "";//Bundle.CommonFilesSearchResultsViewerTable_noDesc(); - Match(Bundle.CentralRepoFileInstancesPropertyType_matchColLbl()), - ParentPath(Bundle.CentralRepoFileInstancesPropertyType_pathColLbl()), - HashsetHits(Bundle.CentralRepoFileInstancesPropertyType_hashsetHitsColLbl()), - Case(Bundle.CentralRepoFileInstancesPropertyType_caseColLbl()), - DataSource(Bundle.CentralRepoFileInstancesPropertyType_dataSourceColLbl()), - MimeType(Bundle.CentralRepoFileInstancesPropertyType_mimeTypeColLbl()); + sheetSet.put(new NodeProperty<>(org.sleuthkit.autopsy.commonfilesearch.Bundle.CommonFilesSearchResultsViewerTable_filesColLbl(), org.sleuthkit.autopsy.commonfilesearch.Bundle.CommonFilesSearchResultsViewerTable_filesColLbl(), NO_DESCR, name)); + sheetSet.put(new NodeProperty<>(org.sleuthkit.autopsy.commonfilesearch.Bundle.CommonFilesSearchResultsViewerTable_pathColLbl(), org.sleuthkit.autopsy.commonfilesearch.Bundle.CommonFilesSearchResultsViewerTable_pathColLbl(), NO_DESCR, parent)); + sheetSet.put(new NodeProperty<>(org.sleuthkit.autopsy.commonfilesearch.Bundle.CommonFilesSearchResultsViewerTable_hashsetHitsColLbl(), org.sleuthkit.autopsy.commonfilesearch.Bundle.CommonFilesSearchResultsViewerTable_hashsetHitsColLbl(), NO_DESCR, "")); + sheetSet.put(new NodeProperty<>(org.sleuthkit.autopsy.commonfilesearch.Bundle.CommonFilesSearchResultsViewerTable_dataSourceColLbl(), org.sleuthkit.autopsy.commonfilesearch.Bundle.CommonFilesSearchResultsViewerTable_dataSourceColLbl(), NO_DESCR, caseQualifiedDataSource)); + sheetSet.put(new NodeProperty<>(org.sleuthkit.autopsy.commonfilesearch.Bundle.CommonFilesSearchResultsViewerTable_mimeTypeColLbl(), org.sleuthkit.autopsy.commonfilesearch.Bundle.CommonFilesSearchResultsViewerTable_mimeTypeColLbl(), NO_DESCR, "")); - final private String displayString; - - private CentralRepoFileInstancesPropertyType(String displayString) { - this.displayString = displayString; - } - - @Override - public String toString() { - return displayString; - } - } + return sheet; + } } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesSearchResultsViewerTable.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesSearchResultsViewerTable.java index 0d00d90735..fc5d65451f 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesSearchResultsViewerTable.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesSearchResultsViewerTable.java @@ -55,6 +55,7 @@ public class CommonFilesSearchResultsViewerTable extends DataResultViewerTable { } @NbBundle.Messages({ + "CommonFilesSearchResultsViewerTable.noDescText= ", "CommonFilesSearchResultsViewerTable.filesColLbl=Files", "CommonFilesSearchResultsViewerTable.instancesColLbl=Instances", "CommonFilesSearchResultsViewerTable.pathColLbl=Parent Path", @@ -74,7 +75,7 @@ public class CommonFilesSearchResultsViewerTable extends DataResultViewerTable { TableColumn column = columnsEnumerator.nextElement(); final String headerValue = column.getHeaderValue().toString(); - final Integer get = COLUMN_WIDTHS.get((String)headerValue); + final Integer get = COLUMN_WIDTHS.get(headerValue); column.setPreferredWidth(get); } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/FileInstanceNodeGenerator.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/FileInstanceNodeGenerator.java index d01ef89547..3458203886 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/FileInstanceNodeGenerator.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/FileInstanceNodeGenerator.java @@ -29,9 +29,7 @@ import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepositoryFile; import org.sleuthkit.autopsy.coreutils.Logger; -import org.sleuthkit.autopsy.datamodel.CentralRepositoryFileInstanceNode; import org.sleuthkit.autopsy.datamodel.DisplayableItemNode; -import org.sleuthkit.autopsy.datamodel.SleuthkitCaseFileInstanceNode; import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.SleuthkitCase; import org.sleuthkit.datamodel.TskCoreException; diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/Md5Node.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/Md5Node.java index 4b341db937..c62cf87acf 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/Md5Node.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/Md5Node.java @@ -22,6 +22,7 @@ package org.sleuthkit.autopsy.commonfilesearch; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; import java.util.concurrent.Callable; import java.util.logging.Level; import org.openide.nodes.ChildFactory; diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/SleuthkitCaseFileInstanceMetadata.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/SleuthkitCaseFileInstanceMetadata.java index dcd3645d8d..32a98c873b 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/SleuthkitCaseFileInstanceMetadata.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/SleuthkitCaseFileInstanceMetadata.java @@ -24,7 +24,6 @@ import java.util.Map; import org.openide.nodes.Node; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepositoryFile; import org.sleuthkit.autopsy.datamodel.DisplayableItemNode; -import org.sleuthkit.autopsy.datamodel.SleuthkitCaseFileInstanceNode; import org.sleuthkit.datamodel.AbstractFile; /** diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/SleuthkitCaseFileInstanceNode.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/SleuthkitCaseFileInstanceNode.java new file mode 100644 index 0000000000..14a69872ae --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/SleuthkitCaseFileInstanceNode.java @@ -0,0 +1,95 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2018 Basis Technology Corp. + * Contact: carrier sleuthkit 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.commonfilesearch; + +import org.apache.commons.lang3.StringUtils; +import org.openide.nodes.Sheet; +import org.sleuthkit.autopsy.datamodel.DisplayableItemNodeVisitor; +import org.sleuthkit.autopsy.datamodel.FileNode; +import org.sleuthkit.autopsy.datamodel.NodeProperty; +import org.sleuthkit.datamodel.AbstractFile; + +/** + * Used by the Common Files search feature to encapsulate instances of a given + * MD5s matched in the search. These nodes will be children of Md5Nodes. + * + * Use this type for files which are in the current case. Contrast with + * CentralRepositoryFileInstanceNode which should be used when the + * FileInstance was found in some case not presently open in Autopsy, but present + * in the Central Repository. + */ +public class SleuthkitCaseFileInstanceNode extends FileNode { + + private final String caseName; + private final String dataSource; + + /** + * Create a node which can be used in a multilayer tree table and is based + * on an AbstractFile. + * + * @param fsContent + * @param dataSource + */ + public SleuthkitCaseFileInstanceNode(AbstractFile fsContent, String caseName, String dataSource) { + super(fsContent); + this.caseName = caseName; + this.dataSource = dataSource; + } + + @Override + public boolean isLeafTypeNode(){ + //Not used atm - could maybe be leveraged for better use in Children objects + return true; + } + + @Override + public T accept(DisplayableItemNodeVisitor visitor) { + return visitor.visit(this); + } + + String getCase(){ + return this.caseName; + } + + String getDataSource() { + return this.dataSource; + } + + @Override + protected Sheet createSheet() { + Sheet sheet = new Sheet(); + Sheet.Set sheetSet = sheet.get(Sheet.PROPERTIES); + if (sheetSet == null) { + sheetSet = Sheet.createPropertiesSet(); + sheet.put(sheetSet); + } + + final String NO_DESCR = Bundle.CommonFilesSearchResultsViewerTable_noDescText(); + + sheetSet.put(new NodeProperty<>(Bundle.CommonFilesSearchResultsViewerTable_filesColLbl(), Bundle.CommonFilesSearchResultsViewerTable_filesColLbl(), NO_DESCR, this.getContent().getName())); + sheetSet.put(new NodeProperty<>(Bundle.CommonFilesSearchResultsViewerTable_pathColLbl(), Bundle.CommonFilesSearchResultsViewerTable_pathColLbl(), NO_DESCR, this.getContent().getParentPath())); + sheetSet.put(new NodeProperty<>(Bundle.CommonFilesSearchResultsViewerTable_hashsetHitsColLbl(), Bundle.CommonFilesSearchResultsViewerTable_hashsetHitsColLbl(), NO_DESCR, getHashSetHitsForFile(this.getContent()))); + sheetSet.put(new NodeProperty<>(Bundle.CommonFilesSearchResultsViewerTable_dataSourceColLbl(), Bundle.CommonFilesSearchResultsViewerTable_dataSourceColLbl(), NO_DESCR, this.getDataSource())); + sheetSet.put(new NodeProperty<>(Bundle.CommonFilesSearchResultsViewerTable_mimeTypeColLbl(), Bundle.CommonFilesSearchResultsViewerTable_mimeTypeColLbl(), NO_DESCR, StringUtils.defaultString(this.getContent().getMIMEType()))); + + this.addTagProperty(sheetSet); + + return sheet; + } +} diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/CommonFileChildNodeLoading.java b/Core/src/org/sleuthkit/autopsy/datamodel/CommonFileChildNodeLoading.java deleted file mode 100644 index 0c83a12f61..0000000000 --- a/Core/src/org/sleuthkit/autopsy/datamodel/CommonFileChildNodeLoading.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * - * Autopsy Forensic Browser - * - * Copyright 2018 Basis Technology Corp. - * Contact: carrier sleuthkit 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.datamodel; - -import java.util.LinkedHashMap; -import java.util.Map; -import org.openide.nodes.Children; -import org.openide.nodes.Sheet; -import org.openide.util.NbBundle; - -/** - * A dummy node used by the child factory to display while children are being - * generated - */ -public class CommonFileChildNodeLoading extends DisplayableItemNode { - - public CommonFileChildNodeLoading(Children children) { - super(children); - } - - @Override - public T accept(DisplayableItemNodeVisitor visitor) { - return visitor.visit(this); - } - - @Override - public boolean isLeafTypeNode() { - return true; - } - - @Override - public String getItemType() { - return getClass().getName(); - } - - @Override - protected Sheet createSheet() { - Sheet sheet = new Sheet(); - Sheet.Set sheetSet = sheet.get(Sheet.PROPERTIES); - if (sheetSet == null) { - sheetSet = Sheet.createPropertiesSet(); - sheet.put(sheetSet); - } - - Map map = new LinkedHashMap<>(); - map.put(CommonFileChildLoadingPropertyType.File.toString(), "Loading..."); - - final String NO_DESCR = Bundle.AbstractFsContentNode_noDesc_text(); - for (CommonFileChildLoadingPropertyType propType : CommonFileChildLoadingPropertyType.values()) { - final String propString = propType.toString(); - sheetSet.put(new NodeProperty<>(propString, propString, NO_DESCR, map.get(propString))); - } - - return sheet; - } - - /** - * Represents the sole column for the 'dummy' loading node. - */ - @NbBundle.Messages({ - "CommonFileChildLoadingPropertyType.fileColLbl=File" - }) - public enum CommonFileChildLoadingPropertyType { - - File(Bundle.CommonFileChildLoadingPropertyType_fileColLbl()); - - final private String displayString; - - private CommonFileChildLoadingPropertyType(String displayString) { - this.displayString = displayString; - } - - @Override - public String toString() { - return displayString; - } - } -} diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/DisplayableItemNodeVisitor.java b/Core/src/org/sleuthkit/autopsy/datamodel/DisplayableItemNodeVisitor.java index 3387dafaec..24e181a2ac 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/DisplayableItemNodeVisitor.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/DisplayableItemNodeVisitor.java @@ -18,10 +18,11 @@ */ package org.sleuthkit.autopsy.datamodel; +import org.sleuthkit.autopsy.commonfilesearch.CentralRepositoryFileInstanceNode; import org.sleuthkit.autopsy.commonfilesearch.CommonFilesNode; -import org.sleuthkit.autopsy.commonfilesearch.FileInstanceNode; import org.sleuthkit.autopsy.commonfilesearch.InstanceCountNode; import org.sleuthkit.autopsy.commonfilesearch.Md5Node; +import org.sleuthkit.autopsy.commonfilesearch.SleuthkitCaseFileInstanceNode; import org.sleuthkit.autopsy.datamodel.DeletedContent.DeletedContentsChildren.DeletedContentNode; import org.sleuthkit.autopsy.datamodel.DeletedContent.DeletedContentsNode; import org.sleuthkit.autopsy.datamodel.FileSize.FileSizeRootChildren.FileSizeNode; @@ -120,8 +121,6 @@ public interface DisplayableItemNodeVisitor { T visit(CommonFilesNode cfn); T visit(SleuthkitCaseFileInstanceNode fin); - - T visit(CommonFileChildNodeLoading cfcnl); T visit(CentralRepositoryFileInstanceNode crfin); @@ -214,11 +213,6 @@ public interface DisplayableItemNodeVisitor { public T visit(InstanceCountNode icn){ return defaultVisit(icn); } - - @Override - public T visit(CommonFileChildNodeLoading cfcnl) { - return defaultVisit(cfcnl); - } @Override public T visit(CentralRepositoryFileInstanceNode crfin){ diff --git a/Core/src/org/sleuthkit/autopsy/directorytree/DataResultFilterNode.java b/Core/src/org/sleuthkit/autopsy/directorytree/DataResultFilterNode.java index d8dfebc0b6..66a623ef86 100644 --- a/Core/src/org/sleuthkit/autopsy/directorytree/DataResultFilterNode.java +++ b/Core/src/org/sleuthkit/autopsy/directorytree/DataResultFilterNode.java @@ -41,7 +41,6 @@ import org.sleuthkit.autopsy.actions.AddBlackboardArtifactTagAction; import org.sleuthkit.autopsy.actions.AddContentTagAction; import org.sleuthkit.autopsy.actions.DeleteFileBlackboardArtifactTagAction; import org.sleuthkit.autopsy.actions.DeleteFileContentTagAction; -import org.sleuthkit.autopsy.commonfilesearch.FileInstanceNode; import org.sleuthkit.autopsy.core.UserPreferences; import org.sleuthkit.autopsy.coreutils.ContextMenuExtensionPoint; import org.sleuthkit.autopsy.coreutils.Logger; @@ -63,9 +62,9 @@ import org.sleuthkit.autopsy.datamodel.LocalDirectoryNode; import org.sleuthkit.autopsy.datamodel.NodeSelectionInfo; import org.sleuthkit.autopsy.datamodel.Reports; import org.sleuthkit.autopsy.datamodel.SlackFileNode; -import org.sleuthkit.autopsy.datamodel.SleuthkitCaseFileInstanceNode; +import org.sleuthkit.autopsy.commonfilesearch.SleuthkitCaseFileInstanceNode; import org.sleuthkit.autopsy.datamodel.VirtualDirectoryNode; -import static org.sleuthkit.autopsy.directorytree.Bundle.*; +import static org.sleuthkit.autopsy.directorytree.Bundle.DataResultFilterNode_viewSourceArtifact_text; import org.sleuthkit.autopsy.modules.embeddedfileextractor.ExtractArchiveWithPasswordAction; import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.BlackboardArtifact; From 911c7870034a819a6bd7b87b3be80d7b45c0b770 Mon Sep 17 00:00:00 2001 From: "U-BASIS\\zhaohui" Date: Fri, 29 Jun 2018 14:32:22 -0400 Subject: [PATCH 110/287] 3964: Functional test include testing flag for zip bomb --- .../autopsy/ingest/EmbeddedFileTest.java | 22 ++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/ingest/EmbeddedFileTest.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/ingest/EmbeddedFileTest.java index 8f562d698b..a3502c89ac 100755 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/ingest/EmbeddedFileTest.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/ingest/EmbeddedFileTest.java @@ -23,6 +23,7 @@ import java.nio.file.Paths; import java.util.ArrayList; import java.util.List; import static junit.framework.Assert.assertEquals; +import static junit.framework.Assert.assertNotNull; import junit.framework.Test; import org.netbeans.junit.NbModuleSuite; import org.netbeans.junit.NbTestCase; @@ -37,6 +38,7 @@ import org.sleuthkit.autopsy.testutils.CaseUtils; import org.sleuthkit.autopsy.testutils.IngestUtils; import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.BlackboardArtifact; +import org.sleuthkit.datamodel.BlackboardAttribute; import org.sleuthkit.datamodel.TskCoreException; /** @@ -45,7 +47,7 @@ import org.sleuthkit.datamodel.TskCoreException; public class EmbeddedFileTest extends NbTestCase { private static final String CASE_NAME = "EmbeddedFileTest"; - private final Path IMAGE_PATH = Paths.get(this.getDataDir().toString(), "EmbeddedIM_img1_v1.vhd"); + private final Path IMAGE_PATH = Paths.get(this.getDataDir().toString(), "new_embedded.vhd"); public static final String HASH_VALUE = "098f6bcd4621d373cade4e832627b4f6"; private static final int DEEP_FOLDER_COUNT = 25; private Case openCase; @@ -92,13 +94,16 @@ public class EmbeddedFileTest extends NbTestCase { CaseUtils.closeCurrentCase(testSucceeded); } - public void testEncryption() { + public void testEncryptionAndZipBomb() { try { List results = openCase.getSleuthkitCase().findAllFilesWhere("name LIKE '%%'"); String protectedName1 = "password_protected.zip"; String protectedName2 = "level1_protected.zip"; String protectedName3 = "42.zip"; - assertEquals(2207, results.size()); + String depthZipBomb = "DepthTriggerZipBomb.zip"; + String ratioZipBomb = "RatioTriggerZipBomb.zip"; + int zipBombs = 0; + assertEquals(2221, results.size()); int passwdProtectedZips = 0; for (AbstractFile file : results) { //.zip file has artifact TSK_ENCRYPTION_DETECTED @@ -109,6 +114,15 @@ public class EmbeddedFileTest extends NbTestCase { assertEquals(artifact.getArtifactTypeID(), BlackboardArtifact.ARTIFACT_TYPE.TSK_ENCRYPTION_DETECTED.getTypeID()); passwdProtectedZips++; } + } else if (file.getName().equalsIgnoreCase(depthZipBomb) || file.getName().equalsIgnoreCase(ratioZipBomb)){ + ArrayList artifacts = file.getAllArtifacts(); + assertEquals(1, artifacts.size()); + for (BlackboardArtifact artifact : artifacts) { + assertEquals(artifact.getArtifactTypeID(), BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT.getTypeID()); + BlackboardAttribute attribute = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME)); + assertNotNull("Possible Zip Bomb", attribute); + zipBombs++; + } } else {//No other files have artifact defined assertEquals(0, file.getAllArtifacts().size()); } @@ -117,6 +131,8 @@ public class EmbeddedFileTest extends NbTestCase { } //Make sure 3 password protected zip files have been tested: password_protected.zip, level1_protected.zip and 42.zip that we download for bomb testing. assertEquals(3, passwdProtectedZips); + //Make sure 2 zip bomb files have been tested: DepthTriggerZipBomb.zip and RatioTriggerZipBomb.zip. + assertEquals(2, zipBombs); } catch (TskCoreException ex) { Exceptions.printStackTrace(ex); Assert.fail(ex); From 3eaf840a5f50d9ac1cdecda0164be3a97929730d Mon Sep 17 00:00:00 2001 From: "U-BASIS\\zhaohui" Date: Fri, 29 Jun 2018 14:36:44 -0400 Subject: [PATCH 111/287] 3964: correct the image name --- .../src/org/sleuthkit/autopsy/ingest/EmbeddedFileTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/ingest/EmbeddedFileTest.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/ingest/EmbeddedFileTest.java index a3502c89ac..24366414d7 100755 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/ingest/EmbeddedFileTest.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/ingest/EmbeddedFileTest.java @@ -47,7 +47,7 @@ import org.sleuthkit.datamodel.TskCoreException; public class EmbeddedFileTest extends NbTestCase { private static final String CASE_NAME = "EmbeddedFileTest"; - private final Path IMAGE_PATH = Paths.get(this.getDataDir().toString(), "new_embedded.vhd"); + private final Path IMAGE_PATH = Paths.get(this.getDataDir().toString(), "EmbeddedIM_img1_v1.vhd"); public static final String HASH_VALUE = "098f6bcd4621d373cade4e832627b4f6"; private static final int DEEP_FOLDER_COUNT = 25; private Case openCase; From 7e37d4cdd25e1c60449612264ec500648095e75b Mon Sep 17 00:00:00 2001 From: "U-BASIS\\zhaohui" Date: Fri, 29 Jun 2018 14:41:34 -0400 Subject: [PATCH 112/287] 3964: rename image name --- .../src/org/sleuthkit/autopsy/ingest/EmbeddedFileTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/ingest/EmbeddedFileTest.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/ingest/EmbeddedFileTest.java index 24366414d7..0bb8144527 100755 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/ingest/EmbeddedFileTest.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/ingest/EmbeddedFileTest.java @@ -47,7 +47,7 @@ import org.sleuthkit.datamodel.TskCoreException; public class EmbeddedFileTest extends NbTestCase { private static final String CASE_NAME = "EmbeddedFileTest"; - private final Path IMAGE_PATH = Paths.get(this.getDataDir().toString(), "EmbeddedIM_img1_v1.vhd"); + private final Path IMAGE_PATH = Paths.get(this.getDataDir().toString(), "EmbeddedIM_img2_v1.vhd"); public static final String HASH_VALUE = "098f6bcd4621d373cade4e832627b4f6"; private static final int DEEP_FOLDER_COUNT = 25; private Case openCase; From 91cbc5877437b5ced54a271b0ac99a532cd35d06 Mon Sep 17 00:00:00 2001 From: "U-BASIS\\zhaohui" Date: Fri, 29 Jun 2018 15:08:14 -0400 Subject: [PATCH 113/287] 3964: The new vhd file includes the 2 zip bomb test files --- Core/build.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/build.xml b/Core/build.xml index f38f7732b2..322fe961ff 100644 --- a/Core/build.xml +++ b/Core/build.xml @@ -86,7 +86,7 @@ - + From 9e8f613d0860e35edaeed56ee995e13aa436af57 Mon Sep 17 00:00:00 2001 From: Andrew Ziehl Date: Mon, 2 Jul 2018 08:16:57 -0700 Subject: [PATCH 114/287] Cleanup CommonFilesPanel --- .../commonfilesearch/CommonFilesPanel.java | 171 +++++++++--------- .../commonfilessearch/InterCaseUtils.java | 4 +- 2 files changed, 92 insertions(+), 83 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java index d986be5ac0..3dc07956fe 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java @@ -30,6 +30,7 @@ import javax.swing.SwingUtilities; import javax.swing.SwingWorker; import org.netbeans.api.progress.ProgressHandle; import org.openide.explorer.ExplorerManager; +import org.openide.util.Exceptions; import org.openide.util.NbBundle; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; @@ -57,6 +58,7 @@ public final class CommonFilesPanel extends javax.swing.JPanel { private static final Long NO_DATA_SOURCE_SELECTED = -1L; private static final Logger LOGGER = Logger.getLogger(CommonFilesPanel.class.getName()); + private boolean singleDataSource = false; private String selectedDataSource = ""; private boolean pictureViewCheckboxState; @@ -74,7 +76,6 @@ public final class CommonFilesPanel extends javax.swing.JPanel { this.errorText.setVisible(false); this.intraCasePanel.setParent(this); - this.interCasePanel.setParent(this); this.setupDataSources(); @@ -85,79 +86,21 @@ public final class CommonFilesPanel extends javax.swing.JPanel { } } + private static boolean isEamDbAvailable() { + try { + EamDb DbManager = EamDb.getInstance(); + return DbManager != null; + } catch (EamDbException ex) { + LOGGER.log(Level.SEVERE, "Unexpected exception while checking for EamDB enabled.", ex); + } + return false; + } + private void disableIntercaseSearch() { this.intraCaseRadio.setSelected(true); this.interCaseRadio.setEnabled(false); } - //only enable all this stuff if we actually have datasources - if (dataSourcesNames.length > 0) { - dataSourcesNames = CommonFilesPanel.this.dataSourceMap.values().toArray(dataSourcesNames); - CommonFilesPanel.this.dataSourcesList = new DataSourceComboBoxModel(dataSourcesNames); - CommonFilesPanel.this.selectDataSourceComboBox.setModel(CommonFilesPanel.this.dataSourcesList); - - boolean multipleDataSources = this.caseHasMultipleSources(); - - CommonFilesPanel.this.allDataSourcesRadioButton.setEnabled(true); - CommonFilesPanel.this.allDataSourcesRadioButton.setSelected(true); - - if (!multipleDataSources) { - CommonFilesPanel.this.withinDataSourceRadioButton.setEnabled(false); - CommonFilesPanel.this.withinDataSourceRadioButton.setSelected(false); - withinDataSourceSelected(false); - CommonFilesPanel.this.selectDataSourceComboBox.setEnabled(false); - } - - CommonFilesPanel.this.searchButton.setEnabled(true); - } else { - MessageNotifyUtil.Message.info(Bundle.CommonFilesPanel_buildDataSourcesMap_updateUi_noDataSources()); - CommonFilesPanel.this.cancelButtonActionPerformed(null); - } - } - - private boolean caseHasMultipleSources() { - return CommonFilesPanel.this.dataSourceMap.size() >= 3; - } - - @Override - protected Map doInBackground() throws NoCurrentCaseException, TskCoreException, SQLException { - DataSourceLoader loader = new DataSourceLoader(); - return loader.getDataSourceMap(); - } - - @Override - protected void done() { - - try { - CommonFilesPanel.this.dataSourceMap = this.get(); - - updateUi(); - - } catch (InterruptedException ex) { - LOGGER.log(Level.SEVERE, "Interrupted while building Common Files Search dialog.", ex); - MessageNotifyUtil.Message.error(Bundle.CommonFilesPanel_buildDataSourceMap_done_interupted()); - } catch (ExecutionException ex) { - String errorMessage; - Throwable inner = ex.getCause(); - if (inner instanceof TskCoreException) { - LOGGER.log(Level.SEVERE, "Failed to load data sources from database.", ex); - errorMessage = Bundle.CommonFilesPanel_buildDataSourceMap_done_tskCoreException(); - } else if (inner instanceof NoCurrentCaseException) { - LOGGER.log(Level.SEVERE, "Current case has been closed.", ex); - errorMessage = Bundle.CommonFilesPanel_buildDataSourceMap_done_noCurrentCaseException(); - } else if (inner instanceof SQLException) { - LOGGER.log(Level.SEVERE, "Unable to query db for data sources.", ex); - errorMessage = Bundle.CommonFilesPanel_buildDataSourceMap_done_sqlException(); - } else { - LOGGER.log(Level.SEVERE, "Unexpected exception while building Common Files Search dialog panel.", ex); - errorMessage = Bundle.CommonFilesPanel_buildDataSourceMap_done_exception(); - } - MessageNotifyUtil.Message.error(errorMessage); - } - } - }.execute(); - } - @NbBundle.Messages({ "CommonFilesPanel.search.results.titleAll=Common Files (All Data Sources)", "CommonFilesPanel.search.results.titleSingle=Common Files (Match Within Data Source: %s)", @@ -176,7 +119,7 @@ public final class CommonFilesPanel extends javax.swing.JPanel { private String tabTitle; private ProgressHandle progress; - + private void setTitleForAllDataSources() { this.tabTitle = Bundle.CommonFilesPanel_search_results_titleAll(); } @@ -194,7 +137,7 @@ public final class CommonFilesPanel extends javax.swing.JPanel { progress = ProgressHandle.createHandle(Bundle.CommonFilesPanel_search_done_searchProgressGathering()); progress.start(); progress.switchToIndeterminate(); - + Long dataSourceId = CommonFilesPanel.this.intraCasePanel.getSelectedDataSourceId(); Integer caseId = CommonFilesPanel.this.interCasePanel.getSelectedCaseId(); @@ -213,8 +156,8 @@ public final class CommonFilesPanel extends javax.swing.JPanel { } if (CommonFilesPanel.this.interCaseRadio.isSelected()) { - - if(caseId == InterCasePanel.NO_CASE_SELECTED){ + + if (caseId == InterCasePanel.NO_CASE_SELECTED) { builder = new AllCasesEamDbCommonFilesAlgorithm(CommonFilesPanel.this.intraCasePanel.getDataSourceMap(), filterByMedia, filterByDocuments); } else { builder = new SingleCaseEamDbCommonFilesAlgorithm(caseId, CommonFilesPanel.this.intraCasePanel.getDataSourceMap(), filterByMedia, filterByDocuments); @@ -230,11 +173,10 @@ public final class CommonFilesPanel extends javax.swing.JPanel { setTitleForSingleSource(dataSourceId); } } - + //TODO set title from one method rathe than two (or more) overloads - metadata = builder.findFiles(); - + this.tabTitle = builder.buildTabTitle(); return metadata; @@ -244,7 +186,7 @@ public final class CommonFilesPanel extends javax.swing.JPanel { protected void done() { try { super.done(); - + CommonFilesMetadata metadata = this.get(); CommonFilesNode commonFilesNode = new CommonFilesNode(metadata); @@ -258,11 +200,11 @@ public final class CommonFilesPanel extends javax.swing.JPanel { Collection viewers = new ArrayList<>(1); viewers.add(table); - + progress.setDisplayName(Bundle.CommonFilesPanel_search_done_searchProgressDisplay()); DataResultTopComponent.createInstance(tabTitle, pathText, tableFilterWithDescendantsNode, metadata.size(), viewers); progress.finish(); - + } catch (InterruptedException ex) { LOGGER.log(Level.SEVERE, "Interrupted while loading Common Files", ex); MessageNotifyUtil.Message.error(Bundle.CommonFilesPanel_search_done_interupted()); @@ -288,6 +230,73 @@ public final class CommonFilesPanel extends javax.swing.JPanel { }.execute(); } + //only enable all this stuff if we actually have datasources +// if (dataSourcesNames.length > 0) { +// dataSourcesNames = CommonFilesPanel.this.dataSourceMap.values().toArray(dataSourcesNames); +// CommonFilesPanel.this.dataSourcesList = new DataSourceComboBoxModel(dataSourcesNames); +// CommonFilesPanel.this.selectDataSourceComboBox.setModel(CommonFilesPanel.this.dataSourcesList); +// +// boolean multipleDataSources = this.caseHasMultipleSources(); +// +// CommonFilesPanel.this.allDataSourcesRadioButton.setEnabled(true); +// CommonFilesPanel.this.allDataSourcesRadioButton.setSelected(true); +// +// if (!multipleDataSources) { +// CommonFilesPanel.this.withinDataSourceRadioButton.setEnabled(false); +// CommonFilesPanel.this.withinDataSourceRadioButton.setSelected(false); +// withinDataSourceSelected(false); +// CommonFilesPanel.this.selectDataSourceComboBox.setEnabled(false); +// } +// +// CommonFilesPanel.this.searchButton.setEnabled(true); +// } else { +// MessageNotifyUtil.Message.info(Bundle.CommonFilesPanel_buildDataSourcesMap_updateUi_noDataSources()); +// CommonFilesPanel.this.cancelButtonActionPerformed(null); +// } +// } +// +// private boolean caseHasMultipleSources() { +// return CommonFilesPanel.this.dataSourceMap.size() >= 3; +// } +// +// @Override +// protected Map doInBackground() throws NoCurrentCaseException, TskCoreException, SQLException { +// DataSourceLoader loader = new DataSourceLoader(); +// return loader.getDataSourceMap(); +// } +// +// @Override +// protected void done() { +// +// try { +// CommonFilesPanel.this.dataSourceMap = this.get(); +// +// updateUi(); +// +// } catch (InterruptedException ex) { +// LOGGER.log(Level.SEVERE, "Interrupted while building Common Files Search dialog.", ex); +// MessageNotifyUtil.Message.error(Bundle.CommonFilesPanel_buildDataSourceMap_done_interupted()); +// } catch (ExecutionException ex) { +// String errorMessage; +// Throwable inner = ex.getCause(); +// if (inner instanceof TskCoreException) { +// LOGGER.log(Level.SEVERE, "Failed to load data sources from database.", ex); +// errorMessage = Bundle.CommonFilesPanel_buildDataSourceMap_done_tskCoreException(); +// } else if (inner instanceof NoCurrentCaseException) { +// LOGGER.log(Level.SEVERE, "Current case has been closed.", ex); +// errorMessage = Bundle.CommonFilesPanel_buildDataSourceMap_done_noCurrentCaseException(); +// } else if (inner instanceof SQLException) { +// LOGGER.log(Level.SEVERE, "Unable to query db for data sources.", ex); +// errorMessage = Bundle.CommonFilesPanel_buildDataSourceMap_done_sqlException(); +// } else { +// LOGGER.log(Level.SEVERE, "Unexpected exception while building Common Files Search dialog panel.", ex); +// errorMessage = Bundle.CommonFilesPanel_buildDataSourceMap_done_exception(); +// } +// MessageNotifyUtil.Message.error(errorMessage); +// } +// } +// }.execute(); +// } /** * Sets up the data sources dropdown and returns the data sources map for * future usage. @@ -396,7 +405,7 @@ public final class CommonFilesPanel extends javax.swing.JPanel { Map casemap = new HashMap<>(); CorrelationCase currentCorCase = EamDb.getInstance().getCase(Case.getCurrentCase()); for (CorrelationCase correlationCase : cases) { - if(currentCorCase.getID() != correlationCase.getID()) { // if not the current Case + if (currentCorCase.getID() != correlationCase.getID()) { // if not the current Case casemap.put(correlationCase.getID(), correlationCase.getDisplayName()); } } @@ -688,7 +697,7 @@ public final class CommonFilesPanel extends javax.swing.JPanel { this.pictureViewCheckboxState = this.pictureVideoCheckbox.isSelected(); this.documentsCheckboxState = this.documentsCheckbox.isSelected(); - + if (this.allFileCategoriesRadioButton.isSelected()) { this.pictureVideoCheckbox.setEnabled(false); this.documentsCheckbox.setEnabled(false); diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/InterCaseUtils.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/InterCaseUtils.java index ba8e9dccce..f8b62294da 100644 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/InterCaseUtils.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/InterCaseUtils.java @@ -295,9 +295,9 @@ class InterCaseUtils { int tally = 0; - for(Map.Entry file : searchDomain.getMetadata().entrySet()){ + for(Map.Entry> file : searchDomain.getMetadata().entrySet()){ - Collection fileInstances = file.getValue().getMetadata(); + Collection fileInstances = file.getValue(); for(SleuthkitCaseFileInstanceMetadata fileInstance : fileInstances){ From 5e4178c9bc9fe727a3bb6ab7965c051da05899a9 Mon Sep 17 00:00:00 2001 From: Andrew Ziehl Date: Mon, 2 Jul 2018 12:54:51 -0700 Subject: [PATCH 115/287] Cleanup broken setup datasources code, restore intracase logic. Allow Common Files Search for intercase if CR contains > 1 even if there is only one datasource. --- .../commonfilesearch/CommonFilesPanel.java | 73 +------------------ .../CommonFilesSearchAction.java | 10 ++- 2 files changed, 11 insertions(+), 72 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java index 3dc07956fe..5555c4ce03 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java @@ -176,7 +176,6 @@ public final class CommonFilesPanel extends javax.swing.JPanel { //TODO set title from one method rathe than two (or more) overloads metadata = builder.findFiles(); - this.tabTitle = builder.buildTabTitle(); return metadata; @@ -191,7 +190,7 @@ public final class CommonFilesPanel extends javax.swing.JPanel { CommonFilesNode commonFilesNode = new CommonFilesNode(metadata); - //TODO this could be enumerating the children!!! + // #VIK-3969 DataResultFilterNode dataResultFilterNode = new DataResultFilterNode(commonFilesNode, ExplorerManager.find(CommonFilesPanel.this)); TableFilterNode tableFilterWithDescendantsNode = new TableFilterNode(dataResultFilterNode, 3); @@ -230,73 +229,7 @@ public final class CommonFilesPanel extends javax.swing.JPanel { }.execute(); } - //only enable all this stuff if we actually have datasources -// if (dataSourcesNames.length > 0) { -// dataSourcesNames = CommonFilesPanel.this.dataSourceMap.values().toArray(dataSourcesNames); -// CommonFilesPanel.this.dataSourcesList = new DataSourceComboBoxModel(dataSourcesNames); -// CommonFilesPanel.this.selectDataSourceComboBox.setModel(CommonFilesPanel.this.dataSourcesList); -// -// boolean multipleDataSources = this.caseHasMultipleSources(); -// -// CommonFilesPanel.this.allDataSourcesRadioButton.setEnabled(true); -// CommonFilesPanel.this.allDataSourcesRadioButton.setSelected(true); -// -// if (!multipleDataSources) { -// CommonFilesPanel.this.withinDataSourceRadioButton.setEnabled(false); -// CommonFilesPanel.this.withinDataSourceRadioButton.setSelected(false); -// withinDataSourceSelected(false); -// CommonFilesPanel.this.selectDataSourceComboBox.setEnabled(false); -// } -// -// CommonFilesPanel.this.searchButton.setEnabled(true); -// } else { -// MessageNotifyUtil.Message.info(Bundle.CommonFilesPanel_buildDataSourcesMap_updateUi_noDataSources()); -// CommonFilesPanel.this.cancelButtonActionPerformed(null); -// } -// } -// -// private boolean caseHasMultipleSources() { -// return CommonFilesPanel.this.dataSourceMap.size() >= 3; -// } -// -// @Override -// protected Map doInBackground() throws NoCurrentCaseException, TskCoreException, SQLException { -// DataSourceLoader loader = new DataSourceLoader(); -// return loader.getDataSourceMap(); -// } -// -// @Override -// protected void done() { -// -// try { -// CommonFilesPanel.this.dataSourceMap = this.get(); -// -// updateUi(); -// -// } catch (InterruptedException ex) { -// LOGGER.log(Level.SEVERE, "Interrupted while building Common Files Search dialog.", ex); -// MessageNotifyUtil.Message.error(Bundle.CommonFilesPanel_buildDataSourceMap_done_interupted()); -// } catch (ExecutionException ex) { -// String errorMessage; -// Throwable inner = ex.getCause(); -// if (inner instanceof TskCoreException) { -// LOGGER.log(Level.SEVERE, "Failed to load data sources from database.", ex); -// errorMessage = Bundle.CommonFilesPanel_buildDataSourceMap_done_tskCoreException(); -// } else if (inner instanceof NoCurrentCaseException) { -// LOGGER.log(Level.SEVERE, "Current case has been closed.", ex); -// errorMessage = Bundle.CommonFilesPanel_buildDataSourceMap_done_noCurrentCaseException(); -// } else if (inner instanceof SQLException) { -// LOGGER.log(Level.SEVERE, "Unable to query db for data sources.", ex); -// errorMessage = Bundle.CommonFilesPanel_buildDataSourceMap_done_sqlException(); -// } else { -// LOGGER.log(Level.SEVERE, "Unexpected exception while building Common Files Search dialog panel.", ex); -// errorMessage = Bundle.CommonFilesPanel_buildDataSourceMap_done_exception(); -// } -// MessageNotifyUtil.Message.error(errorMessage); -// } -// } -// }.execute(); -// } + /** * Sets up the data sources dropdown and returns the data sources map for * future usage. @@ -335,7 +268,7 @@ public final class CommonFilesPanel extends javax.swing.JPanel { } private boolean caseHasMultipleSources() { - return CommonFilesPanel.this.intraCasePanel.getDataSourceMap().size() >= 2; + return CommonFilesPanel.this.intraCasePanel.getDataSourceMap().size() >= 3; } @Override diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesSearchAction.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesSearchAction.java index 2ecea6732a..c902a2d00b 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesSearchAction.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesSearchAction.java @@ -24,7 +24,8 @@ import org.openide.util.HelpCtx; import org.openide.util.NbBundle; import org.openide.util.actions.CallableSystemAction; import org.sleuthkit.autopsy.casemodule.Case; -import org.sleuthkit.autopsy.core.Installer; +import org.sleuthkit.autopsy.centralrepository.datamodel.EamDb; +import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException; import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.autopsy.coreutils.Logger; @@ -48,9 +49,14 @@ final public class CommonFilesSearchAction extends CallableSystemAction { public boolean isEnabled(){ boolean shouldBeEnabled = false; try { - shouldBeEnabled = Case.isCaseOpen() && Case.getCurrentCase().getDataSources().size() > 1; + shouldBeEnabled = Case.isCaseOpen() + && Case.getCurrentCase().getDataSources().size() > 1 + || (EamDb.isEnabled() && EamDb.getInstance().getCases().size() > 1); + } catch(TskCoreException ex) { logger.log(Level.SEVERE, "Error getting data sources for action enabled check", ex); + } catch (EamDbException ex) { + logger.log(Level.SEVERE, "Error getting CR cases for action enabled check", ex); } return super.isEnabled() && shouldBeEnabled; } From 2ec7ce6c5b5a0ef557c1befaed0d4fbf0f089525 Mon Sep 17 00:00:00 2001 From: Andrew Ziehl Date: Mon, 2 Jul 2018 13:33:57 -0700 Subject: [PATCH 116/287] FIx for NPE when interacting with IntercasePanel --- .../sleuthkit/autopsy/commonfilesearch/InterCasePanel.java | 5 ++--- .../sleuthkit/autopsy/commonfilesearch/IntraCasePanel.java | 4 ++-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.java index 940b1d5ba7..e636d322c7 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.java @@ -55,6 +55,7 @@ public class InterCasePanel extends javax.swing.JPanel { private void specificCaseSelected(boolean selected) { this.specificCentralRepoCaseRadio.setEnabled(selected); if (this.specificCentralRepoCaseRadio.isEnabled()) { + this.caseComboBox.setEnabled(true); this.caseComboBox.setSelectedIndex(0); } } @@ -128,15 +129,13 @@ public class InterCasePanel extends javax.swing.JPanel { private void specificCentralRepoCaseRadioActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_specificCentralRepoCaseRadioActionPerformed this.caseComboBox.setEnabled(true); - if(this.caseComboBox.getSelectedItem() == null){ + if(this.caseComboBox.isEnabled() && this.caseComboBox.getSelectedItem() == null){ this.caseComboBox.setSelectedIndex(0); } - this.parent.handleInterCaseSearchCriteriaChanged(); }//GEN-LAST:event_specificCentralRepoCaseRadioActionPerformed private void anyCentralRepoCaseRadioActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_anyCentralRepoCaseRadioActionPerformed this.caseComboBox.setEnabled(false); - this.parent.handleInterCaseSearchCriteriaChanged(); }//GEN-LAST:event_anyCentralRepoCaseRadioActionPerformed diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCasePanel.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCasePanel.java index d0b4d58daf..dd0cca8ae2 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCasePanel.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCasePanel.java @@ -152,12 +152,12 @@ public class IntraCasePanel extends javax.swing.JPanel { private void allDataSourcesRadioButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_allDataSourcesRadioButtonActionPerformed selectDataSourceComboBox.setEnabled(!allDataSourcesRadioButton.isSelected()); singleDataSource = false; - this.parent.handleIntraCaseSearchCriteriaChanged(); + //this.parent.handleIntraCaseSearchCriteriaChanged(); }//GEN-LAST:event_allDataSourcesRadioButtonActionPerformed private void withinDataSourceRadioButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_withinDataSourceRadioButtonActionPerformed withinDataSourceSelected(withinDataSourceRadioButton.isSelected()); - this.parent.handleIntraCaseSearchCriteriaChanged(); + //this.parent.handleIntraCaseSearchCriteriaChanged(); }//GEN-LAST:event_withinDataSourceRadioButtonActionPerformed private void selectDataSourceComboBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_selectDataSourceComboBoxActionPerformed From 952698fc06cc4993f904a0313f5f327040fb0939 Mon Sep 17 00:00:00 2001 From: Andrew Ziehl Date: Mon, 2 Jul 2018 14:11:30 -0700 Subject: [PATCH 117/287] Add Case column --- .../commonfilesearch/CentralRepositoryFileInstanceNode.java | 5 +++-- .../CommonFilesSearchResultsViewerTable.java | 2 +- .../autopsy/commonfilesearch/FileInstanceNode.java | 1 + .../autopsy/commonfilesearch/FileInstanceNodeGenerator.java | 6 ++---- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepositoryFileInstanceNode.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepositoryFileInstanceNode.java index 96565bbd39..1c0c336b55 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepositoryFileInstanceNode.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepositoryFileInstanceNode.java @@ -113,15 +113,16 @@ public class CentralRepositoryFileInstanceNode extends DisplayableItemNode { final String name = file.getName(); final String parent = file.getParent(); - final String caseQualifiedDataSource = String.format("%s: %s", centralRepoFile.getCorrelationCase().getDisplayName(), centralRepoFile.getCorrelationDataSource().getName()); + final String caseQualifiedDataSource = centralRepoFile.getCorrelationDataSource().getName(); - final String NO_DESCR = "";//Bundle.CommonFilesSearchResultsViewerTable_noDesc(); + final String NO_DESCR = Bundle.CommonFilesSearchResultsViewerTable_noDescText(); sheetSet.put(new NodeProperty<>(org.sleuthkit.autopsy.commonfilesearch.Bundle.CommonFilesSearchResultsViewerTable_filesColLbl(), org.sleuthkit.autopsy.commonfilesearch.Bundle.CommonFilesSearchResultsViewerTable_filesColLbl(), NO_DESCR, name)); sheetSet.put(new NodeProperty<>(org.sleuthkit.autopsy.commonfilesearch.Bundle.CommonFilesSearchResultsViewerTable_pathColLbl(), org.sleuthkit.autopsy.commonfilesearch.Bundle.CommonFilesSearchResultsViewerTable_pathColLbl(), NO_DESCR, parent)); sheetSet.put(new NodeProperty<>(org.sleuthkit.autopsy.commonfilesearch.Bundle.CommonFilesSearchResultsViewerTable_hashsetHitsColLbl(), org.sleuthkit.autopsy.commonfilesearch.Bundle.CommonFilesSearchResultsViewerTable_hashsetHitsColLbl(), NO_DESCR, "")); sheetSet.put(new NodeProperty<>(org.sleuthkit.autopsy.commonfilesearch.Bundle.CommonFilesSearchResultsViewerTable_dataSourceColLbl(), org.sleuthkit.autopsy.commonfilesearch.Bundle.CommonFilesSearchResultsViewerTable_dataSourceColLbl(), NO_DESCR, caseQualifiedDataSource)); sheetSet.put(new NodeProperty<>(org.sleuthkit.autopsy.commonfilesearch.Bundle.CommonFilesSearchResultsViewerTable_mimeTypeColLbl(), org.sleuthkit.autopsy.commonfilesearch.Bundle.CommonFilesSearchResultsViewerTable_mimeTypeColLbl(), NO_DESCR, "")); + sheetSet.put(new NodeProperty<>(org.sleuthkit.autopsy.commonfilesearch.Bundle.CommonFilesSearchResultsViewerTable_caseColLbl1(), org.sleuthkit.autopsy.commonfilesearch.Bundle.CommonFilesSearchResultsViewerTable_caseColLbl1(), NO_DESCR, caseName)); return sheet; } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesSearchResultsViewerTable.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesSearchResultsViewerTable.java index fc5d65451f..904822c3cb 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesSearchResultsViewerTable.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesSearchResultsViewerTable.java @@ -49,7 +49,7 @@ public class CommonFilesSearchResultsViewerTable extends DataResultViewerTable { map.put(Bundle.CommonFilesSearchResultsViewerTable_dataSourceColLbl(), 200); map.put(Bundle.CommonFilesSearchResultsViewerTable_hashsetHitsColLbl(), 100); map.put(Bundle.CommonFilesSearchResultsViewerTable_mimeTypeColLbl(), 130); - map.put(Bundle.CommonFilesSearchResultsViewerTable_tagsColLbl1(), 300); + map.put(Bundle.CommonFilesSearchResultsViewerTable_tagsColLbl1(), 300);; COLUMN_WIDTHS = Collections.unmodifiableMap(map); } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/FileInstanceNode.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/FileInstanceNode.java index 07c87035e1..b57b6b0b07 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/FileInstanceNode.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/FileInstanceNode.java @@ -80,6 +80,7 @@ public class FileInstanceNode extends FileNode { sheetSet.put(new NodeProperty<>(Bundle.CommonFilesSearchResultsViewerTable_hashsetHitsColLbl(), Bundle.CommonFilesSearchResultsViewerTable_hashsetHitsColLbl(), NO_DESCR, getHashSetHitsForFile(this.getContent()))); sheetSet.put(new NodeProperty<>(Bundle.CommonFilesSearchResultsViewerTable_dataSourceColLbl(), Bundle.CommonFilesSearchResultsViewerTable_dataSourceColLbl(), NO_DESCR, this.getDataSource())); sheetSet.put(new NodeProperty<>(Bundle.CommonFilesSearchResultsViewerTable_mimeTypeColLbl(), Bundle.CommonFilesSearchResultsViewerTable_mimeTypeColLbl(), NO_DESCR, StringUtils.defaultString(this.getContent().getMIMEType()))); + sheetSet.put(new NodeProperty<>(Bundle.CommonFilesSearchResultsViewerTable_caseColLbl1(), Bundle.CommonFilesSearchResultsViewerTable_caseColLbl1(), NO_DESCR, this.getContent().getSleuthkitCase().getDatabaseName())); this.addTagProperty(sheetSet); diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/FileInstanceNodeGenerator.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/FileInstanceNodeGenerator.java index 3458203886..71f2d67eb8 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/FileInstanceNodeGenerator.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/FileInstanceNodeGenerator.java @@ -19,12 +19,10 @@ */ package org.sleuthkit.autopsy.commonfilesearch; -import java.nio.file.Path; import java.nio.file.Paths; import java.util.Iterator; import java.util.Map; import java.util.logging.Level; -import org.openide.util.Exceptions; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepositoryFile; @@ -108,10 +106,10 @@ public abstract class FileInstanceNodeGenerator { */ public abstract DisplayableItemNode generateNode(); - public String getCaseName(){ + public String getCaseName() { return this.caseName; } - + /** * Get string name of the data source where this instance appears. * From 43f610eb9766606b6bd140d49be4e962a7514b27 Mon Sep 17 00:00:00 2001 From: Andrew Ziehl Date: Mon, 2 Jul 2018 14:54:00 -0700 Subject: [PATCH 118/287] Fix intracase radio logic to match 3961 requirements. Add Case string to Case column in search results. add .tif to list of image file extensions. --- .../CentralRepositoryFileInstanceNode.java | 2 +- .../autopsy/commonfilesearch/CommonFilesPanel.java | 2 +- .../autopsy/commonfilesearch/FileInstanceNode.java | 4 ++-- .../autopsy/commonfilesearch/IntraCasePanel.java | 12 ++++-------- .../autopsy/datamodel/FileTypeExtensions.java | 2 +- 5 files changed, 9 insertions(+), 13 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepositoryFileInstanceNode.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepositoryFileInstanceNode.java index 1c0c336b55..5c5f71082e 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepositoryFileInstanceNode.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepositoryFileInstanceNode.java @@ -51,7 +51,7 @@ public class CentralRepositoryFileInstanceNode extends DisplayableItemNode { private final AbstractFile md5Reference; public CentralRepositoryFileInstanceNode(CentralRepositoryFile content, AbstractFile md5Reference) { - super(Children.LEAF, Lookups.fixed(content)); + super(Children.LEAF, Lookups.fixed(content)); // TODO, using md5Reference enables Other Occurances..but for the incorrect file path this.crFile = content; this.setDisplayName(new File(this.crFile.getFilePath()).getName()); diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java index 5555c4ce03..ce33631c16 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java @@ -268,7 +268,7 @@ public final class CommonFilesPanel extends javax.swing.JPanel { } private boolean caseHasMultipleSources() { - return CommonFilesPanel.this.intraCasePanel.getDataSourceMap().size() >= 3; + return CommonFilesPanel.this.intraCasePanel.getDataSourceMap().size() > 2; } @Override diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/FileInstanceNode.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/FileInstanceNode.java index b57b6b0b07..6138c0f78f 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/FileInstanceNode.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/FileInstanceNode.java @@ -21,6 +21,7 @@ package org.sleuthkit.autopsy.commonfilesearch; import org.apache.commons.lang3.StringUtils; import org.openide.nodes.Sheet; import org.openide.util.NbBundle; +import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.datamodel.DisplayableItemNodeVisitor; import org.sleuthkit.autopsy.datamodel.FileNode; import org.sleuthkit.autopsy.datamodel.NodeProperty; @@ -80,9 +81,8 @@ public class FileInstanceNode extends FileNode { sheetSet.put(new NodeProperty<>(Bundle.CommonFilesSearchResultsViewerTable_hashsetHitsColLbl(), Bundle.CommonFilesSearchResultsViewerTable_hashsetHitsColLbl(), NO_DESCR, getHashSetHitsForFile(this.getContent()))); sheetSet.put(new NodeProperty<>(Bundle.CommonFilesSearchResultsViewerTable_dataSourceColLbl(), Bundle.CommonFilesSearchResultsViewerTable_dataSourceColLbl(), NO_DESCR, this.getDataSource())); sheetSet.put(new NodeProperty<>(Bundle.CommonFilesSearchResultsViewerTable_mimeTypeColLbl(), Bundle.CommonFilesSearchResultsViewerTable_mimeTypeColLbl(), NO_DESCR, StringUtils.defaultString(this.getContent().getMIMEType()))); - sheetSet.put(new NodeProperty<>(Bundle.CommonFilesSearchResultsViewerTable_caseColLbl1(), Bundle.CommonFilesSearchResultsViewerTable_caseColLbl1(), NO_DESCR, this.getContent().getSleuthkitCase().getDatabaseName())); - this.addTagProperty(sheetSet); + sheetSet.put(new NodeProperty<>(Bundle.CommonFilesSearchResultsViewerTable_caseColLbl1(), Bundle.CommonFilesSearchResultsViewerTable_caseColLbl1(), NO_DESCR, Case.getCurrentCase().getDisplayName())); return sheet; } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCasePanel.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCasePanel.java index dd0cca8ae2..13e70b1e97 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCasePanel.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCasePanel.java @@ -152,12 +152,10 @@ public class IntraCasePanel extends javax.swing.JPanel { private void allDataSourcesRadioButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_allDataSourcesRadioButtonActionPerformed selectDataSourceComboBox.setEnabled(!allDataSourcesRadioButton.isSelected()); singleDataSource = false; - //this.parent.handleIntraCaseSearchCriteriaChanged(); }//GEN-LAST:event_allDataSourcesRadioButtonActionPerformed private void withinDataSourceRadioButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_withinDataSourceRadioButtonActionPerformed withinDataSourceSelected(withinDataSourceRadioButton.isSelected()); - //this.parent.handleIntraCaseSearchCriteriaChanged(); }//GEN-LAST:event_withinDataSourceRadioButtonActionPerformed private void selectDataSourceComboBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_selectDataSourceComboBoxActionPerformed @@ -190,13 +188,11 @@ public class IntraCasePanel extends javax.swing.JPanel { } void rigForMultipleDataSources(boolean multipleDataSources) { - this.allDataSourcesRadioButton.setEnabled(multipleDataSources); - this.allDataSourcesRadioButton.setSelected(multipleDataSources); + this.withinDataSourceRadioButton.setEnabled(multipleDataSources); + this.allDataSourcesRadioButton.setSelected(!multipleDataSources); + this.withinDataSourceRadioButton.setSelected(multipleDataSources); + this.withinDataSourceSelected(multipleDataSources); - if(!multipleDataSources){ - this.withinDataSourceRadioButton.setSelected(true); - this.withinDataSourceSelected(true); - } } void setDataSourceMap(Map dataSourceMap) { diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/FileTypeExtensions.java b/Core/src/org/sleuthkit/autopsy/datamodel/FileTypeExtensions.java index eafa8377b2..f09238e507 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/FileTypeExtensions.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/FileTypeExtensions.java @@ -27,7 +27,7 @@ import java.util.List; */ public class FileTypeExtensions { - private final static List IMAGE_EXTENSIONS = Arrays.asList(".jpg", ".jpeg", ".png", ".psd", ".nef", ".tiff", ".bmp", ".tec"); //NON-NLS + private final static List IMAGE_EXTENSIONS = Arrays.asList(".jpg", ".jpeg", ".png", ".psd", ".nef", ".tiff", ".bmp", ".tec", ".tif"); //NON-NLS private final static List VIDEO_EXTENSIONS = Arrays.asList(".aaf", ".3gp", ".asf", ".avi", ".m1v", ".m2v", //NON-NLS ".m4v", ".mp4", ".mov", ".mpeg", ".mpg", ".mpe", ".mp4", ".rm", ".wmv", ".mpv", ".flv", ".swf"); //NON-NLS private final static List AUDIO_EXTENSIONS = Arrays.asList(".aiff", ".aif", ".flac", ".wav", ".m4a", ".ape", //NON-NLS From 1dc55ba7e8b65a3c86cbdcc6ac5e20dcbe9117f0 Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dgrove" Date: Fri, 6 Jul 2018 10:59:38 -0400 Subject: [PATCH 119/287] Implemented message node to handle 'No results found' message. --- .../DataContentViewerOtherCases.form | 4 +- .../DataContentViewerOtherCases.java | 33 +-- ...DataContentViewerOtherCasesTableModel.java | 46 ++-- .../OtherOccurrenceNodeData.java | 213 +--------------- .../OtherOccurrenceNodeInstanceData.java | 233 ++++++++++++++++++ .../OtherOccurrenceNodeMessageData.java | 34 +++ 6 files changed, 319 insertions(+), 244 deletions(-) mode change 100644 => 100755 Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/OtherOccurrenceNodeData.java create mode 100644 Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/OtherOccurrenceNodeInstanceData.java create mode 100755 Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/OtherOccurrenceNodeMessageData.java diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/DataContentViewerOtherCases.form b/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/DataContentViewerOtherCases.form index 60667bae46..7b9e47c236 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/DataContentViewerOtherCases.form +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/DataContentViewerOtherCases.form @@ -80,7 +80,7 @@ - + @@ -106,7 +106,7 @@ - + diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/DataContentViewerOtherCases.java b/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/DataContentViewerOtherCases.java index 8ead475d95..c3558a106b 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/DataContentViewerOtherCases.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/DataContentViewerOtherCases.java @@ -126,7 +126,7 @@ public class DataContentViewerOtherCases extends JPanel implements DataContentVi showCommonalityDetails(); } else if (jmi.equals(addCommentMenuItem)) { try { - OtherOccurrenceNodeData selectedNode = (OtherOccurrenceNodeData) tableModel.getRow(otherCasesTable.getSelectedRow()); + OtherOccurrenceNodeInstanceData selectedNode = (OtherOccurrenceNodeInstanceData) tableModel.getRow(otherCasesTable.getSelectedRow()); AddEditCentralRepoCommentAction action = AddEditCentralRepoCommentAction.createAddEditCommentAction(selectedNode.createCorrelationAttribute()); String currentComment = action.addEditCentralRepoComment(); selectedNode.updateComment(currentComment); @@ -205,7 +205,7 @@ public class DataContentViewerOtherCases extends JPanel implements DataContentVi if (-1 != selectedRowViewIdx) { EamDb dbManager = EamDb.getInstance(); int selectedRowModelIdx = otherCasesTable.convertRowIndexToModel(selectedRowViewIdx); - OtherOccurrenceNodeData nodeData = (OtherOccurrenceNodeData) tableModel.getRow(selectedRowModelIdx); + OtherOccurrenceNodeInstanceData nodeData = (OtherOccurrenceNodeInstanceData) tableModel.getRow(selectedRowModelIdx); CorrelationCase eamCasePartial = nodeData.getCorrelationAttributeInstance().getCorrelationCase(); if (eamCasePartial == null) { JOptionPane.showConfirmDialog(showCaseDetailsMenuItem, @@ -504,13 +504,13 @@ public class DataContentViewerOtherCases extends JPanel implements DataContentVi * * @return A collection of correlated artifact instances */ - private Map getCorrelatedInstances(CorrelationAttribute corAttr, String dataSourceName, String deviceId) { + private Map getCorrelatedInstances(CorrelationAttribute corAttr, String dataSourceName, String deviceId) { // @@@ Check exception try { final Case openCase = Case.getCurrentCase(); String caseUUID = openCase.getName(); - HashMap nodeDataMap = new HashMap<>(); + HashMap nodeDataMap = new HashMap<>(); if (EamDb.isEnabled()) { List instances = EamDb.getInstance().getArtifactInstancesByTypeValue(corAttr.getCorrelationType(), corAttr.getCorrelationValue()); @@ -528,7 +528,7 @@ public class DataContentViewerOtherCases extends JPanel implements DataContentVi || !artifactInstance.getCorrelationDataSource().getDeviceID().equals(deviceId) || !artifactInstance.getFilePath().equalsIgnoreCase(file.getParentPath() + file.getName())) { - OtherOccurrenceNodeData newNode = new OtherOccurrenceNodeData(artifactInstance, corAttr.getCorrelationType(), corAttr.getCorrelationValue()); + OtherOccurrenceNodeInstanceData newNode = new OtherOccurrenceNodeInstanceData(artifactInstance, corAttr.getCorrelationType(), corAttr.getCorrelationValue()); UniquePathKey uniquePathKey = new UniquePathKey(newNode); nodeDataMap.put(uniquePathKey, newNode); } @@ -592,9 +592,9 @@ public class DataContentViewerOtherCases extends JPanel implements DataContentVi * @throws TskCoreException * @throws EamDbException */ - private void addOrUpdateNodeData(final Case autopsyCase, Map nodeDataMap, AbstractFile newFile) throws TskCoreException, EamDbException { + private void addOrUpdateNodeData(final Case autopsyCase, Map nodeDataMap, AbstractFile newFile) throws TskCoreException, EamDbException { - OtherOccurrenceNodeData newNode = new OtherOccurrenceNodeData(newFile, autopsyCase); + OtherOccurrenceNodeInstanceData newNode = new OtherOccurrenceNodeInstanceData(newFile, autopsyCase); // If the caseDB object has a notable tag associated with it, update // the known status to BAD @@ -617,7 +617,7 @@ public class DataContentViewerOtherCases extends JPanel implements DataContentVi // Otherwise this is a new node so add the new node to the map. if (nodeDataMap.containsKey(uniquePathKey)) { if (newNode.getKnown() == TskData.FileKnown.BAD) { - OtherOccurrenceNodeData prevInstance = nodeDataMap.get(uniquePathKey); + OtherOccurrenceNodeInstanceData prevInstance = nodeDataMap.get(uniquePathKey); prevInstance.updateKnown(newNode.getKnown()); } } else { @@ -663,8 +663,10 @@ public class DataContentViewerOtherCases extends JPanel implements DataContentVi * * @param node The node being viewed. */ - @Messages({"DataContentViewerOtherCases.table.isempty=There are no associated artifacts or files from other occurrences to display.", - "DataContentViewerOtherCases.table.noArtifacts=Correlation cannot be performed on the selected file."}) + @Messages({ + "DataContentViewerOtherCases.table.noResultsFound=No results found.", + "DataContentViewerOtherCases.table.noArtifacts=Correlation cannot be performed on the selected file." + }) private void populateTable(Node node) { String dataSourceName = ""; String deviceId = ""; @@ -682,7 +684,7 @@ public class DataContentViewerOtherCases extends JPanel implements DataContentVi // get the attributes we can correlate on correlationAttributes.addAll(getCorrelationAttributesFromNode(node)); for (CorrelationAttribute corAttr : correlationAttributes) { - Map correlatedNodeDataMap = new HashMap<>(0); + Map correlatedNodeDataMap = new HashMap<>(0); // get correlation and reference set instances from DB correlatedNodeDataMap.putAll(getCorrelatedInstances(corAttr, dataSourceName, deviceId)); @@ -697,7 +699,7 @@ public class DataContentViewerOtherCases extends JPanel implements DataContentVi // @@@ BC: We should have a more descriptive message than this. Mention that the file didn't have a MD5, etc. displayMessageOnTableStatusPanel(Bundle.DataContentViewerOtherCases_table_noArtifacts()); } else if (0 == tableModel.getRowCount()) { - displayMessageOnTableStatusPanel(Bundle.DataContentViewerOtherCases_table_isempty()); + tableModel.addNodeData(new OtherOccurrenceNodeMessageData(Bundle.DataContentViewerOtherCases_table_noResultsFound())); } else { clearMessageOnTableStatusPanel(); setColumnWidths(); @@ -877,8 +879,9 @@ public class DataContentViewerOtherCases extends JPanel implements DataContentVi if (EamDbUtil.useCentralRepo() && otherCasesTable.getSelectedRowCount() == 1) { int rowIndex = otherCasesTable.getSelectedRow(); OtherOccurrenceNodeData selectedNode = (OtherOccurrenceNodeData) tableModel.getRow(rowIndex); - if (selectedNode.isCentralRepoNode()) { - enableCentralRepoActions = true; + if (selectedNode instanceof OtherOccurrenceNodeInstanceData) { + OtherOccurrenceNodeInstanceData instanceData = (OtherOccurrenceNodeInstanceData) selectedNode; + enableCentralRepoActions = instanceData.isCentralRepoNode(); } } @@ -915,7 +918,7 @@ public class DataContentViewerOtherCases extends JPanel implements DataContentVi private final String filePath; private final String type; - UniquePathKey(OtherOccurrenceNodeData nodeData) { + UniquePathKey(OtherOccurrenceNodeInstanceData nodeData) { super(); dataSourceID = nodeData.getDeviceID(); if (nodeData.getFilePath() != null) { diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/DataContentViewerOtherCasesTableModel.java b/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/DataContentViewerOtherCasesTableModel.java index 5febf88dc3..0d7018885c 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/DataContentViewerOtherCasesTableModel.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/DataContentViewerOtherCasesTableModel.java @@ -1,7 +1,7 @@ /* * Central Repository * - * Copyright 2015-2017 Basis Technology Corp. + * Copyright 2015-2018 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -22,8 +22,6 @@ import java.util.ArrayList; import java.util.List; import javax.swing.table.AbstractTableModel; import org.openide.util.NbBundle.Messages; -import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttribute; -import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance; /** * Model for cells in data content viewer table @@ -34,7 +32,7 @@ public class DataContentViewerOtherCasesTableModel extends AbstractTableModel { "DataContentViewerOtherCasesTableModel.device=Device", "DataContentViewerOtherCasesTableModel.dataSource=Data Source", "DataContentViewerOtherCasesTableModel.path=Path", - "DataContentViewerOtherCasesTableModel.type=Correlation Type", + "DataContentViewerOtherCasesTableModel.property=Correlation Property", "DataContentViewerOtherCasesTableModel.value=Correlation Value", "DataContentViewerOtherCasesTableModel.known=Known", "DataContentViewerOtherCasesTableModel.comment=Comment", @@ -44,7 +42,7 @@ public class DataContentViewerOtherCasesTableModel extends AbstractTableModel { // If order is changed, update the CellRenderer to ensure correct row coloring. CASE_NAME(Bundle.DataContentViewerOtherCasesTableModel_case(), 100), DATA_SOURCE(Bundle.DataContentViewerOtherCasesTableModel_dataSource(), 100), - TYPE(Bundle.DataContentViewerOtherCasesTableModel_type(), 100), + PROPERTY(Bundle.DataContentViewerOtherCasesTableModel_property(), 125), VALUE(Bundle.DataContentViewerOtherCasesTableModel_value(), 200), KNOWN(Bundle.DataContentViewerOtherCasesTableModel_known(), 50), FILE_PATH(Bundle.DataContentViewerOtherCasesTableModel_path(), 450), @@ -126,38 +124,49 @@ public class DataContentViewerOtherCasesTableModel extends AbstractTableModel { */ private Object mapValueById(int rowIdx, TableColumns colId) { OtherOccurrenceNodeData nodeData = nodeDataList.get(rowIdx); + + if (nodeData instanceof OtherOccurrenceNodeMessageData) { + if (colId == TableColumns.CASE_NAME) { + OtherOccurrenceNodeMessageData messageData = (OtherOccurrenceNodeMessageData) nodeData; + return messageData.getDisplayMessage(); + } else { + return ""; + } + } + + OtherOccurrenceNodeInstanceData instanceData = (OtherOccurrenceNodeInstanceData) nodeData; String value = Bundle.DataContentViewerOtherCasesTableModel_noData(); switch (colId) { case CASE_NAME: - if (null != nodeData.getCaseName()) { - value = nodeData.getCaseName(); + if (null != instanceData.getCaseName()) { + value = instanceData.getCaseName(); } break; case DEVICE: - if (null != nodeData.getDeviceID()) { - value = nodeData.getDeviceID(); + if (null != instanceData.getDeviceID()) { + value = instanceData.getDeviceID(); } break; case DATA_SOURCE: - if (null != nodeData.getDataSourceName()) { - value = nodeData.getDataSourceName(); + if (null != instanceData.getDataSourceName()) { + value = instanceData.getDataSourceName(); } break; case FILE_PATH: - value = nodeData.getFilePath(); + value = instanceData.getFilePath(); break; - case TYPE: - value = nodeData.getType(); + case PROPERTY: + value = instanceData.getType(); break; case VALUE: - value = nodeData.getValue(); + value = instanceData.getValue(); break; case KNOWN: - value = nodeData.getKnown().getName(); + value = instanceData.getKnown().getName(); break; case COMMENT: - value = nodeData.getComment(); + value = instanceData.getComment(); break; } return value; @@ -178,6 +187,9 @@ public class DataContentViewerOtherCasesTableModel extends AbstractTableModel { fireTableDataChanged(); } + /** + * Clear the node data table. + */ void clearTable() { nodeDataList.clear(); fireTableDataChanged(); diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/OtherOccurrenceNodeData.java b/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/OtherOccurrenceNodeData.java old mode 100644 new mode 100755 index 958068fb14..c10f078313 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/OtherOccurrenceNodeData.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/OtherOccurrenceNodeData.java @@ -1,5 +1,5 @@ /* - * Central Repository + * Autopsy Forensic Browser * * Copyright 2018 Basis Technology Corp. * Contact: carrier sleuthkit org @@ -18,216 +18,9 @@ */ package org.sleuthkit.autopsy.centralrepository.contentviewer; -import org.sleuthkit.autopsy.casemodule.Case; -import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttribute; -import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance; -import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException; -import org.sleuthkit.datamodel.AbstractFile; -import org.sleuthkit.datamodel.DataSource; -import org.sleuthkit.datamodel.TskCoreException; -import org.sleuthkit.datamodel.TskData; -import org.sleuthkit.datamodel.TskDataException; - /** - * Class for populating the Other Occurrences tab + * Marker interface for Other Occurrences nodes. */ -class OtherOccurrenceNodeData { +interface OtherOccurrenceNodeData { - // For now hard code the string for the central repo files type, since - // getting it dynamically can fail. - private static final String FILE_TYPE_STR = "Files"; - - private final String caseName; - private String deviceID; - private String dataSourceName; - private final String filePath; - private final String typeStr; - private final CorrelationAttribute.Type type; - private final String value; - private TskData.FileKnown known; - private String comment; - - private AbstractFile originalAbstractFile = null; - private CorrelationAttributeInstance originalCorrelationInstance = null; - - /** - * Create a node from a central repo instance. - * @param instance The central repo instance - * @param type The type of the instance - * @param value The value of the instance - */ - OtherOccurrenceNodeData(CorrelationAttributeInstance instance, CorrelationAttribute.Type type, String value) { - caseName = instance.getCorrelationCase().getDisplayName(); - deviceID = instance.getCorrelationDataSource().getDeviceID(); - dataSourceName = instance.getCorrelationDataSource().getName(); - filePath = instance.getFilePath(); - this.typeStr = type.getDisplayName(); - this.type = type; - this.value = value; - known = instance.getKnownStatus(); - comment = instance.getComment(); - - originalCorrelationInstance = instance; - } - - /** - * Create a node from an abstract file. - * @param newFile The abstract file - * @param autopsyCase The current case - * @throws EamDbException - */ - OtherOccurrenceNodeData(AbstractFile newFile, Case autopsyCase) throws EamDbException { - caseName = autopsyCase.getDisplayName(); - try { - DataSource dataSource = autopsyCase.getSleuthkitCase().getDataSource(newFile.getDataSource().getId()); - deviceID = dataSource.getDeviceId(); - dataSourceName = dataSource.getName(); - } catch (TskDataException | TskCoreException ex) { - throw new EamDbException("Error loading data source for abstract file ID " + newFile.getId(), ex); - } - - filePath = newFile.getParentPath() + newFile.getName(); - typeStr = FILE_TYPE_STR; - this.type = null; - value = newFile.getMd5Hash(); - known = newFile.getKnown(); - comment = ""; - - originalAbstractFile = newFile; - } - - /** - * Check if this node is a "file" type - * @return true if it is a file type - */ - boolean isFileType() { - return FILE_TYPE_STR.equals(typeStr); - } - - /** - * Update the known status for this node - * @param newKnownStatus The new known status - */ - void updateKnown(TskData.FileKnown newKnownStatus) { - known = newKnownStatus; - } - - /** - * Update the comment for this node - * @param newComment The new comment - */ - void updateComment(String newComment) { - comment = newComment; - } - - /** - * Check if this is a central repo node. - * @return true if this node was created from a central repo instance, false otherwise - */ - boolean isCentralRepoNode() { - return (originalCorrelationInstance != null); - } - - /** - * Uses the saved instance plus type and value to make a new CorrelationAttribute. - * Should only be called if isCentralRepoNode() is true. - * @return the newly created CorrelationAttribute - */ - CorrelationAttribute createCorrelationAttribute() throws EamDbException { - if (! isCentralRepoNode() ) { - throw new EamDbException("Can not create CorrelationAttribute for non central repo node"); - } - CorrelationAttribute attr = new CorrelationAttribute(type, value); - attr.addInstance(originalCorrelationInstance); - return attr; - } - - /** - * Get the case name - * @return the case name - */ - String getCaseName() { - return caseName; - } - - /** - * Get the device ID - * @return the device ID - */ - String getDeviceID() { - return deviceID; - } - - /** - * Get the data source name - * @return the data source name - */ - String getDataSourceName() { - return dataSourceName; - } - - /** - * Get the file path - * @return the file path - */ - String getFilePath() { - return filePath; - } - - /** - * Get the type (as a string) - * @return the type - */ - String getType() { - return typeStr; - } - - /** - * Get the value (MD5 hash for files) - * @return the value - */ - String getValue() { - return value; - } - - /** - * Get the known status - * @return the known status - */ - TskData.FileKnown getKnown() { - return known; - } - - /** - * Get the comment - * @return the comment - */ - String getComment() { - return comment; - } - - /** - * Get the backing abstract file. - * Should only be called if isCentralRepoNode() is false - * @return the original abstract file - */ - AbstractFile getAbstractFile() throws EamDbException { - if (originalCorrelationInstance == null) { - throw new EamDbException("AbstractFile is null"); - } - return originalAbstractFile; - } - - /** - * Get the backing CorrelationAttributeInstance. - * Should only be called if isCentralRepoNode() is true - * @return the original CorrelationAttributeInstance - * @throws EamDbException - */ - CorrelationAttributeInstance getCorrelationAttributeInstance() throws EamDbException { - if (originalCorrelationInstance == null) { - throw new EamDbException("CorrelationAttributeInstance is null"); - } - return originalCorrelationInstance; - } } diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/OtherOccurrenceNodeInstanceData.java b/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/OtherOccurrenceNodeInstanceData.java new file mode 100644 index 0000000000..7eb907aba8 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/OtherOccurrenceNodeInstanceData.java @@ -0,0 +1,233 @@ +/* + * Central Repository + * + * Copyright 2018 Basis Technology Corp. + * Contact: carrier sleuthkit 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.centralrepository.contentviewer; + +import org.sleuthkit.autopsy.casemodule.Case; +import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttribute; +import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance; +import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException; +import org.sleuthkit.datamodel.AbstractFile; +import org.sleuthkit.datamodel.DataSource; +import org.sleuthkit.datamodel.TskCoreException; +import org.sleuthkit.datamodel.TskData; +import org.sleuthkit.datamodel.TskDataException; + +/** + * Class for populating the Other Occurrences tab + */ +class OtherOccurrenceNodeInstanceData implements OtherOccurrenceNodeData { + + // For now hard code the string for the central repo files type, since + // getting it dynamically can fail. + private static final String FILE_TYPE_STR = "Files"; + + private final String caseName; + private String deviceID; + private String dataSourceName; + private final String filePath; + private final String typeStr; + private final CorrelationAttribute.Type type; + private final String value; + private TskData.FileKnown known; + private String comment; + + private AbstractFile originalAbstractFile = null; + private CorrelationAttributeInstance originalCorrelationInstance = null; + + /** + * Create a node from a central repo instance. + * @param instance The central repo instance + * @param type The type of the instance + * @param value The value of the instance + */ + OtherOccurrenceNodeInstanceData(CorrelationAttributeInstance instance, CorrelationAttribute.Type type, String value) { + caseName = instance.getCorrelationCase().getDisplayName(); + deviceID = instance.getCorrelationDataSource().getDeviceID(); + dataSourceName = instance.getCorrelationDataSource().getName(); + filePath = instance.getFilePath(); + this.typeStr = type.getDisplayName(); + this.type = type; + this.value = value; + known = instance.getKnownStatus(); + comment = instance.getComment(); + + originalCorrelationInstance = instance; + } + + /** + * Create a node from an abstract file. + * @param newFile The abstract file + * @param autopsyCase The current case + * @throws EamDbException + */ + OtherOccurrenceNodeInstanceData(AbstractFile newFile, Case autopsyCase) throws EamDbException { + caseName = autopsyCase.getDisplayName(); + try { + DataSource dataSource = autopsyCase.getSleuthkitCase().getDataSource(newFile.getDataSource().getId()); + deviceID = dataSource.getDeviceId(); + dataSourceName = dataSource.getName(); + } catch (TskDataException | TskCoreException ex) { + throw new EamDbException("Error loading data source for abstract file ID " + newFile.getId(), ex); + } + + filePath = newFile.getParentPath() + newFile.getName(); + typeStr = FILE_TYPE_STR; + this.type = null; + value = newFile.getMd5Hash(); + known = newFile.getKnown(); + comment = ""; + + originalAbstractFile = newFile; + } + + /** + * Check if this node is a "file" type + * @return true if it is a file type + */ + boolean isFileType() { + return FILE_TYPE_STR.equals(typeStr); + } + + /** + * Update the known status for this node + * @param newKnownStatus The new known status + */ + void updateKnown(TskData.FileKnown newKnownStatus) { + known = newKnownStatus; + } + + /** + * Update the comment for this node + * @param newComment The new comment + */ + void updateComment(String newComment) { + comment = newComment; + } + + /** + * Check if this is a central repo node. + * @return true if this node was created from a central repo instance, false otherwise + */ + boolean isCentralRepoNode() { + return (originalCorrelationInstance != null); + } + + /** + * Uses the saved instance plus type and value to make a new CorrelationAttribute. + * Should only be called if isCentralRepoNode() is true. + * @return the newly created CorrelationAttribute + */ + CorrelationAttribute createCorrelationAttribute() throws EamDbException { + if (! isCentralRepoNode() ) { + throw new EamDbException("Can not create CorrelationAttribute for non central repo node"); + } + CorrelationAttribute attr = new CorrelationAttribute(type, value); + attr.addInstance(originalCorrelationInstance); + return attr; + } + + /** + * Get the case name + * @return the case name + */ + String getCaseName() { + return caseName; + } + + /** + * Get the device ID + * @return the device ID + */ + String getDeviceID() { + return deviceID; + } + + /** + * Get the data source name + * @return the data source name + */ + String getDataSourceName() { + return dataSourceName; + } + + /** + * Get the file path + * @return the file path + */ + String getFilePath() { + return filePath; + } + + /** + * Get the type (as a string) + * @return the type + */ + String getType() { + return typeStr; + } + + /** + * Get the value (MD5 hash for files) + * @return the value + */ + String getValue() { + return value; + } + + /** + * Get the known status + * @return the known status + */ + TskData.FileKnown getKnown() { + return known; + } + + /** + * Get the comment + * @return the comment + */ + String getComment() { + return comment; + } + + /** + * Get the backing abstract file. + * Should only be called if isCentralRepoNode() is false + * @return the original abstract file + */ + AbstractFile getAbstractFile() throws EamDbException { + if (originalCorrelationInstance == null) { + throw new EamDbException("AbstractFile is null"); + } + return originalAbstractFile; + } + + /** + * Get the backing CorrelationAttributeInstance. + * Should only be called if isCentralRepoNode() is true + * @return the original CorrelationAttributeInstance + * @throws EamDbException + */ + CorrelationAttributeInstance getCorrelationAttributeInstance() throws EamDbException { + if (originalCorrelationInstance == null) { + throw new EamDbException("CorrelationAttributeInstance is null"); + } + return originalCorrelationInstance; + } +} diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/OtherOccurrenceNodeMessageData.java b/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/OtherOccurrenceNodeMessageData.java new file mode 100755 index 0000000000..99e530349a --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/OtherOccurrenceNodeMessageData.java @@ -0,0 +1,34 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2018 Basis Technology Corp. + * Contact: carrier sleuthkit 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.centralrepository.contentviewer; + +/** + * Class for populating the Other Occurrences tab with a single message. + */ +final class OtherOccurrenceNodeMessageData implements OtherOccurrenceNodeData { + private final String displayMessage; + + OtherOccurrenceNodeMessageData(String displayMessage) { + this.displayMessage = displayMessage; + } + + String getDisplayMessage() { + return displayMessage; + } +} From 5aec70fbaf03c09630ddba81185a59a5fa13c1fb Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dgrove" Date: Fri, 6 Jul 2018 16:43:56 -0400 Subject: [PATCH 120/287] Partial handling of 'noArtifacts' message. --- .../DataContentViewerOtherCases.java | 25 +++++++------------ ...DataContentViewerOtherCasesTableModel.java | 8 +++--- 2 files changed, 13 insertions(+), 20 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/DataContentViewerOtherCases.java b/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/DataContentViewerOtherCases.java index c3558a106b..ebc5b7c375 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/DataContentViewerOtherCases.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/DataContentViewerOtherCases.java @@ -38,7 +38,6 @@ import java.util.Map; import java.util.Objects; import java.util.logging.Level; import org.sleuthkit.autopsy.coreutils.Logger; -import java.util.stream.Collectors; import javax.swing.JFileChooser; import javax.swing.JMenuItem; import javax.swing.JOptionPane; @@ -49,6 +48,7 @@ import javax.swing.JPanel; import javax.swing.filechooser.FileNameExtensionFilter; import javax.swing.table.TableCellRenderer; import javax.swing.table.TableColumn; +import javax.swing.table.TableColumnModel; import org.joda.time.DateTimeZone; import org.joda.time.LocalDateTime; import org.openide.nodes.Node; @@ -147,7 +147,6 @@ public class DataContentViewerOtherCases extends JPanel implements DataContentVi // Set background of every nth row as light grey. TableCellRenderer renderer = new DataContentViewerOtherCasesTableCellRenderer(); otherCasesTable.setDefaultRenderer(Object.class, renderer); - tableStatusPanelLabel.setVisible(false); } @@ -664,8 +663,8 @@ public class DataContentViewerOtherCases extends JPanel implements DataContentVi * @param node The node being viewed. */ @Messages({ - "DataContentViewerOtherCases.table.noResultsFound=No results found.", - "DataContentViewerOtherCases.table.noArtifacts=Correlation cannot be performed on the selected file." + "DataContentViewerOtherCases.table.noArtifacts=Item has no attributes with which to search.", + "DataContentViewerOtherCases.table.noResultsFound=No results found." }) private void populateTable(Node node) { String dataSourceName = ""; @@ -696,17 +695,20 @@ public class DataContentViewerOtherCases extends JPanel implements DataContentVi } if (correlationAttributes.isEmpty()) { - // @@@ BC: We should have a more descriptive message than this. Mention that the file didn't have a MD5, etc. - displayMessageOnTableStatusPanel(Bundle.DataContentViewerOtherCases_table_noArtifacts()); + tableModel.addNodeData(new OtherOccurrenceNodeMessageData(Bundle.DataContentViewerOtherCases_table_noArtifacts())); + //DLG: Removing columns causes problems. Look into resizing columns. } else if (0 == tableModel.getRowCount()) { tableModel.addNodeData(new OtherOccurrenceNodeMessageData(Bundle.DataContentViewerOtherCases_table_noResultsFound())); + //DLG: Removing columns causes problems. Look into resizing columns. } else { - clearMessageOnTableStatusPanel(); setColumnWidths(); } setEarliestCaseDate(); } + /** + * Adjust column widths to their preferred values. + */ private void setColumnWidths() { for (int idx = 0; idx < tableModel.getColumnCount(); idx++) { TableColumn column = otherCasesTable.getColumnModel().getColumn(idx); @@ -717,15 +719,6 @@ public class DataContentViewerOtherCases extends JPanel implements DataContentVi } } - private void displayMessageOnTableStatusPanel(String message) { - tableStatusPanelLabel.setText(message); - tableStatusPanelLabel.setVisible(true); - } - - private void clearMessageOnTableStatusPanel() { - tableStatusPanelLabel.setVisible(false); - } - /** * This method is called from within the constructor to initialize the form. * WARNING: Do NOT modify this code. The content of this method is always diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/DataContentViewerOtherCasesTableModel.java b/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/DataContentViewerOtherCasesTableModel.java index 0d7018885c..de528e2d42 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/DataContentViewerOtherCasesTableModel.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/DataContentViewerOtherCasesTableModel.java @@ -32,8 +32,8 @@ public class DataContentViewerOtherCasesTableModel extends AbstractTableModel { "DataContentViewerOtherCasesTableModel.device=Device", "DataContentViewerOtherCasesTableModel.dataSource=Data Source", "DataContentViewerOtherCasesTableModel.path=Path", - "DataContentViewerOtherCasesTableModel.property=Correlation Property", - "DataContentViewerOtherCasesTableModel.value=Correlation Value", + "DataContentViewerOtherCasesTableModel.attribute=Matched Attribute", + "DataContentViewerOtherCasesTableModel.value=Attribute Value", "DataContentViewerOtherCasesTableModel.known=Known", "DataContentViewerOtherCasesTableModel.comment=Comment", "DataContentViewerOtherCasesTableModel.noData=No Data.",}) @@ -42,7 +42,7 @@ public class DataContentViewerOtherCasesTableModel extends AbstractTableModel { // If order is changed, update the CellRenderer to ensure correct row coloring. CASE_NAME(Bundle.DataContentViewerOtherCasesTableModel_case(), 100), DATA_SOURCE(Bundle.DataContentViewerOtherCasesTableModel_dataSource(), 100), - PROPERTY(Bundle.DataContentViewerOtherCasesTableModel_property(), 125), + ATTRIBUTE(Bundle.DataContentViewerOtherCasesTableModel_attribute(), 125), VALUE(Bundle.DataContentViewerOtherCasesTableModel_value(), 200), KNOWN(Bundle.DataContentViewerOtherCasesTableModel_known(), 50), FILE_PATH(Bundle.DataContentViewerOtherCasesTableModel_path(), 450), @@ -156,7 +156,7 @@ public class DataContentViewerOtherCasesTableModel extends AbstractTableModel { case FILE_PATH: value = instanceData.getFilePath(); break; - case PROPERTY: + case ATTRIBUTE: value = instanceData.getType(); break; case VALUE: From 174608ed66fd125309e66cbed4d84de600018176 Mon Sep 17 00:00:00 2001 From: Andrew Ziehl Date: Mon, 9 Jul 2018 21:15:18 -0700 Subject: [PATCH 121/287] Cleaned up and builds with new query logic. --- .../datamodel/AbstractSqlEamDb.java | 148 +----------------- .../datamodel/CentralRepositoryFile.java | 45 ------ .../centralrepository/datamodel/EamDb.java | 22 --- .../datamodel/SqliteEamDb.java | 39 ----- ...ralRepositoryCaseFileInstanceMetadata.java | 40 +++-- .../CentralRepositoryFileInstanceNode.java | 10 +- .../EamDbAttributeInstancesAlgorithm.java | 14 +- .../EamDbCommonFilesAlgorithm.java | 129 ++++++--------- .../FileInstanceNodeGenerator.java | 64 +++----- .../autopsy/commonfilesearch/Md5Metadata.java | 1 - .../autopsy/commonfilesearch/Md5Node.java | 17 +- .../SleuthkitCaseFileInstanceMetadata.java | 17 +- 12 files changed, 125 insertions(+), 421 deletions(-) delete mode 100644 Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepositoryFile.java diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java index deb4770ef0..73a24c0d6d 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java @@ -659,126 +659,6 @@ abstract class AbstractSqlEamDb implements EamDb { return artifactInstances; } - - /** - * Retrieves eamArtifact instances from the database that match the given - * list of MD5 values; - * - * @param values MD5s to use as search keys - * @return matching files in the form of CentralRepositoryFile - * @throws EamDbException - */ - public List getArtifactInstancesByCaseValues(Collection values) throws EamDbException { - //passing null and -1 here has the effect of making this case agnostic: - // rather than looking for instances that must appear in a certain case - // we accept instances occur in any case - return getArtifactInstancesByCaseValues(null, values, -1); - } - - /** - * Retrieves eamArtifact instances from the database that match the given - * list of MD5 values and optionally filters by given case. - * - * Warning: Does not benefit from PreparedStatement caching to since values - * will be variable in length - * - * @param correlationCase Case id to search on, if null, searches all cases - * @param values List of ArtifactInstance MD5 values to find matches of. - * - * @return List of artifact instances for a given list of MD5 values - * - * @throws EamDbException if EamDb is inaccessible. - */ - @Override - public List getArtifactInstancesByCaseValues(CorrelationCase correlationCase, Collection values, int currentCaseId) throws EamDbException { - CorrelationAttribute.Type aType = CorrelationAttribute.getDefaultCorrelationTypes().get(0); // Files type - if (aType == null) { - throw new EamDbException("Correlation Type is null"); - } - boolean singleCase = false; - if (correlationCase != null) { - singleCase = true; - } - if (values == null) { - values = new ArrayList<>(); - } - - List artifactInstances = new ArrayList<>(); - - if (values != null && !values.isEmpty()) { - - //we can skip all this if there is nothing to search for - String tableName = EamDbUtil.correlationTypeToInstanceTableName(aType); - StringBuilder sql = new StringBuilder(10); - sql.append("SELECT cases.case_name, cases.case_uid, data_sources.name, device_id, file_path, known_status, comment, data_sources.case_id, value FROM "); - sql.append(tableName); - sql.append(" LEFT JOIN cases ON "); - sql.append(tableName); - sql.append(".case_id=cases.id"); - sql.append(" LEFT JOIN data_sources ON "); - sql.append(tableName); - sql.append(".data_source_id=data_sources.id"); - sql.append(" WHERE value IN (SELECT value FROM "); - sql.append(tableName); - sql.append(" WHERE value IN ("); - - // Note: PreparedStatement has a limit on ? variable replacement so instead query is built with values appended directly into the string - for (String value : values) { - sql.append("'"); - sql.append(value); - sql.append("',"); - } - if (values.size() > 0) { - sql.deleteCharAt(sql.length() - 1); - } - - if (singleCase && correlationCase != null) { - sql.append(") AND "); - sql.append(tableName); - sql.append(".case_id=?)"); // inner select checks for other case results - sql.append(" AND ("); - sql.append(tableName); - sql.append(".case_id=?"); - sql.append(" OR "); - sql.append(tableName); - sql.append(".case_id=?)"); - - } else { - sql.append(") GROUP BY value HAVING COUNT(*) > 1)"); // - } - - sql.append(" ORDER BY value, cases.case_name, file_path"); - - Connection conn = connect(); - CentralRepositoryFile artifactInstance; - PreparedStatement preparedStatement = null; - ResultSet resultSet = null; - try { - preparedStatement = conn.prepareStatement(sql.toString()); - if (singleCase && correlationCase != null) { - preparedStatement.setInt(1, correlationCase.getID()); - preparedStatement.setInt(2, correlationCase.getID()); - preparedStatement.setInt(3, currentCaseId); - } - - resultSet = preparedStatement.executeQuery(); - while (resultSet.next()) { - artifactInstance = getCommonEamArtifactInstanceFromResultSet(resultSet); - artifactInstances.add(artifactInstance); - } - - } catch (SQLException ex) { - throw new EamDbException("Error getting artifact instances by artifactType and artifactValue.", ex); // NON-NLS - } finally { - EamDbUtil.closePreparedStatement(preparedStatement); - EamDbUtil.closeResultSet(resultSet); - EamDbUtil.closeConnection(conn); - } - } - - return artifactInstances; - } - /** * Retrieves eamArtifact instances from the database that are associated * with the aType and filePath @@ -1964,7 +1844,7 @@ abstract class AbstractSqlEamDb implements EamDb { ResultSet resultSet = null; String tableName = EamDbUtil.correlationTypeToInstanceTableName(type); StringBuilder sql = new StringBuilder(); - sql.append("SELECT id,value, data_source_id FROM "); // TODO should this select * so any field is available? + sql.append("SELECT id, value, case_id FROM "); // TODO should this select * so any field is available? sql.append(tableName); sql.append(" WHERE value IN (SELECT value FROM "); sql.append(tableName); @@ -2828,32 +2708,6 @@ abstract class AbstractSqlEamDb implements EamDb { ); } - /** - * Convert a ResultSet to a Common EamArtifactInstance object - * - * @param resultSet A resultSet with a set of values to create a - * EamArtifactInstance object. - * - * @return fully populated EamArtifactInstance, or null - * - * @throws SQLException when an expected column name is not in the resultSet - */ - private CentralRepositoryFile getCommonEamArtifactInstanceFromResultSet(ResultSet resultSet) throws SQLException, EamDbException { - if (null == resultSet) { - return null; - } - CentralRepositoryFile eamArtifactInstance = new CentralRepositoryFile( - new CorrelationCase(resultSet.getInt("case_id"), resultSet.getString("case_uid"), resultSet.getString("case_name")), - new CorrelationDataSource(-1, resultSet.getInt("case_id"), resultSet.getString("device_id"), resultSet.getString("name")), - resultSet.getString("file_path"), - resultSet.getString("comment"), - TskData.FileKnown.valueOf(resultSet.getByte("known_status")), - resultSet.getString("value") - ); - - return eamArtifactInstance; - } - private EamOrganization getEamOrganizationFromResultSet(ResultSet resultSet) throws SQLException { if (null == resultSet) { return null; diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepositoryFile.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepositoryFile.java deleted file mode 100644 index 6fcc50b60a..0000000000 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepositoryFile.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Central Repository - * - * Copyright 2015-2017 Basis Technology Corp. - * Contact: carrier sleuthkit 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.centralrepository.datamodel; - -import org.sleuthkit.datamodel.TskData; - - -/** - * Common Files Search usage which extends CorrelationAttributeInstance - * by adding the MD5 value to match on for the results table. - */ -public class CentralRepositoryFile extends CorrelationAttributeInstance { - - private static final long serialVersionUID = 1L; - - /** - * The common MD5 value - */ - private final String value; - - public CentralRepositoryFile(CorrelationCase eamCase, CorrelationDataSource eamDataSource, String filePath, String comment, TskData.FileKnown knownStatus, String value) throws EamDbException { - super(eamCase, eamDataSource, filePath, comment, knownStatus); - this.value = value; - } - - public String getValue() { - return value; - } -} diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDb.java index 74863294c0..d9cd7d7af1 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDb.java @@ -226,28 +226,6 @@ public interface EamDb { * @return List of artifact instances for a given type/value */ List getArtifactInstancesByTypeValue(CorrelationAttribute.Type aType, String value) throws EamDbException; - - /** - * Retrieves eamArtiifact instances from the database that match the given - * list of MD5 values; - * - * @param correlationCase Case id to search on - * @param values List of ArtifactInstance MD5 values to find matches of. - * @param currentCaseId current case - * - * @return matching files in the form of CentralRepositoryFile - */ - List getArtifactInstancesByCaseValues(CorrelationCase correlationCase, Collection values, int currentCaseId) throws EamDbException; - - /** - * Retrieves eamArtiifact instances from the database that match the given - * list of MD5 values; - * - * @param values MD5s to use as search keys - * @return matching files in the form of CentralRepositoryFile - * @throws EamDbException - */ - List getArtifactInstancesByCaseValues(Collection values) throws EamDbException; /** * Retrieves eamArtifact instances from the database that are associated diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java index 433a86f8fa..237c1a0633 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java @@ -22,7 +22,6 @@ import java.sql.Connection; import java.sql.SQLException; import java.sql.Statement; import java.util.Arrays; -import java.util.Collection; import java.util.List; import java.util.Set; import java.util.concurrent.locks.ReentrantReadWriteLock; @@ -419,44 +418,6 @@ final class SqliteEamDb extends AbstractSqlEamDb { releaseSharedLock(); } } - - /** - * Retrieves eamArtiifact instances from the database that match the given - * list of MD5 values; - * - * @param correlationCase Case id to search on - * @param values List of ArtifactInstance MD5 values to find matches of. - * - * @return List of artifact instances for a given list of MD5 values - */ - @Override - public List getArtifactInstancesByCaseValues(Collection values) throws EamDbException { - try { - acquireSharedLock(); - return super.getArtifactInstancesByCaseValues(null, values, -1); - } finally { - releaseSharedLock(); - } - } - - /** - * Retrieves eamArtiifact instances from the database that match the given - * list of MD5 values; - * - * @param correlationCase Case id to search on - * @param values List of ArtifactInstance MD5 values to find matches of. - * - * @return List of artifact instances for a given list of MD5 values - */ - @Override - public List getArtifactInstancesByCaseValues(CorrelationCase correlationCase, Collection values, int currentCaseId) throws EamDbException { - try { - acquireSharedLock(); - return super.getArtifactInstancesByCaseValues(correlationCase, values, currentCaseId); - } finally { - releaseSharedLock(); - } - } /** * Retrieves eamArtifact instances from the database that are associated diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepositoryCaseFileInstanceMetadata.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepositoryCaseFileInstanceMetadata.java index 94fbe9cfcb..c6ede2eabd 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepositoryCaseFileInstanceMetadata.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepositoryCaseFileInstanceMetadata.java @@ -19,8 +19,11 @@ */ package org.sleuthkit.autopsy.commonfilesearch; +import java.util.ArrayList; +import java.util.List; import java.util.Map; -import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepositoryFile; +import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttribute; +import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance; import org.sleuthkit.autopsy.datamodel.DisplayableItemNode; import org.sleuthkit.datamodel.AbstractFile; @@ -28,18 +31,37 @@ import org.sleuthkit.datamodel.AbstractFile; * Generates a DisplayableItmeNode using a CentralRepositoryFile. */ final public class CentralRepositoryCaseFileInstanceMetadata extends FileInstanceNodeGenerator { - - private CentralRepositoryFile crFile; - CentralRepositoryCaseFileInstanceMetadata(CentralRepositoryFile crFile, Long abstractFileReference, Map cachedFiles, String dataSource, String caseName){ - super(abstractFileReference, cachedFiles, dataSource, caseName); - //TODO should we actually just take an ID instead of the whole object - // like we've done previously, or is this ok? - this.crFile = crFile; + private final Integer crFileId; + private CorrelationAttributeInstance tempAttributeInst; + + CentralRepositoryCaseFileInstanceMetadata(Integer attrInstId, Map cachedFiles) { + super(cachedFiles); + this.crFileId = attrInstId; } @Override public DisplayableItemNode generateNode() { - return new CentralRepositoryFileInstanceNode(this.crFile, this.lookupOrCreateAbstractFile()); + if (tempAttributeInst != null) { + return new CentralRepositoryFileInstanceNode(tempAttributeInst, this.lookupOrCreateAbstractFile()); + } + return null; + } + + @Override + public DisplayableItemNode[] generateNodes() { + EamDbAttributeInstancesAlgorithm eamDbAttrInst = new EamDbAttributeInstancesAlgorithm(); + CorrelationAttribute corrAttr = eamDbAttrInst.processCorrelationCaseSingleAttribute(crFileId); //TODO which do we want + List attrInstNodeList = new ArrayList<>(0); + this.abstractFileReference = Long.getLong(corrAttr.getCorrelationValue()); + + for (CorrelationAttributeInstance attrInst : corrAttr.getInstances()) { + tempAttributeInst = attrInst; + DisplayableItemNode generatedInstNode = generateNode(); + if (generatedInstNode != null) { + attrInstNodeList.add(generatedInstNode); + } + } + return attrInstNodeList.toArray(new DisplayableItemNode[attrInstNodeList.size()]); } } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepositoryFileInstanceNode.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepositoryFileInstanceNode.java index 5c5f71082e..056c489431 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepositoryFileInstanceNode.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepositoryFileInstanceNode.java @@ -27,7 +27,7 @@ import javax.swing.Action; import org.openide.nodes.Children; import org.openide.nodes.Sheet; import org.openide.util.lookup.Lookups; -import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepositoryFile; +import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance; import org.sleuthkit.autopsy.datamodel.DisplayableItemNode; import org.sleuthkit.autopsy.datamodel.DisplayableItemNodeVisitor; import org.sleuthkit.autopsy.datamodel.NodeProperty; @@ -44,13 +44,13 @@ import org.sleuthkit.datamodel.Content; */ public class CentralRepositoryFileInstanceNode extends DisplayableItemNode { - private final CentralRepositoryFile crFile; + private final CorrelationAttributeInstance crFile; //this may not be the same file, but at least it is identical, // and we can use this to support certain actions in the tree table and crFile viewer private final AbstractFile md5Reference; - public CentralRepositoryFileInstanceNode(CentralRepositoryFile content, AbstractFile md5Reference) { + public CentralRepositoryFileInstanceNode(CorrelationAttributeInstance content, AbstractFile md5Reference) { super(Children.LEAF, Lookups.fixed(content)); // TODO, using md5Reference enables Other Occurances..but for the incorrect file path this.crFile = content; @@ -58,7 +58,7 @@ public class CentralRepositoryFileInstanceNode extends DisplayableItemNode { this.md5Reference = md5Reference; } - public CentralRepositoryFile getCentralRepoFile(){ + public CorrelationAttributeInstance getCentralRepoFile(){ return this.crFile; } @@ -103,7 +103,7 @@ public class CentralRepositoryFileInstanceNode extends DisplayableItemNode { sheet.put(sheetSet); } - final CentralRepositoryFile centralRepoFile = this.getCentralRepoFile(); + final CorrelationAttributeInstance centralRepoFile = this.getCentralRepoFile(); final String fullPath = centralRepoFile.getFilePath(); final File file = new File(fullPath); diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbAttributeInstancesAlgorithm.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbAttributeInstancesAlgorithm.java index c492c43cfb..ba4ca0ebfa 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbAttributeInstancesAlgorithm.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbAttributeInstancesAlgorithm.java @@ -37,12 +37,12 @@ import org.sleuthkit.autopsy.coreutils.Logger; * Used to process and return CorrelationCase md5s from the EamDB for * CommonFilesSearch. */ -class EamDbAttributeInstancesAlgorithm { +final class EamDbAttributeInstancesAlgorithm { private static final Logger logger = Logger.getLogger(CommonFilesPanel.class.getName()); private final Map intercaseCommonValuesMap = new HashMap<>(); - private final Map intercaseCommonDatasourcesMap = new HashMap<>(); + private final Map intercaseCommonCasesMap = new HashMap<>(); CorrelationAttribute processCorrelationCaseSingleAttribute(int attrbuteId) { try { @@ -70,7 +70,7 @@ class EamDbAttributeInstancesAlgorithm { DbManager.processCaseInstancesTable(fileType, DbManager.getCase(currentCase), instancetableCallback); intercaseCommonValuesMap.putAll(instancetableCallback.getCorrelationIdValueMap()); - intercaseCommonDatasourcesMap.putAll(instancetableCallback.getCorrelationIdDatasourceMap()); + intercaseCommonCasesMap.putAll(instancetableCallback.getCorrelationIdToCaseMap()); } catch (EamDbException ex) { logger.log(Level.SEVERE, "Error accessing EamDb processing CaseInstancesTable.", ex); } @@ -81,8 +81,8 @@ class EamDbAttributeInstancesAlgorithm { return Collections.unmodifiableMap(intercaseCommonValuesMap); } - Map getIntercaseCommonDatasourcesMap() { - return Collections.unmodifiableMap(intercaseCommonDatasourcesMap); + Map getIntercaseCommonCasesMap() { + return Collections.unmodifiableMap(intercaseCommonCasesMap); } /** @@ -100,7 +100,7 @@ class EamDbAttributeInstancesAlgorithm { while (resultSet.next()) { int resultId = InstanceTableCallback.getId(resultSet); correlationIdToValueMap.put(resultId, InstanceTableCallback.getValue(resultSet)); - correlationIdToDatasourceMap.put(resultId, InstanceTableCallback.getValue(resultSet)); + correlationIdToDatasourceMap.put(resultId, String.valueOf(InstanceTableCallback.getCaseId(resultSet))); } } catch (SQLException ex) { Exceptions.printStackTrace(ex); @@ -111,7 +111,7 @@ class EamDbAttributeInstancesAlgorithm { return Collections.unmodifiableMap(correlationIdToValueMap); } - Map getCorrelationIdDatasourceMap() { + Map getCorrelationIdToCaseMap() { return Collections.unmodifiableMap(correlationIdToDatasourceMap); } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbCommonFilesAlgorithm.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbCommonFilesAlgorithm.java index 16122a9ab0..03309ac9b5 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbCommonFilesAlgorithm.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbCommonFilesAlgorithm.java @@ -19,27 +19,18 @@ */ package org.sleuthkit.autopsy.commonfilesearch; -import java.io.File; import java.sql.SQLException; -import java.util.ArrayList; -import java.util.Collection; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; -import java.util.TreeMap; import java.util.logging.Level; -import java.util.stream.Collectors; -import org.openide.util.Exceptions; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; -import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepositoryFile; import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationCase; import org.sleuthkit.autopsy.centralrepository.datamodel.EamDb; import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException; -import static org.sleuthkit.autopsy.commonfilesearch.CommonFilesMetadataBuilder.SELECT_PREFIX; import static org.sleuthkit.autopsy.timeline.datamodel.eventtype.ArtifactEventType.LOGGER; -import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.HashUtility; import org.sleuthkit.datamodel.TskCoreException; @@ -52,11 +43,7 @@ public abstract class EamDbCommonFilesAlgorithm extends CommonFilesMetadataBuild // instead of an abstract class and then have two abstract classes: // inter- and intra- which implement the interface and then 4 subclasses // 2 for each abstract class: singlecase/allcase; singledatasource/all datasource - - private static final String WHERE_CLAUSE = "%s md5 in (select md5 from tsk_files where (known != 1 OR known IS NULL)%s GROUP BY md5) order by md5"; //NON-NLS - - private final EamDb dbManager; - + EamDb dbManager; /** * Implements the algorithm for getting common files across all data sources * and all cases. Can filter on mime types conjoined by logical AND. @@ -71,7 +58,7 @@ public abstract class EamDbCommonFilesAlgorithm extends CommonFilesMetadataBuild */ EamDbCommonFilesAlgorithm(Map dataSourceIdMap, boolean filterByMediaMimeType, boolean filterByDocMimeType) throws EamDbException { super(dataSourceIdMap, filterByMediaMimeType, filterByDocMimeType); - + dbManager = EamDb.getInstance(); } @@ -81,83 +68,67 @@ public abstract class EamDbCommonFilesAlgorithm extends CommonFilesMetadataBuild } protected CommonFilesMetadata findFiles(CorrelationCase correlationCase) throws TskCoreException, NoCurrentCaseException, SQLException, EamDbException, Exception { - Map> currentCaseMetadata = getMetadataForCurrentCase(); - Collection values = currentCaseMetadata.values().stream().flatMap(List::stream).collect(Collectors.toList()).stream().map(Md5Metadata::getMd5).collect(Collectors.toList()); - - int currentCaseId; - Map> interCaseCommonFiles = new HashMap<>(); - try { - // Need to include current Cases results for specific case comparison - currentCaseId = dbManager.getCase(Case.getCurrentCase()).getID(); - Collection artifactInstances; - if(this.dbManager == null){ - artifactInstances = new ArrayList<>(0); - } else { - artifactInstances = dbManager.getArtifactInstancesByCaseValues(correlationCase, values, currentCaseId).stream() - .collect(Collectors.toList()); - } - - interCaseCommonFiles = gatherIntercaseResults(artifactInstances, currentCaseMetadata); - } catch (EamDbException ex) { - LOGGER.log(Level.SEVERE, "Error getting artifact instances from database.", ex); // NON-NLS - } + //TODO separate if case for correlationCase + Map> interCaseCommonFiles = new HashMap<>(); + + // Need to include current Cases results for specific case comparison + EamDbAttributeInstancesAlgorithm eamDbAttrInst = new EamDbAttributeInstancesAlgorithm(); + eamDbAttrInst.processCorrelationCaseAttributeValues(Case.getCurrentCase()); + interCaseCommonFiles = gatherIntercaseResults(eamDbAttrInst.getIntercaseCommonValuesMap(), eamDbAttrInst.getIntercaseCommonCasesMap()); + // Builds intercase-only matches metadata return new CommonFilesMetadata(interCaseCommonFiles); } - private Map> getMetadataForCurrentCase() throws NoCurrentCaseException, TskCoreException, SQLException, Exception { - //we need the list of files in the present case so we can compare against the central repo - CommonFilesMetadata metaData = super.findFiles(); - Map> commonFiles = metaData.getMetadata(); - return commonFiles; - } + //TODO, only use to filter mimeType in memory against currentCase against, unless mimeType is added to CR +// private Map> getMetadataForCurrentCase() throws NoCurrentCaseException, TskCoreException, SQLException, Exception { +// //we need the list of files in the present case so we can compare against the central repo +// CommonFilesMetadata metaData = super.findFiles(); +// Map> commonFiles = metaData.getMetadata(); +// return commonFiles; +// } /** * @param artifactInstances all 'common files' in central repo * @param commonFiles matches must ultimately have appeared in this collection * @return collated map of instance counts to lists of matches */ - private Map> gatherIntercaseResults(Collection artifactInstances, Map> commonFiles) { + private Map> gatherIntercaseResults(Map commonFiles, Map commonFileCases) { Map interCaseCommonFiles = new HashMap<>(); - - Map cachedFiles = new HashMap<>(); - - Map flattenedCommonFiles = flatten(commonFiles); - for (CentralRepositoryFile instance : artifactInstances) { - - String md5 = instance.getValue(); - final String correlationCaseDisplayName = instance.getCorrelationCase().getDisplayName(); + for (int commonAttrId : commonFiles.keySet()) { + String md5 = commonFiles.get(commonAttrId); if (md5 == null || HashUtility.isNoDataMd5(md5)) { continue; } - //Builds a 3rd list which contains instances which are in currentCaseMetadata map, uses current case objectId - if (flattenedCommonFiles.containsKey(md5)) { - try { - // we don't *have* all the information for the rows in the CR, - // so we need to consult the present case via the SleuthkitCase object - - final Iterator identitcalFileInstanceMetadata = flattenedCommonFiles.get(md5).getMetadata().iterator(); - - FileInstanceNodeGenerator nodeGenerator = FileInstanceNodeGenerator.createInstance(identitcalFileInstanceMetadata, instance, cachedFiles); - - if(interCaseCommonFiles.containsKey(md5)) { - //Add to intercase metaData - final Md5Metadata md5Metadata = interCaseCommonFiles.get(md5); - md5Metadata.addFileInstanceMetadata(nodeGenerator, correlationCaseDisplayName); - - } else { - Md5Metadata md5Metadata = new Md5Metadata(md5); - md5Metadata.addFileInstanceMetadata(nodeGenerator, correlationCaseDisplayName); - interCaseCommonFiles.put(md5, md5Metadata); - } - } catch (Exception ex) { - LOGGER.log(Level.WARNING, "Error getting artifact instances from database.", ex); // NON-NLS + + try { + // TODO, pass proper Case + final String correlationCaseDisplayName = dbManager.getCaseByUUID(commonFileCases.get(commonAttrId)).getDisplayName(); + // we don't *have* all the information for the rows in the CR, + // so we need to consult the present case via the SleuthkitCase object + + final Iterator identitcalFileInstanceMetadata = interCaseCommonFiles.get(md5).getMetadata().iterator(); + + FileInstanceNodeGenerator nodeGenerator = FileInstanceNodeGenerator.createInstance(identitcalFileInstanceMetadata, commonAttrId); + + if(interCaseCommonFiles.containsKey(md5)) { + //Add to intercase metaData + final Md5Metadata md5Metadata = interCaseCommonFiles.get(md5); + md5Metadata.addFileInstanceMetadata(nodeGenerator, correlationCaseDisplayName); + + } else { + Md5Metadata md5Metadata = new Md5Metadata(md5); + md5Metadata.addFileInstanceMetadata(nodeGenerator, correlationCaseDisplayName); + interCaseCommonFiles.put(md5, md5Metadata); } + } catch (Exception ex) { + LOGGER.log(Level.WARNING, "Error getting artifact instances from database.", ex); // NON-NLS } + } Map> instanceCollatedCommonFiles = collatetMatchesByNumberOfInstances(interCaseCommonFiles); @@ -167,8 +138,7 @@ public abstract class EamDbCommonFilesAlgorithm extends CommonFilesMetadataBuild @Override protected String buildSqlSelectStatement() { - Object[] args = new String[]{SELECT_PREFIX, determineMimeTypeFilter()}; - return String.format(WHERE_CLAUSE, args); + return ""; // TODO Unused } @Override @@ -187,15 +157,4 @@ public abstract class EamDbCommonFilesAlgorithm extends CommonFilesMetadataBuild throw new Exception("Cannot locate case."); } - private Map flatten(Map> commonFiles) { - //This is obviously junk and will go away when we perform subsequent refactors - Map flattened = new HashMap<>(); - for(List list : commonFiles.values()){ - for(Md5Metadata md5 : list){ - flattened.put(md5.getMd5(), md5); - } - } - - return flattened; - } } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/FileInstanceNodeGenerator.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/FileInstanceNodeGenerator.java index 71f2d67eb8..d5fdf2ba37 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/FileInstanceNodeGenerator.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/FileInstanceNodeGenerator.java @@ -19,13 +19,11 @@ */ package org.sleuthkit.autopsy.commonfilesearch; -import java.nio.file.Paths; import java.util.Iterator; import java.util.Map; import java.util.logging.Level; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; -import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepositoryFile; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.datamodel.DisplayableItemNode; import org.sleuthkit.datamodel.AbstractFile; @@ -40,16 +38,23 @@ public abstract class FileInstanceNodeGenerator { private static final Logger LOGGER = Logger.getLogger(FileInstanceNodeGenerator.class.getName()); protected Long abstractFileReference; - protected Map cachedFiles; - private final String caseName; - private String dataSource; + protected static Map cachedFiles; + String caseName; + String dataSource; public FileInstanceNodeGenerator(Long abstractFileReference, Map cachedFiles, String dataSource, String caseName) { this.abstractFileReference = abstractFileReference; - this.cachedFiles = cachedFiles; + cachedFiles = cachedFiles; this.caseName = caseName; this.dataSource = dataSource; } + + public FileInstanceNodeGenerator(Map cachedFiles) { + this.abstractFileReference = null; + cachedFiles = cachedFiles; + this.caseName = null; + this.dataSource = null; + } /** * Grab a cached instance of the AbstractFile or grab one from the @@ -105,6 +110,14 @@ public abstract class FileInstanceNodeGenerator { * @return child row node */ public abstract DisplayableItemNode generateNode(); + + /** + * Create a list of nodes which are a child of the MD5Node, to be used to display a + * row in the tree table + * + * @return child row node + */ + public abstract DisplayableItemNode[] generateNodes(); public String getCaseName() { return this.caseName; @@ -129,43 +142,10 @@ public abstract class FileInstanceNodeGenerator { return this.abstractFileReference; } - public static FileInstanceNodeGenerator createInstance(Iterator identicalFileNodeGeneratorIterator, CentralRepositoryFile instance, Map cachedFiles) throws Exception { + public static FileInstanceNodeGenerator createInstance(Iterator identicalFileNodeGeneratorIterator, Integer instanceId) throws Exception { - Long arbitraryIdenticalAbstractFileId = null; + //Long arbitraryIdenticalAbstractFileId = null; + return new CentralRepositoryCaseFileInstanceMetadata(instanceId, cachedFiles); - final String instanceDataSource = instance.getCorrelationDataSource().getName().toLowerCase(); - final String instanceCase = instance.getCorrelationCase().getDisplayName().toLowerCase(); - final String instancePath = instance.getFilePath().toLowerCase(); - - while (identicalFileNodeGeneratorIterator.hasNext()) { - - FileInstanceNodeGenerator identicalFileNodeGenerator = identicalFileNodeGeneratorIterator.next(); - - final Long identicalFileSleuthkitCaseObjectID = identicalFileNodeGenerator.getIdenticalFileSleuthkitCaseObjectID(); - - final AbstractFile referenceFile = FileInstanceNodeGenerator.lookupOrCreateAbstractFile(identicalFileSleuthkitCaseObjectID, cachedFiles); - final Long referenceFileId = referenceFile.getId(); - arbitraryIdenticalAbstractFileId = referenceFileId; - - final String referenceFileDataSource = identicalFileNodeGenerator.getDataSource().toLowerCase(); - - final String referenceCase = Case.getCurrentCase().getDisplayName().toLowerCase(); - - final String referencePath = Paths.get(referenceFile.getParentPath(), referenceFile.getName()).toString().toLowerCase().replace("\\", "/"); - - final boolean sameDataSource = referenceFileDataSource.equals(instanceDataSource); - final boolean sameCase = referenceCase.equals(instanceCase); - final boolean samePathAndName = referencePath.equals(instancePath); - - if (sameDataSource && sameCase && samePathAndName) { - return new SleuthkitCaseFileInstanceMetadata(referenceFile.getId(), cachedFiles, referenceFileDataSource, referenceCase); - } - } - - if (arbitraryIdenticalAbstractFileId != null) { - return new CentralRepositoryCaseFileInstanceMetadata(instance, arbitraryIdenticalAbstractFileId, cachedFiles, instanceDataSource, instanceCase); - } else { - throw new Exception("Unable to get instance."); - } } } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/Md5Metadata.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/Md5Metadata.java index 7d77971683..9611ccac95 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/Md5Metadata.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/Md5Metadata.java @@ -25,7 +25,6 @@ import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; -import java.util.stream.Collector; import java.util.stream.Collectors; /** diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/Md5Node.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/Md5Node.java index c62cf87acf..b22e3e35e7 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/Md5Node.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/Md5Node.java @@ -20,29 +20,20 @@ package org.sleuthkit.autopsy.commonfilesearch; import java.util.HashMap; -import java.util.LinkedHashMap; import java.util.List; import java.util.Map; -import java.util.concurrent.Callable; -import java.util.logging.Level; import org.openide.nodes.ChildFactory; import org.openide.nodes.Children; import org.openide.nodes.Node; import org.openide.nodes.Sheet; import org.openide.util.NbBundle; -import org.sleuthkit.autopsy.casemodule.Case; -import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; -import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepositoryFile; import org.sleuthkit.autopsy.commonfilesearch.FileInstanceNodeGenerator; -import org.sleuthkit.autopsy.commonfilesearch.SleuthkitCaseFileInstanceMetadata; import org.sleuthkit.autopsy.commonfilesearch.Md5Metadata; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.datamodel.DisplayableItemNode; import org.sleuthkit.autopsy.datamodel.DisplayableItemNodeVisitor; import org.sleuthkit.autopsy.datamodel.NodeProperty; import org.sleuthkit.datamodel.AbstractFile; -import org.sleuthkit.datamodel.SleuthkitCase; -import org.sleuthkit.datamodel.TskCoreException; /** * Represents a common files match - two or more files which appear to be the @@ -148,18 +139,18 @@ public class Md5Node extends DisplayableItemNode { */ static class FileInstanceNodeFactory extends ChildFactory { - private Map cachedFiles; + //private final Map cachedFiles; private final Md5Metadata descendants; FileInstanceNodeFactory(Md5Metadata descendants) { this.descendants = descendants; - this.cachedFiles = new HashMap<>(); + //this.cachedFiles = new HashMap<>(); } @Override - protected Node createNodeForKey(FileInstanceNodeGenerator file) { - return file.generateNode(); + protected Node[] createNodesForKey(FileInstanceNodeGenerator file) { + return file.generateNodes(); } @Override diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/SleuthkitCaseFileInstanceMetadata.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/SleuthkitCaseFileInstanceMetadata.java index 32a98c873b..8b9370d703 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/SleuthkitCaseFileInstanceMetadata.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/SleuthkitCaseFileInstanceMetadata.java @@ -19,10 +19,8 @@ */ package org.sleuthkit.autopsy.commonfilesearch; -import java.io.File; +import java.util.Arrays; import java.util.Map; -import org.openide.nodes.Node; -import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepositoryFile; import org.sleuthkit.autopsy.datamodel.DisplayableItemNode; import org.sleuthkit.datamodel.AbstractFile; @@ -30,13 +28,15 @@ import org.sleuthkit.datamodel.AbstractFile; * Encapsulates data required to instantiate a FileInstanceNode. */ final public class SleuthkitCaseFileInstanceMetadata extends FileInstanceNodeGenerator { - + /** - * Create meta data required to find an abstract file and build a FileInstanceNode. + * Create meta data required to find an abstract file and build a + * FileInstanceNode. + * * @param objectId id of abstract file to find * @param dataSourceName name of datasource where the object is found */ - SleuthkitCaseFileInstanceMetadata (Long abstractFileReference, Map cachedFiles, String dataSource, String caseName) { + SleuthkitCaseFileInstanceMetadata(Long abstractFileReference, Map cachedFiles, String dataSource, String caseName) { super(abstractFileReference, cachedFiles, dataSource, caseName); } @@ -44,4 +44,9 @@ final public class SleuthkitCaseFileInstanceMetadata extends FileInstanceNodeGen public DisplayableItemNode generateNode() { return new SleuthkitCaseFileInstanceNode(this.lookupOrCreateAbstractFile(), this.getCaseName(), this.getDataSource()); } + + @Override + public DisplayableItemNode[] generateNodes() { + return Arrays.asList(generateNode()).toArray(new DisplayableItemNode[1]); + } } From 6d80671aba3ca5832e3de53c874f21f4ae898625 Mon Sep 17 00:00:00 2001 From: Andrew Ziehl Date: Tue, 10 Jul 2018 21:10:06 -0700 Subject: [PATCH 122/287] query chaanges to utilize InstanceCallback returning case id, and having distinct return all rows from all matching cases. Common Files Alg logic cleanup. WIP FileInstanceNode for CR node creation. --- .../datamodel/AbstractSqlEamDb.java | 48 +++++++++++++++++-- .../centralrepository/datamodel/EamDb.java | 8 ++++ .../datamodel/SqliteEamDb.java | 43 +++++++++++++---- .../EamDbAttributeInstancesAlgorithm.java | 10 ++-- .../EamDbCommonFilesAlgorithm.java | 14 ++++-- 5 files changed, 101 insertions(+), 22 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java index 73a24c0d6d..e148c39a02 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java @@ -384,6 +384,46 @@ abstract class AbstractSqlEamDb implements EamDb { return eamCaseResult; } + /** + * Retrieves Case details based on Case ID + * + * @param caseID unique identifier for a case + * + * @return The retrieved case + */ + @Override + public CorrelationCase getCaseById(int caseId) throws EamDbException { + // @@@ We should have a cache here... + + Connection conn = connect(); + + CorrelationCase eamCaseResult = null; + PreparedStatement preparedStatement = null; + ResultSet resultSet = null; + + String sql = "SELECT cases.id as case_id, case_uid, case_name, creation_date, case_number, examiner_name, " + + "examiner_email, examiner_phone, notes, organizations.id as org_id, org_name, poc_name, poc_email, poc_phone " + + "FROM cases " + + "LEFT JOIN organizations ON cases.org_id=organizations.id " + + "WHERE cases.id=?"; + + try { + preparedStatement = conn.prepareStatement(sql); + preparedStatement.setInt(1, caseId); + resultSet = preparedStatement.executeQuery(); + if (resultSet.next()) { + eamCaseResult = getEamCaseFromResultSet(resultSet); + } + } catch (SQLException ex) { + throw new EamDbException("Error getting case details.", ex); // NON-NLS + } finally { + EamDbUtil.closeStatement(preparedStatement); + EamDbUtil.closeResultSet(resultSet); + EamDbUtil.closeConnection(conn); + } + + return eamCaseResult; + } /** * Retrieves cases that are in DB. @@ -1844,15 +1884,17 @@ abstract class AbstractSqlEamDb implements EamDb { ResultSet resultSet = null; String tableName = EamDbUtil.correlationTypeToInstanceTableName(type); StringBuilder sql = new StringBuilder(); - sql.append("SELECT id, value, case_id FROM "); // TODO should this select * so any field is available? + sql.append("SELECT id, value, case_id FROM "); + sql.append(tableName); + sql.append(" WHERE value IN (SELECT value FROM "); // TODO should this select * so any field is available? sql.append(tableName); sql.append(" WHERE value IN (SELECT value FROM "); sql.append(tableName); - sql.append(" WHERE case_id=? AND (known_status !=? OR known_status IS NULL) GROUP BY value HAVING COUNT(DISTINCT case_id) > 1 ORDER BY value"); + sql.append(" WHERE case_id=? AND (known_status !=? OR known_status IS NULL) GROUP BY value) GROUP BY value HAVING COUNT(DISTINCT case_id) > 1) ORDER BY value"); try { preparedStatement = conn.prepareStatement(sql.toString()); - preparedStatement.setString(1, correlationCase.getCaseUUID()); + preparedStatement.setInt(1, correlationCase.getID()); preparedStatement.setByte(2, TskData.FileKnown.KNOWN.getFileKnownValue()); resultSet = preparedStatement.executeQuery(); instanceTableCallback.process(resultSet); diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDb.java index d9cd7d7af1..4e9b47d7ea 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDb.java @@ -176,6 +176,14 @@ public interface EamDb { */ CorrelationCase getCaseByUUID(String caseUUID) throws EamDbException; + /** + * Retrieves Case details based on Case ID + * + * @param caseID unique identifier for a case + * + * @return The retrieved case + */ + CorrelationCase getCaseById(int caseId) throws EamDbException; /** * Retrieves cases that are in DB. * diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java index 237c1a0633..2cac1ebfa8 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java @@ -320,6 +320,24 @@ final class SqliteEamDb extends AbstractSqlEamDb { } } + /** + * Retrieves Case details based on Case ID + * + * @param caseID unique identifier for a case + * + * @return The retrieved case + */ + @Override + public CorrelationCase getCaseById(int caseId) throws EamDbException { + try { + acquireSharedLock(); + return super.getCaseById(caseId); + } finally { + releaseSharedLock(); + } + + } + /** * Retrieves cases that are in DB. * @@ -593,20 +611,21 @@ final class SqliteEamDb extends AbstractSqlEamDb { * * Gets list of matching eamArtifact instances that have knownStatus = * "Bad". + * * @param aType EamArtifact.Type to search for * @return List with 0 or more matching eamArtifact instances. * @throws EamDbException */ @Override public List getArtifactInstancesKnownBad(CorrelationAttribute.Type aType) throws EamDbException { - try{ + try { acquireSharedLock(); return super.getArtifactInstancesKnownBad(aType); } finally { releaseSharedLock(); - } + } } - + /** * Count matching eamArtifacts instances that have knownStatus = "Bad". * @@ -697,7 +716,7 @@ final class SqliteEamDb extends AbstractSqlEamDb { releaseSharedLock(); } } - + /** * Process a single Artifact instance row in the EamDb * @@ -715,11 +734,13 @@ final class SqliteEamDb extends AbstractSqlEamDb { releaseSharedLock(); } } - + /** - * Process the Artifact md5s in the EamDb for matches of case files which are not known + * Process the Artifact md5s in the EamDb for matches of case files which + * are not known + * * @param type EamArtifact.Type to search for - * @param correlationCase CorrelationCase to filter by + * @param correlationCase CorrelationCase to filter by * @param instanceTableCallback callback to process the instance * @throws EamDbException */ @@ -732,10 +753,12 @@ final class SqliteEamDb extends AbstractSqlEamDb { releaseSharedLock(); } } - + /** - * Check whether a reference set with the given name/version is in the central repo. - * Used to check for name collisions when creating reference sets. + * Check whether a reference set with the given name/version is in the + * central repo. Used to check for name collisions when creating reference + * sets. + * * @param referenceSetName * @param version * @return true if a matching set is found diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbAttributeInstancesAlgorithm.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbAttributeInstancesAlgorithm.java index ba4ca0ebfa..9f6365b05b 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbAttributeInstancesAlgorithm.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbAttributeInstancesAlgorithm.java @@ -42,7 +42,7 @@ final class EamDbAttributeInstancesAlgorithm { private static final Logger logger = Logger.getLogger(CommonFilesPanel.class.getName()); private final Map intercaseCommonValuesMap = new HashMap<>(); - private final Map intercaseCommonCasesMap = new HashMap<>(); + private final Map intercaseCommonCasesMap = new HashMap<>(); CorrelationAttribute processCorrelationCaseSingleAttribute(int attrbuteId) { try { @@ -81,7 +81,7 @@ final class EamDbAttributeInstancesAlgorithm { return Collections.unmodifiableMap(intercaseCommonValuesMap); } - Map getIntercaseCommonCasesMap() { + Map getIntercaseCommonCasesMap() { return Collections.unmodifiableMap(intercaseCommonCasesMap); } @@ -92,7 +92,7 @@ final class EamDbAttributeInstancesAlgorithm { private class EamDbAttributeInstancesCallback implements InstanceTableCallback { private final Map correlationIdToValueMap = new HashMap<>(); - private final Map correlationIdToDatasourceMap = new HashMap<>(); + private final Map correlationIdToDatasourceMap = new HashMap<>(); @Override public void process(ResultSet resultSet) { @@ -100,7 +100,7 @@ final class EamDbAttributeInstancesAlgorithm { while (resultSet.next()) { int resultId = InstanceTableCallback.getId(resultSet); correlationIdToValueMap.put(resultId, InstanceTableCallback.getValue(resultSet)); - correlationIdToDatasourceMap.put(resultId, String.valueOf(InstanceTableCallback.getCaseId(resultSet))); + correlationIdToDatasourceMap.put(resultId, InstanceTableCallback.getCaseId(resultSet)); } } catch (SQLException ex) { Exceptions.printStackTrace(ex); @@ -111,7 +111,7 @@ final class EamDbAttributeInstancesAlgorithm { return Collections.unmodifiableMap(correlationIdToValueMap); } - Map getCorrelationIdToCaseMap() { + Map getCorrelationIdToCaseMap() { return Collections.unmodifiableMap(correlationIdToDatasourceMap); } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbCommonFilesAlgorithm.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbCommonFilesAlgorithm.java index 03309ac9b5..39db0fcf7b 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbCommonFilesAlgorithm.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbCommonFilesAlgorithm.java @@ -94,7 +94,7 @@ public abstract class EamDbCommonFilesAlgorithm extends CommonFilesMetadataBuild * @param commonFiles matches must ultimately have appeared in this collection * @return collated map of instance counts to lists of matches */ - private Map> gatherIntercaseResults(Map commonFiles, Map commonFileCases) { + private Map> gatherIntercaseResults(Map commonFiles, Map commonFileCases) { Map interCaseCommonFiles = new HashMap<>(); @@ -107,21 +107,27 @@ public abstract class EamDbCommonFilesAlgorithm extends CommonFilesMetadataBuild try { // TODO, pass proper Case - final String correlationCaseDisplayName = dbManager.getCaseByUUID(commonFileCases.get(commonAttrId)).getDisplayName(); + int caseId = commonFileCases.get(commonAttrId); + CorrelationCase autopsyCrCase = dbManager.getCaseById(caseId); + final String correlationCaseDisplayName = autopsyCrCase.getDisplayName(); // we don't *have* all the information for the rows in the CR, // so we need to consult the present case via the SleuthkitCase object - final Iterator identitcalFileInstanceMetadata = interCaseCommonFiles.get(md5).getMetadata().iterator(); + - FileInstanceNodeGenerator nodeGenerator = FileInstanceNodeGenerator.createInstance(identitcalFileInstanceMetadata, commonAttrId); + if(interCaseCommonFiles.containsKey(md5)) { //Add to intercase metaData final Md5Metadata md5Metadata = interCaseCommonFiles.get(md5); + final Iterator identitcalFileInstanceMetadata = interCaseCommonFiles.get(md5).getMetadata().iterator(); + FileInstanceNodeGenerator nodeGenerator = FileInstanceNodeGenerator.createInstance(identitcalFileInstanceMetadata, commonAttrId); md5Metadata.addFileInstanceMetadata(nodeGenerator, correlationCaseDisplayName); } else { Md5Metadata md5Metadata = new Md5Metadata(md5); + final Iterator identitcalFileInstanceMetadata = md5Metadata.getMetadata().iterator(); + FileInstanceNodeGenerator nodeGenerator = FileInstanceNodeGenerator.createInstance(identitcalFileInstanceMetadata, commonAttrId); md5Metadata.addFileInstanceMetadata(nodeGenerator, correlationCaseDisplayName); interCaseCommonFiles.put(md5, md5Metadata); } From 75fbb309b9ad390b5ce9261ec5e228d994a01be8 Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dgrove" Date: Wed, 11 Jul 2018 01:35:06 -0400 Subject: [PATCH 123/287] Column width adjustments handled. --- .../DataContentViewerOtherCases.form | 24 +--- .../DataContentViewerOtherCases.java | 123 +++++++++-------- ...DataContentViewerOtherCasesTableModel.java | 126 ++++++++++-------- 3 files changed, 142 insertions(+), 131 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/DataContentViewerOtherCases.form b/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/DataContentViewerOtherCases.form index 7b9e47c236..9c42be16a8 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/DataContentViewerOtherCases.form +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/DataContentViewerOtherCases.form @@ -133,23 +133,18 @@ - - - + - - - - - - - - + + + + + @@ -230,13 +225,6 @@ - - - - - - - diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/DataContentViewerOtherCases.java b/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/DataContentViewerOtherCases.java index ebc5b7c375..1c69671b05 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/DataContentViewerOtherCases.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/DataContentViewerOtherCases.java @@ -19,6 +19,7 @@ package org.sleuthkit.autopsy.centralrepository.contentviewer; import java.awt.Component; +import java.awt.FontMetrics; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.BufferedWriter; @@ -86,7 +87,10 @@ public class DataContentViewerOtherCases extends JPanel implements DataContentVi private static final long serialVersionUID = -1L; - private final static Logger logger = Logger.getLogger(DataContentViewerOtherCases.class.getName()); + private static final Logger logger = Logger.getLogger(DataContentViewerOtherCases.class.getName()); + + private static final int DEFAULT_MIN_CELL_WIDTH = 15; + private static final int CELL_TEXT_WIDTH_PADDING = 5; private final DataContentViewerOtherCasesTableModel tableModel; private final Collection correlationAttributes; @@ -459,12 +463,12 @@ public class DataContentViewerOtherCases extends JPanel implements DataContentVi @Messages({"DataContentViewerOtherCases.earliestCaseNotAvailable= Not Enabled."}) /** - * Gets the list of Eam Cases and determines the earliest case creation date. - * Sets the label to display the earliest date string to the user. + * Gets the list of Eam Cases and determines the earliest case creation + * date. Sets the label to display the earliest date string to the user. */ - private void setEarliestCaseDate() { - String dateStringDisplay = Bundle.DataContentViewerOtherCases_earliestCaseNotAvailable(); - + private void setEarliestCaseDate() { + String dateStringDisplay = Bundle.DataContentViewerOtherCases_earliestCaseNotAvailable(); + if (EamDb.isEnabled()) { LocalDateTime earliestDate = LocalDateTime.now(DateTimeZone.UTC); DateFormat datetimeFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss", Locale.US); @@ -472,15 +476,15 @@ public class DataContentViewerOtherCases extends JPanel implements DataContentVi EamDb dbManager = EamDb.getInstance(); List cases = dbManager.getCases(); for (CorrelationCase aCase : cases) { - LocalDateTime caseDate = LocalDateTime.fromDateFields(datetimeFormat.parse(aCase.getCreationDate())); - - if (caseDate.isBefore(earliestDate)) { + LocalDateTime caseDate = LocalDateTime.fromDateFields(datetimeFormat.parse(aCase.getCreationDate())); + + if (caseDate.isBefore(earliestDate)) { earliestDate = caseDate; dateStringDisplay = aCase.getCreationDate(); - } + } } - + } catch (EamDbException ex) { logger.log(Level.SEVERE, "Error getting list of cases from database.", ex); // NON-NLS } catch (ParseException ex) { @@ -492,10 +496,10 @@ public class DataContentViewerOtherCases extends JPanel implements DataContentVi } /** - * Query the central repo database (if enabled) and the case database to find all - * artifact instances correlated to the given central repository artifact. If the - * central repo is not enabled, this will only return files from the current case - * with matching MD5 hashes. + * Query the central repo database (if enabled) and the case database to + * find all artifact instances correlated to the given central repository + * artifact. If the central repo is not enabled, this will only return files + * from the current case with matching MD5 hashes. * * @param corAttr CorrelationAttribute to query for * @param dataSourceName Data source to filter results @@ -503,19 +507,19 @@ public class DataContentViewerOtherCases extends JPanel implements DataContentVi * * @return A collection of correlated artifact instances */ - private Map getCorrelatedInstances(CorrelationAttribute corAttr, String dataSourceName, String deviceId) { + private Map getCorrelatedInstances(CorrelationAttribute corAttr, String dataSourceName, String deviceId) { // @@@ Check exception try { final Case openCase = Case.getCurrentCase(); String caseUUID = openCase.getName(); - HashMap nodeDataMap = new HashMap<>(); + HashMap nodeDataMap = new HashMap<>(); if (EamDb.isEnabled()) { List instances = EamDb.getInstance().getArtifactInstancesByTypeValue(corAttr.getCorrelationType(), corAttr.getCorrelationValue()); - for (CorrelationAttributeInstance artifactInstance:instances) { - + for (CorrelationAttributeInstance artifactInstance : instances) { + // Only add the attribute if it isn't the object the user selected. // We consider it to be a different object if at least one of the following is true: // - the case UUID is different @@ -534,7 +538,7 @@ public class DataContentViewerOtherCases extends JPanel implements DataContentVi } } - if (corAttr.getCorrelationType().getDisplayName().equals("Files")) { + if (corAttr.getCorrelationType().getDisplayName().equals("Files")) { List caseDbFiles = getCaseDbMatches(corAttr, openCase); for (AbstractFile caseDbFile : caseDbFiles) { @@ -557,13 +561,17 @@ public class DataContentViewerOtherCases extends JPanel implements DataContentVi } /** - * Get all other abstract files in the current case with the same MD5 as the selected node. + * Get all other abstract files in the current case with the same MD5 as the + * selected node. + * * @param corAttr The CorrelationAttribute containing the MD5 to search for * @param openCase The current case + * * @return List of matching AbstractFile objects + * * @throws NoCurrentCaseException * @throws TskCoreException - * @throws EamDbException + * @throws EamDbException */ private List getCaseDbMatches(CorrelationAttribute corAttr, Case openCase) throws NoCurrentCaseException, TskCoreException, EamDbException { String md5 = corAttr.getCorrelationValue(); @@ -583,18 +591,18 @@ public class DataContentViewerOtherCases extends JPanel implements DataContentVi /** * Adds the file to the nodeDataMap map if it does not already exist - * - * @param autopsyCase + * + * @param autopsyCase * @param nodeDataMap * @param newFile * * @throws TskCoreException * @throws EamDbException */ - private void addOrUpdateNodeData(final Case autopsyCase, Map nodeDataMap, AbstractFile newFile) throws TskCoreException, EamDbException { - + private void addOrUpdateNodeData(final Case autopsyCase, Map nodeDataMap, AbstractFile newFile) throws TskCoreException, EamDbException { + OtherOccurrenceNodeInstanceData newNode = new OtherOccurrenceNodeInstanceData(newFile, autopsyCase); - + // If the caseDB object has a notable tag associated with it, update // the known status to BAD if (newNode.getKnown() != TskData.FileKnown.BAD) { @@ -610,7 +618,7 @@ public class DataContentViewerOtherCases extends JPanel implements DataContentVi // Make a key to see if the file is already in the map UniquePathKey uniquePathKey = new UniquePathKey(newNode); - + // If this node is already in the list, the only thing we need to do is // update the known status to BAD if the caseDB version had known status BAD. // Otherwise this is a new node so add the new node to the map. @@ -639,7 +647,7 @@ public class DataContentViewerOtherCases extends JPanel implements DataContentVi } else { return this.file != null && this.file.getSize() > 0 - && ((this.file.getMd5Hash() != null) && ( ! this.file.getMd5Hash().isEmpty())); + && ((this.file.getMd5Hash() != null) && (!this.file.getMd5Hash().isEmpty())); } } @@ -683,7 +691,7 @@ public class DataContentViewerOtherCases extends JPanel implements DataContentVi // get the attributes we can correlate on correlationAttributes.addAll(getCorrelationAttributesFromNode(node)); for (CorrelationAttribute corAttr : correlationAttributes) { - Map correlatedNodeDataMap = new HashMap<>(0); + Map correlatedNodeDataMap = new HashMap<>(0); // get correlation and reference set instances from DB correlatedNodeDataMap.putAll(getCorrelatedInstances(corAttr, dataSourceName, deviceId)); @@ -696,25 +704,40 @@ public class DataContentViewerOtherCases extends JPanel implements DataContentVi if (correlationAttributes.isEmpty()) { tableModel.addNodeData(new OtherOccurrenceNodeMessageData(Bundle.DataContentViewerOtherCases_table_noArtifacts())); - //DLG: Removing columns causes problems. Look into resizing columns. + setColumnWidthToText(0, Bundle.DataContentViewerOtherCases_table_noArtifacts()); } else if (0 == tableModel.getRowCount()) { tableModel.addNodeData(new OtherOccurrenceNodeMessageData(Bundle.DataContentViewerOtherCases_table_noResultsFound())); - //DLG: Removing columns causes problems. Look into resizing columns. + setColumnWidthToText(0, Bundle.DataContentViewerOtherCases_table_noResultsFound()); } else { setColumnWidths(); } setEarliestCaseDate(); } + /** + * Adjust a given column for the text provided. + * + * @param columnIndex The index of the column to adjust. + * @param text The text whose length will be used to adjust the + * column width. + */ + private void setColumnWidthToText(int columnIndex, String text) { + TableColumn column = otherCasesTable.getColumnModel().getColumn(columnIndex); + FontMetrics fontMetrics = otherCasesTable.getFontMetrics(otherCasesTable.getFont()); + int stringWidth = fontMetrics.stringWidth(text); + column.setMinWidth(stringWidth + CELL_TEXT_WIDTH_PADDING); + } + /** * Adjust column widths to their preferred values. */ private void setColumnWidths() { for (int idx = 0; idx < tableModel.getColumnCount(); idx++) { TableColumn column = otherCasesTable.getColumnModel().getColumn(idx); - int colWidth = tableModel.getColumnPreferredWidth(idx); - if (0 < colWidth) { - column.setPreferredWidth(colWidth); + column.setMinWidth(DEFAULT_MIN_CELL_WIDTH); + int columnWidth = tableModel.getColumnPreferredWidth(idx); + if (columnWidth > 0) { + column.setPreferredWidth(columnWidth); } } } @@ -742,7 +765,6 @@ public class DataContentViewerOtherCases extends JPanel implements DataContentVi earliestCaseLabel = new javax.swing.JLabel(); earliestCaseDate = new javax.swing.JLabel(); tableStatusPanel = new javax.swing.JPanel(); - tableStatusPanelLabel = new javax.swing.JLabel(); rightClickPopupMenu.addPopupMenuListener(new javax.swing.event.PopupMenuListener() { public void popupMenuCanceled(javax.swing.event.PopupMenuEvent evt) { @@ -804,8 +826,6 @@ public class DataContentViewerOtherCases extends JPanel implements DataContentVi .addGap(0, 16, Short.MAX_VALUE) ); - tableStatusPanelLabel.setForeground(new java.awt.Color(255, 0, 51)); - javax.swing.GroupLayout tableContainerPanelLayout = new javax.swing.GroupLayout(tableContainerPanel); tableContainerPanel.setLayout(tableContainerPanelLayout); tableContainerPanelLayout.setHorizontalGroup( @@ -818,20 +838,16 @@ public class DataContentViewerOtherCases extends JPanel implements DataContentVi .addComponent(earliestCaseLabel) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(earliestCaseDate) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(tableStatusPanelLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addContainerGap()) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); tableContainerPanelLayout.setVerticalGroup( tableContainerPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, tableContainerPanelLayout.createSequentialGroup() - .addComponent(tableScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 176, Short.MAX_VALUE) - .addGap(0, 0, 0) - .addGroup(tableContainerPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) - .addGroup(tableContainerPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(earliestCaseLabel) - .addComponent(earliestCaseDate)) - .addComponent(tableStatusPanelLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 16, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(tableScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 27, Short.MAX_VALUE) + .addGap(2, 2, 2) + .addGroup(tableContainerPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(earliestCaseLabel) + .addComponent(earliestCaseDate)) .addGap(0, 0, 0) .addComponent(tableStatusPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addGap(0, 0, 0)) @@ -850,7 +866,7 @@ public class DataContentViewerOtherCases extends JPanel implements DataContentVi .addGap(0, 483, Short.MAX_VALUE) .addGroup(otherCasesPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(otherCasesPanelLayout.createSequentialGroup() - .addComponent(tableContainerPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 483, Short.MAX_VALUE) + .addComponent(tableContainerPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 59, Short.MAX_VALUE) .addGap(0, 0, 0))) ); @@ -862,7 +878,7 @@ public class DataContentViewerOtherCases extends JPanel implements DataContentVi ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(otherCasesPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 483, Short.MAX_VALUE) + .addComponent(otherCasesPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 59, Short.MAX_VALUE) ); }// //GEN-END:initComponents @@ -898,7 +914,6 @@ public class DataContentViewerOtherCases extends JPanel implements DataContentVi private javax.swing.JPanel tableContainerPanel; private javax.swing.JScrollPane tableScrollPane; private javax.swing.JPanel tableStatusPanel; - private javax.swing.JLabel tableStatusPanelLabel; // End of variables declaration//GEN-END:variables /** @@ -925,9 +940,9 @@ public class DataContentViewerOtherCases extends JPanel implements DataContentVi @Override public boolean equals(Object other) { if (other instanceof UniquePathKey) { - UniquePathKey otherKey = (UniquePathKey)(other); - return ( Objects.equals(otherKey.dataSourceID, this.dataSourceID) - && Objects.equals(otherKey.filePath, this.filePath) + UniquePathKey otherKey = (UniquePathKey) (other); + return (Objects.equals(otherKey.dataSourceID, this.dataSourceID) + && Objects.equals(otherKey.filePath, this.filePath) && Objects.equals(otherKey.type, this.type)); } return false; diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/DataContentViewerOtherCasesTableModel.java b/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/DataContentViewerOtherCasesTableModel.java index de528e2d42..9ae79259c2 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/DataContentViewerOtherCasesTableModel.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/DataContentViewerOtherCasesTableModel.java @@ -107,71 +107,79 @@ public class DataContentViewerOtherCasesTableModel extends AbstractTableModel { return Bundle.DataContentViewerOtherCasesTableModel_noData(); } - return mapValueById(rowIdx, TableColumns.values()[colIdx]); + OtherOccurrenceNodeData nodeData = nodeDataList.get(rowIdx); + TableColumns columnId = TableColumns.values()[colIdx]; + if (nodeData instanceof OtherOccurrenceNodeMessageData) { + return mapNodeMessageData((OtherOccurrenceNodeMessageData) nodeData, columnId); + } + return mapNodeInstanceData((OtherOccurrenceNodeInstanceData) nodeData, columnId); + } + + /** + * Map a column ID to the value in that cell for node message data. + * + * @param nodeData The node message data. + * @param columnId The ID of the cell column. + * + * @return The value in the cell. + */ + private Object mapNodeMessageData(OtherOccurrenceNodeMessageData nodeData, TableColumns columnId) { + if (columnId == TableColumns.CASE_NAME) { + return nodeData.getDisplayMessage(); + } + return ""; + } + + /** + * Map a column ID to the value in that cell for node instance data. + * + * @param nodeData The node instance data. + * @param columnId The ID of the cell column. + * + * @return The value in the cell. + */ + private Object mapNodeInstanceData(OtherOccurrenceNodeInstanceData nodeData, TableColumns columnId) { + String value = Bundle.DataContentViewerOtherCasesTableModel_noData(); + + switch (columnId) { + case CASE_NAME: + if (null != nodeData.getCaseName()) { + value = nodeData.getCaseName(); + } + break; + case DEVICE: + if (null != nodeData.getDeviceID()) { + value = nodeData.getDeviceID(); + } + break; + case DATA_SOURCE: + if (null != nodeData.getDataSourceName()) { + value = nodeData.getDataSourceName(); + } + break; + case FILE_PATH: + value = nodeData.getFilePath(); + break; + case ATTRIBUTE: + value = nodeData.getType(); + break; + case VALUE: + value = nodeData.getValue(); + break; + case KNOWN: + value = nodeData.getKnown().getName(); + break; + case COMMENT: + value = nodeData.getComment(); + break; + } + return value; } Object getRow(int rowIdx) { return nodeDataList.get(rowIdx); } - /** - * Map a rowIdx and colId to the value in that cell. - * - * @param rowIdx Index of row to search - * @param colId ID of column to search - * - * @return value in the cell - */ - private Object mapValueById(int rowIdx, TableColumns colId) { - OtherOccurrenceNodeData nodeData = nodeDataList.get(rowIdx); - - if (nodeData instanceof OtherOccurrenceNodeMessageData) { - if (colId == TableColumns.CASE_NAME) { - OtherOccurrenceNodeMessageData messageData = (OtherOccurrenceNodeMessageData) nodeData; - return messageData.getDisplayMessage(); - } else { - return ""; - } - } - - OtherOccurrenceNodeInstanceData instanceData = (OtherOccurrenceNodeInstanceData) nodeData; - String value = Bundle.DataContentViewerOtherCasesTableModel_noData(); - - switch (colId) { - case CASE_NAME: - if (null != instanceData.getCaseName()) { - value = instanceData.getCaseName(); - } - break; - case DEVICE: - if (null != instanceData.getDeviceID()) { - value = instanceData.getDeviceID(); - } - break; - case DATA_SOURCE: - if (null != instanceData.getDataSourceName()) { - value = instanceData.getDataSourceName(); - } - break; - case FILE_PATH: - value = instanceData.getFilePath(); - break; - case ATTRIBUTE: - value = instanceData.getType(); - break; - case VALUE: - value = instanceData.getValue(); - break; - case KNOWN: - value = instanceData.getKnown().getName(); - break; - case COMMENT: - value = instanceData.getComment(); - break; - } - return value; - } - @Override public Class getColumnClass(int colIdx) { return String.class; From c16a41c0ed6b66bd6e08478ef80491e930966c56 Mon Sep 17 00:00:00 2001 From: Andrew Ziehl Date: Wed, 11 Jul 2018 10:45:03 -0700 Subject: [PATCH 124/287] Add way to get datasource using InstanceCallback CorrelationAttributeInstance. Bugfixes for logic. --- .../datamodel/AbstractSqlEamDb.java | 44 ++++++++++++++++++- .../centralrepository/datamodel/EamDb.java | 12 +++++ .../datamodel/SqliteEamDb.java | 19 ++++++++ ...ralRepositoryCaseFileInstanceMetadata.java | 30 ++++++++++++- .../EamDbAttributeInstancesAlgorithm.java | 6 ++- .../FileInstanceNodeGenerator.java | 22 +++------- .../SleuthkitCaseFileInstanceMetadata.java | 2 +- 7 files changed, 113 insertions(+), 22 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java index e148c39a02..4651264478 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java @@ -538,6 +538,48 @@ abstract class AbstractSqlEamDb implements EamDb { return eamDataSourceResult; } + + /** + * Retrieves Data Source details based on data source ID + * + * @param correlationCase the current CorrelationCase used for ensuring + * uniqueness of DataSource + * @param dataSourceId the data source ID number + * + * @return The data source + */ + @Override + public CorrelationDataSource getDataSourceById(CorrelationCase correlationCase, int dataSourceId) throws EamDbException { + if (correlationCase == null) { + throw new EamDbException("Correlation case is null"); + } + + Connection conn = connect(); + + CorrelationDataSource eamDataSourceResult = null; + PreparedStatement preparedStatement = null; + ResultSet resultSet = null; + + String sql = "SELECT * FROM data_sources WHERE id=? AND case_id=?"; // NON-NLS + + try { + preparedStatement = conn.prepareStatement(sql); + preparedStatement.setInt(1, dataSourceId); + preparedStatement.setInt(2, correlationCase.getID()); + resultSet = preparedStatement.executeQuery(); + if (resultSet.next()) { + eamDataSourceResult = getEamDataSourceFromResultSet(resultSet); + } + } catch (SQLException ex) { + throw new EamDbException("Error getting data source.", ex); // NON-NLS + } finally { + EamDbUtil.closeStatement(preparedStatement); + EamDbUtil.closeResultSet(resultSet); + EamDbUtil.closeConnection(conn); + } + + return eamDataSourceResult; + } /** * Return a list of data sources in the DB @@ -1841,7 +1883,7 @@ abstract class AbstractSqlEamDb implements EamDb { StringBuilder sql = new StringBuilder(); sql.append("select * from "); sql.append(tableName); - sql.append("WHERE id = ?"); + sql.append(" WHERE id = ?"); try { preparedStatement = conn.prepareStatement(sql.toString()); diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDb.java index 4e9b47d7ea..7fd81087e0 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDb.java @@ -209,6 +209,18 @@ public interface EamDb { */ CorrelationDataSource getDataSource(CorrelationCase correlationCase, String dataSourceDeviceId) throws EamDbException; + + /** + * Retrieves Data Source details based on data source ID + * + * @param correlationCase the current CorrelationCase used for ensuring + * uniqueness of DataSource + * @param dataSourceId the data source ID number + * + * @return The data source + */ + CorrelationDataSource getDataSourceById(CorrelationCase correlationCase, int dataSourceId) throws EamDbException; + /** * Retrieves data sources that are in DB * diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java index 2cac1ebfa8..b2ebad1b32 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java @@ -386,6 +386,25 @@ final class SqliteEamDb extends AbstractSqlEamDb { releaseSharedLock(); } } + + /** + * Retrieves Data Source details based on data source ID + * + * @param correlationCase the current CorrelationCase used for ensuring + * uniqueness of DataSource + * @param dataSourceId the data source ID number + * + * @return The data source + */ + @Override + public CorrelationDataSource getDataSourceById(CorrelationCase correlationCase, int dataSourceId) throws EamDbException { + try { + acquireSharedLock(); + return super.getDataSourceById(correlationCase, dataSourceId); + } finally { + releaseSharedLock(); + } + } /** * Return a list of data sources in the DB diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepositoryCaseFileInstanceMetadata.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepositoryCaseFileInstanceMetadata.java index c6ede2eabd..67df0c6221 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepositoryCaseFileInstanceMetadata.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepositoryCaseFileInstanceMetadata.java @@ -22,16 +22,23 @@ package org.sleuthkit.autopsy.commonfilesearch; import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.logging.Level; +import org.sleuthkit.autopsy.casemodule.Case; +import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttribute; import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance; +import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.datamodel.DisplayableItemNode; import org.sleuthkit.datamodel.AbstractFile; +import org.sleuthkit.datamodel.SleuthkitCase; +import org.sleuthkit.datamodel.TskCoreException; /** * Generates a DisplayableItmeNode using a CentralRepositoryFile. */ final public class CentralRepositoryCaseFileInstanceMetadata extends FileInstanceNodeGenerator { + private static final Logger LOGGER = Logger.getLogger(CentralRepositoryCaseFileInstanceMetadata.class.getName()); private final Integer crFileId; private CorrelationAttributeInstance tempAttributeInst; @@ -40,6 +47,26 @@ final public class CentralRepositoryCaseFileInstanceMetadata extends FileInstanc this.crFileId = attrInstId; } + + private static AbstractFile loadFileFromSleuthkitCase(String path) { + + Case currentCase; + try { + currentCase = Case.getCurrentCaseThrows(); + + SleuthkitCase tskDb = currentCase.getSleuthkitCase(); + String[] splitPath = path.split("/"); + String fileName = splitPath[splitPath.length -1]; + AbstractFile abstractFile = tskDb.findAllFilesWhere(String.format("lower(name) = '%s'", fileName)).get(0); // TODO workaround where we don't need AbstractFile? + + return abstractFile; + + } catch (TskCoreException | NoCurrentCaseException ex) { + LOGGER.log(Level.SEVERE, String.format("Unable to find AbstractFile for record with filePath: %s. Node not created.", new Object[]{path}), ex); + return null; + } + } + @Override public DisplayableItemNode generateNode() { if (tempAttributeInst != null) { @@ -53,11 +80,10 @@ final public class CentralRepositoryCaseFileInstanceMetadata extends FileInstanc EamDbAttributeInstancesAlgorithm eamDbAttrInst = new EamDbAttributeInstancesAlgorithm(); CorrelationAttribute corrAttr = eamDbAttrInst.processCorrelationCaseSingleAttribute(crFileId); //TODO which do we want List attrInstNodeList = new ArrayList<>(0); - this.abstractFileReference = Long.getLong(corrAttr.getCorrelationValue()); for (CorrelationAttributeInstance attrInst : corrAttr.getInstances()) { tempAttributeInst = attrInst; - DisplayableItemNode generatedInstNode = generateNode(); + DisplayableItemNode generatedInstNode = new CentralRepositoryFileInstanceNode(tempAttributeInst, loadFileFromSleuthkitCase(tempAttributeInst.getFilePath())); if (generatedInstNode != null) { attrInstNodeList.add(generatedInstNode); } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbAttributeInstancesAlgorithm.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbAttributeInstancesAlgorithm.java index 9f6365b05b..fa6baaa34d 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbAttributeInstancesAlgorithm.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbAttributeInstancesAlgorithm.java @@ -28,6 +28,7 @@ import org.openide.util.Exceptions; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttribute; 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.datamodel.InstanceTableCallback; @@ -132,10 +133,11 @@ final class EamDbAttributeInstancesAlgorithm { CorrelationAttribute.Type fileType = DbManager.getCorrelationTypeById(CorrelationAttribute.FILES_TYPE_ID); while (resultSet.next()) { - CorrelationCase correlationCase = DbManager.getCaseByUUID(String.valueOf(InstanceTableCallback.getCaseId(resultSet))); + CorrelationCase correlationCase = DbManager.getCaseById(InstanceTableCallback.getCaseId(resultSet)); + CorrelationDataSource dataSource = DbManager.getDataSourceById(correlationCase, InstanceTableCallback.getDataSourceId(resultSet)); correlationAttribute = DbManager.getCorrelationAttribute(fileType, correlationCase, - DbManager.getDataSource(correlationCase, String.valueOf(InstanceTableCallback.getDataSourceId(resultSet))), + dataSource, InstanceTableCallback.getValue(resultSet), InstanceTableCallback.getFilePath(resultSet)); diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/FileInstanceNodeGenerator.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/FileInstanceNodeGenerator.java index d5fdf2ba37..91e3a9aa97 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/FileInstanceNodeGenerator.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/FileInstanceNodeGenerator.java @@ -50,10 +50,10 @@ public abstract class FileInstanceNodeGenerator { } public FileInstanceNodeGenerator(Map cachedFiles) { - this.abstractFileReference = null; + this.abstractFileReference = -1L; cachedFiles = cachedFiles; - this.caseName = null; - this.dataSource = null; + this.caseName = ""; + this.dataSource = ""; } /** @@ -66,11 +66,11 @@ public abstract class FileInstanceNodeGenerator { * implementations of this object */ protected AbstractFile lookupOrCreateAbstractFile() { - if (this.cachedFiles.containsKey(this.abstractFileReference)) { - return this.cachedFiles.get(this.abstractFileReference); + if (cachedFiles.containsKey(this.abstractFileReference)) { + return cachedFiles.get(this.abstractFileReference); } else { AbstractFile file = FileInstanceNodeGenerator.loadFileFromSleuthkitCase(this.abstractFileReference); - this.cachedFiles.put(this.abstractFileReference, file); + cachedFiles.put(this.abstractFileReference, file); return file; } } @@ -93,16 +93,6 @@ public abstract class FileInstanceNodeGenerator { } } - private static AbstractFile lookupOrCreateAbstractFile(Long objectId, Map cachedFiles) { - if (cachedFiles.containsKey(objectId)) { - return cachedFiles.get(objectId); - } else { - AbstractFile file = FileInstanceNodeGenerator.loadFileFromSleuthkitCase(objectId); - cachedFiles.put(objectId, file); - return file; - } - } - /** * Create a node which is a child of the MD5Node, to be used to display a * row in the tree table diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/SleuthkitCaseFileInstanceMetadata.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/SleuthkitCaseFileInstanceMetadata.java index 8b9370d703..ef9b9e813a 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/SleuthkitCaseFileInstanceMetadata.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/SleuthkitCaseFileInstanceMetadata.java @@ -47,6 +47,6 @@ final public class SleuthkitCaseFileInstanceMetadata extends FileInstanceNodeGen @Override public DisplayableItemNode[] generateNodes() { - return Arrays.asList(generateNode()).toArray(new DisplayableItemNode[1]); + return Arrays.asList(new SleuthkitCaseFileInstanceNode(this.lookupOrCreateAbstractFile(), this.getCaseName(), this.getDataSource())).toArray(new DisplayableItemNode[1]); } } From bea41995406be5cb3d7b2f477fafb4e97d4c146a Mon Sep 17 00:00:00 2001 From: Andrew Ziehl Date: Wed, 11 Jul 2018 20:50:29 -0700 Subject: [PATCH 125/287] Add Single Case logic. Enable Other Occurances tab for CR common files results. --- .../datamodel/AbstractSqlEamDb.java | 58 ++++++++++++++++++- .../centralrepository/datamodel/EamDb.java | 13 ++++- .../datamodel/SqliteEamDb.java | 19 ++++++ .../AllDataSourcesCommonFilesAlgorithm.java | 2 +- .../CentralRepositoryFileInstanceNode.java | 3 +- .../EamDbAttributeInstancesAlgorithm.java | 16 +++++ .../EamDbCommonFilesAlgorithm.java | 26 ++++----- .../SingleCaseEamDbCommonFilesAlgorithm.java | 2 +- 8 files changed, 116 insertions(+), 23 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java index 4651264478..ac286aa569 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java @@ -1880,7 +1880,7 @@ abstract class AbstractSqlEamDb implements EamDb { PreparedStatement preparedStatement = null; ResultSet resultSet = null; String tableName = EamDbUtil.correlationTypeToInstanceTableName(type); - StringBuilder sql = new StringBuilder(); + StringBuilder sql = new StringBuilder(3); sql.append("select * from "); sql.append(tableName); sql.append(" WHERE id = ?"); @@ -1925,7 +1925,7 @@ abstract class AbstractSqlEamDb implements EamDb { PreparedStatement preparedStatement = null; ResultSet resultSet = null; String tableName = EamDbUtil.correlationTypeToInstanceTableName(type); - StringBuilder sql = new StringBuilder(); + StringBuilder sql = new StringBuilder(7); sql.append("SELECT id, value, case_id FROM "); sql.append(tableName); sql.append(" WHERE value IN (SELECT value FROM "); // TODO should this select * so any field is available? @@ -1949,6 +1949,60 @@ abstract class AbstractSqlEamDb implements EamDb { } } + /** + * Process the Artifact instance in the EamDb + * + * @param type EamArtifact.Type to search for + * @param correlationCase CorrelationCase to filter by + * @param singleCase Single Case to filter by + * @param instanceTableCallback callback to process the instance + * @throws EamDbException + */ + @Override + public void processSingleCaseInstancesTable(CorrelationAttribute.Type type, CorrelationCase correlationCase, CorrelationCase singleCase,InstanceTableCallback instanceTableCallback) throws EamDbException { + if (type == null) { + throw new EamDbException("Correlation type is null"); + } + + if (instanceTableCallback == null) { + throw new EamDbException("Callback interface is null"); + } + + if(correlationCase == null) { + throw new EamDbException("Correlation Case is null"); + } + + Connection conn = connect(); + PreparedStatement preparedStatement = null; + ResultSet resultSet = null; + String tableName = EamDbUtil.correlationTypeToInstanceTableName(type); + StringBuilder sql = new StringBuilder(8); + sql.append("SELECT id, value, case_id FROM "); + sql.append(tableName); + sql.append(" WHERE value IN (SELECT value FROM "); // TODO should this select * so any field is available? + sql.append(tableName); + sql.append(" WHERE value IN (SELECT value FROM "); + sql.append(tableName); + sql.append(" WHERE case_id=? AND (known_status !=? OR known_status IS NULL) GROUP BY value)"); + sql.append(" AND (case_id=? OR case_id=?) GROUP BY value HAVING COUNT(DISTINCT case_id) > 1) ORDER BY value"); + + try { + preparedStatement = conn.prepareStatement(sql.toString()); + preparedStatement.setInt(1, correlationCase.getID()); + preparedStatement.setByte(2, TskData.FileKnown.KNOWN.getFileKnownValue()); + preparedStatement.setInt(3, correlationCase.getID()); + preparedStatement.setInt(4, singleCase.getID()); + resultSet = preparedStatement.executeQuery(); + instanceTableCallback.process(resultSet); + } catch (SQLException ex) { + throw new EamDbException("Error getting all artifact instances from instances table", ex); + } finally { + EamDbUtil.closeStatement(preparedStatement); + EamDbUtil.closeResultSet(resultSet); + EamDbUtil.closeConnection(conn); + } + } + @Override public EamOrganization newOrganization(EamOrganization eamOrg) throws EamDbException { diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDb.java index 7fd81087e0..f9f37a86f0 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDb.java @@ -19,7 +19,6 @@ package org.sleuthkit.autopsy.centralrepository.datamodel; import java.sql.SQLException; -import java.util.Collection; import java.util.List; import java.util.Set; import org.sleuthkit.datamodel.TskData; @@ -725,4 +724,16 @@ public interface EamDb { * @throws EamDbException */ void processCaseInstancesTable(CorrelationAttribute.Type type, CorrelationCase correlationCase, InstanceTableCallback instanceTableCallback) throws EamDbException; + + /** + * Process the Artifact instance in the EamDb + * + * @param type EamArtifact.Type to search for + * @param correlationCase CorrelationCase to filter by + * @param singleCase Single Case to filter by + * @param instanceTableCallback callback to process the instance + * @throws EamDbException + */ + void processSingleCaseInstancesTable(CorrelationAttribute.Type type, CorrelationCase correlationCase, CorrelationCase singleCase,InstanceTableCallback instanceTableCallback) throws EamDbException; + } diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java index b2ebad1b32..a9f930fd0c 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java @@ -772,6 +772,25 @@ final class SqliteEamDb extends AbstractSqlEamDb { releaseSharedLock(); } } + + /** + * Process the Artifact instance in the EamDb + * + * @param type EamArtifact.Type to search for + * @param correlationCase CorrelationCase to filter by + * @param singleCase Single Case to filter by + * @param instanceTableCallback callback to process the instance + * @throws EamDbException + */ + @Override + public void processSingleCaseInstancesTable(CorrelationAttribute.Type type, CorrelationCase correlationCase, CorrelationCase singleCase,InstanceTableCallback instanceTableCallback) throws EamDbException { + try { + acquireSharedLock(); + super.processSingleCaseInstancesTable(type, correlationCase, singleCase, instanceTableCallback); + } finally { + releaseSharedLock(); + } + } /** * Check whether a reference set with the given name/version is in the diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllDataSourcesCommonFilesAlgorithm.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllDataSourcesCommonFilesAlgorithm.java index 111cf4aed9..a53572d093 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllDataSourcesCommonFilesAlgorithm.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllDataSourcesCommonFilesAlgorithm.java @@ -27,7 +27,7 @@ import org.sleuthkit.datamodel.TskData.FileKnown; */ final public class AllDataSourcesCommonFilesAlgorithm extends CommonFilesMetadataBuilder { - private static final String WHERE_CLAUSE = "%s md5 in (select md5 from tsk_files where (known != "+ FileKnown.KNOWN.getFileKnownValue() + " OR known IS NULL)%s GROUP BY md5 HAVING COUNT(DISTINCT data_source_obj_id) > 1) order by md5"; //NON-NLS + private static final String WHERE_CLAUSE = "%s md5 in (select md5 from tsk_files where (known != "+ FileKnown.KNOWN.getFileKnownValue() + " OR known IS NULL)%s GROUP BY md5 HAVING COUNT(DISTINCT data_source_obj_id) > 1) order by md5"; //NON-NLS /** * Implements the algorithm for getting common files across all data diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepositoryFileInstanceNode.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepositoryFileInstanceNode.java index 056c489431..d85d5bf644 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepositoryFileInstanceNode.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepositoryFileInstanceNode.java @@ -51,8 +51,7 @@ public class CentralRepositoryFileInstanceNode extends DisplayableItemNode { private final AbstractFile md5Reference; public CentralRepositoryFileInstanceNode(CorrelationAttributeInstance content, AbstractFile md5Reference) { - super(Children.LEAF, Lookups.fixed(content)); // TODO, using md5Reference enables Other Occurances..but for the incorrect file path - + super(Children.LEAF, Lookups.fixed(md5Reference)); // Using md5Reference enables Other Occurances..but for the current file path this.crFile = content; this.setDisplayName(new File(this.crFile.getFilePath()).getName()); this.md5Reference = md5Reference; diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbAttributeInstancesAlgorithm.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbAttributeInstancesAlgorithm.java index fa6baaa34d..4fcf89d3cd 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbAttributeInstancesAlgorithm.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbAttributeInstancesAlgorithm.java @@ -76,6 +76,22 @@ final class EamDbAttributeInstancesAlgorithm { logger.log(Level.SEVERE, "Error accessing EamDb processing CaseInstancesTable.", ex); } + } + + void processSingleCaseCorrelationCaseAttributeValues(Case currentCase, CorrelationCase singleCase) { + + try { + EamDbAttributeInstancesCallback instancetableCallback = new EamDbAttributeInstancesCallback(); + EamDb DbManager = EamDb.getInstance(); + CorrelationAttribute.Type fileType = DbManager.getCorrelationTypeById(CorrelationAttribute.FILES_TYPE_ID); + DbManager.processSingleCaseInstancesTable(fileType, DbManager.getCase(currentCase), singleCase, instancetableCallback); + + intercaseCommonValuesMap.putAll(instancetableCallback.getCorrelationIdValueMap()); + intercaseCommonCasesMap.putAll(instancetableCallback.getCorrelationIdToCaseMap()); + } catch (EamDbException ex) { + logger.log(Level.SEVERE, "Error accessing EamDb processing CaseInstancesTable.", ex); + } + } Map getIntercaseCommonValuesMap() { diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbCommonFilesAlgorithm.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbCommonFilesAlgorithm.java index 39db0fcf7b..8b34e6dfad 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbCommonFilesAlgorithm.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbCommonFilesAlgorithm.java @@ -69,26 +69,24 @@ public abstract class EamDbCommonFilesAlgorithm extends CommonFilesMetadataBuild protected CommonFilesMetadata findFiles(CorrelationCase correlationCase) throws TskCoreException, NoCurrentCaseException, SQLException, EamDbException, Exception { - //TODO separate if case for correlationCase Map> interCaseCommonFiles = new HashMap<>(); - // Need to include current Cases results for specific case comparison EamDbAttributeInstancesAlgorithm eamDbAttrInst = new EamDbAttributeInstancesAlgorithm(); - eamDbAttrInst.processCorrelationCaseAttributeValues(Case.getCurrentCase()); + if(correlationCase != null) { + // Filter by matches both within current case and a specific case. + // TODO, move to Single class + eamDbAttrInst.processSingleCaseCorrelationCaseAttributeValues(Case.getCurrentCase(), correlationCase); + } else { + // Filter by matches of current case md5s. + eamDbAttrInst.processCorrelationCaseAttributeValues(Case.getCurrentCase()); + } interCaseCommonFiles = gatherIntercaseResults(eamDbAttrInst.getIntercaseCommonValuesMap(), eamDbAttrInst.getIntercaseCommonCasesMap()); + //TODO, only use to filter mimeType in memory against currentCase against, unless mimeType is added to CR // Builds intercase-only matches metadata return new CommonFilesMetadata(interCaseCommonFiles); } - //TODO, only use to filter mimeType in memory against currentCase against, unless mimeType is added to CR -// private Map> getMetadataForCurrentCase() throws NoCurrentCaseException, TskCoreException, SQLException, Exception { -// //we need the list of files in the present case so we can compare against the central repo -// CommonFilesMetadata metaData = super.findFiles(); -// Map> commonFiles = metaData.getMetadata(); -// return commonFiles; -// } - /** * @param artifactInstances all 'common files' in central repo * @param commonFiles matches must ultimately have appeared in this collection @@ -106,16 +104,12 @@ public abstract class EamDbCommonFilesAlgorithm extends CommonFilesMetadataBuild } try { - // TODO, pass proper Case int caseId = commonFileCases.get(commonAttrId); CorrelationCase autopsyCrCase = dbManager.getCaseById(caseId); final String correlationCaseDisplayName = autopsyCrCase.getDisplayName(); // we don't *have* all the information for the rows in the CR, // so we need to consult the present case via the SleuthkitCase object - - - - + // Later, when the FileInstanceNodde is built. Therefore, build node generators for now. if(interCaseCommonFiles.containsKey(md5)) { //Add to intercase metaData diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/SingleCaseEamDbCommonFilesAlgorithm.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/SingleCaseEamDbCommonFilesAlgorithm.java index 8aad5414a8..339d0846a1 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/SingleCaseEamDbCommonFilesAlgorithm.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/SingleCaseEamDbCommonFilesAlgorithm.java @@ -28,7 +28,7 @@ import org.sleuthkit.datamodel.TskCoreException; /** * - * TODO + * */ public class SingleCaseEamDbCommonFilesAlgorithm extends EamDbCommonFilesAlgorithm { From 8f11dcffd31fb1e76e4e2cb4082de61616be4978 Mon Sep 17 00:00:00 2001 From: Andrew Ziehl Date: Wed, 11 Jul 2018 21:09:27 -0700 Subject: [PATCH 126/287] Cleanup --- .../AllCasesEamDbCommonFilesAlgorithm.java | 5 ++--- .../commonfilesearch/CommonFilesPanel.java | 16 ++++++++-------- .../EamDbCommonFilesAlgorithm.java | 6 ++---- .../SingleCaseEamDbCommonFilesAlgorithm.java | 7 +++---- 4 files changed, 15 insertions(+), 19 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllCasesEamDbCommonFilesAlgorithm.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllCasesEamDbCommonFilesAlgorithm.java index 8aad1eb1bb..251ee3e454 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllCasesEamDbCommonFilesAlgorithm.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllCasesEamDbCommonFilesAlgorithm.java @@ -19,7 +19,6 @@ */ package org.sleuthkit.autopsy.commonfilesearch; -import java.util.Map; import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException; /** @@ -28,7 +27,7 @@ import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException; */ public class AllCasesEamDbCommonFilesAlgorithm extends EamDbCommonFilesAlgorithm { - public AllCasesEamDbCommonFilesAlgorithm(Map dataSourceIdMap, boolean filterByMediaMimeType, boolean filterByDocMimeType) throws EamDbException { - super(dataSourceIdMap, filterByMediaMimeType, filterByDocMimeType); + public AllCasesEamDbCommonFilesAlgorithm(boolean filterByMediaMimeType, boolean filterByDocMimeType) throws EamDbException { + super(filterByMediaMimeType, filterByDocMimeType); } } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java index ce33631c16..92df647941 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java @@ -126,7 +126,7 @@ public final class CommonFilesPanel extends javax.swing.JPanel { private void setTitleForSingleSource(Long dataSourceId) { final String CommonFilesPanel_search_results_titleSingle = Bundle.CommonFilesPanel_search_results_titleSingle(); - final Object[] dataSourceName = new Object[]{CommonFilesPanel.this.intraCasePanel.getDataSourceMap().get(dataSourceId)}; + final Object[] dataSourceName = new Object[]{intraCasePanel.getDataSourceMap().get(dataSourceId)}; this.tabTitle = String.format(CommonFilesPanel_search_results_titleSingle, dataSourceName); } @@ -138,8 +138,8 @@ public final class CommonFilesPanel extends javax.swing.JPanel { progress.start(); progress.switchToIndeterminate(); - Long dataSourceId = CommonFilesPanel.this.intraCasePanel.getSelectedDataSourceId(); - Integer caseId = CommonFilesPanel.this.interCasePanel.getSelectedCaseId(); + Long dataSourceId = intraCasePanel.getSelectedDataSourceId(); + Integer caseId = interCasePanel.getSelectedCaseId(); CommonFilesMetadataBuilder builder; CommonFilesMetadata metadata; @@ -158,23 +158,23 @@ public final class CommonFilesPanel extends javax.swing.JPanel { if (CommonFilesPanel.this.interCaseRadio.isSelected()) { if (caseId == InterCasePanel.NO_CASE_SELECTED) { - builder = new AllCasesEamDbCommonFilesAlgorithm(CommonFilesPanel.this.intraCasePanel.getDataSourceMap(), filterByMedia, filterByDocuments); + builder = new AllCasesEamDbCommonFilesAlgorithm(filterByMedia, filterByDocuments); } else { - builder = new SingleCaseEamDbCommonFilesAlgorithm(caseId, CommonFilesPanel.this.intraCasePanel.getDataSourceMap(), filterByMedia, filterByDocuments); + builder = new SingleCaseEamDbCommonFilesAlgorithm(caseId, filterByMedia, filterByDocuments); } } else { if (dataSourceId == CommonFilesPanel.NO_DATA_SOURCE_SELECTED) { - builder = new AllDataSourcesCommonFilesAlgorithm(CommonFilesPanel.this.intraCasePanel.getDataSourceMap(), filterByMedia, filterByDocuments); + builder = new AllDataSourcesCommonFilesAlgorithm(intraCasePanel.getDataSourceMap(), filterByMedia, filterByDocuments); setTitleForAllDataSources(); } else { - builder = new SingleDataSource(dataSourceId, CommonFilesPanel.this.intraCasePanel.getDataSourceMap(), filterByMedia, filterByDocuments); + builder = new SingleDataSource(dataSourceId, intraCasePanel.getDataSourceMap(), filterByMedia, filterByDocuments); setTitleForSingleSource(dataSourceId); } } - //TODO set title from one method rathe than two (or more) overloads + //TODO set title from one method rather than two (or more) overloads metadata = builder.findFiles(); this.tabTitle = builder.buildTabTitle(); diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbCommonFilesAlgorithm.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbCommonFilesAlgorithm.java index 8b34e6dfad..e292acb0b0 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbCommonFilesAlgorithm.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbCommonFilesAlgorithm.java @@ -48,7 +48,6 @@ public abstract class EamDbCommonFilesAlgorithm extends CommonFilesMetadataBuild * Implements the algorithm for getting common files across all data sources * and all cases. Can filter on mime types conjoined by logical AND. * - * @param dataSourceIdMap a map of obj_id to datasource name * @param filterByMediaMimeType match only on files whose mime types can be * broadly categorized as media types * @param filterByDocMimeType match only on files whose mime types can be @@ -56,9 +55,8 @@ public abstract class EamDbCommonFilesAlgorithm extends CommonFilesMetadataBuild * * @throws EamDbException */ - EamDbCommonFilesAlgorithm(Map dataSourceIdMap, boolean filterByMediaMimeType, boolean filterByDocMimeType) throws EamDbException { - super(dataSourceIdMap, filterByMediaMimeType, filterByDocMimeType); - + EamDbCommonFilesAlgorithm(boolean filterByMediaMimeType, boolean filterByDocMimeType) throws EamDbException { + super(new HashMap(), filterByMediaMimeType, filterByDocMimeType); // Pass empty datasources. Unused for intercase matches. dbManager = EamDb.getInstance(); } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/SingleCaseEamDbCommonFilesAlgorithm.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/SingleCaseEamDbCommonFilesAlgorithm.java index 339d0846a1..622057e06c 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/SingleCaseEamDbCommonFilesAlgorithm.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/SingleCaseEamDbCommonFilesAlgorithm.java @@ -20,7 +20,6 @@ package org.sleuthkit.autopsy.commonfilesearch; import java.sql.SQLException; -import java.util.Map; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationCase; import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException; @@ -37,13 +36,12 @@ public class SingleCaseEamDbCommonFilesAlgorithm extends EamDbCommonFilesAlgorit /** * * @param correlationCaseId - * @param dataSourceIdMap * @param filterByMediaMimeType * @param filterByDocMimeType * @throws EamDbException */ - public SingleCaseEamDbCommonFilesAlgorithm(int correlationCaseId, Map dataSourceIdMap, boolean filterByMediaMimeType, boolean filterByDocMimeType) throws EamDbException { - super(dataSourceIdMap, filterByMediaMimeType, filterByDocMimeType); + public SingleCaseEamDbCommonFilesAlgorithm(int correlationCaseId, boolean filterByMediaMimeType, boolean filterByDocMimeType) throws EamDbException { + super(filterByMediaMimeType, filterByDocMimeType); this.corrleationCaseId = correlationCaseId; } @@ -67,4 +65,5 @@ public class SingleCaseEamDbCommonFilesAlgorithm extends EamDbCommonFilesAlgorit return this.findFiles(cCase); } + } From 2fa8ffa4fb7c026704ad290d1a9d4d84a6b16c92 Mon Sep 17 00:00:00 2001 From: Andrew Ziehl Date: Thu, 12 Jul 2018 07:51:45 -0700 Subject: [PATCH 127/287] disable other occurances --- .../commonfilesearch/CentralRepositoryFileInstanceNode.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepositoryFileInstanceNode.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepositoryFileInstanceNode.java index d85d5bf644..1f72b4eafa 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepositoryFileInstanceNode.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepositoryFileInstanceNode.java @@ -51,7 +51,7 @@ public class CentralRepositoryFileInstanceNode extends DisplayableItemNode { private final AbstractFile md5Reference; public CentralRepositoryFileInstanceNode(CorrelationAttributeInstance content, AbstractFile md5Reference) { - super(Children.LEAF, Lookups.fixed(md5Reference)); // Using md5Reference enables Other Occurances..but for the current file path + super(Children.LEAF, Lookups.fixed(content)); // Using md5Reference enables Other Occurances, but for the current file path this.crFile = content; this.setDisplayName(new File(this.crFile.getFilePath()).getName()); this.md5Reference = md5Reference; From 2b33110dcb7ee5baeab15ada42af377b075e75e3 Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Mon, 16 Jul 2018 14:10:38 -0600 Subject: [PATCH 128/287] cleaned up --- .../AllCasesEamDbCommonFilesAlgorithm.java | 26 +++- .../AllDataSourcesCommonFilesAlgorithm.java | 2 +- .../commonfilesearch/CommonFilesPanel.java | 4 +- .../ICommonFilesMetadataBuilder.java | 126 ++++++++++++++++++ ... InterCaseCommonFilesMetadataBuilder.java} | 47 +------ ... IntraCaseCommonFilesMetadataBuilder.java} | 99 +------------- .../SingleCaseEamDbCommonFilesAlgorithm.java | 24 +++- ...SingleDataSourceCommonFilesAlgorithm.java} | 8 +- ...stedWithHashAndFileTypeInterCaseTests.java | 4 +- ...stedWithHashAndFileTypeIntraCaseTests.java | 22 +-- ...IngestedWithNoFileTypesIntraCaseTests.java | 8 +- .../NoCentralRepoEnabledInterCaseTests.java | 4 +- .../UningestedCasesIntraCaseTests.java | 8 +- 13 files changed, 212 insertions(+), 170 deletions(-) create mode 100644 Core/src/org/sleuthkit/autopsy/commonfilesearch/ICommonFilesMetadataBuilder.java rename Core/src/org/sleuthkit/autopsy/commonfilesearch/{EamDbCommonFilesAlgorithm.java => InterCaseCommonFilesMetadataBuilder.java} (70%) rename Core/src/org/sleuthkit/autopsy/commonfilesearch/{CommonFilesMetadataBuilder.java => IntraCaseCommonFilesMetadataBuilder.java} (63%) rename Core/src/org/sleuthkit/autopsy/commonfilesearch/{SingleDataSource.java => SingleDataSourceCommonFilesAlgorithm.java} (86%) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllCasesEamDbCommonFilesAlgorithm.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllCasesEamDbCommonFilesAlgorithm.java index 251ee3e454..63c5525097 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllCasesEamDbCommonFilesAlgorithm.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllCasesEamDbCommonFilesAlgorithm.java @@ -19,15 +19,39 @@ */ package org.sleuthkit.autopsy.commonfilesearch; +import java.sql.SQLException; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import org.sleuthkit.autopsy.casemodule.Case; +import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException; +import org.sleuthkit.datamodel.TskCoreException; /** * Algorithm which finds files anywhere in the Central Repo which also occur in * present case. */ -public class AllCasesEamDbCommonFilesAlgorithm extends EamDbCommonFilesAlgorithm { +public class AllCasesEamDbCommonFilesAlgorithm extends InterCaseCommonFilesMetadataBuilder { public AllCasesEamDbCommonFilesAlgorithm(boolean filterByMediaMimeType, boolean filterByDocMimeType) throws EamDbException { super(filterByMediaMimeType, filterByDocMimeType); } + + @Override + public CommonFilesMetadata findFiles() throws TskCoreException, NoCurrentCaseException, SQLException, EamDbException, Exception { + Map> interCaseCommonFiles = new HashMap<>(); + + EamDbAttributeInstancesAlgorithm eamDbAttrInst = new EamDbAttributeInstancesAlgorithm(); + eamDbAttrInst.processCorrelationCaseAttributeValues(Case.getCurrentCase()); + interCaseCommonFiles = gatherIntercaseResults(eamDbAttrInst.getIntercaseCommonValuesMap(), eamDbAttrInst.getIntercaseCommonCasesMap()); + + return new CommonFilesMetadata(interCaseCommonFiles); + } + + @Override + String buildCategorySelectionString() { + //TODO + return ""; + } } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllDataSourcesCommonFilesAlgorithm.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllDataSourcesCommonFilesAlgorithm.java index a53572d093..931c307453 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllDataSourcesCommonFilesAlgorithm.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllDataSourcesCommonFilesAlgorithm.java @@ -25,7 +25,7 @@ import org.sleuthkit.datamodel.TskData.FileKnown; /** * Provides logic for selecting common files from all data sources. */ -final public class AllDataSourcesCommonFilesAlgorithm extends CommonFilesMetadataBuilder { +final public class AllDataSourcesCommonFilesAlgorithm extends IntraCaseCommonFilesMetadataBuilder { private static final String WHERE_CLAUSE = "%s md5 in (select md5 from tsk_files where (known != "+ FileKnown.KNOWN.getFileKnownValue() + " OR known IS NULL)%s GROUP BY md5 HAVING COUNT(DISTINCT data_source_obj_id) > 1) order by md5"; //NON-NLS diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java index 92df647941..a5ea73065e 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java @@ -141,7 +141,7 @@ public final class CommonFilesPanel extends javax.swing.JPanel { Long dataSourceId = intraCasePanel.getSelectedDataSourceId(); Integer caseId = interCasePanel.getSelectedCaseId(); - CommonFilesMetadataBuilder builder; + IntraCaseCommonFilesMetadataBuilder builder; CommonFilesMetadata metadata; boolean filterByMedia = false; @@ -168,7 +168,7 @@ public final class CommonFilesPanel extends javax.swing.JPanel { setTitleForAllDataSources(); } else { - builder = new SingleDataSource(dataSourceId, intraCasePanel.getDataSourceMap(), filterByMedia, filterByDocuments); + builder = new SingleDataSourceCommonFilesAlgorithm(dataSourceId, intraCasePanel.getDataSourceMap(), filterByMedia, filterByDocuments); setTitleForSingleSource(dataSourceId); } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/ICommonFilesMetadataBuilder.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/ICommonFilesMetadataBuilder.java new file mode 100644 index 0000000000..19a41f5652 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/ICommonFilesMetadataBuilder.java @@ -0,0 +1,126 @@ +/* + * + * Autopsy Forensic Browser + * + * Copyright 2018 Basis Technology Corp. + * Contact: carrier sleuthkit 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.commonfilesearch; + +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TreeMap; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; +import org.sleuthkit.datamodel.TskCoreException; + +/** + * + * @author bsweeney + */ +abstract class ICommonFilesMetadataBuilder { + + abstract CommonFilesMetadata findFiles() throws TskCoreException, NoCurrentCaseException, SQLException, Exception; + + abstract String buildTabTitle(); + + abstract String buildCategorySelectionString(); + + static Map> collateMatchesByNumberOfInstances(Map commonFiles) { + //collate matches by number of matching instances - doing this in sql doesnt seem efficient + Map> instanceCollatedCommonFiles = new TreeMap<>(); + for(Md5Metadata md5Metadata : commonFiles.values()){ + Integer size = md5Metadata.size(); + + if(instanceCollatedCommonFiles.containsKey(size)){ + instanceCollatedCommonFiles.get(size).add(md5Metadata); + } else { + ArrayList value = new ArrayList<>(); + value.add(md5Metadata); + instanceCollatedCommonFiles.put(size, value); + } + } + return instanceCollatedCommonFiles; + } + + /* + * The set of the MIME types that will be checked for extension mismatches + * when checkType is ONLY_MEDIA. + * ".jpg", ".jpeg", ".png", ".psd", ".nef", ".tiff", ".bmp", ".tec" + * ".aaf", ".3gp", ".asf", ".avi", ".m1v", ".m2v", //NON-NLS + * ".m4v", ".mp4", ".mov", ".mpeg", ".mpg", ".mpe", ".mp4", ".rm", ".wmv", ".mpv", ".flv", ".swf" + */ + static final Set MEDIA_PICS_VIDEO_MIME_TYPES = Stream.of( + "image/bmp", //NON-NLS + "image/gif", //NON-NLS + "image/jpeg", //NON-NLS + "image/png", //NON-NLS + "image/tiff", //NON-NLS + "image/vnd.adobe.photoshop", //NON-NLS + "image/x-raw-nikon", //NON-NLS + "image/x-ms-bmp", //NON-NLS + "image/x-icon", //NON-NLS + "video/webm", //NON-NLS + "video/3gpp", //NON-NLS + "video/3gpp2", //NON-NLS + "video/ogg", //NON-NLS + "video/mpeg", //NON-NLS + "video/mp4", //NON-NLS + "video/quicktime", //NON-NLS + "video/x-msvideo", //NON-NLS + "video/x-flv", //NON-NLS + "video/x-m4v", //NON-NLS + "video/x-ms-wmv", //NON-NLS + "application/vnd.ms-asf", //NON-NLS + "application/vnd.rn-realmedia", //NON-NLS + "application/x-shockwave-flash" //NON-NLS + ).collect(Collectors.toSet()); + + /* + * The set of the MIME types that will be checked for extension mismatches + * when checkType is ONLY_TEXT_FILES. + * ".doc", ".docx", ".odt", ".xls", ".xlsx", ".ppt", ".pptx" + * ".txt", ".rtf", ".log", ".text", ".xml" + * ".html", ".htm", ".css", ".js", ".php", ".aspx" + * ".pdf" + */ + static final Set TEXT_FILES_MIME_TYPES = Stream.of( + "text/plain", //NON-NLS + "application/rtf", //NON-NLS + "application/pdf", //NON-NLS + "text/css", //NON-NLS + "text/html", //NON-NLS + "text/csv", //NON-NLS + "application/json", //NON-NLS + "application/javascript", //NON-NLS + "application/xml", //NON-NLS + "text/calendar", //NON-NLS + "application/x-msoffice", //NON-NLS + "application/x-ooxml", //NON-NLS + "application/msword", //NON-NLS + "application/vnd.openxmlformats-officedocument.wordprocessingml.document", //NON-NLS + "application/vnd.ms-powerpoint", //NON-NLS + "application/vnd.openxmlformats-officedocument.presentationml.presentation", //NON-NLS + "application/vnd.ms-excel", //NON-NLS + "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", //NON-NLS + "application/vnd.oasis.opendocument.presentation", //NON-NLS + "application/vnd.oasis.opendocument.spreadsheet", //NON-NLS + "application/vnd.oasis.opendocument.text" //NON-NLS + ).collect(Collectors.toSet()); +} diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbCommonFilesAlgorithm.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonFilesMetadataBuilder.java similarity index 70% rename from Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbCommonFilesAlgorithm.java rename to Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonFilesMetadataBuilder.java index e292acb0b0..539c15fd6a 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbCommonFilesAlgorithm.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonFilesMetadataBuilder.java @@ -19,26 +19,22 @@ */ package org.sleuthkit.autopsy.commonfilesearch; -import java.sql.SQLException; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.logging.Level; -import org.sleuthkit.autopsy.casemodule.Case; -import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationCase; import org.sleuthkit.autopsy.centralrepository.datamodel.EamDb; import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException; import static org.sleuthkit.autopsy.timeline.datamodel.eventtype.ArtifactEventType.LOGGER; import org.sleuthkit.datamodel.HashUtility; -import org.sleuthkit.datamodel.TskCoreException; /** * Provides logic for selecting common files from all data sources and all cases * in the Central Repo. */ -public abstract class EamDbCommonFilesAlgorithm extends CommonFilesMetadataBuilder { +public abstract class InterCaseCommonFilesMetadataBuilder extends ICommonFilesMetadataBuilder { //CONSIDER: we should create an interface which specifies the findFiles feature // instead of an abstract class and then have two abstract classes: // inter- and intra- which implement the interface and then 4 subclasses @@ -55,42 +51,17 @@ public abstract class EamDbCommonFilesAlgorithm extends CommonFilesMetadataBuild * * @throws EamDbException */ - EamDbCommonFilesAlgorithm(boolean filterByMediaMimeType, boolean filterByDocMimeType) throws EamDbException { - super(new HashMap(), filterByMediaMimeType, filterByDocMimeType); // Pass empty datasources. Unused for intercase matches. + InterCaseCommonFilesMetadataBuilder(boolean filterByMediaMimeType, boolean filterByDocMimeType) throws EamDbException { + //TODO these two boolean variables are unused for the intercase feature at the moment dbManager = EamDb.getInstance(); } - @Override - public CommonFilesMetadata findFiles() throws TskCoreException, NoCurrentCaseException, SQLException, EamDbException, Exception { - return this.findFiles(null); - } - - protected CommonFilesMetadata findFiles(CorrelationCase correlationCase) throws TskCoreException, NoCurrentCaseException, SQLException, EamDbException, Exception { - - Map> interCaseCommonFiles = new HashMap<>(); - - EamDbAttributeInstancesAlgorithm eamDbAttrInst = new EamDbAttributeInstancesAlgorithm(); - if(correlationCase != null) { - // Filter by matches both within current case and a specific case. - // TODO, move to Single class - eamDbAttrInst.processSingleCaseCorrelationCaseAttributeValues(Case.getCurrentCase(), correlationCase); - } else { - // Filter by matches of current case md5s. - eamDbAttrInst.processCorrelationCaseAttributeValues(Case.getCurrentCase()); - } - interCaseCommonFiles = gatherIntercaseResults(eamDbAttrInst.getIntercaseCommonValuesMap(), eamDbAttrInst.getIntercaseCommonCasesMap()); - - //TODO, only use to filter mimeType in memory against currentCase against, unless mimeType is added to CR - // Builds intercase-only matches metadata - return new CommonFilesMetadata(interCaseCommonFiles); - } - /** * @param artifactInstances all 'common files' in central repo * @param commonFiles matches must ultimately have appeared in this collection * @return collated map of instance counts to lists of matches */ - private Map> gatherIntercaseResults(Map commonFiles, Map commonFileCases) { + Map> gatherIntercaseResults(Map commonFiles, Map commonFileCases) { Map interCaseCommonFiles = new HashMap<>(); @@ -129,18 +100,13 @@ public abstract class EamDbCommonFilesAlgorithm extends CommonFilesMetadataBuild } - Map> instanceCollatedCommonFiles = collatetMatchesByNumberOfInstances(interCaseCommonFiles); + Map> instanceCollatedCommonFiles = collateMatchesByNumberOfInstances(interCaseCommonFiles); return instanceCollatedCommonFiles; } @Override - protected String buildSqlSelectStatement() { - return ""; // TODO Unused - } - - @Override - protected String buildTabTitle() { + String buildTabTitle() { final String buildCategorySelectionString = this.buildCategorySelectionString(); final String titleTemplate = Bundle.CommonFilesMetadataBuilder_buildTabTitle_titleEamDb(); return String.format(titleTemplate, new Object[]{buildCategorySelectionString}); @@ -154,5 +120,4 @@ public abstract class EamDbCommonFilesAlgorithm extends CommonFilesMetadataBuild } throw new Exception("Cannot locate case."); } - } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesMetadataBuilder.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCaseCommonFilesMetadataBuilder.java similarity index 63% rename from Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesMetadataBuilder.java rename to Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCaseCommonFilesMetadataBuilder.java index 0108b4840e..e1a35c0c2f 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesMetadataBuilder.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCaseCommonFilesMetadataBuilder.java @@ -27,9 +27,6 @@ import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; -import java.util.TreeMap; -import java.util.stream.Collectors; -import java.util.stream.Stream; import org.openide.util.NbBundle; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; @@ -48,78 +45,13 @@ import org.sleuthkit.datamodel.TskCoreException; * This entire thing runs on a background thread where exceptions are handled. */ @SuppressWarnings("PMD.AbstractNaming") -public abstract class CommonFilesMetadataBuilder { +public abstract class IntraCaseCommonFilesMetadataBuilder extends ICommonFilesMetadataBuilder { private final Map dataSourceIdToNameMap; private final boolean filterByMedia; private final boolean filterByDoc; private static final String FILTER_BY_MIME_TYPES_WHERE_CLAUSE = " and mime_type in (%s)"; //NON-NLS // where %s is csv list of mime_types to filter on - /* - * The set of the MIME types that will be checked for extension mismatches - * when checkType is ONLY_MEDIA. - * ".jpg", ".jpeg", ".png", ".psd", ".nef", ".tiff", ".bmp", ".tec" - * ".aaf", ".3gp", ".asf", ".avi", ".m1v", ".m2v", //NON-NLS - * ".m4v", ".mp4", ".mov", ".mpeg", ".mpg", ".mpe", ".mp4", ".rm", ".wmv", ".mpv", ".flv", ".swf" - */ - private static final Set MEDIA_PICS_VIDEO_MIME_TYPES = Stream.of( - "image/bmp", //NON-NLS - "image/gif", //NON-NLS - "image/jpeg", //NON-NLS - "image/png", //NON-NLS - "image/tiff", //NON-NLS - "image/vnd.adobe.photoshop", //NON-NLS - "image/x-raw-nikon", //NON-NLS - "image/x-ms-bmp", //NON-NLS - "image/x-icon", //NON-NLS - "video/webm", //NON-NLS - "video/3gpp", //NON-NLS - "video/3gpp2", //NON-NLS - "video/ogg", //NON-NLS - "video/mpeg", //NON-NLS - "video/mp4", //NON-NLS - "video/quicktime", //NON-NLS - "video/x-msvideo", //NON-NLS - "video/x-flv", //NON-NLS - "video/x-m4v", //NON-NLS - "video/x-ms-wmv", //NON-NLS - "application/vnd.ms-asf", //NON-NLS - "application/vnd.rn-realmedia", //NON-NLS - "application/x-shockwave-flash" //NON-NLS - ).collect(Collectors.toSet()); - - /* - * The set of the MIME types that will be checked for extension mismatches - * when checkType is ONLY_TEXT_FILES. - * ".doc", ".docx", ".odt", ".xls", ".xlsx", ".ppt", ".pptx" - * ".txt", ".rtf", ".log", ".text", ".xml" - * ".html", ".htm", ".css", ".js", ".php", ".aspx" - * ".pdf" - */ - private static final Set TEXT_FILES_MIME_TYPES = Stream.of( - "text/plain", //NON-NLS - "application/rtf", //NON-NLS - "application/pdf", //NON-NLS - "text/css", //NON-NLS - "text/html", //NON-NLS - "text/csv", //NON-NLS - "application/json", //NON-NLS - "application/javascript", //NON-NLS - "application/xml", //NON-NLS - "text/calendar", //NON-NLS - "application/x-msoffice", //NON-NLS - "application/x-ooxml", //NON-NLS - "application/msword", //NON-NLS - "application/vnd.openxmlformats-officedocument.wordprocessingml.document", //NON-NLS - "application/vnd.ms-powerpoint", //NON-NLS - "application/vnd.openxmlformats-officedocument.presentationml.presentation", //NON-NLS - "application/vnd.ms-excel", //NON-NLS - "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", //NON-NLS - "application/vnd.oasis.opendocument.presentation", //NON-NLS - "application/vnd.oasis.opendocument.spreadsheet", //NON-NLS - "application/vnd.oasis.opendocument.text" //NON-NLS - ).collect(Collectors.toSet()); - /** * Subclass this to implement different algorithms for getting common files. * @@ -129,7 +61,7 @@ public abstract class CommonFilesMetadataBuilder { * @param filterByDocMimeType match only on files whose mime types can be * broadly categorized as document types */ - CommonFilesMetadataBuilder(Map dataSourceIdMap, boolean filterByMediaMimeType, boolean filterByDocMimeType) { + IntraCaseCommonFilesMetadataBuilder(Map dataSourceIdMap, boolean filterByMediaMimeType, boolean filterByDocMimeType) { dataSourceIdToNameMap = dataSourceIdMap; filterByMedia = filterByMediaMimeType; filterByDoc = filterByDocMimeType; @@ -206,28 +138,11 @@ public abstract class CommonFilesMetadataBuilder { } } - Map> instanceCollatedCommonFiles = collatetMatchesByNumberOfInstances(commonFiles); + Map> instanceCollatedCommonFiles = collateMatchesByNumberOfInstances(commonFiles); return new CommonFilesMetadata(instanceCollatedCommonFiles); } - protected static Map> collatetMatchesByNumberOfInstances(Map commonFiles) { - //collate matches by number of matching instances - doing this in sql doesnt seem efficient - Map> instanceCollatedCommonFiles = new TreeMap<>(); - for(Md5Metadata md5Metadata : commonFiles.values()){ - Integer size = md5Metadata.size(); - - if(instanceCollatedCommonFiles.containsKey(size)){ - instanceCollatedCommonFiles.get(size).add(md5Metadata); - } else { - ArrayList value = new ArrayList<>(); - value.add(md5Metadata); - instanceCollatedCommonFiles.put(size, value); - } - } - return instanceCollatedCommonFiles; - } - /** * Should be used by subclasses, in their * buildSqlSelectStatement() function to create an SQL boolean @@ -258,20 +173,12 @@ public abstract class CommonFilesMetadataBuilder { } return mimeTypeString; } - - @NbBundle.Messages({ - "CommonFilesMetadataBuilder.buildTabTitle.titleAll=Common Files (All Data Sources, %s)", - "CommonFilesMetadataBuilder.buildTabTitle.titleSingle=Common Files (Match Within Data Source: %s, %s)", - "CommonFilesMetadataBuilder.buildTabTitle.titleEamDb=Common Files (Central Repository Source(s), %s)", - }) - protected abstract String buildTabTitle(); @NbBundle.Messages({ "CommonFilesMetadataBuilder.buildCategorySelectionString.doc=Documents", "CommonFilesMetadataBuilder.buildCategorySelectionString.media=Media", "CommonFilesMetadataBuilder.buildCategorySelectionString.all=All File Categories" }) - protected String buildCategorySelectionString() { if (!this.filterByDoc && !this.filterByMedia) { return Bundle.CommonFilesMetadataBuilder_buildCategorySelectionString_all(); diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/SingleCaseEamDbCommonFilesAlgorithm.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/SingleCaseEamDbCommonFilesAlgorithm.java index 622057e06c..7d31517478 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/SingleCaseEamDbCommonFilesAlgorithm.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/SingleCaseEamDbCommonFilesAlgorithm.java @@ -20,6 +20,10 @@ package org.sleuthkit.autopsy.commonfilesearch; import java.sql.SQLException; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationCase; import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException; @@ -29,7 +33,7 @@ import org.sleuthkit.datamodel.TskCoreException; * * */ -public class SingleCaseEamDbCommonFilesAlgorithm extends EamDbCommonFilesAlgorithm { +public class SingleCaseEamDbCommonFilesAlgorithm extends InterCaseCommonFilesMetadataBuilder { private final int corrleationCaseId; @@ -65,5 +69,21 @@ public class SingleCaseEamDbCommonFilesAlgorithm extends EamDbCommonFilesAlgorit return this.findFiles(cCase); } - + + protected CommonFilesMetadata findFiles(CorrelationCase correlationCase) throws TskCoreException, NoCurrentCaseException, SQLException, EamDbException, Exception { + + Map> interCaseCommonFiles = new HashMap<>(); + + EamDbAttributeInstancesAlgorithm eamDbAttrInst = new EamDbAttributeInstancesAlgorithm(); + eamDbAttrInst.processSingleCaseCorrelationCaseAttributeValues(Case.getCurrentCase(), correlationCase); + interCaseCommonFiles = gatherIntercaseResults(eamDbAttrInst.getIntercaseCommonValuesMap(), eamDbAttrInst.getIntercaseCommonCasesMap()); + + return new CommonFilesMetadata(interCaseCommonFiles); + } + + @Override + String buildCategorySelectionString() { + //TODO + return ""; + } } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/SingleDataSource.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/SingleDataSourceCommonFilesAlgorithm.java similarity index 86% rename from Core/src/org/sleuthkit/autopsy/commonfilesearch/SingleDataSource.java rename to Core/src/org/sleuthkit/autopsy/commonfilesearch/SingleDataSourceCommonFilesAlgorithm.java index f22715960f..a6594eb664 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/SingleDataSource.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/SingleDataSourceCommonFilesAlgorithm.java @@ -25,7 +25,7 @@ import org.sleuthkit.datamodel.TskData.FileKnown; /** * Provides logic for selecting common files from a single data source. */ -final public class SingleDataSource extends CommonFilesMetadataBuilder { +final public class SingleDataSourceCommonFilesAlgorithm extends IntraCaseCommonFilesMetadataBuilder { private static final String WHERE_CLAUSE = "%s md5 in (select md5 from tsk_files where md5 in (select md5 from tsk_files where (known != "+ FileKnown.KNOWN.getFileKnownValue() + " OR known IS NULL) and data_source_obj_id=%s%s) GROUP BY md5 HAVING COUNT(DISTINCT data_source_obj_id) > 1) order by md5"; //NON-NLS private final Long selectedDataSourceId; @@ -41,7 +41,7 @@ final public class SingleDataSource extends CommonFilesMetadataBuilder { * @param filterByDocMimeType match only on files whose mime types can be * broadly categorized as document types */ - public SingleDataSource(Long dataSourceId, Map dataSourceIdMap, boolean filterByMediaMimeType, boolean filterByDocMimeType) { + public SingleDataSourceCommonFilesAlgorithm(Long dataSourceId, Map dataSourceIdMap, boolean filterByMediaMimeType, boolean filterByDocMimeType) { super(dataSourceIdMap, filterByMediaMimeType, filterByDocMimeType); this.selectedDataSourceId = dataSourceId; this.dataSourceName = dataSourceIdMap.get(this.selectedDataSourceId); @@ -50,11 +50,11 @@ final public class SingleDataSource extends CommonFilesMetadataBuilder { @Override protected String buildSqlSelectStatement() { Object[] args = new String[]{SELECT_PREFIX, Long.toString(this.selectedDataSourceId), determineMimeTypeFilter()}; - return String.format(SingleDataSource.WHERE_CLAUSE, args); + return String.format(SingleDataSourceCommonFilesAlgorithm.WHERE_CLAUSE, args); } @Override - protected String buildTabTitle() { + public String buildTabTitle() { final String buildCategorySelectionString = this.buildCategorySelectionString(); final String titleTemplate = Bundle.CommonFilesMetadataBuilder_buildTabTitle_titleSingle(); return String.format(titleTemplate, new Object[]{this.dataSourceName, buildCategorySelectionString}); diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileTypeInterCaseTests.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileTypeInterCaseTests.java index 9538fe6549..3d1e0c2ff3 100644 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileTypeInterCaseTests.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileTypeInterCaseTests.java @@ -31,7 +31,7 @@ import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException; import org.sleuthkit.autopsy.commonfilesearch.AllCasesEamDbCommonFilesAlgorithm; import org.sleuthkit.autopsy.commonfilesearch.CommonFilesMetadata; -import org.sleuthkit.autopsy.commonfilesearch.CommonFilesMetadataBuilder; +import org.sleuthkit.autopsy.commonfilesearch.IntraCaseCommonFilesMetadataBuilder; import org.sleuthkit.datamodel.TskCoreException; /** @@ -86,7 +86,7 @@ public class IngestedWithHashAndFileTypeInterCaseTests extends NbTestCase { //this is proabbly not needed and should be pulled out of the constructor if possible Map dataSources = this.utils.getDataSourceMap(); - CommonFilesMetadataBuilder builder = new AllCasesEamDbCommonFilesAlgorithm(dataSources, false, false); + IntraCaseCommonFilesMetadataBuilder builder = new AllCasesEamDbCommonFilesAlgorithm(dataSources, false, false); CommonFilesMetadata metadata = builder.findFiles(); diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileTypeIntraCaseTests.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileTypeIntraCaseTests.java index e9e538c004..88b78d076d 100644 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileTypeIntraCaseTests.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileTypeIntraCaseTests.java @@ -31,8 +31,8 @@ import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; import org.sleuthkit.autopsy.commonfilesearch.AllDataSourcesCommonFilesAlgorithm; import org.sleuthkit.autopsy.commonfilesearch.CommonFilesMetadata; -import org.sleuthkit.autopsy.commonfilesearch.CommonFilesMetadataBuilder; -import org.sleuthkit.autopsy.commonfilesearch.SingleDataSource; +import org.sleuthkit.autopsy.commonfilesearch.IntraCaseCommonFilesMetadataBuilder; +import org.sleuthkit.autopsy.commonfilesearch.SingleDataSourceCommonFilesAlgorithm; import static org.sleuthkit.autopsy.commonfilessearch.IntraCaseUtils.*; import org.sleuthkit.autopsy.ingest.IngestJobSettings; import org.sleuthkit.autopsy.ingest.IngestJobSettings.IngestType; @@ -97,7 +97,7 @@ public class IngestedWithHashAndFileTypeIntraCaseTests extends NbTestCase { try { Map dataSources = this.utils.getDataSourceMap(); - CommonFilesMetadataBuilder allSourcesBuilder = new AllDataSourcesCommonFilesAlgorithm(dataSources, false, false); + IntraCaseCommonFilesMetadataBuilder allSourcesBuilder = new AllDataSourcesCommonFilesAlgorithm(dataSources, false, false); CommonFilesMetadata metadata = allSourcesBuilder.findFiles(); Map objectIdToDataSource = IntraCaseUtils.mapFileInstancesToDataSources(metadata); @@ -138,7 +138,7 @@ public class IngestedWithHashAndFileTypeIntraCaseTests extends NbTestCase { try { Map dataSources = this.utils.getDataSourceMap(); - CommonFilesMetadataBuilder allSourcesBuilder = new AllDataSourcesCommonFilesAlgorithm(dataSources, true, false); + IntraCaseCommonFilesMetadataBuilder allSourcesBuilder = new AllDataSourcesCommonFilesAlgorithm(dataSources, true, false); CommonFilesMetadata metadata = allSourcesBuilder.findFiles(); Map objectIdToDataSource = mapFileInstancesToDataSources(metadata); @@ -179,7 +179,7 @@ public class IngestedWithHashAndFileTypeIntraCaseTests extends NbTestCase { try { Map dataSources = this.utils.getDataSourceMap(); - CommonFilesMetadataBuilder allSourcesBuilder = new AllDataSourcesCommonFilesAlgorithm(dataSources, false, true); + IntraCaseCommonFilesMetadataBuilder allSourcesBuilder = new AllDataSourcesCommonFilesAlgorithm(dataSources, false, true); CommonFilesMetadata metadata = allSourcesBuilder.findFiles(); Map objectIdToDataSource = mapFileInstancesToDataSources(metadata); @@ -221,7 +221,7 @@ public class IngestedWithHashAndFileTypeIntraCaseTests extends NbTestCase { Map dataSources = this.utils.getDataSourceMap(); Long first = getDataSourceIdByName(SET1, dataSources); - CommonFilesMetadataBuilder singleSourceBuilder = new SingleDataSource(first, dataSources, false, false); + IntraCaseCommonFilesMetadataBuilder singleSourceBuilder = new SingleDataSourceCommonFilesAlgorithm(first, dataSources, false, false); CommonFilesMetadata metadata = singleSourceBuilder.findFiles(); Map objectIdToDataSource = mapFileInstancesToDataSources(metadata); @@ -263,7 +263,7 @@ public class IngestedWithHashAndFileTypeIntraCaseTests extends NbTestCase { Map dataSources = this.utils.getDataSourceMap(); Long first = getDataSourceIdByName(SET1, dataSources); - CommonFilesMetadataBuilder singleSourceBuilder = new SingleDataSource(first, dataSources, true, false); + IntraCaseCommonFilesMetadataBuilder singleSourceBuilder = new SingleDataSourceCommonFilesAlgorithm(first, dataSources, true, false); CommonFilesMetadata metadata = singleSourceBuilder.findFiles(); Map objectIdToDataSource = mapFileInstancesToDataSources(metadata); @@ -305,7 +305,7 @@ public class IngestedWithHashAndFileTypeIntraCaseTests extends NbTestCase { Map dataSources = this.utils.getDataSourceMap(); Long first = getDataSourceIdByName(SET1, dataSources); - CommonFilesMetadataBuilder singleSourceBuilder = new SingleDataSource(first, dataSources, false, true); + IntraCaseCommonFilesMetadataBuilder singleSourceBuilder = new SingleDataSourceCommonFilesAlgorithm(first, dataSources, false, true); CommonFilesMetadata metadata = singleSourceBuilder.findFiles(); Map objectIdToDataSource = mapFileInstancesToDataSources(metadata); @@ -347,7 +347,7 @@ public class IngestedWithHashAndFileTypeIntraCaseTests extends NbTestCase { Map dataSources = this.utils.getDataSourceMap(); Long second = getDataSourceIdByName(SET2, dataSources); - CommonFilesMetadataBuilder singleSourceBuilder = new SingleDataSource(second, dataSources, false, false); + IntraCaseCommonFilesMetadataBuilder singleSourceBuilder = new SingleDataSourceCommonFilesAlgorithm(second, dataSources, false, false); CommonFilesMetadata metadata = singleSourceBuilder.findFiles(); Map objectIdToDataSource = mapFileInstancesToDataSources(metadata); @@ -388,7 +388,7 @@ public class IngestedWithHashAndFileTypeIntraCaseTests extends NbTestCase { Map dataSources = this.utils.getDataSourceMap(); Long last = getDataSourceIdByName(SET4, dataSources); - CommonFilesMetadataBuilder singleSourceBuilder = new SingleDataSource(last, dataSources, false, false); + IntraCaseCommonFilesMetadataBuilder singleSourceBuilder = new SingleDataSourceCommonFilesAlgorithm(last, dataSources, false, false); CommonFilesMetadata metadata = singleSourceBuilder.findFiles(); Map objectIdToDataSource = mapFileInstancesToDataSources(metadata); @@ -429,7 +429,7 @@ public class IngestedWithHashAndFileTypeIntraCaseTests extends NbTestCase { Map dataSources = this.utils.getDataSourceMap(); Long third = getDataSourceIdByName(SET3, dataSources); - CommonFilesMetadataBuilder singleSourceBuilder = new SingleDataSource(third, dataSources, false, false); + IntraCaseCommonFilesMetadataBuilder singleSourceBuilder = new SingleDataSourceCommonFilesAlgorithm(third, dataSources, false, false); CommonFilesMetadata metadata = singleSourceBuilder.findFiles(); Map objectIdToDataSource = mapFileInstancesToDataSources(metadata); diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithNoFileTypesIntraCaseTests.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithNoFileTypesIntraCaseTests.java index 4d14417efc..3fb720cb53 100644 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithNoFileTypesIntraCaseTests.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithNoFileTypesIntraCaseTests.java @@ -32,8 +32,8 @@ import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; import org.sleuthkit.autopsy.commonfilesearch.AllDataSourcesCommonFilesAlgorithm; import org.sleuthkit.autopsy.commonfilesearch.CommonFilesMetadata; -import org.sleuthkit.autopsy.commonfilesearch.CommonFilesMetadataBuilder; -import org.sleuthkit.autopsy.commonfilesearch.SingleDataSource; +import org.sleuthkit.autopsy.commonfilesearch.IntraCaseCommonFilesMetadataBuilder; +import org.sleuthkit.autopsy.commonfilesearch.SingleDataSourceCommonFilesAlgorithm; import org.sleuthkit.autopsy.ingest.IngestJobSettings; import org.sleuthkit.autopsy.ingest.IngestModuleTemplate; import org.sleuthkit.autopsy.modules.hashdatabase.HashLookupModuleFactory; @@ -99,7 +99,7 @@ public class IngestedWithNoFileTypesIntraCaseTests extends NbTestCase { try { Map dataSources = this.utils.getDataSourceMap(); - CommonFilesMetadataBuilder allSourcesBuilder = new AllDataSourcesCommonFilesAlgorithm(dataSources, true, false); + IntraCaseCommonFilesMetadataBuilder allSourcesBuilder = new AllDataSourcesCommonFilesAlgorithm(dataSources, true, false); CommonFilesMetadata metadata = allSourcesBuilder.findFiles(); Map objectIdToDataSource = IntraCaseUtils.mapFileInstancesToDataSources(metadata); @@ -123,7 +123,7 @@ public class IngestedWithNoFileTypesIntraCaseTests extends NbTestCase { Map dataSources = this.utils.getDataSourceMap(); Long third = IntraCaseUtils.getDataSourceIdByName(IntraCaseUtils.SET3, dataSources); - CommonFilesMetadataBuilder singleSourceBuilder = new SingleDataSource(third, dataSources, true, false); + IntraCaseCommonFilesMetadataBuilder singleSourceBuilder = new SingleDataSourceCommonFilesAlgorithm(third, dataSources, true, false); CommonFilesMetadata metadata = singleSourceBuilder.findFiles(); Map objectIdToDataSource = IntraCaseUtils.mapFileInstancesToDataSources(metadata); diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/NoCentralRepoEnabledInterCaseTests.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/NoCentralRepoEnabledInterCaseTests.java index 276229213a..39c4ba42d1 100644 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/NoCentralRepoEnabledInterCaseTests.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/NoCentralRepoEnabledInterCaseTests.java @@ -30,7 +30,7 @@ import org.python.icu.impl.Assert; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.commonfilesearch.AllCasesEamDbCommonFilesAlgorithm; import org.sleuthkit.autopsy.commonfilesearch.CommonFilesMetadata; -import org.sleuthkit.autopsy.commonfilesearch.CommonFilesMetadataBuilder; +import org.sleuthkit.autopsy.commonfilesearch.IntraCaseCommonFilesMetadataBuilder; /** * @@ -75,7 +75,7 @@ public class NoCentralRepoEnabledInterCaseTests extends NbTestCase { try { Map dataSources = this.utils.getDataSourceMap(); - CommonFilesMetadataBuilder builder = new AllCasesEamDbCommonFilesAlgorithm(dataSources, false, false); + IntraCaseCommonFilesMetadataBuilder builder = new AllCasesEamDbCommonFilesAlgorithm(dataSources, false, false); CommonFilesMetadata metadata = builder.findFiles(); diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/UningestedCasesIntraCaseTests.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/UningestedCasesIntraCaseTests.java index 2b68f4371e..c9e54bcf41 100644 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/UningestedCasesIntraCaseTests.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/UningestedCasesIntraCaseTests.java @@ -28,8 +28,8 @@ import org.openide.util.Exceptions; import org.python.icu.impl.Assert; import org.sleuthkit.autopsy.commonfilesearch.AllDataSourcesCommonFilesAlgorithm; import org.sleuthkit.autopsy.commonfilesearch.CommonFilesMetadata; -import org.sleuthkit.autopsy.commonfilesearch.CommonFilesMetadataBuilder; -import org.sleuthkit.autopsy.commonfilesearch.SingleDataSource; +import org.sleuthkit.autopsy.commonfilesearch.IntraCaseCommonFilesMetadataBuilder; +import org.sleuthkit.autopsy.commonfilesearch.SingleDataSourceCommonFilesAlgorithm; import static org.sleuthkit.autopsy.commonfilessearch.IntraCaseUtils.SET1; import static org.sleuthkit.autopsy.commonfilessearch.IntraCaseUtils.getDataSourceIdByName; @@ -77,7 +77,7 @@ public class UningestedCasesIntraCaseTests extends NbTestCase { try { Map dataSources = this.utils.getDataSourceMap(); - CommonFilesMetadataBuilder allSourcesBuilder = new AllDataSourcesCommonFilesAlgorithm(dataSources, false, false); + IntraCaseCommonFilesMetadataBuilder allSourcesBuilder = new AllDataSourcesCommonFilesAlgorithm(dataSources, false, false); CommonFilesMetadata metadata = allSourcesBuilder.findFiles(); int resultCount = metadata.size(); @@ -97,7 +97,7 @@ public class UningestedCasesIntraCaseTests extends NbTestCase { Map dataSources = this.utils.getDataSourceMap(); Long first = getDataSourceIdByName(SET1, dataSources); - CommonFilesMetadataBuilder singleSourceBuilder = new SingleDataSource(first, dataSources, false, false); + IntraCaseCommonFilesMetadataBuilder singleSourceBuilder = new SingleDataSourceCommonFilesAlgorithm(first, dataSources, false, false); CommonFilesMetadata metadata = singleSourceBuilder.findFiles(); int resultCount = metadata.size(); From 071f783bb44cfd9a94f32a6f0fb59e5baf88ab1b Mon Sep 17 00:00:00 2001 From: Andrew Ziehl Date: Mon, 16 Jul 2018 14:17:38 -0700 Subject: [PATCH 129/287] Fix bundle strings, cleanup. --- ...> AbstractCommonFilesMetadataBuilder.java} | 36 +++++++++++++++---- .../AllCasesEamDbCommonFilesAlgorithm.java | 8 +++-- .../AllDataSourcesCommonFilesAlgorithm.java | 2 +- .../commonfilesearch/CommonFilesPanel.java | 11 +----- .../InterCaseCommonFilesMetadataBuilder.java | 12 ++----- .../IntraCaseCommonFilesMetadataBuilder.java | 27 ++------------ .../autopsy/commonfilesearch/Md5Node.java | 5 --- .../SingleCaseEamDbCommonFilesAlgorithm.java | 14 +++++--- .../SingleDataSourceCommonFilesAlgorithm.java | 2 +- 9 files changed, 53 insertions(+), 64 deletions(-) rename Core/src/org/sleuthkit/autopsy/commonfilesearch/{ICommonFilesMetadataBuilder.java => AbstractCommonFilesMetadataBuilder.java} (75%) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/ICommonFilesMetadataBuilder.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonFilesMetadataBuilder.java similarity index 75% rename from Core/src/org/sleuthkit/autopsy/commonfilesearch/ICommonFilesMetadataBuilder.java rename to Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonFilesMetadataBuilder.java index 19a41f5652..9190ac1a73 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/ICommonFilesMetadataBuilder.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonFilesMetadataBuilder.java @@ -27,20 +27,44 @@ import java.util.Set; import java.util.TreeMap; import java.util.stream.Collectors; import java.util.stream.Stream; +import org.openide.util.NbBundle; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; import org.sleuthkit.datamodel.TskCoreException; -/** - * - * @author bsweeney - */ -abstract class ICommonFilesMetadataBuilder { +abstract class AbstractCommonFilesMetadataBuilder { + + boolean filterByMedia; + boolean filterByDoc; abstract CommonFilesMetadata findFiles() throws TskCoreException, NoCurrentCaseException, SQLException, Exception; + @NbBundle.Messages({ + "AbstractCommonFilesMetadataBuilder.buildTabTitle.titleIntraAll=Common Files (All Data Sources, %s)", + "AbstractCommonFilesMetadataBuilder.buildTabTitle.titleIntraSingle=Common Files (Data Source: %s, %s)", + "AbstractCommonFilesMetadataBuilder.buildTabTitle.titleInterAll=Common Files (All Central Repository Cases, %s)", + "AbstractCommonFilesMetadataBuilder.buildTabTitle.titleInterSingle=Common Files (Central Repository Case: %s, %s)", + }) abstract String buildTabTitle(); - abstract String buildCategorySelectionString(); + @NbBundle.Messages({ + "AbstractCommonFilesMetadataBuilder.buildCategorySelectionString.doc=Documents", + "AbstractCommonFilesMetadataBuilder.buildCategorySelectionString.media=Media", + "AbstractCommonFilesMetadataBuilder.buildCategorySelectionString.all=All File Categories" + }) + protected String buildCategorySelectionString() { + if (!this.filterByDoc && !this.filterByMedia) { + return Bundle.AbstractCommonFilesMetadataBuilder_buildCategorySelectionString_all(); + } else { + List filters = new ArrayList<>(); + if (this.filterByDoc) { + filters.add(Bundle.AbstractCommonFilesMetadataBuilder_buildCategorySelectionString_doc()); + } + if (this.filterByMedia) { + filters.add(Bundle.AbstractCommonFilesMetadataBuilder_buildCategorySelectionString_media()); + } + return String.join(", ", filters); + } + } static Map> collateMatchesByNumberOfInstances(Map commonFiles) { //collate matches by number of matching instances - doing this in sql doesnt seem efficient diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllCasesEamDbCommonFilesAlgorithm.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllCasesEamDbCommonFilesAlgorithm.java index 63c5525097..f7d1c65b41 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllCasesEamDbCommonFilesAlgorithm.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllCasesEamDbCommonFilesAlgorithm.java @@ -50,8 +50,10 @@ public class AllCasesEamDbCommonFilesAlgorithm extends InterCaseCommonFilesMetad } @Override - String buildCategorySelectionString() { - //TODO - return ""; + String buildTabTitle() { + final String buildCategorySelectionString = this.buildCategorySelectionString(); + final String titleTemplate = Bundle.AbstractCommonFilesMetadataBuilder_buildTabTitle_titleInterAll(); + return String.format(titleTemplate, new Object[]{buildCategorySelectionString}); } + } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllDataSourcesCommonFilesAlgorithm.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllDataSourcesCommonFilesAlgorithm.java index 931c307453..e330ddc05e 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllDataSourcesCommonFilesAlgorithm.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllDataSourcesCommonFilesAlgorithm.java @@ -51,7 +51,7 @@ final public class AllDataSourcesCommonFilesAlgorithm extends IntraCaseCommonFil @Override protected String buildTabTitle() { final String buildCategorySelectionString = this.buildCategorySelectionString(); - final String titleTemplate = Bundle.CommonFilesMetadataBuilder_buildTabTitle_titleAll(); + final String titleTemplate = Bundle.AbstractCommonFilesMetadataBuilder_buildTabTitle_titleIntraAll(); return String.format(titleTemplate, new Object[]{buildCategorySelectionString}); } } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java index a5ea73065e..38cf65c656 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java @@ -30,7 +30,6 @@ import javax.swing.SwingUtilities; import javax.swing.SwingWorker; import org.netbeans.api.progress.ProgressHandle; import org.openide.explorer.ExplorerManager; -import org.openide.util.Exceptions; import org.openide.util.NbBundle; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; @@ -58,9 +57,6 @@ public final class CommonFilesPanel extends javax.swing.JPanel { private static final Long NO_DATA_SOURCE_SELECTED = -1L; private static final Logger LOGGER = Logger.getLogger(CommonFilesPanel.class.getName()); - - private boolean singleDataSource = false; - private String selectedDataSource = ""; private boolean pictureViewCheckboxState; private boolean documentsCheckboxState; @@ -74,9 +70,6 @@ public final class CommonFilesPanel extends javax.swing.JPanel { initComponents(); this.errorText.setVisible(false); - - this.intraCasePanel.setParent(this); - this.setupDataSources(); if (CommonFilesPanel.isEamDbAvailable()) { @@ -141,7 +134,7 @@ public final class CommonFilesPanel extends javax.swing.JPanel { Long dataSourceId = intraCasePanel.getSelectedDataSourceId(); Integer caseId = interCasePanel.getSelectedCaseId(); - IntraCaseCommonFilesMetadataBuilder builder; + AbstractCommonFilesMetadataBuilder builder; CommonFilesMetadata metadata; boolean filterByMedia = false; @@ -173,8 +166,6 @@ public final class CommonFilesPanel extends javax.swing.JPanel { setTitleForSingleSource(dataSourceId); } } - - //TODO set title from one method rather than two (or more) overloads metadata = builder.findFiles(); this.tabTitle = builder.buildTabTitle(); diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonFilesMetadataBuilder.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonFilesMetadataBuilder.java index 539c15fd6a..a4b71bf950 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonFilesMetadataBuilder.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonFilesMetadataBuilder.java @@ -34,7 +34,7 @@ import org.sleuthkit.datamodel.HashUtility; * Provides logic for selecting common files from all data sources and all cases * in the Central Repo. */ -public abstract class InterCaseCommonFilesMetadataBuilder extends ICommonFilesMetadataBuilder { +public abstract class InterCaseCommonFilesMetadataBuilder extends AbstractCommonFilesMetadataBuilder { //CONSIDER: we should create an interface which specifies the findFiles feature // instead of an abstract class and then have two abstract classes: // inter- and intra- which implement the interface and then 4 subclasses @@ -52,7 +52,8 @@ public abstract class InterCaseCommonFilesMetadataBuilder extends ICommonFilesMe * @throws EamDbException */ InterCaseCommonFilesMetadataBuilder(boolean filterByMediaMimeType, boolean filterByDocMimeType) throws EamDbException { - //TODO these two boolean variables are unused for the intercase feature at the moment + filterByMedia = filterByMediaMimeType; + filterByDoc = filterByDocMimeType; dbManager = EamDb.getInstance(); } @@ -105,13 +106,6 @@ public abstract class InterCaseCommonFilesMetadataBuilder extends ICommonFilesMe return instanceCollatedCommonFiles; } - @Override - String buildTabTitle() { - final String buildCategorySelectionString = this.buildCategorySelectionString(); - final String titleTemplate = Bundle.CommonFilesMetadataBuilder_buildTabTitle_titleEamDb(); - return String.format(titleTemplate, new Object[]{buildCategorySelectionString}); - } - protected CorrelationCase getCorrelationCaseFromId(int correlationCaseId) throws EamDbException, Exception { for (CorrelationCase cCase : this.dbManager.getCases()) { if (cCase.getID() == correlationCaseId) { diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCaseCommonFilesMetadataBuilder.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCaseCommonFilesMetadataBuilder.java index e1a35c0c2f..89f011c425 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCaseCommonFilesMetadataBuilder.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCaseCommonFilesMetadataBuilder.java @@ -27,7 +27,6 @@ import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; -import org.openide.util.NbBundle; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; import org.sleuthkit.datamodel.AbstractFile; @@ -45,11 +44,9 @@ import org.sleuthkit.datamodel.TskCoreException; * This entire thing runs on a background thread where exceptions are handled. */ @SuppressWarnings("PMD.AbstractNaming") -public abstract class IntraCaseCommonFilesMetadataBuilder extends ICommonFilesMetadataBuilder { +public abstract class IntraCaseCommonFilesMetadataBuilder extends AbstractCommonFilesMetadataBuilder { private final Map dataSourceIdToNameMap; - private final boolean filterByMedia; - private final boolean filterByDoc; private static final String FILTER_BY_MIME_TYPES_WHERE_CLAUSE = " and mime_type in (%s)"; //NON-NLS // where %s is csv list of mime_types to filter on /** @@ -100,6 +97,7 @@ public abstract class IntraCaseCommonFilesMetadataBuilder extends ICommonFilesMe * @throws NoCurrentCaseException * @throws SQLException */ + @Override public CommonFilesMetadata findFiles() throws TskCoreException, NoCurrentCaseException, SQLException, Exception { //TODO do we need all those exceptions or can we differentiate when they are caught? Map commonFiles = new HashMap<>(); @@ -173,24 +171,5 @@ public abstract class IntraCaseCommonFilesMetadataBuilder extends ICommonFilesMe } return mimeTypeString; } - - @NbBundle.Messages({ - "CommonFilesMetadataBuilder.buildCategorySelectionString.doc=Documents", - "CommonFilesMetadataBuilder.buildCategorySelectionString.media=Media", - "CommonFilesMetadataBuilder.buildCategorySelectionString.all=All File Categories" - }) - protected String buildCategorySelectionString() { - if (!this.filterByDoc && !this.filterByMedia) { - return Bundle.CommonFilesMetadataBuilder_buildCategorySelectionString_all(); - } else { - List filters = new ArrayList<>(); - if (this.filterByDoc) { - filters.add(Bundle.CommonFilesMetadataBuilder_buildCategorySelectionString_doc()); - } - if (this.filterByMedia) { - filters.add(Bundle.CommonFilesMetadataBuilder_buildCategorySelectionString_media()); - } - return String.join(", ", filters); - } - } + } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/Md5Node.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/Md5Node.java index b22e3e35e7..45edc96c39 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/Md5Node.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/Md5Node.java @@ -19,21 +19,16 @@ */ package org.sleuthkit.autopsy.commonfilesearch; -import java.util.HashMap; import java.util.List; -import java.util.Map; import org.openide.nodes.ChildFactory; import org.openide.nodes.Children; import org.openide.nodes.Node; import org.openide.nodes.Sheet; import org.openide.util.NbBundle; -import org.sleuthkit.autopsy.commonfilesearch.FileInstanceNodeGenerator; -import org.sleuthkit.autopsy.commonfilesearch.Md5Metadata; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.datamodel.DisplayableItemNode; import org.sleuthkit.autopsy.datamodel.DisplayableItemNodeVisitor; import org.sleuthkit.autopsy.datamodel.NodeProperty; -import org.sleuthkit.datamodel.AbstractFile; /** * Represents a common files match - two or more files which appear to be the diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/SingleCaseEamDbCommonFilesAlgorithm.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/SingleCaseEamDbCommonFilesAlgorithm.java index 7d31517478..0cd96eb1ee 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/SingleCaseEamDbCommonFilesAlgorithm.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/SingleCaseEamDbCommonFilesAlgorithm.java @@ -36,6 +36,7 @@ import org.sleuthkit.datamodel.TskCoreException; public class SingleCaseEamDbCommonFilesAlgorithm extends InterCaseCommonFilesMetadataBuilder { private final int corrleationCaseId; + private String correlationCaseName; /** * @@ -48,6 +49,7 @@ public class SingleCaseEamDbCommonFilesAlgorithm extends InterCaseCommonFilesMet super(filterByMediaMimeType, filterByDocMimeType); this.corrleationCaseId = correlationCaseId; + this.correlationCaseName = ""; } /** @@ -66,7 +68,7 @@ public class SingleCaseEamDbCommonFilesAlgorithm extends InterCaseCommonFilesMet public CommonFilesMetadata findFiles() throws TskCoreException, NoCurrentCaseException, SQLException, EamDbException, Exception { CorrelationCase cCase = this.getCorrelationCaseFromId(this.corrleationCaseId); - + correlationCaseName = cCase.getDisplayName(); return this.findFiles(cCase); } @@ -80,10 +82,12 @@ public class SingleCaseEamDbCommonFilesAlgorithm extends InterCaseCommonFilesMet return new CommonFilesMetadata(interCaseCommonFiles); } - + @Override - String buildCategorySelectionString() { - //TODO - return ""; + String buildTabTitle() { + final String buildCategorySelectionString = this.buildCategorySelectionString(); + final String titleTemplate = Bundle.AbstractCommonFilesMetadataBuilder_buildTabTitle_titleInterSingle(); + return String.format(titleTemplate, new Object[]{correlationCaseName, buildCategorySelectionString}); } + } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/SingleDataSourceCommonFilesAlgorithm.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/SingleDataSourceCommonFilesAlgorithm.java index a6594eb664..c97b15ae0b 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/SingleDataSourceCommonFilesAlgorithm.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/SingleDataSourceCommonFilesAlgorithm.java @@ -56,7 +56,7 @@ final public class SingleDataSourceCommonFilesAlgorithm extends IntraCaseCommonF @Override public String buildTabTitle() { final String buildCategorySelectionString = this.buildCategorySelectionString(); - final String titleTemplate = Bundle.CommonFilesMetadataBuilder_buildTabTitle_titleSingle(); + final String titleTemplate = Bundle.AbstractCommonFilesMetadataBuilder_buildTabTitle_titleIntraSingle(); return String.format(titleTemplate, new Object[]{this.dataSourceName, buildCategorySelectionString}); } } From 5c93eca945d8d0d71e5074516072d31fcaf661a6 Mon Sep 17 00:00:00 2001 From: Andrew Ziehl Date: Mon, 16 Jul 2018 14:29:57 -0700 Subject: [PATCH 130/287] Fix intracase cache being null. --- .../autopsy/commonfilesearch/FileInstanceNodeGenerator.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/FileInstanceNodeGenerator.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/FileInstanceNodeGenerator.java index 91e3a9aa97..a4863aa0b6 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/FileInstanceNodeGenerator.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/FileInstanceNodeGenerator.java @@ -44,14 +44,14 @@ public abstract class FileInstanceNodeGenerator { public FileInstanceNodeGenerator(Long abstractFileReference, Map cachedFiles, String dataSource, String caseName) { this.abstractFileReference = abstractFileReference; - cachedFiles = cachedFiles; + FileInstanceNodeGenerator.cachedFiles = cachedFiles; this.caseName = caseName; this.dataSource = dataSource; } public FileInstanceNodeGenerator(Map cachedFiles) { this.abstractFileReference = -1L; - cachedFiles = cachedFiles; + FileInstanceNodeGenerator.cachedFiles = cachedFiles; this.caseName = ""; this.dataSource = ""; } From 6ecf9132933cbbcceda1b1eb9153280c0d9064ef Mon Sep 17 00:00:00 2001 From: Andrew Ziehl Date: Mon, 16 Jul 2018 15:50:01 -0700 Subject: [PATCH 131/287] 3904, remove CommonFilesDialog --- .../commonfilesearch/CommonFilesDialog.form | 51 ---------- .../commonfilesearch/CommonFilesDialog.java | 94 ------------------- .../commonfilesearch/CommonFilesPanel.form | 8 +- .../commonfilesearch/CommonFilesPanel.java | 31 ++++-- .../CommonFilesSearchAction.java | 4 +- 5 files changed, 32 insertions(+), 156 deletions(-) delete mode 100644 Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesDialog.form delete mode 100644 Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesDialog.java diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesDialog.form b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesDialog.form deleted file mode 100644 index 7a6e3dabe5..0000000000 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesDialog.form +++ /dev/null @@ -1,51 +0,0 @@ - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesDialog.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesDialog.java deleted file mode 100644 index 204b3136a9..0000000000 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesDialog.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Autopsy Forensic Browser - * - * Copyright 2018 Basis Technology Corp. - * Contact: carrier sleuthkit 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.commonfilesearch; - -import javax.swing.JFrame; -import javax.swing.SwingUtilities; -import org.openide.util.NbBundle; -import org.openide.windows.WindowManager; - -/** - * Dialog box for configuring and running common files search. - */ -@SuppressWarnings("PMD.SingularField") // UI widgets cause lots of false positives -public final class CommonFilesDialog extends javax.swing.JDialog { - - private static final long serialVersionUID = 1L; - - /** - * Creates new form CommonFilesDialog - */ - @NbBundle.Messages({ - "CommonFilesDialog.frame.title=Find Common Files", - "CommonFilesDialog.frame.msg=Find Common Files"}) - public CommonFilesDialog() { - super(new JFrame(Bundle.CommonFilesDialog_frame_title()), - Bundle.CommonFilesDialog_frame_msg(), true); - initComponents(); - - this.setResizable(false); - this.setLocationRelativeTo(WindowManager.getDefault().getMainWindow()); - } - - /** - * This method is called from within the constructor to initialize the form. - * WARNING: Do NOT modify this code. The content of this method is always - * regenerated by the Form Editor. - */ - @SuppressWarnings("unchecked") - // //GEN-BEGIN:initComponents - private void initComponents() { - - commonFilesPanel1 = new org.sleuthkit.autopsy.commonfilesearch.CommonFilesPanel(); - - setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); - setSize(new java.awt.Dimension(340, 320)); - addWindowListener(new java.awt.event.WindowAdapter() { - public void windowClosed(java.awt.event.WindowEvent evt) { - formWindowClosed(evt); - } - }); - - javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); - getContentPane().setLayout(layout); - layout.setHorizontalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addComponent(commonFilesPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGap(0, 0, Short.MAX_VALUE)) - ); - layout.setVerticalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addComponent(commonFilesPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGap(0, 0, Short.MAX_VALUE)) - ); - - pack(); - setLocationRelativeTo(null); - }// //GEN-END:initComponents - - private void formWindowClosed(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowClosed - SwingUtilities.windowForComponent(this).dispose(); - }//GEN-LAST:event_formWindowClosed - - // Variables declaration - do not modify//GEN-BEGIN:variables - private org.sleuthkit.autopsy.commonfilesearch.CommonFilesPanel commonFilesPanel1; - // End of variables declaration//GEN-END:variables -} diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.form b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.form index e51aedbef3..da071802d8 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.form +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.form @@ -1,12 +1,18 @@ -
+ + + + + + + diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java index 38cf65c656..6b57b40f3f 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java @@ -26,11 +26,13 @@ import java.util.List; import java.util.Map; import java.util.concurrent.ExecutionException; import java.util.logging.Level; +import javax.swing.JFrame; import javax.swing.SwingUtilities; import javax.swing.SwingWorker; import org.netbeans.api.progress.ProgressHandle; import org.openide.explorer.ExplorerManager; import org.openide.util.NbBundle; +import org.openide.windows.WindowManager; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationCase; @@ -50,7 +52,7 @@ import org.sleuthkit.datamodel.TskCoreException; * logic. Nested within CommonFilesDialog. */ @SuppressWarnings("PMD.SingularField") // UI widgets cause lots of false positives -public final class CommonFilesPanel extends javax.swing.JPanel { +public final class CommonFilesPanel extends javax.swing.JDialog { private static final long serialVersionUID = 1L; @@ -65,10 +67,15 @@ public final class CommonFilesPanel extends javax.swing.JPanel { */ @NbBundle.Messages({ "CommonFilesPanel.title=Common Files Panel", - "CommonFilesPanel.exception=Unexpected Exception loading DataSources."}) + "CommonFilesPanel.exception=Unexpected Exception loading DataSources.", + "CommonFilesPanel.frame.title=Find Common Files", + "CommonFilesPanel.frame.msg=Find Common Files"}) public CommonFilesPanel() { + super(new JFrame(Bundle.CommonFilesDialog_frame_title()), + Bundle.CommonFilesDialog_frame_msg(), true); initComponents(); - + this.setResizable(false); + this.setLocationRelativeTo(WindowManager.getDefault().getMainWindow()); this.errorText.setVisible(false); this.setupDataSources(); @@ -395,6 +402,12 @@ public final class CommonFilesPanel extends javax.swing.JPanel { intraCasePanel = new org.sleuthkit.autopsy.commonfilesearch.IntraCasePanel(); interCasePanel = new org.sleuthkit.autopsy.commonfilesearch.InterCasePanel(); + addWindowListener(new java.awt.event.WindowAdapter() { + public void windowClosed(java.awt.event.WindowEvent evt) { + formWindowClosed(evt); + } + }); + org.openide.awt.Mnemonics.setLocalizedText(commonFilesSearchLabel2, org.openide.util.NbBundle.getMessage(CommonFilesPanel.class, "CommonFilesPanel.commonFilesSearchLabel2.text")); // NOI18N commonFilesSearchLabel2.setFocusable(false); @@ -481,8 +494,8 @@ public final class CommonFilesPanel extends javax.swing.JPanel { layoutPanel.add(intraCasePanel, "card3"); layoutPanel.add(interCasePanel, "card2"); - javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); - this.setLayout(layout); + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); + getContentPane().setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() @@ -495,9 +508,7 @@ public final class CommonFilesPanel extends javax.swing.JPanel { .addGap(21, 21, 21) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(pictureVideoCheckbox) - .addGroup(layout.createSequentialGroup() - .addComponent(documentsCheckbox) - .addContainerGap()))) + .addComponent(documentsCheckbox))) .addComponent(allFileCategoriesRadioButton) .addComponent(selectedFileCategoriesButton) .addComponent(interCaseRadio) @@ -596,6 +607,10 @@ public final class CommonFilesPanel extends javax.swing.JPanel { handleInterCaseSearchCriteriaChanged(); }//GEN-LAST:event_interCaseRadioActionPerformed + private void formWindowClosed(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowClosed + SwingUtilities.windowForComponent(this).dispose(); + }//GEN-LAST:event_formWindowClosed + public void handleInterCaseSearchCriteriaChanged() { if (this.areInterCaseSearchCriteriaMet()) { this.searchButton.setEnabled(true); diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesSearchAction.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesSearchAction.java index c902a2d00b..cc09b5ccec 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesSearchAction.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesSearchAction.java @@ -70,12 +70,12 @@ final public class CommonFilesSearchAction extends CallableSystemAction { @Override public void actionPerformed(ActionEvent event) { - new CommonFilesDialog().setVisible(true); + new CommonFilesPanel().setVisible(true); } @Override public void performAction() { - new CommonFilesDialog().setVisible(true); + new CommonFilesPanel().setVisible(true); } @NbBundle.Messages({ From 78d47955f41db321a3a73fdee6a853192e1a34f0 Mon Sep 17 00:00:00 2001 From: Andrew Ziehl Date: Mon, 16 Jul 2018 16:58:27 -0700 Subject: [PATCH 132/287] Renames. --- ...a => AbstractCommonAttributeSearcher.java} | 12 +- ... AllInterCaseCommonAttributeSearcher.java} | 12 +- ... AllIntraCaseCommonAttributeSearcher.java} | 4 +- .../commonfilesearch/Bundle.properties | 28 +- ....java => CommonAttributeInstanceNode.java} | 4 +- .../CommonAttributePanel.form | 304 ++++++++++++++++++ ...esPanel.java => CommonAttributePanel.java} | 194 +++++------ ...a => CommonAttributeSearchResultNode.java} | 12 +- ...java => CommonAttributeSearchResults.java} | 16 +- ...etadata.java => CommonAttributeValue.java} | 6 +- ...ode.java => CommonAttributeValueNode.java} | 12 +- ...onAttributesSearchResultsViewerTable.java} | 4 +- .../commonfilesearch/CommonFilesPanel.form | 270 ---------------- .../CommonFilesSearchAction.java | 4 +- .../FileInstanceNodeGenerator.java | 2 +- .../commonfilesearch/InstanceCountNode.java | 18 +- ...InterCaseCommonAttributeInstanceNode.java} | 6 +- ...nterCaseCommonAttributeSearchResults.java} | 12 +- ... => InterCaseCommonAttributeSearcher.java} | 14 +- .../commonfilesearch/InterCasePanel.java | 4 +- ...a => InterCaseSearchResultsProcessor.java} | 4 +- ...IntraCaseCommonAttributeInstanceNode.java} | 4 +- ...ntraCaseCommonAttributeSearchResults.java} | 8 +- ... => IntraCaseCommonAttributeSearcher.java} | 20 +- .../commonfilesearch/IntraCasePanel.java | 6 +- ...ngleInterCaseCommonAttributeSearcher.java} | 14 +- ...ngleIntraCaseCommonAttributeSearcher.java} | 6 +- .../datamodel/DisplayableItemNodeVisitor.java | 24 +- .../directorytree/DataResultFilterNode.java | 8 +- ...stedWithHashAndFileTypeInterCaseTests.java | 10 +- ...stedWithHashAndFileTypeIntraCaseTests.java | 44 +-- ...IngestedWithNoFileTypesIntraCaseTests.java | 16 +- .../commonfilessearch/InterCaseUtils.java | 16 +- .../commonfilessearch/IntraCaseUtils.java | 14 +- .../NoCentralRepoEnabledInterCaseTests.java | 10 +- .../UningestedCasesIntraCaseTests.java | 16 +- 36 files changed, 603 insertions(+), 555 deletions(-) rename Core/src/org/sleuthkit/autopsy/commonfilesearch/{AbstractCommonFilesMetadataBuilder.java => AbstractCommonAttributeSearcher.java} (91%) rename Core/src/org/sleuthkit/autopsy/commonfilesearch/{AllCasesEamDbCommonFilesAlgorithm.java => AllInterCaseCommonAttributeSearcher.java} (74%) rename Core/src/org/sleuthkit/autopsy/commonfilesearch/{AllDataSourcesCommonFilesAlgorithm.java => AllIntraCaseCommonAttributeSearcher.java} (89%) rename Core/src/org/sleuthkit/autopsy/commonfilesearch/{FileInstanceNode.java => CommonAttributeInstanceNode.java} (96%) create mode 100644 Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributePanel.form rename Core/src/org/sleuthkit/autopsy/commonfilesearch/{CommonFilesPanel.java => CommonAttributePanel.java} (77%) rename Core/src/org/sleuthkit/autopsy/commonfilesearch/{CommonFilesNode.java => CommonAttributeSearchResultNode.java} (83%) rename Core/src/org/sleuthkit/autopsy/commonfilesearch/{CommonFilesMetadata.java => CommonAttributeSearchResults.java} (75%) rename Core/src/org/sleuthkit/autopsy/commonfilesearch/{Md5Metadata.java => CommonAttributeValue.java} (93%) rename Core/src/org/sleuthkit/autopsy/commonfilesearch/{Md5Node.java => CommonAttributeValueNode.java} (92%) rename Core/src/org/sleuthkit/autopsy/commonfilesearch/{CommonFilesSearchResultsViewerTable.java => CommonAttributesSearchResultsViewerTable.java} (95%) delete mode 100644 Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.form rename Core/src/org/sleuthkit/autopsy/commonfilesearch/{CentralRepositoryFileInstanceNode.java => InterCaseCommonAttributeInstanceNode.java} (95%) rename Core/src/org/sleuthkit/autopsy/commonfilesearch/{CentralRepositoryCaseFileInstanceMetadata.java => InterCaseCommonAttributeSearchResults.java} (82%) rename Core/src/org/sleuthkit/autopsy/commonfilesearch/{InterCaseCommonFilesMetadataBuilder.java => InterCaseCommonAttributeSearcher.java} (86%) rename Core/src/org/sleuthkit/autopsy/commonfilesearch/{EamDbAttributeInstancesAlgorithm.java => InterCaseSearchResultsProcessor.java} (98%) rename Core/src/org/sleuthkit/autopsy/commonfilesearch/{SleuthkitCaseFileInstanceNode.java => IntraCaseCommonAttributeInstanceNode.java} (95%) rename Core/src/org/sleuthkit/autopsy/commonfilesearch/{SleuthkitCaseFileInstanceMetadata.java => IntraCaseCommonAttributeSearchResults.java} (72%) rename Core/src/org/sleuthkit/autopsy/commonfilesearch/{IntraCaseCommonFilesMetadataBuilder.java => IntraCaseCommonAttributeSearcher.java} (84%) rename Core/src/org/sleuthkit/autopsy/commonfilesearch/{SingleCaseEamDbCommonFilesAlgorithm.java => SingleInterCaseCommonAttributeSearcher.java} (77%) rename Core/src/org/sleuthkit/autopsy/commonfilesearch/{SingleDataSourceCommonFilesAlgorithm.java => SingleIntraCaseCommonAttributeSearcher.java} (87%) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonFilesMetadataBuilder.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeSearcher.java similarity index 91% rename from Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonFilesMetadataBuilder.java rename to Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeSearcher.java index 9190ac1a73..840e765285 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonFilesMetadataBuilder.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeSearcher.java @@ -31,12 +31,12 @@ import org.openide.util.NbBundle; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; import org.sleuthkit.datamodel.TskCoreException; -abstract class AbstractCommonFilesMetadataBuilder { +abstract class AbstractCommonAttributeSearcher { boolean filterByMedia; boolean filterByDoc; - abstract CommonFilesMetadata findFiles() throws TskCoreException, NoCurrentCaseException, SQLException, Exception; + abstract CommonAttributeSearchResults findFiles() throws TskCoreException, NoCurrentCaseException, SQLException, Exception; @NbBundle.Messages({ "AbstractCommonFilesMetadataBuilder.buildTabTitle.titleIntraAll=Common Files (All Data Sources, %s)", @@ -66,16 +66,16 @@ abstract class AbstractCommonFilesMetadataBuilder { } } - static Map> collateMatchesByNumberOfInstances(Map commonFiles) { + static Map> collateMatchesByNumberOfInstances(Map commonFiles) { //collate matches by number of matching instances - doing this in sql doesnt seem efficient - Map> instanceCollatedCommonFiles = new TreeMap<>(); - for(Md5Metadata md5Metadata : commonFiles.values()){ + Map> instanceCollatedCommonFiles = new TreeMap<>(); + for(CommonAttributeValue md5Metadata : commonFiles.values()){ Integer size = md5Metadata.size(); if(instanceCollatedCommonFiles.containsKey(size)){ instanceCollatedCommonFiles.get(size).add(md5Metadata); } else { - ArrayList value = new ArrayList<>(); + ArrayList value = new ArrayList<>(); value.add(md5Metadata); instanceCollatedCommonFiles.put(size, value); } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllCasesEamDbCommonFilesAlgorithm.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllInterCaseCommonAttributeSearcher.java similarity index 74% rename from Core/src/org/sleuthkit/autopsy/commonfilesearch/AllCasesEamDbCommonFilesAlgorithm.java rename to Core/src/org/sleuthkit/autopsy/commonfilesearch/AllInterCaseCommonAttributeSearcher.java index f7d1c65b41..b16ffc65dc 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllCasesEamDbCommonFilesAlgorithm.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllInterCaseCommonAttributeSearcher.java @@ -32,21 +32,21 @@ import org.sleuthkit.datamodel.TskCoreException; * Algorithm which finds files anywhere in the Central Repo which also occur in * present case. */ -public class AllCasesEamDbCommonFilesAlgorithm extends InterCaseCommonFilesMetadataBuilder { +public class AllInterCaseCommonAttributeSearcher extends InterCaseCommonAttributeSearcher { - public AllCasesEamDbCommonFilesAlgorithm(boolean filterByMediaMimeType, boolean filterByDocMimeType) throws EamDbException { + public AllInterCaseCommonAttributeSearcher(boolean filterByMediaMimeType, boolean filterByDocMimeType) throws EamDbException { super(filterByMediaMimeType, filterByDocMimeType); } @Override - public CommonFilesMetadata findFiles() throws TskCoreException, NoCurrentCaseException, SQLException, EamDbException, Exception { - Map> interCaseCommonFiles = new HashMap<>(); + public CommonAttributeSearchResults findFiles() throws TskCoreException, NoCurrentCaseException, SQLException, EamDbException, Exception { + Map> interCaseCommonFiles = new HashMap<>(); - EamDbAttributeInstancesAlgorithm eamDbAttrInst = new EamDbAttributeInstancesAlgorithm(); + InterCaseSearchResultsProcessor eamDbAttrInst = new InterCaseSearchResultsProcessor(); eamDbAttrInst.processCorrelationCaseAttributeValues(Case.getCurrentCase()); interCaseCommonFiles = gatherIntercaseResults(eamDbAttrInst.getIntercaseCommonValuesMap(), eamDbAttrInst.getIntercaseCommonCasesMap()); - return new CommonFilesMetadata(interCaseCommonFiles); + return new CommonAttributeSearchResults(interCaseCommonFiles); } @Override diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllDataSourcesCommonFilesAlgorithm.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllIntraCaseCommonAttributeSearcher.java similarity index 89% rename from Core/src/org/sleuthkit/autopsy/commonfilesearch/AllDataSourcesCommonFilesAlgorithm.java rename to Core/src/org/sleuthkit/autopsy/commonfilesearch/AllIntraCaseCommonAttributeSearcher.java index e330ddc05e..a4237b6679 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllDataSourcesCommonFilesAlgorithm.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllIntraCaseCommonAttributeSearcher.java @@ -25,7 +25,7 @@ import org.sleuthkit.datamodel.TskData.FileKnown; /** * Provides logic for selecting common files from all data sources. */ -final public class AllDataSourcesCommonFilesAlgorithm extends IntraCaseCommonFilesMetadataBuilder { +final public class AllIntraCaseCommonAttributeSearcher extends IntraCaseCommonAttributeSearcher { private static final String WHERE_CLAUSE = "%s md5 in (select md5 from tsk_files where (known != "+ FileKnown.KNOWN.getFileKnownValue() + " OR known IS NULL)%s GROUP BY md5 HAVING COUNT(DISTINCT data_source_obj_id) > 1) order by md5"; //NON-NLS @@ -37,7 +37,7 @@ final public class AllDataSourcesCommonFilesAlgorithm extends IntraCaseCommonFil * @param filterByMediaMimeType match only on files whose mime types can be broadly categorized as media types * @param filterByDocMimeType match only on files whose mime types can be broadly categorized as document types */ - public AllDataSourcesCommonFilesAlgorithm(Map dataSourceIdMap, boolean filterByMediaMimeType, boolean filterByDocMimeType) { + public AllIntraCaseCommonAttributeSearcher(Map dataSourceIdMap, boolean filterByMediaMimeType, boolean filterByDocMimeType) { super(dataSourceIdMap, filterByMediaMimeType, filterByDocMimeType); } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/Bundle.properties b/Core/src/org/sleuthkit/autopsy/commonfilesearch/Bundle.properties index 790a8d541b..fbdc43d143 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/Bundle.properties @@ -1,16 +1,5 @@ -CommonFilesPanel.searchButton.text=Search -CommonFilesPanel.cancelButton.text=Cancel -CommonFilesPanel.cancelButton.actionCommand=Cancel -CommonFilesPanel.selectedFileCategoriesButton.text=Only the selected file types: -CommonFilesPanel.selectedFileCategoriesButton.toolTipText=Select from the options below... -CommonFilesPanel.pictureVideoCheckbox.text=Pictures and Videos -CommonFilesPanel.documentsCheckbox.text=Documents CommonFilesPanel.commonFilesSearchLabel.text=Find files in multiple data sources in the current case. -CommonFilesPanel.allFileCategoriesRadioButton.toolTipText=No filtering applied to results... -CommonFilesPanel.allFileCategoriesRadioButton.text=All file types CommonFilesPanel.text=Indicate which data sources to consider while searching for duplicates: -CommonFilesPanel.categoriesLabel.text=File Types To Include: -CommonFilesPanel.errorText.text=In order to search, you must select a file category. CommonFilesPanel.jRadioButton1.text=jRadioButton1 CommonFilesPanel.jRadioButton2.text=With previous cases in the Central Repository CommonFilesPanel.intraCaseRadio.label=Correlate within current case only @@ -19,6 +8,17 @@ IntraCasePanel.allDataSourcesRadioButton.text=Matches may be from any data sourc IntraCasePanel.withinDataSourceRadioButton.text=At least one match must appear in the data source selected below: InterCasePanel.specificCentralRepoCaseRadio.text=Matches must be from the following Central Repo case: InterCasePanel.anyCentralRepoCaseRadio.text=Matches may be from any Central Repo case -CommonFilesPanel.commonFilesSearchLabel1.text=Find common files to correlate data soures or cases. -CommonFilesPanel.commonFilesSearchLabel2.text=Scope of Search -CommonFilesPanel.intraCaseRadio.text=Within current case +CommonAttributePanel.selectedFileCategoriesButton.toolTipText=Select from the options below... +CommonAttributePanel.selectedFileCategoriesButton.text=Only the selected file types: +CommonAttributePanel.allFileCategoriesRadioButton.toolTipText=No filtering applied to results... +CommonAttributePanel.allFileCategoriesRadioButton.text=All file types +CommonAttributePanel.cancelButton.actionCommand=Cancel +CommonAttributePanel.cancelButton.text=Cancel +CommonAttributePanel.searchButton.text=Search +CommonAttributePanel.commonFilesSearchLabel2.text=Scope of Search +CommonAttributePanel.intraCaseRadio.text=Within current case +CommonAttributePanel.commonFilesSearchLabel1.text=Find common files to correlate data soures or cases. +CommonAttributePanel.errorText.text=In order to search, you must select a file category. +CommonAttributePanel.categoriesLabel.text=File Types To Include: +CommonAttributePanel.documentsCheckbox.text=Documents +CommonAttributePanel.pictureVideoCheckbox.text=Pictures and Videos diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/FileInstanceNode.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeInstanceNode.java similarity index 96% rename from Core/src/org/sleuthkit/autopsy/commonfilesearch/FileInstanceNode.java rename to Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeInstanceNode.java index 6138c0f78f..1b385467d4 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/FileInstanceNode.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeInstanceNode.java @@ -31,7 +31,7 @@ import org.sleuthkit.datamodel.AbstractFile; * Used by the Common Files search feature to encapsulate instances of a given MD5s matched in the search. These nodes will be children of Md5Nodes. */ -public class FileInstanceNode extends FileNode { +public class CommonAttributeInstanceNode extends FileNode { private final String dataSource; @@ -42,7 +42,7 @@ public class FileInstanceNode extends FileNode { * @param fsContent * @param dataSource */ - public FileInstanceNode(AbstractFile fsContent, String dataSource) { + public CommonAttributeInstanceNode(AbstractFile fsContent, String dataSource) { super(fsContent); this.dataSource = dataSource; diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributePanel.form b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributePanel.form new file mode 100644 index 0000000000..601366d8f0 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributePanel.form @@ -0,0 +1,304 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributePanel.java similarity index 77% rename from Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java rename to Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributePanel.java index 6b57b40f3f..24f1352598 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributePanel.java @@ -52,13 +52,13 @@ import org.sleuthkit.datamodel.TskCoreException; * logic. Nested within CommonFilesDialog. */ @SuppressWarnings("PMD.SingularField") // UI widgets cause lots of false positives -public final class CommonFilesPanel extends javax.swing.JDialog { +public final class CommonAttributePanel extends javax.swing.JDialog { private static final long serialVersionUID = 1L; private static final Long NO_DATA_SOURCE_SELECTED = -1L; - private static final Logger LOGGER = Logger.getLogger(CommonFilesPanel.class.getName()); + private static final Logger LOGGER = Logger.getLogger(CommonAttributePanel.class.getName()); private boolean pictureViewCheckboxState; private boolean documentsCheckboxState; @@ -70,16 +70,15 @@ public final class CommonFilesPanel extends javax.swing.JDialog { "CommonFilesPanel.exception=Unexpected Exception loading DataSources.", "CommonFilesPanel.frame.title=Find Common Files", "CommonFilesPanel.frame.msg=Find Common Files"}) - public CommonFilesPanel() { - super(new JFrame(Bundle.CommonFilesDialog_frame_title()), - Bundle.CommonFilesDialog_frame_msg(), true); + public CommonAttributePanel() { + super(new JFrame(Bundle.CommonFilesPanel_frame_title()), + Bundle.CommonFilesPanel_frame_msg(), true); initComponents(); - this.setResizable(false); this.setLocationRelativeTo(WindowManager.getDefault().getMainWindow()); this.errorText.setVisible(false); this.setupDataSources(); - if (CommonFilesPanel.isEamDbAvailable()) { + if (CommonAttributePanel.isEamDbAvailable()) { this.setupCases(); } else { this.disableIntercaseSearch(); @@ -115,7 +114,7 @@ public final class CommonFilesPanel extends javax.swing.JDialog { private void search() { String pathText = Bundle.CommonFilesPanel_search_results_pathText(); - new SwingWorker() { + new SwingWorker() { private String tabTitle; private ProgressHandle progress; @@ -133,7 +132,7 @@ public final class CommonFilesPanel extends javax.swing.JDialog { @Override @SuppressWarnings({"BoxedValueEquality", "NumberEquality"}) - protected CommonFilesMetadata doInBackground() throws TskCoreException, NoCurrentCaseException, SQLException, EamDbException, Exception { + protected CommonAttributeSearchResults doInBackground() throws TskCoreException, NoCurrentCaseException, SQLException, EamDbException, Exception { progress = ProgressHandle.createHandle(Bundle.CommonFilesPanel_search_done_searchProgressGathering()); progress.start(); progress.switchToIndeterminate(); @@ -141,8 +140,8 @@ public final class CommonFilesPanel extends javax.swing.JDialog { Long dataSourceId = intraCasePanel.getSelectedDataSourceId(); Integer caseId = interCasePanel.getSelectedCaseId(); - AbstractCommonFilesMetadataBuilder builder; - CommonFilesMetadata metadata; + AbstractCommonAttributeSearcher builder; + CommonAttributeSearchResults metadata; boolean filterByMedia = false; boolean filterByDocuments = false; @@ -155,20 +154,20 @@ public final class CommonFilesPanel extends javax.swing.JDialog { } } - if (CommonFilesPanel.this.interCaseRadio.isSelected()) { + if (CommonAttributePanel.this.interCaseRadio.isSelected()) { if (caseId == InterCasePanel.NO_CASE_SELECTED) { - builder = new AllCasesEamDbCommonFilesAlgorithm(filterByMedia, filterByDocuments); + builder = new AllInterCaseCommonAttributeSearcher(filterByMedia, filterByDocuments); } else { - builder = new SingleCaseEamDbCommonFilesAlgorithm(caseId, filterByMedia, filterByDocuments); + builder = new SingleInterCaseCommonAttributeSearcher(caseId, filterByMedia, filterByDocuments); } } else { - if (dataSourceId == CommonFilesPanel.NO_DATA_SOURCE_SELECTED) { - builder = new AllDataSourcesCommonFilesAlgorithm(intraCasePanel.getDataSourceMap(), filterByMedia, filterByDocuments); + if (dataSourceId == CommonAttributePanel.NO_DATA_SOURCE_SELECTED) { + builder = new AllIntraCaseCommonAttributeSearcher(intraCasePanel.getDataSourceMap(), filterByMedia, filterByDocuments); setTitleForAllDataSources(); } else { - builder = new SingleDataSourceCommonFilesAlgorithm(dataSourceId, intraCasePanel.getDataSourceMap(), filterByMedia, filterByDocuments); + builder = new SingleIntraCaseCommonAttributeSearcher(dataSourceId, intraCasePanel.getDataSourceMap(), filterByMedia, filterByDocuments); setTitleForSingleSource(dataSourceId); } @@ -184,16 +183,16 @@ public final class CommonFilesPanel extends javax.swing.JDialog { try { super.done(); - CommonFilesMetadata metadata = this.get(); + CommonAttributeSearchResults metadata = this.get(); - CommonFilesNode commonFilesNode = new CommonFilesNode(metadata); + CommonAttributeSearchResultNode commonFilesNode = new CommonAttributeSearchResultNode(metadata); // #VIK-3969 - DataResultFilterNode dataResultFilterNode = new DataResultFilterNode(commonFilesNode, ExplorerManager.find(CommonFilesPanel.this)); + DataResultFilterNode dataResultFilterNode = new DataResultFilterNode(commonFilesNode, ExplorerManager.find(CommonAttributePanel.this)); TableFilterNode tableFilterWithDescendantsNode = new TableFilterNode(dataResultFilterNode, 3); - DataResultViewerTable table = new CommonFilesSearchResultsViewerTable(); + DataResultViewerTable table = new CommonAttributesSearchResultsViewerTable(); Collection viewers = new ArrayList<>(1); viewers.add(table); @@ -248,25 +247,25 @@ public final class CommonFilesPanel extends javax.swing.JDialog { private void updateUi() { - final Map dataSourceMap = CommonFilesPanel.this.intraCasePanel.getDataSourceMap(); + final Map dataSourceMap = CommonAttributePanel.this.intraCasePanel.getDataSourceMap(); String[] dataSourcesNames = new String[dataSourceMap.size()]; //only enable all this stuff if we actually have datasources if (dataSourcesNames.length > 0) { dataSourcesNames = dataSourceMap.values().toArray(dataSourcesNames); - CommonFilesPanel.this.intraCasePanel.setDataModel(new DataSourceComboBoxModel(dataSourcesNames)); + CommonAttributePanel.this.intraCasePanel.setDataModel(new DataSourceComboBoxModel(dataSourcesNames)); boolean multipleDataSources = this.caseHasMultipleSources(); - CommonFilesPanel.this.intraCasePanel.rigForMultipleDataSources(multipleDataSources); + CommonAttributePanel.this.intraCasePanel.rigForMultipleDataSources(multipleDataSources); //TODO this should be attached to the intra/inter radio buttons - CommonFilesPanel.this.setSearchButtonEnabled(true); + CommonAttributePanel.this.setSearchButtonEnabled(true); } } private boolean caseHasMultipleSources() { - return CommonFilesPanel.this.intraCasePanel.getDataSourceMap().size() > 2; + return CommonAttributePanel.this.intraCasePanel.getDataSourceMap().size() > 2; } @Override @@ -279,7 +278,7 @@ public final class CommonFilesPanel extends javax.swing.JDialog { protected void done() { try { - CommonFilesPanel.this.intraCasePanel.setDataSourceMap(this.get()); + CommonAttributePanel.this.intraCasePanel.setDataSourceMap(this.get()); updateUi(); } catch (InterruptedException ex) { @@ -316,19 +315,19 @@ public final class CommonFilesPanel extends javax.swing.JDialog { private void updateUi() { - final Map caseMap = CommonFilesPanel.this.interCasePanel.getCaseMap(); + final Map caseMap = CommonAttributePanel.this.interCasePanel.getCaseMap(); String[] caseNames = new String[caseMap.size()]; if (caseNames.length > 0) { caseNames = caseMap.values().toArray(caseNames); - CommonFilesPanel.this.interCasePanel.setCaseList(new DataSourceComboBoxModel(caseNames)); + CommonAttributePanel.this.interCasePanel.setCaseList(new DataSourceComboBoxModel(caseNames)); boolean multipleCases = this.centralRepoHasMultipleCases(); - CommonFilesPanel.this.interCasePanel.rigForMultipleCases(multipleCases); + CommonAttributePanel.this.interCasePanel.rigForMultipleCases(multipleCases); } else { - CommonFilesPanel.this.disableIntercaseSearch(); + CommonAttributePanel.this.disableIntercaseSearch(); } } @@ -357,7 +356,7 @@ public final class CommonFilesPanel extends javax.swing.JDialog { protected void done() { try { Map cases = this.get(); - CommonFilesPanel.this.interCasePanel.setCaseMap(cases); + CommonAttributePanel.this.interCasePanel.setCaseMap(cases); this.updateUi(); } catch (InterruptedException ex) { LOGGER.log(Level.SEVERE, "Interrupted while building Common Files Search dialog.", ex); @@ -369,7 +368,7 @@ public final class CommonFilesPanel extends javax.swing.JDialog { } private boolean centralRepoHasMultipleCases() { - return CommonFilesPanel.this.interCasePanel.centralRepoHasMultipleCases(); + return CommonAttributePanel.this.interCasePanel.centralRepoHasMultipleCases(); } }.execute(); @@ -386,6 +385,7 @@ public final class CommonFilesPanel extends javax.swing.JDialog { fileTypeFilterButtonGroup = new javax.swing.ButtonGroup(); interIntraButtonGroup = new javax.swing.ButtonGroup(); + jPanel1 = new javax.swing.JPanel(); commonFilesSearchLabel2 = new javax.swing.JLabel(); searchButton = new javax.swing.JButton(); cancelButton = new javax.swing.JButton(); @@ -402,16 +402,21 @@ public final class CommonFilesPanel extends javax.swing.JDialog { intraCasePanel = new org.sleuthkit.autopsy.commonfilesearch.IntraCasePanel(); interCasePanel = new org.sleuthkit.autopsy.commonfilesearch.InterCasePanel(); + setMinimumSize(new java.awt.Dimension(412, 350)); + setPreferredSize(new java.awt.Dimension(412, 350)); + setResizable(false); addWindowListener(new java.awt.event.WindowAdapter() { public void windowClosed(java.awt.event.WindowEvent evt) { formWindowClosed(evt); } }); - org.openide.awt.Mnemonics.setLocalizedText(commonFilesSearchLabel2, org.openide.util.NbBundle.getMessage(CommonFilesPanel.class, "CommonFilesPanel.commonFilesSearchLabel2.text")); // NOI18N + jPanel1.setPreferredSize(new java.awt.Dimension(412, 350)); + + org.openide.awt.Mnemonics.setLocalizedText(commonFilesSearchLabel2, org.openide.util.NbBundle.getMessage(CommonAttributePanel.class, "CommonAttributePanel.commonFilesSearchLabel2.text")); // NOI18N commonFilesSearchLabel2.setFocusable(false); - org.openide.awt.Mnemonics.setLocalizedText(searchButton, org.openide.util.NbBundle.getMessage(CommonFilesPanel.class, "CommonFilesPanel.searchButton.text")); // NOI18N + org.openide.awt.Mnemonics.setLocalizedText(searchButton, org.openide.util.NbBundle.getMessage(CommonAttributePanel.class, "CommonAttributePanel.searchButton.text")); // NOI18N searchButton.setEnabled(false); searchButton.setHorizontalTextPosition(javax.swing.SwingConstants.LEADING); searchButton.addActionListener(new java.awt.event.ActionListener() { @@ -420,8 +425,8 @@ public final class CommonFilesPanel extends javax.swing.JDialog { } }); - org.openide.awt.Mnemonics.setLocalizedText(cancelButton, org.openide.util.NbBundle.getMessage(CommonFilesPanel.class, "CommonFilesPanel.cancelButton.text")); // NOI18N - cancelButton.setActionCommand(org.openide.util.NbBundle.getMessage(CommonFilesPanel.class, "CommonFilesPanel.cancelButton.actionCommand")); // NOI18N + org.openide.awt.Mnemonics.setLocalizedText(cancelButton, org.openide.util.NbBundle.getMessage(CommonAttributePanel.class, "CommonAttributePanel.cancelButton.text")); // NOI18N + cancelButton.setActionCommand(org.openide.util.NbBundle.getMessage(CommonAttributePanel.class, "CommonAttributePanel.cancelButton.actionCommand")); // NOI18N cancelButton.setHorizontalTextPosition(javax.swing.SwingConstants.LEADING); cancelButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { @@ -430,8 +435,8 @@ public final class CommonFilesPanel extends javax.swing.JDialog { }); fileTypeFilterButtonGroup.add(allFileCategoriesRadioButton); - org.openide.awt.Mnemonics.setLocalizedText(allFileCategoriesRadioButton, org.openide.util.NbBundle.getMessage(CommonFilesPanel.class, "CommonFilesPanel.allFileCategoriesRadioButton.text")); // NOI18N - allFileCategoriesRadioButton.setToolTipText(org.openide.util.NbBundle.getMessage(CommonFilesPanel.class, "CommonFilesPanel.allFileCategoriesRadioButton.toolTipText")); // NOI18N + org.openide.awt.Mnemonics.setLocalizedText(allFileCategoriesRadioButton, org.openide.util.NbBundle.getMessage(CommonAttributePanel.class, "CommonAttributePanel.allFileCategoriesRadioButton.text")); // NOI18N + allFileCategoriesRadioButton.setToolTipText(org.openide.util.NbBundle.getMessage(CommonAttributePanel.class, "CommonAttributePanel.allFileCategoriesRadioButton.toolTipText")); // NOI18N allFileCategoriesRadioButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { allFileCategoriesRadioButtonActionPerformed(evt); @@ -440,8 +445,8 @@ public final class CommonFilesPanel extends javax.swing.JDialog { fileTypeFilterButtonGroup.add(selectedFileCategoriesButton); selectedFileCategoriesButton.setSelected(true); - org.openide.awt.Mnemonics.setLocalizedText(selectedFileCategoriesButton, org.openide.util.NbBundle.getMessage(CommonFilesPanel.class, "CommonFilesPanel.selectedFileCategoriesButton.text")); // NOI18N - selectedFileCategoriesButton.setToolTipText(org.openide.util.NbBundle.getMessage(CommonFilesPanel.class, "CommonFilesPanel.selectedFileCategoriesButton.toolTipText")); // NOI18N + org.openide.awt.Mnemonics.setLocalizedText(selectedFileCategoriesButton, org.openide.util.NbBundle.getMessage(CommonAttributePanel.class, "CommonAttributePanel.selectedFileCategoriesButton.text")); // NOI18N + selectedFileCategoriesButton.setToolTipText(org.openide.util.NbBundle.getMessage(CommonAttributePanel.class, "CommonAttributePanel.selectedFileCategoriesButton.toolTipText")); // NOI18N selectedFileCategoriesButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { selectedFileCategoriesButtonActionPerformed(evt); @@ -449,7 +454,7 @@ public final class CommonFilesPanel extends javax.swing.JDialog { }); pictureVideoCheckbox.setSelected(true); - org.openide.awt.Mnemonics.setLocalizedText(pictureVideoCheckbox, org.openide.util.NbBundle.getMessage(CommonFilesPanel.class, "CommonFilesPanel.pictureVideoCheckbox.text")); // NOI18N + org.openide.awt.Mnemonics.setLocalizedText(pictureVideoCheckbox, org.openide.util.NbBundle.getMessage(CommonAttributePanel.class, "CommonAttributePanel.pictureVideoCheckbox.text")); // NOI18N pictureVideoCheckbox.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { pictureVideoCheckboxActionPerformed(evt); @@ -457,25 +462,25 @@ public final class CommonFilesPanel extends javax.swing.JDialog { }); documentsCheckbox.setSelected(true); - org.openide.awt.Mnemonics.setLocalizedText(documentsCheckbox, org.openide.util.NbBundle.getMessage(CommonFilesPanel.class, "CommonFilesPanel.documentsCheckbox.text")); // NOI18N + org.openide.awt.Mnemonics.setLocalizedText(documentsCheckbox, org.openide.util.NbBundle.getMessage(CommonAttributePanel.class, "CommonAttributePanel.documentsCheckbox.text")); // NOI18N documentsCheckbox.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { documentsCheckboxActionPerformed(evt); } }); - org.openide.awt.Mnemonics.setLocalizedText(categoriesLabel, org.openide.util.NbBundle.getMessage(CommonFilesPanel.class, "CommonFilesPanel.categoriesLabel.text")); // NOI18N + org.openide.awt.Mnemonics.setLocalizedText(categoriesLabel, org.openide.util.NbBundle.getMessage(CommonAttributePanel.class, "CommonAttributePanel.categoriesLabel.text")); // NOI18N categoriesLabel.setName(""); // NOI18N errorText.setForeground(new java.awt.Color(255, 0, 0)); - org.openide.awt.Mnemonics.setLocalizedText(errorText, org.openide.util.NbBundle.getMessage(CommonFilesPanel.class, "CommonFilesPanel.errorText.text")); // NOI18N + org.openide.awt.Mnemonics.setLocalizedText(errorText, org.openide.util.NbBundle.getMessage(CommonAttributePanel.class, "CommonAttributePanel.errorText.text")); // NOI18N - org.openide.awt.Mnemonics.setLocalizedText(commonFilesSearchLabel1, org.openide.util.NbBundle.getMessage(CommonFilesPanel.class, "CommonFilesPanel.commonFilesSearchLabel1.text")); // NOI18N + org.openide.awt.Mnemonics.setLocalizedText(commonFilesSearchLabel1, org.openide.util.NbBundle.getMessage(CommonAttributePanel.class, "CommonAttributePanel.commonFilesSearchLabel1.text")); // NOI18N commonFilesSearchLabel1.setFocusable(false); interIntraButtonGroup.add(intraCaseRadio); intraCaseRadio.setSelected(true); - org.openide.awt.Mnemonics.setLocalizedText(intraCaseRadio, org.openide.util.NbBundle.getMessage(CommonFilesPanel.class, "CommonFilesPanel.intraCaseRadio.text")); // NOI18N + org.openide.awt.Mnemonics.setLocalizedText(intraCaseRadio, org.openide.util.NbBundle.getMessage(CommonAttributePanel.class, "CommonAttributePanel.intraCaseRadio.text")); // NOI18N intraCaseRadio.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { intraCaseRadioActionPerformed(evt); @@ -483,7 +488,7 @@ public final class CommonFilesPanel extends javax.swing.JDialog { }); interIntraButtonGroup.add(interCaseRadio); - org.openide.awt.Mnemonics.setLocalizedText(interCaseRadio, org.openide.util.NbBundle.getMessage(CommonFilesPanel.class, "CommonFilesPanel.jRadioButton2.text")); // NOI18N + org.openide.awt.Mnemonics.setLocalizedText(interCaseRadio, org.openide.util.NbBundle.getMessage(CommonAttributePanel.class, "CommonFilesPanel.jRadioButton2.text")); // NOI18N interCaseRadio.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { interCaseRadioActionPerformed(evt); @@ -494,55 +499,55 @@ public final class CommonFilesPanel extends javax.swing.JDialog { layoutPanel.add(intraCasePanel, "card3"); layoutPanel.add(interCasePanel, "card2"); - javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); - getContentPane().setLayout(layout); - layout.setHorizontalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addContainerGap() - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addGap(6, 6, 6) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addGap(21, 21, 21) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(pictureVideoCheckbox) - .addComponent(documentsCheckbox))) - .addComponent(allFileCategoriesRadioButton) - .addComponent(selectedFileCategoriesButton) - .addComponent(interCaseRadio) + javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1); + jPanel1.setLayout(jPanel1Layout); + jPanel1Layout.setHorizontalGroup( + jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createSequentialGroup() + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createSequentialGroup() + .addContainerGap() + .addComponent(searchButton) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(cancelButton) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(errorText)) + .addGroup(jPanel1Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(commonFilesSearchLabel2) .addComponent(intraCaseRadio) - .addGroup(layout.createSequentialGroup() - .addGap(10, 10, 10) - .addComponent(layoutPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))) - .addGroup(layout.createSequentialGroup() - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(interCaseRadio) .addComponent(commonFilesSearchLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(categoriesLabel) - .addComponent(commonFilesSearchLabel2) - .addGroup(layout.createSequentialGroup() - .addComponent(searchButton) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(cancelButton) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(errorText))) - .addContainerGap()))) + .addComponent(selectedFileCategoriesButton))) + .addGroup(jPanel1Layout.createSequentialGroup() + .addGap(35, 35, 35) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(documentsCheckbox) + .addComponent(pictureVideoCheckbox))) + .addGroup(jPanel1Layout.createSequentialGroup() + .addContainerGap() + .addComponent(allFileCategoriesRadioButton))) + .addContainerGap()) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createSequentialGroup() + .addGap(20, 20, 20) + .addComponent(layoutPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(10, 10, 10))) ); - layout.setVerticalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + jPanel1Layout.setVerticalGroup( + jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createSequentialGroup() .addContainerGap() .addComponent(commonFilesSearchLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGap(18, 18, 18) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(commonFilesSearchLabel2) - .addGap(2, 2, 2) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(intraCaseRadio) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(interCaseRadio) - .addGap(0, 0, 0) - .addComponent(layoutPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGap(0, 0, 0) + .addGap(79, 79, 79) .addComponent(categoriesLabel) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(selectedFileCategoriesButton) @@ -553,11 +558,19 @@ public final class CommonFilesPanel extends javax.swing.JDialog { .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(allFileCategoriesRadioButton) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(cancelButton) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(searchButton) - .addComponent(errorText))) + .addComponent(cancelButton) + .addComponent(errorText)) + .addContainerGap()) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup() + .addGap(98, 98, 98) + .addComponent(layoutPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(180, 180, 180))) ); + + getContentPane().add(jPanel1, java.awt.BorderLayout.CENTER); }// //GEN-END:initComponents private void searchButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_searchButtonActionPerformed @@ -668,6 +681,7 @@ public final class CommonFilesPanel extends javax.swing.JDialog { private javax.swing.ButtonGroup interIntraButtonGroup; private org.sleuthkit.autopsy.commonfilesearch.IntraCasePanel intraCasePanel; private javax.swing.JRadioButton intraCaseRadio; + private javax.swing.JPanel jPanel1; private java.awt.Panel layoutPanel; private javax.swing.JCheckBox pictureVideoCheckbox; private javax.swing.JButton searchButton; diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesNode.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeSearchResultNode.java similarity index 83% rename from Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesNode.java rename to Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeSearchResultNode.java index cf4927a1bc..334cebe68b 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesNode.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeSearchResultNode.java @@ -30,10 +30,10 @@ import org.sleuthkit.autopsy.datamodel.DisplayableItemNodeVisitor; * Wrapper node for Md5Node used to display common files search * results in the top right pane. Calls InstanceCountNodeFactory. */ -final public class CommonFilesNode extends DisplayableItemNode { +final public class CommonAttributeSearchResultNode extends DisplayableItemNode { - CommonFilesNode(CommonFilesMetadata metadataList) { + CommonAttributeSearchResultNode(CommonAttributeSearchResults metadataList) { super(Children.create(new InstanceCountNodeFactory(metadataList), true)); } @@ -64,14 +64,14 @@ final public class CommonFilesNode extends DisplayableItemNode { */ static class InstanceCountNodeFactory extends ChildFactory{ - private final CommonFilesMetadata metadata; + private final CommonAttributeSearchResults metadata; /** - * Build a factory which converts a CommonFilesMetadata + * Build a factory which converts a CommonAttributeSearchResults * object into DisplayableItemNodes. * @param metadata */ - InstanceCountNodeFactory(CommonFilesMetadata metadata){ + InstanceCountNodeFactory(CommonAttributeSearchResults metadata){ this.metadata = metadata; } @@ -83,7 +83,7 @@ final public class CommonFilesNode extends DisplayableItemNode { @Override protected Node createNodeForKey(Integer instanceCount){ - List md5Metadata = this.metadata.getMetadataForMd5(instanceCount); + List md5Metadata = this.metadata.getMetadataForMd5(instanceCount); return new InstanceCountNode(instanceCount, md5Metadata); } } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesMetadata.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeSearchResults.java similarity index 75% rename from Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesMetadata.java rename to Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeSearchResults.java index b04792fb6b..58fa884516 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesMetadata.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeSearchResults.java @@ -27,17 +27,17 @@ import java.util.Map; * Utility and wrapper model around data required for Common Files Search results. * Subclass this to implement different selections of files from the case. */ -final public class CommonFilesMetadata { +final public class CommonAttributeSearchResults { - private final Map> metadata; + private final Map> metadata; /** * Create a metadata object which can be handed off to the node * factories. * - * @param metadata list of Md5Metadata indexed by size of Md5Metadata + * @param metadata list of CommonAttributeValue indexed by size of CommonAttributeValue */ - CommonFilesMetadata(Map> metadata){ + CommonAttributeSearchResults(Map> metadata){ this.metadata = metadata; } @@ -50,11 +50,11 @@ final public class CommonFilesMetadata { * @param md5 key * @return */ - List getMetadataForMd5(Integer instanceCount) { + List getMetadataForMd5(Integer instanceCount) { return this.metadata.get(instanceCount); } - public Map> getMetadata() { + public Map> getMetadata() { return Collections.unmodifiableMap(this.metadata); } @@ -65,8 +65,8 @@ final public class CommonFilesMetadata { public int size() { int count = 0; - for (List data : this.metadata.values()) { - for(Md5Metadata md5 : data){ + for (List data : this.metadata.values()) { + for(CommonAttributeValue md5 : data){ count += md5.size(); } } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/Md5Metadata.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeValue.java similarity index 93% rename from Core/src/org/sleuthkit/autopsy/commonfilesearch/Md5Metadata.java rename to Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeValue.java index 9611ccac95..aefbaa4376 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/Md5Metadata.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeValue.java @@ -30,17 +30,17 @@ import java.util.stream.Collectors; /** * Encapsulates data required to instantiate an Md5Node. */ -final public class Md5Metadata { +final public class CommonAttributeValue { private final String md5; private final List fileInstances; - Md5Metadata(String md5, List fileInstances) { + CommonAttributeValue(String md5, List fileInstances) { this.md5 = md5; this.fileInstances = fileInstances; } - Md5Metadata(String md5) { + CommonAttributeValue(String md5) { this.md5 = md5; this.fileInstances = new ArrayList<>(); } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/Md5Node.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeValueNode.java similarity index 92% rename from Core/src/org/sleuthkit/autopsy/commonfilesearch/Md5Node.java rename to Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeValueNode.java index 45edc96c39..53b6c38366 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/Md5Node.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeValueNode.java @@ -36,9 +36,9 @@ import org.sleuthkit.autopsy.datamodel.NodeProperty; * the MD5 of the matched files, the data sources those files were found within, * and a count of the instances represented by the md5. */ -public class Md5Node extends DisplayableItemNode { +public class CommonAttributeValueNode extends DisplayableItemNode { - private static final Logger LOGGER = Logger.getLogger(Md5Node.class.getName()); + private static final Logger LOGGER = Logger.getLogger(CommonAttributeValueNode.class.getName()); private final String md5Hash; private final int commonFileCount; @@ -52,7 +52,7 @@ public class Md5Node extends DisplayableItemNode { * Create a Match node whose children will all have this object in common. * @param data the common feature, and the children */ - public Md5Node(Md5Metadata data) { + public CommonAttributeValueNode(CommonAttributeValue data) { super(Children.create( new FileInstanceNodeFactory(data), true)); @@ -130,15 +130,15 @@ public class Md5Node extends DisplayableItemNode { /** * Child generator for SleuthkitCaseFileInstanceNode of - * Md5Node. + * CommonAttributeValueNode. */ static class FileInstanceNodeFactory extends ChildFactory { //private final Map cachedFiles; - private final Md5Metadata descendants; + private final CommonAttributeValue descendants; - FileInstanceNodeFactory(Md5Metadata descendants) { + FileInstanceNodeFactory(CommonAttributeValue descendants) { this.descendants = descendants; //this.cachedFiles = new HashMap<>(); } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesSearchResultsViewerTable.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributesSearchResultsViewerTable.java similarity index 95% rename from Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesSearchResultsViewerTable.java rename to Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributesSearchResultsViewerTable.java index 904822c3cb..8aab16c667 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesSearchResultsViewerTable.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributesSearchResultsViewerTable.java @@ -30,12 +30,12 @@ import org.sleuthkit.autopsy.corecomponents.DataResultViewerTable; /** * DataResultViewerTable which overrides the default column - * header width calculations. The CommonFilesSearchResultsViewerTable + * header width calculations. The CommonAttributesSearchResultsViewerTable * presents multiple tiers of data which are not always present and it may not * make sense to try to calculate the column widths for such tables by sampling * rows and looking for wide cells. Rather, we just pick some reasonable values. */ -public class CommonFilesSearchResultsViewerTable extends DataResultViewerTable { +public class CommonAttributesSearchResultsViewerTable extends DataResultViewerTable { private static final Map COLUMN_WIDTHS; private static final long serialVersionUID = 1L; diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.form b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.form deleted file mode 100644 index da071802d8..0000000000 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.form +++ /dev/null @@ -1,270 +0,0 @@ - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesSearchAction.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesSearchAction.java index cc09b5ccec..cde1f4b3cb 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesSearchAction.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesSearchAction.java @@ -70,12 +70,12 @@ final public class CommonFilesSearchAction extends CallableSystemAction { @Override public void actionPerformed(ActionEvent event) { - new CommonFilesPanel().setVisible(true); + new CommonAttributePanel().setVisible(true); } @Override public void performAction() { - new CommonFilesPanel().setVisible(true); + new CommonAttributePanel().setVisible(true); } @NbBundle.Messages({ diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/FileInstanceNodeGenerator.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/FileInstanceNodeGenerator.java index a4863aa0b6..39b7a7673d 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/FileInstanceNodeGenerator.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/FileInstanceNodeGenerator.java @@ -135,7 +135,7 @@ public abstract class FileInstanceNodeGenerator { public static FileInstanceNodeGenerator createInstance(Iterator identicalFileNodeGeneratorIterator, Integer instanceId) throws Exception { //Long arbitraryIdenticalAbstractFileId = null; - return new CentralRepositoryCaseFileInstanceMetadata(instanceId, cachedFiles); + return new InterCaseCommonAttributeSearchResults(instanceId, cachedFiles); } } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InstanceCountNode.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InstanceCountNode.java index 987e6faa08..3b29e9ce38 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InstanceCountNode.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InstanceCountNode.java @@ -40,7 +40,7 @@ import org.sleuthkit.autopsy.datamodel.NodeProperty; final public class InstanceCountNode extends DisplayableItemNode { final private int instanceCount; - final private List metadataList; + final private List metadataList; /** * Create a node with the given number of instances, and the given @@ -51,7 +51,7 @@ final public class InstanceCountNode extends DisplayableItemNode { @NbBundle.Messages({ "InstanceCountNode.displayName=Files with %s instances (%s)" }) - public InstanceCountNode(int instanceCount, List md5Metadata) { + public InstanceCountNode(int instanceCount, List md5Metadata) { super(Children.create(new Md5NodeFactory(md5Metadata), true)); this.instanceCount = instanceCount; @@ -73,7 +73,7 @@ final public class InstanceCountNode extends DisplayableItemNode { * Get a list of metadata for the MD5s which are children of this object. * @return List */ - List getMetadata() { + List getMetadata() { return Collections.unmodifiableList(this.metadataList); } @@ -119,22 +119,22 @@ final public class InstanceCountNode extends DisplayableItemNode { * List of models, each of which is a parent node matching a single md5, * containing children FileNodes. */ - private final Map metadata; + private final Map metadata; - Md5NodeFactory(List metadata) { + Md5NodeFactory(List metadata) { this.metadata = new HashMap<>(); - Iterator iterator = metadata.iterator(); + Iterator iterator = metadata.iterator(); while (iterator.hasNext()) { - Md5Metadata md5Metadata = iterator.next(); + CommonAttributeValue md5Metadata = iterator.next(); this.metadata.put(md5Metadata.getMd5(), md5Metadata); } } @Override protected Node createNodeForKey(String md5) { - Md5Metadata md5Metadata = this.metadata.get(md5); - return new Md5Node(md5Metadata); + CommonAttributeValue md5Metadata = this.metadata.get(md5); + return new CommonAttributeValueNode(md5Metadata); } @Override diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepositoryFileInstanceNode.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeInstanceNode.java similarity index 95% rename from Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepositoryFileInstanceNode.java rename to Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeInstanceNode.java index 1f72b4eafa..d998093a74 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepositoryFileInstanceNode.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeInstanceNode.java @@ -42,7 +42,7 @@ import org.sleuthkit.datamodel.Content; * Central Repo. Contrast with SleuthkitCase which should be used * when the FileInstance was found in the case presently open in Autopsy. */ -public class CentralRepositoryFileInstanceNode extends DisplayableItemNode { +public class InterCaseCommonAttributeInstanceNode extends DisplayableItemNode { private final CorrelationAttributeInstance crFile; @@ -50,7 +50,7 @@ public class CentralRepositoryFileInstanceNode extends DisplayableItemNode { // and we can use this to support certain actions in the tree table and crFile viewer private final AbstractFile md5Reference; - public CentralRepositoryFileInstanceNode(CorrelationAttributeInstance content, AbstractFile md5Reference) { + public InterCaseCommonAttributeInstanceNode(CorrelationAttributeInstance content, AbstractFile md5Reference) { super(Children.LEAF, Lookups.fixed(content)); // Using md5Reference enables Other Occurances, but for the current file path this.crFile = content; this.setDisplayName(new File(this.crFile.getFilePath()).getName()); @@ -89,7 +89,7 @@ public class CentralRepositoryFileInstanceNode extends DisplayableItemNode { public String getItemType() { //objects of type FileNode will co-occur in the treetable with objects // of this type and they will need to provide the same key - return SleuthkitCaseFileInstanceNode.class.getName(); + return IntraCaseCommonAttributeInstanceNode.class.getName(); } @Override diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepositoryCaseFileInstanceMetadata.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearchResults.java similarity index 82% rename from Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepositoryCaseFileInstanceMetadata.java rename to Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearchResults.java index 67df0c6221..23aa865038 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepositoryCaseFileInstanceMetadata.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearchResults.java @@ -36,13 +36,13 @@ import org.sleuthkit.datamodel.TskCoreException; /** * Generates a DisplayableItmeNode using a CentralRepositoryFile. */ -final public class CentralRepositoryCaseFileInstanceMetadata extends FileInstanceNodeGenerator { +final public class InterCaseCommonAttributeSearchResults extends FileInstanceNodeGenerator { - private static final Logger LOGGER = Logger.getLogger(CentralRepositoryCaseFileInstanceMetadata.class.getName()); + private static final Logger LOGGER = Logger.getLogger(InterCaseCommonAttributeSearchResults.class.getName()); private final Integer crFileId; private CorrelationAttributeInstance tempAttributeInst; - CentralRepositoryCaseFileInstanceMetadata(Integer attrInstId, Map cachedFiles) { + InterCaseCommonAttributeSearchResults(Integer attrInstId, Map cachedFiles) { super(cachedFiles); this.crFileId = attrInstId; } @@ -70,20 +70,20 @@ final public class CentralRepositoryCaseFileInstanceMetadata extends FileInstanc @Override public DisplayableItemNode generateNode() { if (tempAttributeInst != null) { - return new CentralRepositoryFileInstanceNode(tempAttributeInst, this.lookupOrCreateAbstractFile()); + return new InterCaseCommonAttributeInstanceNode(tempAttributeInst, this.lookupOrCreateAbstractFile()); } return null; } @Override public DisplayableItemNode[] generateNodes() { - EamDbAttributeInstancesAlgorithm eamDbAttrInst = new EamDbAttributeInstancesAlgorithm(); + InterCaseSearchResultsProcessor eamDbAttrInst = new InterCaseSearchResultsProcessor(); CorrelationAttribute corrAttr = eamDbAttrInst.processCorrelationCaseSingleAttribute(crFileId); //TODO which do we want List attrInstNodeList = new ArrayList<>(0); for (CorrelationAttributeInstance attrInst : corrAttr.getInstances()) { tempAttributeInst = attrInst; - DisplayableItemNode generatedInstNode = new CentralRepositoryFileInstanceNode(tempAttributeInst, loadFileFromSleuthkitCase(tempAttributeInst.getFilePath())); + DisplayableItemNode generatedInstNode = new InterCaseCommonAttributeInstanceNode(tempAttributeInst, loadFileFromSleuthkitCase(tempAttributeInst.getFilePath())); if (generatedInstNode != null) { attrInstNodeList.add(generatedInstNode); } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonFilesMetadataBuilder.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearcher.java similarity index 86% rename from Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonFilesMetadataBuilder.java rename to Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearcher.java index a4b71bf950..2229981ace 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonFilesMetadataBuilder.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearcher.java @@ -34,7 +34,7 @@ import org.sleuthkit.datamodel.HashUtility; * Provides logic for selecting common files from all data sources and all cases * in the Central Repo. */ -public abstract class InterCaseCommonFilesMetadataBuilder extends AbstractCommonFilesMetadataBuilder { +public abstract class InterCaseCommonAttributeSearcher extends AbstractCommonAttributeSearcher { //CONSIDER: we should create an interface which specifies the findFiles feature // instead of an abstract class and then have two abstract classes: // inter- and intra- which implement the interface and then 4 subclasses @@ -51,7 +51,7 @@ public abstract class InterCaseCommonFilesMetadataBuilder extends AbstractCommon * * @throws EamDbException */ - InterCaseCommonFilesMetadataBuilder(boolean filterByMediaMimeType, boolean filterByDocMimeType) throws EamDbException { + InterCaseCommonAttributeSearcher(boolean filterByMediaMimeType, boolean filterByDocMimeType) throws EamDbException { filterByMedia = filterByMediaMimeType; filterByDoc = filterByDocMimeType; dbManager = EamDb.getInstance(); @@ -62,9 +62,9 @@ public abstract class InterCaseCommonFilesMetadataBuilder extends AbstractCommon * @param commonFiles matches must ultimately have appeared in this collection * @return collated map of instance counts to lists of matches */ - Map> gatherIntercaseResults(Map commonFiles, Map commonFileCases) { + Map> gatherIntercaseResults(Map commonFiles, Map commonFileCases) { - Map interCaseCommonFiles = new HashMap<>(); + Map interCaseCommonFiles = new HashMap<>(); for (int commonAttrId : commonFiles.keySet()) { @@ -83,13 +83,13 @@ public abstract class InterCaseCommonFilesMetadataBuilder extends AbstractCommon if(interCaseCommonFiles.containsKey(md5)) { //Add to intercase metaData - final Md5Metadata md5Metadata = interCaseCommonFiles.get(md5); + final CommonAttributeValue md5Metadata = interCaseCommonFiles.get(md5); final Iterator identitcalFileInstanceMetadata = interCaseCommonFiles.get(md5).getMetadata().iterator(); FileInstanceNodeGenerator nodeGenerator = FileInstanceNodeGenerator.createInstance(identitcalFileInstanceMetadata, commonAttrId); md5Metadata.addFileInstanceMetadata(nodeGenerator, correlationCaseDisplayName); } else { - Md5Metadata md5Metadata = new Md5Metadata(md5); + CommonAttributeValue md5Metadata = new CommonAttributeValue(md5); final Iterator identitcalFileInstanceMetadata = md5Metadata.getMetadata().iterator(); FileInstanceNodeGenerator nodeGenerator = FileInstanceNodeGenerator.createInstance(identitcalFileInstanceMetadata, commonAttrId); md5Metadata.addFileInstanceMetadata(nodeGenerator, correlationCaseDisplayName); @@ -101,7 +101,7 @@ public abstract class InterCaseCommonFilesMetadataBuilder extends AbstractCommon } - Map> instanceCollatedCommonFiles = collateMatchesByNumberOfInstances(interCaseCommonFiles); + Map> instanceCollatedCommonFiles = collateMatchesByNumberOfInstances(interCaseCommonFiles); return instanceCollatedCommonFiles; } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.java index e636d322c7..613c034c31 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.java @@ -39,7 +39,7 @@ public class InterCasePanel extends javax.swing.JPanel { private ComboBoxModel casesList = new DataSourceComboBoxModel(); private final Map caseMap; - private CommonFilesPanel parent; + private CommonAttributePanel parent; private String errorMessage; @@ -60,7 +60,7 @@ public class InterCasePanel extends javax.swing.JPanel { } } - void setParent(CommonFilesPanel parent) { + void setParent(CommonAttributePanel parent) { this.parent = parent; } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbAttributeInstancesAlgorithm.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseSearchResultsProcessor.java similarity index 98% rename from Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbAttributeInstancesAlgorithm.java rename to Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseSearchResultsProcessor.java index 4fcf89d3cd..d4b63e1c04 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/EamDbAttributeInstancesAlgorithm.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseSearchResultsProcessor.java @@ -38,9 +38,9 @@ import org.sleuthkit.autopsy.coreutils.Logger; * Used to process and return CorrelationCase md5s from the EamDB for * CommonFilesSearch. */ -final class EamDbAttributeInstancesAlgorithm { +final class InterCaseSearchResultsProcessor { - private static final Logger logger = Logger.getLogger(CommonFilesPanel.class.getName()); + private static final Logger logger = Logger.getLogger(CommonAttributePanel.class.getName()); private final Map intercaseCommonValuesMap = new HashMap<>(); private final Map intercaseCommonCasesMap = new HashMap<>(); diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/SleuthkitCaseFileInstanceNode.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCaseCommonAttributeInstanceNode.java similarity index 95% rename from Core/src/org/sleuthkit/autopsy/commonfilesearch/SleuthkitCaseFileInstanceNode.java rename to Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCaseCommonAttributeInstanceNode.java index 14a69872ae..f977e72d88 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/SleuthkitCaseFileInstanceNode.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCaseCommonAttributeInstanceNode.java @@ -34,7 +34,7 @@ import org.sleuthkit.datamodel.AbstractFile; * FileInstance was found in some case not presently open in Autopsy, but present * in the Central Repository. */ -public class SleuthkitCaseFileInstanceNode extends FileNode { +public class IntraCaseCommonAttributeInstanceNode extends FileNode { private final String caseName; private final String dataSource; @@ -46,7 +46,7 @@ public class SleuthkitCaseFileInstanceNode extends FileNode { * @param fsContent * @param dataSource */ - public SleuthkitCaseFileInstanceNode(AbstractFile fsContent, String caseName, String dataSource) { + public IntraCaseCommonAttributeInstanceNode(AbstractFile fsContent, String caseName, String dataSource) { super(fsContent); this.caseName = caseName; this.dataSource = dataSource; diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/SleuthkitCaseFileInstanceMetadata.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCaseCommonAttributeSearchResults.java similarity index 72% rename from Core/src/org/sleuthkit/autopsy/commonfilesearch/SleuthkitCaseFileInstanceMetadata.java rename to Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCaseCommonAttributeSearchResults.java index ef9b9e813a..e158332349 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/SleuthkitCaseFileInstanceMetadata.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCaseCommonAttributeSearchResults.java @@ -27,7 +27,7 @@ import org.sleuthkit.datamodel.AbstractFile; /** * Encapsulates data required to instantiate a FileInstanceNode. */ -final public class SleuthkitCaseFileInstanceMetadata extends FileInstanceNodeGenerator { +final public class IntraCaseCommonAttributeSearchResults extends FileInstanceNodeGenerator { /** * Create meta data required to find an abstract file and build a @@ -36,17 +36,17 @@ final public class SleuthkitCaseFileInstanceMetadata extends FileInstanceNodeGen * @param objectId id of abstract file to find * @param dataSourceName name of datasource where the object is found */ - SleuthkitCaseFileInstanceMetadata(Long abstractFileReference, Map cachedFiles, String dataSource, String caseName) { + IntraCaseCommonAttributeSearchResults(Long abstractFileReference, Map cachedFiles, String dataSource, String caseName) { super(abstractFileReference, cachedFiles, dataSource, caseName); } @Override public DisplayableItemNode generateNode() { - return new SleuthkitCaseFileInstanceNode(this.lookupOrCreateAbstractFile(), this.getCaseName(), this.getDataSource()); + return new IntraCaseCommonAttributeInstanceNode(this.lookupOrCreateAbstractFile(), this.getCaseName(), this.getDataSource()); } @Override public DisplayableItemNode[] generateNodes() { - return Arrays.asList(new SleuthkitCaseFileInstanceNode(this.lookupOrCreateAbstractFile(), this.getCaseName(), this.getDataSource())).toArray(new DisplayableItemNode[1]); + return Arrays.asList(new IntraCaseCommonAttributeInstanceNode(this.lookupOrCreateAbstractFile(), this.getCaseName(), this.getDataSource())).toArray(new DisplayableItemNode[1]); } } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCaseCommonFilesMetadataBuilder.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCaseCommonAttributeSearcher.java similarity index 84% rename from Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCaseCommonFilesMetadataBuilder.java rename to Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCaseCommonAttributeSearcher.java index 89f011c425..652442cca2 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCaseCommonFilesMetadataBuilder.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCaseCommonAttributeSearcher.java @@ -44,7 +44,7 @@ import org.sleuthkit.datamodel.TskCoreException; * This entire thing runs on a background thread where exceptions are handled. */ @SuppressWarnings("PMD.AbstractNaming") -public abstract class IntraCaseCommonFilesMetadataBuilder extends AbstractCommonFilesMetadataBuilder { +public abstract class IntraCaseCommonAttributeSearcher extends AbstractCommonAttributeSearcher { private final Map dataSourceIdToNameMap; private static final String FILTER_BY_MIME_TYPES_WHERE_CLAUSE = " and mime_type in (%s)"; //NON-NLS // where %s is csv list of mime_types to filter on @@ -58,7 +58,7 @@ public abstract class IntraCaseCommonFilesMetadataBuilder extends AbstractCommon * @param filterByDocMimeType match only on files whose mime types can be * broadly categorized as document types */ - IntraCaseCommonFilesMetadataBuilder(Map dataSourceIdMap, boolean filterByMediaMimeType, boolean filterByDocMimeType) { + IntraCaseCommonAttributeSearcher(Map dataSourceIdMap, boolean filterByMediaMimeType, boolean filterByDocMimeType) { dataSourceIdToNameMap = dataSourceIdMap; filterByMedia = filterByMediaMimeType; filterByDoc = filterByDocMimeType; @@ -98,9 +98,9 @@ public abstract class IntraCaseCommonFilesMetadataBuilder extends AbstractCommon * @throws SQLException */ @Override - public CommonFilesMetadata findFiles() throws TskCoreException, NoCurrentCaseException, SQLException, Exception { + public CommonAttributeSearchResults findFiles() throws TskCoreException, NoCurrentCaseException, SQLException, Exception { //TODO do we need all those exceptions or can we differentiate when they are caught? - Map commonFiles = new HashMap<>(); + Map commonFiles = new HashMap<>(); final Case currentCase = Case.getCurrentCaseThrows(); final String caseName = currentCase.getDisplayName(); @@ -126,19 +126,19 @@ public abstract class IntraCaseCommonFilesMetadataBuilder extends AbstractCommon } if (commonFiles.containsKey(md5)) { - final Md5Metadata md5Metadata = commonFiles.get(md5); - md5Metadata.addFileInstanceMetadata(new SleuthkitCaseFileInstanceMetadata(objectId, fileCache, dataSource, caseName)); + final CommonAttributeValue md5Metadata = commonFiles.get(md5); + md5Metadata.addFileInstanceMetadata(new IntraCaseCommonAttributeSearchResults(objectId, fileCache, dataSource, caseName)); } else { - final Md5Metadata md5Metadata = new Md5Metadata(md5); - md5Metadata.addFileInstanceMetadata(new SleuthkitCaseFileInstanceMetadata(objectId, fileCache, dataSource, caseName)); + final CommonAttributeValue md5Metadata = new CommonAttributeValue(md5); + md5Metadata.addFileInstanceMetadata(new IntraCaseCommonAttributeSearchResults(objectId, fileCache, dataSource, caseName)); commonFiles.put(md5, md5Metadata); } } } - Map> instanceCollatedCommonFiles = collateMatchesByNumberOfInstances(commonFiles); + Map> instanceCollatedCommonFiles = collateMatchesByNumberOfInstances(commonFiles); - return new CommonFilesMetadata(instanceCollatedCommonFiles); + return new CommonAttributeSearchResults(instanceCollatedCommonFiles); } /** diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCasePanel.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCasePanel.java index 13e70b1e97..3daee45ffa 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCasePanel.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCasePanel.java @@ -34,13 +34,13 @@ public class IntraCasePanel extends javax.swing.JPanel { private static final long serialVersionUID = 1L; static final long NO_DATA_SOURCE_SELECTED = -1; - private static final Logger LOGGER = Logger.getLogger(CommonFilesPanel.class.getName()); + private static final Logger LOGGER = Logger.getLogger(CommonAttributePanel.class.getName()); private boolean singleDataSource; private String selectedDataSource; private ComboBoxModel dataSourcesList = new DataSourceComboBoxModel(); private Map dataSourceMap; - private CommonFilesPanel parent; + private CommonAttributePanel parent; private String errorMessage; @@ -52,7 +52,7 @@ public class IntraCasePanel extends javax.swing.JPanel { this.errorMessage = ""; } - public void setParent(CommonFilesPanel parent){ + public void setParent(CommonAttributePanel parent){ this.parent = parent; } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/SingleCaseEamDbCommonFilesAlgorithm.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/SingleInterCaseCommonAttributeSearcher.java similarity index 77% rename from Core/src/org/sleuthkit/autopsy/commonfilesearch/SingleCaseEamDbCommonFilesAlgorithm.java rename to Core/src/org/sleuthkit/autopsy/commonfilesearch/SingleInterCaseCommonAttributeSearcher.java index 0cd96eb1ee..09fdeeb013 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/SingleCaseEamDbCommonFilesAlgorithm.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/SingleInterCaseCommonAttributeSearcher.java @@ -33,7 +33,7 @@ import org.sleuthkit.datamodel.TskCoreException; * * */ -public class SingleCaseEamDbCommonFilesAlgorithm extends InterCaseCommonFilesMetadataBuilder { +public class SingleInterCaseCommonAttributeSearcher extends InterCaseCommonAttributeSearcher { private final int corrleationCaseId; private String correlationCaseName; @@ -45,7 +45,7 @@ public class SingleCaseEamDbCommonFilesAlgorithm extends InterCaseCommonFilesMet * @param filterByDocMimeType * @throws EamDbException */ - public SingleCaseEamDbCommonFilesAlgorithm(int correlationCaseId, boolean filterByMediaMimeType, boolean filterByDocMimeType) throws EamDbException { + public SingleInterCaseCommonAttributeSearcher(int correlationCaseId, boolean filterByMediaMimeType, boolean filterByDocMimeType) throws EamDbException { super(filterByMediaMimeType, filterByDocMimeType); this.corrleationCaseId = correlationCaseId; @@ -65,22 +65,22 @@ public class SingleCaseEamDbCommonFilesAlgorithm extends InterCaseCommonFilesMet * @throws Exception */ @Override - public CommonFilesMetadata findFiles() throws TskCoreException, NoCurrentCaseException, SQLException, EamDbException, Exception { + public CommonAttributeSearchResults findFiles() throws TskCoreException, NoCurrentCaseException, SQLException, EamDbException, Exception { CorrelationCase cCase = this.getCorrelationCaseFromId(this.corrleationCaseId); correlationCaseName = cCase.getDisplayName(); return this.findFiles(cCase); } - protected CommonFilesMetadata findFiles(CorrelationCase correlationCase) throws TskCoreException, NoCurrentCaseException, SQLException, EamDbException, Exception { + protected CommonAttributeSearchResults findFiles(CorrelationCase correlationCase) throws TskCoreException, NoCurrentCaseException, SQLException, EamDbException, Exception { - Map> interCaseCommonFiles = new HashMap<>(); + Map> interCaseCommonFiles = new HashMap<>(); - EamDbAttributeInstancesAlgorithm eamDbAttrInst = new EamDbAttributeInstancesAlgorithm(); + InterCaseSearchResultsProcessor eamDbAttrInst = new InterCaseSearchResultsProcessor(); eamDbAttrInst.processSingleCaseCorrelationCaseAttributeValues(Case.getCurrentCase(), correlationCase); interCaseCommonFiles = gatherIntercaseResults(eamDbAttrInst.getIntercaseCommonValuesMap(), eamDbAttrInst.getIntercaseCommonCasesMap()); - return new CommonFilesMetadata(interCaseCommonFiles); + return new CommonAttributeSearchResults(interCaseCommonFiles); } @Override diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/SingleDataSourceCommonFilesAlgorithm.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/SingleIntraCaseCommonAttributeSearcher.java similarity index 87% rename from Core/src/org/sleuthkit/autopsy/commonfilesearch/SingleDataSourceCommonFilesAlgorithm.java rename to Core/src/org/sleuthkit/autopsy/commonfilesearch/SingleIntraCaseCommonAttributeSearcher.java index c97b15ae0b..565b5c8d39 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/SingleDataSourceCommonFilesAlgorithm.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/SingleIntraCaseCommonAttributeSearcher.java @@ -25,7 +25,7 @@ import org.sleuthkit.datamodel.TskData.FileKnown; /** * Provides logic for selecting common files from a single data source. */ -final public class SingleDataSourceCommonFilesAlgorithm extends IntraCaseCommonFilesMetadataBuilder { +final public class SingleIntraCaseCommonAttributeSearcher extends IntraCaseCommonAttributeSearcher { private static final String WHERE_CLAUSE = "%s md5 in (select md5 from tsk_files where md5 in (select md5 from tsk_files where (known != "+ FileKnown.KNOWN.getFileKnownValue() + " OR known IS NULL) and data_source_obj_id=%s%s) GROUP BY md5 HAVING COUNT(DISTINCT data_source_obj_id) > 1) order by md5"; //NON-NLS private final Long selectedDataSourceId; @@ -41,7 +41,7 @@ final public class SingleDataSourceCommonFilesAlgorithm extends IntraCaseCommonF * @param filterByDocMimeType match only on files whose mime types can be * broadly categorized as document types */ - public SingleDataSourceCommonFilesAlgorithm(Long dataSourceId, Map dataSourceIdMap, boolean filterByMediaMimeType, boolean filterByDocMimeType) { + public SingleIntraCaseCommonAttributeSearcher(Long dataSourceId, Map dataSourceIdMap, boolean filterByMediaMimeType, boolean filterByDocMimeType) { super(dataSourceIdMap, filterByMediaMimeType, filterByDocMimeType); this.selectedDataSourceId = dataSourceId; this.dataSourceName = dataSourceIdMap.get(this.selectedDataSourceId); @@ -50,7 +50,7 @@ final public class SingleDataSourceCommonFilesAlgorithm extends IntraCaseCommonF @Override protected String buildSqlSelectStatement() { Object[] args = new String[]{SELECT_PREFIX, Long.toString(this.selectedDataSourceId), determineMimeTypeFilter()}; - return String.format(SingleDataSourceCommonFilesAlgorithm.WHERE_CLAUSE, args); + return String.format(SingleIntraCaseCommonAttributeSearcher.WHERE_CLAUSE, args); } @Override diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/DisplayableItemNodeVisitor.java b/Core/src/org/sleuthkit/autopsy/datamodel/DisplayableItemNodeVisitor.java index 24e181a2ac..d7e4cf3ebb 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/DisplayableItemNodeVisitor.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/DisplayableItemNodeVisitor.java @@ -18,11 +18,11 @@ */ package org.sleuthkit.autopsy.datamodel; -import org.sleuthkit.autopsy.commonfilesearch.CentralRepositoryFileInstanceNode; -import org.sleuthkit.autopsy.commonfilesearch.CommonFilesNode; +import org.sleuthkit.autopsy.commonfilesearch.InterCaseCommonAttributeInstanceNode; +import org.sleuthkit.autopsy.commonfilesearch.CommonAttributeSearchResultNode; import org.sleuthkit.autopsy.commonfilesearch.InstanceCountNode; -import org.sleuthkit.autopsy.commonfilesearch.Md5Node; -import org.sleuthkit.autopsy.commonfilesearch.SleuthkitCaseFileInstanceNode; +import org.sleuthkit.autopsy.commonfilesearch.CommonAttributeValueNode; +import org.sleuthkit.autopsy.commonfilesearch.IntraCaseCommonAttributeInstanceNode; import org.sleuthkit.autopsy.datamodel.DeletedContent.DeletedContentsChildren.DeletedContentNode; import org.sleuthkit.autopsy.datamodel.DeletedContent.DeletedContentsNode; import org.sleuthkit.autopsy.datamodel.FileSize.FileSizeRootChildren.FileSizeNode; @@ -116,13 +116,13 @@ public interface DisplayableItemNodeVisitor { T visit(InterestingHits.SetNameNode ihsn); - T visit(Md5Node mn); + T visit(CommonAttributeValueNode mn); - T visit(CommonFilesNode cfn); + T visit(CommonAttributeSearchResultNode cfn); - T visit(SleuthkitCaseFileInstanceNode fin); + T visit(IntraCaseCommonAttributeInstanceNode fin); - T visit(CentralRepositoryFileInstanceNode crfin); + T visit(InterCaseCommonAttributeInstanceNode crfin); T visit(InstanceCountNode icn); @@ -195,17 +195,17 @@ public interface DisplayableItemNodeVisitor { protected abstract T defaultVisit(DisplayableItemNode c); @Override - public T visit(SleuthkitCaseFileInstanceNode fin) { + public T visit(IntraCaseCommonAttributeInstanceNode fin) { return defaultVisit(fin); } @Override - public T visit(Md5Node mn) { + public T visit(CommonAttributeValueNode mn) { return defaultVisit(mn); } @Override - public T visit(CommonFilesNode cfn) { + public T visit(CommonAttributeSearchResultNode cfn) { return defaultVisit(cfn); } @@ -215,7 +215,7 @@ public interface DisplayableItemNodeVisitor { } @Override - public T visit(CentralRepositoryFileInstanceNode crfin){ + public T visit(InterCaseCommonAttributeInstanceNode crfin){ return defaultVisit(crfin); } diff --git a/Core/src/org/sleuthkit/autopsy/directorytree/DataResultFilterNode.java b/Core/src/org/sleuthkit/autopsy/directorytree/DataResultFilterNode.java index 8250985fc7..855cdbe41b 100644 --- a/Core/src/org/sleuthkit/autopsy/directorytree/DataResultFilterNode.java +++ b/Core/src/org/sleuthkit/autopsy/directorytree/DataResultFilterNode.java @@ -55,14 +55,14 @@ import org.sleuthkit.autopsy.datamodel.FileNode; import org.sleuthkit.autopsy.datamodel.FileTypeExtensions; import org.sleuthkit.autopsy.datamodel.FileTypes.FileTypesNode; import org.sleuthkit.autopsy.commonfilesearch.InstanceCountNode; -import org.sleuthkit.autopsy.commonfilesearch.Md5Node; +import org.sleuthkit.autopsy.commonfilesearch.CommonAttributeValueNode; import org.sleuthkit.autopsy.datamodel.LayoutFileNode; import org.sleuthkit.autopsy.datamodel.LocalFileNode; import org.sleuthkit.autopsy.datamodel.LocalDirectoryNode; import org.sleuthkit.autopsy.datamodel.NodeSelectionInfo; import org.sleuthkit.autopsy.datamodel.Reports; import org.sleuthkit.autopsy.datamodel.SlackFileNode; -import org.sleuthkit.autopsy.commonfilesearch.SleuthkitCaseFileInstanceNode; +import org.sleuthkit.autopsy.commonfilesearch.IntraCaseCommonAttributeInstanceNode; import org.sleuthkit.autopsy.datamodel.VirtualDirectoryNode; import static org.sleuthkit.autopsy.directorytree.Bundle.DataResultFilterNode_viewSourceArtifact_text; import org.sleuthkit.autopsy.modules.embeddedfileextractor.ExtractArchiveWithPasswordAction; @@ -529,12 +529,12 @@ public class DataResultFilterNode extends FilterNode { } @Override - public AbstractAction visit(Md5Node md5n){ + public AbstractAction visit(CommonAttributeValueNode md5n){ return null; } @Override - public AbstractAction visit(SleuthkitCaseFileInstanceNode fin){ + public AbstractAction visit(IntraCaseCommonAttributeInstanceNode fin){ return null; } diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileTypeInterCaseTests.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileTypeInterCaseTests.java index 3d1e0c2ff3..5e3dadb4df 100644 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileTypeInterCaseTests.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileTypeInterCaseTests.java @@ -29,9 +29,9 @@ import org.python.icu.impl.Assert; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException; -import org.sleuthkit.autopsy.commonfilesearch.AllCasesEamDbCommonFilesAlgorithm; -import org.sleuthkit.autopsy.commonfilesearch.CommonFilesMetadata; -import org.sleuthkit.autopsy.commonfilesearch.IntraCaseCommonFilesMetadataBuilder; +import org.sleuthkit.autopsy.commonfilesearch.AllInterCaseCommonAttributeSearcher; +import org.sleuthkit.autopsy.commonfilesearch.CommonAttributeSearchResults; +import org.sleuthkit.autopsy.commonfilesearch.IntraCaseCommonAttributeSearcher; import org.sleuthkit.datamodel.TskCoreException; /** @@ -86,9 +86,9 @@ public class IngestedWithHashAndFileTypeInterCaseTests extends NbTestCase { //this is proabbly not needed and should be pulled out of the constructor if possible Map dataSources = this.utils.getDataSourceMap(); - IntraCaseCommonFilesMetadataBuilder builder = new AllCasesEamDbCommonFilesAlgorithm(dataSources, false, false); + IntraCaseCommonAttributeSearcher builder = new AllInterCaseCommonAttributeSearcher(dataSources, false, false); - CommonFilesMetadata metadata = builder.findFiles(); + CommonAttributeSearchResults metadata = builder.findFiles(); assertTrue("Results should not be empty", metadata.size() != 0); diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileTypeIntraCaseTests.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileTypeIntraCaseTests.java index 88b78d076d..dbef8cd6ca 100644 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileTypeIntraCaseTests.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileTypeIntraCaseTests.java @@ -29,10 +29,10 @@ import org.openide.util.Exceptions; import org.python.icu.impl.Assert; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; -import org.sleuthkit.autopsy.commonfilesearch.AllDataSourcesCommonFilesAlgorithm; -import org.sleuthkit.autopsy.commonfilesearch.CommonFilesMetadata; -import org.sleuthkit.autopsy.commonfilesearch.IntraCaseCommonFilesMetadataBuilder; -import org.sleuthkit.autopsy.commonfilesearch.SingleDataSourceCommonFilesAlgorithm; +import org.sleuthkit.autopsy.commonfilesearch.AllIntraCaseCommonAttributeSearcher; +import org.sleuthkit.autopsy.commonfilesearch.CommonAttributeSearchResults; +import org.sleuthkit.autopsy.commonfilesearch.IntraCaseCommonAttributeSearcher; +import org.sleuthkit.autopsy.commonfilesearch.SingleIntraCaseCommonAttributeSearcher; import static org.sleuthkit.autopsy.commonfilessearch.IntraCaseUtils.*; import org.sleuthkit.autopsy.ingest.IngestJobSettings; import org.sleuthkit.autopsy.ingest.IngestJobSettings.IngestType; @@ -97,8 +97,8 @@ public class IngestedWithHashAndFileTypeIntraCaseTests extends NbTestCase { try { Map dataSources = this.utils.getDataSourceMap(); - IntraCaseCommonFilesMetadataBuilder allSourcesBuilder = new AllDataSourcesCommonFilesAlgorithm(dataSources, false, false); - CommonFilesMetadata metadata = allSourcesBuilder.findFiles(); + IntraCaseCommonAttributeSearcher allSourcesBuilder = new AllIntraCaseCommonAttributeSearcher(dataSources, false, false); + CommonAttributeSearchResults metadata = allSourcesBuilder.findFiles(); Map objectIdToDataSource = IntraCaseUtils.mapFileInstancesToDataSources(metadata); @@ -138,8 +138,8 @@ public class IngestedWithHashAndFileTypeIntraCaseTests extends NbTestCase { try { Map dataSources = this.utils.getDataSourceMap(); - IntraCaseCommonFilesMetadataBuilder allSourcesBuilder = new AllDataSourcesCommonFilesAlgorithm(dataSources, true, false); - CommonFilesMetadata metadata = allSourcesBuilder.findFiles(); + IntraCaseCommonAttributeSearcher allSourcesBuilder = new AllIntraCaseCommonAttributeSearcher(dataSources, true, false); + CommonAttributeSearchResults metadata = allSourcesBuilder.findFiles(); Map objectIdToDataSource = mapFileInstancesToDataSources(metadata); @@ -179,8 +179,8 @@ public class IngestedWithHashAndFileTypeIntraCaseTests extends NbTestCase { try { Map dataSources = this.utils.getDataSourceMap(); - IntraCaseCommonFilesMetadataBuilder allSourcesBuilder = new AllDataSourcesCommonFilesAlgorithm(dataSources, false, true); - CommonFilesMetadata metadata = allSourcesBuilder.findFiles(); + IntraCaseCommonAttributeSearcher allSourcesBuilder = new AllIntraCaseCommonAttributeSearcher(dataSources, false, true); + CommonAttributeSearchResults metadata = allSourcesBuilder.findFiles(); Map objectIdToDataSource = mapFileInstancesToDataSources(metadata); @@ -221,8 +221,8 @@ public class IngestedWithHashAndFileTypeIntraCaseTests extends NbTestCase { Map dataSources = this.utils.getDataSourceMap(); Long first = getDataSourceIdByName(SET1, dataSources); - IntraCaseCommonFilesMetadataBuilder singleSourceBuilder = new SingleDataSourceCommonFilesAlgorithm(first, dataSources, false, false); - CommonFilesMetadata metadata = singleSourceBuilder.findFiles(); + IntraCaseCommonAttributeSearcher singleSourceBuilder = new SingleIntraCaseCommonAttributeSearcher(first, dataSources, false, false); + CommonAttributeSearchResults metadata = singleSourceBuilder.findFiles(); Map objectIdToDataSource = mapFileInstancesToDataSources(metadata); @@ -263,8 +263,8 @@ public class IngestedWithHashAndFileTypeIntraCaseTests extends NbTestCase { Map dataSources = this.utils.getDataSourceMap(); Long first = getDataSourceIdByName(SET1, dataSources); - IntraCaseCommonFilesMetadataBuilder singleSourceBuilder = new SingleDataSourceCommonFilesAlgorithm(first, dataSources, true, false); - CommonFilesMetadata metadata = singleSourceBuilder.findFiles(); + IntraCaseCommonAttributeSearcher singleSourceBuilder = new SingleIntraCaseCommonAttributeSearcher(first, dataSources, true, false); + CommonAttributeSearchResults metadata = singleSourceBuilder.findFiles(); Map objectIdToDataSource = mapFileInstancesToDataSources(metadata); @@ -305,8 +305,8 @@ public class IngestedWithHashAndFileTypeIntraCaseTests extends NbTestCase { Map dataSources = this.utils.getDataSourceMap(); Long first = getDataSourceIdByName(SET1, dataSources); - IntraCaseCommonFilesMetadataBuilder singleSourceBuilder = new SingleDataSourceCommonFilesAlgorithm(first, dataSources, false, true); - CommonFilesMetadata metadata = singleSourceBuilder.findFiles(); + IntraCaseCommonAttributeSearcher singleSourceBuilder = new SingleIntraCaseCommonAttributeSearcher(first, dataSources, false, true); + CommonAttributeSearchResults metadata = singleSourceBuilder.findFiles(); Map objectIdToDataSource = mapFileInstancesToDataSources(metadata); @@ -347,8 +347,8 @@ public class IngestedWithHashAndFileTypeIntraCaseTests extends NbTestCase { Map dataSources = this.utils.getDataSourceMap(); Long second = getDataSourceIdByName(SET2, dataSources); - IntraCaseCommonFilesMetadataBuilder singleSourceBuilder = new SingleDataSourceCommonFilesAlgorithm(second, dataSources, false, false); - CommonFilesMetadata metadata = singleSourceBuilder.findFiles(); + IntraCaseCommonAttributeSearcher singleSourceBuilder = new SingleIntraCaseCommonAttributeSearcher(second, dataSources, false, false); + CommonAttributeSearchResults metadata = singleSourceBuilder.findFiles(); Map objectIdToDataSource = mapFileInstancesToDataSources(metadata); @@ -388,8 +388,8 @@ public class IngestedWithHashAndFileTypeIntraCaseTests extends NbTestCase { Map dataSources = this.utils.getDataSourceMap(); Long last = getDataSourceIdByName(SET4, dataSources); - IntraCaseCommonFilesMetadataBuilder singleSourceBuilder = new SingleDataSourceCommonFilesAlgorithm(last, dataSources, false, false); - CommonFilesMetadata metadata = singleSourceBuilder.findFiles(); + IntraCaseCommonAttributeSearcher singleSourceBuilder = new SingleIntraCaseCommonAttributeSearcher(last, dataSources, false, false); + CommonAttributeSearchResults metadata = singleSourceBuilder.findFiles(); Map objectIdToDataSource = mapFileInstancesToDataSources(metadata); @@ -429,8 +429,8 @@ public class IngestedWithHashAndFileTypeIntraCaseTests extends NbTestCase { Map dataSources = this.utils.getDataSourceMap(); Long third = getDataSourceIdByName(SET3, dataSources); - IntraCaseCommonFilesMetadataBuilder singleSourceBuilder = new SingleDataSourceCommonFilesAlgorithm(third, dataSources, false, false); - CommonFilesMetadata metadata = singleSourceBuilder.findFiles(); + IntraCaseCommonAttributeSearcher singleSourceBuilder = new SingleIntraCaseCommonAttributeSearcher(third, dataSources, false, false); + CommonAttributeSearchResults metadata = singleSourceBuilder.findFiles(); Map objectIdToDataSource = mapFileInstancesToDataSources(metadata); diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithNoFileTypesIntraCaseTests.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithNoFileTypesIntraCaseTests.java index 3fb720cb53..c8f289ab72 100644 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithNoFileTypesIntraCaseTests.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithNoFileTypesIntraCaseTests.java @@ -30,10 +30,10 @@ import org.openide.util.Exceptions; import org.python.icu.impl.Assert; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; -import org.sleuthkit.autopsy.commonfilesearch.AllDataSourcesCommonFilesAlgorithm; -import org.sleuthkit.autopsy.commonfilesearch.CommonFilesMetadata; -import org.sleuthkit.autopsy.commonfilesearch.IntraCaseCommonFilesMetadataBuilder; -import org.sleuthkit.autopsy.commonfilesearch.SingleDataSourceCommonFilesAlgorithm; +import org.sleuthkit.autopsy.commonfilesearch.AllIntraCaseCommonAttributeSearcher; +import org.sleuthkit.autopsy.commonfilesearch.CommonAttributeSearchResults; +import org.sleuthkit.autopsy.commonfilesearch.IntraCaseCommonAttributeSearcher; +import org.sleuthkit.autopsy.commonfilesearch.SingleIntraCaseCommonAttributeSearcher; import org.sleuthkit.autopsy.ingest.IngestJobSettings; import org.sleuthkit.autopsy.ingest.IngestModuleTemplate; import org.sleuthkit.autopsy.modules.hashdatabase.HashLookupModuleFactory; @@ -99,8 +99,8 @@ public class IngestedWithNoFileTypesIntraCaseTests extends NbTestCase { try { Map dataSources = this.utils.getDataSourceMap(); - IntraCaseCommonFilesMetadataBuilder allSourcesBuilder = new AllDataSourcesCommonFilesAlgorithm(dataSources, true, false); - CommonFilesMetadata metadata = allSourcesBuilder.findFiles(); + IntraCaseCommonAttributeSearcher allSourcesBuilder = new AllIntraCaseCommonAttributeSearcher(dataSources, true, false); + CommonAttributeSearchResults metadata = allSourcesBuilder.findFiles(); Map objectIdToDataSource = IntraCaseUtils.mapFileInstancesToDataSources(metadata); @@ -123,8 +123,8 @@ public class IngestedWithNoFileTypesIntraCaseTests extends NbTestCase { Map dataSources = this.utils.getDataSourceMap(); Long third = IntraCaseUtils.getDataSourceIdByName(IntraCaseUtils.SET3, dataSources); - IntraCaseCommonFilesMetadataBuilder singleSourceBuilder = new SingleDataSourceCommonFilesAlgorithm(third, dataSources, true, false); - CommonFilesMetadata metadata = singleSourceBuilder.findFiles(); + IntraCaseCommonAttributeSearcher singleSourceBuilder = new SingleIntraCaseCommonAttributeSearcher(third, dataSources, true, false); + CommonAttributeSearchResults metadata = singleSourceBuilder.findFiles(); Map objectIdToDataSource = IntraCaseUtils.mapFileInstancesToDataSources(metadata); diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/InterCaseUtils.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/InterCaseUtils.java index f8b62294da..11fbe5f543 100644 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/InterCaseUtils.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/InterCaseUtils.java @@ -51,10 +51,10 @@ import org.python.icu.impl.Assert; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationCase; import org.sleuthkit.autopsy.centralrepository.datamodel.EamDb; -import org.sleuthkit.autopsy.commonfilesearch.CommonFilesMetadata; +import org.sleuthkit.autopsy.commonfilesearch.CommonAttributeSearchResults; import org.sleuthkit.autopsy.commonfilesearch.DataSourceLoader; -import org.sleuthkit.autopsy.commonfilesearch.SleuthkitCaseFileInstanceMetadata; -import org.sleuthkit.autopsy.commonfilesearch.Md5Metadata; +import org.sleuthkit.autopsy.commonfilesearch.IntraCaseCommonAttributeSearchResults; +import org.sleuthkit.autopsy.commonfilesearch.CommonAttributeValue; import org.sleuthkit.datamodel.AbstractFile; /** @@ -291,15 +291,15 @@ class InterCaseUtils { } } - static boolean verifyInstanceExistanceAndCount(CommonFilesMetadata searchDomain, String fileName, String dataSource, String crCase, int instanceCount){ + static boolean verifyInstanceExistanceAndCount(CommonAttributeSearchResults searchDomain, String fileName, String dataSource, String crCase, int instanceCount){ int tally = 0; - for(Map.Entry> file : searchDomain.getMetadata().entrySet()){ + for(Map.Entry> file : searchDomain.getMetadata().entrySet()){ - Collection fileInstances = file.getValue(); + Collection fileInstances = file.getValue(); - for(SleuthkitCaseFileInstanceMetadata fileInstance : fileInstances){ + for(IntraCaseCommonAttributeSearchResults fileInstance : fileInstances){ } @@ -308,7 +308,7 @@ class InterCaseUtils { return false; } - static Map mapFileInstancesToDataSource(CommonFilesMetadata metadata){ + static Map mapFileInstancesToDataSource(CommonAttributeSearchResults metadata){ return IntraCaseUtils.mapFileInstancesToDataSources(metadata); } diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IntraCaseUtils.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IntraCaseUtils.java index 78c6b78ac2..f557641df0 100644 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IntraCaseUtils.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IntraCaseUtils.java @@ -33,10 +33,10 @@ import org.python.icu.impl.Assert; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.ImageDSProcessor; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; -import org.sleuthkit.autopsy.commonfilesearch.CommonFilesMetadata; +import org.sleuthkit.autopsy.commonfilesearch.CommonAttributeSearchResults; import org.sleuthkit.autopsy.commonfilesearch.DataSourceLoader; -import org.sleuthkit.autopsy.commonfilesearch.SleuthkitCaseFileInstanceMetadata; -import org.sleuthkit.autopsy.commonfilesearch.Md5Metadata; +import org.sleuthkit.autopsy.commonfilesearch.IntraCaseCommonAttributeSearchResults; +import org.sleuthkit.autopsy.commonfilesearch.CommonAttributeValue; import org.sleuthkit.autopsy.testutils.CaseUtils; import org.sleuthkit.autopsy.testutils.IngestUtils; import org.sleuthkit.datamodel.AbstractFile; @@ -182,12 +182,12 @@ class IntraCaseUtils { * @param metadata object returned by the code under test * @return mapping of objectId to data source name */ - static Map mapFileInstancesToDataSources(CommonFilesMetadata metadata) { + static Map mapFileInstancesToDataSources(CommonAttributeSearchResults metadata) { Map instanceIdToDataSource = new HashMap<>(); - for (Map.Entry> entry : metadata.getMetadata().entrySet()) { - for (Md5Metadata md : entry.getValue()) { - for (SleuthkitCaseFileInstanceMetadata fim : md.getMetadata()) { + for (Map.Entry> entry : metadata.getMetadata().entrySet()) { + for (CommonAttributeValue md : entry.getValue()) { + for (IntraCaseCommonAttributeSearchResults fim : md.getMetadata()) { instanceIdToDataSource.put(fim.getObjectId(), fim.getDataSourceName()); } } diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/NoCentralRepoEnabledInterCaseTests.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/NoCentralRepoEnabledInterCaseTests.java index 39c4ba42d1..e19252a13d 100644 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/NoCentralRepoEnabledInterCaseTests.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/NoCentralRepoEnabledInterCaseTests.java @@ -28,9 +28,9 @@ import org.openide.util.Exceptions; import org.sleuthkit.datamodel.TskCoreException; import org.python.icu.impl.Assert; import org.sleuthkit.autopsy.casemodule.Case; -import org.sleuthkit.autopsy.commonfilesearch.AllCasesEamDbCommonFilesAlgorithm; -import org.sleuthkit.autopsy.commonfilesearch.CommonFilesMetadata; -import org.sleuthkit.autopsy.commonfilesearch.IntraCaseCommonFilesMetadataBuilder; +import org.sleuthkit.autopsy.commonfilesearch.AllInterCaseCommonAttributeSearcher; +import org.sleuthkit.autopsy.commonfilesearch.CommonAttributeSearchResults; +import org.sleuthkit.autopsy.commonfilesearch.IntraCaseCommonAttributeSearcher; /** * @@ -75,9 +75,9 @@ public class NoCentralRepoEnabledInterCaseTests extends NbTestCase { try { Map dataSources = this.utils.getDataSourceMap(); - IntraCaseCommonFilesMetadataBuilder builder = new AllCasesEamDbCommonFilesAlgorithm(dataSources, false, false); + IntraCaseCommonAttributeSearcher builder = new AllInterCaseCommonAttributeSearcher(dataSources, false, false); - CommonFilesMetadata metadata = builder.findFiles(); + CommonAttributeSearchResults metadata = builder.findFiles(); assertTrue("Should be no results.", metadata.size() == 0); } catch (Exception ex) { diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/UningestedCasesIntraCaseTests.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/UningestedCasesIntraCaseTests.java index c9e54bcf41..015ee9d4b3 100644 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/UningestedCasesIntraCaseTests.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/UningestedCasesIntraCaseTests.java @@ -26,10 +26,10 @@ import org.netbeans.junit.NbModuleSuite; import org.netbeans.junit.NbTestCase; import org.openide.util.Exceptions; import org.python.icu.impl.Assert; -import org.sleuthkit.autopsy.commonfilesearch.AllDataSourcesCommonFilesAlgorithm; -import org.sleuthkit.autopsy.commonfilesearch.CommonFilesMetadata; -import org.sleuthkit.autopsy.commonfilesearch.IntraCaseCommonFilesMetadataBuilder; -import org.sleuthkit.autopsy.commonfilesearch.SingleDataSourceCommonFilesAlgorithm; +import org.sleuthkit.autopsy.commonfilesearch.AllIntraCaseCommonAttributeSearcher; +import org.sleuthkit.autopsy.commonfilesearch.CommonAttributeSearchResults; +import org.sleuthkit.autopsy.commonfilesearch.IntraCaseCommonAttributeSearcher; +import org.sleuthkit.autopsy.commonfilesearch.SingleIntraCaseCommonAttributeSearcher; import static org.sleuthkit.autopsy.commonfilessearch.IntraCaseUtils.SET1; import static org.sleuthkit.autopsy.commonfilessearch.IntraCaseUtils.getDataSourceIdByName; @@ -77,8 +77,8 @@ public class UningestedCasesIntraCaseTests extends NbTestCase { try { Map dataSources = this.utils.getDataSourceMap(); - IntraCaseCommonFilesMetadataBuilder allSourcesBuilder = new AllDataSourcesCommonFilesAlgorithm(dataSources, false, false); - CommonFilesMetadata metadata = allSourcesBuilder.findFiles(); + IntraCaseCommonAttributeSearcher allSourcesBuilder = new AllIntraCaseCommonAttributeSearcher(dataSources, false, false); + CommonAttributeSearchResults metadata = allSourcesBuilder.findFiles(); int resultCount = metadata.size(); assertEquals(resultCount, 0); @@ -97,8 +97,8 @@ public class UningestedCasesIntraCaseTests extends NbTestCase { Map dataSources = this.utils.getDataSourceMap(); Long first = getDataSourceIdByName(SET1, dataSources); - IntraCaseCommonFilesMetadataBuilder singleSourceBuilder = new SingleDataSourceCommonFilesAlgorithm(first, dataSources, false, false); - CommonFilesMetadata metadata = singleSourceBuilder.findFiles(); + IntraCaseCommonAttributeSearcher singleSourceBuilder = new SingleIntraCaseCommonAttributeSearcher(first, dataSources, false, false); + CommonAttributeSearchResults metadata = singleSourceBuilder.findFiles(); int resultCount = metadata.size(); assertEquals(resultCount, 0); From 487222dcbc663eb5173e9932a35d024bf088d811 Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Tue, 17 Jul 2018 11:47:59 -0600 Subject: [PATCH 133/287] renames, accessibility stuff --- .../AbstractCommonAttributeSearcher.java | 52 ++++++++++++++++--- .../AllInterCaseCommonAttributeSearcher.java | 3 +- ...CommonAttributeInstanceNodeGenerator.java} | 18 +++---- .../CommonAttributeValue.java | 14 ++--- .../CommonAttributeValueNode.java | 6 +-- .../CommonFilesSearchAction.java | 5 +- ...InterCaseCommonAttributeSearchResults.java | 2 +- .../InterCaseCommonAttributeSearcher.java | 20 +++---- .../InterCaseSearchResultsProcessor.java | 9 ++-- ...IntraCaseCommonAttributeSearchResults.java | 2 +- .../IntraCaseCommonAttributeSearcher.java | 9 ++-- ...ingleInterCaseCommonAttributeSearcher.java | 5 +- 12 files changed, 86 insertions(+), 59 deletions(-) rename Core/src/org/sleuthkit/autopsy/commonfilesearch/{FileInstanceNodeGenerator.java => CommonAttributeInstanceNodeGenerator.java} (82%) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeSearcher.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeSearcher.java index 840e765285..40c81431e6 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeSearcher.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeSearcher.java @@ -29,14 +29,24 @@ import java.util.stream.Collectors; import java.util.stream.Stream; import org.openide.util.NbBundle; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; +import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException; import org.sleuthkit.datamodel.TskCoreException; +/** + * Prototype for an object which finds files with common attributes. + * Subclass this and implement findFiles in order + */ abstract class AbstractCommonAttributeSearcher { - boolean filterByMedia; - boolean filterByDoc; + private boolean filterByMedia; + private boolean filterByDoc; - abstract CommonAttributeSearchResults findFiles() throws TskCoreException, NoCurrentCaseException, SQLException, Exception; + AbstractCommonAttributeSearcher(boolean filterByMedia, boolean filterByDoc){ + this.filterByDoc = filterByDoc; + this.filterByMedia = filterByMedia; + } + + abstract CommonAttributeSearchResults findFiles() throws TskCoreException, NoCurrentCaseException, SQLException, EamDbException; @NbBundle.Messages({ "AbstractCommonFilesMetadataBuilder.buildTabTitle.titleIntraAll=Common Files (All Data Sources, %s)", @@ -51,15 +61,15 @@ abstract class AbstractCommonAttributeSearcher { "AbstractCommonFilesMetadataBuilder.buildCategorySelectionString.media=Media", "AbstractCommonFilesMetadataBuilder.buildCategorySelectionString.all=All File Categories" }) - protected String buildCategorySelectionString() { - if (!this.filterByDoc && !this.filterByMedia) { + String buildCategorySelectionString() { + if (!this.isFilterByDoc() && !this.isFilterByMedia()) { return Bundle.AbstractCommonFilesMetadataBuilder_buildCategorySelectionString_all(); } else { List filters = new ArrayList<>(); - if (this.filterByDoc) { + if (this.isFilterByDoc()) { filters.add(Bundle.AbstractCommonFilesMetadataBuilder_buildCategorySelectionString_doc()); } - if (this.filterByMedia) { + if (this.isFilterByMedia()) { filters.add(Bundle.AbstractCommonFilesMetadataBuilder_buildCategorySelectionString_media()); } return String.join(", ", filters); @@ -147,4 +157,32 @@ abstract class AbstractCommonAttributeSearcher { "application/vnd.oasis.opendocument.spreadsheet", //NON-NLS "application/vnd.oasis.opendocument.text" //NON-NLS ).collect(Collectors.toSet()); + + /** + * @return the filterByMedia + */ + boolean isFilterByMedia() { + return filterByMedia; + } + + /** + * @param filterByMedia the filterByMedia to set + */ + void setFilterByMedia(boolean filterByMedia) { + this.filterByMedia = filterByMedia; + } + + /** + * @return the filterByDoc + */ + boolean isFilterByDoc() { + return filterByDoc; + } + + /** + * @param filterByDoc the filterByDoc to set + */ + void setFilterByDoc(boolean filterByDoc) { + this.filterByDoc = filterByDoc; + } } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllInterCaseCommonAttributeSearcher.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllInterCaseCommonAttributeSearcher.java index b16ffc65dc..076410e252 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllInterCaseCommonAttributeSearcher.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllInterCaseCommonAttributeSearcher.java @@ -39,7 +39,7 @@ public class AllInterCaseCommonAttributeSearcher extends InterCaseCommonAttribut } @Override - public CommonAttributeSearchResults findFiles() throws TskCoreException, NoCurrentCaseException, SQLException, EamDbException, Exception { + public CommonAttributeSearchResults findFiles() throws TskCoreException, NoCurrentCaseException, SQLException, EamDbException { Map> interCaseCommonFiles = new HashMap<>(); InterCaseSearchResultsProcessor eamDbAttrInst = new InterCaseSearchResultsProcessor(); @@ -55,5 +55,4 @@ public class AllInterCaseCommonAttributeSearcher extends InterCaseCommonAttribut final String titleTemplate = Bundle.AbstractCommonFilesMetadataBuilder_buildTabTitle_titleInterAll(); return String.format(titleTemplate, new Object[]{buildCategorySelectionString}); } - } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/FileInstanceNodeGenerator.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeInstanceNodeGenerator.java similarity index 82% rename from Core/src/org/sleuthkit/autopsy/commonfilesearch/FileInstanceNodeGenerator.java rename to Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeInstanceNodeGenerator.java index 39b7a7673d..466fdd011e 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/FileInstanceNodeGenerator.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeInstanceNodeGenerator.java @@ -34,24 +34,24 @@ import org.sleuthkit.datamodel.TskCoreException; * Defines types which can be used to get some sort of File Instance node (a * child of the MD5Node) for use in the common files tree table. */ -public abstract class FileInstanceNodeGenerator { +public abstract class CommonAttributeInstanceNodeGenerator { - private static final Logger LOGGER = Logger.getLogger(FileInstanceNodeGenerator.class.getName()); + private static final Logger LOGGER = Logger.getLogger(CommonAttributeInstanceNodeGenerator.class.getName()); protected Long abstractFileReference; protected static Map cachedFiles; String caseName; String dataSource; - public FileInstanceNodeGenerator(Long abstractFileReference, Map cachedFiles, String dataSource, String caseName) { + public CommonAttributeInstanceNodeGenerator(Long abstractFileReference, Map cachedFiles, String dataSource, String caseName) { this.abstractFileReference = abstractFileReference; - FileInstanceNodeGenerator.cachedFiles = cachedFiles; + CommonAttributeInstanceNodeGenerator.cachedFiles = cachedFiles; this.caseName = caseName; this.dataSource = dataSource; } - public FileInstanceNodeGenerator(Map cachedFiles) { + public CommonAttributeInstanceNodeGenerator(Map cachedFiles) { this.abstractFileReference = -1L; - FileInstanceNodeGenerator.cachedFiles = cachedFiles; + CommonAttributeInstanceNodeGenerator.cachedFiles = cachedFiles; this.caseName = ""; this.dataSource = ""; } @@ -69,7 +69,7 @@ public abstract class FileInstanceNodeGenerator { if (cachedFiles.containsKey(this.abstractFileReference)) { return cachedFiles.get(this.abstractFileReference); } else { - AbstractFile file = FileInstanceNodeGenerator.loadFileFromSleuthkitCase(this.abstractFileReference); + AbstractFile file = CommonAttributeInstanceNodeGenerator.loadFileFromSleuthkitCase(this.abstractFileReference); cachedFiles.put(this.abstractFileReference, file); return file; } @@ -132,10 +132,8 @@ public abstract class FileInstanceNodeGenerator { return this.abstractFileReference; } - public static FileInstanceNodeGenerator createInstance(Iterator identicalFileNodeGeneratorIterator, Integer instanceId) throws Exception { + public static CommonAttributeInstanceNodeGenerator createInstance(Iterator identicalFileNodeGeneratorIterator, Integer instanceId) throws Exception { - //Long arbitraryIdenticalAbstractFileId = null; return new InterCaseCommonAttributeSearchResults(instanceId, cachedFiles); - } } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeValue.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeValue.java index aefbaa4376..169dad10ed 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeValue.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeValue.java @@ -33,9 +33,9 @@ import java.util.stream.Collectors; final public class CommonAttributeValue { private final String md5; - private final List fileInstances; + private final List fileInstances; - CommonAttributeValue(String md5, List fileInstances) { + CommonAttributeValue(String md5, List fileInstances) { this.md5 = md5; this.fileInstances = fileInstances; } @@ -50,13 +50,13 @@ final public class CommonAttributeValue { } public String getCases() { - final String cases = this.fileInstances.stream().map(FileInstanceNodeGenerator::getCaseName).collect(Collectors.joining(", ")); + final String cases = this.fileInstances.stream().map(CommonAttributeInstanceNodeGenerator::getCaseName).collect(Collectors.joining(", ")); return cases; } public String getDataSources() { Set sources = new HashSet<>(); - for (FileInstanceNodeGenerator data : this.fileInstances) { + for (CommonAttributeInstanceNodeGenerator data : this.fileInstances) { sources.add(data.getDataSource()); } @@ -64,15 +64,15 @@ final public class CommonAttributeValue { return dataSources; } - void addFileInstanceMetadata(FileInstanceNodeGenerator metadata) { + void addFileInstanceMetadata(CommonAttributeInstanceNodeGenerator metadata) { this.fileInstances.add(metadata); } - void addFileInstanceMetadata(FileInstanceNodeGenerator metadata, String caseName) { + void addFileInstanceMetadata(CommonAttributeInstanceNodeGenerator metadata, String caseName) { this.fileInstances.add(metadata); } - public Collection getMetadata() { + public Collection getMetadata() { return Collections.unmodifiableCollection(this.fileInstances); } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeValueNode.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeValueNode.java index 53b6c38366..edfa436a04 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeValueNode.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeValueNode.java @@ -132,7 +132,7 @@ public class CommonAttributeValueNode extends DisplayableItemNode { * Child generator for SleuthkitCaseFileInstanceNode of * CommonAttributeValueNode. */ - static class FileInstanceNodeFactory extends ChildFactory { + static class FileInstanceNodeFactory extends ChildFactory { //private final Map cachedFiles; @@ -144,12 +144,12 @@ public class CommonAttributeValueNode extends DisplayableItemNode { } @Override - protected Node[] createNodesForKey(FileInstanceNodeGenerator file) { + protected Node[] createNodesForKey(CommonAttributeInstanceNodeGenerator file) { return file.generateNodes(); } @Override - protected boolean createKeys(List list) { + protected boolean createKeys(List list) { list.addAll(this.descendants.getMetadata()); return true; } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesSearchAction.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesSearchAction.java index cde1f4b3cb..80e4f9754a 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesSearchAction.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesSearchAction.java @@ -38,7 +38,6 @@ final public class CommonFilesSearchAction extends CallableSystemAction { private static CommonFilesSearchAction instance = null; private static final long serialVersionUID = 1L; - private static final Logger logger = Logger.getLogger(CommonFilesSearchAction.class.getName()); CommonFilesSearchAction() { super(); @@ -54,9 +53,9 @@ final public class CommonFilesSearchAction extends CallableSystemAction { || (EamDb.isEnabled() && EamDb.getInstance().getCases().size() > 1); } catch(TskCoreException ex) { - logger.log(Level.SEVERE, "Error getting data sources for action enabled check", ex); + LOGGER.log(Level.SEVERE, "Error getting data sources for action enabled check", ex); } catch (EamDbException ex) { - logger.log(Level.SEVERE, "Error getting CR cases for action enabled check", ex); + LOGGER.log(Level.SEVERE, "Error getting CR cases for action enabled check", ex); } return super.isEnabled() && shouldBeEnabled; } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearchResults.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearchResults.java index 23aa865038..d9dd776cc9 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearchResults.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearchResults.java @@ -36,7 +36,7 @@ import org.sleuthkit.datamodel.TskCoreException; /** * Generates a DisplayableItmeNode using a CentralRepositoryFile. */ -final public class InterCaseCommonAttributeSearchResults extends FileInstanceNodeGenerator { +final public class InterCaseCommonAttributeSearchResults extends CommonAttributeInstanceNodeGenerator { private static final Logger LOGGER = Logger.getLogger(InterCaseCommonAttributeSearchResults.class.getName()); private final Integer crFileId; diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearcher.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearcher.java index 2229981ace..f71b1a7db6 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearcher.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearcher.java @@ -35,10 +35,7 @@ import org.sleuthkit.datamodel.HashUtility; * in the Central Repo. */ public abstract class InterCaseCommonAttributeSearcher extends AbstractCommonAttributeSearcher { - //CONSIDER: we should create an interface which specifies the findFiles feature - // instead of an abstract class and then have two abstract classes: - // inter- and intra- which implement the interface and then 4 subclasses - // 2 for each abstract class: singlecase/allcase; singledatasource/all datasource + EamDb dbManager; /** * Implements the algorithm for getting common files across all data sources @@ -52,8 +49,7 @@ public abstract class InterCaseCommonAttributeSearcher extends AbstractCommonAtt * @throws EamDbException */ InterCaseCommonAttributeSearcher(boolean filterByMediaMimeType, boolean filterByDocMimeType) throws EamDbException { - filterByMedia = filterByMediaMimeType; - filterByDoc = filterByDocMimeType; + super(filterByMediaMimeType, filterByDocMimeType); dbManager = EamDb.getInstance(); } @@ -84,14 +80,14 @@ public abstract class InterCaseCommonAttributeSearcher extends AbstractCommonAtt if(interCaseCommonFiles.containsKey(md5)) { //Add to intercase metaData final CommonAttributeValue md5Metadata = interCaseCommonFiles.get(md5); - final Iterator identitcalFileInstanceMetadata = interCaseCommonFiles.get(md5).getMetadata().iterator(); - FileInstanceNodeGenerator nodeGenerator = FileInstanceNodeGenerator.createInstance(identitcalFileInstanceMetadata, commonAttrId); + final Iterator identitcalFileInstanceMetadata = interCaseCommonFiles.get(md5).getMetadata().iterator(); + CommonAttributeInstanceNodeGenerator nodeGenerator = CommonAttributeInstanceNodeGenerator.createInstance(identitcalFileInstanceMetadata, commonAttrId); md5Metadata.addFileInstanceMetadata(nodeGenerator, correlationCaseDisplayName); } else { CommonAttributeValue md5Metadata = new CommonAttributeValue(md5); - final Iterator identitcalFileInstanceMetadata = md5Metadata.getMetadata().iterator(); - FileInstanceNodeGenerator nodeGenerator = FileInstanceNodeGenerator.createInstance(identitcalFileInstanceMetadata, commonAttrId); + final Iterator identitcalFileInstanceMetadata = md5Metadata.getMetadata().iterator(); + CommonAttributeInstanceNodeGenerator nodeGenerator = CommonAttributeInstanceNodeGenerator.createInstance(identitcalFileInstanceMetadata, commonAttrId); md5Metadata.addFileInstanceMetadata(nodeGenerator, correlationCaseDisplayName); interCaseCommonFiles.put(md5, md5Metadata); } @@ -106,12 +102,12 @@ public abstract class InterCaseCommonAttributeSearcher extends AbstractCommonAtt return instanceCollatedCommonFiles; } - protected CorrelationCase getCorrelationCaseFromId(int correlationCaseId) throws EamDbException, Exception { + protected CorrelationCase getCorrelationCaseFromId(int correlationCaseId) throws EamDbException { for (CorrelationCase cCase : this.dbManager.getCases()) { if (cCase.getID() == correlationCaseId) { return cCase; } } - throw new Exception("Cannot locate case."); + throw new IllegalArgumentException("Cannot locate case."); } } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseSearchResultsProcessor.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseSearchResultsProcessor.java index d4b63e1c04..29da243113 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseSearchResultsProcessor.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseSearchResultsProcessor.java @@ -40,7 +40,7 @@ import org.sleuthkit.autopsy.coreutils.Logger; */ final class InterCaseSearchResultsProcessor { - private static final Logger logger = Logger.getLogger(CommonAttributePanel.class.getName()); + private static final Logger LOGGER = Logger.getLogger(CommonAttributePanel.class.getName()); private final Map intercaseCommonValuesMap = new HashMap<>(); private final Map intercaseCommonCasesMap = new HashMap<>(); @@ -55,11 +55,10 @@ final class InterCaseSearchResultsProcessor { return instancetableCallback.getCorrelationAttribute(); } catch (EamDbException ex) { - logger.log(Level.SEVERE, "Error accessing EamDb processing InstanceTable row.", ex); + LOGGER.log(Level.SEVERE, "Error accessing EamDb processing InstanceTable row.", ex); } return null; - } void processCorrelationCaseAttributeValues(Case currentCase) { @@ -73,7 +72,7 @@ final class InterCaseSearchResultsProcessor { intercaseCommonValuesMap.putAll(instancetableCallback.getCorrelationIdValueMap()); intercaseCommonCasesMap.putAll(instancetableCallback.getCorrelationIdToCaseMap()); } catch (EamDbException ex) { - logger.log(Level.SEVERE, "Error accessing EamDb processing CaseInstancesTable.", ex); + LOGGER.log(Level.SEVERE, "Error accessing EamDb processing CaseInstancesTable.", ex); } } @@ -89,7 +88,7 @@ final class InterCaseSearchResultsProcessor { intercaseCommonValuesMap.putAll(instancetableCallback.getCorrelationIdValueMap()); intercaseCommonCasesMap.putAll(instancetableCallback.getCorrelationIdToCaseMap()); } catch (EamDbException ex) { - logger.log(Level.SEVERE, "Error accessing EamDb processing CaseInstancesTable.", ex); + LOGGER.log(Level.SEVERE, "Error accessing EamDb processing CaseInstancesTable.", ex); } } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCaseCommonAttributeSearchResults.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCaseCommonAttributeSearchResults.java index e158332349..2697cc8fbd 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCaseCommonAttributeSearchResults.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCaseCommonAttributeSearchResults.java @@ -27,7 +27,7 @@ import org.sleuthkit.datamodel.AbstractFile; /** * Encapsulates data required to instantiate a FileInstanceNode. */ -final public class IntraCaseCommonAttributeSearchResults extends FileInstanceNodeGenerator { +final public class IntraCaseCommonAttributeSearchResults extends CommonAttributeInstanceNodeGenerator { /** * Create meta data required to find an abstract file and build a diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCaseCommonAttributeSearcher.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCaseCommonAttributeSearcher.java index 652442cca2..ef1ae7945b 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCaseCommonAttributeSearcher.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCaseCommonAttributeSearcher.java @@ -59,9 +59,8 @@ public abstract class IntraCaseCommonAttributeSearcher extends AbstractCommonAtt * broadly categorized as document types */ IntraCaseCommonAttributeSearcher(Map dataSourceIdMap, boolean filterByMediaMimeType, boolean filterByDocMimeType) { + super(filterByMediaMimeType, filterByDocMimeType); dataSourceIdToNameMap = dataSourceIdMap; - filterByMedia = filterByMediaMimeType; - filterByDoc = filterByDocMimeType; } /** @@ -98,7 +97,7 @@ public abstract class IntraCaseCommonAttributeSearcher extends AbstractCommonAtt * @throws SQLException */ @Override - public CommonAttributeSearchResults findFiles() throws TskCoreException, NoCurrentCaseException, SQLException, Exception { + public CommonAttributeSearchResults findFiles() throws TskCoreException, NoCurrentCaseException, SQLException { //TODO do we need all those exceptions or can we differentiate when they are caught? Map commonFiles = new HashMap<>(); @@ -155,10 +154,10 @@ public abstract class IntraCaseCommonAttributeSearcher extends AbstractCommonAtt Set mimeTypesToFilterOn = new HashSet<>(); String mimeTypeString = ""; - if (filterByMedia) { + if (isFilterByMedia()) { mimeTypesToFilterOn.addAll(MEDIA_PICS_VIDEO_MIME_TYPES); } - if (filterByDoc) { + if (isFilterByDoc()) { mimeTypesToFilterOn.addAll(TEXT_FILES_MIME_TYPES); } StringBuilder mimeTypeFilter = new StringBuilder(mimeTypesToFilterOn.size()); diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/SingleInterCaseCommonAttributeSearcher.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/SingleInterCaseCommonAttributeSearcher.java index 09fdeeb013..d0f72018f7 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/SingleInterCaseCommonAttributeSearcher.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/SingleInterCaseCommonAttributeSearcher.java @@ -62,17 +62,16 @@ public class SingleInterCaseCommonAttributeSearcher extends InterCaseCommonAttri * @throws NoCurrentCaseException * @throws SQLException * @throws EamDbException - * @throws Exception */ @Override - public CommonAttributeSearchResults findFiles() throws TskCoreException, NoCurrentCaseException, SQLException, EamDbException, Exception { + public CommonAttributeSearchResults findFiles() throws TskCoreException, NoCurrentCaseException, SQLException, EamDbException { CorrelationCase cCase = this.getCorrelationCaseFromId(this.corrleationCaseId); correlationCaseName = cCase.getDisplayName(); return this.findFiles(cCase); } - protected CommonAttributeSearchResults findFiles(CorrelationCase correlationCase) throws TskCoreException, NoCurrentCaseException, SQLException, EamDbException, Exception { + protected CommonAttributeSearchResults findFiles(CorrelationCase correlationCase) throws TskCoreException, NoCurrentCaseException, SQLException, EamDbException { Map> interCaseCommonFiles = new HashMap<>(); From 8233f41fd6c9c1b6483cb17eb86e84e80aebf99e Mon Sep 17 00:00:00 2001 From: Andrew Ziehl Date: Tue, 17 Jul 2018 11:58:15 -0700 Subject: [PATCH 134/287] renames and comments for CR results processing. --- .../AllInterCaseCommonAttributeSearcher.java | 12 ++- ...InterCaseCommonAttributeSearchResults.java | 2 +- .../InterCaseSearchResultsProcessor.java | 76 ++++++++++--------- ...ingleInterCaseCommonAttributeSearcher.java | 2 +- 4 files changed, 46 insertions(+), 46 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllInterCaseCommonAttributeSearcher.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllInterCaseCommonAttributeSearcher.java index 076410e252..2e4019850a 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllInterCaseCommonAttributeSearcher.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllInterCaseCommonAttributeSearcher.java @@ -33,18 +33,16 @@ import org.sleuthkit.datamodel.TskCoreException; * present case. */ public class AllInterCaseCommonAttributeSearcher extends InterCaseCommonAttributeSearcher { - + public AllInterCaseCommonAttributeSearcher(boolean filterByMediaMimeType, boolean filterByDocMimeType) throws EamDbException { super(filterByMediaMimeType, filterByDocMimeType); - } - + } + @Override public CommonAttributeSearchResults findFiles() throws TskCoreException, NoCurrentCaseException, SQLException, EamDbException { - Map> interCaseCommonFiles = new HashMap<>(); - InterCaseSearchResultsProcessor eamDbAttrInst = new InterCaseSearchResultsProcessor(); - eamDbAttrInst.processCorrelationCaseAttributeValues(Case.getCurrentCase()); - interCaseCommonFiles = gatherIntercaseResults(eamDbAttrInst.getIntercaseCommonValuesMap(), eamDbAttrInst.getIntercaseCommonCasesMap()); + eamDbAttrInst.findInterCaseCommonAttributeValues(Case.getCurrentCase()); + Map> interCaseCommonFiles = gatherIntercaseResults(eamDbAttrInst.getIntercaseCommonValuesMap(), eamDbAttrInst.getIntercaseCommonCasesMap()); return new CommonAttributeSearchResults(interCaseCommonFiles); } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearchResults.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearchResults.java index d9dd776cc9..ab65e5ae73 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearchResults.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearchResults.java @@ -78,7 +78,7 @@ final public class InterCaseCommonAttributeSearchResults extends CommonAttribute @Override public DisplayableItemNode[] generateNodes() { InterCaseSearchResultsProcessor eamDbAttrInst = new InterCaseSearchResultsProcessor(); - CorrelationAttribute corrAttr = eamDbAttrInst.processCorrelationCaseSingleAttribute(crFileId); //TODO which do we want + CorrelationAttribute corrAttr = eamDbAttrInst.findSingleCorrelationAttribute(crFileId); //TODO which do we want List attrInstNodeList = new ArrayList<>(0); for (CorrelationAttributeInstance attrInst : corrAttr.getInstances()) { diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseSearchResultsProcessor.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseSearchResultsProcessor.java index 29da243113..f6980a1229 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseSearchResultsProcessor.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseSearchResultsProcessor.java @@ -44,49 +44,62 @@ final class InterCaseSearchResultsProcessor { private final Map intercaseCommonValuesMap = new HashMap<>(); private final Map intercaseCommonCasesMap = new HashMap<>(); - - CorrelationAttribute processCorrelationCaseSingleAttribute(int attrbuteId) { - try { - EamDbAttributeInstanceRowCallback instancetableCallback = new EamDbAttributeInstanceRowCallback(); + + /** + * Finds a single CorrelationAttribute given an id. + * + * @param attrbuteId Row of CorrelationAttribute to retrieve from the EamDb + * @return CorrelationAttribute object representation of retrieved match + */ + CorrelationAttribute findSingleCorrelationAttribute(int attrbuteId) { + try { + InterCaseCommonAttributeRowCallback instancetableCallback = new InterCaseCommonAttributeRowCallback(); EamDb DbManager = EamDb.getInstance(); CorrelationAttribute.Type fileType = DbManager.getCorrelationTypeById(CorrelationAttribute.FILES_TYPE_ID); DbManager.processInstanceTableRow(fileType, attrbuteId, instancetableCallback); return instancetableCallback.getCorrelationAttribute(); - + } catch (EamDbException ex) { LOGGER.log(Level.SEVERE, "Error accessing EamDb processing InstanceTable row.", ex); } - + return null; } - void processCorrelationCaseAttributeValues(Case currentCase) { - + /** + * Given the current case, fins all intercase common files from the EamDb + * and builds maps of obj id to md5 and case. + * + * @param currentCase The current TSK Case. + */ + void findInterCaseCommonAttributeValues(Case currentCase) { try { - EamDbAttributeInstancesCallback instancetableCallback = new EamDbAttributeInstancesCallback(); + InterCaseCommonAttributesCallback instancetableCallback = new InterCaseCommonAttributesCallback(); EamDb DbManager = EamDb.getInstance(); CorrelationAttribute.Type fileType = DbManager.getCorrelationTypeById(CorrelationAttribute.FILES_TYPE_ID); DbManager.processCaseInstancesTable(fileType, DbManager.getCase(currentCase), instancetableCallback); - intercaseCommonValuesMap.putAll(instancetableCallback.getCorrelationIdValueMap()); - intercaseCommonCasesMap.putAll(instancetableCallback.getCorrelationIdToCaseMap()); } catch (EamDbException ex) { LOGGER.log(Level.SEVERE, "Error accessing EamDb processing CaseInstancesTable.", ex); } } - - void processSingleCaseCorrelationCaseAttributeValues(Case currentCase, CorrelationCase singleCase) { + /** + * Given the current case, and a specific case of interest, finds common + * files which exist between cases from the EamDb. Builds maps of obj id to + * md5 and case. + * + * @param currentCase The current TSK Case. + * @param singleCase The case of interest. Matches must exist in this case. + */ + void findSingleInterCaseCommonAttributeValues(Case currentCase, CorrelationCase singleCase) { try { - EamDbAttributeInstancesCallback instancetableCallback = new EamDbAttributeInstancesCallback(); + InterCaseCommonAttributesCallback instancetableCallback = new InterCaseCommonAttributesCallback(); EamDb DbManager = EamDb.getInstance(); CorrelationAttribute.Type fileType = DbManager.getCorrelationTypeById(CorrelationAttribute.FILES_TYPE_ID); DbManager.processSingleCaseInstancesTable(fileType, DbManager.getCase(currentCase), singleCase, instancetableCallback); - - intercaseCommonValuesMap.putAll(instancetableCallback.getCorrelationIdValueMap()); - intercaseCommonCasesMap.putAll(instancetableCallback.getCorrelationIdToCaseMap()); } catch (EamDbException ex) { LOGGER.log(Level.SEVERE, "Error accessing EamDb processing CaseInstancesTable.", ex); } @@ -102,42 +115,31 @@ final class InterCaseSearchResultsProcessor { } /** - * Callback to use with processCaseInstancesTable which generates a list of - * md5s for common files search + * Callback to use with findInterCaseCommonAttributeValues which generates a + * list of md5s for common files search */ - private class EamDbAttributeInstancesCallback implements InstanceTableCallback { - - private final Map correlationIdToValueMap = new HashMap<>(); - private final Map correlationIdToDatasourceMap = new HashMap<>(); + private class InterCaseCommonAttributesCallback implements InstanceTableCallback { @Override public void process(ResultSet resultSet) { try { while (resultSet.next()) { int resultId = InstanceTableCallback.getId(resultSet); - correlationIdToValueMap.put(resultId, InstanceTableCallback.getValue(resultSet)); - correlationIdToDatasourceMap.put(resultId, InstanceTableCallback.getCaseId(resultSet)); + intercaseCommonValuesMap.put(resultId, InstanceTableCallback.getValue(resultSet)); + intercaseCommonCasesMap.put(resultId, InstanceTableCallback.getCaseId(resultSet)); } } catch (SQLException ex) { Exceptions.printStackTrace(ex); } } - Map getCorrelationIdValueMap() { - return Collections.unmodifiableMap(correlationIdToValueMap); - } - - Map getCorrelationIdToCaseMap() { - return Collections.unmodifiableMap(correlationIdToDatasourceMap); - } - } /** - * Callback to use with processCaseInstancesTable which generates a list of - * md5s for common files search + * Callback to use with findSingleCorrelationAttribute which retrieves a + * single CorrelationAttribute from the EamDb. */ - private class EamDbAttributeInstanceRowCallback implements InstanceTableCallback { + private class InterCaseCommonAttributeRowCallback implements InstanceTableCallback { CorrelationAttribute correlationAttribute = null; @@ -146,7 +148,7 @@ final class InterCaseSearchResultsProcessor { try { EamDb DbManager = EamDb.getInstance(); CorrelationAttribute.Type fileType = DbManager.getCorrelationTypeById(CorrelationAttribute.FILES_TYPE_ID); - + while (resultSet.next()) { CorrelationCase correlationCase = DbManager.getCaseById(InstanceTableCallback.getCaseId(resultSet)); CorrelationDataSource dataSource = DbManager.getDataSourceById(correlationCase, InstanceTableCallback.getDataSourceId(resultSet)); diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/SingleInterCaseCommonAttributeSearcher.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/SingleInterCaseCommonAttributeSearcher.java index d0f72018f7..67f4ffc588 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/SingleInterCaseCommonAttributeSearcher.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/SingleInterCaseCommonAttributeSearcher.java @@ -76,7 +76,7 @@ public class SingleInterCaseCommonAttributeSearcher extends InterCaseCommonAttri Map> interCaseCommonFiles = new HashMap<>(); InterCaseSearchResultsProcessor eamDbAttrInst = new InterCaseSearchResultsProcessor(); - eamDbAttrInst.processSingleCaseCorrelationCaseAttributeValues(Case.getCurrentCase(), correlationCase); + eamDbAttrInst.findSingleInterCaseCommonAttributeValues(Case.getCurrentCase(), correlationCase); interCaseCommonFiles = gatherIntercaseResults(eamDbAttrInst.getIntercaseCommonValuesMap(), eamDbAttrInst.getIntercaseCommonCasesMap()); return new CommonAttributeSearchResults(interCaseCommonFiles); From 4450b1619bf5c0b46b2f81d686fb22f14c6beda2 Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Tue, 17 Jul 2018 13:22:14 -0600 Subject: [PATCH 135/287] cleanup --- .../AbstractCommonAttributeSearcher.java | 5 +++++ .../InterCaseSearchResultsProcessor.java | 16 +++++++--------- .../IntraCaseCommonAttributeSearcher.java | 1 - 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeSearcher.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeSearcher.java index 40c81431e6..ad05771e51 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeSearcher.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeSearcher.java @@ -48,6 +48,11 @@ abstract class AbstractCommonAttributeSearcher { abstract CommonAttributeSearchResults findFiles() throws TskCoreException, NoCurrentCaseException, SQLException, EamDbException; + /** + * Implement this to create a descriptive string for the tab which will display + * this data. + * @return an informative string + */ @NbBundle.Messages({ "AbstractCommonFilesMetadataBuilder.buildTabTitle.titleIntraAll=Common Files (All Data Sources, %s)", "AbstractCommonFilesMetadataBuilder.buildTabTitle.titleIntraSingle=Common Files (Data Source: %s, %s)", diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseSearchResultsProcessor.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseSearchResultsProcessor.java index 29da243113..f9e248d9dc 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseSearchResultsProcessor.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseSearchResultsProcessor.java @@ -44,20 +44,20 @@ final class InterCaseSearchResultsProcessor { private final Map intercaseCommonValuesMap = new HashMap<>(); private final Map intercaseCommonCasesMap = new HashMap<>(); - + CorrelationAttribute processCorrelationCaseSingleAttribute(int attrbuteId) { - try { + try { EamDbAttributeInstanceRowCallback instancetableCallback = new EamDbAttributeInstanceRowCallback(); EamDb DbManager = EamDb.getInstance(); CorrelationAttribute.Type fileType = DbManager.getCorrelationTypeById(CorrelationAttribute.FILES_TYPE_ID); DbManager.processInstanceTableRow(fileType, attrbuteId, instancetableCallback); return instancetableCallback.getCorrelationAttribute(); - + } catch (EamDbException ex) { LOGGER.log(Level.SEVERE, "Error accessing EamDb processing InstanceTable row.", ex); } - + return null; } @@ -76,8 +76,8 @@ final class InterCaseSearchResultsProcessor { } } - - void processSingleCaseCorrelationCaseAttributeValues(Case currentCase, CorrelationCase singleCase) { + + void processSingleCaseCorrelationCaseAttributeValues(Case currentCase, CorrelationCase singleCase) { try { EamDbAttributeInstancesCallback instancetableCallback = new EamDbAttributeInstancesCallback(); @@ -90,7 +90,6 @@ final class InterCaseSearchResultsProcessor { } catch (EamDbException ex) { LOGGER.log(Level.SEVERE, "Error accessing EamDb processing CaseInstancesTable.", ex); } - } Map getIntercaseCommonValuesMap() { @@ -146,7 +145,7 @@ final class InterCaseSearchResultsProcessor { try { EamDb DbManager = EamDb.getInstance(); CorrelationAttribute.Type fileType = DbManager.getCorrelationTypeById(CorrelationAttribute.FILES_TYPE_ID); - + while (resultSet.next()) { CorrelationCase correlationCase = DbManager.getCaseById(InstanceTableCallback.getCaseId(resultSet)); CorrelationDataSource dataSource = DbManager.getDataSourceById(correlationCase, InstanceTableCallback.getDataSourceId(resultSet)); @@ -165,6 +164,5 @@ final class InterCaseSearchResultsProcessor { CorrelationAttribute getCorrelationAttribute() { return correlationAttribute; } - } } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCaseCommonAttributeSearcher.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCaseCommonAttributeSearcher.java index ef1ae7945b..e60476da36 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCaseCommonAttributeSearcher.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCaseCommonAttributeSearcher.java @@ -21,7 +21,6 @@ package org.sleuthkit.autopsy.commonfilesearch; import java.sql.ResultSet; import java.sql.SQLException; -import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; From a6c4e93543cf9e8eb34a55a51442f6b0a5804e31 Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Tue, 17 Jul 2018 14:17:10 -0600 Subject: [PATCH 136/287] cleanup comments --- .../AbstractCommonAttributeSearcher.java | 12 ++++++++++++ .../AllInterCaseCommonAttributeSearcher.java | 1 - .../CommonAttributeInstanceNodeGenerator.java | 16 ++++++++-------- 3 files changed, 20 insertions(+), 9 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeSearcher.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeSearcher.java index ad05771e51..0308f60823 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeSearcher.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeSearcher.java @@ -46,6 +46,18 @@ abstract class AbstractCommonAttributeSearcher { this.filterByMedia = filterByMedia; } + /** + * Implement this to search for files with common attributes. Creates an + * object (CommonAttributeSearchResults) which contains all of the information + * required to display a tree view in the UI. The view will contain 3 layers: + * a top level node, indicating the number matches each of it's children possess, + * a mid level node indicating the matched attribute, + * @return + * @throws TskCoreException + * @throws NoCurrentCaseException + * @throws SQLException + * @throws EamDbException + */ abstract CommonAttributeSearchResults findFiles() throws TskCoreException, NoCurrentCaseException, SQLException, EamDbException; /** diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllInterCaseCommonAttributeSearcher.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllInterCaseCommonAttributeSearcher.java index 2e4019850a..74e3aabb2a 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllInterCaseCommonAttributeSearcher.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllInterCaseCommonAttributeSearcher.java @@ -20,7 +20,6 @@ package org.sleuthkit.autopsy.commonfilesearch; import java.sql.SQLException; -import java.util.HashMap; import java.util.List; import java.util.Map; import org.sleuthkit.autopsy.casemodule.Case; diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeInstanceNodeGenerator.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeInstanceNodeGenerator.java index 466fdd011e..1ed6c884ad 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeInstanceNodeGenerator.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeInstanceNodeGenerator.java @@ -37,20 +37,20 @@ import org.sleuthkit.datamodel.TskCoreException; public abstract class CommonAttributeInstanceNodeGenerator { private static final Logger LOGGER = Logger.getLogger(CommonAttributeInstanceNodeGenerator.class.getName()); - protected Long abstractFileReference; + protected Long abstractFileObjectId; protected static Map cachedFiles; String caseName; String dataSource; public CommonAttributeInstanceNodeGenerator(Long abstractFileReference, Map cachedFiles, String dataSource, String caseName) { - this.abstractFileReference = abstractFileReference; + this.abstractFileObjectId = abstractFileReference; CommonAttributeInstanceNodeGenerator.cachedFiles = cachedFiles; this.caseName = caseName; this.dataSource = dataSource; } public CommonAttributeInstanceNodeGenerator(Map cachedFiles) { - this.abstractFileReference = -1L; + this.abstractFileObjectId = -1L; CommonAttributeInstanceNodeGenerator.cachedFiles = cachedFiles; this.caseName = ""; this.dataSource = ""; @@ -66,11 +66,11 @@ public abstract class CommonAttributeInstanceNodeGenerator { * implementations of this object */ protected AbstractFile lookupOrCreateAbstractFile() { - if (cachedFiles.containsKey(this.abstractFileReference)) { - return cachedFiles.get(this.abstractFileReference); + if (cachedFiles.containsKey(this.abstractFileObjectId)) { + return cachedFiles.get(this.abstractFileObjectId); } else { - AbstractFile file = CommonAttributeInstanceNodeGenerator.loadFileFromSleuthkitCase(this.abstractFileReference); - cachedFiles.put(this.abstractFileReference, file); + AbstractFile file = CommonAttributeInstanceNodeGenerator.loadFileFromSleuthkitCase(this.abstractFileObjectId); + cachedFiles.put(this.abstractFileObjectId, file); return file; } } @@ -129,7 +129,7 @@ public abstract class CommonAttributeInstanceNodeGenerator { } public Long getIdenticalFileSleuthkitCaseObjectID() { - return this.abstractFileReference; + return this.abstractFileObjectId; } public static CommonAttributeInstanceNodeGenerator createInstance(Iterator identicalFileNodeGeneratorIterator, Integer instanceId) throws Exception { From 601a8bb212a8ddfb3874c7f01b86e2a6bac8908d Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Tue, 17 Jul 2018 15:05:26 -0600 Subject: [PATCH 137/287] omg --- .../CommonAttributeInstanceNodeGenerator.java | 28 +++---------------- ...InterCaseCommonAttributeSearchResults.java | 27 ++++++++---------- ...IntraCaseCommonAttributeSearchResults.java | 28 +++++++++++++++---- 3 files changed, 39 insertions(+), 44 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeInstanceNodeGenerator.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeInstanceNodeGenerator.java index 1ed6c884ad..008bb37dcc 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeInstanceNodeGenerator.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeInstanceNodeGenerator.java @@ -69,37 +69,17 @@ public abstract class CommonAttributeInstanceNodeGenerator { if (cachedFiles.containsKey(this.abstractFileObjectId)) { return cachedFiles.get(this.abstractFileObjectId); } else { - AbstractFile file = CommonAttributeInstanceNodeGenerator.loadFileFromSleuthkitCase(this.abstractFileObjectId); + AbstractFile file = this.loadFileFromSleuthkitCase(); cachedFiles.put(this.abstractFileObjectId, file); return file; } } - private static AbstractFile loadFileFromSleuthkitCase(Long objectId) { - - Case currentCase; - try { - currentCase = Case.getCurrentCaseThrows(); - - SleuthkitCase tskDb = currentCase.getSleuthkitCase(); - - AbstractFile abstractFile = tskDb.findAllFilesWhere(String.format("obj_id in (%s)", objectId)).get(0); - - return abstractFile; - - } catch (TskCoreException | NoCurrentCaseException ex) { - LOGGER.log(Level.SEVERE, String.format("Unable to find AbstractFile for record with obj_id: %s. Node not created.", new Object[]{objectId}), ex); - return null; - } - } - /** - * Create a node which is a child of the MD5Node, to be used to display a - * row in the tree table - * - * @return child row node + * + * @return */ - public abstract DisplayableItemNode generateNode(); + abstract protected AbstractFile loadFileFromSleuthkitCase(); /** * Create a list of nodes which are a child of the MD5Node, to be used to display a diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearchResults.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearchResults.java index ab65e5ae73..3302e15f16 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearchResults.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearchResults.java @@ -40,7 +40,8 @@ final public class InterCaseCommonAttributeSearchResults extends CommonAttribute private static final Logger LOGGER = Logger.getLogger(InterCaseCommonAttributeSearchResults.class.getName()); private final Integer crFileId; - private CorrelationAttributeInstance tempAttributeInst; + private CorrelationAttributeInstance currentAttributeInst; + private String currentFullPath; InterCaseCommonAttributeSearchResults(Integer attrInstId, Map cachedFiles) { super(cachedFiles); @@ -48,42 +49,38 @@ final public class InterCaseCommonAttributeSearchResults extends CommonAttribute } - private static AbstractFile loadFileFromSleuthkitCase(String path) { + @Override + protected AbstractFile loadFileFromSleuthkitCase() { Case currentCase; + this.currentFullPath = this.currentAttributeInst.getFilePath(); + try { currentCase = Case.getCurrentCaseThrows(); SleuthkitCase tskDb = currentCase.getSleuthkitCase(); - String[] splitPath = path.split("/"); + String[] splitPath = this.currentFullPath.split("/"); String fileName = splitPath[splitPath.length -1]; AbstractFile abstractFile = tskDb.findAllFilesWhere(String.format("lower(name) = '%s'", fileName)).get(0); // TODO workaround where we don't need AbstractFile? return abstractFile; } catch (TskCoreException | NoCurrentCaseException ex) { - LOGGER.log(Level.SEVERE, String.format("Unable to find AbstractFile for record with filePath: %s. Node not created.", new Object[]{path}), ex); + LOGGER.log(Level.SEVERE, String.format("Unable to find AbstractFile for record with filePath: %s. Node not created.", new Object[]{this.currentFullPath}), ex); return null; } } - @Override - public DisplayableItemNode generateNode() { - if (tempAttributeInst != null) { - return new InterCaseCommonAttributeInstanceNode(tempAttributeInst, this.lookupOrCreateAbstractFile()); - } - return null; - } - @Override public DisplayableItemNode[] generateNodes() { InterCaseSearchResultsProcessor eamDbAttrInst = new InterCaseSearchResultsProcessor(); - CorrelationAttribute corrAttr = eamDbAttrInst.findSingleCorrelationAttribute(crFileId); //TODO which do we want + CorrelationAttribute corrAttr = eamDbAttrInst.findSingleCorrelationAttribute(crFileId); List attrInstNodeList = new ArrayList<>(0); for (CorrelationAttributeInstance attrInst : corrAttr.getInstances()) { - tempAttributeInst = attrInst; - DisplayableItemNode generatedInstNode = new InterCaseCommonAttributeInstanceNode(tempAttributeInst, loadFileFromSleuthkitCase(tempAttributeInst.getFilePath())); + currentAttributeInst = attrInst; + + DisplayableItemNode generatedInstNode = new InterCaseCommonAttributeInstanceNode(currentAttributeInst, this.lookupOrCreateAbstractFile()); if (generatedInstNode != null) { attrInstNodeList.add(generatedInstNode); } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCaseCommonAttributeSearchResults.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCaseCommonAttributeSearchResults.java index 2697cc8fbd..3cb989e58e 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCaseCommonAttributeSearchResults.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCaseCommonAttributeSearchResults.java @@ -21,8 +21,13 @@ package org.sleuthkit.autopsy.commonfilesearch; import java.util.Arrays; import java.util.Map; +import java.util.logging.Level; +import org.sleuthkit.autopsy.casemodule.Case; +import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; import org.sleuthkit.autopsy.datamodel.DisplayableItemNode; import org.sleuthkit.datamodel.AbstractFile; +import org.sleuthkit.datamodel.SleuthkitCase; +import org.sleuthkit.datamodel.TskCoreException; /** * Encapsulates data required to instantiate a FileInstanceNode. @@ -40,13 +45,26 @@ final public class IntraCaseCommonAttributeSearchResults extends CommonAttribute super(abstractFileReference, cachedFiles, dataSource, caseName); } - @Override - public DisplayableItemNode generateNode() { - return new IntraCaseCommonAttributeInstanceNode(this.lookupOrCreateAbstractFile(), this.getCaseName(), this.getDataSource()); - } - @Override public DisplayableItemNode[] generateNodes() { return Arrays.asList(new IntraCaseCommonAttributeInstanceNode(this.lookupOrCreateAbstractFile(), this.getCaseName(), this.getDataSource())).toArray(new DisplayableItemNode[1]); } + + protected AbstractFile loadFileFromSleuthkitCase(Long objectId) { + + Case currentCase; + try { + currentCase = Case.getCurrentCaseThrows(); + + SleuthkitCase tskDb = currentCase.getSleuthkitCase(); + + AbstractFile abstractFile = tskDb.findAllFilesWhere(String.format("obj_id in (%s)", objectId)).get(0); + + return abstractFile; + + } catch (TskCoreException | NoCurrentCaseException ex) { + LOGGER.log(Level.SEVERE, String.format("Unable to find AbstractFile for record with obj_id: %s. Node not created.", new Object[]{objectId}), ex); + return null; + } + } } From 8f59f705be228524603fc186b838a6c556b0cc55 Mon Sep 17 00:00:00 2001 From: Andrew Ziehl Date: Tue, 17 Jul 2018 14:51:31 -0700 Subject: [PATCH 138/287] restore logic to return intracase node if match is in the current case. --- .../CommonAttributeInstanceNodeGenerator.java | 18 ++------ ...InterCaseCommonAttributeSearchResults.java | 42 +++++++++++++------ .../InterCaseCommonAttributeSearcher.java | 27 ++++++------ ...IntraCaseCommonAttributeSearchResults.java | 10 +++-- 4 files changed, 53 insertions(+), 44 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeInstanceNodeGenerator.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeInstanceNodeGenerator.java index 008bb37dcc..2c50ab5714 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeInstanceNodeGenerator.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeInstanceNodeGenerator.java @@ -19,16 +19,9 @@ */ package org.sleuthkit.autopsy.commonfilesearch; -import java.util.Iterator; import java.util.Map; -import java.util.logging.Level; -import org.sleuthkit.autopsy.casemodule.Case; -import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; -import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.datamodel.DisplayableItemNode; import org.sleuthkit.datamodel.AbstractFile; -import org.sleuthkit.datamodel.SleuthkitCase; -import org.sleuthkit.datamodel.TskCoreException; /** * Defines types which can be used to get some sort of File Instance node (a @@ -36,22 +29,21 @@ import org.sleuthkit.datamodel.TskCoreException; */ public abstract class CommonAttributeInstanceNodeGenerator { - private static final Logger LOGGER = Logger.getLogger(CommonAttributeInstanceNodeGenerator.class.getName()); protected Long abstractFileObjectId; - protected static Map cachedFiles; + protected Map cachedFiles; String caseName; String dataSource; public CommonAttributeInstanceNodeGenerator(Long abstractFileReference, Map cachedFiles, String dataSource, String caseName) { this.abstractFileObjectId = abstractFileReference; - CommonAttributeInstanceNodeGenerator.cachedFiles = cachedFiles; + this.cachedFiles = cachedFiles; this.caseName = caseName; this.dataSource = dataSource; } public CommonAttributeInstanceNodeGenerator(Map cachedFiles) { this.abstractFileObjectId = -1L; - CommonAttributeInstanceNodeGenerator.cachedFiles = cachedFiles; + this.cachedFiles = cachedFiles; this.caseName = ""; this.dataSource = ""; } @@ -112,8 +104,4 @@ public abstract class CommonAttributeInstanceNodeGenerator { return this.abstractFileObjectId; } - public static CommonAttributeInstanceNodeGenerator createInstance(Iterator identicalFileNodeGeneratorIterator, Integer instanceId) throws Exception { - - return new InterCaseCommonAttributeSearchResults(instanceId, cachedFiles); - } } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearchResults.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearchResults.java index 3302e15f16..ebc2e8b218 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearchResults.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearchResults.java @@ -19,6 +19,8 @@ */ package org.sleuthkit.autopsy.commonfilesearch; +import java.io.File; +import java.nio.file.Paths; import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -37,30 +39,29 @@ import org.sleuthkit.datamodel.TskCoreException; * Generates a DisplayableItmeNode using a CentralRepositoryFile. */ final public class InterCaseCommonAttributeSearchResults extends CommonAttributeInstanceNodeGenerator { - + private static final Logger LOGGER = Logger.getLogger(InterCaseCommonAttributeSearchResults.class.getName()); private final Integer crFileId; private CorrelationAttributeInstance currentAttributeInst; private String currentFullPath; - + InterCaseCommonAttributeSearchResults(Integer attrInstId, Map cachedFiles) { super(cachedFiles); this.crFileId = attrInstId; } - - + @Override protected AbstractFile loadFileFromSleuthkitCase() { Case currentCase; this.currentFullPath = this.currentAttributeInst.getFilePath(); - + try { currentCase = Case.getCurrentCaseThrows(); SleuthkitCase tskDb = currentCase.getSleuthkitCase(); - String[] splitPath = this.currentFullPath.split("/"); - String fileName = splitPath[splitPath.length -1]; + File fileFromPath = new File(this.currentFullPath); + String fileName = fileFromPath.getName(); AbstractFile abstractFile = tskDb.findAllFilesWhere(String.format("lower(name) = '%s'", fileName)).get(0); // TODO workaround where we don't need AbstractFile? return abstractFile; @@ -70,19 +71,36 @@ final public class InterCaseCommonAttributeSearchResults extends CommonAttribute return null; } } - + @Override public DisplayableItemNode[] generateNodes() { InterCaseSearchResultsProcessor eamDbAttrInst = new InterCaseSearchResultsProcessor(); CorrelationAttribute corrAttr = eamDbAttrInst.findSingleCorrelationAttribute(crFileId); List attrInstNodeList = new ArrayList<>(0); + String currCaseDbName = Case.getCurrentCase().getDisplayName(); for (CorrelationAttributeInstance attrInst : corrAttr.getInstances()) { - currentAttributeInst = attrInst; - - DisplayableItemNode generatedInstNode = new InterCaseCommonAttributeInstanceNode(currentAttributeInst, this.lookupOrCreateAbstractFile()); - if (generatedInstNode != null) { + try { + currentAttributeInst = attrInst; + AbstractFile currentAbstractFile = this.lookupOrCreateAbstractFile(); + DisplayableItemNode generatedInstNode; + + String currAttributeDataSource = currentAttributeInst.getCorrelationDataSource().getName(); + String currAbstractFileDataSource = currentAbstractFile.getDataSource().getName(); + + if (currentAttributeInst.getCorrelationCase().getDisplayName().equals(currCaseDbName) + && currentAttributeInst.getFilePath().toLowerCase().equals(Paths.get(currentAbstractFile.getParentPath(), currentAbstractFile.getName()).toString()) + && currAttributeDataSource.equals(currAbstractFileDataSource)) { + generatedInstNode = new IntraCaseCommonAttributeInstanceNode(currentAbstractFile, currCaseDbName, currAbstractFileDataSource); + } else { + generatedInstNode = new InterCaseCommonAttributeInstanceNode(currentAttributeInst, currentAbstractFile); + } + attrInstNodeList.add(generatedInstNode); + + } catch (TskCoreException ex) { + LOGGER.log(Level.SEVERE, String.format("Unable to get DataSource for record with filePath: %s. Node not created.", new Object[]{attrInst.getFilePath()}), ex); + } } return attrInstNodeList.toArray(new DisplayableItemNode[attrInstNodeList.size()]); diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearcher.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearcher.java index f71b1a7db6..ffa6027eff 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearcher.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearcher.java @@ -20,7 +20,6 @@ package org.sleuthkit.autopsy.commonfilesearch; import java.util.HashMap; -import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.logging.Level; @@ -28,15 +27,17 @@ import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationCase; import org.sleuthkit.autopsy.centralrepository.datamodel.EamDb; import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException; import static org.sleuthkit.autopsy.timeline.datamodel.eventtype.ArtifactEventType.LOGGER; +import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.HashUtility; /** * Provides logic for selecting common files from all data sources and all cases * in the Central Repo. */ -public abstract class InterCaseCommonAttributeSearcher extends AbstractCommonAttributeSearcher { +abstract class InterCaseCommonAttributeSearcher extends AbstractCommonAttributeSearcher { EamDb dbManager; + /** * Implements the algorithm for getting common files across all data sources * and all cases. Can filter on mime types conjoined by logical AND. @@ -55,7 +56,8 @@ public abstract class InterCaseCommonAttributeSearcher extends AbstractCommonAtt /** * @param artifactInstances all 'common files' in central repo - * @param commonFiles matches must ultimately have appeared in this collection + * @param commonFiles matches must ultimately have appeared in this + * collection * @return collated map of instance counts to lists of matches */ Map> gatherIntercaseResults(Map commonFiles, Map commonFileCases) { @@ -68,37 +70,36 @@ public abstract class InterCaseCommonAttributeSearcher extends AbstractCommonAtt if (md5 == null || HashUtility.isNoDataMd5(md5)) { continue; } + Map fileCache = new HashMap<>(); try { int caseId = commonFileCases.get(commonAttrId); CorrelationCase autopsyCrCase = dbManager.getCaseById(caseId); - final String correlationCaseDisplayName = autopsyCrCase.getDisplayName(); + final String correlationCaseDisplayName = autopsyCrCase.getDisplayName(); // we don't *have* all the information for the rows in the CR, // so we need to consult the present case via the SleuthkitCase object // Later, when the FileInstanceNodde is built. Therefore, build node generators for now. - if(interCaseCommonFiles.containsKey(md5)) { + if (interCaseCommonFiles.containsKey(md5)) { //Add to intercase metaData final CommonAttributeValue md5Metadata = interCaseCommonFiles.get(md5); - final Iterator identitcalFileInstanceMetadata = interCaseCommonFiles.get(md5).getMetadata().iterator(); - CommonAttributeInstanceNodeGenerator nodeGenerator = CommonAttributeInstanceNodeGenerator.createInstance(identitcalFileInstanceMetadata, commonAttrId); + CommonAttributeInstanceNodeGenerator nodeGenerator = new InterCaseCommonAttributeSearchResults(commonAttrId, fileCache); md5Metadata.addFileInstanceMetadata(nodeGenerator, correlationCaseDisplayName); } else { CommonAttributeValue md5Metadata = new CommonAttributeValue(md5); - final Iterator identitcalFileInstanceMetadata = md5Metadata.getMetadata().iterator(); - CommonAttributeInstanceNodeGenerator nodeGenerator = CommonAttributeInstanceNodeGenerator.createInstance(identitcalFileInstanceMetadata, commonAttrId); + CommonAttributeInstanceNodeGenerator nodeGenerator = new InterCaseCommonAttributeSearchResults(commonAttrId, fileCache); md5Metadata.addFileInstanceMetadata(nodeGenerator, correlationCaseDisplayName); interCaseCommonFiles.put(md5, md5Metadata); } } catch (Exception ex) { LOGGER.log(Level.WARNING, "Error getting artifact instances from database.", ex); // NON-NLS } - + } - - Map> instanceCollatedCommonFiles = collateMatchesByNumberOfInstances(interCaseCommonFiles); - + + Map> instanceCollatedCommonFiles = collateMatchesByNumberOfInstances(interCaseCommonFiles); + return instanceCollatedCommonFiles; } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCaseCommonAttributeSearchResults.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCaseCommonAttributeSearchResults.java index 3cb989e58e..d4a47d543b 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCaseCommonAttributeSearchResults.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCaseCommonAttributeSearchResults.java @@ -24,6 +24,7 @@ import java.util.Map; import java.util.logging.Level; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; +import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.datamodel.DisplayableItemNode; import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.SleuthkitCase; @@ -33,7 +34,8 @@ import org.sleuthkit.datamodel.TskCoreException; * Encapsulates data required to instantiate a FileInstanceNode. */ final public class IntraCaseCommonAttributeSearchResults extends CommonAttributeInstanceNodeGenerator { - + private static final Logger LOGGER = Logger.getLogger(IntraCaseCommonAttributeSearchResults.class.getName()); + /** * Create meta data required to find an abstract file and build a * FileInstanceNode. @@ -50,7 +52,7 @@ final public class IntraCaseCommonAttributeSearchResults extends CommonAttribute return Arrays.asList(new IntraCaseCommonAttributeInstanceNode(this.lookupOrCreateAbstractFile(), this.getCaseName(), this.getDataSource())).toArray(new DisplayableItemNode[1]); } - protected AbstractFile loadFileFromSleuthkitCase(Long objectId) { + protected AbstractFile loadFileFromSleuthkitCase() { Case currentCase; try { @@ -58,12 +60,12 @@ final public class IntraCaseCommonAttributeSearchResults extends CommonAttribute SleuthkitCase tskDb = currentCase.getSleuthkitCase(); - AbstractFile abstractFile = tskDb.findAllFilesWhere(String.format("obj_id in (%s)", objectId)).get(0); + AbstractFile abstractFile = tskDb.findAllFilesWhere(String.format("obj_id in (%s)", this.abstractFileObjectId)).get(0); return abstractFile; } catch (TskCoreException | NoCurrentCaseException ex) { - LOGGER.log(Level.SEVERE, String.format("Unable to find AbstractFile for record with obj_id: %s. Node not created.", new Object[]{objectId}), ex); + LOGGER.log(Level.SEVERE, String.format("Unable to find AbstractFile for record with obj_id: %s. Node not created.", new Object[]{this.abstractFileObjectId}), ex); return null; } } From 57ab0fbd893c98320b647eb994e876cb9ab5862c Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Tue, 17 Jul 2018 17:54:27 -0600 Subject: [PATCH 139/287] disable double click on leaf nodes --- .../autopsy/directorytree/DataResultFilterNode.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Core/src/org/sleuthkit/autopsy/directorytree/DataResultFilterNode.java b/Core/src/org/sleuthkit/autopsy/directorytree/DataResultFilterNode.java index 855cdbe41b..32598d4cfd 100644 --- a/Core/src/org/sleuthkit/autopsy/directorytree/DataResultFilterNode.java +++ b/Core/src/org/sleuthkit/autopsy/directorytree/DataResultFilterNode.java @@ -56,6 +56,7 @@ import org.sleuthkit.autopsy.datamodel.FileTypeExtensions; import org.sleuthkit.autopsy.datamodel.FileTypes.FileTypesNode; import org.sleuthkit.autopsy.commonfilesearch.InstanceCountNode; import org.sleuthkit.autopsy.commonfilesearch.CommonAttributeValueNode; +import org.sleuthkit.autopsy.commonfilesearch.InterCaseCommonAttributeInstanceNode; import org.sleuthkit.autopsy.datamodel.LayoutFileNode; import org.sleuthkit.autopsy.datamodel.LocalFileNode; import org.sleuthkit.autopsy.datamodel.LocalDirectoryNode; @@ -538,6 +539,11 @@ public class DataResultFilterNode extends FilterNode { return null; } + @Override + public AbstractAction visit(InterCaseCommonAttributeInstanceNode iccan){ + return null; + } + @Override public AbstractAction visit(BlackboardArtifactNode ban) { BlackboardArtifact artifact = ban.getArtifact(); From d4abf71f261b49d9540da67b4feed161262dbd00 Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Wed, 18 Jul 2018 09:15:26 -0600 Subject: [PATCH 140/287] fixes for identifying abstract files that we have access to even tho we (mostly) only query the eamdb for this one --- .../CommonAttributeInstanceNodeGenerator.java | 1 - .../InterCaseCommonAttributeSearchResults.java | 12 +++++++++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeInstanceNodeGenerator.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeInstanceNodeGenerator.java index 2c50ab5714..b828f8bd91 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeInstanceNodeGenerator.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeInstanceNodeGenerator.java @@ -103,5 +103,4 @@ public abstract class CommonAttributeInstanceNodeGenerator { public Long getIdenticalFileSleuthkitCaseObjectID() { return this.abstractFileObjectId; } - } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearchResults.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearchResults.java index ebc2e8b218..fc6210180c 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearchResults.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearchResults.java @@ -88,9 +88,15 @@ final public class InterCaseCommonAttributeSearchResults extends CommonAttribute String currAttributeDataSource = currentAttributeInst.getCorrelationDataSource().getName(); String currAbstractFileDataSource = currentAbstractFile.getDataSource().getName(); - if (currentAttributeInst.getCorrelationCase().getDisplayName().equals(currCaseDbName) - && currentAttributeInst.getFilePath().toLowerCase().equals(Paths.get(currentAbstractFile.getParentPath(), currentAbstractFile.getName()).toString()) - && currAttributeDataSource.equals(currAbstractFileDataSource)) { + final String displayName = currentAttributeInst.getCorrelationCase().getDisplayName(); + final String path = currentAttributeInst.getFilePath(); + final String representativeFilePath = Paths.get(currentAbstractFile.getParentPath(), currentAbstractFile.getName()).toString().replace("\\", "/"); + + final boolean sameCase = displayName.equalsIgnoreCase(currCaseDbName); + final boolean sameFileName = path.equalsIgnoreCase(representativeFilePath); + final boolean sameDataSource = currAttributeDataSource.equalsIgnoreCase(currAbstractFileDataSource); + + if (sameCase && sameFileName && sameDataSource) { generatedInstNode = new IntraCaseCommonAttributeInstanceNode(currentAbstractFile, currCaseDbName, currAbstractFileDataSource); } else { generatedInstNode = new InterCaseCommonAttributeInstanceNode(currentAttributeInst, currentAbstractFile); From 83f88a40b348dd7687b8e0a53e6d19fe16adec86 Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Wed, 18 Jul 2018 10:26:06 -0600 Subject: [PATCH 141/287] fixes for issues where not all md5 nodes would have the correct number of children --- .../InterCaseCommonAttributeSearchResults.java | 6 ++++-- .../commonfilesearch/InterCaseCommonAttributeSearcher.java | 1 - 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearchResults.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearchResults.java index fc6210180c..ff18132bfe 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearchResults.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearchResults.java @@ -90,7 +90,10 @@ final public class InterCaseCommonAttributeSearchResults extends CommonAttribute final String displayName = currentAttributeInst.getCorrelationCase().getDisplayName(); final String path = currentAttributeInst.getFilePath(); - final String representativeFilePath = Paths.get(currentAbstractFile.getParentPath(), currentAbstractFile.getName()).toString().replace("\\", "/"); + final String currentAbstractFileParentPath = currentAbstractFile.getParentPath(); + final String currentAbstractFileName = currentAbstractFile.getName(); + //final String representativeFilePath = Paths.get(currentAbstractFileParentPath, currentAbstractFileName).toString().replace("\\", "/"); + final String representativeFilePath = (currentAbstractFileParentPath + currentAbstractFileName).replace("\\", "/"); final boolean sameCase = displayName.equalsIgnoreCase(currCaseDbName); final boolean sameFileName = path.equalsIgnoreCase(representativeFilePath); @@ -106,7 +109,6 @@ final public class InterCaseCommonAttributeSearchResults extends CommonAttribute } catch (TskCoreException ex) { LOGGER.log(Level.SEVERE, String.format("Unable to get DataSource for record with filePath: %s. Node not created.", new Object[]{attrInst.getFilePath()}), ex); - } } return attrInstNodeList.toArray(new DisplayableItemNode[attrInstNodeList.size()]); diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearcher.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearcher.java index ffa6027eff..72352797f8 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearcher.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearcher.java @@ -95,7 +95,6 @@ abstract class InterCaseCommonAttributeSearcher extends AbstractCommonAttributeS } catch (Exception ex) { LOGGER.log(Level.WARNING, "Error getting artifact instances from database.", ex); // NON-NLS } - } Map> instanceCollatedCommonFiles = collateMatchesByNumberOfInstances(interCaseCommonFiles); From adae6940650b3a54610128ec0b90c600ed74249c Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Wed, 18 Jul 2018 10:46:04 -0600 Subject: [PATCH 142/287] cleanup / defensive coding --- .../InterCaseCommonAttributeSearchResults.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearchResults.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearchResults.java index ff18132bfe..00b564d6b4 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearchResults.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearchResults.java @@ -20,7 +20,6 @@ package org.sleuthkit.autopsy.commonfilesearch; import java.io.File; -import java.nio.file.Paths; import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -89,10 +88,9 @@ final public class InterCaseCommonAttributeSearchResults extends CommonAttribute String currAbstractFileDataSource = currentAbstractFile.getDataSource().getName(); final String displayName = currentAttributeInst.getCorrelationCase().getDisplayName(); - final String path = currentAttributeInst.getFilePath(); + final String path = currentAttributeInst.getFilePath().replace("\\", "/"); final String currentAbstractFileParentPath = currentAbstractFile.getParentPath(); final String currentAbstractFileName = currentAbstractFile.getName(); - //final String representativeFilePath = Paths.get(currentAbstractFileParentPath, currentAbstractFileName).toString().replace("\\", "/"); final String representativeFilePath = (currentAbstractFileParentPath + currentAbstractFileName).replace("\\", "/"); final boolean sameCase = displayName.equalsIgnoreCase(currCaseDbName); From ce385483ce8abbc82118fbee5821ef099a012e49 Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Wed, 18 Jul 2018 11:05:10 -0600 Subject: [PATCH 143/287] typo (bad merge) in logger instantiation --- .../CommonAttributesSearchResultsViewerTable.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributesSearchResultsViewerTable.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributesSearchResultsViewerTable.java index 1e54ff80fd..55fe8b0956 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributesSearchResultsViewerTable.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributesSearchResultsViewerTable.java @@ -42,7 +42,7 @@ public class CommonAttributesSearchResultsViewerTable extends DataResultViewerTa private static final Map COLUMN_WIDTHS; private static final long serialVersionUID = 1L; - private static final Logger LOGGER = Logger.getLogger(CommonFilesSearchResultsViewerTable.class.getName()); + private static final Logger LOGGER = Logger.getLogger(CommonAttributesSearchResultsViewerTable.class.getName()); private static final int DEFAULT_WIDTH = 100; From 0210e71a76e341967cda64779f7ce7250bb807c4 Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Wed, 18 Jul 2018 19:15:06 -0600 Subject: [PATCH 144/287] comments renames cleanup --- ... AbstractCommonAttributeInstanceNode.java} | 54 ++++++++++++------- .../CommonAttributeValue.java | 14 ++--- .../CommonAttributeValueNode.java | 6 +-- ...InterCaseCommonAttributeSearchResults.java | 2 +- .../InterCaseCommonAttributeSearcher.java | 4 +- ...IntraCaseCommonAttributeSearchResults.java | 4 +- 6 files changed, 51 insertions(+), 33 deletions(-) rename Core/src/org/sleuthkit/autopsy/commonfilesearch/{CommonAttributeInstanceNodeGenerator.java => AbstractCommonAttributeInstanceNode.java} (55%) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeInstanceNodeGenerator.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeInstanceNode.java similarity index 55% rename from Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeInstanceNodeGenerator.java rename to Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeInstanceNode.java index b828f8bd91..914bed2aca 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeInstanceNodeGenerator.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeInstanceNode.java @@ -24,25 +24,43 @@ import org.sleuthkit.autopsy.datamodel.DisplayableItemNode; import org.sleuthkit.datamodel.AbstractFile; /** - * Defines types which can be used to get some sort of File Instance node (a - * child of the MD5Node) for use in the common files tree table. + * Defines leaf-type nodes used in the Common Files Search results tree. + * Leaf nodes, may describe common attributes which exist in the current case DB + * or in the Central Repo. When a reference to the AbstractFile is lacking + * (such as in the case that a common attribute is found in the Central Repo) + * not all features of the Content Viewer, and context menu can be supported. + * Thus, multiple types of leaf nodes are required to represent Common Attribute + * Instance nodes. */ -public abstract class CommonAttributeInstanceNodeGenerator { +public abstract class AbstractCommonAttributeInstanceNode { protected Long abstractFileObjectId; protected Map cachedFiles; String caseName; String dataSource; - public CommonAttributeInstanceNodeGenerator(Long abstractFileReference, Map cachedFiles, String dataSource, String caseName) { + /** + * Create a leaf node for attributes found in files in the current case db. + * + * @param abstractFileReference file from which the common attribute was found + * @param cachedFiles storage for abstract files which have been used already so we can avoid extra roundtrips to the case db + * @param dataSource datasource where this attribute appears + * @param caseName case where this attribute appears + */ + public AbstractCommonAttributeInstanceNode(Long abstractFileReference, Map cachedFiles, String dataSource, String caseName) { this.abstractFileObjectId = abstractFileReference; this.cachedFiles = cachedFiles; this.caseName = caseName; this.dataSource = dataSource; } - public CommonAttributeInstanceNodeGenerator(Map cachedFiles) { - this.abstractFileObjectId = -1L; + /** + * Create a leaf node for attributes found in the central repo and not + * available in the current data case. + * + * @param cachedFiles storage for abstract files which have been used already so we can avoid extra roundtrips to the case db + */ + public AbstractCommonAttributeInstanceNode(Map cachedFiles) { this.cachedFiles = cachedFiles; this.caseName = ""; this.dataSource = ""; @@ -50,10 +68,8 @@ public abstract class CommonAttributeInstanceNodeGenerator { /** * Grab a cached instance of the AbstractFile or grab one from the - * SleuthkitCase. Use this in implementations of generateNode. - * - * @param objectId - * @param cachedFiles + * SleuthkitCase. Use this in implementations of generateNodes. + * * @return AbstractFile which is identical to the file instance generated by * implementations of this object */ @@ -68,16 +84,20 @@ public abstract class CommonAttributeInstanceNodeGenerator { } /** + * Implement this in subclasses to find the AbstractFile by whatever means + * necessary. This will be called by this.lookupOrCreateAbstractFile. In + * some cases we may have the object id, in other cases we may need to use + * something else. * - * @return + * @return AbstractFile corresponding to this common attribute */ abstract protected AbstractFile loadFileFromSleuthkitCase(); /** - * Create a list of nodes which are a child of the MD5Node, to be used to display a + * Create a list of leaf nodes, to be used to display a * row in the tree table * - * @return child row node + * @return leaf nodes for tree */ public abstract DisplayableItemNode[] generateNodes(); @@ -86,9 +106,9 @@ public abstract class CommonAttributeInstanceNodeGenerator { } /** - * Get string name of the data source where this instance appears. + * Get string name of the data source where this common attribute appears. * - * @return + * @return data source name */ public String getDataSource() { @@ -99,8 +119,4 @@ public abstract class CommonAttributeInstanceNodeGenerator { */ return this.dataSource; } - - public Long getIdenticalFileSleuthkitCaseObjectID() { - return this.abstractFileObjectId; - } } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeValue.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeValue.java index 169dad10ed..f997c3b111 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeValue.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeValue.java @@ -33,9 +33,9 @@ import java.util.stream.Collectors; final public class CommonAttributeValue { private final String md5; - private final List fileInstances; + private final List fileInstances; - CommonAttributeValue(String md5, List fileInstances) { + CommonAttributeValue(String md5, List fileInstances) { this.md5 = md5; this.fileInstances = fileInstances; } @@ -50,13 +50,13 @@ final public class CommonAttributeValue { } public String getCases() { - final String cases = this.fileInstances.stream().map(CommonAttributeInstanceNodeGenerator::getCaseName).collect(Collectors.joining(", ")); + final String cases = this.fileInstances.stream().map(AbstractCommonAttributeInstanceNode::getCaseName).collect(Collectors.joining(", ")); return cases; } public String getDataSources() { Set sources = new HashSet<>(); - for (CommonAttributeInstanceNodeGenerator data : this.fileInstances) { + for (AbstractCommonAttributeInstanceNode data : this.fileInstances) { sources.add(data.getDataSource()); } @@ -64,15 +64,15 @@ final public class CommonAttributeValue { return dataSources; } - void addFileInstanceMetadata(CommonAttributeInstanceNodeGenerator metadata) { + void addFileInstanceMetadata(AbstractCommonAttributeInstanceNode metadata) { this.fileInstances.add(metadata); } - void addFileInstanceMetadata(CommonAttributeInstanceNodeGenerator metadata, String caseName) { + void addFileInstanceMetadata(AbstractCommonAttributeInstanceNode metadata, String caseName) { this.fileInstances.add(metadata); } - public Collection getMetadata() { + public Collection getMetadata() { return Collections.unmodifiableCollection(this.fileInstances); } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeValueNode.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeValueNode.java index edfa436a04..4c3a2e9fc4 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeValueNode.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeValueNode.java @@ -132,7 +132,7 @@ public class CommonAttributeValueNode extends DisplayableItemNode { * Child generator for SleuthkitCaseFileInstanceNode of * CommonAttributeValueNode. */ - static class FileInstanceNodeFactory extends ChildFactory { + static class FileInstanceNodeFactory extends ChildFactory { //private final Map cachedFiles; @@ -144,12 +144,12 @@ public class CommonAttributeValueNode extends DisplayableItemNode { } @Override - protected Node[] createNodesForKey(CommonAttributeInstanceNodeGenerator file) { + protected Node[] createNodesForKey(AbstractCommonAttributeInstanceNode file) { return file.generateNodes(); } @Override - protected boolean createKeys(List list) { + protected boolean createKeys(List list) { list.addAll(this.descendants.getMetadata()); return true; } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearchResults.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearchResults.java index 00b564d6b4..334d75abc0 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearchResults.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearchResults.java @@ -37,7 +37,7 @@ import org.sleuthkit.datamodel.TskCoreException; /** * Generates a DisplayableItmeNode using a CentralRepositoryFile. */ -final public class InterCaseCommonAttributeSearchResults extends CommonAttributeInstanceNodeGenerator { +final public class InterCaseCommonAttributeSearchResults extends AbstractCommonAttributeInstanceNode { private static final Logger LOGGER = Logger.getLogger(InterCaseCommonAttributeSearchResults.class.getName()); private final Integer crFileId; diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearcher.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearcher.java index 72352797f8..7d926ff92d 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearcher.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearcher.java @@ -83,12 +83,12 @@ abstract class InterCaseCommonAttributeSearcher extends AbstractCommonAttributeS if (interCaseCommonFiles.containsKey(md5)) { //Add to intercase metaData final CommonAttributeValue md5Metadata = interCaseCommonFiles.get(md5); - CommonAttributeInstanceNodeGenerator nodeGenerator = new InterCaseCommonAttributeSearchResults(commonAttrId, fileCache); + AbstractCommonAttributeInstanceNode nodeGenerator = new InterCaseCommonAttributeSearchResults(commonAttrId, fileCache); md5Metadata.addFileInstanceMetadata(nodeGenerator, correlationCaseDisplayName); } else { CommonAttributeValue md5Metadata = new CommonAttributeValue(md5); - CommonAttributeInstanceNodeGenerator nodeGenerator = new InterCaseCommonAttributeSearchResults(commonAttrId, fileCache); + AbstractCommonAttributeInstanceNode nodeGenerator = new InterCaseCommonAttributeSearchResults(commonAttrId, fileCache); md5Metadata.addFileInstanceMetadata(nodeGenerator, correlationCaseDisplayName); interCaseCommonFiles.put(md5, md5Metadata); } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCaseCommonAttributeSearchResults.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCaseCommonAttributeSearchResults.java index d4a47d543b..43df490865 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCaseCommonAttributeSearchResults.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCaseCommonAttributeSearchResults.java @@ -33,9 +33,11 @@ import org.sleuthkit.datamodel.TskCoreException; /** * Encapsulates data required to instantiate a FileInstanceNode. */ -final public class IntraCaseCommonAttributeSearchResults extends CommonAttributeInstanceNodeGenerator { +final public class IntraCaseCommonAttributeSearchResults extends AbstractCommonAttributeInstanceNode { + private static final Logger LOGGER = Logger.getLogger(IntraCaseCommonAttributeSearchResults.class.getName()); + /** * Create meta data required to find an abstract file and build a * FileInstanceNode. From f87e8de83097ccfbb0caccd35268e1a9b56fb927 Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Wed, 18 Jul 2018 20:26:53 -0600 Subject: [PATCH 145/287] cleanup, comments, access modifiers --- .../AbstractCommonAttributeInstanceNode.java | 56 +++++++++++++------ .../InterCaseCommonAttributeInstanceNode.java | 1 - ...InterCaseCommonAttributeSearchResults.java | 4 +- ...IntraCaseCommonAttributeSearchResults.java | 7 ++- ...stedWithHashAndFileTypeInterCaseTests.java | 4 -- .../commonfilessearch/InterCaseUtils.java | 2 - .../NoCentralRepoEnabledInterCaseTests.java | 2 - 7 files changed, 45 insertions(+), 31 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeInstanceNode.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeInstanceNode.java index 914bed2aca..73c7017bbf 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeInstanceNode.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeInstanceNode.java @@ -19,6 +19,7 @@ */ package org.sleuthkit.autopsy.commonfilesearch; +import java.util.Collections; import java.util.Map; import org.sleuthkit.autopsy.datamodel.DisplayableItemNode; import org.sleuthkit.datamodel.AbstractFile; @@ -32,12 +33,12 @@ import org.sleuthkit.datamodel.AbstractFile; * Thus, multiple types of leaf nodes are required to represent Common Attribute * Instance nodes. */ -public abstract class AbstractCommonAttributeInstanceNode { +abstract class AbstractCommonAttributeInstanceNode { - protected Long abstractFileObjectId; - protected Map cachedFiles; - String caseName; - String dataSource; + private Long abstractFileObjectId; + private final Map cachedFiles; + private final String caseName; + private final String dataSource; /** * Create a leaf node for attributes found in files in the current case db. @@ -47,7 +48,7 @@ public abstract class AbstractCommonAttributeInstanceNode { * @param dataSource datasource where this attribute appears * @param caseName case where this attribute appears */ - public AbstractCommonAttributeInstanceNode(Long abstractFileReference, Map cachedFiles, String dataSource, String caseName) { + AbstractCommonAttributeInstanceNode(Long abstractFileReference, Map cachedFiles, String dataSource, String caseName) { this.abstractFileObjectId = abstractFileReference; this.cachedFiles = cachedFiles; this.caseName = caseName; @@ -60,7 +61,7 @@ public abstract class AbstractCommonAttributeInstanceNode { * * @param cachedFiles storage for abstract files which have been used already so we can avoid extra roundtrips to the case db */ - public AbstractCommonAttributeInstanceNode(Map cachedFiles) { + AbstractCommonAttributeInstanceNode(Map cachedFiles) { this.cachedFiles = cachedFiles; this.caseName = ""; this.dataSource = ""; @@ -73,25 +74,25 @@ public abstract class AbstractCommonAttributeInstanceNode { * @return AbstractFile which is identical to the file instance generated by * implementations of this object */ - protected AbstractFile lookupOrCreateAbstractFile() { - if (cachedFiles.containsKey(this.abstractFileObjectId)) { - return cachedFiles.get(this.abstractFileObjectId); + AbstractFile lookupOrLoadAbstractFile() { + if (getCachedFiles().containsKey(this.getAbstractFileObjectId())) { + return getCachedFiles().get(this.getAbstractFileObjectId()); } else { AbstractFile file = this.loadFileFromSleuthkitCase(); - cachedFiles.put(this.abstractFileObjectId, file); + getCachedFiles().put(this.getAbstractFileObjectId(), file); return file; } } /** * Implement this in subclasses to find the AbstractFile by whatever means - * necessary. This will be called by this.lookupOrCreateAbstractFile. In + * necessary. This will be called by this.lookupOrLoadAbstractFile. In * some cases we may have the object id, in other cases we may need to use - * something else. + * the file name. * * @return AbstractFile corresponding to this common attribute */ - abstract protected AbstractFile loadFileFromSleuthkitCase(); + abstract AbstractFile loadFileFromSleuthkitCase(); /** * Create a list of leaf nodes, to be used to display a @@ -99,9 +100,13 @@ public abstract class AbstractCommonAttributeInstanceNode { * * @return leaf nodes for tree */ - public abstract DisplayableItemNode[] generateNodes(); + abstract DisplayableItemNode[] generateNodes(); - public String getCaseName() { + /** + * The name of the case where this common attribute is found. + * @return case name + */ + String getCaseName() { return this.caseName; } @@ -110,7 +115,7 @@ public abstract class AbstractCommonAttributeInstanceNode { * * @return data source name */ - public String getDataSource() { + String getDataSource() { /** * Even though we could get this from the CR record or the AbstractFile, @@ -119,4 +124,21 @@ public abstract class AbstractCommonAttributeInstanceNode { */ return this.dataSource; } + + /** + * @return the abstractFileObjectId + */ + Long getAbstractFileObjectId() { + return abstractFileObjectId; + } + + /** + * Get the map of AbstractFile which we use to avoid loading the same + * file from the SleuthkitCase more than necessary. + * + * @return the cachedFiles + */ + Map getCachedFiles() { + return Collections.unmodifiableMap(cachedFiles); + } } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeInstanceNode.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeInstanceNode.java index d998093a74..79c2e2d08b 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeInstanceNode.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeInstanceNode.java @@ -70,7 +70,6 @@ public class InterCaseCommonAttributeInstanceNode extends DisplayableItemNode { List actionsList = new ArrayList<>(); actionsList.addAll(Arrays.asList(super.getActions(true))); - //TODO probably can support more than just this return actionsList.toArray(new Action[actionsList.size()]); } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearchResults.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearchResults.java index 334d75abc0..f9158c8676 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearchResults.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearchResults.java @@ -61,7 +61,7 @@ final public class InterCaseCommonAttributeSearchResults extends AbstractCommonA SleuthkitCase tskDb = currentCase.getSleuthkitCase(); File fileFromPath = new File(this.currentFullPath); String fileName = fileFromPath.getName(); - AbstractFile abstractFile = tskDb.findAllFilesWhere(String.format("lower(name) = '%s'", fileName)).get(0); // TODO workaround where we don't need AbstractFile? + AbstractFile abstractFile = tskDb.findAllFilesWhere(String.format("lower(name) = '%s'", fileName)).get(0); return abstractFile; @@ -81,7 +81,7 @@ final public class InterCaseCommonAttributeSearchResults extends AbstractCommonA for (CorrelationAttributeInstance attrInst : corrAttr.getInstances()) { try { currentAttributeInst = attrInst; - AbstractFile currentAbstractFile = this.lookupOrCreateAbstractFile(); + AbstractFile currentAbstractFile = this.lookupOrLoadAbstractFile(); DisplayableItemNode generatedInstNode; String currAttributeDataSource = currentAttributeInst.getCorrelationDataSource().getName(); diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCaseCommonAttributeSearchResults.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCaseCommonAttributeSearchResults.java index 43df490865..6cd39355ca 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCaseCommonAttributeSearchResults.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCaseCommonAttributeSearchResults.java @@ -51,7 +51,8 @@ final public class IntraCaseCommonAttributeSearchResults extends AbstractCommonA @Override public DisplayableItemNode[] generateNodes() { - return Arrays.asList(new IntraCaseCommonAttributeInstanceNode(this.lookupOrCreateAbstractFile(), this.getCaseName(), this.getDataSource())).toArray(new DisplayableItemNode[1]); + final IntraCaseCommonAttributeInstanceNode intraCaseCommonAttributeInstanceNode = new IntraCaseCommonAttributeInstanceNode(this.lookupOrLoadAbstractFile(), this.getCaseName(), this.getDataSource()); + return Arrays.asList(intraCaseCommonAttributeInstanceNode).toArray(new DisplayableItemNode[1]); } protected AbstractFile loadFileFromSleuthkitCase() { @@ -62,12 +63,12 @@ final public class IntraCaseCommonAttributeSearchResults extends AbstractCommonA SleuthkitCase tskDb = currentCase.getSleuthkitCase(); - AbstractFile abstractFile = tskDb.findAllFilesWhere(String.format("obj_id in (%s)", this.abstractFileObjectId)).get(0); + AbstractFile abstractFile = tskDb.findAllFilesWhere(String.format("obj_id in (%s)", this.getAbstractFileObjectId())).get(0); return abstractFile; } catch (TskCoreException | NoCurrentCaseException ex) { - LOGGER.log(Level.SEVERE, String.format("Unable to find AbstractFile for record with obj_id: %s. Node not created.", new Object[]{this.abstractFileObjectId}), ex); + LOGGER.log(Level.SEVERE, String.format("Unable to find AbstractFile for record with obj_id: %s. Node not created.", new Object[]{this.getAbstractFileObjectId()}), ex); return null; } } diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileTypeInterCaseTests.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileTypeInterCaseTests.java index 5e3dadb4df..c16347c855 100644 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileTypeInterCaseTests.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileTypeInterCaseTests.java @@ -19,7 +19,6 @@ */ package org.sleuthkit.autopsy.commonfilessearch; -import java.sql.SQLException; import java.util.Map; import junit.framework.Test; import org.netbeans.junit.NbModuleSuite; @@ -27,12 +26,9 @@ import org.netbeans.junit.NbTestCase; import org.openide.util.Exceptions; import org.python.icu.impl.Assert; import org.sleuthkit.autopsy.casemodule.Case; -import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; -import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException; import org.sleuthkit.autopsy.commonfilesearch.AllInterCaseCommonAttributeSearcher; import org.sleuthkit.autopsy.commonfilesearch.CommonAttributeSearchResults; import org.sleuthkit.autopsy.commonfilesearch.IntraCaseCommonAttributeSearcher; -import org.sleuthkit.datamodel.TskCoreException; /** * If I use the search all cases option: One node for Hash A (1_1_A.jpg, diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/InterCaseUtils.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/InterCaseUtils.java index 11fbe5f543..600cf90eea 100644 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/InterCaseUtils.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/InterCaseUtils.java @@ -29,7 +29,6 @@ import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Map.Entry; import org.apache.commons.io.FileUtils; import org.netbeans.junit.NbTestCase; import org.openide.util.Exceptions; @@ -55,7 +54,6 @@ import org.sleuthkit.autopsy.commonfilesearch.CommonAttributeSearchResults; import org.sleuthkit.autopsy.commonfilesearch.DataSourceLoader; import org.sleuthkit.autopsy.commonfilesearch.IntraCaseCommonAttributeSearchResults; import org.sleuthkit.autopsy.commonfilesearch.CommonAttributeValue; -import org.sleuthkit.datamodel.AbstractFile; /** * Utilities for testing intercase correlation feature. diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/NoCentralRepoEnabledInterCaseTests.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/NoCentralRepoEnabledInterCaseTests.java index e19252a13d..048bd5a81e 100644 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/NoCentralRepoEnabledInterCaseTests.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/NoCentralRepoEnabledInterCaseTests.java @@ -19,7 +19,6 @@ */ package org.sleuthkit.autopsy.commonfilessearch; -import java.io.IOException; import java.util.Map; import junit.framework.Test; import org.netbeans.junit.NbModuleSuite; @@ -42,7 +41,6 @@ import org.sleuthkit.autopsy.commonfilesearch.IntraCaseCommonAttributeSearcher; public class NoCentralRepoEnabledInterCaseTests extends NbTestCase { private final InterCaseUtils utils; - private Case currentCase; //TODO do we need this??? public static Test suite() { NbModuleSuite.Configuration conf = NbModuleSuite.createConfiguration(NoCentralRepoEnabledInterCaseTests.class). From 7df457b5e31c5518c9f6193e5c28878bdfe5e3de Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Thu, 19 Jul 2018 11:02:33 -0600 Subject: [PATCH 146/287] polish --- .../AbstractCommonAttributeInstanceNode.java | 99 ++++++++++---- .../InterCaseCommonAttributeInstanceNode.java | 2 +- ...InterCaseCommonAttributeSearchResults.java | 39 ++---- .../MatchesInAtLeastTwoSources.java | 128 ++++++++++++++++++ 4 files changed, 217 insertions(+), 51 deletions(-) create mode 100644 Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/MatchesInAtLeastTwoSources.java diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeInstanceNode.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeInstanceNode.java index 73c7017bbf..adbf70dfc7 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeInstanceNode.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeInstanceNode.java @@ -21,16 +21,18 @@ package org.sleuthkit.autopsy.commonfilesearch; import java.util.Collections; import java.util.Map; +import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance; import org.sleuthkit.autopsy.datamodel.DisplayableItemNode; import org.sleuthkit.datamodel.AbstractFile; +import org.sleuthkit.datamodel.TskCoreException; /** - * Defines leaf-type nodes used in the Common Files Search results tree. - * Leaf nodes, may describe common attributes which exist in the current case DB - * or in the Central Repo. When a reference to the AbstractFile is lacking - * (such as in the case that a common attribute is found in the Central Repo) - * not all features of the Content Viewer, and context menu can be supported. - * Thus, multiple types of leaf nodes are required to represent Common Attribute + * Defines leaf-type nodes used in the Common Files Search results tree. Leaf + * nodes, may describe common attributes which exist in the current case DB or + * in the Central Repo. When a reference to the AbstractFile is lacking (such as + * in the case that a common attribute is found in the Central Repo) not all + * features of the Content Viewer, and context menu can be supported. Thus, + * multiple types of leaf nodes are required to represent Common Attribute * Instance nodes. */ abstract class AbstractCommonAttributeInstanceNode { @@ -42,9 +44,11 @@ abstract class AbstractCommonAttributeInstanceNode { /** * Create a leaf node for attributes found in files in the current case db. - * - * @param abstractFileReference file from which the common attribute was found - * @param cachedFiles storage for abstract files which have been used already so we can avoid extra roundtrips to the case db + * + * @param abstractFileReference file from which the common attribute was + * found + * @param cachedFiles storage for abstract files which have been used + * already so we can avoid extra roundtrips to the case db * @param dataSource datasource where this attribute appears * @param caseName case where this attribute appears */ @@ -54,12 +58,13 @@ abstract class AbstractCommonAttributeInstanceNode { this.caseName = caseName; this.dataSource = dataSource; } - + /** - * Create a leaf node for attributes found in the central repo and not + * Create a leaf node for attributes found in the central repo and not * available in the current data case. - * - * @param cachedFiles storage for abstract files which have been used already so we can avoid extra roundtrips to the case db + * + * @param cachedFiles storage for abstract files which have been used + * already so we can avoid extra roundtrips to the case db */ AbstractCommonAttributeInstanceNode(Map cachedFiles) { this.cachedFiles = cachedFiles; @@ -70,7 +75,7 @@ abstract class AbstractCommonAttributeInstanceNode { /** * Grab a cached instance of the AbstractFile or grab one from the * SleuthkitCase. Use this in implementations of generateNodes. - * + * * @return AbstractFile which is identical to the file instance generated by * implementations of this object */ @@ -86,17 +91,17 @@ abstract class AbstractCommonAttributeInstanceNode { /** * Implement this in subclasses to find the AbstractFile by whatever means - * necessary. This will be called by this.lookupOrLoadAbstractFile. In - * some cases we may have the object id, in other cases we may need to use - * the file name. - * + * necessary. This will be called by this.lookupOrLoadAbstractFile. In some + * cases we may have the object id, in other cases we may need to use the + * file name. + * * @return AbstractFile corresponding to this common attribute */ abstract AbstractFile loadFileFromSleuthkitCase(); - + /** - * Create a list of leaf nodes, to be used to display a - * row in the tree table + * Create a list of leaf nodes, to be used to display a row in the tree + * table * * @return leaf nodes for tree */ @@ -104,6 +109,7 @@ abstract class AbstractCommonAttributeInstanceNode { /** * The name of the case where this common attribute is found. + * * @return case name */ String getCaseName() { @@ -133,12 +139,57 @@ abstract class AbstractCommonAttributeInstanceNode { } /** - * Get the map of AbstractFile which we use to avoid loading the same - * file from the SleuthkitCase more than necessary. - * + * Get the map of AbstractFile which we use to avoid loading the same file + * from the SleuthkitCase more than necessary. + * * @return the cachedFiles */ Map getCachedFiles() { return Collections.unmodifiableMap(cachedFiles); } + + /** + * Use this to create an AbstractCommonAttributeInstanceNode of the + * appropriate type. In any case, we'll get something which extends + * DisplayableItemNode which can be used to populate the tree. + * + * If the common attribute in question could be derived from an AbstractFile + * in the present SleuthkitCase, we can use an + * IntraCaseCommonAttributeInstanceNode which enables extended functionality + * in the context menu and in the content viewer. + * + * Otherwise, we will get an InterCaseCommonAttributeInstanceNode which + * supports only baseline functionality. + * + * @param attributeInstance common file attribute instance form the central repo + * @param equivalentAbstractFile an AbstractFile which is equivalent to the file in which the attribute instance was found + * @param currentCaseName + * @return the appropriate leaf node for the results tree + * @throws TskCoreException + */ + static DisplayableItemNode createInstance(CorrelationAttributeInstance attributeInstance, AbstractFile equivalentAbstractFile, String currentCaseName) throws TskCoreException { + DisplayableItemNode leafNode; + + final String attributeDataSourceName = attributeInstance.getCorrelationDataSource().getName(); + final String abstractFileDataSourceName = equivalentAbstractFile.getDataSource().getName(); + + final String attributeInstanceCaseName = attributeInstance.getCorrelationCase().getDisplayName(); + + final String attributeInstanceFullPath = attributeInstance.getFilePath().replace("\\", "/"); + + final String currentAbstractFileParentPath = equivalentAbstractFile.getParentPath(); + final String currentAbstractFileName = equivalentAbstractFile.getName(); + final String abstractFileFullPath = (currentAbstractFileParentPath + currentAbstractFileName).replace("\\", "/"); + + final boolean sameCase = attributeInstanceCaseName.equalsIgnoreCase(currentCaseName); + final boolean sameFileName = attributeInstanceFullPath.equalsIgnoreCase(abstractFileFullPath); + final boolean sameDataSource = attributeDataSourceName.equalsIgnoreCase(abstractFileDataSourceName); + + if (sameCase && sameFileName && sameDataSource) { + leafNode = new IntraCaseCommonAttributeInstanceNode(equivalentAbstractFile, currentCaseName, abstractFileDataSourceName); + } else { + leafNode = new InterCaseCommonAttributeInstanceNode(attributeInstance, equivalentAbstractFile); + } + return leafNode; + } } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeInstanceNode.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeInstanceNode.java index 79c2e2d08b..ee9b173d3e 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeInstanceNode.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeInstanceNode.java @@ -50,7 +50,7 @@ public class InterCaseCommonAttributeInstanceNode extends DisplayableItemNode { // and we can use this to support certain actions in the tree table and crFile viewer private final AbstractFile md5Reference; - public InterCaseCommonAttributeInstanceNode(CorrelationAttributeInstance content, AbstractFile md5Reference) { + InterCaseCommonAttributeInstanceNode(CorrelationAttributeInstance content, AbstractFile md5Reference) { super(Children.LEAF, Lookups.fixed(content)); // Using md5Reference enables Other Occurances, but for the current file path this.crFile = content; this.setDisplayName(new File(this.crFile.getFilePath()).getName()); diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearchResults.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearchResults.java index f9158c8676..e2dbfd79b9 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearchResults.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearchResults.java @@ -41,38 +41,42 @@ final public class InterCaseCommonAttributeSearchResults extends AbstractCommonA private static final Logger LOGGER = Logger.getLogger(InterCaseCommonAttributeSearchResults.class.getName()); private final Integer crFileId; - private CorrelationAttributeInstance currentAttributeInst; - private String currentFullPath; + private CorrelationAttributeInstance currentAttributeInstance; InterCaseCommonAttributeSearchResults(Integer attrInstId, Map cachedFiles) { super(cachedFiles); this.crFileId = attrInstId; } + + void setCurrentAttributeInst(CorrelationAttributeInstance attributeInstance) { + this.currentAttributeInstance = attributeInstance; + } @Override - protected AbstractFile loadFileFromSleuthkitCase() { + AbstractFile loadFileFromSleuthkitCase() { Case currentCase; - this.currentFullPath = this.currentAttributeInst.getFilePath(); + String currentFullPath = this.currentAttributeInstance.getFilePath(); try { currentCase = Case.getCurrentCaseThrows(); SleuthkitCase tskDb = currentCase.getSleuthkitCase(); - File fileFromPath = new File(this.currentFullPath); + File fileFromPath = new File(currentFullPath); String fileName = fileFromPath.getName(); AbstractFile abstractFile = tskDb.findAllFilesWhere(String.format("lower(name) = '%s'", fileName)).get(0); return abstractFile; } catch (TskCoreException | NoCurrentCaseException ex) { - LOGGER.log(Level.SEVERE, String.format("Unable to find AbstractFile for record with filePath: %s. Node not created.", new Object[]{this.currentFullPath}), ex); + LOGGER.log(Level.SEVERE, String.format("Unable to find AbstractFile for record with filePath: %s. Node not created.", new Object[]{currentFullPath}), ex); return null; } } @Override public DisplayableItemNode[] generateNodes() { + InterCaseSearchResultsProcessor eamDbAttrInst = new InterCaseSearchResultsProcessor(); CorrelationAttribute corrAttr = eamDbAttrInst.findSingleCorrelationAttribute(crFileId); List attrInstNodeList = new ArrayList<>(0); @@ -80,28 +84,11 @@ final public class InterCaseCommonAttributeSearchResults extends AbstractCommonA for (CorrelationAttributeInstance attrInst : corrAttr.getInstances()) { try { - currentAttributeInst = attrInst; - AbstractFile currentAbstractFile = this.lookupOrLoadAbstractFile(); - DisplayableItemNode generatedInstNode; - - String currAttributeDataSource = currentAttributeInst.getCorrelationDataSource().getName(); - String currAbstractFileDataSource = currentAbstractFile.getDataSource().getName(); + this.setCurrentAttributeInst(attrInst); - final String displayName = currentAttributeInst.getCorrelationCase().getDisplayName(); - final String path = currentAttributeInst.getFilePath().replace("\\", "/"); - final String currentAbstractFileParentPath = currentAbstractFile.getParentPath(); - final String currentAbstractFileName = currentAbstractFile.getName(); - final String representativeFilePath = (currentAbstractFileParentPath + currentAbstractFileName).replace("\\", "/"); + AbstractFile equivalentAbstractFile = this.lookupOrLoadAbstractFile(); - final boolean sameCase = displayName.equalsIgnoreCase(currCaseDbName); - final boolean sameFileName = path.equalsIgnoreCase(representativeFilePath); - final boolean sameDataSource = currAttributeDataSource.equalsIgnoreCase(currAbstractFileDataSource); - - if (sameCase && sameFileName && sameDataSource) { - generatedInstNode = new IntraCaseCommonAttributeInstanceNode(currentAbstractFile, currCaseDbName, currAbstractFileDataSource); - } else { - generatedInstNode = new InterCaseCommonAttributeInstanceNode(currentAttributeInst, currentAbstractFile); - } + DisplayableItemNode generatedInstNode = AbstractCommonAttributeInstanceNode.createInstance(attrInst, equivalentAbstractFile, currCaseDbName); attrInstNodeList.add(generatedInstNode); diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/MatchesInAtLeastTwoSources.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/MatchesInAtLeastTwoSources.java new file mode 100644 index 0000000000..ba178a59f6 --- /dev/null +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/MatchesInAtLeastTwoSources.java @@ -0,0 +1,128 @@ +/* + * + * Autopsy Forensic Browser + * + * Copyright 2018 Basis Technology Corp. + * Contact: carrier sleuthkit 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.commonfilessearch; + +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import junit.framework.Test; +import org.netbeans.junit.NbModuleSuite; +import org.netbeans.junit.NbTestCase; +import org.openide.util.Exceptions; +import org.python.icu.impl.Assert; +import org.sleuthkit.autopsy.casemodule.Case; +import org.sleuthkit.autopsy.casemodule.ImageDSProcessor; +import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; +import org.sleuthkit.autopsy.commonfilesearch.AllDataSourcesCommonFilesAlgorithm; +import org.sleuthkit.autopsy.commonfilesearch.CommonFilesMetadata; +import org.sleuthkit.autopsy.commonfilesearch.CommonFilesMetadataBuilder; +import static org.sleuthkit.autopsy.commonfilessearch.IntraCaseUtils.*; +import org.sleuthkit.autopsy.ingest.IngestJobSettings; +import org.sleuthkit.autopsy.ingest.IngestModuleTemplate; +import org.sleuthkit.autopsy.modules.filetypeid.FileTypeIdModuleFactory; +import org.sleuthkit.autopsy.modules.hashdatabase.HashLookupModuleFactory; +import org.sleuthkit.autopsy.testutils.IngestUtils; +import org.sleuthkit.datamodel.AbstractFile; +import org.sleuthkit.datamodel.TskCoreException; + +/** + * Ensures that matches only are found for files which appear in at least two + * data sources. + * + * The two datasources used here have no common files. One of the data sources + * has two identical files within it. This should not count as a match. + * + * None of the test files should be found in the results of this test. + */ +public class MatchesInAtLeastTwoSources extends NbTestCase { + + public static Test suite() { + NbModuleSuite.Configuration conf = NbModuleSuite.createConfiguration(MatchesInAtLeastTwoSources.class). + clusters(".*"). + enableModules(".*"); + return conf.suite(); + } + + private final IntraCaseUtils utils; + + public MatchesInAtLeastTwoSources(String name) { + super(name); + + this.utils = new IntraCaseUtils(this, "MatchesInAtLeastTwoSources"); + } + + @Override + public void setUp() { + this.utils.createAsCurrentCase(); + + final ImageDSProcessor imageDSProcessor = new ImageDSProcessor(); + + this.utils.addImageOne(imageDSProcessor); + this.utils.addImageFour(imageDSProcessor); + + IngestModuleTemplate hashLookupTemplate = IngestUtils.getIngestModuleTemplate(new HashLookupModuleFactory()); + IngestModuleTemplate mimeTypeLookupTemplate = IngestUtils.getIngestModuleTemplate(new FileTypeIdModuleFactory()); + + ArrayList templates = new ArrayList<>(); + templates.add(hashLookupTemplate); + templates.add(mimeTypeLookupTemplate); + + IngestJobSettings ingestJobSettings = new IngestJobSettings(IngestedWithHashAndFileType.class.getCanonicalName(), IngestJobSettings.IngestType.FILES_ONLY, templates); + + try { + IngestUtils.runIngestJob(Case.getCurrentCaseThrows().getDataSources(), ingestJobSettings); + } catch (NoCurrentCaseException | TskCoreException ex) { + Exceptions.printStackTrace(ex); + Assert.fail(ex); + } + } + + @Override + public void tearDown() { + this.utils.tearDown(); + } + + public void testOne() { + try { + Map dataSources = this.utils.getDataSourceMap(); + + CommonFilesMetadataBuilder allSourcesBuilder = new AllDataSourcesCommonFilesAlgorithm(dataSources, false, false); + CommonFilesMetadata metadata = allSourcesBuilder.findCommonFiles(); + + Map objectIdToDataSource = IntraCaseUtils.mapFileInstancesToDataSources(metadata); + + List files = IntraCaseUtils.getFiles(objectIdToDataSource.keySet()); + + assertTrue(IntraCaseUtils.verifyFileExistanceAndCount(files, dataSources, IMG, SET1, 0)); + assertTrue(IntraCaseUtils.verifyFileExistanceAndCount(files, dataSources, IMG, SET4, 0)); + + assertTrue(IntraCaseUtils.verifyFileExistanceAndCount(files, dataSources, DOC, SET1, 0)); + assertTrue(IntraCaseUtils.verifyFileExistanceAndCount(files, dataSources, DOC, SET4, 0)); + + assertTrue(IntraCaseUtils.verifyFileExistanceAndCount(files, dataSources, EMPTY, SET1, 0)); + assertTrue(IntraCaseUtils.verifyFileExistanceAndCount(files, dataSources, EMPTY, SET4, 0)); + + } catch (NoCurrentCaseException | TskCoreException | SQLException ex) { + Exceptions.printStackTrace(ex); + Assert.fail(ex); + } + } +} From 1e84766419ee71e8e11789095e253cc2fca3b67d Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Thu, 19 Jul 2018 11:52:40 -0600 Subject: [PATCH 147/287] these were deleted and i think it was a mistake --- .../directorytree/GroupDataSourcesDialog.form | 101 ++++ .../directorytree/GroupDataSourcesDialog.java | 147 ++++++ .../IngestedWithHashAndFileType.java | 465 ++++++++++++++++++ .../keywordsearch/TextFileExtractor.java | 80 +++ 4 files changed, 793 insertions(+) create mode 100644 Core/src/org/sleuthkit/autopsy/directorytree/GroupDataSourcesDialog.form create mode 100644 Core/src/org/sleuthkit/autopsy/directorytree/GroupDataSourcesDialog.java create mode 100644 Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileType.java create mode 100644 KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TextFileExtractor.java diff --git a/Core/src/org/sleuthkit/autopsy/directorytree/GroupDataSourcesDialog.form b/Core/src/org/sleuthkit/autopsy/directorytree/GroupDataSourcesDialog.form new file mode 100644 index 0000000000..e31c97d4ba --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/directorytree/GroupDataSourcesDialog.form @@ -0,0 +1,101 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/Core/src/org/sleuthkit/autopsy/directorytree/GroupDataSourcesDialog.java b/Core/src/org/sleuthkit/autopsy/directorytree/GroupDataSourcesDialog.java new file mode 100644 index 0000000000..7641655d57 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/directorytree/GroupDataSourcesDialog.java @@ -0,0 +1,147 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2011-2018 Basis Technology Corp. + * Contact: carrier sleuthkit 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.directorytree; + +import javax.swing.JFrame; +import org.openide.util.NbBundle; +import org.openide.windows.WindowManager; + +/** + * + */ +@SuppressWarnings("PMD.SingularField") // UI widgets cause lots of false positives +final class GroupDataSourcesDialog extends javax.swing.JDialog { + + boolean shouldGroupByDataSource = false; + + /** + * Creates new form GroupDataSourcesDialog + */ + @NbBundle.Messages({"# {0} - dataSourceCount", + "GroupDataSourcesDialog.groupDataSources.text=This case contains {0} data sources."}) + GroupDataSourcesDialog(int dataSourceCount) { + super((JFrame) WindowManager.getDefault().getMainWindow()); + initComponents(); + dataSourceCountLabel.setText(Bundle.GroupDataSourcesDialog_groupDataSources_text(dataSourceCount)); + } + + /** + * Display the dialog. + */ + void display() { + setModal(true); + setSize(getPreferredSize()); + setLocationRelativeTo(this.getParent()); + setAlwaysOnTop(false); + pack(); + setVisible(true); + } + + boolean groupByDataSourceSelected() { + return shouldGroupByDataSource; + } + + /** + * This method is called from within the constructor to initialize the form. + * WARNING: Do NOT modify this code. The content of this method is always + * regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // //GEN-BEGIN:initComponents + private void initComponents() { + + dataSourceCountLabel = new javax.swing.JLabel(); + queryLabel = new javax.swing.JLabel(); + yesButton = new javax.swing.JButton(); + noButton = new javax.swing.JButton(); + + setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + setTitle(org.openide.util.NbBundle.getMessage(GroupDataSourcesDialog.class, "GroupDataSourcesDialog.title")); // NOI18N + + org.openide.awt.Mnemonics.setLocalizedText(dataSourceCountLabel, org.openide.util.NbBundle.getMessage(GroupDataSourcesDialog.class, "GroupDataSourcesDialog.dataSourceCountLabel.text")); // NOI18N + + org.openide.awt.Mnemonics.setLocalizedText(queryLabel, org.openide.util.NbBundle.getMessage(GroupDataSourcesDialog.class, "GroupDataSourcesDialog.queryLabel.text")); // NOI18N + + org.openide.awt.Mnemonics.setLocalizedText(yesButton, org.openide.util.NbBundle.getMessage(GroupDataSourcesDialog.class, "GroupDataSourcesDialog.yesButton.text")); // NOI18N + yesButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + yesButtonActionPerformed(evt); + } + }); + + org.openide.awt.Mnemonics.setLocalizedText(noButton, org.openide.util.NbBundle.getMessage(GroupDataSourcesDialog.class, "GroupDataSourcesDialog.noButton.text")); // NOI18N + noButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + noButtonActionPerformed(evt); + } + }); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); + getContentPane().setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(queryLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGroup(layout.createSequentialGroup() + .addComponent(dataSourceCountLabel) + .addGap(0, 0, Short.MAX_VALUE)) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addGap(0, 0, Short.MAX_VALUE) + .addComponent(yesButton, javax.swing.GroupLayout.PREFERRED_SIZE, 76, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(noButton, javax.swing.GroupLayout.PREFERRED_SIZE, 76, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addContainerGap()) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addComponent(dataSourceCountLabel) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(queryLabel) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(yesButton) + .addComponent(noButton)) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + + pack(); + }// //GEN-END:initComponents + + private void yesButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_yesButtonActionPerformed + shouldGroupByDataSource = true; + dispose(); + }//GEN-LAST:event_yesButtonActionPerformed + + private void noButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_noButtonActionPerformed + shouldGroupByDataSource = false; + dispose(); + }//GEN-LAST:event_noButtonActionPerformed + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JLabel dataSourceCountLabel; + private javax.swing.JButton noButton; + private javax.swing.JLabel queryLabel; + private javax.swing.JButton yesButton; + // End of variables declaration//GEN-END:variables +} diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileType.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileType.java new file mode 100644 index 0000000000..a599763346 --- /dev/null +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileType.java @@ -0,0 +1,465 @@ +/* + * + * Autopsy Forensic Browser + * + * Copyright 2018 Basis Technology Corp. + * Contact: carrier sleuthkit 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.commonfilessearch; + +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import junit.framework.Test; +import org.netbeans.junit.NbModuleSuite; +import org.netbeans.junit.NbTestCase; +import org.openide.util.Exceptions; +import org.python.icu.impl.Assert; +import org.sleuthkit.autopsy.casemodule.Case; +import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; +import org.sleuthkit.autopsy.commonfilesearch.AllDataSourcesCommonFilesAlgorithm; +import org.sleuthkit.autopsy.commonfilesearch.CommonFilesMetadata; +import org.sleuthkit.autopsy.commonfilesearch.CommonFilesMetadataBuilder; +import org.sleuthkit.autopsy.commonfilesearch.SingleDataSource; +import static org.sleuthkit.autopsy.commonfilessearch.IntraCaseUtils.*; +import org.sleuthkit.autopsy.ingest.IngestJobSettings; +import org.sleuthkit.autopsy.ingest.IngestJobSettings.IngestType; +import org.sleuthkit.autopsy.ingest.IngestModuleTemplate; +import org.sleuthkit.autopsy.modules.filetypeid.FileTypeIdModuleFactory; +import org.sleuthkit.autopsy.modules.hashdatabase.HashLookupModuleFactory; +import org.sleuthkit.autopsy.testutils.IngestUtils; +import org.sleuthkit.datamodel.AbstractFile; +import org.sleuthkit.datamodel.TskCoreException; + +/** + * Add set 1, set 2, set 3, and set 4 to case and ingest with hash algorithm. + */ +public class IngestedWithHashAndFileType extends NbTestCase { + + public static Test suite() { + NbModuleSuite.Configuration conf = NbModuleSuite.createConfiguration(IngestedWithHashAndFileType.class). + clusters(".*"). + enableModules(".*"); + return conf.suite(); + } + + private final IntraCaseUtils utils; + + public IngestedWithHashAndFileType(String name) { + super(name); + + this.utils = new IntraCaseUtils(this, "IngestedWithHashAndFileTypeTests"); + } + + @Override + public void setUp() { + this.utils.setUp(); + + IngestModuleTemplate hashLookupTemplate = IngestUtils.getIngestModuleTemplate(new HashLookupModuleFactory()); + IngestModuleTemplate mimeTypeLookupTemplate = IngestUtils.getIngestModuleTemplate(new FileTypeIdModuleFactory()); + + ArrayList templates = new ArrayList<>(); + templates.add(hashLookupTemplate); + templates.add(mimeTypeLookupTemplate); + + IngestJobSettings ingestJobSettings = new IngestJobSettings(IngestedWithHashAndFileType.class.getCanonicalName(), IngestType.FILES_ONLY, templates); + + try { + IngestUtils.runIngestJob(Case.getCurrentCaseThrows().getDataSources(), ingestJobSettings); + } catch (NoCurrentCaseException | TskCoreException ex) { + Exceptions.printStackTrace(ex); + Assert.fail(ex); + } + } + + @Override + public void tearDown() { + this.utils.tearDown(); + } + + /** + * Find all matches & all file types. Confirm file.jpg is found on all three + * and file.docx is found on two. + */ + public void testOneA() { + try { + Map dataSources = this.utils.getDataSourceMap(); + + CommonFilesMetadataBuilder allSourcesBuilder = new AllDataSourcesCommonFilesAlgorithm(dataSources, false, false); + CommonFilesMetadata metadata = allSourcesBuilder.findCommonFiles(); + + Map objectIdToDataSource = IntraCaseUtils.mapFileInstancesToDataSources(metadata); + + List files = IntraCaseUtils.getFiles(objectIdToDataSource.keySet()); + + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, IMG, SET1, 2)); + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, IMG, SET2, 1)); + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, IMG, SET3, 1)); + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, IMG, SET4, 0)); + + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, DOC, SET1, 1)); + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, DOC, SET2, 0)); + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, DOC, SET3, 1)); + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, DOC, SET4, 0)); + + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, PDF, SET1, 0)); + assertTrue(IntraCaseUtils.verifyFileExistanceAndCount(files, objectIdToDataSource, PDF, SET2, 0)); + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, PDF, SET3, 0)); + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, PDF, SET4, 0)); + + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, EMPTY, SET1, 0)); + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, EMPTY, SET2, 0)); + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, EMPTY, SET3, 0)); + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, EMPTY, SET4, 0)); + + } catch (NoCurrentCaseException | TskCoreException | SQLException ex) { + Exceptions.printStackTrace(ex); + Assert.fail(ex); + } + } + + /** + * Find all matches & only image types. Confirm file.jpg is found on all + * three. + */ + public void testOneB() { + try { + Map dataSources = this.utils.getDataSourceMap(); + + CommonFilesMetadataBuilder allSourcesBuilder = new AllDataSourcesCommonFilesAlgorithm(dataSources, true, false); + CommonFilesMetadata metadata = allSourcesBuilder.findCommonFiles(); + + Map objectIdToDataSource = mapFileInstancesToDataSources(metadata); + + List files = getFiles(objectIdToDataSource.keySet()); + + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, IMG, SET1, 2)); + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, IMG, SET2, 1)); + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, IMG, SET3, 1)); + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, IMG, SET4, 0)); + + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, DOC, SET1, 0)); + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, DOC, SET2, 0)); + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, DOC, SET3, 0)); + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, DOC, SET4, 0)); + + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, PDF, SET1, 0)); + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, PDF, SET2, 0)); + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, PDF, SET3, 0)); + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, PDF, SET4, 0)); + + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, EMPTY, SET1, 0)); + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, EMPTY, SET2, 0)); + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, EMPTY, SET3, 0)); + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, EMPTY, SET4, 0)); + + } catch (NoCurrentCaseException | TskCoreException | SQLException ex) { + Exceptions.printStackTrace(ex); + Assert.fail(ex); + } + } + + /** + * Find all matches & only image types. Confirm file.jpg is found on all + * three. + */ + public void testOneC() { + try { + Map dataSources = this.utils.getDataSourceMap(); + + CommonFilesMetadataBuilder allSourcesBuilder = new AllDataSourcesCommonFilesAlgorithm(dataSources, false, true); + CommonFilesMetadata metadata = allSourcesBuilder.findCommonFiles(); + + Map objectIdToDataSource = mapFileInstancesToDataSources(metadata); + + List files = getFiles(objectIdToDataSource.keySet()); + + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, IMG, SET1, 0)); + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, IMG, SET2, 0)); + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, IMG, SET3, 0)); + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, IMG, SET4, 0)); + + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, DOC, SET1, 1)); + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, DOC, SET2, 0)); + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, DOC, SET3, 1)); + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, DOC, SET4, 0)); + + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, PDF, SET1, 0)); + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, PDF, SET2, 0)); + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, PDF, SET3, 0)); + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, PDF, SET4, 0)); + + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, EMPTY, SET1, 0)); + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, EMPTY, SET2, 0)); + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, EMPTY, SET3, 0)); + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, EMPTY, SET4, 0)); + + } catch (NoCurrentCaseException | TskCoreException | SQLException ex) { + Exceptions.printStackTrace(ex); + Assert.fail(ex); + } + } + + /** + * Find matches on set 1 & all file types. Confirm same results. + * + */ + public void testTwoA() { + try { + Map dataSources = this.utils.getDataSourceMap(); + Long first = getDataSourceIdByName(SET1, dataSources); + + CommonFilesMetadataBuilder singleSourceBuilder = new SingleDataSource(first, dataSources, false, false); + CommonFilesMetadata metadata = singleSourceBuilder.findCommonFiles(); + + Map objectIdToDataSource = mapFileInstancesToDataSources(metadata); + + List files = getFiles(objectIdToDataSource.keySet()); + + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, IMG, SET1, 2)); + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, IMG, SET2, 1)); + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, IMG, SET3, 1)); + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, IMG, SET4, 0)); + + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, DOC, SET1, 1)); + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, DOC, SET2, 0)); + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, DOC, SET3, 1)); + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, DOC, SET4, 0)); + + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, PDF, SET1, 0)); + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, PDF, SET2, 0)); + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, PDF, SET3, 0)); + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, PDF, SET4, 0)); + + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, EMPTY, SET1, 0)); + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, EMPTY, SET2, 0)); + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, EMPTY, SET3, 0)); + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, EMPTY, SET4, 0)); + + } catch (NoCurrentCaseException | TskCoreException | SQLException ex) { + Exceptions.printStackTrace(ex); + Assert.fail(ex); + } + } + + /** + * Find matches on set 1 & only media types. Confirm same results. + * + */ + public void testTwoB() { + try { + Map dataSources = this.utils.getDataSourceMap(); + Long first = getDataSourceIdByName(SET1, dataSources); + + CommonFilesMetadataBuilder singleSourceBuilder = new SingleDataSource(first, dataSources, true, false); + CommonFilesMetadata metadata = singleSourceBuilder.findCommonFiles(); + + Map objectIdToDataSource = mapFileInstancesToDataSources(metadata); + + List files = getFiles(objectIdToDataSource.keySet()); + + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, IMG, SET1, 2)); + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, IMG, SET2, 1)); + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, IMG, SET3, 1)); + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, IMG, SET4, 0)); + + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, DOC, SET1, 0)); + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, DOC, SET2, 0)); + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, DOC, SET3, 0)); + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, DOC, SET4, 0)); + + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, PDF, SET1, 0)); + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, PDF, SET2, 0)); + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, PDF, SET3, 0)); + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, PDF, SET4, 0)); + + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, EMPTY, SET1, 0)); + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, EMPTY, SET2, 0)); + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, EMPTY, SET3, 0)); + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, EMPTY, SET4, 0)); + + } catch (NoCurrentCaseException | TskCoreException | SQLException ex) { + Exceptions.printStackTrace(ex); + Assert.fail(ex); + } + } + + /** + * Find matches on set 1 & all file types. Confirm same results. + * + */ + public void testTwoC() { + try { + Map dataSources = this.utils.getDataSourceMap(); + Long first = getDataSourceIdByName(SET1, dataSources); + + CommonFilesMetadataBuilder singleSourceBuilder = new SingleDataSource(first, dataSources, false, true); + CommonFilesMetadata metadata = singleSourceBuilder.findCommonFiles(); + + Map objectIdToDataSource = mapFileInstancesToDataSources(metadata); + + List files = getFiles(objectIdToDataSource.keySet()); + + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, IMG, SET1, 0)); + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, IMG, SET2, 0)); + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, IMG, SET3, 0)); + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, IMG, SET4, 0)); + + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, DOC, SET1, 1)); + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, DOC, SET2, 0)); + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, DOC, SET3, 1)); + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, DOC, SET4, 0)); + + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, PDF, SET1, 0)); + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, PDF, SET2, 0)); + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, PDF, SET3, 0)); + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, PDF, SET4, 0)); + + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, EMPTY, SET1, 0)); + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, EMPTY, SET2, 0)); + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, EMPTY, SET3, 0)); + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, EMPTY, SET4, 0)); + + } catch (NoCurrentCaseException | TskCoreException | SQLException ex) { + Exceptions.printStackTrace(ex); + Assert.fail(ex); + } + } + + /** + * Find matches on set 2 & all file types: Confirm file.jpg. + * + */ + public void testThree() { + try { + Map dataSources = this.utils.getDataSourceMap(); + Long second = getDataSourceIdByName(SET2, dataSources); + + CommonFilesMetadataBuilder singleSourceBuilder = new SingleDataSource(second, dataSources, false, false); + CommonFilesMetadata metadata = singleSourceBuilder.findCommonFiles(); + + Map objectIdToDataSource = mapFileInstancesToDataSources(metadata); + + List files = getFiles(objectIdToDataSource.keySet()); + + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, IMG, SET1, 2)); + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, IMG, SET2, 1)); + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, IMG, SET3, 1)); + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, IMG, SET4, 0)); + + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, DOC, SET1, 0)); + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, DOC, SET2, 0)); + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, DOC, SET3, 0)); + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, DOC, SET4, 0)); + + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, PDF, SET1, 0)); + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, PDF, SET2, 0)); + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, PDF, SET3, 0)); + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, PDF, SET4, 0)); + + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, EMPTY, SET1, 0)); + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, EMPTY, SET2, 0)); + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, EMPTY, SET3, 0)); + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, EMPTY, SET4, 0)); + + } catch (NoCurrentCaseException | TskCoreException | SQLException ex) { + Exceptions.printStackTrace(ex); + Assert.fail(ex); + } + } + + /** + * Find matches on set 4 & all file types: Confirm nothing is found. + */ + public void testFour() { + try { + Map dataSources = this.utils.getDataSourceMap(); + Long last = getDataSourceIdByName(SET4, dataSources); + + CommonFilesMetadataBuilder singleSourceBuilder = new SingleDataSource(last, dataSources, false, false); + CommonFilesMetadata metadata = singleSourceBuilder.findCommonFiles(); + + Map objectIdToDataSource = mapFileInstancesToDataSources(metadata); + + List files = getFiles(objectIdToDataSource.keySet()); + + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, IMG, SET1, 0)); + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, IMG, SET2, 0)); + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, IMG, SET3, 0)); + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, IMG, SET4, 0)); + + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, DOC, SET1, 0)); + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, DOC, SET1, 0)); + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, DOC, SET3, 0)); + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, DOC, SET4, 0)); + + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, PDF, SET1, 0)); + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, PDF, SET2, 0)); + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, PDF, SET3, 0)); + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, PDF, SET4, 0)); + + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, EMPTY, SET1, 0)); + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, EMPTY, SET2, 0)); + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, EMPTY, SET3, 0)); + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, EMPTY, SET4, 0)); + + } catch (NoCurrentCaseException | TskCoreException | SQLException ex) { + Exceptions.printStackTrace(ex); + Assert.fail(ex); + } + } + + /** + * Find matches on set 3 & all file types: Confirm file.jpg and file.docx. + */ + public void testFive() { + try { + Map dataSources = this.utils.getDataSourceMap(); + Long third = getDataSourceIdByName(SET3, dataSources); + + CommonFilesMetadataBuilder singleSourceBuilder = new SingleDataSource(third, dataSources, false, false); + CommonFilesMetadata metadata = singleSourceBuilder.findCommonFiles(); + + Map objectIdToDataSource = mapFileInstancesToDataSources(metadata); + + List files = getFiles(objectIdToDataSource.keySet()); + + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, IMG, SET1, 2)); + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, IMG, SET2, 1)); + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, IMG, SET3, 1)); + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, IMG, SET4, 0)); + + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, DOC, SET1, 1)); + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, DOC, SET2, 0)); + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, DOC, SET3, 1)); + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, DOC, SET4, 0)); + + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, PDF, SET1, 0)); + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, PDF, SET2, 0)); + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, PDF, SET3, 0)); + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, PDF, SET4, 0)); + + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, EMPTY, SET1, 0)); + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, EMPTY, SET2, 0)); + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, EMPTY, SET3, 0)); + assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, EMPTY, SET4, 0)); + + } catch (NoCurrentCaseException | TskCoreException | SQLException ex) { + Exceptions.printStackTrace(ex); + Assert.fail(ex); + } + } +} diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TextFileExtractor.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TextFileExtractor.java new file mode 100644 index 0000000000..bc11515e96 --- /dev/null +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TextFileExtractor.java @@ -0,0 +1,80 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2018 Basis Technology Corp. + * Contact: carrier sleuthkit 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.keywordsearch; + +import java.io.IOException; +import java.io.Reader; +import java.util.logging.Level; +import org.apache.tika.parser.txt.CharsetDetector; +import org.apache.tika.parser.txt.CharsetMatch; +import org.sleuthkit.autopsy.coreutils.Logger; +import org.sleuthkit.datamodel.Content; +import org.sleuthkit.datamodel.ReadContentInputStream; + +/** + * Extract text from .txt files + */ +final class TextFileExtractor extends ContentTextExtractor { + + //Set a Minimum confidence value to reject matches that may not have a valid text encoding + //Values of valid text encodings were generally 100, xml code sometimes had a value around 50, + //and pictures and other files with a .txt extention were showing up with a value of 5 or less in limited testing. + //This limited information was used to select the current value as one that would filter out clearly non-text + //files while hopefully working on all files with a valid text encoding + static final private int MIN_MATCH_CONFIDENCE = 20; + static final private Logger logger = Logger.getLogger(TextFileExtractor.class.getName()); + + @Override + boolean isContentTypeSpecific() { + return true; + } + + @Override + boolean isSupported(Content file, String detectedFormat) { + return true; + } + + @Override + public Reader getReader(Content source) throws TextExtractorException { + CharsetDetector detector = new CharsetDetector(); + ReadContentInputStream stream = new ReadContentInputStream(source); + try { + detector.setText(stream); + } catch (IOException ex) { + throw new TextExtractorException("Unable to get string from detected text in UnicodeTextExtractor", ex); + } + CharsetMatch match = detector.detect(); + if (match.getConfidence() < MIN_MATCH_CONFIDENCE) { + throw new TextExtractorException("Text does not match any character set with a high enough confidence for UnicodeTextExtractor"); + } + + return match.getReader(); + } + + @Override + public boolean isDisabled() { + return false; + } + + @Override + public void logWarning(String msg, Exception ex) { + logger.log(Level.WARNING, msg, ex); + } + +} From 3bbb3261c970af4db16c59ebc8c6da76cbf021a6 Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Thu, 19 Jul 2018 17:12:37 -0400 Subject: [PATCH 148/287] 4040 Associate the user name of who created a tag with that tag --- .../casemodule/SingleUserCaseConverter.java | 8 +++++--- .../datamodel/BlackboardArtifactTagNode.java | 11 +++++++++-- .../autopsy/datamodel/ContentTagNode.java | 16 +++++++++++----- .../autopsy/report/TableReportGenerator.java | 13 +++++++++---- 4 files changed, 34 insertions(+), 14 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/SingleUserCaseConverter.java b/Core/src/org/sleuthkit/autopsy/casemodule/SingleUserCaseConverter.java index 46727fc570..95dfad8c5d 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/SingleUserCaseConverter.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/SingleUserCaseConverter.java @@ -859,13 +859,14 @@ public class SingleUserCaseConverter { if (value > biggestPK) { biggestPK = value; } - outputStatement.executeUpdate("INSERT INTO content_tags (tag_id, obj_id, tag_name_id, comment, begin_byte_offset, end_byte_offset) VALUES (" //NON-NLS + outputStatement.executeUpdate("INSERT INTO content_tags (tag_id, obj_id, tag_name_id, comment, begin_byte_offset, end_byte_offset, user_name) VALUES (" //NON-NLS + value + "," + inputResultSet.getLong(2) + "," + inputResultSet.getLong(3) + ",'" + inputResultSet.getString(4) + "'," + inputResultSet.getLong(5) + "," - + inputResultSet.getLong(6) + ")"); //NON-NLS + + inputResultSet.getLong(6) + ",'" + + inputResultSet.getString(7)+ "')"); //NON-NLS } catch (SQLException ex) { if (ex.getErrorCode() != 0) { // 0 if the entry already exists @@ -892,7 +893,8 @@ public class SingleUserCaseConverter { + value + "," + inputResultSet.getLong(2) + "," + inputResultSet.getLong(3) + ",'" - + inputResultSet.getString(4) + "')"); //NON-NLS + + inputResultSet.getString(4) + "','" + + inputResultSet.getString(5) + "')"); //NON-NLS } catch (SQLException ex) { if (ex.getErrorCode() != 0) { // 0 if the entry already exists diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactTagNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactTagNode.java index ea944b6b43..16cf40680c 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactTagNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactTagNode.java @@ -27,6 +27,7 @@ import javax.swing.Action; import org.openide.nodes.Children; import org.openide.nodes.Sheet; import org.openide.util.NbBundle; +import org.openide.util.NbBundle.Messages; import org.openide.util.lookup.Lookups; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil; @@ -59,6 +60,7 @@ public class BlackboardArtifactTagNode extends DisplayableItemNode { this.tag = tag; } + @Messages({"BlackboardArtifactTagNode.createSheet.userName.text=User Name"}) @Override protected Sheet createSheet() { Sheet propertySheet = super.createSheet(); @@ -80,6 +82,7 @@ public class BlackboardArtifactTagNode extends DisplayableItemNode { Logger.getLogger(ContentTagNode.class.getName()).log(Level.SEVERE, "Failed to get path for content (id = " + tag.getContent().getId() + ")", ex); //NON-NLS contentPath = NbBundle.getMessage(this.getClass(), "BlackboardArtifactTagNode.createSheet.unavail.text"); } + properties.put(new NodeProperty<>( NbBundle.getMessage(this.getClass(), "BlackboardArtifactTagNode.createSheet.srcFilePath.text"), NbBundle.getMessage(this.getClass(), "BlackboardArtifactTagNode.createSheet.srcFilePath.text"), @@ -95,7 +98,11 @@ public class BlackboardArtifactTagNode extends DisplayableItemNode { NbBundle.getMessage(this.getClass(), "BlackboardArtifactTagNode.createSheet.comment.text"), "", tag.getComment())); - + properties.put(new NodeProperty<>( + NbBundle.getMessage(this.getClass(), "BlackboardArtifactTagNode.createSheet.userName.text"), + NbBundle.getMessage(this.getClass(), "BlackboardArtifactTagNode.createSheet.userName.text"), + "", + tag.getUserName())); return propertySheet; } @@ -132,7 +139,7 @@ public class BlackboardArtifactTagNode extends DisplayableItemNode { } actions.add(new ViewTaggedArtifactAction(BlackboardArtifactTagNode_viewSourceArtifact_text(), artifact)); actions.addAll(DataModelActionsFactory.getActions(tag, true)); - + return actions.toArray(new Action[0]); } diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/ContentTagNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/ContentTagNode.java index 547303878b..e213e460cb 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/ContentTagNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/ContentTagNode.java @@ -59,8 +59,8 @@ class ContentTagNode extends DisplayableItemNode { @Messages({ "ContentTagNode.createSheet.artifactMD5.displayName=MD5 Hash", - "ContentTagNode.createSheet.artifactMD5.name=MD5 Hash" - }) + "ContentTagNode.createSheet.artifactMD5.name=MD5 Hash", + "ContentTagNode.createSheet.userName.text=User Name"}) @Override protected Sheet createSheet() { Content content = tag.getContent(); @@ -115,6 +115,11 @@ class ContentTagNode extends DisplayableItemNode { Bundle.ContentTagNode_createSheet_artifactMD5_displayName(), "", file != null ? StringUtils.defaultString(file.getMd5Hash()) : "")); + properties.put(new NodeProperty<>( + NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.userName.text"), + NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.userName.text"), + "", + tag.getUserName())); return propertySheet; } @@ -123,13 +128,14 @@ class ContentTagNode extends DisplayableItemNode { List actions = new ArrayList<>(); actions.addAll(Arrays.asList(super.getActions(context))); - AbstractFile file = getLookup().lookup(AbstractFile.class); + AbstractFile file = getLookup().lookup(AbstractFile.class + ); if (file != null) { actions.add(ViewFileInTimelineAction.createViewFileAction(file)); } - + actions.addAll(DataModelActionsFactory.getActions(tag, false)); - + return actions.toArray(new Action[actions.size()]); } diff --git a/Core/src/org/sleuthkit/autopsy/report/TableReportGenerator.java b/Core/src/org/sleuthkit/autopsy/report/TableReportGenerator.java index f87851fe87..ff1479cd86 100644 --- a/Core/src/org/sleuthkit/autopsy/report/TableReportGenerator.java +++ b/Core/src/org/sleuthkit/autopsy/report/TableReportGenerator.java @@ -38,6 +38,7 @@ import java.util.Set; import java.util.TreeSet; import java.util.logging.Level; import org.openide.util.NbBundle; +import org.openide.util.NbBundle.Messages; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; import org.sleuthkit.autopsy.casemodule.services.TagsManager; @@ -264,6 +265,7 @@ class TableReportGenerator { /** * Make table for tagged files */ + @Messages({"ReportGenerator.tagTable.header.userName=User Name"}) @SuppressWarnings("deprecation") private void makeContentTagsTables() { @@ -286,7 +288,8 @@ class TableReportGenerator { ArrayList columnHeaders = new ArrayList<>(Arrays.asList( NbBundle.getMessage(this.getClass(), "ReportGenerator.htmlOutput.header.tag"), NbBundle.getMessage(this.getClass(), "ReportGenerator.htmlOutput.header.file"), - NbBundle.getMessage(this.getClass(), "ReportGenerator.htmlOutput.header.comment"), + NbBundle.getMessage(this.getClass(), "ReportGenerator.htmlOutput.header.comment"), + NbBundle.getMessage(this.getClass(), "ReportGenerator.tagTable.header.userName"), NbBundle.getMessage(this.getClass(), "ReportGenerator.htmlOutput.header.timeModified"), NbBundle.getMessage(this.getClass(), "ReportGenerator.htmlOutput.header.timeChanged"), NbBundle.getMessage(this.getClass(), "ReportGenerator.htmlOutput.header.timeAccessed"), @@ -324,7 +327,7 @@ class TableReportGenerator { fileName = tag.getContent().getName(); } - ArrayList rowData = new ArrayList<>(Arrays.asList(tag.getName().getDisplayName() + notableString, fileName, tag.getComment())); + ArrayList rowData = new ArrayList<>(Arrays.asList(tag.getName().getDisplayName() + notableString, fileName, tag.getComment(), tag.getUserName())); Content content = tag.getContent(); if (content instanceof AbstractFile) { AbstractFile file = (AbstractFile) content; @@ -386,7 +389,8 @@ class TableReportGenerator { NbBundle.getMessage(this.getClass(), "ReportGenerator.tagTable.header.resultType"), NbBundle.getMessage(this.getClass(), "ReportGenerator.tagTable.header.tag"), NbBundle.getMessage(this.getClass(), "ReportGenerator.tagTable.header.comment"), - NbBundle.getMessage(this.getClass(), "ReportGenerator.tagTable.header.srcFile")))); + NbBundle.getMessage(this.getClass(), "ReportGenerator.tagTable.header.srcFile"), + NbBundle.getMessage(this.getClass(), "ReportGenerator.tagTable.header.userName")))); // Give the modules the rows for the content tags. for (BlackboardArtifactTag tag : tags) { @@ -396,7 +400,8 @@ class TableReportGenerator { } List row; - row = new ArrayList<>(Arrays.asList(tag.getArtifact().getArtifactTypeName(), tag.getName().getDisplayName() + notableString, tag.getComment(), tag.getContent().getName())); + row = new ArrayList<>(Arrays.asList(tag.getArtifact().getArtifactTypeName(), tag.getName().getDisplayName() + notableString, + tag.getComment(), tag.getContent().getName(), tag.getUserName())); tableReport.addRow(row); // check if the tag is an image that we should later make a thumbnail for From 2e40856eab1eb4346879a7f081323da1d9adb9eb Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Fri, 20 Jul 2018 08:50:37 -0600 Subject: [PATCH 149/287] fixes a bug where no leaves files were added to the tree because the map was not populated --- .../AbstractCommonAttributeInstanceNode.java | 57 +++++++++++++------ ...InterCaseCommonAttributeSearchResults.java | 1 + 2 files changed, 40 insertions(+), 18 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeInstanceNode.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeInstanceNode.java index adbf70dfc7..df0831ad90 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeInstanceNode.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeInstanceNode.java @@ -67,6 +67,7 @@ abstract class AbstractCommonAttributeInstanceNode { * already so we can avoid extra roundtrips to the case db */ AbstractCommonAttributeInstanceNode(Map cachedFiles) { + this.abstractFileObjectId = -1L; this.cachedFiles = cachedFiles; this.caseName = ""; this.dataSource = ""; @@ -80,12 +81,18 @@ abstract class AbstractCommonAttributeInstanceNode { * implementations of this object */ AbstractFile lookupOrLoadAbstractFile() { + //TODO this is broken if (getCachedFiles().containsKey(this.getAbstractFileObjectId())) { return getCachedFiles().get(this.getAbstractFileObjectId()); } else { - AbstractFile file = this.loadFileFromSleuthkitCase(); - getCachedFiles().put(this.getAbstractFileObjectId(), file); - return file; + try { + AbstractFile file = this.loadFileFromSleuthkitCase(); + final long id = file.getId(); + this.cachedFiles.put(id, file); + return file; + } catch (Exception e) { + throw e; + } } } @@ -132,12 +139,23 @@ abstract class AbstractCommonAttributeInstanceNode { } /** + * ObjectId of the AbstractFile that is equivalent to the file from which + * this common attribute instance + * * @return the abstractFileObjectId */ Long getAbstractFileObjectId() { return abstractFileObjectId; } + /** + * Set the ObjectId of the AbstractFile that is equaivalent to the file from + * which this common attribute instance + */ + void setAbstractFileObjectId(Long abstractFileObjectId) { + this.abstractFileObjectId = abstractFileObjectId; + } + /** * Get the map of AbstractFile which we use to avoid loading the same file * from the SleuthkitCase more than necessary. @@ -149,34 +167,37 @@ abstract class AbstractCommonAttributeInstanceNode { } /** - * Use this to create an AbstractCommonAttributeInstanceNode of the - * appropriate type. In any case, we'll get something which extends - * DisplayableItemNode which can be used to populate the tree. - * + * Use this to create an AbstractCommonAttributeInstanceNode of the + * appropriate type. In any case, we'll get something which extends + * DisplayableItemNode which can be used to populate the tree. + * * If the common attribute in question could be derived from an AbstractFile - * in the present SleuthkitCase, we can use an - * IntraCaseCommonAttributeInstanceNode which enables extended functionality + * in the present SleuthkitCase, we can use an + * IntraCaseCommonAttributeInstanceNode which enables extended functionality * in the context menu and in the content viewer. - * - * Otherwise, we will get an InterCaseCommonAttributeInstanceNode which + * + * Otherwise, we will get an InterCaseCommonAttributeInstanceNode which * supports only baseline functionality. - * - * @param attributeInstance common file attribute instance form the central repo - * @param equivalentAbstractFile an AbstractFile which is equivalent to the file in which the attribute instance was found - * @param currentCaseName + * + * @param attributeInstance common file attribute instance form the central + * repo + * @param equivalentAbstractFile an AbstractFile which is equivalent to the + * file in which the attribute instance was found + * @param currentCaseName * @return the appropriate leaf node for the results tree - * @throws TskCoreException + * @throws TskCoreException */ static DisplayableItemNode createInstance(CorrelationAttributeInstance attributeInstance, AbstractFile equivalentAbstractFile, String currentCaseName) throws TskCoreException { + DisplayableItemNode leafNode; final String attributeDataSourceName = attributeInstance.getCorrelationDataSource().getName(); final String abstractFileDataSourceName = equivalentAbstractFile.getDataSource().getName(); final String attributeInstanceCaseName = attributeInstance.getCorrelationCase().getDisplayName(); - + final String attributeInstanceFullPath = attributeInstance.getFilePath().replace("\\", "/"); - + final String currentAbstractFileParentPath = equivalentAbstractFile.getParentPath(); final String currentAbstractFileName = equivalentAbstractFile.getName(); final String abstractFileFullPath = (currentAbstractFileParentPath + currentAbstractFileName).replace("\\", "/"); diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearchResults.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearchResults.java index e2dbfd79b9..b6005c333d 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearchResults.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearchResults.java @@ -64,6 +64,7 @@ final public class InterCaseCommonAttributeSearchResults extends AbstractCommonA SleuthkitCase tskDb = currentCase.getSleuthkitCase(); File fileFromPath = new File(currentFullPath); String fileName = fileFromPath.getName(); + //TODO this seems like a bug - we maybe need to look at all of these not just the first AbstractFile abstractFile = tskDb.findAllFilesWhere(String.format("lower(name) = '%s'", fileName)).get(0); return abstractFile; From f283009c6831f24f30eda08ba7c4429687e9def0 Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dgrove" Date: Fri, 20 Jul 2018 15:02:12 -0400 Subject: [PATCH 150/287] Changed form layout to conform with Add Keywords. --- .../AddHashValuesToDatabaseDialog.form | 48 +++++++++---------- .../AddHashValuesToDatabaseDialog.java | 45 +++++++++-------- .../modules/hashdatabase/Bundle.properties | 2 +- .../modules/hashdatabase/Bundle_ja.properties | 2 +- 4 files changed, 47 insertions(+), 50 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/AddHashValuesToDatabaseDialog.form b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/AddHashValuesToDatabaseDialog.form index da0b07d99d..bf4e6ef5a8 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/AddHashValuesToDatabaseDialog.form +++ b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/AddHashValuesToDatabaseDialog.form @@ -26,20 +26,21 @@ - + - + + - - - - - - - + + + + + + + @@ -47,21 +48,18 @@ - - + + - - - - - - - - - - + + + + + + + - + @@ -102,14 +100,14 @@
- + - + - + diff --git a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/AddHashValuesToDatabaseDialog.java b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/AddHashValuesToDatabaseDialog.java index 68535928c7..bcae027d61 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/AddHashValuesToDatabaseDialog.java +++ b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/AddHashValuesToDatabaseDialog.java @@ -73,7 +73,7 @@ public class AddHashValuesToDatabaseDialog extends javax.swing.JDialog { } else { setDefaultCloseOperation(0); } - AddValuesToHashDatabaseButton.setEnabled(enable); + okButton.setEnabled(enable); cancelButton.setEnabled(enable); pasteFromClipboardButton.setEnabled(enable); } @@ -91,7 +91,7 @@ public class AddHashValuesToDatabaseDialog extends javax.swing.JDialog { jScrollPane1 = new javax.swing.JScrollPane(); hashValuesTextArea = new javax.swing.JTextArea(); pasteFromClipboardButton = new javax.swing.JButton(); - AddValuesToHashDatabaseButton = new javax.swing.JButton(); + okButton = new javax.swing.JButton(); cancelButton = new javax.swing.JButton(); setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); @@ -115,10 +115,10 @@ public class AddHashValuesToDatabaseDialog extends javax.swing.JDialog { } }); - org.openide.awt.Mnemonics.setLocalizedText(AddValuesToHashDatabaseButton, org.openide.util.NbBundle.getMessage(AddHashValuesToDatabaseDialog.class, "AddHashValuesToDatabaseDialog.AddValuesToHashDatabaseButton.text_2")); // NOI18N - AddValuesToHashDatabaseButton.addActionListener(new java.awt.event.ActionListener() { + org.openide.awt.Mnemonics.setLocalizedText(okButton, org.openide.util.NbBundle.getMessage(AddHashValuesToDatabaseDialog.class, "AddHashValuesToDatabaseDialog.okButton.text_2")); // NOI18N + okButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { - AddValuesToHashDatabaseButtonActionPerformed(evt); + okButtonActionPerformed(evt); } }); @@ -136,31 +136,30 @@ public class AddHashValuesToDatabaseDialog extends javax.swing.JDialog { .addGroup(layout.createSequentialGroup() .addContainerGap() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jScrollPane1) .addGroup(layout.createSequentialGroup() .addComponent(instructionLabel) .addGap(0, 0, Short.MAX_VALUE)) - .addComponent(jScrollPane1)) - .addGap(18, 18, 18) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(AddValuesToHashDatabaseButton, javax.swing.GroupLayout.Alignment.TRAILING) - .addComponent(cancelButton, javax.swing.GroupLayout.Alignment.TRAILING) - .addComponent(pasteFromClipboardButton, javax.swing.GroupLayout.Alignment.TRAILING)) + .addGroup(layout.createSequentialGroup() + .addComponent(pasteFromClipboardButton) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 121, Short.MAX_VALUE) + .addComponent(okButton, javax.swing.GroupLayout.PREFERRED_SIZE, 84, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(cancelButton, javax.swing.GroupLayout.PREFERRED_SIZE, 84, javax.swing.GroupLayout.PREFERRED_SIZE))) .addContainerGap()) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() .addContainerGap() .addComponent(instructionLabel) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addComponent(AddValuesToHashDatabaseButton) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(cancelButton) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(pasteFromClipboardButton)) - .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 274, Short.MAX_VALUE)) + .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 279, Short.MAX_VALUE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(pasteFromClipboardButton) + .addComponent(okButton) + .addComponent(cancelButton)) .addContainerGap()) ); @@ -213,17 +212,17 @@ public class AddHashValuesToDatabaseDialog extends javax.swing.JDialog { } }//GEN-LAST:event_hashValuesTextAreaMouseClicked - private void AddValuesToHashDatabaseButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_AddValuesToHashDatabaseButtonActionPerformed + private void okButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_okButtonActionPerformed AddHashValuesToDatabaseProgressDialog progressDialog = new AddHashValuesToDatabaseProgressDialog(this, hashDb, hashValuesTextArea.getText()); progressDialog.addHashValuesToDatabase(); - }//GEN-LAST:event_AddValuesToHashDatabaseButtonActionPerformed + }//GEN-LAST:event_okButtonActionPerformed // Variables declaration - do not modify//GEN-BEGIN:variables - private javax.swing.JButton AddValuesToHashDatabaseButton; private javax.swing.JButton cancelButton; private javax.swing.JTextArea hashValuesTextArea; private javax.swing.JLabel instructionLabel; private javax.swing.JScrollPane jScrollPane1; + private javax.swing.JButton okButton; private javax.swing.JButton pasteFromClipboardButton; // End of variables declaration//GEN-END:variables } diff --git a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/Bundle.properties b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/Bundle.properties index c5f6d82425..cbf25e548c 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/Bundle.properties @@ -172,7 +172,6 @@ HashDbSearchPanel.hashTable.defaultModel.title.text=MD5 Hashes AddHashValuesToDatabaseDialog.JDialog.Title=Add Hashes to Hash Set AddHashValuesToDatabaseDialog.instructionLabel.text_1=Paste MD5 hash values (one per line) below: AddHashValuesToDatabaseDialog.cancelButton.text_2=Cancel -AddHashValuesToDatabaseDialog.AddValuesToHashDatabaseButton.text_2=Add Hashes to Hash Set AddHashValuesToDatabaseDialog.pasteFromClipboardButton.text_2=Paste From Clipboard AddHashValuesToDatabaseProgressDialog.okButton.text=OK AddHashValuesToDatabaseProgressDialog.statusLabel.text=status @@ -237,3 +236,4 @@ HashDbCreateDatabaseDialog.centralRepoRadioButton.text=Remote (Central Repositor HashDbCreateDatabaseDialog.lbOrg.text=Source Organization: HashDbCreateDatabaseDialog.orgButton.text=Manage Organizations HashDbCreateDatabaseDialog.databasePathLabel.text=Hash Set Path: +AddHashValuesToDatabaseDialog.okButton.text_2=OK diff --git a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/Bundle_ja.properties b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/Bundle_ja.properties index 828b027bdb..431529542f 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/Bundle_ja.properties +++ b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/Bundle_ja.properties @@ -172,7 +172,6 @@ AddHashValuesToDatabaseDialog.JDialog.Title=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9 HashLookupSettingsPanel.addHashesToDatabaseButton.text=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306b\u30cf\u30c3\u30b7\u30e5\u3092\u8ffd\u52a0 AddHashValuesToDatabaseDialog.instructionLabel.text_1=\u4e0b\u8a18\u306bMD5\u306e\u30cf\u30c3\u30b7\u30e5\u5024\u3092\u8cbc\u308a\u4ed8\u3051\u308b\uff08\u30e9\u30a4\u30f3\u3054\u3068\u306b\u4e00\u3064\u305a\u3064\uff09\uff1a AddHashValuesToDatabaseDialog.cancelButton.text_2=\u30ad\u30e3\u30f3\u30bb\u30eb -AddHashValuesToDatabaseDialog.AddValuesToHashDatabaseButton.text_2=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306b\u30cf\u30c3\u30b7\u30e5\u3092\u8ffd\u52a0 AddHashValuesToDatabaseDialog.pasteFromClipboardButton.text_2=\u30af\u30ea\u30c3\u30d7\u30dc\u30fc\u30c9\u304b\u3089\u8cbc\u308a\u4ed8\u3051\u308b AddHashValuesToDatabaseProgressDialog.okButton.text=OK AddHashValuesToDatabaseProgressDialog.statusLabel.text=\u30b9\u30c6\u30fc\u30bf\u30b9 @@ -207,3 +206,4 @@ HashLookupSettingsPanel.nameLabel.text=\u30cf\u30c3\u30b7\u30e5\u30bb\u30c3\u30c HashLookupSettingsPanel.hashDatabasesLabel.text=\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\uff1a HashLookupSettingsPanel.importDatabaseButton.text=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3092\u30a4\u30f3\u30dd\u30fc\u30c8 HashDbCreateDatabaseDialog.databasePathLabel.text=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30d1\u30b9\uff1a +AddHashValuesToDatabaseDialog.okButton.text_2=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306b\u30cf\u30c3\u30b7\u30e5\u3092\u8ffd\u52a0 From dd0b41e62ddf9312a81906ec1f9bec429c97e6d0 Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Fri, 20 Jul 2018 14:06:39 -0600 Subject: [PATCH 151/287] cleanup --- .../AbstractCommonAttributeInstanceNode.java | 42 ++++--------------- 1 file changed, 9 insertions(+), 33 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeInstanceNode.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeInstanceNode.java index df0831ad90..d7a8a1cfb5 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeInstanceNode.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeInstanceNode.java @@ -19,7 +19,6 @@ */ package org.sleuthkit.autopsy.commonfilesearch; -import java.util.Collections; import java.util.Map; import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance; import org.sleuthkit.autopsy.datamodel.DisplayableItemNode; @@ -37,7 +36,7 @@ import org.sleuthkit.datamodel.TskCoreException; */ abstract class AbstractCommonAttributeInstanceNode { - private Long abstractFileObjectId; + private final Long abstractFileObjectId; private final Map cachedFiles; private final String caseName; private final String dataSource; @@ -81,26 +80,21 @@ abstract class AbstractCommonAttributeInstanceNode { * implementations of this object */ AbstractFile lookupOrLoadAbstractFile() { - //TODO this is broken - if (getCachedFiles().containsKey(this.getAbstractFileObjectId())) { - return getCachedFiles().get(this.getAbstractFileObjectId()); + if (this.cachedFiles.containsKey(this.getAbstractFileObjectId())) { + return this.cachedFiles.get(this.getAbstractFileObjectId()); } else { - try { - AbstractFile file = this.loadFileFromSleuthkitCase(); - final long id = file.getId(); - this.cachedFiles.put(id, file); - return file; - } catch (Exception e) { - throw e; - } + AbstractFile file = this.loadFileFromSleuthkitCase(); + final long abstractFileId = file.getId(); + this.cachedFiles.put(abstractFileId, file); + return file; } } /** * Implement this in subclasses to find the AbstractFile by whatever means * necessary. This will be called by this.lookupOrLoadAbstractFile. In some - * cases we may have the object id, in other cases we may need to use the - * file name. + * cases we may have the object abstractFileId, in other cases we may need + * to use the file name. * * @return AbstractFile corresponding to this common attribute */ @@ -148,24 +142,6 @@ abstract class AbstractCommonAttributeInstanceNode { return abstractFileObjectId; } - /** - * Set the ObjectId of the AbstractFile that is equaivalent to the file from - * which this common attribute instance - */ - void setAbstractFileObjectId(Long abstractFileObjectId) { - this.abstractFileObjectId = abstractFileObjectId; - } - - /** - * Get the map of AbstractFile which we use to avoid loading the same file - * from the SleuthkitCase more than necessary. - * - * @return the cachedFiles - */ - Map getCachedFiles() { - return Collections.unmodifiableMap(cachedFiles); - } - /** * Use this to create an AbstractCommonAttributeInstanceNode of the * appropriate type. In any case, we'll get something which extends From f03c675cf2e8d0e12a0400ef8b6c711b2d3fe7d5 Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Fri, 20 Jul 2018 14:07:07 -0600 Subject: [PATCH 152/287] notes --- .../InterCaseCommonAttributeSearchResults.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearchResults.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearchResults.java index b6005c333d..46ca88f439 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearchResults.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearchResults.java @@ -64,7 +64,8 @@ final public class InterCaseCommonAttributeSearchResults extends AbstractCommonA SleuthkitCase tskDb = currentCase.getSleuthkitCase(); File fileFromPath = new File(currentFullPath); String fileName = fileFromPath.getName(); - //TODO this seems like a bug - we maybe need to look at all of these not just the first + //TODO this seems like a flaw - we maybe need to look at all of these not just the first + //i think we should search by md5 and return all of them AbstractFile abstractFile = tskDb.findAllFilesWhere(String.format("lower(name) = '%s'", fileName)).get(0); return abstractFile; From 0396a52b528759d2487a3659363950e923b6a1d3 Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Fri, 20 Jul 2018 14:49:49 -0600 Subject: [PATCH 153/287] comments --- .../commonfilesearch/AbstractCommonAttributeInstanceNode.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeInstanceNode.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeInstanceNode.java index d7a8a1cfb5..cc15dced19 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeInstanceNode.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeInstanceNode.java @@ -92,7 +92,7 @@ abstract class AbstractCommonAttributeInstanceNode { /** * Implement this in subclasses to find the AbstractFile by whatever means - * necessary. This will be called by this.lookupOrLoadAbstractFile. In some + * available. This will be called by this.lookupOrLoadAbstractFile. In some * cases we may have the object abstractFileId, in other cases we may need * to use the file name. * From cc0639d1d6ffec29b34dd4918ac4c1dab2c31e06 Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Sat, 21 Jul 2018 08:10:24 -0600 Subject: [PATCH 154/287] cleanup --- .../commonfilesearch/AllIntraCaseCommonAttributeSearcher.java | 2 +- .../commonfilesearch/InterCaseCommonAttributeSearcher.java | 2 +- .../sleuthkit/autopsy/commonfilesearch/InterCasePanel.java | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllIntraCaseCommonAttributeSearcher.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllIntraCaseCommonAttributeSearcher.java index a4237b6679..eed61b0fc1 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllIntraCaseCommonAttributeSearcher.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllIntraCaseCommonAttributeSearcher.java @@ -49,7 +49,7 @@ final public class AllIntraCaseCommonAttributeSearcher extends IntraCaseCommonAt } @Override - protected String buildTabTitle() { + String buildTabTitle() { final String buildCategorySelectionString = this.buildCategorySelectionString(); final String titleTemplate = Bundle.AbstractCommonFilesMetadataBuilder_buildTabTitle_titleIntraAll(); return String.format(titleTemplate, new Object[]{buildCategorySelectionString}); diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearcher.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearcher.java index 7d926ff92d..604dbaece2 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearcher.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearcher.java @@ -36,7 +36,7 @@ import org.sleuthkit.datamodel.HashUtility; */ abstract class InterCaseCommonAttributeSearcher extends AbstractCommonAttributeSearcher { - EamDb dbManager; + private final EamDb dbManager; /** * Implements the algorithm for getting common files across all data sources diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.java index 613c034c31..05a7032252 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.java @@ -27,8 +27,8 @@ import javax.swing.ComboBoxModel; import org.openide.util.NbBundle; /** - * - * @author bsweeney + * UI controls for Common Files Search scenario where the user intends to find + * common files between cases in addition to the present case. */ public class InterCasePanel extends javax.swing.JPanel { From 26987a4c5dbbcb42e357b518e2b04e9913f50594 Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Sat, 21 Jul 2018 08:53:42 -0600 Subject: [PATCH 155/287] polish --- .../IntraCaseCommonAttributeSearchResults.java | 3 ++- .../autopsy/commonfilesearch/IntraCasePanel.java | 6 ++++-- .../SingleInterCaseCommonAttributeSearcher.java | 8 ++------ .../SingleIntraCaseCommonAttributeSearcher.java | 2 +- 4 files changed, 9 insertions(+), 10 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCaseCommonAttributeSearchResults.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCaseCommonAttributeSearchResults.java index 6cd39355ca..ba77d3e2c1 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCaseCommonAttributeSearchResults.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCaseCommonAttributeSearchResults.java @@ -55,7 +55,8 @@ final public class IntraCaseCommonAttributeSearchResults extends AbstractCommonA return Arrays.asList(intraCaseCommonAttributeInstanceNode).toArray(new DisplayableItemNode[1]); } - protected AbstractFile loadFileFromSleuthkitCase() { + @Override + AbstractFile loadFileFromSleuthkitCase() { Case currentCase; try { diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCasePanel.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCasePanel.java index 3daee45ffa..c88537cb17 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCasePanel.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCasePanel.java @@ -19,6 +19,7 @@ */ package org.sleuthkit.autopsy.commonfilesearch; +import java.util.Collections; import java.util.Map; import java.util.Map.Entry; import javax.swing.ComboBoxModel; @@ -69,7 +70,7 @@ public class IntraCasePanel extends javax.swing.JPanel { } public Map getDataSourceMap(){ - return this.dataSourceMap; + return Collections.unmodifiableMap(this.dataSourceMap); } Long getSelectedDataSourceId(){ @@ -196,7 +197,8 @@ public class IntraCasePanel extends javax.swing.JPanel { } void setDataSourceMap(Map dataSourceMap) { - this.dataSourceMap = dataSourceMap; + this.dataSourceMap.clear(); + this.dataSourceMap.putAll(dataSourceMap); } @NbBundle.Messages({ diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/SingleInterCaseCommonAttributeSearcher.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/SingleInterCaseCommonAttributeSearcher.java index 67f4ffc588..9486a9e43c 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/SingleInterCaseCommonAttributeSearcher.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/SingleInterCaseCommonAttributeSearcher.java @@ -20,7 +20,6 @@ package org.sleuthkit.autopsy.commonfilesearch; import java.sql.SQLException; -import java.util.HashMap; import java.util.List; import java.util.Map; import org.sleuthkit.autopsy.casemodule.Case; @@ -73,11 +72,9 @@ public class SingleInterCaseCommonAttributeSearcher extends InterCaseCommonAttri protected CommonAttributeSearchResults findFiles(CorrelationCase correlationCase) throws TskCoreException, NoCurrentCaseException, SQLException, EamDbException { - Map> interCaseCommonFiles = new HashMap<>(); - InterCaseSearchResultsProcessor eamDbAttrInst = new InterCaseSearchResultsProcessor(); eamDbAttrInst.findSingleInterCaseCommonAttributeValues(Case.getCurrentCase(), correlationCase); - interCaseCommonFiles = gatherIntercaseResults(eamDbAttrInst.getIntercaseCommonValuesMap(), eamDbAttrInst.getIntercaseCommonCasesMap()); + Map> interCaseCommonFiles = gatherIntercaseResults(eamDbAttrInst.getIntercaseCommonValuesMap(), eamDbAttrInst.getIntercaseCommonCasesMap()); return new CommonAttributeSearchResults(interCaseCommonFiles); } @@ -88,5 +85,4 @@ public class SingleInterCaseCommonAttributeSearcher extends InterCaseCommonAttri final String titleTemplate = Bundle.AbstractCommonFilesMetadataBuilder_buildTabTitle_titleInterSingle(); return String.format(titleTemplate, new Object[]{correlationCaseName, buildCategorySelectionString}); } - -} +} \ No newline at end of file diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/SingleIntraCaseCommonAttributeSearcher.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/SingleIntraCaseCommonAttributeSearcher.java index 565b5c8d39..02bd480093 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/SingleIntraCaseCommonAttributeSearcher.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/SingleIntraCaseCommonAttributeSearcher.java @@ -59,4 +59,4 @@ final public class SingleIntraCaseCommonAttributeSearcher extends IntraCaseCommo final String titleTemplate = Bundle.AbstractCommonFilesMetadataBuilder_buildTabTitle_titleIntraSingle(); return String.format(titleTemplate, new Object[]{this.dataSourceName, buildCategorySelectionString}); } -} +} \ No newline at end of file From ba24556ac089921b539e6f9c467b7a707f218b1c Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Sat, 21 Jul 2018 09:22:26 -0600 Subject: [PATCH 156/287] cleanup --- .../autopsy/commonfilesearch/CommonAttributeValueNode.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeValueNode.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeValueNode.java index 4c3a2e9fc4..56623bc2af 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeValueNode.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeValueNode.java @@ -134,13 +134,10 @@ public class CommonAttributeValueNode extends DisplayableItemNode { */ static class FileInstanceNodeFactory extends ChildFactory { - //private final Map cachedFiles; - private final CommonAttributeValue descendants; FileInstanceNodeFactory(CommonAttributeValue descendants) { this.descendants = descendants; - //this.cachedFiles = new HashMap<>(); } @Override @@ -154,5 +151,4 @@ public class CommonAttributeValueNode extends DisplayableItemNode { return true; } } - } From 8c9d03ec60eee08098750a1654e00d3b5e3e2d31 Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Sat, 21 Jul 2018 09:41:28 -0600 Subject: [PATCH 157/287] work in progress --- .../autopsy/commonfilessearch/InterCaseUtils.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/InterCaseUtils.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/InterCaseUtils.java index 600cf90eea..1dbc67a180 100644 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/InterCaseUtils.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/InterCaseUtils.java @@ -189,7 +189,7 @@ class InterCaseUtils { } else { //it is reasonable that this might happen... // for example when we test the feature in the absence of an enabled eamdb - return new HashMap(0); + return new HashMap<>(0); } } @@ -295,12 +295,12 @@ class InterCaseUtils { for(Map.Entry> file : searchDomain.getMetadata().entrySet()){ - Collection fileInstances = file.getValue(); + //Collection fileInstances = file.getValue(); - for(IntraCaseCommonAttributeSearchResults fileInstance : fileInstances){ - - - } +// for(IntraCaseCommonAttributeSearchResults fileInstance : fileInstances){ +// +// +// } } return false; From f2c97b80797b2646a1ad013955940063ab275b0a Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Sat, 21 Jul 2018 09:46:54 -0600 Subject: [PATCH 158/287] cleanup --- .../commonfilessearch/IngestedWithHashAndFileType.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileType.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileType.java index a599763346..6114efc739 100644 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileType.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileType.java @@ -30,10 +30,6 @@ import org.openide.util.Exceptions; import org.python.icu.impl.Assert; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; -import org.sleuthkit.autopsy.commonfilesearch.AllDataSourcesCommonFilesAlgorithm; -import org.sleuthkit.autopsy.commonfilesearch.CommonFilesMetadata; -import org.sleuthkit.autopsy.commonfilesearch.CommonFilesMetadataBuilder; -import org.sleuthkit.autopsy.commonfilesearch.SingleDataSource; import static org.sleuthkit.autopsy.commonfilessearch.IntraCaseUtils.*; import org.sleuthkit.autopsy.ingest.IngestJobSettings; import org.sleuthkit.autopsy.ingest.IngestJobSettings.IngestType; From 941ae94b1583fb2cba011978f658e4de4ab233b0 Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Sat, 21 Jul 2018 10:16:19 -0600 Subject: [PATCH 159/287] greater access to tests can see these members --- .../AbstractCommonAttributeInstanceNode.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeInstanceNode.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeInstanceNode.java index cc15dced19..a0735eb617 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeInstanceNode.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeInstanceNode.java @@ -34,7 +34,7 @@ import org.sleuthkit.datamodel.TskCoreException; * multiple types of leaf nodes are required to represent Common Attribute * Instance nodes. */ -abstract class AbstractCommonAttributeInstanceNode { +public abstract class AbstractCommonAttributeInstanceNode { private final Long abstractFileObjectId; private final Map cachedFiles; @@ -122,7 +122,7 @@ abstract class AbstractCommonAttributeInstanceNode { * * @return data source name */ - String getDataSource() { + public String getDataSource() { /** * Even though we could get this from the CR record or the AbstractFile, @@ -138,7 +138,7 @@ abstract class AbstractCommonAttributeInstanceNode { * * @return the abstractFileObjectId */ - Long getAbstractFileObjectId() { + public Long getAbstractFileObjectId() { return abstractFileObjectId; } From 2e0b1e0dca1bdd3d5b3e57bb7c9de5afb0d7240f Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Sat, 21 Jul 2018 10:16:38 -0600 Subject: [PATCH 160/287] these did not merge well --- .../sleuthkit/autopsy/commonfilessearch/IntraCaseUtils.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IntraCaseUtils.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IntraCaseUtils.java index 69abc2810f..634968638f 100644 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IntraCaseUtils.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IntraCaseUtils.java @@ -33,9 +33,9 @@ import org.python.icu.impl.Assert; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.ImageDSProcessor; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; +import org.sleuthkit.autopsy.commonfilesearch.AbstractCommonAttributeInstanceNode; import org.sleuthkit.autopsy.commonfilesearch.CommonAttributeSearchResults; import org.sleuthkit.autopsy.commonfilesearch.DataSourceLoader; -import org.sleuthkit.autopsy.commonfilesearch.IntraCaseCommonAttributeSearchResults; import org.sleuthkit.autopsy.commonfilesearch.CommonAttributeValue; import org.sleuthkit.autopsy.testutils.CaseUtils; import org.sleuthkit.autopsy.testutils.IngestUtils; @@ -207,8 +207,8 @@ class IntraCaseUtils { for (Map.Entry> entry : metadata.getMetadata().entrySet()) { for (CommonAttributeValue md : entry.getValue()) { - for (IntraCaseCommonAttributeSearchResults fim : md.getMetadata()) { - instanceIdToDataSource.put(fim.getObjectId(), fim.getDataSourceName()); + for (AbstractCommonAttributeInstanceNode fim : md.getMetadata()) { + instanceIdToDataSource.put(fim.getAbstractFileObjectId(), fim.getDataSource()); } } } From 2258e368b3d0e33cfd00fba752a4005a53fd2631 Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Sat, 21 Jul 2018 18:11:32 -0600 Subject: [PATCH 161/287] merge/refactor de-conflicting --- .../AbstractCommonAttributeSearcher.java | 4 +- .../IngestedWithHashAndFileType.java | 347 +++++++++--------- ...stedWithHashAndFileTypeInterCaseTests.java | 7 +- .../MatchesInAtLeastTwoSources.java | 25 +- .../NoCentralRepoEnabledInterCaseTests.java | 9 +- 5 files changed, 197 insertions(+), 195 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeSearcher.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeSearcher.java index 0308f60823..09a7e89d5d 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeSearcher.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeSearcher.java @@ -36,7 +36,7 @@ import org.sleuthkit.datamodel.TskCoreException; * Prototype for an object which finds files with common attributes. * Subclass this and implement findFiles in order */ -abstract class AbstractCommonAttributeSearcher { +public abstract class AbstractCommonAttributeSearcher { private boolean filterByMedia; private boolean filterByDoc; @@ -58,7 +58,7 @@ abstract class AbstractCommonAttributeSearcher { * @throws SQLException * @throws EamDbException */ - abstract CommonAttributeSearchResults findFiles() throws TskCoreException, NoCurrentCaseException, SQLException, EamDbException; + public abstract CommonAttributeSearchResults findFiles() throws TskCoreException, NoCurrentCaseException, SQLException, EamDbException; /** * Implement this to create a descriptive string for the tab which will display diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileType.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileType.java index 6114efc739..754e96dd0f 100644 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileType.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileType.java @@ -30,6 +30,11 @@ import org.openide.util.Exceptions; import org.python.icu.impl.Assert; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; +import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException; +import org.sleuthkit.autopsy.commonfilesearch.AbstractCommonAttributeSearcher; +import org.sleuthkit.autopsy.commonfilesearch.AllIntraCaseCommonAttributeSearcher; +import org.sleuthkit.autopsy.commonfilesearch.CommonAttributeSearchResults; +import org.sleuthkit.autopsy.commonfilesearch.SingleIntraCaseCommonAttributeSearcher; import static org.sleuthkit.autopsy.commonfilessearch.IntraCaseUtils.*; import org.sleuthkit.autopsy.ingest.IngestJobSettings; import org.sleuthkit.autopsy.ingest.IngestJobSettings.IngestType; @@ -94,34 +99,34 @@ public class IngestedWithHashAndFileType extends NbTestCase { try { Map dataSources = this.utils.getDataSourceMap(); - CommonFilesMetadataBuilder allSourcesBuilder = new AllDataSourcesCommonFilesAlgorithm(dataSources, false, false); - CommonFilesMetadata metadata = allSourcesBuilder.findCommonFiles(); + AbstractCommonAttributeSearcher allSourcesBuilder = new AllIntraCaseCommonAttributeSearcher(dataSources, false, false); + CommonAttributeSearchResults metadata = allSourcesBuilder.findFiles(); Map objectIdToDataSource = IntraCaseUtils.mapFileInstancesToDataSources(metadata); List files = IntraCaseUtils.getFiles(objectIdToDataSource.keySet()); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, IMG, SET1, 2)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, IMG, SET2, 1)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, IMG, SET3, 1)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, IMG, SET4, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET1, 2)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET2, 1)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET3, 1)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET4, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, DOC, SET1, 1)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, DOC, SET2, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, DOC, SET3, 1)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, DOC, SET4, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, DOC, SET1, 1)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, DOC, SET2, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, DOC, SET3, 1)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, DOC, SET4, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, PDF, SET1, 0)); - assertTrue(IntraCaseUtils.verifyFileExistanceAndCount(files, objectIdToDataSource, PDF, SET2, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, PDF, SET3, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, PDF, SET4, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET1, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET2, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET3, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET4, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, EMPTY, SET1, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, EMPTY, SET2, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, EMPTY, SET3, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, EMPTY, SET4, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET1, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET2, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET3, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET4, 0)); - } catch (NoCurrentCaseException | TskCoreException | SQLException ex) { + } catch (NoCurrentCaseException | TskCoreException | SQLException | EamDbException ex) { Exceptions.printStackTrace(ex); Assert.fail(ex); } @@ -135,34 +140,34 @@ public class IngestedWithHashAndFileType extends NbTestCase { try { Map dataSources = this.utils.getDataSourceMap(); - CommonFilesMetadataBuilder allSourcesBuilder = new AllDataSourcesCommonFilesAlgorithm(dataSources, true, false); - CommonFilesMetadata metadata = allSourcesBuilder.findCommonFiles(); + AbstractCommonAttributeSearcher allSourcesBuilder = new AllIntraCaseCommonAttributeSearcher(dataSources, true, false); + CommonAttributeSearchResults metadata = allSourcesBuilder.findFiles(); Map objectIdToDataSource = mapFileInstancesToDataSources(metadata); List files = getFiles(objectIdToDataSource.keySet()); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, IMG, SET1, 2)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, IMG, SET2, 1)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, IMG, SET3, 1)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, IMG, SET4, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET1, 2)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET2, 1)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET3, 1)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET4, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, DOC, SET1, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, DOC, SET2, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, DOC, SET3, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, DOC, SET4, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, DOC, SET1, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, DOC, SET2, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, DOC, SET3, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, DOC, SET4, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, PDF, SET1, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, PDF, SET2, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, PDF, SET3, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, PDF, SET4, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET1, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET2, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET3, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET4, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, EMPTY, SET1, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, EMPTY, SET2, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, EMPTY, SET3, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, EMPTY, SET4, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET1, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET2, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET3, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET4, 0)); - } catch (NoCurrentCaseException | TskCoreException | SQLException ex) { + } catch (NoCurrentCaseException | TskCoreException | SQLException | EamDbException ex) { Exceptions.printStackTrace(ex); Assert.fail(ex); } @@ -176,34 +181,34 @@ public class IngestedWithHashAndFileType extends NbTestCase { try { Map dataSources = this.utils.getDataSourceMap(); - CommonFilesMetadataBuilder allSourcesBuilder = new AllDataSourcesCommonFilesAlgorithm(dataSources, false, true); - CommonFilesMetadata metadata = allSourcesBuilder.findCommonFiles(); + AbstractCommonAttributeSearcher allSourcesBuilder = new AllIntraCaseCommonAttributeSearcher(dataSources, false, true); + CommonAttributeSearchResults metadata = allSourcesBuilder.findFiles(); Map objectIdToDataSource = mapFileInstancesToDataSources(metadata); List files = getFiles(objectIdToDataSource.keySet()); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, IMG, SET1, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, IMG, SET2, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, IMG, SET3, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, IMG, SET4, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET1, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET2, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET3, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET4, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, DOC, SET1, 1)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, DOC, SET2, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, DOC, SET3, 1)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, DOC, SET4, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, DOC, SET1, 1)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, DOC, SET2, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, DOC, SET3, 1)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, DOC, SET4, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, PDF, SET1, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, PDF, SET2, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, PDF, SET3, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, PDF, SET4, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET1, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET2, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET3, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET4, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, EMPTY, SET1, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, EMPTY, SET2, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, EMPTY, SET3, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, EMPTY, SET4, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET1, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET2, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET3, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET4, 0)); - } catch (NoCurrentCaseException | TskCoreException | SQLException ex) { + } catch (NoCurrentCaseException | TskCoreException | SQLException | EamDbException ex) { Exceptions.printStackTrace(ex); Assert.fail(ex); } @@ -218,34 +223,34 @@ public class IngestedWithHashAndFileType extends NbTestCase { Map dataSources = this.utils.getDataSourceMap(); Long first = getDataSourceIdByName(SET1, dataSources); - CommonFilesMetadataBuilder singleSourceBuilder = new SingleDataSource(first, dataSources, false, false); - CommonFilesMetadata metadata = singleSourceBuilder.findCommonFiles(); + AbstractCommonAttributeSearcher singleSourceBuilder = new SingleIntraCaseCommonAttributeSearcher(first, dataSources, false, false); + CommonAttributeSearchResults metadata = singleSourceBuilder.findFiles(); Map objectIdToDataSource = mapFileInstancesToDataSources(metadata); List files = getFiles(objectIdToDataSource.keySet()); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, IMG, SET1, 2)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, IMG, SET2, 1)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, IMG, SET3, 1)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, IMG, SET4, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET1, 2)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET2, 1)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET3, 1)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET4, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, DOC, SET1, 1)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, DOC, SET2, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, DOC, SET3, 1)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, DOC, SET4, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, DOC, SET1, 1)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, DOC, SET2, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, DOC, SET3, 1)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, DOC, SET4, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, PDF, SET1, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, PDF, SET2, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, PDF, SET3, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, PDF, SET4, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET1, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET2, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET3, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET4, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, EMPTY, SET1, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, EMPTY, SET2, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, EMPTY, SET3, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, EMPTY, SET4, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET1, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET2, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET3, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET4, 0)); - } catch (NoCurrentCaseException | TskCoreException | SQLException ex) { + } catch (NoCurrentCaseException | TskCoreException | SQLException | EamDbException ex) { Exceptions.printStackTrace(ex); Assert.fail(ex); } @@ -260,34 +265,34 @@ public class IngestedWithHashAndFileType extends NbTestCase { Map dataSources = this.utils.getDataSourceMap(); Long first = getDataSourceIdByName(SET1, dataSources); - CommonFilesMetadataBuilder singleSourceBuilder = new SingleDataSource(first, dataSources, true, false); - CommonFilesMetadata metadata = singleSourceBuilder.findCommonFiles(); + AbstractCommonAttributeSearcher singleSourceBuilder = new SingleIntraCaseCommonAttributeSearcher(first, dataSources, true, false); + CommonAttributeSearchResults metadata = singleSourceBuilder.findFiles(); Map objectIdToDataSource = mapFileInstancesToDataSources(metadata); List files = getFiles(objectIdToDataSource.keySet()); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, IMG, SET1, 2)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, IMG, SET2, 1)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, IMG, SET3, 1)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, IMG, SET4, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET1, 2)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET2, 1)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET3, 1)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET4, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, DOC, SET1, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, DOC, SET2, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, DOC, SET3, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, DOC, SET4, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, DOC, SET1, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, DOC, SET2, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, DOC, SET3, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, DOC, SET4, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, PDF, SET1, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, PDF, SET2, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, PDF, SET3, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, PDF, SET4, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET1, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET2, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET3, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET4, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, EMPTY, SET1, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, EMPTY, SET2, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, EMPTY, SET3, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, EMPTY, SET4, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET1, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET2, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET3, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET4, 0)); - } catch (NoCurrentCaseException | TskCoreException | SQLException ex) { + } catch (NoCurrentCaseException | TskCoreException | SQLException | EamDbException ex) { Exceptions.printStackTrace(ex); Assert.fail(ex); } @@ -302,34 +307,34 @@ public class IngestedWithHashAndFileType extends NbTestCase { Map dataSources = this.utils.getDataSourceMap(); Long first = getDataSourceIdByName(SET1, dataSources); - CommonFilesMetadataBuilder singleSourceBuilder = new SingleDataSource(first, dataSources, false, true); - CommonFilesMetadata metadata = singleSourceBuilder.findCommonFiles(); + AbstractCommonAttributeSearcher singleSourceBuilder = new SingleIntraCaseCommonAttributeSearcher(first, dataSources, false, true); + CommonAttributeSearchResults metadata = singleSourceBuilder.findFiles(); Map objectIdToDataSource = mapFileInstancesToDataSources(metadata); List files = getFiles(objectIdToDataSource.keySet()); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, IMG, SET1, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, IMG, SET2, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, IMG, SET3, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, IMG, SET4, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET1, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET2, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET3, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET4, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, DOC, SET1, 1)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, DOC, SET2, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, DOC, SET3, 1)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, DOC, SET4, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, DOC, SET1, 1)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, DOC, SET2, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, DOC, SET3, 1)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, DOC, SET4, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, PDF, SET1, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, PDF, SET2, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, PDF, SET3, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, PDF, SET4, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET1, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET2, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET3, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET4, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, EMPTY, SET1, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, EMPTY, SET2, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, EMPTY, SET3, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, EMPTY, SET4, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET1, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET2, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET3, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET4, 0)); - } catch (NoCurrentCaseException | TskCoreException | SQLException ex) { + } catch (NoCurrentCaseException | TskCoreException | SQLException | EamDbException ex) { Exceptions.printStackTrace(ex); Assert.fail(ex); } @@ -344,34 +349,34 @@ public class IngestedWithHashAndFileType extends NbTestCase { Map dataSources = this.utils.getDataSourceMap(); Long second = getDataSourceIdByName(SET2, dataSources); - CommonFilesMetadataBuilder singleSourceBuilder = new SingleDataSource(second, dataSources, false, false); - CommonFilesMetadata metadata = singleSourceBuilder.findCommonFiles(); + AbstractCommonAttributeSearcher singleSourceBuilder = new SingleIntraCaseCommonAttributeSearcher(second, dataSources, false, false); + CommonAttributeSearchResults metadata = singleSourceBuilder.findFiles(); Map objectIdToDataSource = mapFileInstancesToDataSources(metadata); List files = getFiles(objectIdToDataSource.keySet()); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, IMG, SET1, 2)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, IMG, SET2, 1)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, IMG, SET3, 1)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, IMG, SET4, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET1, 2)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET2, 1)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET3, 1)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET4, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, DOC, SET1, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, DOC, SET2, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, DOC, SET3, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, DOC, SET4, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, DOC, SET1, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, DOC, SET2, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, DOC, SET3, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, DOC, SET4, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, PDF, SET1, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, PDF, SET2, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, PDF, SET3, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, PDF, SET4, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET1, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET2, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET3, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET4, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, EMPTY, SET1, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, EMPTY, SET2, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, EMPTY, SET3, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, EMPTY, SET4, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET1, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET2, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET3, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET4, 0)); - } catch (NoCurrentCaseException | TskCoreException | SQLException ex) { + } catch (NoCurrentCaseException | TskCoreException | SQLException | EamDbException ex) { Exceptions.printStackTrace(ex); Assert.fail(ex); } @@ -385,34 +390,34 @@ public class IngestedWithHashAndFileType extends NbTestCase { Map dataSources = this.utils.getDataSourceMap(); Long last = getDataSourceIdByName(SET4, dataSources); - CommonFilesMetadataBuilder singleSourceBuilder = new SingleDataSource(last, dataSources, false, false); - CommonFilesMetadata metadata = singleSourceBuilder.findCommonFiles(); + AbstractCommonAttributeSearcher singleSourceBuilder = new SingleIntraCaseCommonAttributeSearcher(last, dataSources, false, false); + CommonAttributeSearchResults metadata = singleSourceBuilder.findFiles(); Map objectIdToDataSource = mapFileInstancesToDataSources(metadata); List files = getFiles(objectIdToDataSource.keySet()); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, IMG, SET1, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, IMG, SET2, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, IMG, SET3, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, IMG, SET4, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET1, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET2, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET3, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET4, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, DOC, SET1, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, DOC, SET1, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, DOC, SET3, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, DOC, SET4, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, DOC, SET1, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, DOC, SET1, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, DOC, SET3, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, DOC, SET4, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, PDF, SET1, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, PDF, SET2, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, PDF, SET3, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, PDF, SET4, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET1, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET2, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET3, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET4, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, EMPTY, SET1, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, EMPTY, SET2, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, EMPTY, SET3, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, EMPTY, SET4, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET1, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET2, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET3, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET4, 0)); - } catch (NoCurrentCaseException | TskCoreException | SQLException ex) { + } catch (NoCurrentCaseException | TskCoreException | SQLException | EamDbException ex) { Exceptions.printStackTrace(ex); Assert.fail(ex); } @@ -426,34 +431,34 @@ public class IngestedWithHashAndFileType extends NbTestCase { Map dataSources = this.utils.getDataSourceMap(); Long third = getDataSourceIdByName(SET3, dataSources); - CommonFilesMetadataBuilder singleSourceBuilder = new SingleDataSource(third, dataSources, false, false); - CommonFilesMetadata metadata = singleSourceBuilder.findCommonFiles(); + AbstractCommonAttributeSearcher singleSourceBuilder = new SingleIntraCaseCommonAttributeSearcher(third, dataSources, false, false); + CommonAttributeSearchResults metadata = singleSourceBuilder.findFiles(); Map objectIdToDataSource = mapFileInstancesToDataSources(metadata); List files = getFiles(objectIdToDataSource.keySet()); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, IMG, SET1, 2)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, IMG, SET2, 1)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, IMG, SET3, 1)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, IMG, SET4, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET1, 2)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET2, 1)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET3, 1)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET4, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, DOC, SET1, 1)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, DOC, SET2, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, DOC, SET3, 1)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, DOC, SET4, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, DOC, SET1, 1)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, DOC, SET2, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, DOC, SET3, 1)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, DOC, SET4, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, PDF, SET1, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, PDF, SET2, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, PDF, SET3, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, PDF, SET4, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET1, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET2, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET3, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET4, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, EMPTY, SET1, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, EMPTY, SET2, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, EMPTY, SET3, 0)); - assertTrue(verifyFileExistanceAndCount(files, objectIdToDataSource, EMPTY, SET4, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET1, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET2, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET3, 0)); + assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET4, 0)); - } catch (NoCurrentCaseException | TskCoreException | SQLException ex) { + } catch (NoCurrentCaseException | TskCoreException | SQLException | EamDbException ex) { Exceptions.printStackTrace(ex); Assert.fail(ex); } diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileTypeInterCaseTests.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileTypeInterCaseTests.java index c16347c855..411f7cda19 100644 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileTypeInterCaseTests.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileTypeInterCaseTests.java @@ -19,16 +19,15 @@ */ package org.sleuthkit.autopsy.commonfilessearch; -import java.util.Map; import junit.framework.Test; import org.netbeans.junit.NbModuleSuite; import org.netbeans.junit.NbTestCase; import org.openide.util.Exceptions; import org.python.icu.impl.Assert; import org.sleuthkit.autopsy.casemodule.Case; +import org.sleuthkit.autopsy.commonfilesearch.AbstractCommonAttributeSearcher; import org.sleuthkit.autopsy.commonfilesearch.AllInterCaseCommonAttributeSearcher; import org.sleuthkit.autopsy.commonfilesearch.CommonAttributeSearchResults; -import org.sleuthkit.autopsy.commonfilesearch.IntraCaseCommonAttributeSearcher; /** * If I use the search all cases option: One node for Hash A (1_1_A.jpg, @@ -79,10 +78,8 @@ public class IngestedWithHashAndFileTypeInterCaseTests extends NbTestCase { */ public void testOne() { try { - //this is proabbly not needed and should be pulled out of the constructor if possible - Map dataSources = this.utils.getDataSourceMap(); - IntraCaseCommonAttributeSearcher builder = new AllInterCaseCommonAttributeSearcher(dataSources, false, false); + AbstractCommonAttributeSearcher builder = new AllInterCaseCommonAttributeSearcher(false, false); CommonAttributeSearchResults metadata = builder.findFiles(); diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/MatchesInAtLeastTwoSources.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/MatchesInAtLeastTwoSources.java index ba178a59f6..4f5fbee9fb 100644 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/MatchesInAtLeastTwoSources.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/MatchesInAtLeastTwoSources.java @@ -31,9 +31,10 @@ import org.python.icu.impl.Assert; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.ImageDSProcessor; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; -import org.sleuthkit.autopsy.commonfilesearch.AllDataSourcesCommonFilesAlgorithm; -import org.sleuthkit.autopsy.commonfilesearch.CommonFilesMetadata; -import org.sleuthkit.autopsy.commonfilesearch.CommonFilesMetadataBuilder; +import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException; +import org.sleuthkit.autopsy.commonfilesearch.AbstractCommonAttributeSearcher; +import org.sleuthkit.autopsy.commonfilesearch.AllIntraCaseCommonAttributeSearcher; +import org.sleuthkit.autopsy.commonfilesearch.CommonAttributeSearchResults; import static org.sleuthkit.autopsy.commonfilessearch.IntraCaseUtils.*; import org.sleuthkit.autopsy.ingest.IngestJobSettings; import org.sleuthkit.autopsy.ingest.IngestModuleTemplate; @@ -104,23 +105,23 @@ public class MatchesInAtLeastTwoSources extends NbTestCase { try { Map dataSources = this.utils.getDataSourceMap(); - CommonFilesMetadataBuilder allSourcesBuilder = new AllDataSourcesCommonFilesAlgorithm(dataSources, false, false); - CommonFilesMetadata metadata = allSourcesBuilder.findCommonFiles(); + AbstractCommonAttributeSearcher allSourcesBuilder = new AllIntraCaseCommonAttributeSearcher(dataSources, false, false); + CommonAttributeSearchResults metadata = allSourcesBuilder.findFiles(); Map objectIdToDataSource = IntraCaseUtils.mapFileInstancesToDataSources(metadata); List files = IntraCaseUtils.getFiles(objectIdToDataSource.keySet()); - assertTrue(IntraCaseUtils.verifyFileExistanceAndCount(files, dataSources, IMG, SET1, 0)); - assertTrue(IntraCaseUtils.verifyFileExistanceAndCount(files, dataSources, IMG, SET4, 0)); + assertTrue(IntraCaseUtils.verifyInstanceExistanceAndCount(files, dataSources, IMG, SET1, 0)); + assertTrue(IntraCaseUtils.verifyInstanceExistanceAndCount(files, dataSources, IMG, SET4, 0)); - assertTrue(IntraCaseUtils.verifyFileExistanceAndCount(files, dataSources, DOC, SET1, 0)); - assertTrue(IntraCaseUtils.verifyFileExistanceAndCount(files, dataSources, DOC, SET4, 0)); + assertTrue(IntraCaseUtils.verifyInstanceExistanceAndCount(files, dataSources, DOC, SET1, 0)); + assertTrue(IntraCaseUtils.verifyInstanceExistanceAndCount(files, dataSources, DOC, SET4, 0)); - assertTrue(IntraCaseUtils.verifyFileExistanceAndCount(files, dataSources, EMPTY, SET1, 0)); - assertTrue(IntraCaseUtils.verifyFileExistanceAndCount(files, dataSources, EMPTY, SET4, 0)); + assertTrue(IntraCaseUtils.verifyInstanceExistanceAndCount(files, dataSources, EMPTY, SET1, 0)); + assertTrue(IntraCaseUtils.verifyInstanceExistanceAndCount(files, dataSources, EMPTY, SET4, 0)); - } catch (NoCurrentCaseException | TskCoreException | SQLException ex) { + } catch (NoCurrentCaseException | TskCoreException | SQLException | EamDbException ex) { Exceptions.printStackTrace(ex); Assert.fail(ex); } diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/NoCentralRepoEnabledInterCaseTests.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/NoCentralRepoEnabledInterCaseTests.java index 048bd5a81e..03b12c83c3 100644 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/NoCentralRepoEnabledInterCaseTests.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/NoCentralRepoEnabledInterCaseTests.java @@ -19,7 +19,6 @@ */ package org.sleuthkit.autopsy.commonfilessearch; -import java.util.Map; import junit.framework.Test; import org.netbeans.junit.NbModuleSuite; import org.netbeans.junit.NbTestCase; @@ -27,9 +26,9 @@ import org.openide.util.Exceptions; import org.sleuthkit.datamodel.TskCoreException; import org.python.icu.impl.Assert; import org.sleuthkit.autopsy.casemodule.Case; +import org.sleuthkit.autopsy.commonfilesearch.AbstractCommonAttributeSearcher; import org.sleuthkit.autopsy.commonfilesearch.AllInterCaseCommonAttributeSearcher; import org.sleuthkit.autopsy.commonfilesearch.CommonAttributeSearchResults; -import org.sleuthkit.autopsy.commonfilesearch.IntraCaseCommonAttributeSearcher; /** * @@ -41,6 +40,8 @@ import org.sleuthkit.autopsy.commonfilesearch.IntraCaseCommonAttributeSearcher; public class NoCentralRepoEnabledInterCaseTests extends NbTestCase { private final InterCaseUtils utils; + + private Case currentCase; public static Test suite() { NbModuleSuite.Configuration conf = NbModuleSuite.createConfiguration(NoCentralRepoEnabledInterCaseTests.class). @@ -71,9 +72,7 @@ public class NoCentralRepoEnabledInterCaseTests extends NbTestCase { public void testOne() { try { - Map dataSources = this.utils.getDataSourceMap(); - - IntraCaseCommonAttributeSearcher builder = new AllInterCaseCommonAttributeSearcher(dataSources, false, false); + AbstractCommonAttributeSearcher builder = new AllInterCaseCommonAttributeSearcher(false, false); CommonAttributeSearchResults metadata = builder.findFiles(); From 086e57551b7f8e060905640029ddbe44b9c3925f Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Mon, 23 Jul 2018 09:39:52 -0600 Subject: [PATCH 162/287] notes --- .../InterCaseCommonAttributeSearchResults.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearchResults.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearchResults.java index 46ca88f439..90107d6dc0 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearchResults.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearchResults.java @@ -64,8 +64,8 @@ final public class InterCaseCommonAttributeSearchResults extends AbstractCommonA SleuthkitCase tskDb = currentCase.getSleuthkitCase(); File fileFromPath = new File(currentFullPath); String fileName = fileFromPath.getName(); - //TODO this seems like a flaw - we maybe need to look at all of these not just the first - //i think we should search by md5 and return all of them + //TODO this seems like a flaw + //i think we should search by md5, name and file path AbstractFile abstractFile = tskDb.findAllFilesWhere(String.format("lower(name) = '%s'", fileName)).get(0); return abstractFile; From 3b8788c952d55dbed81852167855aaa38199393d Mon Sep 17 00:00:00 2001 From: rishwanth1995 Date: Mon, 23 Jul 2018 11:58:59 -0400 Subject: [PATCH 163/287] live_usb warning --- .../casemodule/NewCaseVisualPanel1.java | 5 +++ .../autopsy/coreutils/PathValidator.java | 31 +++++++++++++++++-- 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/NewCaseVisualPanel1.java b/Core/src/org/sleuthkit/autopsy/casemodule/NewCaseVisualPanel1.java index 6f365af86e..6959883de1 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/NewCaseVisualPanel1.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/NewCaseVisualPanel1.java @@ -155,6 +155,11 @@ final class NewCaseVisualPanel1 extends JPanel implements DocumentListener { caseParentDirWarningLabel.setVisible(true); caseParentDirWarningLabel.setText(NbBundle.getMessage(this.getClass(), "NewCaseVisualPanel1.CaseFolderOnCDriveError.text")); } + + if(!PathValidator.isCasedataPersistable(parentDir)){ + caseParentDirWarningLabel.setVisible(true); + caseParentDirWarningLabel.setText("Please make the case directory in a mounted drive to save case progress"); + } /** * Enable the "Next" button for the wizard if there is text entered for diff --git a/Core/src/org/sleuthkit/autopsy/coreutils/PathValidator.java b/Core/src/org/sleuthkit/autopsy/coreutils/PathValidator.java index 41b5c19d62..41d557c42a 100644 --- a/Core/src/org/sleuthkit/autopsy/coreutils/PathValidator.java +++ b/Core/src/org/sleuthkit/autopsy/coreutils/PathValidator.java @@ -29,6 +29,7 @@ import org.sleuthkit.autopsy.casemodule.Case; public final class PathValidator { private static final Pattern driveLetterPattern = Pattern.compile("^[Cc]:.*$"); + private static final Pattern unixMediaDrivePattern = Pattern.compile("^\\/(media|mnt)\\/.*$"); public static boolean isValid(String path, Case.CaseType caseType) { @@ -39,11 +40,37 @@ public final class PathValidator { } } else { // single user case - no validation needed - } + } return true; } - + + public static boolean isCasedataPersistable(String path) { + if(checkForLiveAutopsy()) { + if(PlatformUtil.isWindowsOS()) { + if(pathOnCDrive(path)){ + return false; + } + }else if(System.getProperty("os.name").toLowerCase().contains("nux")){ + if(!pathIsMedia(path)){ + return false; + } + } + } + return true; + } + + private static boolean checkForLiveAutopsy() { + + String envValue = System.getenv("AUTOPSY_LIVE_TRIAGE"); + return "True".equals(envValue); + } + + private static boolean pathIsMedia(String filePath) { + Matcher m = unixMediaDrivePattern.matcher(filePath); + return m.find(); + } + /** * Checks whether a file path contains drive letter defined by pattern. * From 9d04ef439ee2099417607675b5102dd5eefdbafe Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Mon, 23 Jul 2018 10:38:30 -0600 Subject: [PATCH 164/287] names/comments --- .../CommonAttributeSearchResultNode.java | 6 +-- .../CommonAttributeSearchResults.java | 48 +++++++++++-------- .../commonfilessearch/InterCaseUtils.java | 6 +-- .../commonfilessearch/IntraCaseUtils.java | 2 +- 4 files changed, 33 insertions(+), 29 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeSearchResultNode.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeSearchResultNode.java index 334cebe68b..4a8e435d3c 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeSearchResultNode.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeSearchResultNode.java @@ -77,14 +77,14 @@ final public class CommonAttributeSearchResultNode extends DisplayableItemNode { @Override protected boolean createKeys(List list) { - list.addAll(this.metadata.getMetadata().keySet()); + list.addAll(this.metadata.getValues().keySet()); return true; } @Override protected Node createNodeForKey(Integer instanceCount){ - List md5Metadata = this.metadata.getMetadataForMd5(instanceCount); + List md5Metadata = this.metadata.getValuesByChildSize(instanceCount); return new InstanceCountNode(instanceCount, md5Metadata); - } + } } } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeSearchResults.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeSearchResults.java index 58fa884516..d38c86d96e 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeSearchResults.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeSearchResults.java @@ -29,45 +29,51 @@ import java.util.Map; */ final public class CommonAttributeSearchResults { - private final Map> metadata; + private final Map> values; /** - * Create a metadata object which can be handed off to the node - * factories. + * Create a values object which can be handed off to the node factories. * - * @param metadata list of CommonAttributeValue indexed by size of CommonAttributeValue + * @param values list of CommonAttributeValue indexed by size of + * CommonAttributeValue */ - CommonAttributeSearchResults(Map> metadata){ - this.metadata = metadata; + CommonAttributeSearchResults(Map> values){ + this.values = values; } /** - * Find the meta data for the given md5. + * Find the child node whose children have the specified number of children. * * This is a convenience method - you can also iterate over - * getMetadata(). + * getValues(). * - * @param md5 key - * @return + * @param isntanceCound key + * @return list of values which represent matches */ - List getMetadataForMd5(Integer instanceCount) { - return this.metadata.get(instanceCount); - } - - public Map> getMetadata() { - return Collections.unmodifiableMap(this.metadata); + List getValuesByChildSize(Integer instanceCount) { + return this.values.get(instanceCount); } /** - * How many distinct file instances exist for this metadata? - * @return number of file instances + * Get an unmodifiable collection of values, indexed by number of + * grandchildren, which represents the common attributes found in the + * search. + * @return map of sizes of children to list of matches + */ + public Map> getValues() { + return Collections.unmodifiableMap(this.values); + } + + /** + * How many distinct common files exist for this search results? + * @return number of common files */ public int size() { int count = 0; - for (List data : this.metadata.values()) { - for(CommonAttributeValue md5 : data){ - count += md5.size(); + for (List data : this.values.values()) { + for(CommonAttributeValue value : data){ + count += value.size(); } } return count; diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/InterCaseUtils.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/InterCaseUtils.java index 1dbc67a180..5bc7ac8b72 100644 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/InterCaseUtils.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/InterCaseUtils.java @@ -25,7 +25,6 @@ import java.nio.file.Path; import java.nio.file.Paths; import java.sql.SQLException; import java.util.ArrayList; -import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -52,7 +51,6 @@ import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationCase; import org.sleuthkit.autopsy.centralrepository.datamodel.EamDb; import org.sleuthkit.autopsy.commonfilesearch.CommonAttributeSearchResults; import org.sleuthkit.autopsy.commonfilesearch.DataSourceLoader; -import org.sleuthkit.autopsy.commonfilesearch.IntraCaseCommonAttributeSearchResults; import org.sleuthkit.autopsy.commonfilesearch.CommonAttributeValue; /** @@ -243,7 +241,7 @@ class InterCaseUtils { String lastCaseName = null; Path[] lastPathsForCase = null; - //iterate over the collecitons above, creating cases, and storing + //iterate over the collections above, creating cases, and storing // just one of them for future reference for (int i = 0; i < cases.length; i++) { String caseName = cases[i]; @@ -293,7 +291,7 @@ class InterCaseUtils { int tally = 0; - for(Map.Entry> file : searchDomain.getMetadata().entrySet()){ + for(Map.Entry> file : searchDomain.getValues().entrySet()){ //Collection fileInstances = file.getValue(); diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IntraCaseUtils.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IntraCaseUtils.java index 634968638f..cae0b4d828 100644 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IntraCaseUtils.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IntraCaseUtils.java @@ -205,7 +205,7 @@ class IntraCaseUtils { static Map mapFileInstancesToDataSources(CommonAttributeSearchResults metadata) { Map instanceIdToDataSource = new HashMap<>(); - for (Map.Entry> entry : metadata.getMetadata().entrySet()) { + for (Map.Entry> entry : metadata.getValues().entrySet()) { for (CommonAttributeValue md : entry.getValue()) { for (AbstractCommonAttributeInstanceNode fim : md.getMetadata()) { instanceIdToDataSource.put(fim.getAbstractFileObjectId(), fim.getDataSource()); From 5fad7ae67bf153cae734556c6dd61e05bb163b71 Mon Sep 17 00:00:00 2001 From: Brian Carrier Date: Mon, 23 Jul 2018 12:55:04 -0400 Subject: [PATCH 165/287] minor refactor. No logic changes --- ... AbstractCommonAttributeSearchResult.java} | 7 ++-- .../AbstractCommonAttributeSearcher.java | 2 +- .../CommonAttributePanel.form | 3 -- .../CommonAttributePanel.java | 4 +- ... CommonAttributeSearchResultRootNode.java} | 25 ++++++------ .../CommonAttributeSearchResults.java | 19 ++++----- .../CommonAttributeValue.java | 25 +++++++----- .../CommonAttributeValueNode.java | 37 ++++++++--------- .../commonfilesearch/InstanceCountNode.java | 40 ++++++++++--------- ...InterCaseCommonAttributeSearchResult.java} | 12 ++++-- .../InterCaseCommonAttributeSearcher.java | 26 +++++++----- .../InterCaseSearchResultsProcessor.java | 2 + ...IntraCaseCommonAttributeSearchResults.java | 2 +- .../datamodel/DisplayableItemNodeVisitor.java | 6 +-- .../commonfilessearch/IntraCaseUtils.java | 4 +- 15 files changed, 116 insertions(+), 98 deletions(-) rename Core/src/org/sleuthkit/autopsy/commonfilesearch/{AbstractCommonAttributeInstanceNode.java => AbstractCommonAttributeSearchResult.java} (97%) rename Core/src/org/sleuthkit/autopsy/commonfilesearch/{CommonAttributeSearchResultNode.java => CommonAttributeSearchResultRootNode.java} (72%) rename Core/src/org/sleuthkit/autopsy/commonfilesearch/{InterCaseCommonAttributeSearchResults.java => InterCaseCommonAttributeSearchResult.java} (88%) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeInstanceNode.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeSearchResult.java similarity index 97% rename from Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeInstanceNode.java rename to Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeSearchResult.java index a0735eb617..6efb525b35 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeInstanceNode.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeSearchResult.java @@ -34,9 +34,10 @@ import org.sleuthkit.datamodel.TskCoreException; * multiple types of leaf nodes are required to represent Common Attribute * Instance nodes. */ -public abstract class AbstractCommonAttributeInstanceNode { +public abstract class AbstractCommonAttributeSearchResult { private final Long abstractFileObjectId; + // maps object ID to file private final Map cachedFiles; private final String caseName; private final String dataSource; @@ -51,7 +52,7 @@ public abstract class AbstractCommonAttributeInstanceNode { * @param dataSource datasource where this attribute appears * @param caseName case where this attribute appears */ - AbstractCommonAttributeInstanceNode(Long abstractFileReference, Map cachedFiles, String dataSource, String caseName) { + AbstractCommonAttributeSearchResult(Long abstractFileReference, Map cachedFiles, String dataSource, String caseName) { this.abstractFileObjectId = abstractFileReference; this.cachedFiles = cachedFiles; this.caseName = caseName; @@ -65,7 +66,7 @@ public abstract class AbstractCommonAttributeInstanceNode { * @param cachedFiles storage for abstract files which have been used * already so we can avoid extra roundtrips to the case db */ - AbstractCommonAttributeInstanceNode(Map cachedFiles) { + AbstractCommonAttributeSearchResult(Map cachedFiles) { this.abstractFileObjectId = -1L; this.cachedFiles = cachedFiles; this.caseName = ""; diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeSearcher.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeSearcher.java index 09a7e89d5d..fb8cbd312d 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeSearcher.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeSearcher.java @@ -97,7 +97,7 @@ public abstract class AbstractCommonAttributeSearcher { //collate matches by number of matching instances - doing this in sql doesnt seem efficient Map> instanceCollatedCommonFiles = new TreeMap<>(); for(CommonAttributeValue md5Metadata : commonFiles.values()){ - Integer size = md5Metadata.size(); + Integer size = md5Metadata.getInstanceCount(); if(instanceCollatedCommonFiles.containsKey(size)){ instanceCollatedCommonFiles.get(size).add(md5Metadata); diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributePanel.form b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributePanel.form index 601366d8f0..c08c3c2d78 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributePanel.form +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributePanel.form @@ -11,9 +11,6 @@ - - - diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributePanel.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributePanel.java index 24f1352598..c83876f3ce 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributePanel.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributePanel.java @@ -185,9 +185,9 @@ public final class CommonAttributePanel extends javax.swing.JDialog { CommonAttributeSearchResults metadata = this.get(); - CommonAttributeSearchResultNode commonFilesNode = new CommonAttributeSearchResultNode(metadata); + CommonAttributeSearchResultRootNode commonFilesNode = new CommonAttributeSearchResultRootNode(metadata); - // #VIK-3969 + // -3969 DataResultFilterNode dataResultFilterNode = new DataResultFilterNode(commonFilesNode, ExplorerManager.find(CommonAttributePanel.this)); TableFilterNode tableFilterWithDescendantsNode = new TableFilterNode(dataResultFilterNode, 3); diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeSearchResultNode.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeSearchResultRootNode.java similarity index 72% rename from Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeSearchResultNode.java rename to Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeSearchResultRootNode.java index 334cebe68b..066a780afb 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeSearchResultNode.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeSearchResultRootNode.java @@ -27,13 +27,14 @@ import org.sleuthkit.autopsy.datamodel.DisplayableItemNode; import org.sleuthkit.autopsy.datamodel.DisplayableItemNodeVisitor; /** - * Wrapper node for Md5Node used to display common files search - * results in the top right pane. Calls InstanceCountNodeFactory. + * Top-level node to store common file search results. Current structure is: + * - node for number of matches + * -- node for MD5/commmon attribute + * --- node for instance. */ -final public class CommonAttributeSearchResultNode extends DisplayableItemNode { - +final public class CommonAttributeSearchResultRootNode extends DisplayableItemNode { - CommonAttributeSearchResultNode(CommonAttributeSearchResults metadataList) { + CommonAttributeSearchResultRootNode(CommonAttributeSearchResults metadataList) { super(Children.create(new InstanceCountNodeFactory(metadataList), true)); } @@ -64,27 +65,27 @@ final public class CommonAttributeSearchResultNode extends DisplayableItemNode { */ static class InstanceCountNodeFactory extends ChildFactory{ - private final CommonAttributeSearchResults metadata; + private final CommonAttributeSearchResults searchResults; /** * Build a factory which converts a CommonAttributeSearchResults * object into DisplayableItemNodes. - * @param metadata + * @param searchResults */ - InstanceCountNodeFactory(CommonAttributeSearchResults metadata){ - this.metadata = metadata; + InstanceCountNodeFactory(CommonAttributeSearchResults searchResults){ + this.searchResults = searchResults; } @Override protected boolean createKeys(List list) { - list.addAll(this.metadata.getMetadata().keySet()); + list.addAll(this.searchResults.getMetadata().keySet()); return true; } @Override protected Node createNodeForKey(Integer instanceCount){ - List md5Metadata = this.metadata.getMetadataForMd5(instanceCount); - return new InstanceCountNode(instanceCount, md5Metadata); + List attributeValues = this.searchResults.getAttributeValuesForInstanceCount(instanceCount); + return new InstanceCountNode(instanceCount, attributeValues); } } } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeSearchResults.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeSearchResults.java index 58fa884516..b46cde1316 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeSearchResults.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeSearchResults.java @@ -24,12 +24,13 @@ import java.util.List; import java.util.Map; /** - * Utility and wrapper model around data required for Common Files Search results. - * Subclass this to implement different selections of files from the case. + * Stores the results from the various types of common attribute searching + * Stores results based on how they are currently displayed in the UI */ final public class CommonAttributeSearchResults { - private final Map> metadata; + // maps instance count to list of attribute values. + private final Map> instanceCountToAttributeValues; /** * Create a metadata object which can be handed off to the node @@ -38,7 +39,7 @@ final public class CommonAttributeSearchResults { * @param metadata list of CommonAttributeValue indexed by size of CommonAttributeValue */ CommonAttributeSearchResults(Map> metadata){ - this.metadata = metadata; + this.instanceCountToAttributeValues = metadata; } /** @@ -50,12 +51,12 @@ final public class CommonAttributeSearchResults { * @param md5 key * @return */ - List getMetadataForMd5(Integer instanceCount) { - return this.metadata.get(instanceCount); + List getAttributeValuesForInstanceCount(Integer instanceCount) { + return this.instanceCountToAttributeValues.get(instanceCount); } public Map> getMetadata() { - return Collections.unmodifiableMap(this.metadata); + return Collections.unmodifiableMap(this.instanceCountToAttributeValues); } /** @@ -65,9 +66,9 @@ final public class CommonAttributeSearchResults { public int size() { int count = 0; - for (List data : this.metadata.values()) { + for (List data : this.instanceCountToAttributeValues.values()) { for(CommonAttributeValue md5 : data){ - count += md5.size(); + count += md5.getInstanceCount(); } } return count; diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeValue.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeValue.java index f997c3b111..32ef80f491 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeValue.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeValue.java @@ -28,14 +28,14 @@ import java.util.Set; import java.util.stream.Collectors; /** - * Encapsulates data required to instantiate an Md5Node. + * Defines a value that is used for correlation, such as file MD5 or email address. */ final public class CommonAttributeValue { private final String md5; - private final List fileInstances; + private final List fileInstances; - CommonAttributeValue(String md5, List fileInstances) { + CommonAttributeValue(String md5, List fileInstances) { this.md5 = md5; this.fileInstances = fileInstances; } @@ -45,18 +45,23 @@ final public class CommonAttributeValue { this.fileInstances = new ArrayList<>(); } - public String getMd5() { + public String getValue() { return this.md5; } + /** + * concatenate cases this value was seen into a single string + * + * @return + */ public String getCases() { - final String cases = this.fileInstances.stream().map(AbstractCommonAttributeInstanceNode::getCaseName).collect(Collectors.joining(", ")); + final String cases = this.fileInstances.stream().map(AbstractCommonAttributeSearchResult::getCaseName).collect(Collectors.joining(", ")); return cases; } public String getDataSources() { Set sources = new HashSet<>(); - for (AbstractCommonAttributeInstanceNode data : this.fileInstances) { + for (AbstractCommonAttributeSearchResult data : this.fileInstances) { sources.add(data.getDataSource()); } @@ -64,15 +69,15 @@ final public class CommonAttributeValue { return dataSources; } - void addFileInstanceMetadata(AbstractCommonAttributeInstanceNode metadata) { + void addFileInstanceMetadata(AbstractCommonAttributeSearchResult metadata) { this.fileInstances.add(metadata); } - void addFileInstanceMetadata(AbstractCommonAttributeInstanceNode metadata, String caseName) { + void addFileInstanceMetadata(AbstractCommonAttributeSearchResult metadata, String caseName) { this.fileInstances.add(metadata); } - public Collection getMetadata() { + public Collection getInstances() { return Collections.unmodifiableCollection(this.fileInstances); } @@ -82,7 +87,7 @@ final public class CommonAttributeValue { * * @return number of instances */ - public int size() { + public int getInstanceCount() { return this.fileInstances.size(); } } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeValueNode.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeValueNode.java index 56623bc2af..a5169d63e6 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeValueNode.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeValueNode.java @@ -31,16 +31,14 @@ import org.sleuthkit.autopsy.datamodel.DisplayableItemNodeVisitor; import org.sleuthkit.autopsy.datamodel.NodeProperty; /** - * Represents a common files match - two or more files which appear to be the - * same file and appear as children of this node. This node will simply contain - * the MD5 of the matched files, the data sources those files were found within, - * and a count of the instances represented by the md5. + * Represents the layer in the tree for the value (such as MD5) that was in multiple places. + * Children are instances of that value. */ public class CommonAttributeValueNode extends DisplayableItemNode { private static final Logger LOGGER = Logger.getLogger(CommonAttributeValueNode.class.getName()); - private final String md5Hash; + private final String value; private final int commonFileCount; private final String cases; private final String dataSources; @@ -56,12 +54,13 @@ public class CommonAttributeValueNode extends DisplayableItemNode { super(Children.create( new FileInstanceNodeFactory(data), true)); - this.commonFileCount = data.size(); + this.commonFileCount = data.getInstanceCount(); this.cases = data.getCases(); + // @@ We seem to be doing this string concat twice. We also do it in getDataSources() this.dataSources = String.join(", ", data.getDataSources()); - this.md5Hash = data.getMd5(); + this.value = data.getValue(); - this.setDisplayName(String.format(Bundle.Md5Node_Md5Node_format(), this.md5Hash)); + this.setDisplayName(String.format(Bundle.Md5Node_Md5Node_format(), this.value)); this.setIconBaseWithExtension("org/sleuthkit/autopsy/images/fileset-icon-16.png"); //NON-NLS } @@ -89,8 +88,8 @@ public class CommonAttributeValueNode extends DisplayableItemNode { * MD5 which is common to these matches * @return string md5 hash */ - public String getMd5() { - return this.md5Hash; + public String getValue() { + return this.value; } @NbBundle.Messages({"Md5Node.createSheet.noDescription= "}) @@ -132,7 +131,7 @@ public class CommonAttributeValueNode extends DisplayableItemNode { * Child generator for SleuthkitCaseFileInstanceNode of * CommonAttributeValueNode. */ - static class FileInstanceNodeFactory extends ChildFactory { + static class FileInstanceNodeFactory extends ChildFactory { private final CommonAttributeValue descendants; @@ -141,14 +140,16 @@ public class CommonAttributeValueNode extends DisplayableItemNode { } @Override - protected Node[] createNodesForKey(AbstractCommonAttributeInstanceNode file) { - return file.generateNodes(); - } - - @Override - protected boolean createKeys(List list) { - list.addAll(this.descendants.getMetadata()); + protected boolean createKeys(List list) { + list.addAll(this.descendants.getInstances()); return true; } + + @Override + protected Node[] createNodesForKey(AbstractCommonAttributeSearchResult searchResult) { + return searchResult.generateNodes(); + } + + } } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InstanceCountNode.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InstanceCountNode.java index 3b29e9ce38..dbc3d362e9 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InstanceCountNode.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InstanceCountNode.java @@ -40,24 +40,24 @@ import org.sleuthkit.autopsy.datamodel.NodeProperty; final public class InstanceCountNode extends DisplayableItemNode { final private int instanceCount; - final private List metadataList; + final private List attributeValues; /** * Create a node with the given number of instances, and the given * selection of metadata. * @param instanceCount - * @param md5Metadata + * @param attributeValues */ @NbBundle.Messages({ "InstanceCountNode.displayName=Files with %s instances (%s)" }) - public InstanceCountNode(int instanceCount, List md5Metadata) { - super(Children.create(new Md5NodeFactory(md5Metadata), true)); + public InstanceCountNode(int instanceCount, List attributeValues) { + super(Children.create(new CommonAttributeValueNodeFactory(attributeValues), true)); this.instanceCount = instanceCount; - this.metadataList = md5Metadata; + this.attributeValues = attributeValues; - this.setDisplayName(String.format(Bundle.InstanceCountNode_displayName(), Integer.toString(instanceCount), md5Metadata.size())); + this.setDisplayName(String.format(Bundle.InstanceCountNode_displayName(), Integer.toString(instanceCount), attributeValues.size())); this.setIconBaseWithExtension("org/sleuthkit/autopsy/images/fileset-icon-16.png"); //NON-NLS } @@ -73,8 +73,8 @@ final public class InstanceCountNode extends DisplayableItemNode { * Get a list of metadata for the MD5s which are children of this object. * @return List */ - List getMetadata() { - return Collections.unmodifiableList(this.metadataList); + List getAttributeValues() { + return Collections.unmodifiableList(this.attributeValues); } @Override @@ -113,34 +113,36 @@ final public class InstanceCountNode extends DisplayableItemNode { * ChildFactory which builds CommonFileParentNodes from the * CommonFilesMetaaData models. */ - static class Md5NodeFactory extends ChildFactory { + static class CommonAttributeValueNodeFactory extends ChildFactory { /** * List of models, each of which is a parent node matching a single md5, * containing children FileNodes. */ + // maps sting version of value to value Object (??) private final Map metadata; - Md5NodeFactory(List metadata) { + CommonAttributeValueNodeFactory(List attributeValues) { this.metadata = new HashMap<>(); - Iterator iterator = metadata.iterator(); + Iterator iterator = attributeValues.iterator(); while (iterator.hasNext()) { - CommonAttributeValue md5Metadata = iterator.next(); - this.metadata.put(md5Metadata.getMd5(), md5Metadata); + CommonAttributeValue attributeValue = iterator.next(); + this.metadata.put(attributeValue.getValue(), attributeValue); } } - @Override - protected Node createNodeForKey(String md5) { - CommonAttributeValue md5Metadata = this.metadata.get(md5); - return new CommonAttributeValueNode(md5Metadata); - } - @Override protected boolean createKeys(List list) { + // @@@ We should just use CommonAttributeValue as the key... list.addAll(this.metadata.keySet()); return true; } + + @Override + protected Node createNodeForKey(String attributeValue) { + CommonAttributeValue md5Metadata = this.metadata.get(attributeValue); + return new CommonAttributeValueNode(md5Metadata); + } } } \ No newline at end of file diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearchResults.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearchResult.java similarity index 88% rename from Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearchResults.java rename to Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearchResult.java index 46ca88f439..f5b0703fd2 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearchResults.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearchResult.java @@ -35,15 +35,17 @@ import org.sleuthkit.datamodel.SleuthkitCase; import org.sleuthkit.datamodel.TskCoreException; /** + * Represents that a row in the CR was found in multiple cases. + * * Generates a DisplayableItmeNode using a CentralRepositoryFile. */ -final public class InterCaseCommonAttributeSearchResults extends AbstractCommonAttributeInstanceNode { +final public class InterCaseCommonAttributeSearchResult extends AbstractCommonAttributeSearchResult { - private static final Logger LOGGER = Logger.getLogger(InterCaseCommonAttributeSearchResults.class.getName()); + private static final Logger LOGGER = Logger.getLogger(InterCaseCommonAttributeSearchResult.class.getName()); private final Integer crFileId; private CorrelationAttributeInstance currentAttributeInstance; - InterCaseCommonAttributeSearchResults(Integer attrInstId, Map cachedFiles) { + InterCaseCommonAttributeSearchResult(Integer attrInstId, Map cachedFiles) { super(cachedFiles); this.crFileId = attrInstId; } @@ -79,6 +81,8 @@ final public class InterCaseCommonAttributeSearchResults extends AbstractCommonA @Override public DisplayableItemNode[] generateNodes() { + // @@@ We should be doing more of this work in teh generateKeys method. We want to do as little as possible in generateNodes + InterCaseSearchResultsProcessor eamDbAttrInst = new InterCaseSearchResultsProcessor(); CorrelationAttribute corrAttr = eamDbAttrInst.findSingleCorrelationAttribute(crFileId); List attrInstNodeList = new ArrayList<>(0); @@ -90,7 +94,7 @@ final public class InterCaseCommonAttributeSearchResults extends AbstractCommonA AbstractFile equivalentAbstractFile = this.lookupOrLoadAbstractFile(); - DisplayableItemNode generatedInstNode = AbstractCommonAttributeInstanceNode.createInstance(attrInst, equivalentAbstractFile, currCaseDbName); + DisplayableItemNode generatedInstNode = AbstractCommonAttributeSearchResult.createInstance(attrInst, equivalentAbstractFile, currCaseDbName); attrInstNodeList.add(generatedInstNode); diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearcher.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearcher.java index 604dbaece2..9dc4ad661f 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearcher.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearcher.java @@ -56,17 +56,18 @@ abstract class InterCaseCommonAttributeSearcher extends AbstractCommonAttributeS /** * @param artifactInstances all 'common files' in central repo - * @param commonFiles matches must ultimately have appeared in this + * @param commonValues matches must ultimately have appeared in this * collection * @return collated map of instance counts to lists of matches */ - Map> gatherIntercaseResults(Map commonFiles, Map commonFileCases) { + Map> gatherIntercaseResults(Map commonValues, Map commonFileCases) { + // keyis string of value Map interCaseCommonFiles = new HashMap<>(); - for (int commonAttrId : commonFiles.keySet()) { + for (int commonAttrId : commonValues.keySet()) { - String md5 = commonFiles.get(commonAttrId); + String md5 = commonValues.get(commonAttrId); if (md5 == null || HashUtility.isNoDataMd5(md5)) { continue; } @@ -82,15 +83,18 @@ abstract class InterCaseCommonAttributeSearcher extends AbstractCommonAttributeS if (interCaseCommonFiles.containsKey(md5)) { //Add to intercase metaData - final CommonAttributeValue md5Metadata = interCaseCommonFiles.get(md5); - AbstractCommonAttributeInstanceNode nodeGenerator = new InterCaseCommonAttributeSearchResults(commonAttrId, fileCache); - md5Metadata.addFileInstanceMetadata(nodeGenerator, correlationCaseDisplayName); + final CommonAttributeValue commonAttributeValue = interCaseCommonFiles.get(md5); + + AbstractCommonAttributeSearchResult searchResult = new InterCaseCommonAttributeSearchResult(commonAttrId, fileCache); + commonAttributeValue.addFileInstanceMetadata(searchResult, correlationCaseDisplayName); } else { - CommonAttributeValue md5Metadata = new CommonAttributeValue(md5); - AbstractCommonAttributeInstanceNode nodeGenerator = new InterCaseCommonAttributeSearchResults(commonAttrId, fileCache); - md5Metadata.addFileInstanceMetadata(nodeGenerator, correlationCaseDisplayName); - interCaseCommonFiles.put(md5, md5Metadata); + CommonAttributeValue commonAttributeValue = new CommonAttributeValue(md5); + interCaseCommonFiles.put(md5, commonAttributeValue); + + AbstractCommonAttributeSearchResult searchResult = new InterCaseCommonAttributeSearchResult(commonAttrId, fileCache); + commonAttributeValue.addFileInstanceMetadata(searchResult, correlationCaseDisplayName); + } } catch (Exception ex) { LOGGER.log(Level.WARNING, "Error getting artifact instances from database.", ex); // NON-NLS diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseSearchResultsProcessor.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseSearchResultsProcessor.java index ae679dfee4..8416bbd856 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseSearchResultsProcessor.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseSearchResultsProcessor.java @@ -42,7 +42,9 @@ final class InterCaseSearchResultsProcessor { private static final Logger LOGGER = Logger.getLogger(CommonAttributePanel.class.getName()); + // maps row ID to value private final Map intercaseCommonValuesMap = new HashMap<>(); + // maps row ID to case ID private final Map intercaseCommonCasesMap = new HashMap<>(); /** diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCaseCommonAttributeSearchResults.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCaseCommonAttributeSearchResults.java index ba77d3e2c1..bc39fa60ef 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCaseCommonAttributeSearchResults.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCaseCommonAttributeSearchResults.java @@ -33,7 +33,7 @@ import org.sleuthkit.datamodel.TskCoreException; /** * Encapsulates data required to instantiate a FileInstanceNode. */ -final public class IntraCaseCommonAttributeSearchResults extends AbstractCommonAttributeInstanceNode { +final public class IntraCaseCommonAttributeSearchResults extends AbstractCommonAttributeSearchResult { private static final Logger LOGGER = Logger.getLogger(IntraCaseCommonAttributeSearchResults.class.getName()); diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/DisplayableItemNodeVisitor.java b/Core/src/org/sleuthkit/autopsy/datamodel/DisplayableItemNodeVisitor.java index d7e4cf3ebb..6e6cbb7e70 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/DisplayableItemNodeVisitor.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/DisplayableItemNodeVisitor.java @@ -19,7 +19,7 @@ package org.sleuthkit.autopsy.datamodel; import org.sleuthkit.autopsy.commonfilesearch.InterCaseCommonAttributeInstanceNode; -import org.sleuthkit.autopsy.commonfilesearch.CommonAttributeSearchResultNode; +import org.sleuthkit.autopsy.commonfilesearch.CommonAttributeSearchResultRootNode; import org.sleuthkit.autopsy.commonfilesearch.InstanceCountNode; import org.sleuthkit.autopsy.commonfilesearch.CommonAttributeValueNode; import org.sleuthkit.autopsy.commonfilesearch.IntraCaseCommonAttributeInstanceNode; @@ -118,7 +118,7 @@ public interface DisplayableItemNodeVisitor { T visit(CommonAttributeValueNode mn); - T visit(CommonAttributeSearchResultNode cfn); + T visit(CommonAttributeSearchResultRootNode cfn); T visit(IntraCaseCommonAttributeInstanceNode fin); @@ -205,7 +205,7 @@ public interface DisplayableItemNodeVisitor { } @Override - public T visit(CommonAttributeSearchResultNode cfn) { + public T visit(CommonAttributeSearchResultRootNode cfn) { return defaultVisit(cfn); } diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IntraCaseUtils.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IntraCaseUtils.java index 634968638f..e44e1a3b40 100644 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IntraCaseUtils.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IntraCaseUtils.java @@ -33,7 +33,7 @@ import org.python.icu.impl.Assert; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.ImageDSProcessor; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; -import org.sleuthkit.autopsy.commonfilesearch.AbstractCommonAttributeInstanceNode; +import org.sleuthkit.autopsy.commonfilesearch.AbstractCommonAttributeSearchResult; import org.sleuthkit.autopsy.commonfilesearch.CommonAttributeSearchResults; import org.sleuthkit.autopsy.commonfilesearch.DataSourceLoader; import org.sleuthkit.autopsy.commonfilesearch.CommonAttributeValue; @@ -207,7 +207,7 @@ class IntraCaseUtils { for (Map.Entry> entry : metadata.getMetadata().entrySet()) { for (CommonAttributeValue md : entry.getValue()) { - for (AbstractCommonAttributeInstanceNode fim : md.getMetadata()) { + for (AbstractCommonAttributeSearchResult fim : md.getInstances()) { instanceIdToDataSource.put(fim.getAbstractFileObjectId(), fim.getDataSource()); } } From 23a487c1901828cbd508581949c3c1a5c8cc5c53 Mon Sep 17 00:00:00 2001 From: Brian Carrier Date: Mon, 23 Jul 2018 14:06:49 -0400 Subject: [PATCH 166/287] minor refactor --- ...a => AbstractCommonAttributeInstance.java} | 30 ++++--- ...ava => CaseDBCommonAttributeInstance.java} | 12 +-- ...=> CaseDBCommonAttributeInstanceNode.java} | 13 +-- ...> CentralRepoCommonAttributeInstance.java} | 12 +-- ...ntralRepoCommonAttributeInstanceNode.java} | 6 +- .../CommonAttributeInstanceNode.java | 89 ------------------- .../CommonAttributeValue.java | 18 ++-- .../CommonAttributeValueNode.java | 6 +- .../InterCaseCommonAttributeSearcher.java | 4 +- .../IntraCaseCommonAttributeSearcher.java | 10 +-- .../datamodel/DisplayableItemNodeVisitor.java | 12 +-- .../directorytree/DataResultFilterNode.java | 8 +- .../commonfilessearch/InterCaseUtils.java | 2 +- .../commonfilessearch/IntraCaseUtils.java | 4 +- 14 files changed, 70 insertions(+), 156 deletions(-) rename Core/src/org/sleuthkit/autopsy/commonfilesearch/{AbstractCommonAttributeSearchResult.java => AbstractCommonAttributeInstance.java} (86%) rename Core/src/org/sleuthkit/autopsy/commonfilesearch/{IntraCaseCommonAttributeSearchResults.java => CaseDBCommonAttributeInstance.java} (79%) rename Core/src/org/sleuthkit/autopsy/commonfilesearch/{IntraCaseCommonAttributeInstanceNode.java => CaseDBCommonAttributeInstanceNode.java} (84%) rename Core/src/org/sleuthkit/autopsy/commonfilesearch/{InterCaseCommonAttributeSearchResult.java => CentralRepoCommonAttributeInstance.java} (86%) rename Core/src/org/sleuthkit/autopsy/commonfilesearch/{InterCaseCommonAttributeInstanceNode.java => CentralRepoCommonAttributeInstanceNode.java} (95%) delete mode 100644 Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeInstanceNode.java diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeSearchResult.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeInstance.java similarity index 86% rename from Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeSearchResult.java rename to Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeInstance.java index 6efb525b35..6f445ca0a3 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeSearchResult.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeInstance.java @@ -26,6 +26,10 @@ import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.TskCoreException; /** + * Represents an instance in either the CaseDB or CR that had a common match. + * Different implementations know how to get the instance details from either + * CaseDB or CR. + * * Defines leaf-type nodes used in the Common Files Search results tree. Leaf * nodes, may describe common attributes which exist in the current case DB or * in the Central Repo. When a reference to the AbstractFile is lacking (such as @@ -34,7 +38,7 @@ import org.sleuthkit.datamodel.TskCoreException; * multiple types of leaf nodes are required to represent Common Attribute * Instance nodes. */ -public abstract class AbstractCommonAttributeSearchResult { +public abstract class AbstractCommonAttributeInstance { private final Long abstractFileObjectId; // maps object ID to file @@ -52,7 +56,7 @@ public abstract class AbstractCommonAttributeSearchResult { * @param dataSource datasource where this attribute appears * @param caseName case where this attribute appears */ - AbstractCommonAttributeSearchResult(Long abstractFileReference, Map cachedFiles, String dataSource, String caseName) { + AbstractCommonAttributeInstance(Long abstractFileReference, Map cachedFiles, String dataSource, String caseName) { this.abstractFileObjectId = abstractFileReference; this.cachedFiles = cachedFiles; this.caseName = caseName; @@ -66,7 +70,7 @@ public abstract class AbstractCommonAttributeSearchResult { * @param cachedFiles storage for abstract files which have been used * already so we can avoid extra roundtrips to the case db */ - AbstractCommonAttributeSearchResult(Map cachedFiles) { + AbstractCommonAttributeInstance(Map cachedFiles) { this.abstractFileObjectId = -1L; this.cachedFiles = cachedFiles; this.caseName = ""; @@ -80,11 +84,11 @@ public abstract class AbstractCommonAttributeSearchResult { * @return AbstractFile which is identical to the file instance generated by * implementations of this object */ - AbstractFile lookupOrLoadAbstractFile() { + protected AbstractFile lookupOrLoadAbstractFile() { if (this.cachedFiles.containsKey(this.getAbstractFileObjectId())) { return this.cachedFiles.get(this.getAbstractFileObjectId()); } else { - AbstractFile file = this.loadFileFromSleuthkitCase(); + AbstractFile file = this.getAbstractFile(); final long abstractFileId = file.getId(); this.cachedFiles.put(abstractFileId, file); return file; @@ -92,14 +96,14 @@ public abstract class AbstractCommonAttributeSearchResult { } /** - * Implement this in subclasses to find the AbstractFile by whatever means - * available. This will be called by this.lookupOrLoadAbstractFile. In some - * cases we may have the object abstractFileId, in other cases we may need - * to use the file name. + * Get an AbstractFile for this instance if it can be retrieved from + * the CaseDB. * - * @return AbstractFile corresponding to this common attribute + * @return AbstractFile corresponding to this common attribute or null if + * it cannot be found + * @@@ Consider throwing exception instead of NULL */ - abstract AbstractFile loadFileFromSleuthkitCase(); + abstract AbstractFile getAbstractFile(); /** * Create a list of leaf nodes, to be used to display a row in the tree @@ -184,9 +188,9 @@ public abstract class AbstractCommonAttributeSearchResult { final boolean sameDataSource = attributeDataSourceName.equalsIgnoreCase(abstractFileDataSourceName); if (sameCase && sameFileName && sameDataSource) { - leafNode = new IntraCaseCommonAttributeInstanceNode(equivalentAbstractFile, currentCaseName, abstractFileDataSourceName); + leafNode = new CaseDBCommonAttributeInstanceNode(equivalentAbstractFile, currentCaseName, abstractFileDataSourceName); } else { - leafNode = new InterCaseCommonAttributeInstanceNode(attributeInstance, equivalentAbstractFile); + leafNode = new CentralRepoCommonAttributeInstanceNode(attributeInstance, equivalentAbstractFile); } return leafNode; } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCaseCommonAttributeSearchResults.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CaseDBCommonAttributeInstance.java similarity index 79% rename from Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCaseCommonAttributeSearchResults.java rename to Core/src/org/sleuthkit/autopsy/commonfilesearch/CaseDBCommonAttributeInstance.java index bc39fa60ef..74363a869b 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCaseCommonAttributeSearchResults.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CaseDBCommonAttributeInstance.java @@ -31,11 +31,11 @@ import org.sleuthkit.datamodel.SleuthkitCase; import org.sleuthkit.datamodel.TskCoreException; /** - * Encapsulates data required to instantiate a FileInstanceNode. + * Encapsulates data required to instantiate a FileInstanceNode for an instance in the CaseDB */ -final public class IntraCaseCommonAttributeSearchResults extends AbstractCommonAttributeSearchResult { +final public class CaseDBCommonAttributeInstance extends AbstractCommonAttributeInstance { - private static final Logger LOGGER = Logger.getLogger(IntraCaseCommonAttributeSearchResults.class.getName()); + private static final Logger LOGGER = Logger.getLogger(CaseDBCommonAttributeInstance.class.getName()); /** @@ -45,18 +45,18 @@ final public class IntraCaseCommonAttributeSearchResults extends AbstractCommonA * @param objectId id of abstract file to find * @param dataSourceName name of datasource where the object is found */ - IntraCaseCommonAttributeSearchResults(Long abstractFileReference, Map cachedFiles, String dataSource, String caseName) { + CaseDBCommonAttributeInstance(Long abstractFileReference, Map cachedFiles, String dataSource, String caseName) { super(abstractFileReference, cachedFiles, dataSource, caseName); } @Override public DisplayableItemNode[] generateNodes() { - final IntraCaseCommonAttributeInstanceNode intraCaseCommonAttributeInstanceNode = new IntraCaseCommonAttributeInstanceNode(this.lookupOrLoadAbstractFile(), this.getCaseName(), this.getDataSource()); + final CaseDBCommonAttributeInstanceNode intraCaseCommonAttributeInstanceNode = new CaseDBCommonAttributeInstanceNode(this.lookupOrLoadAbstractFile(), this.getCaseName(), this.getDataSource()); return Arrays.asList(intraCaseCommonAttributeInstanceNode).toArray(new DisplayableItemNode[1]); } @Override - AbstractFile loadFileFromSleuthkitCase() { + AbstractFile getAbstractFile() { Case currentCase; try { diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCaseCommonAttributeInstanceNode.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CaseDBCommonAttributeInstanceNode.java similarity index 84% rename from Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCaseCommonAttributeInstanceNode.java rename to Core/src/org/sleuthkit/autopsy/commonfilesearch/CaseDBCommonAttributeInstanceNode.java index f977e72d88..59e5318801 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCaseCommonAttributeInstanceNode.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CaseDBCommonAttributeInstanceNode.java @@ -26,15 +26,10 @@ import org.sleuthkit.autopsy.datamodel.NodeProperty; import org.sleuthkit.datamodel.AbstractFile; /** - * Used by the Common Files search feature to encapsulate instances of a given - * MD5s matched in the search. These nodes will be children of Md5Nodes. - * - * Use this type for files which are in the current case. Contrast with - * CentralRepositoryFileInstanceNode which should be used when the - * FileInstance was found in some case not presently open in Autopsy, but present - * in the Central Repository. + * Node that wraps CaseDBCommonAttributeInstance to represent a file instance stored + * in the CaseDB. */ -public class IntraCaseCommonAttributeInstanceNode extends FileNode { +public class CaseDBCommonAttributeInstanceNode extends FileNode { private final String caseName; private final String dataSource; @@ -46,7 +41,7 @@ public class IntraCaseCommonAttributeInstanceNode extends FileNode { * @param fsContent * @param dataSource */ - public IntraCaseCommonAttributeInstanceNode(AbstractFile fsContent, String caseName, String dataSource) { + public CaseDBCommonAttributeInstanceNode(AbstractFile fsContent, String caseName, String dataSource) { super(fsContent); this.caseName = caseName; this.dataSource = dataSource; diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearchResult.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepoCommonAttributeInstance.java similarity index 86% rename from Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearchResult.java rename to Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepoCommonAttributeInstance.java index f5b0703fd2..d154e6f1df 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearchResult.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepoCommonAttributeInstance.java @@ -39,13 +39,13 @@ import org.sleuthkit.datamodel.TskCoreException; * * Generates a DisplayableItmeNode using a CentralRepositoryFile. */ -final public class InterCaseCommonAttributeSearchResult extends AbstractCommonAttributeSearchResult { +final public class CentralRepoCommonAttributeInstance extends AbstractCommonAttributeInstance { - private static final Logger LOGGER = Logger.getLogger(InterCaseCommonAttributeSearchResult.class.getName()); + private static final Logger LOGGER = Logger.getLogger(CentralRepoCommonAttributeInstance.class.getName()); private final Integer crFileId; private CorrelationAttributeInstance currentAttributeInstance; - InterCaseCommonAttributeSearchResult(Integer attrInstId, Map cachedFiles) { + CentralRepoCommonAttributeInstance(Integer attrInstId, Map cachedFiles) { super(cachedFiles); this.crFileId = attrInstId; } @@ -55,9 +55,10 @@ final public class InterCaseCommonAttributeSearchResult extends AbstractCommonAt } @Override - AbstractFile loadFileFromSleuthkitCase() { + AbstractFile getAbstractFile() { Case currentCase; + // @@@ Need to CHeck for NULL. This seems to depend on generateNodes to be called first String currentFullPath = this.currentAttributeInstance.getFilePath(); try { @@ -88,13 +89,14 @@ final public class InterCaseCommonAttributeSearchResult extends AbstractCommonAt List attrInstNodeList = new ArrayList<>(0); String currCaseDbName = Case.getCurrentCase().getDisplayName(); + // @@@ This seems wrong that we are looping here, but only setting one attrInst in the class, which is then used by getAbstractFile(). for (CorrelationAttributeInstance attrInst : corrAttr.getInstances()) { try { this.setCurrentAttributeInst(attrInst); AbstractFile equivalentAbstractFile = this.lookupOrLoadAbstractFile(); - DisplayableItemNode generatedInstNode = AbstractCommonAttributeSearchResult.createInstance(attrInst, equivalentAbstractFile, currCaseDbName); + DisplayableItemNode generatedInstNode = AbstractCommonAttributeInstance.createInstance(attrInst, equivalentAbstractFile, currCaseDbName); attrInstNodeList.add(generatedInstNode); diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeInstanceNode.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepoCommonAttributeInstanceNode.java similarity index 95% rename from Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeInstanceNode.java rename to Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepoCommonAttributeInstanceNode.java index ee9b173d3e..ea5b19950c 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeInstanceNode.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepoCommonAttributeInstanceNode.java @@ -42,7 +42,7 @@ import org.sleuthkit.datamodel.Content; * Central Repo. Contrast with SleuthkitCase which should be used * when the FileInstance was found in the case presently open in Autopsy. */ -public class InterCaseCommonAttributeInstanceNode extends DisplayableItemNode { +public class CentralRepoCommonAttributeInstanceNode extends DisplayableItemNode { private final CorrelationAttributeInstance crFile; @@ -50,7 +50,7 @@ public class InterCaseCommonAttributeInstanceNode extends DisplayableItemNode { // and we can use this to support certain actions in the tree table and crFile viewer private final AbstractFile md5Reference; - InterCaseCommonAttributeInstanceNode(CorrelationAttributeInstance content, AbstractFile md5Reference) { + CentralRepoCommonAttributeInstanceNode(CorrelationAttributeInstance content, AbstractFile md5Reference) { super(Children.LEAF, Lookups.fixed(content)); // Using md5Reference enables Other Occurances, but for the current file path this.crFile = content; this.setDisplayName(new File(this.crFile.getFilePath()).getName()); @@ -88,7 +88,7 @@ public class InterCaseCommonAttributeInstanceNode extends DisplayableItemNode { public String getItemType() { //objects of type FileNode will co-occur in the treetable with objects // of this type and they will need to provide the same key - return IntraCaseCommonAttributeInstanceNode.class.getName(); + return CaseDBCommonAttributeInstanceNode.class.getName(); } @Override diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeInstanceNode.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeInstanceNode.java deleted file mode 100644 index 1b385467d4..0000000000 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeInstanceNode.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Autopsy Forensic Browser - * - * Copyright 2018 Basis Technology Corp. - * Contact: carrier sleuthkit 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.commonfilesearch; - -import org.apache.commons.lang3.StringUtils; -import org.openide.nodes.Sheet; -import org.openide.util.NbBundle; -import org.sleuthkit.autopsy.casemodule.Case; -import org.sleuthkit.autopsy.datamodel.DisplayableItemNodeVisitor; -import org.sleuthkit.autopsy.datamodel.FileNode; -import org.sleuthkit.autopsy.datamodel.NodeProperty; -import org.sleuthkit.datamodel.AbstractFile; - -/** - * Used by the Common Files search feature to encapsulate instances of a given - MD5s matched in the search. These nodes will be children of Md5Nodes. - */ -public class CommonAttributeInstanceNode extends FileNode { - - private final String dataSource; - - /** - * Create a node which can be used in a multilayer tree table and is based - * on an AbstractFile. - * - * @param fsContent - * @param dataSource - */ - public CommonAttributeInstanceNode(AbstractFile fsContent, String dataSource) { - super(fsContent); - this.dataSource = dataSource; - - this.setDisplayName(fsContent.getName()); - } - - @Override - public boolean isLeafTypeNode(){ - //Not used atm - could maybe be leveraged for better use in Children objects - return true; - } - - @Override - public T accept(DisplayableItemNodeVisitor visitor) { - return visitor.visit(this); - } - - String getDataSource() { - return this.dataSource; - } - - @NbBundle.Messages({"FileInstanceNode.createSheet.noDescription= "}) - @Override - protected Sheet createSheet() { - Sheet sheet = new Sheet(); - Sheet.Set sheetSet = sheet.get(Sheet.PROPERTIES); - if (sheetSet == null) { - sheetSet = Sheet.createPropertiesSet(); - sheet.put(sheetSet); - } - - final String NO_DESCR = Bundle.FileInstanceNode_createSheet_noDescription(); - - sheetSet.put(new NodeProperty<>(Bundle.CommonFilesSearchResultsViewerTable_filesColLbl(), Bundle.CommonFilesSearchResultsViewerTable_filesColLbl(), NO_DESCR, this.getContent().getName())); - sheetSet.put(new NodeProperty<>(Bundle.CommonFilesSearchResultsViewerTable_pathColLbl(), Bundle.CommonFilesSearchResultsViewerTable_pathColLbl(), NO_DESCR, this.getContent().getParentPath())); - sheetSet.put(new NodeProperty<>(Bundle.CommonFilesSearchResultsViewerTable_hashsetHitsColLbl(), Bundle.CommonFilesSearchResultsViewerTable_hashsetHitsColLbl(), NO_DESCR, getHashSetHitsForFile(this.getContent()))); - sheetSet.put(new NodeProperty<>(Bundle.CommonFilesSearchResultsViewerTable_dataSourceColLbl(), Bundle.CommonFilesSearchResultsViewerTable_dataSourceColLbl(), NO_DESCR, this.getDataSource())); - sheetSet.put(new NodeProperty<>(Bundle.CommonFilesSearchResultsViewerTable_mimeTypeColLbl(), Bundle.CommonFilesSearchResultsViewerTable_mimeTypeColLbl(), NO_DESCR, StringUtils.defaultString(this.getContent().getMIMEType()))); - this.addTagProperty(sheetSet); - sheetSet.put(new NodeProperty<>(Bundle.CommonFilesSearchResultsViewerTable_caseColLbl1(), Bundle.CommonFilesSearchResultsViewerTable_caseColLbl1(), NO_DESCR, Case.getCurrentCase().getDisplayName())); - - return sheet; - } -} diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeValue.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeValue.java index 32ef80f491..3ed386ab10 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeValue.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeValue.java @@ -28,14 +28,15 @@ import java.util.Set; import java.util.stream.Collectors; /** - * Defines a value that is used for correlation, such as file MD5 or email address. + * Defines a value that was in the common file search results + * as well as information about its instances. */ final public class CommonAttributeValue { private final String md5; - private final List fileInstances; + private final List fileInstances; - CommonAttributeValue(String md5, List fileInstances) { + CommonAttributeValue(String md5, List fileInstances) { this.md5 = md5; this.fileInstances = fileInstances; } @@ -55,13 +56,13 @@ final public class CommonAttributeValue { * @return */ public String getCases() { - final String cases = this.fileInstances.stream().map(AbstractCommonAttributeSearchResult::getCaseName).collect(Collectors.joining(", ")); + final String cases = this.fileInstances.stream().map(AbstractCommonAttributeInstance::getCaseName).collect(Collectors.joining(", ")); return cases; } public String getDataSources() { Set sources = new HashSet<>(); - for (AbstractCommonAttributeSearchResult data : this.fileInstances) { + for (AbstractCommonAttributeInstance data : this.fileInstances) { sources.add(data.getDataSource()); } @@ -69,15 +70,16 @@ final public class CommonAttributeValue { return dataSources; } - void addFileInstanceMetadata(AbstractCommonAttributeSearchResult metadata) { + void addInstance(AbstractCommonAttributeInstance metadata) { this.fileInstances.add(metadata); } - void addFileInstanceMetadata(AbstractCommonAttributeSearchResult metadata, String caseName) { + void addFileInstanceMetadata(AbstractCommonAttributeInstance metadata, String caseName) { this.fileInstances.add(metadata); + // @@@ Why are we ignoring caseName? } - public Collection getInstances() { + public Collection getInstances() { return Collections.unmodifiableCollection(this.fileInstances); } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeValueNode.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeValueNode.java index a5169d63e6..e7160e8d11 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeValueNode.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeValueNode.java @@ -131,7 +131,7 @@ public class CommonAttributeValueNode extends DisplayableItemNode { * Child generator for SleuthkitCaseFileInstanceNode of * CommonAttributeValueNode. */ - static class FileInstanceNodeFactory extends ChildFactory { + static class FileInstanceNodeFactory extends ChildFactory { private final CommonAttributeValue descendants; @@ -140,13 +140,13 @@ public class CommonAttributeValueNode extends DisplayableItemNode { } @Override - protected boolean createKeys(List list) { + protected boolean createKeys(List list) { list.addAll(this.descendants.getInstances()); return true; } @Override - protected Node[] createNodesForKey(AbstractCommonAttributeSearchResult searchResult) { + protected Node[] createNodesForKey(AbstractCommonAttributeInstance searchResult) { return searchResult.generateNodes(); } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearcher.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearcher.java index 9dc4ad661f..a5c5f642b7 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearcher.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearcher.java @@ -85,14 +85,14 @@ abstract class InterCaseCommonAttributeSearcher extends AbstractCommonAttributeS //Add to intercase metaData final CommonAttributeValue commonAttributeValue = interCaseCommonFiles.get(md5); - AbstractCommonAttributeSearchResult searchResult = new InterCaseCommonAttributeSearchResult(commonAttrId, fileCache); + AbstractCommonAttributeInstance searchResult = new CentralRepoCommonAttributeInstance(commonAttrId, fileCache); commonAttributeValue.addFileInstanceMetadata(searchResult, correlationCaseDisplayName); } else { CommonAttributeValue commonAttributeValue = new CommonAttributeValue(md5); interCaseCommonFiles.put(md5, commonAttributeValue); - AbstractCommonAttributeSearchResult searchResult = new InterCaseCommonAttributeSearchResult(commonAttrId, fileCache); + AbstractCommonAttributeInstance searchResult = new CentralRepoCommonAttributeInstance(commonAttrId, fileCache); commonAttributeValue.addFileInstanceMetadata(searchResult, correlationCaseDisplayName); } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCaseCommonAttributeSearcher.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCaseCommonAttributeSearcher.java index e60476da36..60a89fb5e5 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCaseCommonAttributeSearcher.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCaseCommonAttributeSearcher.java @@ -124,12 +124,12 @@ public abstract class IntraCaseCommonAttributeSearcher extends AbstractCommonAtt } if (commonFiles.containsKey(md5)) { - final CommonAttributeValue md5Metadata = commonFiles.get(md5); - md5Metadata.addFileInstanceMetadata(new IntraCaseCommonAttributeSearchResults(objectId, fileCache, dataSource, caseName)); + final CommonAttributeValue commonAttributeValue = commonFiles.get(md5); + commonAttributeValue.addInstance(new CaseDBCommonAttributeInstance(objectId, fileCache, dataSource, caseName)); } else { - final CommonAttributeValue md5Metadata = new CommonAttributeValue(md5); - md5Metadata.addFileInstanceMetadata(new IntraCaseCommonAttributeSearchResults(objectId, fileCache, dataSource, caseName)); - commonFiles.put(md5, md5Metadata); + final CommonAttributeValue commonAttributeValue = new CommonAttributeValue(md5); + commonAttributeValue.addInstance(new CaseDBCommonAttributeInstance(objectId, fileCache, dataSource, caseName)); + commonFiles.put(md5, commonAttributeValue); } } } diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/DisplayableItemNodeVisitor.java b/Core/src/org/sleuthkit/autopsy/datamodel/DisplayableItemNodeVisitor.java index 6e6cbb7e70..cd14117c95 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/DisplayableItemNodeVisitor.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/DisplayableItemNodeVisitor.java @@ -18,11 +18,11 @@ */ package org.sleuthkit.autopsy.datamodel; -import org.sleuthkit.autopsy.commonfilesearch.InterCaseCommonAttributeInstanceNode; +import org.sleuthkit.autopsy.commonfilesearch.CentralRepoCommonAttributeInstanceNode; import org.sleuthkit.autopsy.commonfilesearch.CommonAttributeSearchResultRootNode; import org.sleuthkit.autopsy.commonfilesearch.InstanceCountNode; import org.sleuthkit.autopsy.commonfilesearch.CommonAttributeValueNode; -import org.sleuthkit.autopsy.commonfilesearch.IntraCaseCommonAttributeInstanceNode; +import org.sleuthkit.autopsy.commonfilesearch.CaseDBCommonAttributeInstanceNode; import org.sleuthkit.autopsy.datamodel.DeletedContent.DeletedContentsChildren.DeletedContentNode; import org.sleuthkit.autopsy.datamodel.DeletedContent.DeletedContentsNode; import org.sleuthkit.autopsy.datamodel.FileSize.FileSizeRootChildren.FileSizeNode; @@ -120,9 +120,9 @@ public interface DisplayableItemNodeVisitor { T visit(CommonAttributeSearchResultRootNode cfn); - T visit(IntraCaseCommonAttributeInstanceNode fin); + T visit(CaseDBCommonAttributeInstanceNode fin); - T visit(InterCaseCommonAttributeInstanceNode crfin); + T visit(CentralRepoCommonAttributeInstanceNode crfin); T visit(InstanceCountNode icn); @@ -195,7 +195,7 @@ public interface DisplayableItemNodeVisitor { protected abstract T defaultVisit(DisplayableItemNode c); @Override - public T visit(IntraCaseCommonAttributeInstanceNode fin) { + public T visit(CaseDBCommonAttributeInstanceNode fin) { return defaultVisit(fin); } @@ -215,7 +215,7 @@ public interface DisplayableItemNodeVisitor { } @Override - public T visit(InterCaseCommonAttributeInstanceNode crfin){ + public T visit(CentralRepoCommonAttributeInstanceNode crfin){ return defaultVisit(crfin); } diff --git a/Core/src/org/sleuthkit/autopsy/directorytree/DataResultFilterNode.java b/Core/src/org/sleuthkit/autopsy/directorytree/DataResultFilterNode.java index 32598d4cfd..098789597c 100644 --- a/Core/src/org/sleuthkit/autopsy/directorytree/DataResultFilterNode.java +++ b/Core/src/org/sleuthkit/autopsy/directorytree/DataResultFilterNode.java @@ -56,14 +56,14 @@ import org.sleuthkit.autopsy.datamodel.FileTypeExtensions; import org.sleuthkit.autopsy.datamodel.FileTypes.FileTypesNode; import org.sleuthkit.autopsy.commonfilesearch.InstanceCountNode; import org.sleuthkit.autopsy.commonfilesearch.CommonAttributeValueNode; -import org.sleuthkit.autopsy.commonfilesearch.InterCaseCommonAttributeInstanceNode; +import org.sleuthkit.autopsy.commonfilesearch.CentralRepoCommonAttributeInstanceNode; import org.sleuthkit.autopsy.datamodel.LayoutFileNode; import org.sleuthkit.autopsy.datamodel.LocalFileNode; import org.sleuthkit.autopsy.datamodel.LocalDirectoryNode; import org.sleuthkit.autopsy.datamodel.NodeSelectionInfo; import org.sleuthkit.autopsy.datamodel.Reports; import org.sleuthkit.autopsy.datamodel.SlackFileNode; -import org.sleuthkit.autopsy.commonfilesearch.IntraCaseCommonAttributeInstanceNode; +import org.sleuthkit.autopsy.commonfilesearch.CaseDBCommonAttributeInstanceNode; import org.sleuthkit.autopsy.datamodel.VirtualDirectoryNode; import static org.sleuthkit.autopsy.directorytree.Bundle.DataResultFilterNode_viewSourceArtifact_text; import org.sleuthkit.autopsy.modules.embeddedfileextractor.ExtractArchiveWithPasswordAction; @@ -535,12 +535,12 @@ public class DataResultFilterNode extends FilterNode { } @Override - public AbstractAction visit(IntraCaseCommonAttributeInstanceNode fin){ + public AbstractAction visit(CaseDBCommonAttributeInstanceNode fin){ return null; } @Override - public AbstractAction visit(InterCaseCommonAttributeInstanceNode iccan){ + public AbstractAction visit(CentralRepoCommonAttributeInstanceNode iccan){ return null; } diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/InterCaseUtils.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/InterCaseUtils.java index 1dbc67a180..bc626b6459 100644 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/InterCaseUtils.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/InterCaseUtils.java @@ -52,7 +52,7 @@ import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationCase; import org.sleuthkit.autopsy.centralrepository.datamodel.EamDb; import org.sleuthkit.autopsy.commonfilesearch.CommonAttributeSearchResults; import org.sleuthkit.autopsy.commonfilesearch.DataSourceLoader; -import org.sleuthkit.autopsy.commonfilesearch.IntraCaseCommonAttributeSearchResults; +import org.sleuthkit.autopsy.commonfilesearch.CaseDBCommonAttributeInstance; import org.sleuthkit.autopsy.commonfilesearch.CommonAttributeValue; /** diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IntraCaseUtils.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IntraCaseUtils.java index e44e1a3b40..035a16a0ed 100644 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IntraCaseUtils.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IntraCaseUtils.java @@ -33,7 +33,7 @@ import org.python.icu.impl.Assert; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.ImageDSProcessor; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; -import org.sleuthkit.autopsy.commonfilesearch.AbstractCommonAttributeSearchResult; +import org.sleuthkit.autopsy.commonfilesearch.AbstractCommonAttributeInstance; import org.sleuthkit.autopsy.commonfilesearch.CommonAttributeSearchResults; import org.sleuthkit.autopsy.commonfilesearch.DataSourceLoader; import org.sleuthkit.autopsy.commonfilesearch.CommonAttributeValue; @@ -207,7 +207,7 @@ class IntraCaseUtils { for (Map.Entry> entry : metadata.getMetadata().entrySet()) { for (CommonAttributeValue md : entry.getValue()) { - for (AbstractCommonAttributeSearchResult fim : md.getInstances()) { + for (AbstractCommonAttributeInstance fim : md.getInstances()) { instanceIdToDataSource.put(fim.getAbstractFileObjectId(), fim.getDataSource()); } } From a3d03fa0ba41d632b662a38ac51719fac02e3ca0 Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Mon, 23 Jul 2018 15:10:08 -0600 Subject: [PATCH 167/287] test utils and access modifiers required for testing --- .../InterCaseCommonAttributeInstanceNode.java | 14 +- .../IntraCaseCommonAttributeInstanceNode.java | 4 +- .../commonfilessearch/InterCaseUtils.java | 143 ++++++++++++------ 3 files changed, 104 insertions(+), 57 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeInstanceNode.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeInstanceNode.java index ee9b173d3e..8f4a0d6599 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeInstanceNode.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeInstanceNode.java @@ -57,7 +57,7 @@ public class InterCaseCommonAttributeInstanceNode extends DisplayableItemNode { this.md5Reference = md5Reference; } - public CorrelationAttributeInstance getCentralRepoFile(){ + public CorrelationAttributeInstance getCorrelationAttributeInstance(){ return this.crFile; } @@ -101,24 +101,24 @@ public class InterCaseCommonAttributeInstanceNode extends DisplayableItemNode { sheet.put(sheetSet); } - final CorrelationAttributeInstance centralRepoFile = this.getCentralRepoFile(); + final CorrelationAttributeInstance centralRepoFile = this.getCorrelationAttributeInstance(); final String fullPath = centralRepoFile.getFilePath(); final File file = new File(fullPath); - + final String caseName = centralRepoFile.getCorrelationCase().getDisplayName(); - + final String name = file.getName(); final String parent = file.getParent(); - - final String caseQualifiedDataSource = centralRepoFile.getCorrelationDataSource().getName(); + + final String dataSourceName = centralRepoFile.getCorrelationDataSource().getName(); final String NO_DESCR = Bundle.CommonFilesSearchResultsViewerTable_noDescText(); sheetSet.put(new NodeProperty<>(org.sleuthkit.autopsy.commonfilesearch.Bundle.CommonFilesSearchResultsViewerTable_filesColLbl(), org.sleuthkit.autopsy.commonfilesearch.Bundle.CommonFilesSearchResultsViewerTable_filesColLbl(), NO_DESCR, name)); sheetSet.put(new NodeProperty<>(org.sleuthkit.autopsy.commonfilesearch.Bundle.CommonFilesSearchResultsViewerTable_pathColLbl(), org.sleuthkit.autopsy.commonfilesearch.Bundle.CommonFilesSearchResultsViewerTable_pathColLbl(), NO_DESCR, parent)); sheetSet.put(new NodeProperty<>(org.sleuthkit.autopsy.commonfilesearch.Bundle.CommonFilesSearchResultsViewerTable_hashsetHitsColLbl(), org.sleuthkit.autopsy.commonfilesearch.Bundle.CommonFilesSearchResultsViewerTable_hashsetHitsColLbl(), NO_DESCR, "")); - sheetSet.put(new NodeProperty<>(org.sleuthkit.autopsy.commonfilesearch.Bundle.CommonFilesSearchResultsViewerTable_dataSourceColLbl(), org.sleuthkit.autopsy.commonfilesearch.Bundle.CommonFilesSearchResultsViewerTable_dataSourceColLbl(), NO_DESCR, caseQualifiedDataSource)); + sheetSet.put(new NodeProperty<>(org.sleuthkit.autopsy.commonfilesearch.Bundle.CommonFilesSearchResultsViewerTable_dataSourceColLbl(), org.sleuthkit.autopsy.commonfilesearch.Bundle.CommonFilesSearchResultsViewerTable_dataSourceColLbl(), NO_DESCR, dataSourceName)); sheetSet.put(new NodeProperty<>(org.sleuthkit.autopsy.commonfilesearch.Bundle.CommonFilesSearchResultsViewerTable_mimeTypeColLbl(), org.sleuthkit.autopsy.commonfilesearch.Bundle.CommonFilesSearchResultsViewerTable_mimeTypeColLbl(), NO_DESCR, "")); sheetSet.put(new NodeProperty<>(org.sleuthkit.autopsy.commonfilesearch.Bundle.CommonFilesSearchResultsViewerTable_caseColLbl1(), org.sleuthkit.autopsy.commonfilesearch.Bundle.CommonFilesSearchResultsViewerTable_caseColLbl1(), NO_DESCR, caseName)); diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCaseCommonAttributeInstanceNode.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCaseCommonAttributeInstanceNode.java index f977e72d88..b433be2848 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCaseCommonAttributeInstanceNode.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCaseCommonAttributeInstanceNode.java @@ -63,11 +63,11 @@ public class IntraCaseCommonAttributeInstanceNode extends FileNode { return visitor.visit(this); } - String getCase(){ + public String getCase(){ return this.caseName; } - String getDataSource() { + public String getDataSource() { return this.dataSource; } diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/InterCaseUtils.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/InterCaseUtils.java index 5bc7ac8b72..c385daa789 100644 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/InterCaseUtils.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/InterCaseUtils.java @@ -6,7 +6,7 @@ * Contact: carrier sleuthkit 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 not use this testFile except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 @@ -47,47 +47,54 @@ import org.sleuthkit.autopsy.testutils.IngestUtils; import org.sleuthkit.datamodel.TskCoreException; import org.python.icu.impl.Assert; 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.EamDb; +import org.sleuthkit.autopsy.commonfilesearch.AbstractCommonAttributeInstanceNode; import org.sleuthkit.autopsy.commonfilesearch.CommonAttributeSearchResults; import org.sleuthkit.autopsy.commonfilesearch.DataSourceLoader; import org.sleuthkit.autopsy.commonfilesearch.CommonAttributeValue; +import org.sleuthkit.autopsy.commonfilesearch.InterCaseCommonAttributeInstanceNode; +import org.sleuthkit.autopsy.commonfilesearch.InterCaseCommonAttributeSearchResults; +import org.sleuthkit.autopsy.commonfilesearch.IntraCaseCommonAttributeInstanceNode; +import org.sleuthkit.autopsy.datamodel.DisplayableItemNode; +import org.sleuthkit.datamodel.AbstractFile; /** * Utilities for testing intercase correlation feature. * * Description of Test Data: - * (Note: files of the same name and extension are identical; - * files of the same name and differing extension are not identical.) - * - * Case 1 - * +Data Set 1 - * - Hash-0.dat [file of size 0] - * - Hash-A.jpg - * - Hash-A.pdf - * +Data Set2 - * - Hash-0.dat [file of size -0] - * - Hash-A.jpg - * - Hash-A.pdf - * Case 2 - * +Data Set 1 - * - Hash-A.jpg - * - Hash-A.pdf - * +Data Set 2 - * - Hash-A.jpg - * - Hash-A.pdf - * - Hash_D.doc - * Case 3 - * +Data Set 1 - * - Hash-A.jpg - * - Hash-A.pdf - * - Hash-C.jpg [we should never find these!] - * - Hash-C.pdf [we should never find these!] - * - Hash-D.jpg - * +Data Set 2 - * - Hash-C.jpg [we should never find these!] - * - Hash-C.pdf - * - Hash.D-doc + (Note: files of the same name and extension are identical; + files of the same name and differing extension are not identical.) + + Case 1 + +Data Set 1 + - Hash-0.dat [testFile of size 0] + - Hash-A.jpg + - Hash-A.pdf + +Data Set2 + - Hash-0.dat [testFile of size -0] + - Hash-A.jpg + - Hash-A.pdf + Case 2 + +Data Set 1 + - Hash-A.jpg + - Hash-A.pdf + +Data Set 2 + - Hash-A.jpg + - Hash-A.pdf + - Hash_D.doc + Case 3 + +Data Set 1 + - Hash-A.jpg + - Hash-A.pdf + - Hash-C.jpg [we should never find these!] + - Hash-C.pdf [we should never find these!] + - Hash-D.jpg + +Data Set 2 + - Hash-C.jpg [we should never find these!] + - Hash-C.pdf + - Hash.D-doc */ class InterCaseUtils { @@ -291,26 +298,66 @@ class InterCaseUtils { int tally = 0; - for(Map.Entry> file : searchDomain.getValues().entrySet()){ + for(Map.Entry> entry : searchDomain.getValues().entrySet()){ - //Collection fileInstances = file.getValue(); - -// for(IntraCaseCommonAttributeSearchResults fileInstance : fileInstances){ -// -// -// } + for(CommonAttributeValue values : entry.getValue()){ + + for(AbstractCommonAttributeInstanceNode commonAttribute : values.getMetadata()){ + + if(commonAttribute instanceof InterCaseCommonAttributeSearchResults){ + InterCaseCommonAttributeSearchResults results = (InterCaseCommonAttributeSearchResults) commonAttribute; + for (DisplayableItemNode din : results.generateNodes()){ + + if(din instanceof InterCaseCommonAttributeInstanceNode){ + + InterCaseCommonAttributeInstanceNode node = (InterCaseCommonAttributeInstanceNode) din; + CorrelationAttributeInstance instance = node.getCorrelationAttributeInstance(); + + final String fullPath = instance.getFilePath(); + final File testFile = new File(fullPath); + + final String testCaseName = instance.getCorrelationCase().getDisplayName(); + + final String testFileName = testFile.getName(); + + final String testDataSource = instance.getCorrelationDataSource().getName(); + + boolean sameFileName = testFileName.equalsIgnoreCase(fileName); + boolean sameDataSource = testDataSource.equalsIgnoreCase(dataSource); + boolean sameCrCase = testCaseName.equalsIgnoreCase(crCase); + + if( sameFileName && sameDataSource && sameCrCase){ + tally++; + } + } + + if(din instanceof IntraCaseCommonAttributeInstanceNode){ + + IntraCaseCommonAttributeInstanceNode node = (IntraCaseCommonAttributeInstanceNode) din; + AbstractFile file = node.getContent(); + + final String testFileName = file.getName(); + final String testCaseName = node.getCase(); + final String testDataSource = node.getDataSource(); + + boolean sameFileName = testFileName.equalsIgnoreCase(fileName); + boolean sameCaseName = testCaseName.equalsIgnoreCase(crCase); + boolean sameDataSource = testDataSource.equalsIgnoreCase(dataSource); + + if(sameFileName && sameDataSource && sameCaseName){ + tally++; + } + } + } + } else { + Assert.fail("Unable to cast AbstractCommonAttributeInstanceNode to InterCaseCommonAttributeSearchResults."); + } + } + } } - return false; + return tally == instanceCount; } - - static Map mapFileInstancesToDataSource(CommonAttributeSearchResults metadata){ - return IntraCaseUtils.mapFileInstancesToDataSources(metadata); - } - -// static List getFiles(Set md5s){ -// -// } /** * Close the currently open case, delete the case directory, delete the From a65e43d112e3ba45a837f45bf4aa23cb1e540ae4 Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Mon, 23 Jul 2018 16:15:09 -0600 Subject: [PATCH 168/287] more merge conflicts --- .../commonfilessearch/InterCaseUtils.java | 27 +++++++++---------- .../commonfilessearch/IntraCaseUtils.java | 2 +- 2 files changed, 14 insertions(+), 15 deletions(-) diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/InterCaseUtils.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/InterCaseUtils.java index 07e06332f8..f62348fc1e 100644 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/InterCaseUtils.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/InterCaseUtils.java @@ -50,14 +50,13 @@ 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.EamDb; -import org.sleuthkit.autopsy.commonfilesearch.AbstractCommonAttributeInstanceNode; +import org.sleuthkit.autopsy.commonfilesearch.AbstractCommonAttributeInstance; +import org.sleuthkit.autopsy.commonfilesearch.CaseDBCommonAttributeInstanceNode; +import org.sleuthkit.autopsy.commonfilesearch.CentralRepoCommonAttributeInstance; +import org.sleuthkit.autopsy.commonfilesearch.CentralRepoCommonAttributeInstanceNode; import org.sleuthkit.autopsy.commonfilesearch.CommonAttributeSearchResults; import org.sleuthkit.autopsy.commonfilesearch.DataSourceLoader; -import org.sleuthkit.autopsy.commonfilesearch.CaseDBCommonAttributeInstance; import org.sleuthkit.autopsy.commonfilesearch.CommonAttributeValue; -import org.sleuthkit.autopsy.commonfilesearch.InterCaseCommonAttributeInstanceNode; -import org.sleuthkit.autopsy.commonfilesearch.InterCaseCommonAttributeSearchResults; -import org.sleuthkit.autopsy.commonfilesearch.IntraCaseCommonAttributeInstanceNode; import org.sleuthkit.autopsy.datamodel.DisplayableItemNode; import org.sleuthkit.datamodel.AbstractFile; @@ -299,19 +298,19 @@ class InterCaseUtils { int tally = 0; - for(Map.Entry> entry : searchDomain.getValues().entrySet()){ + for(Map.Entry> entry : searchDomain.getMetadata().entrySet()){ - for(CommonAttributeValue values : entry.getValue()){ + for(CommonAttributeValue value : entry.getValue()){ - for(AbstractCommonAttributeInstanceNode commonAttribute : values.getMetadata()){ + for(AbstractCommonAttributeInstance commonAttribute : value.getInstances()){ - if(commonAttribute instanceof InterCaseCommonAttributeSearchResults){ - InterCaseCommonAttributeSearchResults results = (InterCaseCommonAttributeSearchResults) commonAttribute; + if(commonAttribute instanceof CentralRepoCommonAttributeInstance){ + CentralRepoCommonAttributeInstance results = (CentralRepoCommonAttributeInstance) commonAttribute; for (DisplayableItemNode din : results.generateNodes()){ - if(din instanceof InterCaseCommonAttributeInstanceNode){ + if(din instanceof CentralRepoCommonAttributeInstanceNode){ - InterCaseCommonAttributeInstanceNode node = (InterCaseCommonAttributeInstanceNode) din; + CentralRepoCommonAttributeInstanceNode node = (CentralRepoCommonAttributeInstanceNode) din; CorrelationAttributeInstance instance = node.getCorrelationAttributeInstance(); final String fullPath = instance.getFilePath(); @@ -332,9 +331,9 @@ class InterCaseUtils { } } - if(din instanceof IntraCaseCommonAttributeInstanceNode){ + if(din instanceof CaseDBCommonAttributeInstanceNode){ - IntraCaseCommonAttributeInstanceNode node = (IntraCaseCommonAttributeInstanceNode) din; + CaseDBCommonAttributeInstanceNode node = (CaseDBCommonAttributeInstanceNode) din; AbstractFile file = node.getContent(); final String testFileName = file.getName(); diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IntraCaseUtils.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IntraCaseUtils.java index 550d46be2a..035a16a0ed 100644 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IntraCaseUtils.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IntraCaseUtils.java @@ -205,7 +205,7 @@ class IntraCaseUtils { static Map mapFileInstancesToDataSources(CommonAttributeSearchResults metadata) { Map instanceIdToDataSource = new HashMap<>(); - for (Map.Entry> entry : metadata.getValues().entrySet()) { + for (Map.Entry> entry : metadata.getMetadata().entrySet()) { for (CommonAttributeValue md : entry.getValue()) { for (AbstractCommonAttributeInstance fim : md.getInstances()) { instanceIdToDataSource.put(fim.getAbstractFileObjectId(), fim.getDataSource()); From a41073542c0e17f1ab5088dab0609ba0375cb1b9 Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Mon, 23 Jul 2018 17:44:13 -0600 Subject: [PATCH 169/287] vestigial param removed --- .../autopsy/commonfilesearch/CommonAttributeValue.java | 3 +-- .../commonfilesearch/InterCaseCommonAttributeSearcher.java | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeValue.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeValue.java index 3ed386ab10..ef6c22fe90 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeValue.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeValue.java @@ -74,9 +74,8 @@ final public class CommonAttributeValue { this.fileInstances.add(metadata); } - void addFileInstanceMetadata(AbstractCommonAttributeInstance metadata, String caseName) { + void addFileInstanceMetadata(AbstractCommonAttributeInstance metadata) { this.fileInstances.add(metadata); - // @@@ Why are we ignoring caseName? } public Collection getInstances() { diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearcher.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearcher.java index a5c5f642b7..6a1ffb5114 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearcher.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearcher.java @@ -86,14 +86,14 @@ abstract class InterCaseCommonAttributeSearcher extends AbstractCommonAttributeS final CommonAttributeValue commonAttributeValue = interCaseCommonFiles.get(md5); AbstractCommonAttributeInstance searchResult = new CentralRepoCommonAttributeInstance(commonAttrId, fileCache); - commonAttributeValue.addFileInstanceMetadata(searchResult, correlationCaseDisplayName); + commonAttributeValue.addFileInstanceMetadata(searchResult); } else { CommonAttributeValue commonAttributeValue = new CommonAttributeValue(md5); interCaseCommonFiles.put(md5, commonAttributeValue); AbstractCommonAttributeInstance searchResult = new CentralRepoCommonAttributeInstance(commonAttrId, fileCache); - commonAttributeValue.addFileInstanceMetadata(searchResult, correlationCaseDisplayName); + commonAttributeValue.addFileInstanceMetadata(searchResult); } } catch (Exception ex) { From 898448abc58448b33cf95eec28daa1430ce64afc Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Tue, 24 Jul 2018 08:27:30 -0600 Subject: [PATCH 170/287] npe in certain situations fixed --- .../sleuthkit/autopsy/commonfilesearch/IntraCasePanel.java | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCasePanel.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCasePanel.java index c88537cb17..fd83792c34 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCasePanel.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCasePanel.java @@ -20,6 +20,7 @@ package org.sleuthkit.autopsy.commonfilesearch; import java.util.Collections; +import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; import javax.swing.ComboBoxModel; @@ -41,7 +42,6 @@ public class IntraCasePanel extends javax.swing.JPanel { private String selectedDataSource; private ComboBoxModel dataSourcesList = new DataSourceComboBoxModel(); private Map dataSourceMap; - private CommonAttributePanel parent; private String errorMessage; @@ -51,10 +51,7 @@ public class IntraCasePanel extends javax.swing.JPanel { public IntraCasePanel() { initComponents(); this.errorMessage = ""; - } - - public void setParent(CommonAttributePanel parent){ - this.parent = parent; + this.dataSourceMap = new HashMap<>(); } public boolean isSingleDataSource(){ From dd44150b993b48733e507b936428599a03dfdf9a Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Tue, 24 Jul 2018 08:28:57 -0600 Subject: [PATCH 171/287] removed some dead code --- .../sleuthkit/autopsy/commonfilesearch/InterCasePanel.java | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.java index 05a7032252..2959c51078 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCasePanel.java @@ -37,9 +37,8 @@ public class InterCasePanel extends javax.swing.JPanel { static final int NO_CASE_SELECTED = -1; private ComboBoxModel casesList = new DataSourceComboBoxModel(); - private final Map caseMap; - private CommonAttributePanel parent; + private final Map caseMap; private String errorMessage; @@ -60,10 +59,6 @@ public class InterCasePanel extends javax.swing.JPanel { } } - void setParent(CommonAttributePanel parent) { - this.parent = parent; - } - String getErrorMessage(){ return this.errorMessage; } From fd2d9908f5c35e7f93a63cae3838016a885b53da Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Tue, 24 Jul 2018 08:43:55 -0600 Subject: [PATCH 172/287] renaming --- .../commonfilesearch/IntraCasePanel.java | 6 ++--- .../IngestedWithHashAndFileType.java | 10 ++++----- ...stedWithHashAndFileTypeInterCaseTests.java | 6 ++--- ...stedWithHashAndFileTypeIntraCaseTests.java | 10 ++++----- ...IngestedWithNoFileTypesIntraCaseTests.java | 14 ++++++------ ...CaseUtils.java => InterCaseTestUtils.java} | 8 +++---- ...CaseUtils.java => IntraCaseTestUtils.java} | 4 ++-- .../MatchesInAtLeastTwoSources.java | 22 +++++++++---------- .../NoCentralRepoEnabledInterCaseTests.java | 6 ++--- .../UningestedCasesIntraCaseTests.java | 8 +++---- 10 files changed, 47 insertions(+), 47 deletions(-) rename Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/{InterCaseUtils.java => InterCaseTestUtils.java} (98%) rename Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/{IntraCaseUtils.java => IntraCaseTestUtils.java} (98%) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCasePanel.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCasePanel.java index fd83792c34..89036d1824 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCasePanel.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCasePanel.java @@ -63,7 +63,7 @@ public class IntraCasePanel extends javax.swing.JPanel { return selectedDataSource; } else { return ""; - } + } } public Map getDataSourceMap(){ @@ -207,10 +207,10 @@ public class IntraCasePanel extends javax.swing.JPanel { return false; } else { return true; - } + } } String getErrorMessage() { return this.errorMessage; } -} +} \ No newline at end of file diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileType.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileType.java index 754e96dd0f..1d4923d116 100644 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileType.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileType.java @@ -35,7 +35,7 @@ import org.sleuthkit.autopsy.commonfilesearch.AbstractCommonAttributeSearcher; import org.sleuthkit.autopsy.commonfilesearch.AllIntraCaseCommonAttributeSearcher; import org.sleuthkit.autopsy.commonfilesearch.CommonAttributeSearchResults; import org.sleuthkit.autopsy.commonfilesearch.SingleIntraCaseCommonAttributeSearcher; -import static org.sleuthkit.autopsy.commonfilessearch.IntraCaseUtils.*; +import static org.sleuthkit.autopsy.commonfilessearch.IntraCaseTestUtils.*; import org.sleuthkit.autopsy.ingest.IngestJobSettings; import org.sleuthkit.autopsy.ingest.IngestJobSettings.IngestType; import org.sleuthkit.autopsy.ingest.IngestModuleTemplate; @@ -57,12 +57,12 @@ public class IngestedWithHashAndFileType extends NbTestCase { return conf.suite(); } - private final IntraCaseUtils utils; + private final IntraCaseTestUtils utils; public IngestedWithHashAndFileType(String name) { super(name); - this.utils = new IntraCaseUtils(this, "IngestedWithHashAndFileTypeTests"); + this.utils = new IntraCaseTestUtils(this, "IngestedWithHashAndFileTypeTests"); } @Override @@ -102,9 +102,9 @@ public class IngestedWithHashAndFileType extends NbTestCase { AbstractCommonAttributeSearcher allSourcesBuilder = new AllIntraCaseCommonAttributeSearcher(dataSources, false, false); CommonAttributeSearchResults metadata = allSourcesBuilder.findFiles(); - Map objectIdToDataSource = IntraCaseUtils.mapFileInstancesToDataSources(metadata); + Map objectIdToDataSource = IntraCaseTestUtils.mapFileInstancesToDataSources(metadata); - List files = IntraCaseUtils.getFiles(objectIdToDataSource.keySet()); + List files = IntraCaseTestUtils.getFiles(objectIdToDataSource.keySet()); assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET1, 2)); assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET2, 1)); diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileTypeInterCaseTests.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileTypeInterCaseTests.java index 411f7cda19..42d7a2052e 100644 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileTypeInterCaseTests.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileTypeInterCaseTests.java @@ -38,7 +38,7 @@ import org.sleuthkit.autopsy.commonfilesearch.CommonAttributeSearchResults; */ public class IngestedWithHashAndFileTypeInterCaseTests extends NbTestCase { - private final InterCaseUtils utils; + private final InterCaseTestUtils utils; private Case currentCase; @@ -51,7 +51,7 @@ public class IngestedWithHashAndFileTypeInterCaseTests extends NbTestCase { public IngestedWithHashAndFileTypeInterCaseTests(String name) { super(name); - this.utils = new InterCaseUtils(this); + this.utils = new InterCaseTestUtils(this); } @Override @@ -59,7 +59,7 @@ public class IngestedWithHashAndFileTypeInterCaseTests extends NbTestCase { this.utils.clearTestDir(); try { this.utils.enableCentralRepo(); - this.currentCase = this.utils.createCases(this.utils.getIngestSettingsForHashAndFileType(), InterCaseUtils.CASE3); + this.currentCase = this.utils.createCases(this.utils.getIngestSettingsForHashAndFileType(), InterCaseTestUtils.CASE3); } catch (Exception ex) { Exceptions.printStackTrace(ex); Assert.fail(ex); diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileTypeIntraCaseTests.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileTypeIntraCaseTests.java index dbef8cd6ca..e1f37c9b28 100644 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileTypeIntraCaseTests.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileTypeIntraCaseTests.java @@ -33,7 +33,7 @@ import org.sleuthkit.autopsy.commonfilesearch.AllIntraCaseCommonAttributeSearche import org.sleuthkit.autopsy.commonfilesearch.CommonAttributeSearchResults; import org.sleuthkit.autopsy.commonfilesearch.IntraCaseCommonAttributeSearcher; import org.sleuthkit.autopsy.commonfilesearch.SingleIntraCaseCommonAttributeSearcher; -import static org.sleuthkit.autopsy.commonfilessearch.IntraCaseUtils.*; +import static org.sleuthkit.autopsy.commonfilessearch.IntraCaseTestUtils.*; import org.sleuthkit.autopsy.ingest.IngestJobSettings; import org.sleuthkit.autopsy.ingest.IngestJobSettings.IngestType; import org.sleuthkit.autopsy.ingest.IngestModuleTemplate; @@ -55,12 +55,12 @@ public class IngestedWithHashAndFileTypeIntraCaseTests extends NbTestCase { return conf.suite(); } - private final IntraCaseUtils utils; + private final IntraCaseTestUtils utils; public IngestedWithHashAndFileTypeIntraCaseTests(String name) { super(name); - this.utils = new IntraCaseUtils(this, "IngestedWithHashAndFileTypeTests"); + this.utils = new IntraCaseTestUtils(this, "IngestedWithHashAndFileTypeTests"); } @Override @@ -100,9 +100,9 @@ public class IngestedWithHashAndFileTypeIntraCaseTests extends NbTestCase { IntraCaseCommonAttributeSearcher allSourcesBuilder = new AllIntraCaseCommonAttributeSearcher(dataSources, false, false); CommonAttributeSearchResults metadata = allSourcesBuilder.findFiles(); - Map objectIdToDataSource = IntraCaseUtils.mapFileInstancesToDataSources(metadata); + Map objectIdToDataSource = IntraCaseTestUtils.mapFileInstancesToDataSources(metadata); - List files = IntraCaseUtils.getFiles(objectIdToDataSource.keySet()); + List files = IntraCaseTestUtils.getFiles(objectIdToDataSource.keySet()); assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET1, 2)); assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET2, 1)); diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithNoFileTypesIntraCaseTests.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithNoFileTypesIntraCaseTests.java index c8f289ab72..ce56385c61 100644 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithNoFileTypesIntraCaseTests.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithNoFileTypesIntraCaseTests.java @@ -59,12 +59,12 @@ public class IngestedWithNoFileTypesIntraCaseTests extends NbTestCase { return conf.suite(); } - private final IntraCaseUtils utils; + private final IntraCaseTestUtils utils; public IngestedWithNoFileTypesIntraCaseTests(String name) { super(name); - this.utils = new IntraCaseUtils(this, "IngestedWithNoFileTypes"); + this.utils = new IntraCaseTestUtils(this, "IngestedWithNoFileTypes"); } @Override @@ -102,9 +102,9 @@ public class IngestedWithNoFileTypesIntraCaseTests extends NbTestCase { IntraCaseCommonAttributeSearcher allSourcesBuilder = new AllIntraCaseCommonAttributeSearcher(dataSources, true, false); CommonAttributeSearchResults metadata = allSourcesBuilder.findFiles(); - Map objectIdToDataSource = IntraCaseUtils.mapFileInstancesToDataSources(metadata); + Map objectIdToDataSource = IntraCaseTestUtils.mapFileInstancesToDataSources(metadata); - List files = IntraCaseUtils.getFiles(objectIdToDataSource.keySet()); + List files = IntraCaseTestUtils.getFiles(objectIdToDataSource.keySet()); assertTrue(files.isEmpty()); @@ -121,14 +121,14 @@ public class IngestedWithNoFileTypesIntraCaseTests extends NbTestCase { public void testTwo() { try { Map dataSources = this.utils.getDataSourceMap(); - Long third = IntraCaseUtils.getDataSourceIdByName(IntraCaseUtils.SET3, dataSources); + Long third = IntraCaseTestUtils.getDataSourceIdByName(IntraCaseTestUtils.SET3, dataSources); IntraCaseCommonAttributeSearcher singleSourceBuilder = new SingleIntraCaseCommonAttributeSearcher(third, dataSources, true, false); CommonAttributeSearchResults metadata = singleSourceBuilder.findFiles(); - Map objectIdToDataSource = IntraCaseUtils.mapFileInstancesToDataSources(metadata); + Map objectIdToDataSource = IntraCaseTestUtils.mapFileInstancesToDataSources(metadata); - List files = IntraCaseUtils.getFiles(objectIdToDataSource.keySet()); + List files = IntraCaseTestUtils.getFiles(objectIdToDataSource.keySet()); assertTrue(files.isEmpty()); diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/InterCaseUtils.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/InterCaseTestUtils.java similarity index 98% rename from Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/InterCaseUtils.java rename to Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/InterCaseTestUtils.java index f62348fc1e..805f227cf3 100644 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/InterCaseUtils.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/InterCaseTestUtils.java @@ -96,7 +96,7 @@ import org.sleuthkit.datamodel.AbstractFile; - Hash-C.pdf - Hash.D-doc */ -class InterCaseUtils { +class InterCaseTestUtils { private static final Path CASE_DIRECTORY_PATH = Paths.get(System.getProperty("java.io.tmpdir"), "InterCaseCommonFilesSearchTest"); private static final String CR_DB_NAME = "testcentralrepo.db"; @@ -136,7 +136,7 @@ class InterCaseUtils { private final IngestJobSettings hashAndNoFileType; private final DataSourceLoader dataSourceLoader; - InterCaseUtils(NbTestCase testCase) { + InterCaseTestUtils(NbTestCase testCase) { this.case1DataSet1Path = Paths.get(testCase.getDataDir().toString(), CASE1_DATASET_1); this.case1DataSet2Path = Paths.get(testCase.getDataDir().toString(), CASE1_DATASET_2); @@ -156,13 +156,13 @@ class InterCaseUtils { hashAndMimeTemplate.add(mimeTypeLookupTemplate); hashAndMimeTemplate.add(eamDbTemplate); - this.hashAndFileType = new IngestJobSettings(InterCaseUtils.class.getCanonicalName(), IngestType.FILES_ONLY, hashAndMimeTemplate); + this.hashAndFileType = new IngestJobSettings(InterCaseTestUtils.class.getCanonicalName(), IngestType.FILES_ONLY, hashAndMimeTemplate); ArrayList hashAndNoMimeTemplate = new ArrayList<>(1); hashAndNoMimeTemplate.add(hashLookupTemplate); hashAndMimeTemplate.add(eamDbTemplate); - this.hashAndNoFileType = new IngestJobSettings(InterCaseUtils.class.getCanonicalName(), IngestType.FILES_ONLY, hashAndNoMimeTemplate); + this.hashAndNoFileType = new IngestJobSettings(InterCaseTestUtils.class.getCanonicalName(), IngestType.FILES_ONLY, hashAndNoMimeTemplate); this.dataSourceLoader = new DataSourceLoader(); } diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IntraCaseUtils.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IntraCaseTestUtils.java similarity index 98% rename from Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IntraCaseUtils.java rename to Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IntraCaseTestUtils.java index 035a16a0ed..82c38cdf56 100644 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IntraCaseUtils.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IntraCaseTestUtils.java @@ -68,7 +68,7 @@ import org.sleuthkit.datamodel.TskCoreException; * set 4 * - file.dat (empty file) */ -class IntraCaseUtils { +class IntraCaseTestUtils { private static final String CASE_NAME = "IntraCaseCommonFilesSearchTest"; static final Path CASE_DIRECTORY_PATH = Paths.get(System.getProperty("java.io.tmpdir"), CASE_NAME); @@ -92,7 +92,7 @@ class IntraCaseUtils { private final String caseName; - IntraCaseUtils(NbTestCase nbTestCase, String caseName){ + IntraCaseTestUtils(NbTestCase nbTestCase, String caseName){ this.imagePath1 = Paths.get(nbTestCase.getDataDir().toString(), SET1); this.imagePath2 = Paths.get(nbTestCase.getDataDir().toString(), SET2); this.imagePath3 = Paths.get(nbTestCase.getDataDir().toString(), SET3); diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/MatchesInAtLeastTwoSources.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/MatchesInAtLeastTwoSources.java index 4f5fbee9fb..0f7312d80a 100644 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/MatchesInAtLeastTwoSources.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/MatchesInAtLeastTwoSources.java @@ -35,7 +35,7 @@ import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException; import org.sleuthkit.autopsy.commonfilesearch.AbstractCommonAttributeSearcher; import org.sleuthkit.autopsy.commonfilesearch.AllIntraCaseCommonAttributeSearcher; import org.sleuthkit.autopsy.commonfilesearch.CommonAttributeSearchResults; -import static org.sleuthkit.autopsy.commonfilessearch.IntraCaseUtils.*; +import static org.sleuthkit.autopsy.commonfilessearch.IntraCaseTestUtils.*; import org.sleuthkit.autopsy.ingest.IngestJobSettings; import org.sleuthkit.autopsy.ingest.IngestModuleTemplate; import org.sleuthkit.autopsy.modules.filetypeid.FileTypeIdModuleFactory; @@ -62,12 +62,12 @@ public class MatchesInAtLeastTwoSources extends NbTestCase { return conf.suite(); } - private final IntraCaseUtils utils; + private final IntraCaseTestUtils utils; public MatchesInAtLeastTwoSources(String name) { super(name); - this.utils = new IntraCaseUtils(this, "MatchesInAtLeastTwoSources"); + this.utils = new IntraCaseTestUtils(this, "MatchesInAtLeastTwoSources"); } @Override @@ -108,18 +108,18 @@ public class MatchesInAtLeastTwoSources extends NbTestCase { AbstractCommonAttributeSearcher allSourcesBuilder = new AllIntraCaseCommonAttributeSearcher(dataSources, false, false); CommonAttributeSearchResults metadata = allSourcesBuilder.findFiles(); - Map objectIdToDataSource = IntraCaseUtils.mapFileInstancesToDataSources(metadata); + Map objectIdToDataSource = IntraCaseTestUtils.mapFileInstancesToDataSources(metadata); - List files = IntraCaseUtils.getFiles(objectIdToDataSource.keySet()); + List files = IntraCaseTestUtils.getFiles(objectIdToDataSource.keySet()); - assertTrue(IntraCaseUtils.verifyInstanceExistanceAndCount(files, dataSources, IMG, SET1, 0)); - assertTrue(IntraCaseUtils.verifyInstanceExistanceAndCount(files, dataSources, IMG, SET4, 0)); + assertTrue(IntraCaseTestUtils.verifyInstanceExistanceAndCount(files, dataSources, IMG, SET1, 0)); + assertTrue(IntraCaseTestUtils.verifyInstanceExistanceAndCount(files, dataSources, IMG, SET4, 0)); - assertTrue(IntraCaseUtils.verifyInstanceExistanceAndCount(files, dataSources, DOC, SET1, 0)); - assertTrue(IntraCaseUtils.verifyInstanceExistanceAndCount(files, dataSources, DOC, SET4, 0)); + assertTrue(IntraCaseTestUtils.verifyInstanceExistanceAndCount(files, dataSources, DOC, SET1, 0)); + assertTrue(IntraCaseTestUtils.verifyInstanceExistanceAndCount(files, dataSources, DOC, SET4, 0)); - assertTrue(IntraCaseUtils.verifyInstanceExistanceAndCount(files, dataSources, EMPTY, SET1, 0)); - assertTrue(IntraCaseUtils.verifyInstanceExistanceAndCount(files, dataSources, EMPTY, SET4, 0)); + assertTrue(IntraCaseTestUtils.verifyInstanceExistanceAndCount(files, dataSources, EMPTY, SET1, 0)); + assertTrue(IntraCaseTestUtils.verifyInstanceExistanceAndCount(files, dataSources, EMPTY, SET4, 0)); } catch (NoCurrentCaseException | TskCoreException | SQLException | EamDbException ex) { Exceptions.printStackTrace(ex); diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/NoCentralRepoEnabledInterCaseTests.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/NoCentralRepoEnabledInterCaseTests.java index 03b12c83c3..1a1dbe3235 100644 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/NoCentralRepoEnabledInterCaseTests.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/NoCentralRepoEnabledInterCaseTests.java @@ -39,7 +39,7 @@ import org.sleuthkit.autopsy.commonfilesearch.CommonAttributeSearchResults; */ public class NoCentralRepoEnabledInterCaseTests extends NbTestCase { - private final InterCaseUtils utils; + private final InterCaseTestUtils utils; private Case currentCase; @@ -52,13 +52,13 @@ public class NoCentralRepoEnabledInterCaseTests extends NbTestCase { public NoCentralRepoEnabledInterCaseTests(String name) { super(name); - this.utils = new InterCaseUtils(this); + this.utils = new InterCaseTestUtils(this); } @Override public void setUp() { try { - this.currentCase = this.utils.createCases(this.utils.getIngestSettingsForHashAndFileType(), InterCaseUtils.CASE1); + this.currentCase = this.utils.createCases(this.utils.getIngestSettingsForHashAndFileType(), InterCaseTestUtils.CASE1); } catch (TskCoreException ex) { Exceptions.printStackTrace(ex); Assert.fail(ex); diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/UningestedCasesIntraCaseTests.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/UningestedCasesIntraCaseTests.java index 015ee9d4b3..26c0d66296 100644 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/UningestedCasesIntraCaseTests.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/UningestedCasesIntraCaseTests.java @@ -30,8 +30,8 @@ import org.sleuthkit.autopsy.commonfilesearch.AllIntraCaseCommonAttributeSearche import org.sleuthkit.autopsy.commonfilesearch.CommonAttributeSearchResults; import org.sleuthkit.autopsy.commonfilesearch.IntraCaseCommonAttributeSearcher; import org.sleuthkit.autopsy.commonfilesearch.SingleIntraCaseCommonAttributeSearcher; -import static org.sleuthkit.autopsy.commonfilessearch.IntraCaseUtils.SET1; -import static org.sleuthkit.autopsy.commonfilessearch.IntraCaseUtils.getDataSourceIdByName; +import static org.sleuthkit.autopsy.commonfilessearch.IntraCaseTestUtils.SET1; +import static org.sleuthkit.autopsy.commonfilessearch.IntraCaseTestUtils.getDataSourceIdByName; /** * Test that cases which are created but have not run any ingest modules turn up @@ -51,12 +51,12 @@ public class UningestedCasesIntraCaseTests extends NbTestCase { return conf.suite(); } - private final IntraCaseUtils utils; + private final IntraCaseTestUtils utils; public UningestedCasesIntraCaseTests(String name) { super(name); - this.utils = new IntraCaseUtils(this, "UningestedCasesTests"); + this.utils = new IntraCaseTestUtils(this, "UningestedCasesTests"); } @Override From 88ab16833d8b4c5f6920d9386b3bcdf0809dbceb Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Tue, 24 Jul 2018 11:57:30 -0600 Subject: [PATCH 173/287] rename some stuff for clarity --- .../IngestedWithHashAndFileType.java | 466 ------------------ ...stedWithHashAndFileTypeIntraCaseTests.java | 40 +- ...hesInAtLeastTwoSourcesIntraCaseTests.java} | 8 +- 3 files changed, 25 insertions(+), 489 deletions(-) delete mode 100644 Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileType.java rename Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/{MatchesInAtLeastTwoSources.java => MatchesInAtLeastTwoSourcesIntraCaseTests.java} (94%) diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileType.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileType.java deleted file mode 100644 index 1d4923d116..0000000000 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileType.java +++ /dev/null @@ -1,466 +0,0 @@ -/* - * - * Autopsy Forensic Browser - * - * Copyright 2018 Basis Technology Corp. - * Contact: carrier sleuthkit 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.commonfilessearch; - -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import junit.framework.Test; -import org.netbeans.junit.NbModuleSuite; -import org.netbeans.junit.NbTestCase; -import org.openide.util.Exceptions; -import org.python.icu.impl.Assert; -import org.sleuthkit.autopsy.casemodule.Case; -import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; -import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException; -import org.sleuthkit.autopsy.commonfilesearch.AbstractCommonAttributeSearcher; -import org.sleuthkit.autopsy.commonfilesearch.AllIntraCaseCommonAttributeSearcher; -import org.sleuthkit.autopsy.commonfilesearch.CommonAttributeSearchResults; -import org.sleuthkit.autopsy.commonfilesearch.SingleIntraCaseCommonAttributeSearcher; -import static org.sleuthkit.autopsy.commonfilessearch.IntraCaseTestUtils.*; -import org.sleuthkit.autopsy.ingest.IngestJobSettings; -import org.sleuthkit.autopsy.ingest.IngestJobSettings.IngestType; -import org.sleuthkit.autopsy.ingest.IngestModuleTemplate; -import org.sleuthkit.autopsy.modules.filetypeid.FileTypeIdModuleFactory; -import org.sleuthkit.autopsy.modules.hashdatabase.HashLookupModuleFactory; -import org.sleuthkit.autopsy.testutils.IngestUtils; -import org.sleuthkit.datamodel.AbstractFile; -import org.sleuthkit.datamodel.TskCoreException; - -/** - * Add set 1, set 2, set 3, and set 4 to case and ingest with hash algorithm. - */ -public class IngestedWithHashAndFileType extends NbTestCase { - - public static Test suite() { - NbModuleSuite.Configuration conf = NbModuleSuite.createConfiguration(IngestedWithHashAndFileType.class). - clusters(".*"). - enableModules(".*"); - return conf.suite(); - } - - private final IntraCaseTestUtils utils; - - public IngestedWithHashAndFileType(String name) { - super(name); - - this.utils = new IntraCaseTestUtils(this, "IngestedWithHashAndFileTypeTests"); - } - - @Override - public void setUp() { - this.utils.setUp(); - - IngestModuleTemplate hashLookupTemplate = IngestUtils.getIngestModuleTemplate(new HashLookupModuleFactory()); - IngestModuleTemplate mimeTypeLookupTemplate = IngestUtils.getIngestModuleTemplate(new FileTypeIdModuleFactory()); - - ArrayList templates = new ArrayList<>(); - templates.add(hashLookupTemplate); - templates.add(mimeTypeLookupTemplate); - - IngestJobSettings ingestJobSettings = new IngestJobSettings(IngestedWithHashAndFileType.class.getCanonicalName(), IngestType.FILES_ONLY, templates); - - try { - IngestUtils.runIngestJob(Case.getCurrentCaseThrows().getDataSources(), ingestJobSettings); - } catch (NoCurrentCaseException | TskCoreException ex) { - Exceptions.printStackTrace(ex); - Assert.fail(ex); - } - } - - @Override - public void tearDown() { - this.utils.tearDown(); - } - - /** - * Find all matches & all file types. Confirm file.jpg is found on all three - * and file.docx is found on two. - */ - public void testOneA() { - try { - Map dataSources = this.utils.getDataSourceMap(); - - AbstractCommonAttributeSearcher allSourcesBuilder = new AllIntraCaseCommonAttributeSearcher(dataSources, false, false); - CommonAttributeSearchResults metadata = allSourcesBuilder.findFiles(); - - Map objectIdToDataSource = IntraCaseTestUtils.mapFileInstancesToDataSources(metadata); - - List files = IntraCaseTestUtils.getFiles(objectIdToDataSource.keySet()); - - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET1, 2)); - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET2, 1)); - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET3, 1)); - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET4, 0)); - - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, DOC, SET1, 1)); - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, DOC, SET2, 0)); - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, DOC, SET3, 1)); - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, DOC, SET4, 0)); - - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET1, 0)); - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET2, 0)); - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET3, 0)); - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET4, 0)); - - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET1, 0)); - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET2, 0)); - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET3, 0)); - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET4, 0)); - - } catch (NoCurrentCaseException | TskCoreException | SQLException | EamDbException ex) { - Exceptions.printStackTrace(ex); - Assert.fail(ex); - } - } - - /** - * Find all matches & only image types. Confirm file.jpg is found on all - * three. - */ - public void testOneB() { - try { - Map dataSources = this.utils.getDataSourceMap(); - - AbstractCommonAttributeSearcher allSourcesBuilder = new AllIntraCaseCommonAttributeSearcher(dataSources, true, false); - CommonAttributeSearchResults metadata = allSourcesBuilder.findFiles(); - - Map objectIdToDataSource = mapFileInstancesToDataSources(metadata); - - List files = getFiles(objectIdToDataSource.keySet()); - - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET1, 2)); - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET2, 1)); - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET3, 1)); - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET4, 0)); - - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, DOC, SET1, 0)); - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, DOC, SET2, 0)); - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, DOC, SET3, 0)); - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, DOC, SET4, 0)); - - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET1, 0)); - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET2, 0)); - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET3, 0)); - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET4, 0)); - - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET1, 0)); - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET2, 0)); - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET3, 0)); - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET4, 0)); - - } catch (NoCurrentCaseException | TskCoreException | SQLException | EamDbException ex) { - Exceptions.printStackTrace(ex); - Assert.fail(ex); - } - } - - /** - * Find all matches & only image types. Confirm file.jpg is found on all - * three. - */ - public void testOneC() { - try { - Map dataSources = this.utils.getDataSourceMap(); - - AbstractCommonAttributeSearcher allSourcesBuilder = new AllIntraCaseCommonAttributeSearcher(dataSources, false, true); - CommonAttributeSearchResults metadata = allSourcesBuilder.findFiles(); - - Map objectIdToDataSource = mapFileInstancesToDataSources(metadata); - - List files = getFiles(objectIdToDataSource.keySet()); - - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET1, 0)); - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET2, 0)); - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET3, 0)); - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET4, 0)); - - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, DOC, SET1, 1)); - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, DOC, SET2, 0)); - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, DOC, SET3, 1)); - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, DOC, SET4, 0)); - - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET1, 0)); - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET2, 0)); - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET3, 0)); - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET4, 0)); - - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET1, 0)); - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET2, 0)); - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET3, 0)); - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET4, 0)); - - } catch (NoCurrentCaseException | TskCoreException | SQLException | EamDbException ex) { - Exceptions.printStackTrace(ex); - Assert.fail(ex); - } - } - - /** - * Find matches on set 1 & all file types. Confirm same results. - * - */ - public void testTwoA() { - try { - Map dataSources = this.utils.getDataSourceMap(); - Long first = getDataSourceIdByName(SET1, dataSources); - - AbstractCommonAttributeSearcher singleSourceBuilder = new SingleIntraCaseCommonAttributeSearcher(first, dataSources, false, false); - CommonAttributeSearchResults metadata = singleSourceBuilder.findFiles(); - - Map objectIdToDataSource = mapFileInstancesToDataSources(metadata); - - List files = getFiles(objectIdToDataSource.keySet()); - - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET1, 2)); - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET2, 1)); - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET3, 1)); - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET4, 0)); - - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, DOC, SET1, 1)); - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, DOC, SET2, 0)); - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, DOC, SET3, 1)); - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, DOC, SET4, 0)); - - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET1, 0)); - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET2, 0)); - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET3, 0)); - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET4, 0)); - - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET1, 0)); - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET2, 0)); - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET3, 0)); - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET4, 0)); - - } catch (NoCurrentCaseException | TskCoreException | SQLException | EamDbException ex) { - Exceptions.printStackTrace(ex); - Assert.fail(ex); - } - } - - /** - * Find matches on set 1 & only media types. Confirm same results. - * - */ - public void testTwoB() { - try { - Map dataSources = this.utils.getDataSourceMap(); - Long first = getDataSourceIdByName(SET1, dataSources); - - AbstractCommonAttributeSearcher singleSourceBuilder = new SingleIntraCaseCommonAttributeSearcher(first, dataSources, true, false); - CommonAttributeSearchResults metadata = singleSourceBuilder.findFiles(); - - Map objectIdToDataSource = mapFileInstancesToDataSources(metadata); - - List files = getFiles(objectIdToDataSource.keySet()); - - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET1, 2)); - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET2, 1)); - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET3, 1)); - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET4, 0)); - - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, DOC, SET1, 0)); - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, DOC, SET2, 0)); - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, DOC, SET3, 0)); - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, DOC, SET4, 0)); - - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET1, 0)); - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET2, 0)); - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET3, 0)); - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET4, 0)); - - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET1, 0)); - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET2, 0)); - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET3, 0)); - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET4, 0)); - - } catch (NoCurrentCaseException | TskCoreException | SQLException | EamDbException ex) { - Exceptions.printStackTrace(ex); - Assert.fail(ex); - } - } - - /** - * Find matches on set 1 & all file types. Confirm same results. - * - */ - public void testTwoC() { - try { - Map dataSources = this.utils.getDataSourceMap(); - Long first = getDataSourceIdByName(SET1, dataSources); - - AbstractCommonAttributeSearcher singleSourceBuilder = new SingleIntraCaseCommonAttributeSearcher(first, dataSources, false, true); - CommonAttributeSearchResults metadata = singleSourceBuilder.findFiles(); - - Map objectIdToDataSource = mapFileInstancesToDataSources(metadata); - - List files = getFiles(objectIdToDataSource.keySet()); - - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET1, 0)); - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET2, 0)); - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET3, 0)); - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET4, 0)); - - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, DOC, SET1, 1)); - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, DOC, SET2, 0)); - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, DOC, SET3, 1)); - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, DOC, SET4, 0)); - - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET1, 0)); - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET2, 0)); - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET3, 0)); - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET4, 0)); - - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET1, 0)); - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET2, 0)); - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET3, 0)); - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET4, 0)); - - } catch (NoCurrentCaseException | TskCoreException | SQLException | EamDbException ex) { - Exceptions.printStackTrace(ex); - Assert.fail(ex); - } - } - - /** - * Find matches on set 2 & all file types: Confirm file.jpg. - * - */ - public void testThree() { - try { - Map dataSources = this.utils.getDataSourceMap(); - Long second = getDataSourceIdByName(SET2, dataSources); - - AbstractCommonAttributeSearcher singleSourceBuilder = new SingleIntraCaseCommonAttributeSearcher(second, dataSources, false, false); - CommonAttributeSearchResults metadata = singleSourceBuilder.findFiles(); - - Map objectIdToDataSource = mapFileInstancesToDataSources(metadata); - - List files = getFiles(objectIdToDataSource.keySet()); - - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET1, 2)); - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET2, 1)); - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET3, 1)); - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET4, 0)); - - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, DOC, SET1, 0)); - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, DOC, SET2, 0)); - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, DOC, SET3, 0)); - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, DOC, SET4, 0)); - - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET1, 0)); - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET2, 0)); - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET3, 0)); - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET4, 0)); - - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET1, 0)); - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET2, 0)); - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET3, 0)); - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET4, 0)); - - } catch (NoCurrentCaseException | TskCoreException | SQLException | EamDbException ex) { - Exceptions.printStackTrace(ex); - Assert.fail(ex); - } - } - - /** - * Find matches on set 4 & all file types: Confirm nothing is found. - */ - public void testFour() { - try { - Map dataSources = this.utils.getDataSourceMap(); - Long last = getDataSourceIdByName(SET4, dataSources); - - AbstractCommonAttributeSearcher singleSourceBuilder = new SingleIntraCaseCommonAttributeSearcher(last, dataSources, false, false); - CommonAttributeSearchResults metadata = singleSourceBuilder.findFiles(); - - Map objectIdToDataSource = mapFileInstancesToDataSources(metadata); - - List files = getFiles(objectIdToDataSource.keySet()); - - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET1, 0)); - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET2, 0)); - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET3, 0)); - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET4, 0)); - - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, DOC, SET1, 0)); - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, DOC, SET1, 0)); - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, DOC, SET3, 0)); - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, DOC, SET4, 0)); - - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET1, 0)); - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET2, 0)); - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET3, 0)); - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET4, 0)); - - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET1, 0)); - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET2, 0)); - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET3, 0)); - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET4, 0)); - - } catch (NoCurrentCaseException | TskCoreException | SQLException | EamDbException ex) { - Exceptions.printStackTrace(ex); - Assert.fail(ex); - } - } - - /** - * Find matches on set 3 & all file types: Confirm file.jpg and file.docx. - */ - public void testFive() { - try { - Map dataSources = this.utils.getDataSourceMap(); - Long third = getDataSourceIdByName(SET3, dataSources); - - AbstractCommonAttributeSearcher singleSourceBuilder = new SingleIntraCaseCommonAttributeSearcher(third, dataSources, false, false); - CommonAttributeSearchResults metadata = singleSourceBuilder.findFiles(); - - Map objectIdToDataSource = mapFileInstancesToDataSources(metadata); - - List files = getFiles(objectIdToDataSource.keySet()); - - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET1, 2)); - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET2, 1)); - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET3, 1)); - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, IMG, SET4, 0)); - - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, DOC, SET1, 1)); - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, DOC, SET2, 0)); - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, DOC, SET3, 1)); - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, DOC, SET4, 0)); - - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET1, 0)); - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET2, 0)); - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET3, 0)); - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, PDF, SET4, 0)); - - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET1, 0)); - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET2, 0)); - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET3, 0)); - assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET4, 0)); - - } catch (NoCurrentCaseException | TskCoreException | SQLException | EamDbException ex) { - Exceptions.printStackTrace(ex); - Assert.fail(ex); - } - } -} diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileTypeIntraCaseTests.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileTypeIntraCaseTests.java index e1f37c9b28..d1a004d281 100644 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileTypeIntraCaseTests.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileTypeIntraCaseTests.java @@ -19,6 +19,7 @@ */ package org.sleuthkit.autopsy.commonfilessearch; +import java.sql.SQLException; import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -29,9 +30,10 @@ import org.openide.util.Exceptions; import org.python.icu.impl.Assert; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; +import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException; +import org.sleuthkit.autopsy.commonfilesearch.AbstractCommonAttributeSearcher; import org.sleuthkit.autopsy.commonfilesearch.AllIntraCaseCommonAttributeSearcher; import org.sleuthkit.autopsy.commonfilesearch.CommonAttributeSearchResults; -import org.sleuthkit.autopsy.commonfilesearch.IntraCaseCommonAttributeSearcher; import org.sleuthkit.autopsy.commonfilesearch.SingleIntraCaseCommonAttributeSearcher; import static org.sleuthkit.autopsy.commonfilessearch.IntraCaseTestUtils.*; import org.sleuthkit.autopsy.ingest.IngestJobSettings; @@ -97,7 +99,7 @@ public class IngestedWithHashAndFileTypeIntraCaseTests extends NbTestCase { try { Map dataSources = this.utils.getDataSourceMap(); - IntraCaseCommonAttributeSearcher allSourcesBuilder = new AllIntraCaseCommonAttributeSearcher(dataSources, false, false); + AbstractCommonAttributeSearcher allSourcesBuilder = new AllIntraCaseCommonAttributeSearcher(dataSources, false, false); CommonAttributeSearchResults metadata = allSourcesBuilder.findFiles(); Map objectIdToDataSource = IntraCaseTestUtils.mapFileInstancesToDataSources(metadata); @@ -124,7 +126,7 @@ public class IngestedWithHashAndFileTypeIntraCaseTests extends NbTestCase { assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET3, 0)); assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET4, 0)); - } catch (Exception ex) { + } catch (NoCurrentCaseException | TskCoreException | SQLException | EamDbException ex) { Exceptions.printStackTrace(ex); Assert.fail(ex); } @@ -138,7 +140,7 @@ public class IngestedWithHashAndFileTypeIntraCaseTests extends NbTestCase { try { Map dataSources = this.utils.getDataSourceMap(); - IntraCaseCommonAttributeSearcher allSourcesBuilder = new AllIntraCaseCommonAttributeSearcher(dataSources, true, false); + AbstractCommonAttributeSearcher allSourcesBuilder = new AllIntraCaseCommonAttributeSearcher(dataSources, true, false); CommonAttributeSearchResults metadata = allSourcesBuilder.findFiles(); Map objectIdToDataSource = mapFileInstancesToDataSources(metadata); @@ -165,7 +167,7 @@ public class IngestedWithHashAndFileTypeIntraCaseTests extends NbTestCase { assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET3, 0)); assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET4, 0)); - } catch (Exception ex) { + } catch (NoCurrentCaseException | TskCoreException | SQLException | EamDbException ex) { Exceptions.printStackTrace(ex); Assert.fail(ex); } @@ -179,7 +181,7 @@ public class IngestedWithHashAndFileTypeIntraCaseTests extends NbTestCase { try { Map dataSources = this.utils.getDataSourceMap(); - IntraCaseCommonAttributeSearcher allSourcesBuilder = new AllIntraCaseCommonAttributeSearcher(dataSources, false, true); + AbstractCommonAttributeSearcher allSourcesBuilder = new AllIntraCaseCommonAttributeSearcher(dataSources, false, true); CommonAttributeSearchResults metadata = allSourcesBuilder.findFiles(); Map objectIdToDataSource = mapFileInstancesToDataSources(metadata); @@ -206,7 +208,7 @@ public class IngestedWithHashAndFileTypeIntraCaseTests extends NbTestCase { assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET3, 0)); assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET4, 0)); - } catch (Exception ex) { + } catch (NoCurrentCaseException | TskCoreException | SQLException | EamDbException ex) { Exceptions.printStackTrace(ex); Assert.fail(ex); } @@ -221,7 +223,7 @@ public class IngestedWithHashAndFileTypeIntraCaseTests extends NbTestCase { Map dataSources = this.utils.getDataSourceMap(); Long first = getDataSourceIdByName(SET1, dataSources); - IntraCaseCommonAttributeSearcher singleSourceBuilder = new SingleIntraCaseCommonAttributeSearcher(first, dataSources, false, false); + AbstractCommonAttributeSearcher singleSourceBuilder = new SingleIntraCaseCommonAttributeSearcher(first, dataSources, false, false); CommonAttributeSearchResults metadata = singleSourceBuilder.findFiles(); Map objectIdToDataSource = mapFileInstancesToDataSources(metadata); @@ -248,7 +250,7 @@ public class IngestedWithHashAndFileTypeIntraCaseTests extends NbTestCase { assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET3, 0)); assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET4, 0)); - } catch (Exception ex) { + } catch (NoCurrentCaseException | TskCoreException | SQLException | EamDbException ex) { Exceptions.printStackTrace(ex); Assert.fail(ex); } @@ -263,7 +265,7 @@ public class IngestedWithHashAndFileTypeIntraCaseTests extends NbTestCase { Map dataSources = this.utils.getDataSourceMap(); Long first = getDataSourceIdByName(SET1, dataSources); - IntraCaseCommonAttributeSearcher singleSourceBuilder = new SingleIntraCaseCommonAttributeSearcher(first, dataSources, true, false); + AbstractCommonAttributeSearcher singleSourceBuilder = new SingleIntraCaseCommonAttributeSearcher(first, dataSources, true, false); CommonAttributeSearchResults metadata = singleSourceBuilder.findFiles(); Map objectIdToDataSource = mapFileInstancesToDataSources(metadata); @@ -290,7 +292,7 @@ public class IngestedWithHashAndFileTypeIntraCaseTests extends NbTestCase { assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET3, 0)); assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET4, 0)); - } catch (Exception ex) { + } catch (NoCurrentCaseException | TskCoreException | SQLException | EamDbException ex) { Exceptions.printStackTrace(ex); Assert.fail(ex); } @@ -305,7 +307,7 @@ public class IngestedWithHashAndFileTypeIntraCaseTests extends NbTestCase { Map dataSources = this.utils.getDataSourceMap(); Long first = getDataSourceIdByName(SET1, dataSources); - IntraCaseCommonAttributeSearcher singleSourceBuilder = new SingleIntraCaseCommonAttributeSearcher(first, dataSources, false, true); + AbstractCommonAttributeSearcher singleSourceBuilder = new SingleIntraCaseCommonAttributeSearcher(first, dataSources, false, true); CommonAttributeSearchResults metadata = singleSourceBuilder.findFiles(); Map objectIdToDataSource = mapFileInstancesToDataSources(metadata); @@ -332,7 +334,7 @@ public class IngestedWithHashAndFileTypeIntraCaseTests extends NbTestCase { assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET3, 0)); assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET4, 0)); - } catch (Exception ex) { + } catch (NoCurrentCaseException | TskCoreException | SQLException | EamDbException ex) { Exceptions.printStackTrace(ex); Assert.fail(ex); } @@ -347,7 +349,7 @@ public class IngestedWithHashAndFileTypeIntraCaseTests extends NbTestCase { Map dataSources = this.utils.getDataSourceMap(); Long second = getDataSourceIdByName(SET2, dataSources); - IntraCaseCommonAttributeSearcher singleSourceBuilder = new SingleIntraCaseCommonAttributeSearcher(second, dataSources, false, false); + AbstractCommonAttributeSearcher singleSourceBuilder = new SingleIntraCaseCommonAttributeSearcher(second, dataSources, false, false); CommonAttributeSearchResults metadata = singleSourceBuilder.findFiles(); Map objectIdToDataSource = mapFileInstancesToDataSources(metadata); @@ -374,7 +376,7 @@ public class IngestedWithHashAndFileTypeIntraCaseTests extends NbTestCase { assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET3, 0)); assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET4, 0)); - } catch (Exception ex) { + } catch (NoCurrentCaseException | TskCoreException | SQLException | EamDbException ex) { Exceptions.printStackTrace(ex); Assert.fail(ex); } @@ -388,7 +390,7 @@ public class IngestedWithHashAndFileTypeIntraCaseTests extends NbTestCase { Map dataSources = this.utils.getDataSourceMap(); Long last = getDataSourceIdByName(SET4, dataSources); - IntraCaseCommonAttributeSearcher singleSourceBuilder = new SingleIntraCaseCommonAttributeSearcher(last, dataSources, false, false); + AbstractCommonAttributeSearcher singleSourceBuilder = new SingleIntraCaseCommonAttributeSearcher(last, dataSources, false, false); CommonAttributeSearchResults metadata = singleSourceBuilder.findFiles(); Map objectIdToDataSource = mapFileInstancesToDataSources(metadata); @@ -415,7 +417,7 @@ public class IngestedWithHashAndFileTypeIntraCaseTests extends NbTestCase { assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET3, 0)); assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET4, 0)); - } catch (Exception ex) { + } catch (NoCurrentCaseException | TskCoreException | SQLException | EamDbException ex) { Exceptions.printStackTrace(ex); Assert.fail(ex); } @@ -429,7 +431,7 @@ public class IngestedWithHashAndFileTypeIntraCaseTests extends NbTestCase { Map dataSources = this.utils.getDataSourceMap(); Long third = getDataSourceIdByName(SET3, dataSources); - IntraCaseCommonAttributeSearcher singleSourceBuilder = new SingleIntraCaseCommonAttributeSearcher(third, dataSources, false, false); + AbstractCommonAttributeSearcher singleSourceBuilder = new SingleIntraCaseCommonAttributeSearcher(third, dataSources, false, false); CommonAttributeSearchResults metadata = singleSourceBuilder.findFiles(); Map objectIdToDataSource = mapFileInstancesToDataSources(metadata); @@ -456,7 +458,7 @@ public class IngestedWithHashAndFileTypeIntraCaseTests extends NbTestCase { assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET3, 0)); assertTrue(verifyInstanceExistanceAndCount(files, objectIdToDataSource, EMPTY, SET4, 0)); - } catch (Exception ex) { + } catch (NoCurrentCaseException | TskCoreException | SQLException | EamDbException ex) { Exceptions.printStackTrace(ex); Assert.fail(ex); } diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/MatchesInAtLeastTwoSources.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/MatchesInAtLeastTwoSourcesIntraCaseTests.java similarity index 94% rename from Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/MatchesInAtLeastTwoSources.java rename to Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/MatchesInAtLeastTwoSourcesIntraCaseTests.java index 0f7312d80a..f4c397af8d 100644 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/MatchesInAtLeastTwoSources.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/MatchesInAtLeastTwoSourcesIntraCaseTests.java @@ -53,10 +53,10 @@ import org.sleuthkit.datamodel.TskCoreException; * * None of the test files should be found in the results of this test. */ -public class MatchesInAtLeastTwoSources extends NbTestCase { +public class MatchesInAtLeastTwoSourcesIntraCaseTests extends NbTestCase { public static Test suite() { - NbModuleSuite.Configuration conf = NbModuleSuite.createConfiguration(MatchesInAtLeastTwoSources.class). + NbModuleSuite.Configuration conf = NbModuleSuite.createConfiguration(MatchesInAtLeastTwoSourcesIntraCaseTests.class). clusters(".*"). enableModules(".*"); return conf.suite(); @@ -64,7 +64,7 @@ public class MatchesInAtLeastTwoSources extends NbTestCase { private final IntraCaseTestUtils utils; - public MatchesInAtLeastTwoSources(String name) { + public MatchesInAtLeastTwoSourcesIntraCaseTests(String name) { super(name); this.utils = new IntraCaseTestUtils(this, "MatchesInAtLeastTwoSources"); @@ -86,7 +86,7 @@ public class MatchesInAtLeastTwoSources extends NbTestCase { templates.add(hashLookupTemplate); templates.add(mimeTypeLookupTemplate); - IngestJobSettings ingestJobSettings = new IngestJobSettings(IngestedWithHashAndFileType.class.getCanonicalName(), IngestJobSettings.IngestType.FILES_ONLY, templates); + IngestJobSettings ingestJobSettings = new IngestJobSettings(IngestedWithHashAndFileTypeIntraCaseTests.class.getCanonicalName(), IngestJobSettings.IngestType.FILES_ONLY, templates); try { IngestUtils.runIngestJob(Case.getCurrentCaseThrows().getDataSources(), ingestJobSettings); From d71bfe99fe2a9b88124c657bd42981ff2b53be6d Mon Sep 17 00:00:00 2001 From: Andrew Ziehl Date: Tue, 24 Jul 2018 11:26:38 -0700 Subject: [PATCH 174/287] Remove for loop, add md5 qualifier to AbstractFile lookup --- .../AbstractCommonAttributeInstance.java | 5 +- .../CentralRepoCommonAttributeInstance.java | 58 +++++++++---------- .../datamodel/CentralRepoDatamodelTest.java | 54 +---------------- 3 files changed, 31 insertions(+), 86 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeInstance.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeInstance.java index 6f445ca0a3..e75dc7b208 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeInstance.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeInstance.java @@ -20,6 +20,7 @@ package org.sleuthkit.autopsy.commonfilesearch; import java.util.Map; +import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttribute; import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance; import org.sleuthkit.autopsy.datamodel.DisplayableItemNode; import org.sleuthkit.datamodel.AbstractFile; @@ -168,10 +169,10 @@ public abstract class AbstractCommonAttributeInstance { * @return the appropriate leaf node for the results tree * @throws TskCoreException */ - static DisplayableItemNode createInstance(CorrelationAttributeInstance attributeInstance, AbstractFile equivalentAbstractFile, String currentCaseName) throws TskCoreException { + static DisplayableItemNode createInstance(CorrelationAttribute attribute, AbstractFile equivalentAbstractFile, String currentCaseName) throws TskCoreException { DisplayableItemNode leafNode; - + CorrelationAttributeInstance attributeInstance = attribute.getInstances().get(0); final String attributeDataSourceName = attributeInstance.getCorrelationDataSource().getName(); final String abstractFileDataSourceName = equivalentAbstractFile.getDataSource().getName(); diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepoCommonAttributeInstance.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepoCommonAttributeInstance.java index e720cef635..d1bb03c56e 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepoCommonAttributeInstance.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepoCommonAttributeInstance.java @@ -27,7 +27,6 @@ import java.util.logging.Level; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttribute; -import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.datamodel.DisplayableItemNode; import org.sleuthkit.datamodel.AbstractFile; @@ -43,40 +42,41 @@ final public class CentralRepoCommonAttributeInstance extends AbstractCommonAttr private static final Logger LOGGER = Logger.getLogger(CentralRepoCommonAttributeInstance.class.getName()); private final Integer crFileId; - private CorrelationAttributeInstance currentAttributeInstance; + private CorrelationAttribute currentAttribute; CentralRepoCommonAttributeInstance(Integer attrInstId, Map cachedFiles) { super(cachedFiles); this.crFileId = attrInstId; } - void setCurrentAttributeInst(CorrelationAttributeInstance attributeInstance) { - this.currentAttributeInstance = attributeInstance; + void setCurrentAttributeInst(CorrelationAttribute attribute) { + this.currentAttribute = attribute; } @Override AbstractFile getAbstractFile() { Case currentCase; - // @@@ Need to CHeck for NULL. This seems to depend on generateNodes to be called first - String currentFullPath = this.currentAttributeInstance.getFilePath(); + if (this.currentAttribute != null) { + String currentFullPath = this.currentAttribute.getInstances().get(0).getFilePath(); + try { + currentCase = Case.getCurrentCaseThrows(); - try { - currentCase = Case.getCurrentCaseThrows(); + SleuthkitCase tskDb = currentCase.getSleuthkitCase(); + + File fileFromPath = new File(currentFullPath); + String fileName = fileFromPath.getName(); - SleuthkitCase tskDb = currentCase.getSleuthkitCase(); - File fileFromPath = new File(currentFullPath); - String fileName = fileFromPath.getName(); - //TODO this seems like a flaw - //i think we should search by md5, name and file path - AbstractFile abstractFile = tskDb.findAllFilesWhere(String.format("lower(name) = '%s'", fileName)).get(0); + AbstractFile abstractFile = tskDb.findAllFilesWhere(String.format("lower(name) = '%s' AND md5 = '%s'", fileName, currentAttribute.getCorrelationValue())).get(0); - return abstractFile; + return abstractFile; - } catch (TskCoreException | NoCurrentCaseException ex) { - LOGGER.log(Level.SEVERE, String.format("Unable to find AbstractFile for record with filePath: %s. Node not created.", new Object[]{currentFullPath}), ex); - return null; + } catch (TskCoreException | NoCurrentCaseException ex) { + LOGGER.log(Level.SEVERE, String.format("Unable to find AbstractFile for record with filePath: %s. Node not created.", new Object[]{currentFullPath}), ex); + return null; + } } + return null; } @Override @@ -88,22 +88,18 @@ final public class CentralRepoCommonAttributeInstance extends AbstractCommonAttr CorrelationAttribute corrAttr = eamDbAttrInst.findSingleCorrelationAttribute(crFileId); List attrInstNodeList = new ArrayList<>(0); String currCaseDbName = Case.getCurrentCase().getDisplayName(); - - // @@@ This seems wrong that we are looping here, but only setting one attrInst in the class, which is then used by getAbstractFile(). - for (CorrelationAttributeInstance attrInst : corrAttr.getInstances()) { - try { - this.setCurrentAttributeInst(attrInst); - - AbstractFile equivalentAbstractFile = this.lookupOrLoadAbstractFile(); - - DisplayableItemNode generatedInstNode = AbstractCommonAttributeInstance.createInstance(attrInst, equivalentAbstractFile, currCaseDbName); - attrInstNodeList.add(generatedInstNode); + try { + this.setCurrentAttributeInst(corrAttr); - } catch (TskCoreException ex) { - LOGGER.log(Level.SEVERE, String.format("Unable to get DataSource for record with filePath: %s. Node not created.", new Object[]{attrInst.getFilePath()}), ex); - } + AbstractFile equivalentAbstractFile = this.lookupOrLoadAbstractFile(); + DisplayableItemNode generatedInstNode = AbstractCommonAttributeInstance.createInstance(corrAttr, equivalentAbstractFile, currCaseDbName); + attrInstNodeList.add(generatedInstNode); + + } catch (TskCoreException ex) { + LOGGER.log(Level.SEVERE, String.format("Unable to get DataSource for record with md5: %s. Node not created.", new Object[]{corrAttr.getCorrelationValue()}), ex); } + return attrInstNodeList.toArray(new DisplayableItemNode[attrInstNodeList.size()]); } } diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDatamodelTest.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDatamodelTest.java index 030f53ed31..5f82571576 100755 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDatamodelTest.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDatamodelTest.java @@ -853,49 +853,8 @@ public class CentralRepoDatamodelTest extends TestCase { Assert.fail(ex); } - // Test getting common instances with expected results - try { - List instances = EamDb.getInstance().getArtifactInstancesByCaseValues(Arrays.asList(inAllDataSourcesHash, inDataSource1twiceHash)); - assertTrue("getArtifactInstancesByCaseValues returned " + instances.size() + " results - expected 5", instances.size() == 5); - - // This test works because all the instances of this hash were set to the same path - for (CentralRepositoryFile inst : instances) { - if(inst.getValue().equals(inAllDataSourcesHash)) { - assertTrue("getArtifactInstancesByCaseValues returned instance with unexpected path " + inst.getFilePath(), - inAllDataSourcesPath.equalsIgnoreCase(inst.getFilePath())); - } - else if(inst.getValue().equals(inDataSource1twiceHash)) { - assertTrue("getArtifactInstancesByCaseValues returned instance with unexpected path " + inst.getFilePath(), - inDataSource1twicePath1.equalsIgnoreCase(inst.getFilePath()) || inDataSource1twicePath2.equalsIgnoreCase(inst.getFilePath())); - } - } - } catch (EamDbException ex) { - Exceptions.printStackTrace(ex); - Assert.fail(ex); - } - - // Test getting instances expecting no results because they are not in the case - try { - CorrelationCase badCase = new CorrelationCase("badCaseUuid", "badCaseName"); - List instances = EamDb.getInstance().getArtifactInstancesByCaseValues(badCase, Arrays.asList(inAllDataSourcesHash, inDataSource1twiceHash), 0); - - assertTrue("getArtifactInstancesByTypeValue returned " + instances.size() + " results - expected 0", instances.isEmpty()); - } catch (EamDbException ex) { - Exceptions.printStackTrace(ex); - Assert.fail(ex); - } - - - // Test getting instances expecting no results because of bad hashes - try { - List instances = EamDb.getInstance().getArtifactInstancesByCaseValues(Arrays.asList("xyz", "123")); - - assertTrue("getArtifactInstancesByTypeValue returned " + instances.size() + " results - expected 0", instances.isEmpty()); - } catch (EamDbException ex) { - Exceptions.printStackTrace(ex); - Assert.fail(ex); - } + // Test getting instances expecting no results try { @@ -924,17 +883,6 @@ public class CentralRepoDatamodelTest extends TestCase { Exceptions.printStackTrace(ex); Assert.fail(ex); } - - // Test getting instances with null value - // Should just return nothing - try { - List instances = EamDb.getInstance().getArtifactInstancesByCaseValues(null); - - assertTrue("getArtifactInstancesByTypeValue returned non-empty list for null value", instances.isEmpty()); - } catch (EamDbException ex) { - Exceptions.printStackTrace(ex); - Assert.fail(ex); - } // Test getting instances with path that should produce results try { From a758fbe779d04d01426ee6b9d1c70297a13fafc3 Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Tue, 24 Jul 2018 12:42:52 -0600 Subject: [PATCH 175/287] comment out broken stuff for the moment --- .../datamodel/CentralRepoDatamodelTest.java | 104 +++++++++--------- 1 file changed, 52 insertions(+), 52 deletions(-) diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDatamodelTest.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDatamodelTest.java index 030f53ed31..9103906278 100755 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDatamodelTest.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDatamodelTest.java @@ -853,48 +853,48 @@ public class CentralRepoDatamodelTest extends TestCase { Assert.fail(ex); } - // Test getting common instances with expected results - try { - List instances = EamDb.getInstance().getArtifactInstancesByCaseValues(Arrays.asList(inAllDataSourcesHash, inDataSource1twiceHash)); - assertTrue("getArtifactInstancesByCaseValues returned " + instances.size() + " results - expected 5", instances.size() == 5); - - // This test works because all the instances of this hash were set to the same path - for (CentralRepositoryFile inst : instances) { - if(inst.getValue().equals(inAllDataSourcesHash)) { - assertTrue("getArtifactInstancesByCaseValues returned instance with unexpected path " + inst.getFilePath(), - inAllDataSourcesPath.equalsIgnoreCase(inst.getFilePath())); - } - else if(inst.getValue().equals(inDataSource1twiceHash)) { - assertTrue("getArtifactInstancesByCaseValues returned instance with unexpected path " + inst.getFilePath(), - inDataSource1twicePath1.equalsIgnoreCase(inst.getFilePath()) || inDataSource1twicePath2.equalsIgnoreCase(inst.getFilePath())); - } - } - } catch (EamDbException ex) { - Exceptions.printStackTrace(ex); - Assert.fail(ex); - } - - // Test getting instances expecting no results because they are not in the case - try { - CorrelationCase badCase = new CorrelationCase("badCaseUuid", "badCaseName"); - List instances = EamDb.getInstance().getArtifactInstancesByCaseValues(badCase, Arrays.asList(inAllDataSourcesHash, inDataSource1twiceHash), 0); - - assertTrue("getArtifactInstancesByTypeValue returned " + instances.size() + " results - expected 0", instances.isEmpty()); - } catch (EamDbException ex) { - Exceptions.printStackTrace(ex); - Assert.fail(ex); - } - - - // Test getting instances expecting no results because of bad hashes - try { - List instances = EamDb.getInstance().getArtifactInstancesByCaseValues(Arrays.asList("xyz", "123")); - - assertTrue("getArtifactInstancesByTypeValue returned " + instances.size() + " results - expected 0", instances.isEmpty()); - } catch (EamDbException ex) { - Exceptions.printStackTrace(ex); - Assert.fail(ex); - } +// // Test getting common instances with expected results +// try { +// List instances = EamDb.getInstance().getArtifactInstancesByCaseValues(Arrays.asList(inAllDataSourcesHash, inDataSource1twiceHash)); +// assertTrue("getArtifactInstancesByCaseValues returned " + instances.size() + " results - expected 5", instances.size() == 5); +// +// // This test works because all the instances of this hash were set to the same path +// for (CentralRepositoryFile inst : instances) { +// if(inst.getValue().equals(inAllDataSourcesHash)) { +// assertTrue("getArtifactInstancesByCaseValues returned instance with unexpected path " + inst.getFilePath(), +// inAllDataSourcesPath.equalsIgnoreCase(inst.getFilePath())); +// } +// else if(inst.getValue().equals(inDataSource1twiceHash)) { +// assertTrue("getArtifactInstancesByCaseValues returned instance with unexpected path " + inst.getFilePath(), +// inDataSource1twicePath1.equalsIgnoreCase(inst.getFilePath()) || inDataSource1twicePath2.equalsIgnoreCase(inst.getFilePath())); +// } +// } +// } catch (EamDbException ex) { +// Exceptions.printStackTrace(ex); +// Assert.fail(ex); +// } +// +// // Test getting instances expecting no results because they are not in the case +// try { +// CorrelationCase badCase = new CorrelationCase("badCaseUuid", "badCaseName"); +// List instances = EamDb.getInstance().getArtifactInstancesByCaseValues(badCase, Arrays.asList(inAllDataSourcesHash, inDataSource1twiceHash), 0); +// +// assertTrue("getArtifactInstancesByTypeValue returned " + instances.size() + " results - expected 0", instances.isEmpty()); +// } catch (EamDbException ex) { +// Exceptions.printStackTrace(ex); +// Assert.fail(ex); +// } +// +// +// // Test getting instances expecting no results because of bad hashes +// try { +// List instances = EamDb.getInstance().getArtifactInstancesByCaseValues(Arrays.asList("xyz", "123")); +// +// assertTrue("getArtifactInstancesByTypeValue returned " + instances.size() + " results - expected 0", instances.isEmpty()); +// } catch (EamDbException ex) { +// Exceptions.printStackTrace(ex); +// Assert.fail(ex); +// } // Test getting instances expecting no results @@ -925,16 +925,16 @@ public class CentralRepoDatamodelTest extends TestCase { Assert.fail(ex); } - // Test getting instances with null value - // Should just return nothing - try { - List instances = EamDb.getInstance().getArtifactInstancesByCaseValues(null); - - assertTrue("getArtifactInstancesByTypeValue returned non-empty list for null value", instances.isEmpty()); - } catch (EamDbException ex) { - Exceptions.printStackTrace(ex); - Assert.fail(ex); - } +// // Test getting instances with null value +// // Should just return nothing +// try { +// List instances = EamDb.getInstance().getArtifactInstancesByCaseValues(null); +// +// assertTrue("getArtifactInstancesByTypeValue returned non-empty list for null value", instances.isEmpty()); +// } catch (EamDbException ex) { +// Exceptions.printStackTrace(ex); +// Assert.fail(ex); +// } // Test getting instances with path that should produce results try { From 22768a6ed5c793ad0184955f4f19f234dc22d0c4 Mon Sep 17 00:00:00 2001 From: Eugene Livis Date: Tue, 24 Jul 2018 15:34:37 -0400 Subject: [PATCH 176/287] First cut at prototyping the solution --- .../AdHocSearchChildFactory.java | 12 +++++--- .../keywordsearch/AdHocSearchDelegator.java | 4 +-- .../keywordsearch/AdHocSearchPanel.java | 4 +-- .../DropdownListSearchPanel.java | 2 +- .../DropdownSingleTermSearchPanel.java | 2 +- .../keywordsearch/IngestSearchRunner.java | 2 +- .../autopsy/keywordsearch/QueryResults.java | 29 ++++++++++--------- 7 files changed, 31 insertions(+), 24 deletions(-) diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/AdHocSearchChildFactory.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/AdHocSearchChildFactory.java index accc19cb9a..2e58fa01e6 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/AdHocSearchChildFactory.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/AdHocSearchChildFactory.java @@ -83,9 +83,11 @@ class AdHocSearchChildFactory extends ChildFactory { .collect(Collectors.toList()); private final Collection queryRequests; + private final boolean saveResults; - AdHocSearchChildFactory(Collection queryRequests) { + AdHocSearchChildFactory(Collection queryRequests, boolean saveResults) { this.queryRequests = queryRequests; + this.saveResults = saveResults; } /** @@ -223,7 +225,7 @@ class AdHocSearchChildFactory extends ChildFactory { //cannot reuse snippet in BlackboardResultWriter //because for regex searches in UI we compress results by showing a content per regex once (even if multiple term hits) //whereas in bb we write every hit per content separately - new BlackboardResultWriter(queryResults, queryRequest.getKeywordList().getName()).execute(); + new BlackboardResultWriter(queryResults, queryRequest.getKeywordList().getName(), saveResults).execute(); return true; } @@ -396,10 +398,12 @@ class AdHocSearchChildFactory extends ChildFactory { private final KeywordSearchQuery query; private final QueryResults hits; private static final int QUERY_DISPLAY_LEN = 40; + private final boolean saveResults; - BlackboardResultWriter(QueryResults hits, String listName) { + BlackboardResultWriter(QueryResults hits, String listName, boolean saveResults) { this.hits = hits; this.query = hits.getQuery(); + this.saveResults = saveResults; } protected void finalizeWorker() { @@ -414,7 +418,7 @@ class AdHocSearchChildFactory extends ChildFactory { final String queryDisp = queryStr.length() > QUERY_DISPLAY_LEN ? queryStr.substring(0, QUERY_DISPLAY_LEN - 1) + " ..." : queryStr; try { progress = ProgressHandle.createHandle(NbBundle.getMessage(this.getClass(), "KeywordSearchResultFactory.progress.saving", queryDisp), () -> BlackboardResultWriter.this.cancel(true)); - hits.process(progress, null, this, false); + hits.process(progress, null, this, false, saveResults); } finally { finalizeWorker(); } diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/AdHocSearchDelegator.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/AdHocSearchDelegator.java index c085af7a30..4b9a229785 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/AdHocSearchDelegator.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/AdHocSearchDelegator.java @@ -75,7 +75,7 @@ class AdHocSearchDelegator { * Execute the keyword search based on keywords passed into constructor. * Post results into a new DataResultViewer. */ - public void execute() { + public void execute(boolean saveResults) { Collection queryRequests = new ArrayList<>(); int queryID = 0; StringBuilder queryConcat = new StringBuilder(); // concatenation of all query strings @@ -95,7 +95,7 @@ class AdHocSearchDelegator { Node rootNode; if (queryRequests.size() > 0) { Children childNodes = - Children.create(new AdHocSearchChildFactory(queryRequests), true); + Children.create(new AdHocSearchChildFactory(queryRequests, saveResults), true); rootNode = new AbstractNode(childNodes); } else { diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/AdHocSearchPanel.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/AdHocSearchPanel.java index a8dbfb6268..ec75de032e 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/AdHocSearchPanel.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/AdHocSearchPanel.java @@ -99,7 +99,7 @@ abstract class AdHocSearchPanel extends javax.swing.JPanel { * Performs the search using the selected keywords. Creates a * DataResultTopComponent with the results. */ - public void search() { + public void search(boolean saveResults) { boolean isIngestRunning = IngestManager.getInstance().isIngestRunning(); if (filesIndexed == 0) { @@ -138,7 +138,7 @@ abstract class AdHocSearchPanel extends javax.swing.JPanel { AdHocSearchDelegator man = new AdHocSearchDelegator(keywordLists, getDataSourcesSelected()); if (man.validate()) { - man.execute(); + man.execute(saveResults); } else { KeywordSearchUtil.displayDialog(keywordSearchErrorDialogHeader, NbBundle.getMessage(this.getClass(), "AbstractKeywordSearchPerformer.search.invalidSyntaxHeader"), KeywordSearchUtil.DIALOG_MESSAGE_TYPE.ERROR); diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/DropdownListSearchPanel.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/DropdownListSearchPanel.java index 0c7566f52e..81611c130a 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/DropdownListSearchPanel.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/DropdownListSearchPanel.java @@ -333,7 +333,7 @@ class DropdownListSearchPanel extends AdHocSearchPanel { setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); try { - search(); + search(true); // ELTOD do we always want o save these? } finally { setCursor(null); } diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/DropdownSingleTermSearchPanel.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/DropdownSingleTermSearchPanel.java index bdc80084c7..2ed59d253e 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/DropdownSingleTermSearchPanel.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/DropdownSingleTermSearchPanel.java @@ -340,7 +340,7 @@ public class DropdownSingleTermSearchPanel extends AdHocSearchPanel { */ private void keywordTextFieldActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_keywordTextFieldActionPerformed try { - search(); + search(false); // ELTODO get the checkbox value } catch (Exception e) { LOGGER.log(Level.SEVERE, "Error performing ad hoc single keyword search", e); //NON-NLS } diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/IngestSearchRunner.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/IngestSearchRunner.java index 70fd3ba370..cea9fd1a82 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/IngestSearchRunner.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/IngestSearchRunner.java @@ -563,7 +563,7 @@ final class IngestSearchRunner { subProgresses[keywordsSearched].progress(keywordList.getName() + ": " + queryDisplayStr, unitProgress); // Create blackboard artifacts - newResults.process(null, subProgresses[keywordsSearched], this, keywordList.getIngestMessages()); + newResults.process(null, subProgresses[keywordsSearched], this, keywordList.getIngestMessages(), true); } //if has results diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/QueryResults.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/QueryResults.java index e27a01b063..5f672f5f03 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/QueryResults.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/QueryResults.java @@ -143,7 +143,7 @@ class QueryResults { * exrtacted from the text source object. * */ - void process(ProgressHandle progress, ProgressContributor subProgress, SwingWorker worker, boolean notifyInbox) { + void process(ProgressHandle progress, ProgressContributor subProgress, SwingWorker worker, boolean notifyInbox, boolean saveResults) { /* * Initialize the progress indicator to the number of keywords that will * be processed. @@ -218,22 +218,25 @@ class QueryResults { } catch (TskCoreException | NoCurrentCaseException tskCoreException) { logger.log(Level.SEVERE, "Failed to get text source object for ", tskCoreException); //NON-NLS } + + if (saveResults) { - /* + /* * Post an artifact for the hit to the blackboard. - */ - BlackboardArtifact artifact = query.postKeywordHitToBlackboard(content, keyword, hit, snippet, query.getKeywordList().getName()); + */ + BlackboardArtifact artifact = query.postKeywordHitToBlackboard(content, keyword, hit, snippet, query.getKeywordList().getName()); - /* + /* * Send an ingest inbox message for the hit. - */ - if (null != artifact) { - hitArtifacts.add(artifact); - if (notifyInbox) { - try { - writeSingleFileInboxMessage(artifact, content); - } catch (TskCoreException ex) { - logger.log(Level.SEVERE, "Error sending message to ingest messages inbox", ex); //NON-NLS + */ + if (null != artifact) { + hitArtifacts.add(artifact); + if (notifyInbox) { + try { + writeSingleFileInboxMessage(artifact, content); + } catch (TskCoreException ex) { + logger.log(Level.SEVERE, "Error sending message to ingest messages inbox", ex); //NON-NLS + } } } } From 8e7825de5f0eadccfab0705afe3bf6f8618ade6e Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Tue, 24 Jul 2018 13:56:45 -0600 Subject: [PATCH 177/287] cleanup --- .../IngestedWithHashAndFileTypeInterCaseTests.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileTypeInterCaseTests.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileTypeInterCaseTests.java index 42d7a2052e..a36f8322e1 100644 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileTypeInterCaseTests.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileTypeInterCaseTests.java @@ -28,6 +28,10 @@ import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.commonfilesearch.AbstractCommonAttributeSearcher; import org.sleuthkit.autopsy.commonfilesearch.AllInterCaseCommonAttributeSearcher; import org.sleuthkit.autopsy.commonfilesearch.CommonAttributeSearchResults; +import static org.sleuthkit.autopsy.commonfilessearch.InterCaseTestUtils.CASE1; +import static org.sleuthkit.autopsy.commonfilessearch.InterCaseTestUtils.CASE1_DATASET_1; +import static org.sleuthkit.autopsy.commonfilessearch.InterCaseTestUtils.HASH_A_JPG; +import static org.sleuthkit.autopsy.commonfilessearch.InterCaseTestUtils.verifyInstanceExistanceAndCount; /** * If I use the search all cases option: One node for Hash A (1_1_A.jpg, @@ -72,7 +76,7 @@ public class IngestedWithHashAndFileTypeInterCaseTests extends NbTestCase { } /** - * Search All + * Search All cases * * One node for Hash A (1_1_A.jpg, 1_2_A.jpg, 3_1_A.jpg) */ @@ -85,7 +89,7 @@ public class IngestedWithHashAndFileTypeInterCaseTests extends NbTestCase { assertTrue("Results should not be empty", metadata.size() != 0); - //assertTrue("") + assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_A_JPG, CASE1_DATASET_1, CASE1, 1)); } catch (Exception ex) { From 25f7cc5ef536edba4e0e029b3491714d6690fa39 Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Tue, 24 Jul 2018 13:58:18 -0600 Subject: [PATCH 178/287] may still need this variable? --- .../IngestedWithHashAndFileTypeInterCaseTests.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileTypeInterCaseTests.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileTypeInterCaseTests.java index a36f8322e1..2e6ca7d9d0 100644 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileTypeInterCaseTests.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileTypeInterCaseTests.java @@ -28,10 +28,7 @@ import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.commonfilesearch.AbstractCommonAttributeSearcher; import org.sleuthkit.autopsy.commonfilesearch.AllInterCaseCommonAttributeSearcher; import org.sleuthkit.autopsy.commonfilesearch.CommonAttributeSearchResults; -import static org.sleuthkit.autopsy.commonfilessearch.InterCaseTestUtils.CASE1; -import static org.sleuthkit.autopsy.commonfilessearch.InterCaseTestUtils.CASE1_DATASET_1; -import static org.sleuthkit.autopsy.commonfilessearch.InterCaseTestUtils.HASH_A_JPG; -import static org.sleuthkit.autopsy.commonfilessearch.InterCaseTestUtils.verifyInstanceExistanceAndCount; +import static org.sleuthkit.autopsy.commonfilessearch.InterCaseTestUtils.*; /** * If I use the search all cases option: One node for Hash A (1_1_A.jpg, From 0468b6bd597a63c424d81b8569bb3df3bf8f7530 Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Tue, 24 Jul 2018 16:17:26 -0600 Subject: [PATCH 179/287] base case functioning correctly --- .../AllInterCaseCommonAttributeSearcher.java | 8 +++++ ...stedWithHashAndFileTypeInterCaseTests.java | 29 +++++++++++++++++++ .../commonfilessearch/InterCaseTestUtils.java | 8 ++--- 3 files changed, 41 insertions(+), 4 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllInterCaseCommonAttributeSearcher.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllInterCaseCommonAttributeSearcher.java index 74e3aabb2a..d86a4b9878 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllInterCaseCommonAttributeSearcher.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllInterCaseCommonAttributeSearcher.java @@ -33,6 +33,14 @@ import org.sleuthkit.datamodel.TskCoreException; */ public class AllInterCaseCommonAttributeSearcher extends InterCaseCommonAttributeSearcher { + /** + * + * @param filterByMediaMimeType match only on files whose mime types can be + * broadly categorized as media types + * @param filterByDocMimeType match only on files whose mime types can be + * broadly categorized as document types + * @throws EamDbException + */ public AllInterCaseCommonAttributeSearcher(boolean filterByMediaMimeType, boolean filterByDocMimeType) throws EamDbException { super(filterByMediaMimeType, filterByDocMimeType); } diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileTypeInterCaseTests.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileTypeInterCaseTests.java index 2e6ca7d9d0..a6475e3124 100644 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileTypeInterCaseTests.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileTypeInterCaseTests.java @@ -86,8 +86,37 @@ public class IngestedWithHashAndFileTypeInterCaseTests extends NbTestCase { assertTrue("Results should not be empty", metadata.size() != 0); + //case 1 data set 1 + assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_0_DAT, CASE1_DATASET_1, CASE1, 0)); + assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_A_PDF, CASE1_DATASET_1, CASE1, 1)); assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_A_JPG, CASE1_DATASET_1, CASE1, 1)); + //case 1 data set 2 + assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_0_DAT, CASE1_DATASET_2, CASE1, 0)); + assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_A_PDF, CASE1_DATASET_2, CASE1, 1)); + assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_A_JPG, CASE1_DATASET_2, CASE1, 1)); + + //case 2 data set 1 + assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_B_PDF, CASE2_DATASET_1, CASE2, 0)); + assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_B_JPG, CASE2_DATASET_1, CASE2, 0)); + + //case 2 data set 2 + assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_A_PDF, CASE2_DATASET_2, CASE2, 1)); + assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_A_JPG, CASE2_DATASET_2, CASE2, 1)); + assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_D_DOC, CASE2_DATASET_2, CASE2, 1)); + + //case 3 data set 1 + assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_A_JPG, CASE3_DATASET_1, CASE3, 1)); + assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_A_PDF, CASE3_DATASET_1, CASE3, 1)); + assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_C_JPG, CASE3_DATASET_1, CASE3, 0)); + assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_C_PDF, CASE3_DATASET_1, CASE3, 0)); + assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_D_JPG, CASE3_DATASET_1, CASE3, 0)); + + //case 3 data set 2 + assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_C_JPG, CASE3_DATASET_2, CASE3, 0)); + assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_C_PDF, CASE3_DATASET_2, CASE3, 0)); + assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_D_DOC, CASE3_DATASET_2, CASE3, 1)); + } catch (Exception ex) { Exceptions.printStackTrace(ex); diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/InterCaseTestUtils.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/InterCaseTestUtils.java index 805f227cf3..68388a646d 100644 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/InterCaseTestUtils.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/InterCaseTestUtils.java @@ -73,13 +73,13 @@ import org.sleuthkit.datamodel.AbstractFile; - Hash-A.jpg - Hash-A.pdf +Data Set2 - - Hash-0.dat [testFile of size -0] + - Hash-0.dat [testFile of size 0] - Hash-A.jpg - Hash-A.pdf Case 2 +Data Set 1 - - Hash-A.jpg - - Hash-A.pdf + - Hash-B.jpg + - Hash-B.pdf +Data Set 2 - Hash-A.jpg - Hash-A.pdf @@ -94,7 +94,7 @@ import org.sleuthkit.datamodel.AbstractFile; +Data Set 2 - Hash-C.jpg [we should never find these!] - Hash-C.pdf - - Hash.D-doc + - Hash-D.doc */ class InterCaseTestUtils { From d6f3e79b47816217c8baafb1e7eb228506dbd89f Mon Sep 17 00:00:00 2001 From: Andrew Ziehl Date: Tue, 24 Jul 2018 15:50:02 -0700 Subject: [PATCH 180/287] 4070 wip --- .../datamodel/AbstractSqlEamDb.java | 41 ++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java index a81e336fac..4b7b49f7e8 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java @@ -1898,12 +1898,51 @@ abstract class AbstractSqlEamDb implements EamDb { /** * Process the Artifact instance in the EamDb * + * @param type EamArtifact.Type to search for + * @param instanceTableCallback callback to process the instance + * + * @throws EamDbException + */ + @Override + public void processInstanceTable(CorrelationAttribute.Type type, InstanceTableCallback instanceTableCallback) throws EamDbException { + if (type == null) { + throw new EamDbException("Correlation type is null"); + } + + if (instanceTableCallback == null) { + throw new EamDbException("Callback interface is null"); + } + + Connection conn = connect(); + PreparedStatement preparedStatement = null; + ResultSet resultSet = null; + String tableName = EamDbUtil.correlationTypeToInstanceTableName(type); + StringBuilder sql = new StringBuilder(); + sql.append("select * from "); + sql.append(tableName); + + try { + preparedStatement = conn.prepareStatement(sql.toString()); + resultSet = preparedStatement.executeQuery(); + instanceTableCallback.process(resultSet); + } catch (SQLException ex) { + throw new EamDbException("Error getting all artifact instances from instances table", ex); + } finally { + EamDbUtil.closeStatement(preparedStatement); + EamDbUtil.closeResultSet(resultSet); + EamDbUtil.closeConnection(conn); + } + } + + /** + * Process the Artifact instance in the EamDb + * * @param type EamArtifact.Type to search for * @param instanceTableCallback callback to process the instance * @throws EamDbException */ @Override - public void processInstanceTableRow(CorrelationAttribute.Type type, int id, InstanceTableCallback instanceTableCallback) throws EamDbException { + public void processInstanceTableWhere(CorrelationAttribute.Type type, String whereClause, InstanceTableCallback instanceTableCallback) throws EamDbException { if (type == null) { throw new EamDbException("Correlation type is null"); } From c76242a14aa0c7f0ff6e913f0bdf193361c46ec1 Mon Sep 17 00:00:00 2001 From: Eugene Livis Date: Wed, 25 Jul 2018 10:43:51 -0400 Subject: [PATCH 181/287] First cut at UI --- .../autopsy/keywordsearch/Bundle.properties | 2 ++ .../DropdownSingleTermSearchPanel.form | 25 ++++++++++++++----- .../DropdownSingleTermSearchPanel.java | 22 ++++++++++------ 3 files changed, 36 insertions(+), 13 deletions(-) diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Bundle.properties b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Bundle.properties index ee49ae2c2b..81544546da 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Bundle.properties +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Bundle.properties @@ -313,3 +313,5 @@ ExtractedContentPanel.pagesLabel.text=Page: DropdownSingleTermSearchPanel.dataSourceCheckBox.text=Restrict search to the selected data sources: DropdownListSearchPanel.dataSourceCheckBox.text=Restrict search to the selected data sources: DropdownSingleTermSearchPanel.ingestIndexLabel.text=Files Indexed: +DropdownSingleTermSearchPanel.jSaveSearchResults.toolTipText=Performe keyword search without saving the results in the form of keyword hit artifacts +DropdownSingleTermSearchPanel.jSaveSearchResults.text=Save search results diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/DropdownSingleTermSearchPanel.form b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/DropdownSingleTermSearchPanel.form index 19fb132f0d..b7b26a882a 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/DropdownSingleTermSearchPanel.form +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/DropdownSingleTermSearchPanel.form @@ -59,14 +59,14 @@ - + + - @@ -74,8 +74,9 @@ + - + @@ -83,14 +84,16 @@ - + - + + + @@ -99,7 +102,7 @@ - + @@ -217,5 +220,15 @@ + + + + + + + + + + diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/DropdownSingleTermSearchPanel.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/DropdownSingleTermSearchPanel.java index 2ed59d253e..42bebd6169 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/DropdownSingleTermSearchPanel.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/DropdownSingleTermSearchPanel.java @@ -221,6 +221,7 @@ public class DropdownSingleTermSearchPanel extends AdHocSearchPanel { jScrollPane1 = new javax.swing.JScrollPane(); dataSourceList = new javax.swing.JList<>(); ingestIndexLabel = new javax.swing.JLabel(); + jSaveSearchResults = new javax.swing.JCheckBox(); org.openide.awt.Mnemonics.setLocalizedText(cutMenuItem, org.openide.util.NbBundle.getMessage(DropdownSingleTermSearchPanel.class, "DropdownSearchPanel.cutMenuItem.text")); // NOI18N rightClickMenu.add(cutMenuItem); @@ -280,6 +281,9 @@ public class DropdownSingleTermSearchPanel extends AdHocSearchPanel { ingestIndexLabel.setFont(ingestIndexLabel.getFont().deriveFont(ingestIndexLabel.getFont().getStyle() & ~java.awt.Font.BOLD, 10)); org.openide.awt.Mnemonics.setLocalizedText(ingestIndexLabel, org.openide.util.NbBundle.getMessage(DropdownSingleTermSearchPanel.class, "DropdownSingleTermSearchPanel.ingestIndexLabel.text")); // NOI18N + org.openide.awt.Mnemonics.setLocalizedText(jSaveSearchResults, org.openide.util.NbBundle.getMessage(DropdownSingleTermSearchPanel.class, "DropdownSingleTermSearchPanel.jSaveSearchResults.text")); // NOI18N + jSaveSearchResults.setToolTipText(org.openide.util.NbBundle.getMessage(DropdownSingleTermSearchPanel.class, "DropdownSingleTermSearchPanel.jSaveSearchResults.toolTipText")); // NOI18N + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); layout.setHorizontalGroup( @@ -287,32 +291,35 @@ public class DropdownSingleTermSearchPanel extends AdHocSearchPanel { .addGroup(layout.createSequentialGroup() .addGap(5, 5, 5) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jSaveSearchResults) .addGroup(layout.createSequentialGroup() .addComponent(exactRadioButton) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(substringRadioButton) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(regexRadioButton)) - .addComponent(dataSourceCheckBox) .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 297, javax.swing.GroupLayout.PREFERRED_SIZE) .addGroup(layout.createSequentialGroup() .addComponent(searchButton) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(ingestIndexLabel)) - .addComponent(keywordTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 296, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addComponent(keywordTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 296, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(dataSourceCheckBox)) + .addContainerGap(39, Short.MAX_VALUE)) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addContainerGap() - .addComponent(keywordTextField, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(keywordTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(exactRadioButton) .addComponent(substringRadioButton) .addComponent(regexRadioButton)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jSaveSearchResults) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(dataSourceCheckBox) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 61, javax.swing.GroupLayout.PREFERRED_SIZE) @@ -320,7 +327,7 @@ public class DropdownSingleTermSearchPanel extends AdHocSearchPanel { .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(searchButton) .addComponent(ingestIndexLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 13, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addContainerGap()) + .addGap(29, 29, 29)) ); }// //GEN-END:initComponents @@ -340,7 +347,7 @@ public class DropdownSingleTermSearchPanel extends AdHocSearchPanel { */ private void keywordTextFieldActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_keywordTextFieldActionPerformed try { - search(false); // ELTODO get the checkbox value + search(jSaveSearchResults.isSelected()); // ELTODO get the checkbox value } catch (Exception e) { LOGGER.log(Level.SEVERE, "Error performing ad hoc single keyword search", e); //NON-NLS } @@ -431,6 +438,7 @@ public class DropdownSingleTermSearchPanel extends AdHocSearchPanel { private javax.swing.JList dataSourceList; private javax.swing.JRadioButton exactRadioButton; private javax.swing.JLabel ingestIndexLabel; + private javax.swing.JCheckBox jSaveSearchResults; private javax.swing.JScrollPane jScrollPane1; private javax.swing.JTextField keywordTextField; private javax.swing.JMenuItem pasteMenuItem; From 1057c70cb68f747d0e37e0746cbc0bd6c9c01269 Mon Sep 17 00:00:00 2001 From: Andrew Ziehl Date: Wed, 25 Jul 2018 08:27:50 -0700 Subject: [PATCH 182/287] Clean logic to return proper AbstractFile, including specific match if one exists. --- .../CentralRepoCommonAttributeInstance.java | 31 +++++++++++++------ 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepoCommonAttributeInstance.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepoCommonAttributeInstance.java index d1bb03c56e..e11fe32e43 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepoCommonAttributeInstance.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepoCommonAttributeInstance.java @@ -34,8 +34,8 @@ import org.sleuthkit.datamodel.SleuthkitCase; import org.sleuthkit.datamodel.TskCoreException; /** - * Represents that a row in the CR was found in multiple cases. - * + * Represents that a row in the CR was found in multiple cases. + * * Generates a DisplayableItmeNode using a CentralRepositoryFile. */ final public class CentralRepoCommonAttributeInstance extends AbstractCommonAttributeInstance { @@ -48,7 +48,7 @@ final public class CentralRepoCommonAttributeInstance extends AbstractCommonAttr super(cachedFiles); this.crFileId = attrInstId; } - + void setCurrentAttributeInst(CorrelationAttribute attribute) { this.currentAttribute = attribute; } @@ -63,13 +63,25 @@ final public class CentralRepoCommonAttributeInstance extends AbstractCommonAttr currentCase = Case.getCurrentCaseThrows(); SleuthkitCase tskDb = currentCase.getSleuthkitCase(); - + File fileFromPath = new File(currentFullPath); String fileName = fileFromPath.getName(); + String parentPath = fileFromPath.getParent() + File.separator; + List potentialAbstractFiles = tskDb.findAllFilesWhere(String.format("lower(name) = '%s' AND md5 = '%s'", fileName, currentAttribute.getCorrelationValue())); + AbstractFile finalAbstractFile = null; + for (AbstractFile aFile : potentialAbstractFiles) { + // If a direct match exists, return that and we'll create a CaseDb instance node from it + if (aFile.getParentPath().equalsIgnoreCase(parentPath)) { + finalAbstractFile = aFile; + break; + } + } + // If not direct match exists, return first md5 match, only used as a backing file for CR instance node. + if (finalAbstractFile == null) { + finalAbstractFile = potentialAbstractFiles.get(0); + } - AbstractFile abstractFile = tskDb.findAllFilesWhere(String.format("lower(name) = '%s' AND md5 = '%s'", fileName, currentAttribute.getCorrelationValue())).get(0); - - return abstractFile; + return finalAbstractFile; } catch (TskCoreException | NoCurrentCaseException ex) { LOGGER.log(Level.SEVERE, String.format("Unable to find AbstractFile for record with filePath: %s. Node not created.", new Object[]{currentFullPath}), ex); @@ -81,16 +93,15 @@ final public class CentralRepoCommonAttributeInstance extends AbstractCommonAttr @Override public DisplayableItemNode[] generateNodes() { - + // @@@ We should be doing more of this work in teh generateKeys method. We want to do as little as possible in generateNodes - InterCaseSearchResultsProcessor eamDbAttrInst = new InterCaseSearchResultsProcessor(); CorrelationAttribute corrAttr = eamDbAttrInst.findSingleCorrelationAttribute(crFileId); List attrInstNodeList = new ArrayList<>(0); String currCaseDbName = Case.getCurrentCase().getDisplayName(); try { - this.setCurrentAttributeInst(corrAttr); + this.setCurrentAttributeInst(corrAttr); AbstractFile equivalentAbstractFile = this.lookupOrLoadAbstractFile(); DisplayableItemNode generatedInstNode = AbstractCommonAttributeInstance.createInstance(corrAttr, equivalentAbstractFile, currCaseDbName); From 188d63ea725ae21385ef9f742b1137841313a5b0 Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Wed, 25 Jul 2018 10:50:55 -0600 Subject: [PATCH 183/287] test cases for intercase correlation --- ...stedWithHashAndFileTypeInterCaseTests.java | 62 +++++++++++++++++-- .../commonfilessearch/InterCaseTestUtils.java | 21 ++++--- 2 files changed, 70 insertions(+), 13 deletions(-) diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileTypeInterCaseTests.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileTypeInterCaseTests.java index a6475e3124..683cb28fac 100644 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileTypeInterCaseTests.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileTypeInterCaseTests.java @@ -28,9 +28,12 @@ import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.commonfilesearch.AbstractCommonAttributeSearcher; import org.sleuthkit.autopsy.commonfilesearch.AllInterCaseCommonAttributeSearcher; import org.sleuthkit.autopsy.commonfilesearch.CommonAttributeSearchResults; +import org.sleuthkit.autopsy.commonfilesearch.SingleInterCaseCommonAttributeSearcher; import static org.sleuthkit.autopsy.commonfilessearch.InterCaseTestUtils.*; /** + * Tests with case 3 as the current case. + * * If I use the search all cases option: One node for Hash A (1_1_A.jpg, * 1_2_A.jpg, 3_1_A.jpg) If I search for matches only in Case 1: One node for * Hash A (1_1_A.jpg, 1_2_A.jpg, 3_1_A.jpg) If I search for matches only in Case @@ -69,17 +72,16 @@ public class IngestedWithHashAndFileTypeInterCaseTests extends NbTestCase { @Override public void tearDown(){ + this.utils.clearTestDir(); this.utils.tearDown(); } /** - * Search All cases - * - * One node for Hash A (1_1_A.jpg, 1_2_A.jpg, 3_1_A.jpg) + * Search All cases with no file type filtering. */ public void testOne() { try { - + //note that the params false and false are presently meaningless because that feature is not supported yet AbstractCommonAttributeSearcher builder = new AllInterCaseCommonAttributeSearcher(false, false); CommonAttributeSearchResults metadata = builder.findFiles(); @@ -118,6 +120,58 @@ public class IngestedWithHashAndFileTypeInterCaseTests extends NbTestCase { assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_D_DOC, CASE3_DATASET_2, CASE3, 1)); + } catch (Exception ex) { + Exceptions.printStackTrace(ex); + Assert.fail(ex); + } + } + + /** + * Search All cases with no file type filtering. + */ + public void testTwo() { + try { + + int matchesMustAlsoBeFoundInThisCase = this.utils.getCaseMap().get(CASE2); + + AbstractCommonAttributeSearcher builder = new SingleInterCaseCommonAttributeSearcher(matchesMustAlsoBeFoundInThisCase, false, false); + + CommonAttributeSearchResults metadata = builder.findFiles(); + + assertTrue("Results should not be empty", metadata.size() != 0); + + //case 1 data set 1 + assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_0_DAT, CASE1_DATASET_1, CASE1, 0)); + assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_A_PDF, CASE1_DATASET_1, CASE1, 1)); + assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_A_JPG, CASE1_DATASET_1, CASE1, 1)); + + //case 1 data set 2 + assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_0_DAT, CASE1_DATASET_2, CASE1, 0)); + assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_A_PDF, CASE1_DATASET_2, CASE1, 1)); + assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_A_JPG, CASE1_DATASET_2, CASE1, 1)); + + //case 2 data set 1 + assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_B_PDF, CASE2_DATASET_1, CASE2, 0)); + assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_B_JPG, CASE2_DATASET_1, CASE2, 0)); + + //case 2 data set 2 + assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_A_PDF, CASE2_DATASET_2, CASE2, 1)); + assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_A_JPG, CASE2_DATASET_2, CASE2, 1)); + assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_D_DOC, CASE2_DATASET_2, CASE2, 1)); + + //case 3 data set 1 + assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_A_JPG, CASE3_DATASET_1, CASE3, 1)); + assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_A_PDF, CASE3_DATASET_1, CASE3, 1)); + assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_C_JPG, CASE3_DATASET_1, CASE3, 0)); + assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_C_PDF, CASE3_DATASET_1, CASE3, 0)); + assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_D_JPG, CASE3_DATASET_1, CASE3, 0)); + + //case 3 data set 2 + assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_C_JPG, CASE3_DATASET_2, CASE3, 0)); + assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_C_PDF, CASE3_DATASET_2, CASE3, 0)); + assertTrue(verifyInstanceExistanceAndCount(metadata, HASH_D_DOC, CASE3_DATASET_2, CASE3, 1)); + + } catch (Exception ex) { Exceptions.printStackTrace(ex); Assert.fail(ex); diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/InterCaseTestUtils.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/InterCaseTestUtils.java index 68388a646d..53ec609839 100644 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/InterCaseTestUtils.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/InterCaseTestUtils.java @@ -78,8 +78,8 @@ import org.sleuthkit.datamodel.AbstractFile; - Hash-A.pdf Case 2 +Data Set 1 - - Hash-B.jpg - - Hash-B.pdf + - Hash-B.jpg + - Hash-B.pdf +Data Set 2 - Hash-A.jpg - Hash-A.pdf @@ -88,11 +88,11 @@ import org.sleuthkit.datamodel.AbstractFile; +Data Set 1 - Hash-A.jpg - Hash-A.pdf - - Hash-C.jpg [we should never find these!] - - Hash-C.pdf [we should never find these!] + - Hash-C.jpg + - Hash-C.pdf - Hash-D.jpg +Data Set 2 - - Hash-C.jpg [we should never find these!] + - Hash-C.jpg - Hash-C.pdf - Hash-D.doc */ @@ -170,8 +170,10 @@ class InterCaseTestUtils { void clearTestDir(){ if(CASE_DIRECTORY_PATH.toFile().exists()){ try{ + EamDb.getInstance().shutdownConnections(); FileUtils.deleteDirectory(CASE_DIRECTORY_PATH.toFile()); - } catch(IOException ex){ + } catch(IOException | EamDbException ex){ + Exceptions.printStackTrace(ex); Assert.fail(ex); } } @@ -182,13 +184,13 @@ class InterCaseTestUtils { return this.dataSourceLoader.getDataSourceMap(); } - Map getCaseMap() throws EamDbException { + Map getCaseMap() throws EamDbException { if (EamDb.isEnabled()) { - Map mapOfCaseIdsToCase = new HashMap<>(); + Map mapOfCaseIdsToCase = new HashMap<>(); for (CorrelationCase caze : EamDb.getInstance().getCases()) { - mapOfCaseIdsToCase.put(caze.getID(), caze.getDisplayName()); + mapOfCaseIdsToCase.put(caze.getDisplayName(), caze.getID()); } return mapOfCaseIdsToCase; } else { @@ -294,6 +296,7 @@ class InterCaseTestUtils { } } + //TODO refactor static boolean verifyInstanceExistanceAndCount(CommonAttributeSearchResults searchDomain, String fileName, String dataSource, String crCase, int instanceCount){ int tally = 0; From 43cce4fec253df28ae6e98c6d63afcaa74890723 Mon Sep 17 00:00:00 2001 From: Eugene Livis Date: Wed, 25 Jul 2018 13:52:58 -0400 Subject: [PATCH 184/287] Added save search feature to list search --- .../autopsy/keywordsearch/Bundle.properties | 2 ++ .../DropdownListSearchPanel.form | 19 +++++++++++++++++-- .../DropdownListSearchPanel.java | 17 +++++++++++++---- .../DropdownSingleTermSearchPanel.java | 2 +- 4 files changed, 33 insertions(+), 7 deletions(-) diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Bundle.properties b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Bundle.properties index 81544546da..144609972d 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Bundle.properties +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Bundle.properties @@ -315,3 +315,5 @@ DropdownListSearchPanel.dataSourceCheckBox.text=Restrict search to the selected DropdownSingleTermSearchPanel.ingestIndexLabel.text=Files Indexed: DropdownSingleTermSearchPanel.jSaveSearchResults.toolTipText=Performe keyword search without saving the results in the form of keyword hit artifacts DropdownSingleTermSearchPanel.jSaveSearchResults.text=Save search results +DropdownListSearchPanel.jSaveSearchResults.toolTipText=Performe keyword search without saving the results in the form of keyword hit artifacts +DropdownListSearchPanel.jSaveSearchResults.text=Save search results diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/DropdownListSearchPanel.form b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/DropdownListSearchPanel.form index 873824840b..c4988ac8a7 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/DropdownListSearchPanel.form +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/DropdownListSearchPanel.form @@ -33,11 +33,14 @@ + - + + + + - @@ -45,6 +48,8 @@ + + @@ -226,5 +231,15 @@ + + + + + + + + + + diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/DropdownListSearchPanel.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/DropdownListSearchPanel.java index 81611c130a..8d370fee3b 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/DropdownListSearchPanel.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/DropdownListSearchPanel.java @@ -206,6 +206,7 @@ class DropdownListSearchPanel extends AdHocSearchPanel { dataSourceCheckBox = new javax.swing.JCheckBox(); jScrollPane1 = new javax.swing.JScrollPane(); dataSourceList = new javax.swing.JList<>(); + jSaveSearchResults = new javax.swing.JCheckBox(); setFont(getFont().deriveFont(getFont().getStyle() & ~java.awt.Font.BOLD, 11)); @@ -265,6 +266,9 @@ class DropdownListSearchPanel extends AdHocSearchPanel { dataSourceList.setMinimumSize(new java.awt.Dimension(0, 200)); jScrollPane1.setViewportView(dataSourceList); + jSaveSearchResults.setText(org.openide.util.NbBundle.getMessage(DropdownListSearchPanel.class, "DropdownListSearchPanel.jSaveSearchResults.text")); // NOI18N + jSaveSearchResults.setToolTipText(org.openide.util.NbBundle.getMessage(DropdownListSearchPanel.class, "DropdownListSearchPanel.jSaveSearchResults.toolTipText")); // NOI18N + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); layout.setHorizontalGroup( @@ -278,10 +282,12 @@ class DropdownListSearchPanel extends AdHocSearchPanel { .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(ingestIndexLabel) .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - .addGroup(layout.createSequentialGroup() - .addComponent(dataSourceCheckBox) - .addGap(0, 0, Short.MAX_VALUE)) .addComponent(jScrollPane1) + .addGroup(layout.createSequentialGroup() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(dataSourceCheckBox) + .addComponent(jSaveSearchResults)) + .addGap(0, 0, Short.MAX_VALUE)) ); layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {manageListsButton, searchAddButton}); @@ -291,6 +297,8 @@ class DropdownListSearchPanel extends AdHocSearchPanel { .addGroup(layout.createSequentialGroup() .addComponent(jSplitPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 183, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jSaveSearchResults) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(dataSourceCheckBox) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 65, javax.swing.GroupLayout.PREFERRED_SIZE) @@ -319,6 +327,7 @@ class DropdownListSearchPanel extends AdHocSearchPanel { private javax.swing.JCheckBox dataSourceCheckBox; private javax.swing.JList dataSourceList; private javax.swing.JLabel ingestIndexLabel; + private javax.swing.JCheckBox jSaveSearchResults; private javax.swing.JScrollPane jScrollPane1; private javax.swing.JSplitPane jSplitPane1; private javax.swing.JTable keywordsTable; @@ -333,7 +342,7 @@ class DropdownListSearchPanel extends AdHocSearchPanel { setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); try { - search(true); // ELTOD do we always want o save these? + search(jSaveSearchResults.isSelected()); } finally { setCursor(null); } diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/DropdownSingleTermSearchPanel.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/DropdownSingleTermSearchPanel.java index 42bebd6169..2407b3b8c4 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/DropdownSingleTermSearchPanel.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/DropdownSingleTermSearchPanel.java @@ -347,7 +347,7 @@ public class DropdownSingleTermSearchPanel extends AdHocSearchPanel { */ private void keywordTextFieldActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_keywordTextFieldActionPerformed try { - search(jSaveSearchResults.isSelected()); // ELTODO get the checkbox value + search(jSaveSearchResults.isSelected()); } catch (Exception e) { LOGGER.log(Level.SEVERE, "Error performing ad hoc single keyword search", e); //NON-NLS } From c3109afc82510efaa4be7f94bc4ce16b2e9dbfca Mon Sep 17 00:00:00 2001 From: Eugene Livis Date: Wed, 25 Jul 2018 15:24:38 -0400 Subject: [PATCH 185/287] Moved 'save results' button --- .../DropdownListSearchPanel.form | 28 +++++++++---------- .../DropdownListSearchPanel.java | 28 +++++++++---------- .../DropdownSingleTermSearchPanel.form | 10 +++---- .../DropdownSingleTermSearchPanel.java | 10 +++---- 4 files changed, 36 insertions(+), 40 deletions(-) diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/DropdownListSearchPanel.form b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/DropdownListSearchPanel.form index c4988ac8a7..70cd940085 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/DropdownListSearchPanel.form +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/DropdownListSearchPanel.form @@ -23,23 +23,21 @@ - - - - - - - - - - + + + + + + + + - + @@ -47,19 +45,19 @@ - - - + + + - + diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/DropdownListSearchPanel.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/DropdownListSearchPanel.java index 8d370fee3b..12a0ae9b4f 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/DropdownListSearchPanel.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/DropdownListSearchPanel.java @@ -273,21 +273,19 @@ class DropdownListSearchPanel extends AdHocSearchPanel { this.setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(jSplitPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 400, Short.MAX_VALUE) - .addGroup(layout.createSequentialGroup() - .addGap(4, 4, 4) - .addComponent(searchAddButton) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(manageListsButton) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(ingestIndexLabel) - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addComponent(jSplitPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE) .addComponent(jScrollPane1) .addGroup(layout.createSequentialGroup() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(dataSourceCheckBox) - .addComponent(jSaveSearchResults)) - .addGap(0, 0, Short.MAX_VALUE)) + .addComponent(jSaveSearchResults) + .addGroup(layout.createSequentialGroup() + .addComponent(searchAddButton) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(manageListsButton) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(ingestIndexLabel))) + .addGap(0, 120, Short.MAX_VALUE)) ); layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {manageListsButton, searchAddButton}); @@ -296,18 +294,18 @@ class DropdownListSearchPanel extends AdHocSearchPanel { layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addComponent(jSplitPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 183, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(jSaveSearchResults) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(dataSourceCheckBox) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 65, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jSaveSearchResults) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(manageListsButton) .addComponent(searchAddButton) .addComponent(ingestIndexLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 13, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addContainerGap()) + .addGap(23, 23, 23)) ); }// //GEN-END:initComponents diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/DropdownSingleTermSearchPanel.form b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/DropdownSingleTermSearchPanel.form index b7b26a882a..81630d6fa5 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/DropdownSingleTermSearchPanel.form +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/DropdownSingleTermSearchPanel.form @@ -59,7 +59,6 @@ - @@ -68,9 +67,10 @@ + - + @@ -92,17 +92,17 @@ - - + + - + diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/DropdownSingleTermSearchPanel.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/DropdownSingleTermSearchPanel.java index 2407b3b8c4..3e33e73a5c 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/DropdownSingleTermSearchPanel.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/DropdownSingleTermSearchPanel.java @@ -291,7 +291,6 @@ public class DropdownSingleTermSearchPanel extends AdHocSearchPanel { .addGroup(layout.createSequentialGroup() .addGap(5, 5, 5) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(jSaveSearchResults) .addGroup(layout.createSequentialGroup() .addComponent(exactRadioButton) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) @@ -299,9 +298,10 @@ public class DropdownSingleTermSearchPanel extends AdHocSearchPanel { .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(regexRadioButton)) .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 297, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jSaveSearchResults) .addGroup(layout.createSequentialGroup() .addComponent(searchButton) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGap(18, 18, 18) .addComponent(ingestIndexLabel)) .addComponent(keywordTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 296, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(dataSourceCheckBox)) @@ -318,16 +318,16 @@ public class DropdownSingleTermSearchPanel extends AdHocSearchPanel { .addComponent(substringRadioButton) .addComponent(regexRadioButton)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(jSaveSearchResults) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(dataSourceCheckBox) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 61, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jSaveSearchResults) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(searchButton) .addComponent(ingestIndexLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 13, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addGap(29, 29, 29)) + .addContainerGap(22, Short.MAX_VALUE)) ); }// //GEN-END:initComponents From 0d516470218de999e7d1fe2ae185b707e10814c7 Mon Sep 17 00:00:00 2001 From: Eugene Livis Date: Wed, 25 Jul 2018 15:33:43 -0400 Subject: [PATCH 186/287] Updated javadoc --- .../autopsy/keywordsearch/AdHocSearchChildFactory.java | 6 ++++++ .../autopsy/keywordsearch/AdHocSearchDelegator.java | 2 ++ .../sleuthkit/autopsy/keywordsearch/AdHocSearchPanel.java | 2 ++ .../org/sleuthkit/autopsy/keywordsearch/QueryResults.java | 6 +++--- 4 files changed, 13 insertions(+), 3 deletions(-) diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/AdHocSearchChildFactory.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/AdHocSearchChildFactory.java index 2e58fa01e6..2b279bfa88 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/AdHocSearchChildFactory.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/AdHocSearchChildFactory.java @@ -85,6 +85,12 @@ class AdHocSearchChildFactory extends ChildFactory { private final Collection queryRequests; private final boolean saveResults; + /** + * Constructor + * + * @param queryRequests Query results + * @param saveResults Flag whether to save search results as KWS artifacts. + */ AdHocSearchChildFactory(Collection queryRequests, boolean saveResults) { this.queryRequests = queryRequests; this.saveResults = saveResults; diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/AdHocSearchDelegator.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/AdHocSearchDelegator.java index 4b9a229785..a79f050ee2 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/AdHocSearchDelegator.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/AdHocSearchDelegator.java @@ -74,6 +74,8 @@ class AdHocSearchDelegator { /** * Execute the keyword search based on keywords passed into constructor. * Post results into a new DataResultViewer. + * + * @param saveResults Flag whether to save search results as KWS artifacts. */ public void execute(boolean saveResults) { Collection queryRequests = new ArrayList<>(); diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/AdHocSearchPanel.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/AdHocSearchPanel.java index ec75de032e..6190f392e8 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/AdHocSearchPanel.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/AdHocSearchPanel.java @@ -98,6 +98,8 @@ abstract class AdHocSearchPanel extends javax.swing.JPanel { /** * Performs the search using the selected keywords. Creates a * DataResultTopComponent with the results. + * + * @param saveResults Flag whether to save search results as KWS artifacts. */ public void search(boolean saveResults) { boolean isIngestRunning = IngestManager.getInstance().isIngestRunning(); diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/QueryResults.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/QueryResults.java index 5f672f5f03..66d0803812 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/QueryResults.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/QueryResults.java @@ -141,6 +141,7 @@ class QueryResults { * @param notifyInbox Whether or not to write a message to the ingest * messages inbox if there is a keyword hit in the text * exrtacted from the text source object. + * @param saveResults Flag whether to save search results as KWS artifacts. * */ void process(ProgressHandle progress, ProgressContributor subProgress, SwingWorker worker, boolean notifyInbox, boolean saveResults) { @@ -220,14 +221,13 @@ class QueryResults { } if (saveResults) { - /* - * Post an artifact for the hit to the blackboard. + * Post an artifact for the hit to the blackboard. */ BlackboardArtifact artifact = query.postKeywordHitToBlackboard(content, keyword, hit, snippet, query.getKeywordList().getName()); /* - * Send an ingest inbox message for the hit. + * Send an ingest inbox message for the hit. */ if (null != artifact) { hitArtifacts.add(artifact); From 1ae1c34dd27055808502a5b177b562b71007de23 Mon Sep 17 00:00:00 2001 From: Eugene Livis Date: Wed, 25 Jul 2018 15:37:46 -0400 Subject: [PATCH 187/287] Fixed spelling errors --- .../src/org/sleuthkit/autopsy/keywordsearch/Bundle.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Bundle.properties b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Bundle.properties index 144609972d..eedf0cb8ec 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Bundle.properties +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Bundle.properties @@ -313,7 +313,7 @@ ExtractedContentPanel.pagesLabel.text=Page: DropdownSingleTermSearchPanel.dataSourceCheckBox.text=Restrict search to the selected data sources: DropdownListSearchPanel.dataSourceCheckBox.text=Restrict search to the selected data sources: DropdownSingleTermSearchPanel.ingestIndexLabel.text=Files Indexed: -DropdownSingleTermSearchPanel.jSaveSearchResults.toolTipText=Performe keyword search without saving the results in the form of keyword hit artifacts +DropdownSingleTermSearchPanel.jSaveSearchResults.toolTipText=Perform keyword search without saving the results in the form of keyword hit artifacts DropdownSingleTermSearchPanel.jSaveSearchResults.text=Save search results -DropdownListSearchPanel.jSaveSearchResults.toolTipText=Performe keyword search without saving the results in the form of keyword hit artifacts +DropdownListSearchPanel.jSaveSearchResults.toolTipText=Perform keyword search without saving the results in the form of keyword hit artifacts DropdownListSearchPanel.jSaveSearchResults.text=Save search results From 04cc3de2195767439acb6632e4117467ee575492 Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dgrove" Date: Wed, 25 Jul 2018 15:52:57 -0400 Subject: [PATCH 188/287] Added code to prevent duplicate hash set hits; general cleanup. --- .../casemodule/services/Blackboard.java | 112 +++++++++- .../modules/hashdatabase/Bundle.properties | 19 -- .../modules/hashdatabase/Bundle_ja.properties | 23 --- .../hashdatabase/HashDbIngestModule.java | 192 ++++++++++++------ .../hashdatabase/HashLookupModuleFactory.java | 26 +-- 5 files changed, 250 insertions(+), 122 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/services/Blackboard.java b/Core/src/org/sleuthkit/autopsy/casemodule/services/Blackboard.java index 58b4f41d6e..ee4718e8d2 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/services/Blackboard.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/services/Blackboard.java @@ -20,9 +20,15 @@ package org.sleuthkit.autopsy.casemodule.services; import java.io.Closeable; import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import org.openide.util.Exceptions; import org.openide.util.Lookup; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.keywordsearchservice.KeywordSearchService; +import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardAttribute; import org.sleuthkit.datamodel.SleuthkitCase; @@ -38,7 +44,7 @@ import org.sleuthkit.datamodel.TskDataException; public final class Blackboard implements Closeable { private SleuthkitCase caseDb; - + /** * Constructs a representation of the blackboard, a place where artifacts * and their attributes are posted. @@ -80,8 +86,8 @@ public final class Blackboard implements Closeable { * * @return A type object representing the artifact type. * - * @throws BlackboardBlackboardException If there is a problem getting or - * adding the artifact type. + * @throws BlackboardException If there is a problem getting or adding the + * artifact type. */ public synchronized BlackboardArtifact.Type getOrAddArtifactType(String typeName, String displayName) throws BlackboardException { if (null == caseDb) { @@ -110,8 +116,8 @@ public final class Blackboard implements Closeable { * * @return A type object representing the attribute type. * - * @throws BlackboardBlackboardException If there is a problem getting or - * adding the attribute type. + * @throws BlackboardException If there is a problem getting or adding the + * attribute type. */ public synchronized BlackboardAttribute.Type getOrAddAttributeType(String typeName, BlackboardAttribute.TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE valueType, String displayName) throws BlackboardException { if (null == caseDb) { @@ -130,6 +136,101 @@ public final class Blackboard implements Closeable { } } + /** + * Determine if an artifact of a given type exists for a given file with a + * specific set of attributes. + * + * @param file The file whose artifacts need to be looked at. + * @param artifactType The type of artifact to look for. + * @param attributesMap The collection of attributes to look for. + * + * @return True if the specific artifact exists; otherwise false. + * + * @throws BlackboardException If there is a problem getting artifacts or + * attributes. + */ + public static boolean checkIfArtifactExists(AbstractFile file, BlackboardArtifact.ARTIFACT_TYPE artifactType, + Map attributesMap) throws BlackboardException { + + ArrayList artifactsList; + + /* + * Get the file's artifacts. + */ + try { + artifactsList = file.getArtifacts(artifactType); + if (artifactsList.isEmpty()) { + return false; + } + } catch (TskCoreException ex) { + throw new BlackboardException(String.format("Failed to get %s artifacts for file '%s' (id=%d).", + artifactType.getDisplayName(), file.getName(), file.getId()), ex); + } + + /* + * Get each artifact's attributes and analyze them for matches. + */ + for (BlackboardArtifact artifact : artifactsList) { + try { + if (checkIfAttributesMatch(artifact.getAttributes(), attributesMap)) { + /* + * The exact artifact exists, so we don't need to look at + * further. + */ + return true; + } + } catch (TskCoreException ex) { + throw new BlackboardException(String.format("Failed to get attributes from artifact '%s' (id=%d).", + artifact.getName(), artifact.getObjectID()), ex); + } + } + + /* + * None of the artifacts have the exact set of attribute type/value + * combinations. The provided file does not the artifact being sought. + */ + return false; + } + + /** + * Determine if a list of attributes all match a given set of values. + * + * @param attributesList The list of attributes to analyze. + * @param attributesMap The attribute values with which to compare. + * + * @return True if all attributes match; otherwise false. + */ + private static boolean checkIfAttributesMatch(List attributesList, Map attributesMap) { + for (Map.Entry mapEntry : attributesMap.entrySet()) { + boolean match = false; + for (BlackboardAttribute attribute : attributesList) { + BlackboardAttribute.Type attributeType = attribute.getAttributeType(); + String attributeValue = attribute.getValueString(); + if (attributeType.getTypeID() == mapEntry.getKey().getTypeID() && attributeValue.equals(mapEntry.getValue())) { + /* + * The exact attribute type/value combination was found. + * Mark this as a match to continue looping through the + * attributes map. + */ + match = true; + break; + } + } + if (!match) { + /* + * The exact attribute type/value combination was not found. + */ + return false; + } + }; + + /* + * All attribute type/value combinations were found in the provided + * attributes list. + */ + return true; + } + /** * Closes the blackboard. * @@ -140,7 +241,6 @@ public final class Blackboard implements Closeable { caseDb = null; } - /** * A blackboard exception. */ diff --git a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/Bundle.properties b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/Bundle.properties index c5f6d82425..3ca6c162b6 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/Bundle.properties @@ -87,23 +87,6 @@ HashDbImportDatabaseDialog.importHashDbErr=Import Hash Set Error HashDbImportDatabaseDialog.mustSelectHashDbFilePathMsg=A hash set file path must be selected. HashDbImportDatabaseDialog.hashDbDoesNotExistMsg=The selected hash set does not exist. HashDbImportDatabaseDialog.errorMessage.failedToOpenHashDbMsg=Failed to open hash set at {0}. -HashDbIngestModule.moduleName=Hash Lookup -HashDbIngestModule.moduleDescription=Identifies known and notable files using supplied hash sets, such as a standard NSRL hash set. -HashDbIngestModule.fileReadErrorMsg=Read Error\: {0} -HashDbIngestModule.calcHashValueErr=Error encountered while calculating the hash value for {0}. -HashDbIngestModule.hashLookupErrorMsg=Hash Lookup Error\: {0} -HashDbIngestModule.settingKnownBadStateErr=Error encountered while setting notable state for {0}. -HashDbIngestModule.lookingUpKnownBadHashValueErr=Error encountered while looking up notable hash value for {0}. -HashDbIngestModule.lookingUpKnownHashValueErr=Error encountered while looking up known hash value for {0}. -HashDbIngestModule.postToBB.fileName=File Name -HashDbIngestModule.postToBB.md5Hash=MD5 Hash -HashDbIngestModule.postToBB.hashsetName=Hash Set Name -HashDbIngestModule.postToBB.knownBadMsg=Notable\: {0} -HashDbIngestModule.complete.knownBadsFound=Notables found\: -HashDbIngestModule.complete.totalCalcTime=Total Calculation Time -HashDbIngestModule.complete.totalLookupTime=Total Lookup Time -HashDbIngestModule.complete.databasesUsed=Hash Sets Used\: -HashDbIngestModule.complete.hashLookupResults=Hash Lookup Results HashDbManager.moduleErrorListeningToUpdatesMsg=A module caused an error listening to HashDbManager updates. See log to determine which module. Some data could be incomplete. HashDbManager.replacingDuplicateHashsetNameMsg=Duplicate hash set name {0} found.\nReplacing with {1}. HashDbManager.openHashDbErr=Open Hash Set Error @@ -165,8 +148,6 @@ AddContentToHashDbAction.addFilesToHashSet.files=files AddContentToHashDbAction.addFilesToHashSet.file=file HashDbManager.errCreatingIndex.title=Error creating index HashDbManager.errCreatingIndex.msg=Error creating index\: {0} -HashLookupModuleFactory.getIngestJobSettingsPanel.exception.msg=Expected settings argument to be instanceof HashLookupModuleSettings -HashLookupModuleFactory.createFileIngestModule.exception.msg=Expected settings argument to be instanceof HashLookupModuleSettings HashLookupModuleSettingsPanel.alwaysCalcHashesCheckbox.toolTipText=Calculate MD5 even if no hash set is selected HashDbSearchPanel.hashTable.defaultModel.title.text=MD5 Hashes AddHashValuesToDatabaseDialog.JDialog.Title=Add Hashes to Hash Set diff --git a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/Bundle_ja.properties b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/Bundle_ja.properties index 828b027bdb..3d2ab7a085 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/Bundle_ja.properties +++ b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/Bundle_ja.properties @@ -76,28 +76,7 @@ HashDbImportDatabaseDialog.importHashDbErr=\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\ HashDbImportDatabaseDialog.mustSelectHashDbFilePathMsg=\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306e\u30d5\u30a1\u30a4\u30eb\u30d1\u30b9\u306e\u9078\u629e\u304c\u5fc5\u8981\u3067\u3059\u3002 HashDbImportDatabaseDialog.hashDbDoesNotExistMsg=\u9078\u629e\u3055\u308c\u305f\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306f\u5b58\u5728\u3057\u307e\u305b\u3093\u3002 HashDbImportDatabaseDialog.errorMessage.failedToOpenHashDbMsg={0}\u3067\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3092\u958b\u304f\u306e\u306b\u5931\u6557\u3057\u307e\u3057\u305f\u3002 -HashDbIngestModule.moduleName=\u30cf\u30c3\u30b7\u30e5\u30eb\u30c3\u30af\u30a2\u30c3\u30d7 -HashDbIngestModule.moduleDescription=\u6a19\u6e96\u306eNSRL\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306a\u3069\u3001\u63d0\u4f9b\u3055\u308c\u305f\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3092\u5229\u7528\u3057\u3066\u3001\u65e2\u77e5\u307e\u305f\u306f\u7591\u308f\u3057\u3044\u3082\u306e\u3092\u691c\u77e5\u3057\u307e\u3059\u3002 -HashDbIngestModule.noKnownHashDbSetMsg=\u65e2\u77e5\u306e\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u304c\u5b58\u5728\u3057\u307e\u305b\u3093\u3002 -HashDbIngestModule.knownFileSearchWillNotExecuteWarn=\u65e2\u77e5\u306e\u30d5\u30a1\u30a4\u30eb\u691c\u7d22\u304c\u5b9f\u884c\u3055\u308c\u307e\u305b\u3093\u3002 -HashDbIngestModule.noKnownBadHashDbSetMsg=\u65e2\u77e5\u306e\u60aa\u8cea\u306a\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30bb\u30c3\u30c8\u306f\u3042\u308a\u307e\u305b\u3093\u3002 HashDbConfigPanel.dbNotIndexedMsg=\u6b21\u306e\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306f\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u5316\u3055\u308c\u3066\u3044\u307e\u305b\u3093\u3002\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u5316\u3057\u307e\u3059\u304b\uff1f\n{0} -HashDbIngestModule.knownBadFileSearchWillNotExecuteWarn=\u65e2\u77e5\u306e\u60aa\u8cea\u30d5\u30a1\u30a4\u30eb\u691c\u7d22\u306f\u5b9f\u884c\u3055\u308c\u307e\u305b\u3093\u3002 -HashDbIngestModule.fileReadErrorMsg=\u8aad\u307f\u8fbc\u307f\u30a8\u30e9\u30fc\uff1a {0} -HashDbIngestModule.calcHashValueErr={0}\u306e\u30cf\u30c3\u30b7\u30e5\u5024\u3092\u8a08\u7b97\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002 -HashDbIngestModule.hashLookupErrorMsg=\u30cf\u30c3\u30b7\u30e5\u30eb\u30c3\u30af\u30a2\u30c3\u30d7\u30a8\u30e9\u30fc\uff1a {0} -HashDbIngestModule.settingKnownBadStateErr={0}\u306e\u65e2\u77e5\u306e\u60aa\u8cea\u30b9\u30c6\u30fc\u30bf\u30b9\u3092\u8a2d\u5b9a\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002 -HashDbIngestModule.lookingUpKnownBadHashValueErr={0}\u306e\u65e2\u77e5\u306e\u60aa\u8cea\u30cf\u30c3\u30b7\u30e5\u5024\u3092\u30eb\u30c3\u30af\u30a2\u30c3\u30d7\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002 -HashDbIngestModule.lookingUpKnownHashValueErr={0}\u306e\u65e2\u77e5\u306e\u30cf\u30c3\u30b7\u30e5\u5024\u3092\u30eb\u30c3\u30af\u30a2\u30c3\u30d7\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002 -HashDbIngestModule.postToBB.fileName=\u30d5\u30a1\u30a4\u30eb\u540d -HashDbIngestModule.postToBB.md5Hash=MD5\u30cf\u30c3\u30b7\u30e5 -HashDbIngestModule.postToBB.hashsetName=\u30cf\u30c3\u30b7\u30e5\u30bb\u30c3\u30c8\u540d -HashDbIngestModule.postToBB.knownBadMsg=\u65e2\u77e5\u306e\u60aa\u8cea\: {0} -HashDbIngestModule.complete.knownBadsFound=\u767a\u898b\u3055\u308c\u305f\u65e2\u77e5\u306e\u60aa\u8cea\uff1a -HashDbIngestModule.complete.totalCalcTime=\u8a08\u7b97\u6642\u9593\u306e\u5408\u8a08 -HashDbIngestModule.complete.totalLookupTime=\u30eb\u30c3\u30af\u30a2\u30c3\u30d7\u6642\u9593\u306e\u5408\u8a08 -HashDbIngestModule.complete.databasesUsed=\u5229\u7528\u3057\u305f\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\uff1a -HashDbIngestModule.complete.hashLookupResults=\u30cf\u30c3\u30b7\u30e5\u30eb\u30c3\u30af\u30a2\u30c3\u30d7\u7d50\u679c HashDbManager.moduleErrorListeningToUpdatesMsg=HashDbManager\u30a2\u30c3\u30d7\u30c7\u30fc\u30c8\u3092\u78ba\u8a8d\u4e2d\u306b\u30e2\u30b8\u30e5\u30fc\u30eb\u304c\u30a8\u30e9\u30fc\u3092\u8d77\u3053\u3057\u307e\u3057\u305f\u3002\u3069\u306e\u30e2\u30b8\u30e5\u30fc\u30eb\u304c\u539f\u56e0\u306a\u306e\u304b\u3092\u30ed\u30b0\u3092\u78ba\u8a8d\u3057\u3066\u4e0b\u3055\u3044\u3002\u4e00\u90e8\u306e\u30c7\u30fc\u30bf\u304c\u5b8c\u5168\u3067\u306a\u3044\u3053\u3068\u304c\u3042\u308a\u307e\u3059\u3002 HashDbManager.replacingDuplicateHashsetNameMsg=\u91cd\u8907\u306e\u30cf\u30c3\u30b7\u30e5\u30bb\u30c3\u30c8\u540d {0} \u304c\u898b\u3064\u304b\u308a\u307e\u3057\u305f\u3002\n {1}\u306b\u66f8\u304d\u63db\u3048\u307e\u3059\u3002 HashDbManager.openHashDbErr=\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3092\u958b\u304f\u30a8\u30e9\u30fc @@ -163,8 +142,6 @@ HashLookupSettingsPanel.jLabel2.text=\u540d\u524d\uff1a HashLookupModuleSettingsPanel.alwaysCalcHashesCheckbox.text=\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u304c\u9078\u629e\u3055\u308c\u3066\u3044\u306a\u304f\u3066\u3082\u3001MD5\u3092\u8a08\u7b97 HashLookupModuleSettingsPanel.knownHashDbsLabel.text=\u5229\u7528\u3059\u308b\u65e2\u77e5\u306e\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3092\u9078\u629e\uff1a HashLookupModuleSettingsPanel.knownBadHashDbsLabel.text=\u51e6\u7406\u306b\u5229\u7528\u3059\u308b\u65e2\u77e5\u306e\u60aa\u8cea\u306a\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3092\u9078\u629e\uff1a -HashLookupModuleFactory.createFileIngestModule.exception.msg=\u8a2d\u5b9a\u3092\u884c\u3046\u70ba\u306e\u60f3\u5b9a\u3055\u308c\u308b\u5f15\u6570\u306finstanceof HashLookupModuleSettings\u3067\u3059\u3002 -HashLookupModuleFactory.getIngestJobSettingsPanel.exception.msg=\u8a2d\u5b9a\u3092\u884c\u3046\u70ba\u306e\u60f3\u5b9a\u3055\u308c\u308b\u5f15\u6570\u306finstanceof HashLookupModuleSettings\u3067\u3059\u3002 HashLookupModuleSettingsPanel.alwaysCalcHashesCheckbox.toolTipText=\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u304c\u9078\u629e\u3055\u308c\u3066\u3044\u306a\u304f\u3066\u3082\u3001MD5\u3092\u8a08\u7b97 HashDbSearchPanel.hashTable.defaultModel.title.text=MD5\u30cf\u30c3\u30b7\u30e5 AddContentToHashDbAction.addFilesToHashSet.unableToAddFileEmptyMsg=\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306b{0}\u3092\u8ffd\u52a0\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f\u3002\u30d5\u30a1\u30a4\u30eb\u306b\u30b3\u30f3\u30c6\u30f3\u30c4\u304c\u3042\u308a\u307e\u305b\u3093\u3002 diff --git a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbIngestModule.java b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbIngestModule.java index 74387840b5..2a134a7fe7 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbIngestModule.java +++ b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbIngestModule.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2011 - 2013 Basis Technology Corp. + * Copyright 2011-2018 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -24,13 +24,14 @@ import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.concurrent.atomic.AtomicLong; import java.util.logging.Level; -import org.openide.util.NbBundle; import org.openide.util.NbBundle.Messages; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; import org.sleuthkit.autopsy.casemodule.services.Blackboard; +import org.sleuthkit.autopsy.casemodule.services.Blackboard.BlackboardException; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil; import org.sleuthkit.autopsy.healthmonitor.HealthMonitor; @@ -48,37 +49,35 @@ import org.sleuthkit.datamodel.BlackboardAttribute; import org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE; import org.sleuthkit.datamodel.HashHitInfo; import org.sleuthkit.datamodel.HashUtility; -import org.sleuthkit.datamodel.SleuthkitCase; import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.datamodel.TskData; import org.sleuthkit.datamodel.TskException; -@NbBundle.Messages({ - "HashDbIngestModule.noKnownBadHashDbSetMsg=No notable hash set.", - "HashDbIngestModule.knownBadFileSearchWillNotExecuteWarn=Notable file search will not be executed.", - "HashDbIngestModule.noKnownHashDbSetMsg=No known hash set.", - "HashDbIngestModule.knownFileSearchWillNotExecuteWarn=Known file search will not be executed." -}) +/** + * File ingest module to mark files based on hash values. + */ public class HashDbIngestModule implements FileIngestModule { private static final Logger logger = Logger.getLogger(HashDbIngestModule.class.getName()); private static final int MAX_COMMENT_SIZE = 500; private final IngestServices services = IngestServices.getInstance(); - private final SleuthkitCase skCase; private final HashDbManager hashDbManager = HashDbManager.getInstance(); private final HashLookupModuleSettings settings; - private List knownBadHashSets = new ArrayList<>(); - private List knownHashSets = new ArrayList<>(); + private final List knownBadHashSets = new ArrayList<>(); + private final List knownHashSets = new ArrayList<>(); private long jobId; private static final HashMap totalsForIngestJobs = new HashMap<>(); private static final IngestModuleReferenceCounter refCounter = new IngestModuleReferenceCounter(); private Blackboard blackboard; + /** + * A container of values for storing ingest metrics for the job. + */ private static class IngestJobTotals { - private AtomicLong totalKnownBadCount = new AtomicLong(0); - private AtomicLong totalCalctime = new AtomicLong(0); - private AtomicLong totalLookuptime = new AtomicLong(0); + private final AtomicLong totalKnownBadCount = new AtomicLong(0); + private final AtomicLong totalCalctime = new AtomicLong(0); + private final AtomicLong totalLookuptime = new AtomicLong(0); } private static synchronized IngestJobTotals getTotalsForIngestJobs(long ingestJobId) { @@ -90,11 +89,23 @@ public class HashDbIngestModule implements FileIngestModule { return totals; } - HashDbIngestModule(HashLookupModuleSettings settings) throws NoCurrentCaseException { + /** + * Create a HashDbIngestModule object that will mark files based on a + * supplied list of hash values. The supplied HashLookupModuleSettings + * object is used to configure the module. + * + * @param settings The module settings. + */ + HashDbIngestModule(HashLookupModuleSettings settings) { this.settings = settings; - skCase = Case.getCurrentCaseThrows().getSleuthkitCase(); } + @Messages({ + "HashDbIngestModule.noKnownBadHashDbSetMsg=No notable hash set.", + "HashDbIngestModule.knownBadFileSearchWillNotExecuteWarn=Notable file search will not be executed.", + "HashDbIngestModule.noKnownHashDbSetMsg=No known hash set.", + "HashDbIngestModule.knownFileSearchWillNotExecuteWarn=Known file search will not be executed." + }) @Override public void startUp(org.sleuthkit.autopsy.ingest.IngestJobContext context) throws IngestModuleException { jobId = context.getJobId(); @@ -140,12 +151,34 @@ public class HashDbIngestModule implements FileIngestModule { enabledHashSets.add(db); } } catch (TskCoreException ex) { - logger.log(Level.WARNING, "Error getting index status for " + db.getDisplayName()+ " hash set", ex); //NON-NLS + logger.log(Level.WARNING, "Error getting index status for " + db.getDisplayName() + " hash set", ex); //NON-NLS } } } } + @Messages({ + "# {0} - File name", + "HashDbIngestModule.fileReadErrorMsg=Read Error: {0}", + + "# {0} - File name", + "HashDbIngestModule.calcHashValueErr=Error encountered while calculating the hash value for {0}.", + + "# {0} - File name", + "HashDbIngestModule.hashLookupErrorMsg=Hash Lookup Error: {0}", + + "# {0} - File name", + "HashDbIngestModule.lookingUpKnownBadHashValueErr=Error encountered while looking up notable hash value for {0}.", + + "# {0} - File name", + "HashDbIngestModule.lookingUpKnownHashValueErr=Error encountered while looking up known hash value for {0}.", + + "# {0} - File name", + "HashDbIngestModule.dialogTitle.errorFindingArtifacts=Error Finding Artifacts: {0}", + + "# {0} - File name", + "HashDbIngestModule.errorMessage.lookingForFileArtifacts=Error encountered while looking for existing artifacts for {0}." + }) @Override public ProcessResult process(AbstractFile file) { try { @@ -156,8 +189,8 @@ public class HashDbIngestModule implements FileIngestModule { } // Skip unallocated space files. - if ((file.getType().equals(TskData.TSK_DB_FILES_TYPE_ENUM.UNALLOC_BLOCKS) || - file.getType().equals(TskData.TSK_DB_FILES_TYPE_ENUM.SLACK))) { + if ((file.getType().equals(TskData.TSK_DB_FILES_TYPE_ENUM.UNALLOC_BLOCKS) + || file.getType().equals(TskData.TSK_DB_FILES_TYPE_ENUM.SLACK))) { return ProcessResult.OK; } @@ -181,6 +214,7 @@ public class HashDbIngestModule implements FileIngestModule { // calc hash value String name = file.getName(); + long fileId = file.getId(); String md5Hash = file.getMd5Hash(); if (md5Hash == null || md5Hash.isEmpty()) { try { @@ -203,15 +237,11 @@ public class HashDbIngestModule implements FileIngestModule { totals.totalCalctime.addAndGet(delta); } catch (IOException ex) { - logger.log(Level.WARNING, "Error calculating hash of file " + name, ex); //NON-NLS + logger.log(Level.WARNING, String.format("Error calculating hash of file '%s' (id=%d).", name, fileId), ex); //NON-NLS services.postMessage(IngestMessage.createErrorMessage( HashLookupModuleFactory.getModuleName(), - NbBundle.getMessage(this.getClass(), - "HashDbIngestModule.fileReadErrorMsg", - name), - NbBundle.getMessage(this.getClass(), - "HashDbIngestModule.calcHashValueErr", - name))); + Bundle.HashDbIngestModule_fileReadErrorMsg(name), + Bundle.HashDbIngestModule_calcHashValueErr(name))); return ProcessResult.ERROR; } } @@ -245,21 +275,34 @@ public class HashDbIngestModule implements FileIngestModule { } } - postHashSetHitToBlackboard(file, md5Hash, hashSetName, comment, db.getSendIngestMessages()); + /* + * We have a match! Now create an artifact for it is + * determined that one hasn't been created yet. + */ + Map attributeMap = new HashMap<>(); + attributeMap.put(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_SET_NAME), hashSetName); + if (!Blackboard.checkIfArtifactExists(file, BlackboardArtifact.ARTIFACT_TYPE.TSK_HASHSET_HIT, attributeMap)) { + postHashSetHitToBlackboard(file, md5Hash, hashSetName, comment, db.getSendIngestMessages()); + } } long delta = (System.currentTimeMillis() - lookupstart); totals.totalLookuptime.addAndGet(delta); - } catch (TskException ex) { - logger.log(Level.WARNING, "Couldn't lookup notable hash for file " + name + " - see sleuthkit log for details", ex); //NON-NLS + } catch (BlackboardException ex) { + logger.log(Level.SEVERE, String.format( + "A problem occurred while trying checking for existing artifacts for file '%s' (id=%d).", name, fileId), ex); //NON-NLS services.postMessage(IngestMessage.createErrorMessage( HashLookupModuleFactory.getModuleName(), - NbBundle.getMessage(this.getClass(), - "HashDbIngestModule.hashLookupErrorMsg", - name), - NbBundle.getMessage(this.getClass(), - "HashDbIngestModule.lookingUpKnownBadHashValueErr", - name))); + Bundle.HashDbIngestModule_dialogTitle_errorFindingArtifacts(name), + Bundle.HashDbIngestModule_errorMessage_lookingForFileArtifacts(name))); + ret = ProcessResult.ERROR; + } catch (TskException ex) { + logger.log(Level.WARNING, String.format( + "Couldn't lookup notable hash for file '%s' (id=%d) - see sleuthkit log for details", name, fileId), ex); //NON-NLS + services.postMessage(IngestMessage.createErrorMessage( + HashLookupModuleFactory.getModuleName(), + Bundle.HashDbIngestModule_hashLookupErrorMsg(name), + Bundle.HashDbIngestModule_lookingUpKnownBadHashValueErr(name))); ret = ProcessResult.ERROR; } } @@ -279,15 +322,12 @@ public class HashDbIngestModule implements FileIngestModule { totals.totalLookuptime.addAndGet(delta); } catch (TskException ex) { - logger.log(Level.WARNING, "Couldn't lookup known hash for file " + name + " - see sleuthkit log for details", ex); //NON-NLS + logger.log(Level.WARNING, String.format( + "Couldn't lookup known hash for file '%s' (id=%d) - see sleuthkit log for details", name, fileId), ex); //NON-NLS services.postMessage(IngestMessage.createErrorMessage( HashLookupModuleFactory.getModuleName(), - NbBundle.getMessage(this.getClass(), - "HashDbIngestModule.hashLookupErrorMsg", - name), - NbBundle.getMessage(this.getClass(), - "HashDbIngestModule.lookingUpKnownHashValueErr", - name))); + Bundle.HashDbIngestModule_hashLookupErrorMsg(name), + Bundle.HashDbIngestModule_lookingUpKnownHashValueErr(name))); ret = ProcessResult.ERROR; } } @@ -296,18 +336,35 @@ public class HashDbIngestModule implements FileIngestModule { return ret; } - @Messages({"HashDbIngestModule.indexError.message=Failed to index hashset hit artifact for keyword search."}) + /** + * Post hash set hit to the blackboard. + * + * @param abstractFile The file to be processed. + * @param md5Hash The MD5 hash value of the file. + * @param hashSetName The name of the hash set with which to associate + * the hit. + * @param comment A comment to be attached to the artifact. + * @param showInboxMessage Show a message in the inbox? + */ + @Messages({ + "HashDbIngestModule.indexError.message=Failed to index hashset hit artifact for keyword search.", + "HashDbIngestModule.postToBB.fileName=File Name", + "HashDbIngestModule.postToBB.md5Hash=MD5 Hash", + "HashDbIngestModule.postToBB.hashsetName=Hash Set Name", + + "# {0} - File name", + "HashDbIngestModule.postToBB.knownBadMsg=Notable: {0}" + }) private void postHashSetHitToBlackboard(AbstractFile abstractFile, String md5Hash, String hashSetName, String comment, boolean showInboxMessage) { try { - String MODULE_NAME = NbBundle.getMessage(HashDbIngestModule.class, "HashDbIngestModule.moduleName"); - + String moduleName = HashLookupModuleFactory.getModuleName(); BlackboardArtifact badFile = abstractFile.newArtifact(ARTIFACT_TYPE.TSK_HASHSET_HIT); Collection attributes = new ArrayList<>(); //TODO Revisit usage of deprecated constructor as per TSK-583 //BlackboardAttribute att2 = new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_SET_NAME.getTypeID(), MODULE_NAME, "Known Bad", hashSetName); - attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_SET_NAME, MODULE_NAME, hashSetName)); - attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_HASH_MD5, MODULE_NAME, md5Hash)); - attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_COMMENT, MODULE_NAME, comment)); + attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_SET_NAME, moduleName, hashSetName)); + attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_HASH_MD5, moduleName, md5Hash)); + attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_COMMENT, moduleName, comment)); badFile.addAttributes(attributes); @@ -327,7 +384,7 @@ public class HashDbIngestModule implements FileIngestModule { //hit detailsSb.append(""); //NON-NLS detailsSb.append("") //NON-NLS - .append(NbBundle.getMessage(this.getClass(), "HashDbIngestModule.postToBB.fileName")) + .append(Bundle.HashDbIngestModule_postToBB_fileName()) .append(""); //NON-NLS detailsSb.append("") //NON-NLS .append(abstractFile.getName()) @@ -336,14 +393,14 @@ public class HashDbIngestModule implements FileIngestModule { detailsSb.append(""); //NON-NLS detailsSb.append("") //NON-NLS - .append(NbBundle.getMessage(this.getClass(), "HashDbIngestModule.postToBB.md5Hash")) + .append(Bundle.HashDbIngestModule_postToBB_md5Hash()) .append(""); //NON-NLS detailsSb.append("").append(md5Hash).append(""); //NON-NLS detailsSb.append(""); //NON-NLS detailsSb.append(""); //NON-NLS detailsSb.append("") //NON-NLS - .append(NbBundle.getMessage(this.getClass(), "HashDbIngestModule.postToBB.hashsetName")) + .append(Bundle.HashDbIngestModule_postToBB_hashsetName()) .append(""); //NON-NLS detailsSb.append("").append(hashSetName).append(""); //NON-NLS detailsSb.append(""); //NON-NLS @@ -351,19 +408,31 @@ public class HashDbIngestModule implements FileIngestModule { detailsSb.append(""); //NON-NLS services.postMessage(IngestMessage.createDataMessage(HashLookupModuleFactory.getModuleName(), - NbBundle.getMessage(this.getClass(), - "HashDbIngestModule.postToBB.knownBadMsg", - abstractFile.getName()), + Bundle.HashDbIngestModule_postToBB_knownBadMsg(abstractFile.getName()), detailsSb.toString(), abstractFile.getName() + md5Hash, badFile)); } - services.fireModuleDataEvent(new ModuleDataEvent(MODULE_NAME, ARTIFACT_TYPE.TSK_HASHSET_HIT, Collections.singletonList(badFile))); + services.fireModuleDataEvent(new ModuleDataEvent(moduleName, ARTIFACT_TYPE.TSK_HASHSET_HIT, Collections.singletonList(badFile))); } catch (TskException ex) { logger.log(Level.WARNING, "Error creating blackboard artifact", ex); //NON-NLS } } + /** + * Post a message summarizing the results of the ingest. + * + * @param jobId The ID of the job. + * @param knownBadHashSets The list of hash sets for "known bad" files. + * @param knownHashSets The list of hash sets for "known" files. + */ + @Messages({ + "HashDbIngestModule.complete.knownBadsFound=Notables found:", + "HashDbIngestModule.complete.totalCalcTime=Total Calculation Time", + "HashDbIngestModule.complete.totalLookupTime=Total Lookup Time", + "HashDbIngestModule.complete.databasesUsed=Hash Sets Used:", + "HashDbIngestModule.complete.hashLookupResults=Hash Lookup Results" + }) private static synchronized void postSummary(long jobId, List knownBadHashSets, List knownHashSets) { IngestJobTotals jobTotals = getTotalsForIngestJobs(jobId); @@ -375,20 +444,20 @@ public class HashDbIngestModule implements FileIngestModule { detailsSb.append(""); //NON-NLS detailsSb.append(""); //NON-NLS detailsSb.append(""); //NON-NLS detailsSb.append("\n"); //NON-NLS detailsSb.append("\n"); //NON-NLS detailsSb.append("
") //NON-NLS - .append(NbBundle.getMessage(HashDbIngestModule.class, "HashDbIngestModule.complete.knownBadsFound")) + .append(Bundle.HashDbIngestModule_complete_knownBadsFound()) .append("").append(jobTotals.totalKnownBadCount.get()).append("
") //NON-NLS - .append(NbBundle.getMessage(HashDbIngestModule.class, "HashDbIngestModule.complete.totalCalcTime")) + .append(Bundle.HashDbIngestModule_complete_totalCalcTime()) .append("").append(jobTotals.totalCalctime.get()).append("
") //NON-NLS - .append(NbBundle.getMessage(HashDbIngestModule.class, "HashDbIngestModule.complete.totalLookupTime")) + .append(Bundle.HashDbIngestModule_complete_totalLookupTime()) .append("").append(jobTotals.totalLookuptime.get()).append("
"); //NON-NLS detailsSb.append("

") //NON-NLS - .append(NbBundle.getMessage(HashDbIngestModule.class, "HashDbIngestModule.complete.databasesUsed")) + .append(Bundle.HashDbIngestModule_complete_databasesUsed()) .append("

\n
    "); //NON-NLS for (HashDb db : knownBadHashSets) { detailsSb.append("
  • ").append(db.getHashSetName()).append("
  • \n"); //NON-NLS @@ -399,8 +468,7 @@ public class HashDbIngestModule implements FileIngestModule { IngestServices.getInstance().postMessage(IngestMessage.createMessage( IngestMessage.MessageType.INFO, HashLookupModuleFactory.getModuleName(), - NbBundle.getMessage(HashDbIngestModule.class, - "HashDbIngestModule.complete.hashLookupResults"), + Bundle.HashDbIngestModule_complete_hashLookupResults(), detailsSb.toString())); } } diff --git a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashLookupModuleFactory.java b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashLookupModuleFactory.java index 068c52cf5e..a327a659af 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashLookupModuleFactory.java +++ b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashLookupModuleFactory.java @@ -20,7 +20,6 @@ package org.sleuthkit.autopsy.modules.hashdatabase; import org.openide.util.NbBundle; import org.openide.util.lookup.ServiceProvider; -import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; import org.sleuthkit.autopsy.coreutils.Version; import org.sleuthkit.autopsy.ingest.IngestModuleFactoryAdapter; import org.sleuthkit.autopsy.ingest.FileIngestModule; @@ -33,6 +32,10 @@ import org.sleuthkit.autopsy.ingest.IngestModuleGlobalSettingsPanel; * A factory that creates file ingest modules that do hash database lookups. */ @ServiceProvider(service = IngestModuleFactory.class) +@NbBundle.Messages({ + "HashLookupModuleFactory.moduleName.text=Hash Lookup", + "HashLookupModuleFactory.moduleDescription.text=Identifies known and notable files using supplied hash sets, such as a standard NSRL hash set." +}) public class HashLookupModuleFactory extends IngestModuleFactoryAdapter { private HashLookupModuleSettingsPanel moduleSettingsPanel = null; @@ -42,13 +45,18 @@ public class HashLookupModuleFactory extends IngestModuleFactoryAdapter { return getModuleName(); } + /** + * Get the name of the module. + * + * @return The module name. + */ static String getModuleName() { - return NbBundle.getMessage(HashLookupModuleFactory.class, "HashDbIngestModule.moduleName"); + return Bundle.HashLookupModuleFactory_moduleName_text(); } @Override public String getModuleDescription() { - return NbBundle.getMessage(HashLookupModuleFactory.class, "HashDbIngestModule.moduleDescription"); + return Bundle.HashLookupModuleFactory_moduleDescription_text(); } @Override @@ -70,8 +78,7 @@ public class HashLookupModuleFactory extends IngestModuleFactoryAdapter { @Override public IngestModuleIngestJobSettingsPanel getIngestJobSettingsPanel(IngestModuleIngestJobSettings settings) { if (!(settings instanceof HashLookupModuleSettings)) { - throw new IllegalArgumentException(NbBundle.getMessage(this.getClass(), - "HashLookupModuleFactory.getIngestJobSettingsPanel.exception.msg")); + throw new IllegalArgumentException("Expected settings argument to be an instance of HashLookupModuleSettings."); } if (moduleSettingsPanel == null) { moduleSettingsPanel = new HashLookupModuleSettingsPanel((HashLookupModuleSettings) settings); @@ -101,13 +108,8 @@ public class HashLookupModuleFactory extends IngestModuleFactoryAdapter { @Override public FileIngestModule createFileIngestModule(IngestModuleIngestJobSettings settings) { if (!(settings instanceof HashLookupModuleSettings)) { - throw new IllegalArgumentException( - NbBundle.getMessage(this.getClass(), "HashLookupModuleFactory.createFileIngestModule.exception.msg")); - } - try { - return new HashDbIngestModule((HashLookupModuleSettings) settings); - } catch (NoCurrentCaseException ex) { - throw new IllegalArgumentException("Exception while getting open case.", ex); + throw new IllegalArgumentException("Expected settings argument to be an instance of HashLookupModuleSettings."); } + return new HashDbIngestModule((HashLookupModuleSettings) settings); } } From d11dbd7b3767c99800747568c52471b386a5182c Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dgrove" Date: Wed, 25 Jul 2018 16:17:19 -0400 Subject: [PATCH 189/287] Various typos fixed. --- .../autopsy/casemodule/services/Blackboard.java | 17 ++++++++--------- .../hashdatabase/HashDbIngestModule.java | 13 +++---------- 2 files changed, 11 insertions(+), 19 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/services/Blackboard.java b/Core/src/org/sleuthkit/autopsy/casemodule/services/Blackboard.java index ee4718e8d2..234df7564b 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/services/Blackboard.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/services/Blackboard.java @@ -21,12 +21,9 @@ package org.sleuthkit.autopsy.casemodule.services; import java.io.Closeable; import java.io.IOException; import java.util.ArrayList; -import java.util.Collection; import java.util.List; import java.util.Map; -import org.openide.util.Exceptions; import org.openide.util.Lookup; -import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.keywordsearchservice.KeywordSearchService; import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.BlackboardArtifact; @@ -174,7 +171,7 @@ public final class Blackboard implements Closeable { try { if (checkIfAttributesMatch(artifact.getAttributes(), attributesMap)) { /* - * The exact artifact exists, so we don't need to look at + * The exact artifact exists, so we don't need to look any * further. */ return true; @@ -187,18 +184,20 @@ public final class Blackboard implements Closeable { /* * None of the artifacts have the exact set of attribute type/value - * combinations. The provided file does not the artifact being sought. + * combinations. The provided file does not have the artifact being + * sought. */ return false; } /** - * Determine if a list of attributes all match a given set of values. + * Determine if the supplied attribute type/value combinations can all be + * found in the supplied attributes list. * * @param attributesList The list of attributes to analyze. - * @param attributesMap The attribute values with which to compare. + * @param attributesMap The attribute type/value combinations to check for. * - * @return True if all attributes match; otherwise false. + * @return True if all attributes are found; otherwise false. */ private static boolean checkIfAttributesMatch(List attributesList, Map attributesMap) { for (Map.Entry mapEntry : attributesMap.entrySet()) { @@ -222,7 +221,7 @@ public final class Blackboard implements Closeable { */ return false; } - }; + } /* * All attribute type/value combinations were found in the provided diff --git a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbIngestModule.java b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbIngestModule.java index 2a134a7fe7..d78713f23f 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbIngestModule.java +++ b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbIngestModule.java @@ -160,22 +160,16 @@ public class HashDbIngestModule implements FileIngestModule { @Messages({ "# {0} - File name", "HashDbIngestModule.fileReadErrorMsg=Read Error: {0}", - "# {0} - File name", "HashDbIngestModule.calcHashValueErr=Error encountered while calculating the hash value for {0}.", - "# {0} - File name", "HashDbIngestModule.hashLookupErrorMsg=Hash Lookup Error: {0}", - "# {0} - File name", "HashDbIngestModule.lookingUpKnownBadHashValueErr=Error encountered while looking up notable hash value for {0}.", - "# {0} - File name", "HashDbIngestModule.lookingUpKnownHashValueErr=Error encountered while looking up known hash value for {0}.", - "# {0} - File name", "HashDbIngestModule.dialogTitle.errorFindingArtifacts=Error Finding Artifacts: {0}", - "# {0} - File name", "HashDbIngestModule.errorMessage.lookingForFileArtifacts=Error encountered while looking for existing artifacts for {0}." }) @@ -276,7 +270,7 @@ public class HashDbIngestModule implements FileIngestModule { } /* - * We have a match! Now create an artifact for it is + * We have a match. Now create an artifact if it is * determined that one hasn't been created yet. */ Map attributeMap = new HashMap<>(); @@ -290,7 +284,7 @@ public class HashDbIngestModule implements FileIngestModule { } catch (BlackboardException ex) { logger.log(Level.SEVERE, String.format( - "A problem occurred while trying checking for existing artifacts for file '%s' (id=%d).", name, fileId), ex); //NON-NLS + "A problem occurred while checking for existing artifacts for file '%s' (id=%d).", name, fileId), ex); //NON-NLS services.postMessage(IngestMessage.createErrorMessage( HashLookupModuleFactory.getModuleName(), Bundle.HashDbIngestModule_dialogTitle_errorFindingArtifacts(name), @@ -337,7 +331,7 @@ public class HashDbIngestModule implements FileIngestModule { } /** - * Post hash set hit to the blackboard. + * Post a hash set hit to the blackboard. * * @param abstractFile The file to be processed. * @param md5Hash The MD5 hash value of the file. @@ -351,7 +345,6 @@ public class HashDbIngestModule implements FileIngestModule { "HashDbIngestModule.postToBB.fileName=File Name", "HashDbIngestModule.postToBB.md5Hash=MD5 Hash", "HashDbIngestModule.postToBB.hashsetName=Hash Set Name", - "# {0} - File name", "HashDbIngestModule.postToBB.knownBadMsg=Notable: {0}" }) From 3ea46cd32a810164b0066e9af371b875466dedd3 Mon Sep 17 00:00:00 2001 From: Eugene Livis Date: Wed, 25 Jul 2018 16:48:57 -0400 Subject: [PATCH 190/287] Saving searches by default --- .../autopsy/keywordsearch/DropdownListSearchPanel.java | 2 ++ .../autopsy/keywordsearch/DropdownSingleTermSearchPanel.java | 2 ++ 2 files changed, 4 insertions(+) diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/DropdownListSearchPanel.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/DropdownListSearchPanel.java index 12a0ae9b4f..a8a9a93fc6 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/DropdownListSearchPanel.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/DropdownListSearchPanel.java @@ -164,6 +164,8 @@ class DropdownListSearchPanel extends AdHocSearchPanel { } listsTableModel.resync(); updateIngestIndexLabel(); + + jSaveSearchResults.setSelected(true); } private void updateIngestIndexLabel() { diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/DropdownSingleTermSearchPanel.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/DropdownSingleTermSearchPanel.java index 3e33e73a5c..1f6744cced 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/DropdownSingleTermSearchPanel.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/DropdownSingleTermSearchPanel.java @@ -120,6 +120,8 @@ public class DropdownSingleTermSearchPanel extends AdHocSearchPanel { }; ingestRunning = IngestManager.getInstance().isIngestRunning(); updateIngestIndexLabel(); + + jSaveSearchResults.setSelected(true); IngestManager.getInstance().addIngestJobEventListener(new PropertyChangeListener() { @Override From 948bd3d2b3991aa305337c7c9e9a3e9bbe79856a Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Wed, 25 Jul 2018 14:54:46 -0600 Subject: [PATCH 191/287] git screwed this up --- .../datamodel/CentralRepoDatamodelTest.java | 6 ------ 1 file changed, 6 deletions(-) diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDatamodelTest.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDatamodelTest.java index 3e7f2776a8..114816d19c 100755 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDatamodelTest.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDatamodelTest.java @@ -853,8 +853,6 @@ public class CentralRepoDatamodelTest extends TestCase { Assert.fail(ex); } -<<<<<<< HEAD -======= // // Test getting common instances with expected results // try { // List instances = EamDb.getInstance().getArtifactInstancesByCaseValues(Arrays.asList(inAllDataSourcesHash, inDataSource1twiceHash)); @@ -897,7 +895,6 @@ public class CentralRepoDatamodelTest extends TestCase { // Exceptions.printStackTrace(ex); // Assert.fail(ex); // } ->>>>>>> 0468b6bd597a63c424d81b8569bb3df3bf8f7530 @@ -928,8 +925,6 @@ public class CentralRepoDatamodelTest extends TestCase { Exceptions.printStackTrace(ex); Assert.fail(ex); } -<<<<<<< HEAD -======= // // Test getting instances with null value // // Should just return nothing @@ -941,7 +936,6 @@ public class CentralRepoDatamodelTest extends TestCase { // Exceptions.printStackTrace(ex); // Assert.fail(ex); // } ->>>>>>> 0468b6bd597a63c424d81b8569bb3df3bf8f7530 // Test getting instances with path that should produce results try { From 92cf85efa358b1976e7023aad848861159021be9 Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Wed, 25 Jul 2018 14:55:00 -0600 Subject: [PATCH 192/287] this test is obsolete --- .../NoCentralRepoEnabledInterCaseTests.java | 85 ------------------- 1 file changed, 85 deletions(-) delete mode 100644 Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/NoCentralRepoEnabledInterCaseTests.java diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/NoCentralRepoEnabledInterCaseTests.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/NoCentralRepoEnabledInterCaseTests.java deleted file mode 100644 index 1a1dbe3235..0000000000 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/NoCentralRepoEnabledInterCaseTests.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * - * Autopsy Forensic Browser - * - * Copyright 2018 Basis Technology Corp. - * Contact: carrier sleuthkit 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.commonfilessearch; - -import junit.framework.Test; -import org.netbeans.junit.NbModuleSuite; -import org.netbeans.junit.NbTestCase; -import org.openide.util.Exceptions; -import org.sleuthkit.datamodel.TskCoreException; -import org.python.icu.impl.Assert; -import org.sleuthkit.autopsy.casemodule.Case; -import org.sleuthkit.autopsy.commonfilesearch.AbstractCommonAttributeSearcher; -import org.sleuthkit.autopsy.commonfilesearch.AllInterCaseCommonAttributeSearcher; -import org.sleuthkit.autopsy.commonfilesearch.CommonAttributeSearchResults; - -/** - * - * Just make sure nothing explodes when we run the feature in the absence of - * the Central Repo. This should be considered 'defensive' as it should not be - * possible to even run the feature if the CR is not available. - * - */ -public class NoCentralRepoEnabledInterCaseTests extends NbTestCase { - - private final InterCaseTestUtils utils; - - private Case currentCase; - - public static Test suite() { - NbModuleSuite.Configuration conf = NbModuleSuite.createConfiguration(NoCentralRepoEnabledInterCaseTests.class). - clusters(".*"). - enableModules(".*"); - return conf.suite(); - } - - public NoCentralRepoEnabledInterCaseTests(String name) { - super(name); - this.utils = new InterCaseTestUtils(this); - } - - @Override - public void setUp() { - try { - this.currentCase = this.utils.createCases(this.utils.getIngestSettingsForHashAndFileType(), InterCaseTestUtils.CASE1); - } catch (TskCoreException ex) { - Exceptions.printStackTrace(ex); - Assert.fail(ex); - } - } - - @Override - public void tearDown() { - this.utils.tearDown(); - } - - public void testOne() { - try { - AbstractCommonAttributeSearcher builder = new AllInterCaseCommonAttributeSearcher(false, false); - - CommonAttributeSearchResults metadata = builder.findFiles(); - - assertTrue("Should be no results.", metadata.size() == 0); - } catch (Exception ex) { - Exceptions.printStackTrace(ex); - Assert.fail(ex); - } - } -} From 80feccdbca06b5443454289bb2737c2bd30f3402 Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Wed, 25 Jul 2018 14:57:40 -0600 Subject: [PATCH 193/287] comments and cleanup --- .../IngestedWithHashAndFileTypeInterCaseTests.java | 6 ++---- .../autopsy/commonfilessearch/InterCaseTestUtils.java | 6 ++++++ 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileTypeInterCaseTests.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileTypeInterCaseTests.java index 683cb28fac..006989fe60 100644 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileTypeInterCaseTests.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileTypeInterCaseTests.java @@ -43,9 +43,7 @@ import static org.sleuthkit.autopsy.commonfilessearch.InterCaseTestUtils.*; public class IngestedWithHashAndFileTypeInterCaseTests extends NbTestCase { private final InterCaseTestUtils utils; - - private Case currentCase; - + public static Test suite() { NbModuleSuite.Configuration conf = NbModuleSuite.createConfiguration(IngestedWithHashAndFileTypeInterCaseTests.class). clusters(".*"). @@ -63,7 +61,7 @@ public class IngestedWithHashAndFileTypeInterCaseTests extends NbTestCase { this.utils.clearTestDir(); try { this.utils.enableCentralRepo(); - this.currentCase = this.utils.createCases(this.utils.getIngestSettingsForHashAndFileType(), InterCaseTestUtils.CASE3); + this.utils.createCases(this.utils.getIngestSettingsForHashAndFileType(), InterCaseTestUtils.CASE3); } catch (Exception ex) { Exceptions.printStackTrace(ex); Assert.fail(ex); diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/InterCaseTestUtils.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/InterCaseTestUtils.java index 53ec609839..610d31f152 100644 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/InterCaseTestUtils.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/InterCaseTestUtils.java @@ -63,6 +63,12 @@ import org.sleuthkit.datamodel.AbstractFile; /** * Utilities for testing intercase correlation feature. * + * This will be more useful when we add more flush out the intercase + * correlation features and need to add more tests. In particular, + * testing scenarios where we need different cases to be the current case + * will suggest that we create additional test classes, and we will want to + * import this utility in each new intercase test file. + * * Description of Test Data: (Note: files of the same name and extension are identical; files of the same name and differing extension are not identical.) From fa246542f6ab9691888b0344b7e2d8033ea9253a Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dgrove" Date: Wed, 25 Jul 2018 16:57:52 -0400 Subject: [PATCH 194/287] Further cleanup. --- .../casemodule/services/Blackboard.java | 101 ------------------ .../hashdatabase/HashDbIngestModule.java | 23 ++-- 2 files changed, 12 insertions(+), 112 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/services/Blackboard.java b/Core/src/org/sleuthkit/autopsy/casemodule/services/Blackboard.java index 234df7564b..6e954ce725 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/services/Blackboard.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/services/Blackboard.java @@ -20,12 +20,8 @@ package org.sleuthkit.autopsy.casemodule.services; import java.io.Closeable; import java.io.IOException; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; import org.openide.util.Lookup; import org.sleuthkit.autopsy.keywordsearchservice.KeywordSearchService; -import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardAttribute; import org.sleuthkit.datamodel.SleuthkitCase; @@ -133,103 +129,6 @@ public final class Blackboard implements Closeable { } } - /** - * Determine if an artifact of a given type exists for a given file with a - * specific set of attributes. - * - * @param file The file whose artifacts need to be looked at. - * @param artifactType The type of artifact to look for. - * @param attributesMap The collection of attributes to look for. - * - * @return True if the specific artifact exists; otherwise false. - * - * @throws BlackboardException If there is a problem getting artifacts or - * attributes. - */ - public static boolean checkIfArtifactExists(AbstractFile file, BlackboardArtifact.ARTIFACT_TYPE artifactType, - Map attributesMap) throws BlackboardException { - - ArrayList artifactsList; - - /* - * Get the file's artifacts. - */ - try { - artifactsList = file.getArtifacts(artifactType); - if (artifactsList.isEmpty()) { - return false; - } - } catch (TskCoreException ex) { - throw new BlackboardException(String.format("Failed to get %s artifacts for file '%s' (id=%d).", - artifactType.getDisplayName(), file.getName(), file.getId()), ex); - } - - /* - * Get each artifact's attributes and analyze them for matches. - */ - for (BlackboardArtifact artifact : artifactsList) { - try { - if (checkIfAttributesMatch(artifact.getAttributes(), attributesMap)) { - /* - * The exact artifact exists, so we don't need to look any - * further. - */ - return true; - } - } catch (TskCoreException ex) { - throw new BlackboardException(String.format("Failed to get attributes from artifact '%s' (id=%d).", - artifact.getName(), artifact.getObjectID()), ex); - } - } - - /* - * None of the artifacts have the exact set of attribute type/value - * combinations. The provided file does not have the artifact being - * sought. - */ - return false; - } - - /** - * Determine if the supplied attribute type/value combinations can all be - * found in the supplied attributes list. - * - * @param attributesList The list of attributes to analyze. - * @param attributesMap The attribute type/value combinations to check for. - * - * @return True if all attributes are found; otherwise false. - */ - private static boolean checkIfAttributesMatch(List attributesList, Map attributesMap) { - for (Map.Entry mapEntry : attributesMap.entrySet()) { - boolean match = false; - for (BlackboardAttribute attribute : attributesList) { - BlackboardAttribute.Type attributeType = attribute.getAttributeType(); - String attributeValue = attribute.getValueString(); - if (attributeType.getTypeID() == mapEntry.getKey().getTypeID() && attributeValue.equals(mapEntry.getValue())) { - /* - * The exact attribute type/value combination was found. - * Mark this as a match to continue looping through the - * attributes map. - */ - match = true; - break; - } - } - if (!match) { - /* - * The exact attribute type/value combination was not found. - */ - return false; - } - } - - /* - * All attribute type/value combinations were found in the provided - * attributes list. - */ - return true; - } - /** * Closes the blackboard. * diff --git a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbIngestModule.java b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbIngestModule.java index d78713f23f..66ecf89aea 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbIngestModule.java +++ b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbIngestModule.java @@ -31,7 +31,6 @@ import org.openide.util.NbBundle.Messages; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; import org.sleuthkit.autopsy.casemodule.services.Blackboard; -import org.sleuthkit.autopsy.casemodule.services.Blackboard.BlackboardException; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil; import org.sleuthkit.autopsy.healthmonitor.HealthMonitor; @@ -275,21 +274,23 @@ public class HashDbIngestModule implements FileIngestModule { */ Map attributeMap = new HashMap<>(); attributeMap.put(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_SET_NAME), hashSetName); - if (!Blackboard.checkIfArtifactExists(file, BlackboardArtifact.ARTIFACT_TYPE.TSK_HASHSET_HIT, attributeMap)) { - postHashSetHitToBlackboard(file, md5Hash, hashSetName, comment, db.getSendIngestMessages()); + try { + if (!org.sleuthkit.datamodel.Blackboard.checkIfArtifactExists(file, BlackboardArtifact.ARTIFACT_TYPE.TSK_HASHSET_HIT, attributeMap)) { + postHashSetHitToBlackboard(file, md5Hash, hashSetName, comment, db.getSendIngestMessages()); + } + } catch (TskCoreException ex) { + logger.log(Level.SEVERE, String.format( + "A problem occurred while checking for existing artifacts for file '%s' (id=%d).", name, fileId), ex); //NON-NLS + services.postMessage(IngestMessage.createErrorMessage( + HashLookupModuleFactory.getModuleName(), + Bundle.HashDbIngestModule_dialogTitle_errorFindingArtifacts(name), + Bundle.HashDbIngestModule_errorMessage_lookingForFileArtifacts(name))); + ret = ProcessResult.ERROR; } } long delta = (System.currentTimeMillis() - lookupstart); totals.totalLookuptime.addAndGet(delta); - } catch (BlackboardException ex) { - logger.log(Level.SEVERE, String.format( - "A problem occurred while checking for existing artifacts for file '%s' (id=%d).", name, fileId), ex); //NON-NLS - services.postMessage(IngestMessage.createErrorMessage( - HashLookupModuleFactory.getModuleName(), - Bundle.HashDbIngestModule_dialogTitle_errorFindingArtifacts(name), - Bundle.HashDbIngestModule_errorMessage_lookingForFileArtifacts(name))); - ret = ProcessResult.ERROR; } catch (TskException ex) { logger.log(Level.WARNING, String.format( "Couldn't lookup notable hash for file '%s' (id=%d) - see sleuthkit log for details", name, fileId), ex); //NON-NLS From e2a5a177465e38b84ed59633f7481bb127fb2e52 Mon Sep 17 00:00:00 2001 From: Andrew Ziehl Date: Wed, 25 Jul 2018 14:23:53 -0700 Subject: [PATCH 195/287] fix merge conflict of test removal --- .../datamodel/CentralRepoDatamodelTest.java | 62 ------------------- 1 file changed, 62 deletions(-) diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDatamodelTest.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDatamodelTest.java index 3e7f2776a8..a117e487e1 100755 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDatamodelTest.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDatamodelTest.java @@ -852,54 +852,6 @@ public class CentralRepoDatamodelTest extends TestCase { Exceptions.printStackTrace(ex); Assert.fail(ex); } - -<<<<<<< HEAD -======= -// // Test getting common instances with expected results -// try { -// List instances = EamDb.getInstance().getArtifactInstancesByCaseValues(Arrays.asList(inAllDataSourcesHash, inDataSource1twiceHash)); -// assertTrue("getArtifactInstancesByCaseValues returned " + instances.size() + " results - expected 5", instances.size() == 5); -// -// // This test works because all the instances of this hash were set to the same path -// for (CentralRepositoryFile inst : instances) { -// if(inst.getValue().equals(inAllDataSourcesHash)) { -// assertTrue("getArtifactInstancesByCaseValues returned instance with unexpected path " + inst.getFilePath(), -// inAllDataSourcesPath.equalsIgnoreCase(inst.getFilePath())); -// } -// else if(inst.getValue().equals(inDataSource1twiceHash)) { -// assertTrue("getArtifactInstancesByCaseValues returned instance with unexpected path " + inst.getFilePath(), -// inDataSource1twicePath1.equalsIgnoreCase(inst.getFilePath()) || inDataSource1twicePath2.equalsIgnoreCase(inst.getFilePath())); -// } -// } -// } catch (EamDbException ex) { -// Exceptions.printStackTrace(ex); -// Assert.fail(ex); -// } -// -// // Test getting instances expecting no results because they are not in the case -// try { -// CorrelationCase badCase = new CorrelationCase("badCaseUuid", "badCaseName"); -// List instances = EamDb.getInstance().getArtifactInstancesByCaseValues(badCase, Arrays.asList(inAllDataSourcesHash, inDataSource1twiceHash), 0); -// -// assertTrue("getArtifactInstancesByTypeValue returned " + instances.size() + " results - expected 0", instances.isEmpty()); -// } catch (EamDbException ex) { -// Exceptions.printStackTrace(ex); -// Assert.fail(ex); -// } -// -// -// // Test getting instances expecting no results because of bad hashes -// try { -// List instances = EamDb.getInstance().getArtifactInstancesByCaseValues(Arrays.asList("xyz", "123")); -// -// assertTrue("getArtifactInstancesByTypeValue returned " + instances.size() + " results - expected 0", instances.isEmpty()); -// } catch (EamDbException ex) { -// Exceptions.printStackTrace(ex); -// Assert.fail(ex); -// } ->>>>>>> 0468b6bd597a63c424d81b8569bb3df3bf8f7530 - - // Test getting instances expecting no results try { @@ -928,20 +880,6 @@ public class CentralRepoDatamodelTest extends TestCase { Exceptions.printStackTrace(ex); Assert.fail(ex); } -<<<<<<< HEAD -======= - -// // Test getting instances with null value -// // Should just return nothing -// try { -// List instances = EamDb.getInstance().getArtifactInstancesByCaseValues(null); -// -// assertTrue("getArtifactInstancesByTypeValue returned non-empty list for null value", instances.isEmpty()); -// } catch (EamDbException ex) { -// Exceptions.printStackTrace(ex); -// Assert.fail(ex); -// } ->>>>>>> 0468b6bd597a63c424d81b8569bb3df3bf8f7530 // Test getting instances with path that should produce results try { From 12ba928564e56d997eb17ccc0056de0318e9a7df Mon Sep 17 00:00:00 2001 From: Andrew Ziehl Date: Wed, 25 Jul 2018 14:30:25 -0700 Subject: [PATCH 196/287] Remove AbstractFile from constructor --- .../CentralRepoCommonAttributeInstanceNode.java | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepoCommonAttributeInstanceNode.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepoCommonAttributeInstanceNode.java index 5a19aeaead..db5607b192 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepoCommonAttributeInstanceNode.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepoCommonAttributeInstanceNode.java @@ -32,7 +32,6 @@ import org.sleuthkit.autopsy.datamodel.DisplayableItemNode; import org.sleuthkit.autopsy.datamodel.DisplayableItemNodeVisitor; import org.sleuthkit.autopsy.datamodel.NodeProperty; import org.sleuthkit.datamodel.AbstractFile; -import org.sleuthkit.datamodel.Content; /** * Used by the Common Files search feature to encapsulate instances of a given @@ -46,24 +45,17 @@ public class CentralRepoCommonAttributeInstanceNode extends DisplayableItemNode private final CorrelationAttributeInstance crFile; - //this may not be the same file, but at least it is identical, - // and we can use this to support certain actions in the tree table and crFile viewer - private final AbstractFile md5Reference; - CentralRepoCommonAttributeInstanceNode(CorrelationAttributeInstance content, AbstractFile md5Reference) { - super(Children.LEAF, Lookups.fixed(content)); // Using md5Reference enables Other Occurances, but for the current file path + super(Children.LEAF, Lookups.fixed(content)); this.crFile = content; this.setDisplayName(new File(this.crFile.getFilePath()).getName()); - this.md5Reference = md5Reference; } public CorrelationAttributeInstance getCorrelationAttributeInstance(){ return this.crFile; } - public Content getContent(){ - return this.md5Reference; - } + @Override public Action[] getActions(boolean context){ From 331ed172d50ba24841f6e6371aaf7a7619afaa51 Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Wed, 25 Jul 2018 17:10:53 -0600 Subject: [PATCH 197/287] full removal of abstract file cache for leaf node generation --- .../AbstractCommonAttributeInstance.java | 43 +++++-------------- .../CaseDBCommonAttributeInstance.java | 7 ++- .../CentralRepoCommonAttributeInstance.java | 9 ++-- ...entralRepoCommonAttributeInstanceNode.java | 5 +-- .../InterCaseCommonAttributeSearcher.java | 9 +--- .../IntraCaseCommonAttributeSearcher.java | 9 +--- 6 files changed, 22 insertions(+), 60 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeInstance.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeInstance.java index e75dc7b208..5ca29ccdf5 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeInstance.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeInstance.java @@ -19,7 +19,6 @@ */ package org.sleuthkit.autopsy.commonfilesearch; -import java.util.Map; import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttribute; import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance; import org.sleuthkit.autopsy.datamodel.DisplayableItemNode; @@ -42,8 +41,6 @@ import org.sleuthkit.datamodel.TskCoreException; public abstract class AbstractCommonAttributeInstance { private final Long abstractFileObjectId; - // maps object ID to file - private final Map cachedFiles; private final String caseName; private final String dataSource; @@ -57,9 +54,8 @@ public abstract class AbstractCommonAttributeInstance { * @param dataSource datasource where this attribute appears * @param caseName case where this attribute appears */ - AbstractCommonAttributeInstance(Long abstractFileReference, Map cachedFiles, String dataSource, String caseName) { + AbstractCommonAttributeInstance(Long abstractFileReference, String dataSource, String caseName) { this.abstractFileObjectId = abstractFileReference; - this.cachedFiles = cachedFiles; this.caseName = caseName; this.dataSource = dataSource; } @@ -71,31 +67,12 @@ public abstract class AbstractCommonAttributeInstance { * @param cachedFiles storage for abstract files which have been used * already so we can avoid extra roundtrips to the case db */ - AbstractCommonAttributeInstance(Map cachedFiles) { + AbstractCommonAttributeInstance() { this.abstractFileObjectId = -1L; - this.cachedFiles = cachedFiles; this.caseName = ""; this.dataSource = ""; } - /** - * Grab a cached instance of the AbstractFile or grab one from the - * SleuthkitCase. Use this in implementations of generateNodes. - * - * @return AbstractFile which is identical to the file instance generated by - * implementations of this object - */ - protected AbstractFile lookupOrLoadAbstractFile() { - if (this.cachedFiles.containsKey(this.getAbstractFileObjectId())) { - return this.cachedFiles.get(this.getAbstractFileObjectId()); - } else { - AbstractFile file = this.getAbstractFile(); - final long abstractFileId = file.getId(); - this.cachedFiles.put(abstractFileId, file); - return file; - } - } - /** * Get an AbstractFile for this instance if it can be retrieved from * the CaseDB. @@ -163,25 +140,25 @@ public abstract class AbstractCommonAttributeInstance { * * @param attributeInstance common file attribute instance form the central * repo - * @param equivalentAbstractFile an AbstractFile which is equivalent to the - * file in which the attribute instance was found + * @param abstractFile an AbstractFile from which the attribute instance was + * found - applies to CaseDbCommonAttributeInstance only * @param currentCaseName * @return the appropriate leaf node for the results tree * @throws TskCoreException */ - static DisplayableItemNode createInstance(CorrelationAttribute attribute, AbstractFile equivalentAbstractFile, String currentCaseName) throws TskCoreException { + static DisplayableItemNode createInstance(CorrelationAttribute attribute, AbstractFile abstractFile, String currentCaseName) throws TskCoreException { DisplayableItemNode leafNode; CorrelationAttributeInstance attributeInstance = attribute.getInstances().get(0); final String attributeDataSourceName = attributeInstance.getCorrelationDataSource().getName(); - final String abstractFileDataSourceName = equivalentAbstractFile.getDataSource().getName(); + final String abstractFileDataSourceName = abstractFile.getDataSource().getName(); final String attributeInstanceCaseName = attributeInstance.getCorrelationCase().getDisplayName(); final String attributeInstanceFullPath = attributeInstance.getFilePath().replace("\\", "/"); - final String currentAbstractFileParentPath = equivalentAbstractFile.getParentPath(); - final String currentAbstractFileName = equivalentAbstractFile.getName(); + final String currentAbstractFileParentPath = abstractFile.getParentPath(); + final String currentAbstractFileName = abstractFile.getName(); final String abstractFileFullPath = (currentAbstractFileParentPath + currentAbstractFileName).replace("\\", "/"); final boolean sameCase = attributeInstanceCaseName.equalsIgnoreCase(currentCaseName); @@ -189,9 +166,9 @@ public abstract class AbstractCommonAttributeInstance { final boolean sameDataSource = attributeDataSourceName.equalsIgnoreCase(abstractFileDataSourceName); if (sameCase && sameFileName && sameDataSource) { - leafNode = new CaseDBCommonAttributeInstanceNode(equivalentAbstractFile, currentCaseName, abstractFileDataSourceName); + leafNode = new CaseDBCommonAttributeInstanceNode(abstractFile, currentCaseName, abstractFileDataSourceName); } else { - leafNode = new CentralRepoCommonAttributeInstanceNode(attributeInstance, equivalentAbstractFile); + leafNode = new CentralRepoCommonAttributeInstanceNode(attributeInstance); } return leafNode; } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CaseDBCommonAttributeInstance.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CaseDBCommonAttributeInstance.java index 74363a869b..994df4c66a 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CaseDBCommonAttributeInstance.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CaseDBCommonAttributeInstance.java @@ -20,7 +20,6 @@ package org.sleuthkit.autopsy.commonfilesearch; import java.util.Arrays; -import java.util.Map; import java.util.logging.Level; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; @@ -45,13 +44,13 @@ final public class CaseDBCommonAttributeInstance extends AbstractCommonAttribute * @param objectId id of abstract file to find * @param dataSourceName name of datasource where the object is found */ - CaseDBCommonAttributeInstance(Long abstractFileReference, Map cachedFiles, String dataSource, String caseName) { - super(abstractFileReference, cachedFiles, dataSource, caseName); + CaseDBCommonAttributeInstance(Long abstractFileReference, String dataSource, String caseName) { + super(abstractFileReference, dataSource, caseName); } @Override public DisplayableItemNode[] generateNodes() { - final CaseDBCommonAttributeInstanceNode intraCaseCommonAttributeInstanceNode = new CaseDBCommonAttributeInstanceNode(this.lookupOrLoadAbstractFile(), this.getCaseName(), this.getDataSource()); + final CaseDBCommonAttributeInstanceNode intraCaseCommonAttributeInstanceNode = new CaseDBCommonAttributeInstanceNode(this.getAbstractFile(), this.getCaseName(), this.getDataSource()); return Arrays.asList(intraCaseCommonAttributeInstanceNode).toArray(new DisplayableItemNode[1]); } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepoCommonAttributeInstance.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepoCommonAttributeInstance.java index e11fe32e43..59674c2d68 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepoCommonAttributeInstance.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepoCommonAttributeInstance.java @@ -22,7 +22,6 @@ package org.sleuthkit.autopsy.commonfilesearch; import java.io.File; import java.util.ArrayList; import java.util.List; -import java.util.Map; import java.util.logging.Level; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; @@ -44,8 +43,8 @@ final public class CentralRepoCommonAttributeInstance extends AbstractCommonAttr private final Integer crFileId; private CorrelationAttribute currentAttribute; - CentralRepoCommonAttributeInstance(Integer attrInstId, Map cachedFiles) { - super(cachedFiles); + CentralRepoCommonAttributeInstance(Integer attrInstId) { + super(); this.crFileId = attrInstId; } @@ -103,8 +102,8 @@ final public class CentralRepoCommonAttributeInstance extends AbstractCommonAttr try { this.setCurrentAttributeInst(corrAttr); - AbstractFile equivalentAbstractFile = this.lookupOrLoadAbstractFile(); - DisplayableItemNode generatedInstNode = AbstractCommonAttributeInstance.createInstance(corrAttr, equivalentAbstractFile, currCaseDbName); + AbstractFile abstractFileForAttributeInstance = this.getAbstractFile(); + DisplayableItemNode generatedInstNode = AbstractCommonAttributeInstance.createInstance(corrAttr, abstractFileForAttributeInstance, currCaseDbName); attrInstNodeList.add(generatedInstNode); } catch (TskCoreException ex) { diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepoCommonAttributeInstanceNode.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepoCommonAttributeInstanceNode.java index db5607b192..e0b8e928d7 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepoCommonAttributeInstanceNode.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepoCommonAttributeInstanceNode.java @@ -31,7 +31,6 @@ import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeIns import org.sleuthkit.autopsy.datamodel.DisplayableItemNode; import org.sleuthkit.autopsy.datamodel.DisplayableItemNodeVisitor; import org.sleuthkit.autopsy.datamodel.NodeProperty; -import org.sleuthkit.datamodel.AbstractFile; /** * Used by the Common Files search feature to encapsulate instances of a given @@ -45,7 +44,7 @@ public class CentralRepoCommonAttributeInstanceNode extends DisplayableItemNode private final CorrelationAttributeInstance crFile; - CentralRepoCommonAttributeInstanceNode(CorrelationAttributeInstance content, AbstractFile md5Reference) { + CentralRepoCommonAttributeInstanceNode(CorrelationAttributeInstance content) { super(Children.LEAF, Lookups.fixed(content)); this.crFile = content; this.setDisplayName(new File(this.crFile.getFilePath()).getName()); @@ -55,8 +54,6 @@ public class CentralRepoCommonAttributeInstanceNode extends DisplayableItemNode return this.crFile; } - - @Override public Action[] getActions(boolean context){ List actionsList = new ArrayList<>(); diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearcher.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearcher.java index 6a1ffb5114..b8c18d50b8 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearcher.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearcher.java @@ -27,7 +27,6 @@ import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationCase; import org.sleuthkit.autopsy.centralrepository.datamodel.EamDb; import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException; import static org.sleuthkit.autopsy.timeline.datamodel.eventtype.ArtifactEventType.LOGGER; -import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.HashUtility; /** @@ -71,12 +70,8 @@ abstract class InterCaseCommonAttributeSearcher extends AbstractCommonAttributeS if (md5 == null || HashUtility.isNoDataMd5(md5)) { continue; } - Map fileCache = new HashMap<>(); try { - int caseId = commonFileCases.get(commonAttrId); - CorrelationCase autopsyCrCase = dbManager.getCaseById(caseId); - final String correlationCaseDisplayName = autopsyCrCase.getDisplayName(); // we don't *have* all the information for the rows in the CR, // so we need to consult the present case via the SleuthkitCase object // Later, when the FileInstanceNodde is built. Therefore, build node generators for now. @@ -85,14 +80,14 @@ abstract class InterCaseCommonAttributeSearcher extends AbstractCommonAttributeS //Add to intercase metaData final CommonAttributeValue commonAttributeValue = interCaseCommonFiles.get(md5); - AbstractCommonAttributeInstance searchResult = new CentralRepoCommonAttributeInstance(commonAttrId, fileCache); + AbstractCommonAttributeInstance searchResult = new CentralRepoCommonAttributeInstance(commonAttrId); commonAttributeValue.addFileInstanceMetadata(searchResult); } else { CommonAttributeValue commonAttributeValue = new CommonAttributeValue(md5); interCaseCommonFiles.put(md5, commonAttributeValue); - AbstractCommonAttributeInstance searchResult = new CentralRepoCommonAttributeInstance(commonAttrId, fileCache); + AbstractCommonAttributeInstance searchResult = new CentralRepoCommonAttributeInstance(commonAttrId); commonAttributeValue.addFileInstanceMetadata(searchResult); } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCaseCommonAttributeSearcher.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCaseCommonAttributeSearcher.java index 60a89fb5e5..143f061ed2 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCaseCommonAttributeSearcher.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCaseCommonAttributeSearcher.java @@ -28,7 +28,6 @@ import java.util.Map; import java.util.Set; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; -import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.HashUtility; import org.sleuthkit.datamodel.SleuthkitCase; import org.sleuthkit.datamodel.SleuthkitCase.CaseDbQuery; @@ -97,7 +96,6 @@ public abstract class IntraCaseCommonAttributeSearcher extends AbstractCommonAtt */ @Override public CommonAttributeSearchResults findFiles() throws TskCoreException, NoCurrentCaseException, SQLException { - //TODO do we need all those exceptions or can we differentiate when they are caught? Map commonFiles = new HashMap<>(); final Case currentCase = Case.getCurrentCaseThrows(); @@ -106,8 +104,6 @@ public abstract class IntraCaseCommonAttributeSearcher extends AbstractCommonAtt SleuthkitCase sleuthkitCase = currentCase.getSleuthkitCase(); String selectStatement = this.buildSqlSelectStatement(); - - Map fileCache = new HashMap<>(); try ( CaseDbQuery query = sleuthkitCase.executeQuery(selectStatement); @@ -125,10 +121,10 @@ public abstract class IntraCaseCommonAttributeSearcher extends AbstractCommonAtt if (commonFiles.containsKey(md5)) { final CommonAttributeValue commonAttributeValue = commonFiles.get(md5); - commonAttributeValue.addInstance(new CaseDBCommonAttributeInstance(objectId, fileCache, dataSource, caseName)); + commonAttributeValue.addInstance(new CaseDBCommonAttributeInstance(objectId, dataSource, caseName)); } else { final CommonAttributeValue commonAttributeValue = new CommonAttributeValue(md5); - commonAttributeValue.addInstance(new CaseDBCommonAttributeInstance(objectId, fileCache, dataSource, caseName)); + commonAttributeValue.addInstance(new CaseDBCommonAttributeInstance(objectId, dataSource, caseName)); commonFiles.put(md5, commonAttributeValue); } } @@ -169,5 +165,4 @@ public abstract class IntraCaseCommonAttributeSearcher extends AbstractCommonAtt } return mimeTypeString; } - } From 5e9401186ed40cd72e9d6bc36601df642c52d991 Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Thu, 26 Jul 2018 08:21:24 -0600 Subject: [PATCH 198/287] dead code removed and other cleanup --- .../CommonAttributeValue.java | 4 -- .../InterCaseCommonAttributeSearcher.java | 37 ++++++++----------- 2 files changed, 15 insertions(+), 26 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeValue.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeValue.java index ef6c22fe90..fa33df6aab 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeValue.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeValue.java @@ -74,10 +74,6 @@ final public class CommonAttributeValue { this.fileInstances.add(metadata); } - void addFileInstanceMetadata(AbstractCommonAttributeInstance metadata) { - this.fileInstances.add(metadata); - } - public Collection getInstances() { return Collections.unmodifiableCollection(this.fileInstances); } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearcher.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearcher.java index b8c18d50b8..938a33fee8 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearcher.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearcher.java @@ -22,11 +22,9 @@ package org.sleuthkit.autopsy.commonfilesearch; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.logging.Level; import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationCase; import org.sleuthkit.autopsy.centralrepository.datamodel.EamDb; import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException; -import static org.sleuthkit.autopsy.timeline.datamodel.eventtype.ArtifactEventType.LOGGER; import org.sleuthkit.datamodel.HashUtility; /** @@ -71,28 +69,23 @@ abstract class InterCaseCommonAttributeSearcher extends AbstractCommonAttributeS continue; } - try { - // we don't *have* all the information for the rows in the CR, - // so we need to consult the present case via the SleuthkitCase object - // Later, when the FileInstanceNodde is built. Therefore, build node generators for now. + // we don't *have* all the information for the rows in the CR, + // so we need to consult the present case via the SleuthkitCase object + // Later, when the FileInstanceNodde is built. Therefore, build node generators for now. - if (interCaseCommonFiles.containsKey(md5)) { - //Add to intercase metaData - final CommonAttributeValue commonAttributeValue = interCaseCommonFiles.get(md5); - - AbstractCommonAttributeInstance searchResult = new CentralRepoCommonAttributeInstance(commonAttrId); - commonAttributeValue.addFileInstanceMetadata(searchResult); + if (interCaseCommonFiles.containsKey(md5)) { + //Add to intercase metaData + final CommonAttributeValue commonAttributeValue = interCaseCommonFiles.get(md5); - } else { - CommonAttributeValue commonAttributeValue = new CommonAttributeValue(md5); - interCaseCommonFiles.put(md5, commonAttributeValue); - - AbstractCommonAttributeInstance searchResult = new CentralRepoCommonAttributeInstance(commonAttrId); - commonAttributeValue.addFileInstanceMetadata(searchResult); - - } - } catch (Exception ex) { - LOGGER.log(Level.WARNING, "Error getting artifact instances from database.", ex); // NON-NLS + AbstractCommonAttributeInstance searchResult = new CentralRepoCommonAttributeInstance(commonAttrId); + commonAttributeValue.addInstance(searchResult); + + } else { + CommonAttributeValue commonAttributeValue = new CommonAttributeValue(md5); + interCaseCommonFiles.put(md5, commonAttributeValue); + + AbstractCommonAttributeInstance searchResult = new CentralRepoCommonAttributeInstance(commonAttrId); + commonAttributeValue.addInstance(searchResult); } } From 23f48b0d33774ad3c0ea35e82845d6b1c7c0bb29 Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Thu, 26 Jul 2018 08:29:09 -0600 Subject: [PATCH 199/287] cleanup --- .../InterCaseCommonAttributeSearcher.java | 42 +++++++------------ 1 file changed, 16 insertions(+), 26 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearcher.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearcher.java index 6a1ffb5114..835a5e467b 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearcher.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearcher.java @@ -22,11 +22,9 @@ package org.sleuthkit.autopsy.commonfilesearch; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.logging.Level; import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationCase; import org.sleuthkit.autopsy.centralrepository.datamodel.EamDb; import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException; -import static org.sleuthkit.autopsy.timeline.datamodel.eventtype.ArtifactEventType.LOGGER; import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.HashUtility; @@ -72,33 +70,25 @@ abstract class InterCaseCommonAttributeSearcher extends AbstractCommonAttributeS continue; } Map fileCache = new HashMap<>(); + + // we don't *have* all the information for the rows in the CR, + // so we need to consult the present case via the SleuthkitCase object + // Later, when the FileInstanceNodde is built. Therefore, build node generators for now. - try { - int caseId = commonFileCases.get(commonAttrId); - CorrelationCase autopsyCrCase = dbManager.getCaseById(caseId); - final String correlationCaseDisplayName = autopsyCrCase.getDisplayName(); - // we don't *have* all the information for the rows in the CR, - // so we need to consult the present case via the SleuthkitCase object - // Later, when the FileInstanceNodde is built. Therefore, build node generators for now. + if (interCaseCommonFiles.containsKey(md5)) { + //Add to intercase metaData + final CommonAttributeValue commonAttributeValue = interCaseCommonFiles.get(md5); - if (interCaseCommonFiles.containsKey(md5)) { - //Add to intercase metaData - final CommonAttributeValue commonAttributeValue = interCaseCommonFiles.get(md5); - - AbstractCommonAttributeInstance searchResult = new CentralRepoCommonAttributeInstance(commonAttrId, fileCache); - commonAttributeValue.addFileInstanceMetadata(searchResult); + AbstractCommonAttributeInstance searchResult = new CentralRepoCommonAttributeInstance(commonAttrId, fileCache); + commonAttributeValue.addFileInstanceMetadata(searchResult); - } else { - CommonAttributeValue commonAttributeValue = new CommonAttributeValue(md5); - interCaseCommonFiles.put(md5, commonAttributeValue); - - AbstractCommonAttributeInstance searchResult = new CentralRepoCommonAttributeInstance(commonAttrId, fileCache); - commonAttributeValue.addFileInstanceMetadata(searchResult); - - } - } catch (Exception ex) { - LOGGER.log(Level.WARNING, "Error getting artifact instances from database.", ex); // NON-NLS - } + } else { + CommonAttributeValue commonAttributeValue = new CommonAttributeValue(md5); + interCaseCommonFiles.put(md5, commonAttributeValue); + + AbstractCommonAttributeInstance searchResult = new CentralRepoCommonAttributeInstance(commonAttrId, fileCache); + commonAttributeValue.addFileInstanceMetadata(searchResult); + } } Map> instanceCollatedCommonFiles = collateMatchesByNumberOfInstances(interCaseCommonFiles); From c30ed1f25113e595f32e9bee5df8fe57d021621c Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Thu, 26 Jul 2018 08:56:46 -0600 Subject: [PATCH 200/287] build script modified to include intercase correleation test data --- Core/build.xml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Core/build.xml b/Core/build.xml index af90bfdbba..14a6a5a28c 100644 --- a/Core/build.xml +++ b/Core/build.xml @@ -97,12 +97,12 @@ - + + + + + + From 29150018f37bbc435bfdb96bc8a37ec025edd8ae Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Thu, 26 Jul 2018 10:03:05 -0600 Subject: [PATCH 201/287] fixes non-critical bug that still would sometimes throw an exception --- .../AbstractCommonAttributeInstance.java | 54 ++++++++++--------- .../CentralRepoCommonAttributeInstance.java | 6 ++- 2 files changed, 35 insertions(+), 25 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeInstance.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeInstance.java index 5ca29ccdf5..246341163e 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeInstance.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeInstance.java @@ -27,9 +27,9 @@ import org.sleuthkit.datamodel.TskCoreException; /** * Represents an instance in either the CaseDB or CR that had a common match. - * Different implementations know how to get the instance details from either + * Different implementations know how to get the instance details from either * CaseDB or CR. - * + * * Defines leaf-type nodes used in the Common Files Search results tree. Leaf * nodes, may describe common attributes which exist in the current case DB or * in the Central Repo. When a reference to the AbstractFile is lacking (such as @@ -74,11 +74,11 @@ public abstract class AbstractCommonAttributeInstance { } /** - * Get an AbstractFile for this instance if it can be retrieved from - * the CaseDB. + * Get an AbstractFile for this instance if it can be retrieved from the + * CaseDB. * - * @return AbstractFile corresponding to this common attribute or null if - * it cannot be found + * @return AbstractFile corresponding to this common attribute or null if it + * cannot be found * @@@ Consider throwing exception instead of NULL */ abstract AbstractFile getAbstractFile(); @@ -140,7 +140,7 @@ public abstract class AbstractCommonAttributeInstance { * * @param attributeInstance common file attribute instance form the central * repo - * @param abstractFile an AbstractFile from which the attribute instance was + * @param abstractFile an AbstractFile from which the attribute instance was * found - applies to CaseDbCommonAttributeInstance only * @param currentCaseName * @return the appropriate leaf node for the results tree @@ -150,26 +150,32 @@ public abstract class AbstractCommonAttributeInstance { DisplayableItemNode leafNode; CorrelationAttributeInstance attributeInstance = attribute.getInstances().get(0); - final String attributeDataSourceName = attributeInstance.getCorrelationDataSource().getName(); - final String abstractFileDataSourceName = abstractFile.getDataSource().getName(); - final String attributeInstanceCaseName = attributeInstance.getCorrelationCase().getDisplayName(); - - final String attributeInstanceFullPath = attributeInstance.getFilePath().replace("\\", "/"); - - final String currentAbstractFileParentPath = abstractFile.getParentPath(); - final String currentAbstractFileName = abstractFile.getName(); - final String abstractFileFullPath = (currentAbstractFileParentPath + currentAbstractFileName).replace("\\", "/"); - - final boolean sameCase = attributeInstanceCaseName.equalsIgnoreCase(currentCaseName); - final boolean sameFileName = attributeInstanceFullPath.equalsIgnoreCase(abstractFileFullPath); - final boolean sameDataSource = attributeDataSourceName.equalsIgnoreCase(abstractFileDataSourceName); - - if (sameCase && sameFileName && sameDataSource) { - leafNode = new CaseDBCommonAttributeInstanceNode(abstractFile, currentCaseName, abstractFileDataSourceName); - } else { + if (abstractFile == null) { leafNode = new CentralRepoCommonAttributeInstanceNode(attributeInstance); + } else { + final String attributeDataSourceName = attributeInstance.getCorrelationDataSource().getName(); + final String abstractFileDataSourceName = abstractFile.getDataSource().getName(); + + final String attributeInstanceCaseName = attributeInstance.getCorrelationCase().getDisplayName(); + + final String attributeInstanceFullPath = attributeInstance.getFilePath().replace("\\", "/"); + + final String currentAbstractFileParentPath = abstractFile.getParentPath(); + final String currentAbstractFileName = abstractFile.getName(); + final String abstractFileFullPath = (currentAbstractFileParentPath + currentAbstractFileName).replace("\\", "/"); + + final boolean sameCase = attributeInstanceCaseName.equalsIgnoreCase(currentCaseName); + final boolean sameFileName = attributeInstanceFullPath.equalsIgnoreCase(abstractFileFullPath); + final boolean sameDataSource = attributeDataSourceName.equalsIgnoreCase(abstractFileDataSourceName); + + if (sameCase && sameFileName && sameDataSource) { + leafNode = new CaseDBCommonAttributeInstanceNode(abstractFile, currentCaseName, abstractFileDataSourceName); + } else { + leafNode = new CentralRepoCommonAttributeInstanceNode(attributeInstance); + } } + return leafNode; } } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepoCommonAttributeInstance.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepoCommonAttributeInstance.java index 59674c2d68..2e0d623fa4 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepoCommonAttributeInstance.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepoCommonAttributeInstance.java @@ -77,7 +77,11 @@ final public class CentralRepoCommonAttributeInstance extends AbstractCommonAttr } // If not direct match exists, return first md5 match, only used as a backing file for CR instance node. if (finalAbstractFile == null) { - finalAbstractFile = potentialAbstractFiles.get(0); + if(potentialAbstractFiles.isEmpty()){ + return null; + } else { + finalAbstractFile = potentialAbstractFiles.get(0); + } } return finalAbstractFile; From 178b48ecb78fa705253263463bb48e853dab96f4 Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Thu, 26 Jul 2018 10:04:18 -0600 Subject: [PATCH 202/287] comments --- .../commonfilesearch/AbstractCommonAttributeInstance.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeInstance.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeInstance.java index 246341163e..d6ef8dfb03 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeInstance.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeInstance.java @@ -78,8 +78,7 @@ public abstract class AbstractCommonAttributeInstance { * CaseDB. * * @return AbstractFile corresponding to this common attribute or null if it - * cannot be found - * @@@ Consider throwing exception instead of NULL + * cannot be found (for example, in the event that this is a central repo file) */ abstract AbstractFile getAbstractFile(); From 821b8ce04e4d269514e7519f73675ae0bcda9337 Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dgrove" Date: Thu, 26 Jul 2018 14:36:36 -0400 Subject: [PATCH 203/287] Using new method signature. --- .../autopsy/modules/hashdatabase/HashDbIngestModule.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbIngestModule.java b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbIngestModule.java index 66ecf89aea..e018a612e1 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbIngestModule.java +++ b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbIngestModule.java @@ -272,10 +272,10 @@ public class HashDbIngestModule implements FileIngestModule { * We have a match. Now create an artifact if it is * determined that one hasn't been created yet. */ - Map attributeMap = new HashMap<>(); - attributeMap.put(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_SET_NAME), hashSetName); + List attributesList = new ArrayList<>(); + attributesList.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_SET_NAME, HashLookupModuleFactory.getModuleName(), hashSetName)); try { - if (!org.sleuthkit.datamodel.Blackboard.checkIfArtifactExists(file, BlackboardArtifact.ARTIFACT_TYPE.TSK_HASHSET_HIT, attributeMap)) { + if (!org.sleuthkit.datamodel.Blackboard.artifactExists(file, BlackboardArtifact.ARTIFACT_TYPE.TSK_HASHSET_HIT, attributesList)) { postHashSetHitToBlackboard(file, md5Hash, hashSetName, comment, db.getSendIngestMessages()); } } catch (TskCoreException ex) { From 08ad7eeba13c4780e30d2a63316cf4f26b106894 Mon Sep 17 00:00:00 2001 From: Andrew Ziehl Date: Thu, 26 Jul 2018 12:07:27 -0700 Subject: [PATCH 204/287] remove EamDb publicly accessible methods, replace with a single generic processInstanceTableWhere mmethod which takes a query string. --- .../datamodel/AbstractSqlEamDb.java | 151 +----------------- .../centralrepository/datamodel/EamDb.java | 26 +-- .../datamodel/SqliteEamDb.java | 47 +----- .../InterCaseSearchResultsProcessor.java | 23 ++- 4 files changed, 32 insertions(+), 215 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java index 4b7b49f7e8..e6dd3a0ccd 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java @@ -752,6 +752,7 @@ abstract class AbstractSqlEamDb implements EamDb { return artifactInstances; } + /** * Retrieves eamArtifact instances from the database that are associated * with the aType and filePath @@ -1894,51 +1895,13 @@ abstract class AbstractSqlEamDb implements EamDb { EamDbUtil.closeConnection(conn); } } - - /** - * Process the Artifact instance in the EamDb - * - * @param type EamArtifact.Type to search for - * @param instanceTableCallback callback to process the instance - * - * @throws EamDbException - */ - @Override - public void processInstanceTable(CorrelationAttribute.Type type, InstanceTableCallback instanceTableCallback) throws EamDbException { - if (type == null) { - throw new EamDbException("Correlation type is null"); - } - if (instanceTableCallback == null) { - throw new EamDbException("Callback interface is null"); - } - - Connection conn = connect(); - PreparedStatement preparedStatement = null; - ResultSet resultSet = null; - String tableName = EamDbUtil.correlationTypeToInstanceTableName(type); - StringBuilder sql = new StringBuilder(); - sql.append("select * from "); - sql.append(tableName); - - try { - preparedStatement = conn.prepareStatement(sql.toString()); - resultSet = preparedStatement.executeQuery(); - instanceTableCallback.process(resultSet); - } catch (SQLException ex) { - throw new EamDbException("Error getting all artifact instances from instances table", ex); - } finally { - EamDbUtil.closeStatement(preparedStatement); - EamDbUtil.closeResultSet(resultSet); - EamDbUtil.closeConnection(conn); - } - } - /** - * Process the Artifact instance in the EamDb + * Process the Artifact instance in the EamDb give a where clause * * @param type EamArtifact.Type to search for * @param instanceTableCallback callback to process the instance + * @param whereClause query string to execute * @throws EamDbException */ @Override @@ -1958,115 +1921,11 @@ abstract class AbstractSqlEamDb implements EamDb { StringBuilder sql = new StringBuilder(3); sql.append("select * from "); sql.append(tableName); - sql.append(" WHERE id = ?"); + sql.append(" WHERE "); + sql.append(whereClause); try { preparedStatement = conn.prepareStatement(sql.toString()); - preparedStatement.setInt(1, id); - resultSet = preparedStatement.executeQuery(); - instanceTableCallback.process(resultSet); - } catch (SQLException ex) { - throw new EamDbException("Error getting all artifact instances from instances table", ex); - } finally { - EamDbUtil.closeStatement(preparedStatement); - EamDbUtil.closeResultSet(resultSet); - EamDbUtil.closeConnection(conn); - } - } - - /** - * Process the Artifact instance in the EamDb - * - * @param type EamArtifact.Type to search for - * @param correlationCase CorrelationCase to filter by - * @param instanceTableCallback callback to process the instance - * @throws EamDbException - */ - @Override - public void processCaseInstancesTable(CorrelationAttribute.Type type, CorrelationCase correlationCase, InstanceTableCallback instanceTableCallback) throws EamDbException { - if (type == null) { - throw new EamDbException("Correlation type is null"); - } - - if (instanceTableCallback == null) { - throw new EamDbException("Callback interface is null"); - } - - if(correlationCase == null) { - throw new EamDbException("Correlation Case is null"); - } - - Connection conn = connect(); - PreparedStatement preparedStatement = null; - ResultSet resultSet = null; - String tableName = EamDbUtil.correlationTypeToInstanceTableName(type); - StringBuilder sql = new StringBuilder(7); - sql.append("SELECT id, value, case_id FROM "); - sql.append(tableName); - sql.append(" WHERE value IN (SELECT value FROM "); // TODO should this select * so any field is available? - sql.append(tableName); - sql.append(" WHERE value IN (SELECT value FROM "); - sql.append(tableName); - sql.append(" WHERE case_id=? AND (known_status !=? OR known_status IS NULL) GROUP BY value) GROUP BY value HAVING COUNT(DISTINCT case_id) > 1) ORDER BY value"); - - try { - preparedStatement = conn.prepareStatement(sql.toString()); - preparedStatement.setInt(1, correlationCase.getID()); - preparedStatement.setByte(2, TskData.FileKnown.KNOWN.getFileKnownValue()); - resultSet = preparedStatement.executeQuery(); - instanceTableCallback.process(resultSet); - } catch (SQLException ex) { - throw new EamDbException("Error getting all artifact instances from instances table", ex); - } finally { - EamDbUtil.closeStatement(preparedStatement); - EamDbUtil.closeResultSet(resultSet); - EamDbUtil.closeConnection(conn); - } - } - - /** - * Process the Artifact instance in the EamDb - * - * @param type EamArtifact.Type to search for - * @param correlationCase CorrelationCase to filter by - * @param singleCase Single Case to filter by - * @param instanceTableCallback callback to process the instance - * @throws EamDbException - */ - @Override - public void processSingleCaseInstancesTable(CorrelationAttribute.Type type, CorrelationCase correlationCase, CorrelationCase singleCase,InstanceTableCallback instanceTableCallback) throws EamDbException { - if (type == null) { - throw new EamDbException("Correlation type is null"); - } - - if (instanceTableCallback == null) { - throw new EamDbException("Callback interface is null"); - } - - if(correlationCase == null) { - throw new EamDbException("Correlation Case is null"); - } - - Connection conn = connect(); - PreparedStatement preparedStatement = null; - ResultSet resultSet = null; - String tableName = EamDbUtil.correlationTypeToInstanceTableName(type); - StringBuilder sql = new StringBuilder(8); - sql.append("SELECT id, value, case_id FROM "); - sql.append(tableName); - sql.append(" WHERE value IN (SELECT value FROM "); // TODO should this select * so any field is available? - sql.append(tableName); - sql.append(" WHERE value IN (SELECT value FROM "); - sql.append(tableName); - sql.append(" WHERE case_id=? AND (known_status !=? OR known_status IS NULL) GROUP BY value)"); - sql.append(" AND (case_id=? OR case_id=?) GROUP BY value HAVING COUNT(DISTINCT case_id) > 1) ORDER BY value"); - - try { - preparedStatement = conn.prepareStatement(sql.toString()); - preparedStatement.setInt(1, correlationCase.getID()); - preparedStatement.setByte(2, TskData.FileKnown.KNOWN.getFileKnownValue()); - preparedStatement.setInt(3, correlationCase.getID()); - preparedStatement.setInt(4, singleCase.getID()); resultSet = preparedStatement.executeQuery(); instanceTableCallback.process(resultSet); } catch (SQLException ex) { diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDb.java index f9f37a86f0..e4fb30583e 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDb.java @@ -706,34 +706,14 @@ public interface EamDb { */ void processInstanceTable(CorrelationAttribute.Type type, InstanceTableCallback instanceTableCallback) throws EamDbException; - /** - * Process a single Artifact instance in the EamDb - * - * @param type EamArtifact.Type to search for - * @param id the id of the row to return - * @param instanceTableCallback callback to process the instance - * @throws EamDbException - */ - void processInstanceTableRow(CorrelationAttribute.Type type, int id, InstanceTableCallback instanceTableCallback) throws EamDbException; - - /** - * Process the Artifact md5s in the EamDb for matches of case files which are not known - * @param type EamArtifact.Type to search for - * @param correlationCase CorrelationCase to filter by - * @param instanceTableCallback callback to process the instance - * @throws EamDbException - */ - void processCaseInstancesTable(CorrelationAttribute.Type type, CorrelationCase correlationCase, InstanceTableCallback instanceTableCallback) throws EamDbException; - /** * Process the Artifact instance in the EamDb * * @param type EamArtifact.Type to search for - * @param correlationCase CorrelationCase to filter by - * @param singleCase Single Case to filter by * @param instanceTableCallback callback to process the instance + * @param whereClause query string to execute * @throws EamDbException */ - void processSingleCaseInstancesTable(CorrelationAttribute.Type type, CorrelationCase correlationCase, CorrelationCase singleCase,InstanceTableCallback instanceTableCallback) throws EamDbException; - + void processInstanceTableWhere(CorrelationAttribute.Type type, String whereClause, InstanceTableCallback instanceTableCallback) throws EamDbException; + } diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java index a9f930fd0c..300451cdbd 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java @@ -735,62 +735,23 @@ final class SqliteEamDb extends AbstractSqlEamDb { releaseSharedLock(); } } - - /** - * Process a single Artifact instance row in the EamDb - * - * @param type EamArtifact.Type to search for - * @param id the id of the row to return - * @param instanceTableCallback callback to process the instance - * @throws EamDbException - */ - @Override - public void processInstanceTableRow(CorrelationAttribute.Type type, int id, InstanceTableCallback instanceTableCallback) throws EamDbException { - try { - acquireSharedLock(); - super.processInstanceTableRow(type, id, instanceTableCallback); - } finally { - releaseSharedLock(); - } - } - - /** - * Process the Artifact md5s in the EamDb for matches of case files which - * are not known - * - * @param type EamArtifact.Type to search for - * @param correlationCase CorrelationCase to filter by - * @param instanceTableCallback callback to process the instance - * @throws EamDbException - */ - @Override - public void processCaseInstancesTable(CorrelationAttribute.Type type, CorrelationCase correlationCase, InstanceTableCallback instanceTableCallback) throws EamDbException { - try { - acquireSharedLock(); - super.processCaseInstancesTable(type, correlationCase, instanceTableCallback); - } finally { - releaseSharedLock(); - } - } /** * Process the Artifact instance in the EamDb * * @param type EamArtifact.Type to search for - * @param correlationCase CorrelationCase to filter by - * @param singleCase Single Case to filter by * @param instanceTableCallback callback to process the instance * @throws EamDbException */ @Override - public void processSingleCaseInstancesTable(CorrelationAttribute.Type type, CorrelationCase correlationCase, CorrelationCase singleCase,InstanceTableCallback instanceTableCallback) throws EamDbException { - try { + public void processInstanceTableWhere(CorrelationAttribute.Type type, String whereClause, InstanceTableCallback instanceTableCallback) throws EamDbException { + try { acquireSharedLock(); - super.processSingleCaseInstancesTable(type, correlationCase, singleCase, instanceTableCallback); + super.processInstanceTable(type, instanceTableCallback); } finally { releaseSharedLock(); } - } + } /** * Check whether a reference set with the given name/version is in the diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseSearchResultsProcessor.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseSearchResultsProcessor.java index 8416bbd856..498cfb36a7 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseSearchResultsProcessor.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseSearchResultsProcessor.java @@ -33,6 +33,7 @@ import org.sleuthkit.autopsy.centralrepository.datamodel.EamDb; import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException; import org.sleuthkit.autopsy.centralrepository.datamodel.InstanceTableCallback; import org.sleuthkit.autopsy.coreutils.Logger; +import org.sleuthkit.datamodel.TskData; /** * Used to process and return CorrelationCase md5s from the EamDB for @@ -46,6 +47,15 @@ final class InterCaseSearchResultsProcessor { private final Map intercaseCommonValuesMap = new HashMap<>(); // maps row ID to case ID private final Map intercaseCommonCasesMap = new HashMap<>(); + private final String interCaseWhereClause = "value IN (SELECT value FROM file_instances" + + " WHERE value IN (SELECT value FROM file_instances" + + " WHERE case_id=%s AND (known_status !=%s OR known_status IS NULL) GROUP BY value)" + + " GROUP BY value HAVING COUNT(DISTINCT case_id) > 1) ORDER BY value"; + private final String singleInterCaseWhereClause = "value IN (SELECT value FROM file_instances " + + "WHERE value IN (SELECT value FROM file_instances " + + "WHERE case_id=%s AND (known_status !=%s OR known_status IS NULL) GROUP BY value) " + + "AND (case_id=%s OR case_id=%s) GROUP BY value HAVING COUNT(DISTINCT case_id) > 1) ORDER BY value"; + /** * Finds a single CorrelationAttribute given an id. @@ -58,7 +68,7 @@ final class InterCaseSearchResultsProcessor { InterCaseCommonAttributeRowCallback instancetableCallback = new InterCaseCommonAttributeRowCallback(); EamDb DbManager = EamDb.getInstance(); CorrelationAttribute.Type fileType = DbManager.getCorrelationTypeById(CorrelationAttribute.FILES_TYPE_ID); - DbManager.processInstanceTableRow(fileType, attrbuteId, instancetableCallback); + DbManager.processInstanceTableWhere(fileType, String.format("id = %s", attrbuteId), instancetableCallback); return instancetableCallback.getCorrelationAttribute(); @@ -80,7 +90,11 @@ final class InterCaseSearchResultsProcessor { InterCaseCommonAttributesCallback instancetableCallback = new InterCaseCommonAttributesCallback(); EamDb DbManager = EamDb.getInstance(); CorrelationAttribute.Type fileType = DbManager.getCorrelationTypeById(CorrelationAttribute.FILES_TYPE_ID); - DbManager.processCaseInstancesTable(fileType, DbManager.getCase(currentCase), instancetableCallback); + int caseId = DbManager.getCase(currentCase).getID(); + + DbManager.processInstanceTableWhere(fileType, String.format(interCaseWhereClause, caseId, + TskData.FileKnown.KNOWN.getFileKnownValue()), + instancetableCallback); } catch (EamDbException ex) { LOGGER.log(Level.SEVERE, "Error accessing EamDb processing CaseInstancesTable.", ex); @@ -101,7 +115,10 @@ final class InterCaseSearchResultsProcessor { InterCaseCommonAttributesCallback instancetableCallback = new InterCaseCommonAttributesCallback(); EamDb DbManager = EamDb.getInstance(); CorrelationAttribute.Type fileType = DbManager.getCorrelationTypeById(CorrelationAttribute.FILES_TYPE_ID); - DbManager.processSingleCaseInstancesTable(fileType, DbManager.getCase(currentCase), singleCase, instancetableCallback); + int caseId = DbManager.getCase(currentCase).getID(); + int targetCaseId = singleCase.getID(); + DbManager.processInstanceTableWhere(fileType, String.format(singleInterCaseWhereClause, caseId, + TskData.FileKnown.KNOWN.getFileKnownValue(), caseId, targetCaseId), instancetableCallback); } catch (EamDbException ex) { LOGGER.log(Level.SEVERE, "Error accessing EamDb processing CaseInstancesTable.", ex); } From 9ee4f8d44fe43904de4a3f10f0d743d07e418872 Mon Sep 17 00:00:00 2001 From: Andrew Ziehl Date: Thu, 26 Jul 2018 12:38:25 -0700 Subject: [PATCH 205/287] fix bug where intracase datasource was not initialized. --- .../sleuthkit/autopsy/commonfilesearch/IntraCasePanel.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCasePanel.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCasePanel.java index c88537cb17..397cf04098 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCasePanel.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCasePanel.java @@ -20,6 +20,7 @@ package org.sleuthkit.autopsy.commonfilesearch; import java.util.Collections; +import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; import javax.swing.ComboBoxModel; @@ -40,7 +41,7 @@ public class IntraCasePanel extends javax.swing.JPanel { private boolean singleDataSource; private String selectedDataSource; private ComboBoxModel dataSourcesList = new DataSourceComboBoxModel(); - private Map dataSourceMap; + private final Map dataSourceMap; private CommonAttributePanel parent; private String errorMessage; @@ -51,6 +52,7 @@ public class IntraCasePanel extends javax.swing.JPanel { public IntraCasePanel() { initComponents(); this.errorMessage = ""; + this.dataSourceMap = new HashMap<>(); } public void setParent(CommonAttributePanel parent){ From 5bad6cff780c7957fb74647850d28daf1886a345 Mon Sep 17 00:00:00 2001 From: Andrew Ziehl Date: Thu, 26 Jul 2018 12:57:24 -0700 Subject: [PATCH 206/287] Cleanup and add tests, add null check. --- .../datamodel/AbstractSqlEamDb.java | 4 + .../datamodel/CentralRepoDatamodelTest.java | 84 +++++++------------ 2 files changed, 33 insertions(+), 55 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java index e6dd3a0ccd..c2e4651808 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java @@ -1913,6 +1913,10 @@ abstract class AbstractSqlEamDb implements EamDb { if (instanceTableCallback == null) { throw new EamDbException("Callback interface is null"); } + + if(whereClause == null) { + throw new EamDbException("Where clause is null"); + } Connection conn = connect(); PreparedStatement preparedStatement = null; diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDatamodelTest.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDatamodelTest.java index 030f53ed31..6efee65f71 100755 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDatamodelTest.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDatamodelTest.java @@ -852,50 +852,6 @@ public class CentralRepoDatamodelTest extends TestCase { Exceptions.printStackTrace(ex); Assert.fail(ex); } - - // Test getting common instances with expected results - try { - List instances = EamDb.getInstance().getArtifactInstancesByCaseValues(Arrays.asList(inAllDataSourcesHash, inDataSource1twiceHash)); - assertTrue("getArtifactInstancesByCaseValues returned " + instances.size() + " results - expected 5", instances.size() == 5); - - // This test works because all the instances of this hash were set to the same path - for (CentralRepositoryFile inst : instances) { - if(inst.getValue().equals(inAllDataSourcesHash)) { - assertTrue("getArtifactInstancesByCaseValues returned instance with unexpected path " + inst.getFilePath(), - inAllDataSourcesPath.equalsIgnoreCase(inst.getFilePath())); - } - else if(inst.getValue().equals(inDataSource1twiceHash)) { - assertTrue("getArtifactInstancesByCaseValues returned instance with unexpected path " + inst.getFilePath(), - inDataSource1twicePath1.equalsIgnoreCase(inst.getFilePath()) || inDataSource1twicePath2.equalsIgnoreCase(inst.getFilePath())); - } - } - } catch (EamDbException ex) { - Exceptions.printStackTrace(ex); - Assert.fail(ex); - } - - // Test getting instances expecting no results because they are not in the case - try { - CorrelationCase badCase = new CorrelationCase("badCaseUuid", "badCaseName"); - List instances = EamDb.getInstance().getArtifactInstancesByCaseValues(badCase, Arrays.asList(inAllDataSourcesHash, inDataSource1twiceHash), 0); - - assertTrue("getArtifactInstancesByTypeValue returned " + instances.size() + " results - expected 0", instances.isEmpty()); - } catch (EamDbException ex) { - Exceptions.printStackTrace(ex); - Assert.fail(ex); - } - - - // Test getting instances expecting no results because of bad hashes - try { - List instances = EamDb.getInstance().getArtifactInstancesByCaseValues(Arrays.asList("xyz", "123")); - - assertTrue("getArtifactInstancesByTypeValue returned " + instances.size() + " results - expected 0", instances.isEmpty()); - } catch (EamDbException ex) { - Exceptions.printStackTrace(ex); - Assert.fail(ex); - } - // Test getting instances expecting no results try { @@ -924,17 +880,7 @@ public class CentralRepoDatamodelTest extends TestCase { Exceptions.printStackTrace(ex); Assert.fail(ex); } - - // Test getting instances with null value - // Should just return nothing - try { - List instances = EamDb.getInstance().getArtifactInstancesByCaseValues(null); - - assertTrue("getArtifactInstancesByTypeValue returned non-empty list for null value", instances.isEmpty()); - } catch (EamDbException ex) { - Exceptions.printStackTrace(ex); - Assert.fail(ex); - } + // Test getting instances with path that should produce results try { @@ -1178,6 +1124,34 @@ public class CentralRepoDatamodelTest extends TestCase { } catch (EamDbException ex) { // This is the expected } + + // Test running processinstance which queries all rows from instances table + try { + // Add two instances to the central repository and use the callback query to verify we can see them + CorrelationAttribute attr = new CorrelationAttribute(fileType, callbackTestFileHash); + CorrelationAttributeInstance inst1 = new CorrelationAttributeInstance(case1, dataSource1fromCase1, callbackTestFilePath1); + CorrelationAttributeInstance inst2 = new CorrelationAttributeInstance(case1, dataSource1fromCase1, callbackTestFilePath2); + attr.addInstance(inst1); + attr.addInstance(inst2); + EamDb DbManager = EamDb.getInstance(); + DbManager.addArtifact(attr); + AttributeInstanceTableCallback instancetableCallback = new AttributeInstanceTableCallback(); + DbManager.processInstanceTableWhere(fileType, String.format("id = %s", attr.getID()), instancetableCallback); + int count1 = instancetableCallback.getCounter(); + int count2 = instancetableCallback.getCounterNamingConvention(); + assertTrue("Process Instance count with filepath naming convention: " + count2 + "-expected 2", count2 == 2); + assertTrue("Process Instance count with filepath without naming convention: " + count1 + "-expected greater than 0", count1 > 0); + } catch (EamDbException ex) { + Exceptions.printStackTrace(ex); + } + + try { + //test null inputs + EamDb.getInstance().processInstanceTableWhere(null, null, null); + Assert.fail("processinstance method failed to throw exception for null type value"); + } catch (EamDbException ex) { + // This is the expected + } } /** From 4ad2b2c8fb425fb780cdc6cf84dba0812dd850c8 Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dgrove" Date: Thu, 26 Jul 2018 17:22:15 -0400 Subject: [PATCH 207/287] Cleanup. --- .../modules/hashdatabase/Bundle.properties | 2 ++ .../modules/hashdatabase/Bundle_ja.properties | 22 +++++++++++++++++++ .../hashdatabase/HashDbIngestModule.java | 6 ++--- .../hashdatabase/HashLookupModuleFactory.java | 6 +++-- 4 files changed, 31 insertions(+), 5 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/Bundle.properties b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/Bundle.properties index 3ca6c162b6..c18245d7c7 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/Bundle.properties @@ -148,6 +148,8 @@ AddContentToHashDbAction.addFilesToHashSet.files=files AddContentToHashDbAction.addFilesToHashSet.file=file HashDbManager.errCreatingIndex.title=Error creating index HashDbManager.errCreatingIndex.msg=Error creating index\: {0} +HashLookupModuleFactory.getIngestJobSettingsPanel.exception.msg=Expected settings argument to be instanceof HashLookupModuleSettings +HashLookupModuleFactory.createFileIngestModule.exception.msg=Expected settings argument to be instanceof HashLookupModuleSettings HashLookupModuleSettingsPanel.alwaysCalcHashesCheckbox.toolTipText=Calculate MD5 even if no hash set is selected HashDbSearchPanel.hashTable.defaultModel.title.text=MD5 Hashes AddHashValuesToDatabaseDialog.JDialog.Title=Add Hashes to Hash Set diff --git a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/Bundle_ja.properties b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/Bundle_ja.properties index 3d2ab7a085..d3ffff1cfb 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/Bundle_ja.properties +++ b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/Bundle_ja.properties @@ -76,7 +76,27 @@ HashDbImportDatabaseDialog.importHashDbErr=\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\ HashDbImportDatabaseDialog.mustSelectHashDbFilePathMsg=\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306e\u30d5\u30a1\u30a4\u30eb\u30d1\u30b9\u306e\u9078\u629e\u304c\u5fc5\u8981\u3067\u3059\u3002 HashDbImportDatabaseDialog.hashDbDoesNotExistMsg=\u9078\u629e\u3055\u308c\u305f\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306f\u5b58\u5728\u3057\u307e\u305b\u3093\u3002 HashDbImportDatabaseDialog.errorMessage.failedToOpenHashDbMsg={0}\u3067\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3092\u958b\u304f\u306e\u306b\u5931\u6557\u3057\u307e\u3057\u305f\u3002 +HashLookupModuleFactory.moduleName.text=\u30cf\u30c3\u30b7\u30e5\u30eb\u30c3\u30af\u30a2\u30c3\u30d7 +HashLookupModuleFactory.moduleDescription.text=\u6a19\u6e96\u306eNSRL\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306a\u3069\u3001\u63d0\u4f9b\u3055\u308c\u305f\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3092\u5229\u7528\u3057\u3066\u3001\u65e2\u77e5\u307e\u305f\u306f\u7591\u308f\u3057\u3044\u3082\u306e\u3092\u691c\u77e5\u3057\u307e\u3059\u3002 +HashDbIngestModule.noKnownHashDbSetMsg=\u65e2\u77e5\u306e\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u304c\u5b58\u5728\u3057\u307e\u305b\u3093\u3002 +HashDbIngestModule.knownFileSearchWillNotExecuteWarn=\u65e2\u77e5\u306e\u30d5\u30a1\u30a4\u30eb\u691c\u7d22\u304c\u5b9f\u884c\u3055\u308c\u307e\u305b\u3093\u3002 +HashDbIngestModule.noKnownBadHashDbSetMsg=\u65e2\u77e5\u306e\u60aa\u8cea\u306a\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30bb\u30c3\u30c8\u306f\u3042\u308a\u307e\u305b\u3093\u3002 HashDbConfigPanel.dbNotIndexedMsg=\u6b21\u306e\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306f\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u5316\u3055\u308c\u3066\u3044\u307e\u305b\u3093\u3002\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u5316\u3057\u307e\u3059\u304b\uff1f\n{0} +HashDbIngestModule.knownBadFileSearchWillNotExecuteWarn=\u65e2\u77e5\u306e\u60aa\u8cea\u30d5\u30a1\u30a4\u30eb\u691c\u7d22\u306f\u5b9f\u884c\u3055\u308c\u307e\u305b\u3093\u3002 +HashDbIngestModule.fileReadErrorMsg=\u8aad\u307f\u8fbc\u307f\u30a8\u30e9\u30fc\uff1a {0} +HashDbIngestModule.calcHashValueErr={0}\u306e\u30cf\u30c3\u30b7\u30e5\u5024\u3092\u8a08\u7b97\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002 +HashDbIngestModule.hashLookupErrorMsg=\u30cf\u30c3\u30b7\u30e5\u30eb\u30c3\u30af\u30a2\u30c3\u30d7\u30a8\u30e9\u30fc\uff1a {0} +HashDbIngestModule.lookingUpKnownBadHashValueErr={0}\u306e\u65e2\u77e5\u306e\u60aa\u8cea\u30cf\u30c3\u30b7\u30e5\u5024\u3092\u30eb\u30c3\u30af\u30a2\u30c3\u30d7\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002 +HashDbIngestModule.lookingUpKnownHashValueErr={0}\u306e\u65e2\u77e5\u306e\u30cf\u30c3\u30b7\u30e5\u5024\u3092\u30eb\u30c3\u30af\u30a2\u30c3\u30d7\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002 +HashDbIngestModule.postToBB.fileName=\u30d5\u30a1\u30a4\u30eb\u540d +HashDbIngestModule.postToBB.md5Hash=MD5\u30cf\u30c3\u30b7\u30e5 +HashDbIngestModule.postToBB.hashsetName=\u30cf\u30c3\u30b7\u30e5\u30bb\u30c3\u30c8\u540d +HashDbIngestModule.postToBB.knownBadMsg=\u65e2\u77e5\u306e\u60aa\u8cea\: {0} +HashDbIngestModule.complete.knownBadsFound=\u767a\u898b\u3055\u308c\u305f\u65e2\u77e5\u306e\u60aa\u8cea\uff1a +HashDbIngestModule.complete.totalCalcTime=\u8a08\u7b97\u6642\u9593\u306e\u5408\u8a08 +HashDbIngestModule.complete.totalLookupTime=\u30eb\u30c3\u30af\u30a2\u30c3\u30d7\u6642\u9593\u306e\u5408\u8a08 +HashDbIngestModule.complete.databasesUsed=\u5229\u7528\u3057\u305f\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\uff1a +HashDbIngestModule.complete.hashLookupResults=\u30cf\u30c3\u30b7\u30e5\u30eb\u30c3\u30af\u30a2\u30c3\u30d7\u7d50\u679c HashDbManager.moduleErrorListeningToUpdatesMsg=HashDbManager\u30a2\u30c3\u30d7\u30c7\u30fc\u30c8\u3092\u78ba\u8a8d\u4e2d\u306b\u30e2\u30b8\u30e5\u30fc\u30eb\u304c\u30a8\u30e9\u30fc\u3092\u8d77\u3053\u3057\u307e\u3057\u305f\u3002\u3069\u306e\u30e2\u30b8\u30e5\u30fc\u30eb\u304c\u539f\u56e0\u306a\u306e\u304b\u3092\u30ed\u30b0\u3092\u78ba\u8a8d\u3057\u3066\u4e0b\u3055\u3044\u3002\u4e00\u90e8\u306e\u30c7\u30fc\u30bf\u304c\u5b8c\u5168\u3067\u306a\u3044\u3053\u3068\u304c\u3042\u308a\u307e\u3059\u3002 HashDbManager.replacingDuplicateHashsetNameMsg=\u91cd\u8907\u306e\u30cf\u30c3\u30b7\u30e5\u30bb\u30c3\u30c8\u540d {0} \u304c\u898b\u3064\u304b\u308a\u307e\u3057\u305f\u3002\n {1}\u306b\u66f8\u304d\u63db\u3048\u307e\u3059\u3002 HashDbManager.openHashDbErr=\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3092\u958b\u304f\u30a8\u30e9\u30fc @@ -142,6 +162,8 @@ HashLookupSettingsPanel.jLabel2.text=\u540d\u524d\uff1a HashLookupModuleSettingsPanel.alwaysCalcHashesCheckbox.text=\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u304c\u9078\u629e\u3055\u308c\u3066\u3044\u306a\u304f\u3066\u3082\u3001MD5\u3092\u8a08\u7b97 HashLookupModuleSettingsPanel.knownHashDbsLabel.text=\u5229\u7528\u3059\u308b\u65e2\u77e5\u306e\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3092\u9078\u629e\uff1a HashLookupModuleSettingsPanel.knownBadHashDbsLabel.text=\u51e6\u7406\u306b\u5229\u7528\u3059\u308b\u65e2\u77e5\u306e\u60aa\u8cea\u306a\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3092\u9078\u629e\uff1a +HashLookupModuleFactory.createFileIngestModule.exception.msg=\u8a2d\u5b9a\u3092\u884c\u3046\u70ba\u306e\u60f3\u5b9a\u3055\u308c\u308b\u5f15\u6570\u306finstanceof HashLookupModuleSettings\u3067\u3059\u3002 +HashLookupModuleFactory.getIngestJobSettingsPanel.exception.msg=\u8a2d\u5b9a\u3092\u884c\u3046\u70ba\u306e\u60f3\u5b9a\u3055\u308c\u308b\u5f15\u6570\u306finstanceof HashLookupModuleSettings\u3067\u3059\u3002 HashLookupModuleSettingsPanel.alwaysCalcHashesCheckbox.toolTipText=\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u304c\u9078\u629e\u3055\u308c\u3066\u3044\u306a\u304f\u3066\u3082\u3001MD5\u3092\u8a08\u7b97 HashDbSearchPanel.hashTable.defaultModel.title.text=MD5\u30cf\u30c3\u30b7\u30e5 AddContentToHashDbAction.addFilesToHashSet.unableToAddFileEmptyMsg=\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306b{0}\u3092\u8ffd\u52a0\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f\u3002\u30d5\u30a1\u30a4\u30eb\u306b\u30b3\u30f3\u30c6\u30f3\u30c4\u304c\u3042\u308a\u307e\u305b\u3093\u3002 diff --git a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbIngestModule.java b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbIngestModule.java index e018a612e1..3067acff4a 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbIngestModule.java +++ b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbIngestModule.java @@ -24,7 +24,6 @@ import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.List; -import java.util.Map; import java.util.concurrent.atomic.AtomicLong; import java.util.logging.Level; import org.openide.util.NbBundle.Messages; @@ -275,10 +274,11 @@ public class HashDbIngestModule implements FileIngestModule { List attributesList = new ArrayList<>(); attributesList.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_SET_NAME, HashLookupModuleFactory.getModuleName(), hashSetName)); try { - if (!org.sleuthkit.datamodel.Blackboard.artifactExists(file, BlackboardArtifact.ARTIFACT_TYPE.TSK_HASHSET_HIT, attributesList)) { + org.sleuthkit.datamodel.Blackboard tskBlackboard = Case.getCurrentCaseThrows().getSleuthkitCase().getBlackboard(); + if (tskBlackboard.artifactExists(file, BlackboardArtifact.ARTIFACT_TYPE.TSK_HASHSET_HIT, attributesList) == false) { postHashSetHitToBlackboard(file, md5Hash, hashSetName, comment, db.getSendIngestMessages()); } - } catch (TskCoreException ex) { + } catch (NoCurrentCaseException | TskCoreException ex) { logger.log(Level.SEVERE, String.format( "A problem occurred while checking for existing artifacts for file '%s' (id=%d).", name, fileId), ex); //NON-NLS services.postMessage(IngestMessage.createErrorMessage( diff --git a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashLookupModuleFactory.java b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashLookupModuleFactory.java index a327a659af..51995505c5 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashLookupModuleFactory.java +++ b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashLookupModuleFactory.java @@ -78,7 +78,8 @@ public class HashLookupModuleFactory extends IngestModuleFactoryAdapter { @Override public IngestModuleIngestJobSettingsPanel getIngestJobSettingsPanel(IngestModuleIngestJobSettings settings) { if (!(settings instanceof HashLookupModuleSettings)) { - throw new IllegalArgumentException("Expected settings argument to be an instance of HashLookupModuleSettings."); + throw new IllegalArgumentException(NbBundle.getMessage(this.getClass(), + "HashLookupModuleFactory.getIngestJobSettingsPanel.exception.msg")); } if (moduleSettingsPanel == null) { moduleSettingsPanel = new HashLookupModuleSettingsPanel((HashLookupModuleSettings) settings); @@ -108,7 +109,8 @@ public class HashLookupModuleFactory extends IngestModuleFactoryAdapter { @Override public FileIngestModule createFileIngestModule(IngestModuleIngestJobSettings settings) { if (!(settings instanceof HashLookupModuleSettings)) { - throw new IllegalArgumentException("Expected settings argument to be an instance of HashLookupModuleSettings."); + throw new IllegalArgumentException(NbBundle.getMessage(this.getClass(), + "HashLookupModuleFactory.getIngestJobSettingsPanel.exception.msg")); } return new HashDbIngestModule((HashLookupModuleSettings) settings); } From 94f0dfbee17cb102327ab8c526ce157a853f9394 Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Thu, 26 Jul 2018 17:16:11 -0600 Subject: [PATCH 208/287] cleared up bugs illuminated by removing the file cache for the inter case leaf notes --- .../AbstractCommonAttributeInstance.java | 20 +----- .../AbstractCommonAttributeSearcher.java | 9 ++- .../AllInterCaseCommonAttributeSearcher.java | 4 +- .../CentralRepoCommonAttributeInstance.java | 70 ++++++++++++------- .../CommonAttributePanel.java | 4 +- .../InterCaseCommonAttributeSearcher.java | 8 +-- .../IntraCaseCommonAttributeSearcher.java | 6 +- ...ingleInterCaseCommonAttributeSearcher.java | 4 +- 8 files changed, 65 insertions(+), 60 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeInstance.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeInstance.java index d6ef8dfb03..abb7a1e683 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeInstance.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeInstance.java @@ -153,26 +153,8 @@ public abstract class AbstractCommonAttributeInstance { if (abstractFile == null) { leafNode = new CentralRepoCommonAttributeInstanceNode(attributeInstance); } else { - final String attributeDataSourceName = attributeInstance.getCorrelationDataSource().getName(); final String abstractFileDataSourceName = abstractFile.getDataSource().getName(); - - final String attributeInstanceCaseName = attributeInstance.getCorrelationCase().getDisplayName(); - - final String attributeInstanceFullPath = attributeInstance.getFilePath().replace("\\", "/"); - - final String currentAbstractFileParentPath = abstractFile.getParentPath(); - final String currentAbstractFileName = abstractFile.getName(); - final String abstractFileFullPath = (currentAbstractFileParentPath + currentAbstractFileName).replace("\\", "/"); - - final boolean sameCase = attributeInstanceCaseName.equalsIgnoreCase(currentCaseName); - final boolean sameFileName = attributeInstanceFullPath.equalsIgnoreCase(abstractFileFullPath); - final boolean sameDataSource = attributeDataSourceName.equalsIgnoreCase(abstractFileDataSourceName); - - if (sameCase && sameFileName && sameDataSource) { - leafNode = new CaseDBCommonAttributeInstanceNode(abstractFile, currentCaseName, abstractFileDataSourceName); - } else { - leafNode = new CentralRepoCommonAttributeInstanceNode(attributeInstance); - } + leafNode = new CaseDBCommonAttributeInstanceNode(abstractFile, currentCaseName, abstractFileDataSourceName); } return leafNode; diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeSearcher.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeSearcher.java index fb8cbd312d..97456bda04 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeSearcher.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeSearcher.java @@ -21,6 +21,7 @@ package org.sleuthkit.autopsy.commonfilesearch; import java.sql.SQLException; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Set; @@ -38,12 +39,18 @@ import org.sleuthkit.datamodel.TskCoreException; */ public abstract class AbstractCommonAttributeSearcher { + private final Map dataSourceIdToNameMap; private boolean filterByMedia; private boolean filterByDoc; - AbstractCommonAttributeSearcher(boolean filterByMedia, boolean filterByDoc){ + AbstractCommonAttributeSearcher(Map dataSourceIdMap, boolean filterByMedia, boolean filterByDoc){ this.filterByDoc = filterByDoc; this.filterByMedia = filterByMedia; + this.dataSourceIdToNameMap = dataSourceIdMap; + } + + Map getDataSourceIdToNameMap(){ + return Collections.unmodifiableMap(this.dataSourceIdToNameMap); } /** diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllInterCaseCommonAttributeSearcher.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllInterCaseCommonAttributeSearcher.java index d86a4b9878..7e039a9419 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllInterCaseCommonAttributeSearcher.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllInterCaseCommonAttributeSearcher.java @@ -41,8 +41,8 @@ public class AllInterCaseCommonAttributeSearcher extends InterCaseCommonAttribut * broadly categorized as document types * @throws EamDbException */ - public AllInterCaseCommonAttributeSearcher(boolean filterByMediaMimeType, boolean filterByDocMimeType) throws EamDbException { - super(filterByMediaMimeType, filterByDocMimeType); + public AllInterCaseCommonAttributeSearcher(Map dataSourceIdMap, boolean filterByMediaMimeType, boolean filterByDocMimeType) throws EamDbException { + super(dataSourceIdMap, filterByMediaMimeType, filterByDocMimeType); } @Override diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepoCommonAttributeInstance.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepoCommonAttributeInstance.java index 2e0d623fa4..68e795d37b 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepoCommonAttributeInstance.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepoCommonAttributeInstance.java @@ -21,11 +21,14 @@ package org.sleuthkit.autopsy.commonfilesearch; import java.io.File; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.logging.Level; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttribute; +import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.datamodel.DisplayableItemNode; import org.sleuthkit.datamodel.AbstractFile; @@ -42,10 +45,12 @@ final public class CentralRepoCommonAttributeInstance extends AbstractCommonAttr private static final Logger LOGGER = Logger.getLogger(CentralRepoCommonAttributeInstance.class.getName()); private final Integer crFileId; private CorrelationAttribute currentAttribute; + private Map dataSourceNameToIdMap; - CentralRepoCommonAttributeInstance(Integer attrInstId) { + CentralRepoCommonAttributeInstance(Integer attrInstId, Map dataSourceIdToNameMap) { super(); this.crFileId = attrInstId; + this.dataSourceNameToIdMap = invertMap(dataSourceIdToNameMap); } void setCurrentAttributeInst(CorrelationAttribute attribute) { @@ -57,39 +62,44 @@ final public class CentralRepoCommonAttributeInstance extends AbstractCommonAttr Case currentCase; if (this.currentAttribute != null) { - String currentFullPath = this.currentAttribute.getInstances().get(0).getFilePath(); - try { - currentCase = Case.getCurrentCaseThrows(); + + final CorrelationAttributeInstance currentAttributeInstance = this.currentAttribute.getInstances().get(0); + + String currentFullPath = currentAttributeInstance.getFilePath(); + String currentDataSource = currentAttributeInstance.getCorrelationDataSource().getName(); + + + if(this.dataSourceNameToIdMap.containsKey(currentDataSource)){ + Long dataSourceObjectId = this.dataSourceNameToIdMap.get(currentDataSource); + + try { + currentCase = Case.getCurrentCaseThrows(); - SleuthkitCase tskDb = currentCase.getSleuthkitCase(); + SleuthkitCase tskDb = currentCase.getSleuthkitCase(); + + File fileFromPath = new File(currentFullPath); + String fileName = fileFromPath.getName(); + String parentPath = (fileFromPath.getParent() + File.separator).replace("\\", "/"); + + final String whereClause = String.format("lower(name) = '%s' AND md5 = '%s' AND lower(parent_path) = '%s' AND data_source_obj_id = %s", fileName, currentAttribute.getCorrelationValue(), parentPath, dataSourceObjectId); + List potentialAbstractFiles = tskDb.findAllFilesWhere(whereClause); - File fileFromPath = new File(currentFullPath); - String fileName = fileFromPath.getName(); - String parentPath = fileFromPath.getParent() + File.separator; - List potentialAbstractFiles = tskDb.findAllFilesWhere(String.format("lower(name) = '%s' AND md5 = '%s'", fileName, currentAttribute.getCorrelationValue())); - AbstractFile finalAbstractFile = null; - for (AbstractFile aFile : potentialAbstractFiles) { - // If a direct match exists, return that and we'll create a CaseDb instance node from it - if (aFile.getParentPath().equalsIgnoreCase(parentPath)) { - finalAbstractFile = aFile; - break; - } - } - // If not direct match exists, return first md5 match, only used as a backing file for CR instance node. - if (finalAbstractFile == null) { if(potentialAbstractFiles.isEmpty()){ return null; + } else if(potentialAbstractFiles.size() > 1){ + LOGGER.log(Level.WARNING, String.format("Unable to find an exact match for AbstractFile for record with filePath: %s. May have returned the wrong file.", new Object[]{currentFullPath})); + return potentialAbstractFiles.get(0); } else { - finalAbstractFile = potentialAbstractFiles.get(0); + return potentialAbstractFiles.get(0); } + + } catch (TskCoreException | NoCurrentCaseException ex) { + LOGGER.log(Level.SEVERE, String.format("Unable to find AbstractFile for record with filePath: %s. Node not created.", new Object[]{currentFullPath}), ex); + return null; } - - return finalAbstractFile; - - } catch (TskCoreException | NoCurrentCaseException ex) { - LOGGER.log(Level.SEVERE, String.format("Unable to find AbstractFile for record with filePath: %s. Node not created.", new Object[]{currentFullPath}), ex); + } else { return null; - } + } } return null; } @@ -116,4 +126,12 @@ final public class CentralRepoCommonAttributeInstance extends AbstractCommonAttr return attrInstNodeList.toArray(new DisplayableItemNode[attrInstNodeList.size()]); } + + private Map invertMap(Map dataSourceIdToNameMap) { + HashMap invertedMap = new HashMap<>(); + for (Map.Entry entry : dataSourceIdToNameMap.entrySet()){ + invertedMap.put(entry.getValue(), entry.getKey()); + } + return invertedMap; + } } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributePanel.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributePanel.java index c83876f3ce..1b33bb9422 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributePanel.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributePanel.java @@ -157,9 +157,9 @@ public final class CommonAttributePanel extends javax.swing.JDialog { if (CommonAttributePanel.this.interCaseRadio.isSelected()) { if (caseId == InterCasePanel.NO_CASE_SELECTED) { - builder = new AllInterCaseCommonAttributeSearcher(filterByMedia, filterByDocuments); + builder = new AllInterCaseCommonAttributeSearcher(intraCasePanel.getDataSourceMap(), filterByMedia, filterByDocuments); } else { - builder = new SingleInterCaseCommonAttributeSearcher(caseId, filterByMedia, filterByDocuments); + builder = new SingleInterCaseCommonAttributeSearcher(caseId, intraCasePanel.getDataSourceMap(), filterByMedia, filterByDocuments); } } else { if (dataSourceId == CommonAttributePanel.NO_DATA_SOURCE_SELECTED) { diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearcher.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearcher.java index 938a33fee8..fcdb4a319c 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearcher.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearcher.java @@ -46,8 +46,8 @@ abstract class InterCaseCommonAttributeSearcher extends AbstractCommonAttributeS * * @throws EamDbException */ - InterCaseCommonAttributeSearcher(boolean filterByMediaMimeType, boolean filterByDocMimeType) throws EamDbException { - super(filterByMediaMimeType, filterByDocMimeType); + InterCaseCommonAttributeSearcher(Map dataSourceIdMap, boolean filterByMediaMimeType, boolean filterByDocMimeType) throws EamDbException { + super(dataSourceIdMap, filterByMediaMimeType, filterByDocMimeType); dbManager = EamDb.getInstance(); } @@ -77,14 +77,14 @@ abstract class InterCaseCommonAttributeSearcher extends AbstractCommonAttributeS //Add to intercase metaData final CommonAttributeValue commonAttributeValue = interCaseCommonFiles.get(md5); - AbstractCommonAttributeInstance searchResult = new CentralRepoCommonAttributeInstance(commonAttrId); + AbstractCommonAttributeInstance searchResult = new CentralRepoCommonAttributeInstance(commonAttrId, this.getDataSourceIdToNameMap()); commonAttributeValue.addInstance(searchResult); } else { CommonAttributeValue commonAttributeValue = new CommonAttributeValue(md5); interCaseCommonFiles.put(md5, commonAttributeValue); - AbstractCommonAttributeInstance searchResult = new CentralRepoCommonAttributeInstance(commonAttrId); + AbstractCommonAttributeInstance searchResult = new CentralRepoCommonAttributeInstance(commonAttrId, this.getDataSourceIdToNameMap()); commonAttributeValue.addInstance(searchResult); } } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCaseCommonAttributeSearcher.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCaseCommonAttributeSearcher.java index 143f061ed2..0967041b30 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCaseCommonAttributeSearcher.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCaseCommonAttributeSearcher.java @@ -44,7 +44,6 @@ import org.sleuthkit.datamodel.TskCoreException; @SuppressWarnings("PMD.AbstractNaming") public abstract class IntraCaseCommonAttributeSearcher extends AbstractCommonAttributeSearcher { - private final Map dataSourceIdToNameMap; private static final String FILTER_BY_MIME_TYPES_WHERE_CLAUSE = " and mime_type in (%s)"; //NON-NLS // where %s is csv list of mime_types to filter on /** @@ -57,8 +56,7 @@ public abstract class IntraCaseCommonAttributeSearcher extends AbstractCommonAtt * broadly categorized as document types */ IntraCaseCommonAttributeSearcher(Map dataSourceIdMap, boolean filterByMediaMimeType, boolean filterByDocMimeType) { - super(filterByMediaMimeType, filterByDocMimeType); - dataSourceIdToNameMap = dataSourceIdMap; + super(dataSourceIdMap, filterByMediaMimeType, filterByDocMimeType); } /** @@ -113,7 +111,7 @@ public abstract class IntraCaseCommonAttributeSearcher extends AbstractCommonAtt Long objectId = resultSet.getLong(1); String md5 = resultSet.getString(2); Long dataSourceId = resultSet.getLong(3); - String dataSource = this.dataSourceIdToNameMap.get(dataSourceId); + String dataSource = this.getDataSourceIdToNameMap().get(dataSourceId); if (md5 == null || HashUtility.isNoDataMd5(md5)) { continue; diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/SingleInterCaseCommonAttributeSearcher.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/SingleInterCaseCommonAttributeSearcher.java index 9486a9e43c..66a7106c63 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/SingleInterCaseCommonAttributeSearcher.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/SingleInterCaseCommonAttributeSearcher.java @@ -44,8 +44,8 @@ public class SingleInterCaseCommonAttributeSearcher extends InterCaseCommonAttri * @param filterByDocMimeType * @throws EamDbException */ - public SingleInterCaseCommonAttributeSearcher(int correlationCaseId, boolean filterByMediaMimeType, boolean filterByDocMimeType) throws EamDbException { - super(filterByMediaMimeType, filterByDocMimeType); + public SingleInterCaseCommonAttributeSearcher(int correlationCaseId, Map dataSourceIdMap, boolean filterByMediaMimeType, boolean filterByDocMimeType) throws EamDbException { + super(dataSourceIdMap,filterByMediaMimeType, filterByDocMimeType); this.corrleationCaseId = correlationCaseId; this.correlationCaseName = ""; From 441230d3e969af2d684feb42db28480227cd8e72 Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Thu, 26 Jul 2018 17:19:23 -0600 Subject: [PATCH 209/287] and the tests are fixed --- .../IngestedWithHashAndFileTypeInterCaseTests.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileTypeInterCaseTests.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileTypeInterCaseTests.java index 006989fe60..d758e8c935 100644 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileTypeInterCaseTests.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IngestedWithHashAndFileTypeInterCaseTests.java @@ -19,12 +19,12 @@ */ package org.sleuthkit.autopsy.commonfilessearch; +import java.util.Map; import junit.framework.Test; import org.netbeans.junit.NbModuleSuite; import org.netbeans.junit.NbTestCase; import org.openide.util.Exceptions; import org.python.icu.impl.Assert; -import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.commonfilesearch.AbstractCommonAttributeSearcher; import org.sleuthkit.autopsy.commonfilesearch.AllInterCaseCommonAttributeSearcher; import org.sleuthkit.autopsy.commonfilesearch.CommonAttributeSearchResults; @@ -79,8 +79,10 @@ public class IngestedWithHashAndFileTypeInterCaseTests extends NbTestCase { */ public void testOne() { try { + Map dataSources = this.utils.getDataSourceMap(); + //note that the params false and false are presently meaningless because that feature is not supported yet - AbstractCommonAttributeSearcher builder = new AllInterCaseCommonAttributeSearcher(false, false); + AbstractCommonAttributeSearcher builder = new AllInterCaseCommonAttributeSearcher(dataSources, false, false); CommonAttributeSearchResults metadata = builder.findFiles(); @@ -129,10 +131,11 @@ public class IngestedWithHashAndFileTypeInterCaseTests extends NbTestCase { */ public void testTwo() { try { + Map dataSources = this.utils.getDataSourceMap(); int matchesMustAlsoBeFoundInThisCase = this.utils.getCaseMap().get(CASE2); - AbstractCommonAttributeSearcher builder = new SingleInterCaseCommonAttributeSearcher(matchesMustAlsoBeFoundInThisCase, false, false); + AbstractCommonAttributeSearcher builder = new SingleInterCaseCommonAttributeSearcher(matchesMustAlsoBeFoundInThisCase, dataSources, false, false); CommonAttributeSearchResults metadata = builder.findFiles(); From b570830d1bac850038b4c92857af7e524ffb151f Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Thu, 26 Jul 2018 17:32:54 -0600 Subject: [PATCH 210/287] need to check for existance of eamdb before trying getinstance --- .../autopsy/commonfilessearch/InterCaseTestUtils.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/InterCaseTestUtils.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/InterCaseTestUtils.java index 610d31f152..cf6bd36fbc 100644 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/InterCaseTestUtils.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/InterCaseTestUtils.java @@ -176,7 +176,9 @@ class InterCaseTestUtils { void clearTestDir(){ if(CASE_DIRECTORY_PATH.toFile().exists()){ try{ - EamDb.getInstance().shutdownConnections(); + if(EamDb.isEnabled()) { + EamDb.getInstance().shutdownConnections(); + } FileUtils.deleteDirectory(CASE_DIRECTORY_PATH.toFile()); } catch(IOException | EamDbException ex){ Exceptions.printStackTrace(ex); From 5f43a4fe52d76c0aa16d2c4f64bce2d9d040d0b1 Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dgrove" Date: Thu, 26 Jul 2018 22:22:02 -0400 Subject: [PATCH 211/287] Reverted comments back to 'Bundle.properties'. --- .../modules/hashdatabase/Bundle.properties | 17 +++++ .../hashdatabase/HashDbIngestModule.java | 69 +++++++------------ .../hashdatabase/HashLookupModuleFactory.java | 8 +-- 3 files changed, 43 insertions(+), 51 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/Bundle.properties b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/Bundle.properties index c18245d7c7..a3f75b9048 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/Bundle.properties @@ -87,6 +87,23 @@ HashDbImportDatabaseDialog.importHashDbErr=Import Hash Set Error HashDbImportDatabaseDialog.mustSelectHashDbFilePathMsg=A hash set file path must be selected. HashDbImportDatabaseDialog.hashDbDoesNotExistMsg=The selected hash set does not exist. HashDbImportDatabaseDialog.errorMessage.failedToOpenHashDbMsg=Failed to open hash set at {0}. +HashLookupModuleFactory.moduleName.text=Hash Lookup +HashLookupModuleFactory.moduleDescription.text=Identifies known and notable files using supplied hash sets, such as a standard NSRL hash set. +HashDbIngestModule.fileReadErrorMsg=Read Error\: {0} +HashDbIngestModule.calcHashValueErr=Error encountered while calculating the hash value for {0}. +HashDbIngestModule.hashLookupErrorMsg=Hash Lookup Error\: {0} +HashDbIngestModule.settingKnownBadStateErr=Error encountered while setting notable state for {0}. +HashDbIngestModule.lookingUpKnownBadHashValueErr=Error encountered while looking up notable hash value for {0}. +HashDbIngestModule.lookingUpKnownHashValueErr=Error encountered while looking up known hash value for {0}. +HashDbIngestModule.postToBB.fileName=File Name +HashDbIngestModule.postToBB.md5Hash=MD5 Hash +HashDbIngestModule.postToBB.hashsetName=Hash Set Name +HashDbIngestModule.postToBB.knownBadMsg=Notable\: {0} +HashDbIngestModule.complete.knownBadsFound=Notables found\: +HashDbIngestModule.complete.totalCalcTime=Total Calculation Time +HashDbIngestModule.complete.totalLookupTime=Total Lookup Time +HashDbIngestModule.complete.databasesUsed=Hash Sets Used\: +HashDbIngestModule.complete.hashLookupResults=Hash Lookup Results HashDbManager.moduleErrorListeningToUpdatesMsg=A module caused an error listening to HashDbManager updates. See log to determine which module. Some data could be incomplete. HashDbManager.replacingDuplicateHashsetNameMsg=Duplicate hash set name {0} found.\nReplacing with {1}. HashDbManager.openHashDbErr=Open Hash Set Error diff --git a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbIngestModule.java b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbIngestModule.java index 3067acff4a..46165e34fa 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbIngestModule.java +++ b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbIngestModule.java @@ -26,6 +26,7 @@ import java.util.HashMap; import java.util.List; import java.util.concurrent.atomic.AtomicLong; import java.util.logging.Level; +import org.openide.util.NbBundle; import org.openide.util.NbBundle.Messages; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; @@ -54,6 +55,12 @@ import org.sleuthkit.datamodel.TskException; /** * File ingest module to mark files based on hash values. */ +@Messages({ + "HashDbIngestModule.noKnownBadHashDbSetMsg=No notable hash set.", + "HashDbIngestModule.knownBadFileSearchWillNotExecuteWarn=Notable file search will not be executed.", + "HashDbIngestModule.noKnownHashDbSetMsg=No known hash set.", + "HashDbIngestModule.knownFileSearchWillNotExecuteWarn=Known file search will not be executed." +}) public class HashDbIngestModule implements FileIngestModule { private static final Logger logger = Logger.getLogger(HashDbIngestModule.class.getName()); @@ -98,12 +105,6 @@ public class HashDbIngestModule implements FileIngestModule { this.settings = settings; } - @Messages({ - "HashDbIngestModule.noKnownBadHashDbSetMsg=No notable hash set.", - "HashDbIngestModule.knownBadFileSearchWillNotExecuteWarn=Notable file search will not be executed.", - "HashDbIngestModule.noKnownHashDbSetMsg=No known hash set.", - "HashDbIngestModule.knownFileSearchWillNotExecuteWarn=Known file search will not be executed." - }) @Override public void startUp(org.sleuthkit.autopsy.ingest.IngestJobContext context) throws IngestModuleException { jobId = context.getJobId(); @@ -121,7 +122,7 @@ public class HashDbIngestModule implements FileIngestModule { if (knownBadHashSets.isEmpty()) { services.postMessage(IngestMessage.createWarningMessage( HashLookupModuleFactory.getModuleName(), - Bundle.HashDbIngestModule_noKnownBadHashDbSetMsg(), + NbBundle.getMessage(this.getClass(), "HashDbIngestModule.noKnownBadHashDbSetMsg"), Bundle.HashDbIngestModule_knownBadFileSearchWillNotExecuteWarn())); } @@ -156,16 +157,6 @@ public class HashDbIngestModule implements FileIngestModule { } @Messages({ - "# {0} - File name", - "HashDbIngestModule.fileReadErrorMsg=Read Error: {0}", - "# {0} - File name", - "HashDbIngestModule.calcHashValueErr=Error encountered while calculating the hash value for {0}.", - "# {0} - File name", - "HashDbIngestModule.hashLookupErrorMsg=Hash Lookup Error: {0}", - "# {0} - File name", - "HashDbIngestModule.lookingUpKnownBadHashValueErr=Error encountered while looking up notable hash value for {0}.", - "# {0} - File name", - "HashDbIngestModule.lookingUpKnownHashValueErr=Error encountered while looking up known hash value for {0}.", "# {0} - File name", "HashDbIngestModule.dialogTitle.errorFindingArtifacts=Error Finding Artifacts: {0}", "# {0} - File name", @@ -232,8 +223,8 @@ public class HashDbIngestModule implements FileIngestModule { logger.log(Level.WARNING, String.format("Error calculating hash of file '%s' (id=%d).", name, fileId), ex); //NON-NLS services.postMessage(IngestMessage.createErrorMessage( HashLookupModuleFactory.getModuleName(), - Bundle.HashDbIngestModule_fileReadErrorMsg(name), - Bundle.HashDbIngestModule_calcHashValueErr(name))); + NbBundle.getMessage(this.getClass(), "HashDbIngestModule.fileReadErrorMsg", name), + NbBundle.getMessage(this.getClass(), "HashDbIngestModule.calcHashValueErr", name))); return ProcessResult.ERROR; } } @@ -296,8 +287,8 @@ public class HashDbIngestModule implements FileIngestModule { "Couldn't lookup notable hash for file '%s' (id=%d) - see sleuthkit log for details", name, fileId), ex); //NON-NLS services.postMessage(IngestMessage.createErrorMessage( HashLookupModuleFactory.getModuleName(), - Bundle.HashDbIngestModule_hashLookupErrorMsg(name), - Bundle.HashDbIngestModule_lookingUpKnownBadHashValueErr(name))); + NbBundle.getMessage(this.getClass(), "HashDbIngestModule.hashLookupErrorMsg", name), + NbBundle.getMessage(this.getClass(), "HashDbIngestModule.lookingUpKnownBadHashValueErr", name))); ret = ProcessResult.ERROR; } } @@ -321,8 +312,8 @@ public class HashDbIngestModule implements FileIngestModule { "Couldn't lookup known hash for file '%s' (id=%d) - see sleuthkit log for details", name, fileId), ex); //NON-NLS services.postMessage(IngestMessage.createErrorMessage( HashLookupModuleFactory.getModuleName(), - Bundle.HashDbIngestModule_hashLookupErrorMsg(name), - Bundle.HashDbIngestModule_lookingUpKnownHashValueErr(name))); + NbBundle.getMessage(this.getClass(), "HashDbIngestModule.hashLookupErrorMsg", name), + NbBundle.getMessage(this.getClass(), "HashDbIngestModule.lookingUpKnownHashValueErr", name))); ret = ProcessResult.ERROR; } } @@ -342,12 +333,7 @@ public class HashDbIngestModule implements FileIngestModule { * @param showInboxMessage Show a message in the inbox? */ @Messages({ - "HashDbIngestModule.indexError.message=Failed to index hashset hit artifact for keyword search.", - "HashDbIngestModule.postToBB.fileName=File Name", - "HashDbIngestModule.postToBB.md5Hash=MD5 Hash", - "HashDbIngestModule.postToBB.hashsetName=Hash Set Name", - "# {0} - File name", - "HashDbIngestModule.postToBB.knownBadMsg=Notable: {0}" + "HashDbIngestModule.indexError.message=Failed to index hashset hit artifact for keyword search." }) private void postHashSetHitToBlackboard(AbstractFile abstractFile, String md5Hash, String hashSetName, String comment, boolean showInboxMessage) { try { @@ -378,7 +364,7 @@ public class HashDbIngestModule implements FileIngestModule { //hit detailsSb.append(""); //NON-NLS detailsSb.append("") //NON-NLS - .append(Bundle.HashDbIngestModule_postToBB_fileName()) + .append(NbBundle.getMessage(this.getClass(), "HashDbIngestModule.postToBB.fileName")) .append(""); //NON-NLS detailsSb.append("") //NON-NLS .append(abstractFile.getName()) @@ -387,14 +373,14 @@ public class HashDbIngestModule implements FileIngestModule { detailsSb.append(""); //NON-NLS detailsSb.append("") //NON-NLS - .append(Bundle.HashDbIngestModule_postToBB_md5Hash()) + .append(NbBundle.getMessage(this.getClass(), "HashDbIngestModule.postToBB.md5Hash")) .append(""); //NON-NLS detailsSb.append("").append(md5Hash).append(""); //NON-NLS detailsSb.append(""); //NON-NLS detailsSb.append(""); //NON-NLS detailsSb.append("") //NON-NLS - .append(Bundle.HashDbIngestModule_postToBB_hashsetName()) + .append(NbBundle.getMessage(this.getClass(), "HashDbIngestModule.postToBB.hashsetName")) .append(""); //NON-NLS detailsSb.append("").append(hashSetName).append(""); //NON-NLS detailsSb.append(""); //NON-NLS @@ -402,7 +388,7 @@ public class HashDbIngestModule implements FileIngestModule { detailsSb.append(""); //NON-NLS services.postMessage(IngestMessage.createDataMessage(HashLookupModuleFactory.getModuleName(), - Bundle.HashDbIngestModule_postToBB_knownBadMsg(abstractFile.getName()), + NbBundle.getMessage(this.getClass(), "HashDbIngestModule.postToBB.knownBadMsg", abstractFile.getName()), detailsSb.toString(), abstractFile.getName() + md5Hash, badFile)); @@ -420,13 +406,6 @@ public class HashDbIngestModule implements FileIngestModule { * @param knownBadHashSets The list of hash sets for "known bad" files. * @param knownHashSets The list of hash sets for "known" files. */ - @Messages({ - "HashDbIngestModule.complete.knownBadsFound=Notables found:", - "HashDbIngestModule.complete.totalCalcTime=Total Calculation Time", - "HashDbIngestModule.complete.totalLookupTime=Total Lookup Time", - "HashDbIngestModule.complete.databasesUsed=Hash Sets Used:", - "HashDbIngestModule.complete.hashLookupResults=Hash Lookup Results" - }) private static synchronized void postSummary(long jobId, List knownBadHashSets, List knownHashSets) { IngestJobTotals jobTotals = getTotalsForIngestJobs(jobId); @@ -438,20 +417,20 @@ public class HashDbIngestModule implements FileIngestModule { detailsSb.append(""); //NON-NLS detailsSb.append(""); //NON-NLS detailsSb.append(""); //NON-NLS detailsSb.append("\n"); //NON-NLS detailsSb.append("\n"); //NON-NLS detailsSb.append("
    ") //NON-NLS - .append(Bundle.HashDbIngestModule_complete_knownBadsFound()) + .append(NbBundle.getMessage(HashDbIngestModule.class, "HashDbIngestModule.complete.knownBadsFound")) .append("").append(jobTotals.totalKnownBadCount.get()).append("
    ") //NON-NLS - .append(Bundle.HashDbIngestModule_complete_totalCalcTime()) + .append(NbBundle.getMessage(HashDbIngestModule.class, "HashDbIngestModule.complete.totalCalcTime")) .append("").append(jobTotals.totalCalctime.get()).append("
    ") //NON-NLS - .append(Bundle.HashDbIngestModule_complete_totalLookupTime()) + .append(NbBundle.getMessage(HashDbIngestModule.class, "HashDbIngestModule.complete.totalLookupTime")) .append("").append(jobTotals.totalLookuptime.get()).append("
    "); //NON-NLS detailsSb.append("

    ") //NON-NLS - .append(Bundle.HashDbIngestModule_complete_databasesUsed()) + .append(NbBundle.getMessage(HashDbIngestModule.class, "HashDbIngestModule.complete.databasesUsed")) .append("

    \n
      "); //NON-NLS for (HashDb db : knownBadHashSets) { detailsSb.append("
    • ").append(db.getHashSetName()).append("
    • \n"); //NON-NLS @@ -462,7 +441,7 @@ public class HashDbIngestModule implements FileIngestModule { IngestServices.getInstance().postMessage(IngestMessage.createMessage( IngestMessage.MessageType.INFO, HashLookupModuleFactory.getModuleName(), - Bundle.HashDbIngestModule_complete_hashLookupResults(), + NbBundle.getMessage(HashDbIngestModule.class, "HashDbIngestModule.complete.hashLookupResults"), detailsSb.toString())); } } diff --git a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashLookupModuleFactory.java b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashLookupModuleFactory.java index 51995505c5..fc9ab24521 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashLookupModuleFactory.java +++ b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashLookupModuleFactory.java @@ -32,10 +32,6 @@ import org.sleuthkit.autopsy.ingest.IngestModuleGlobalSettingsPanel; * A factory that creates file ingest modules that do hash database lookups. */ @ServiceProvider(service = IngestModuleFactory.class) -@NbBundle.Messages({ - "HashLookupModuleFactory.moduleName.text=Hash Lookup", - "HashLookupModuleFactory.moduleDescription.text=Identifies known and notable files using supplied hash sets, such as a standard NSRL hash set." -}) public class HashLookupModuleFactory extends IngestModuleFactoryAdapter { private HashLookupModuleSettingsPanel moduleSettingsPanel = null; @@ -51,12 +47,12 @@ public class HashLookupModuleFactory extends IngestModuleFactoryAdapter { * @return The module name. */ static String getModuleName() { - return Bundle.HashLookupModuleFactory_moduleName_text(); + return NbBundle.getMessage(HashLookupModuleFactory.class, "HashLookupModuleFactory.moduleName.text"); } @Override public String getModuleDescription() { - return Bundle.HashLookupModuleFactory_moduleDescription_text(); + return NbBundle.getMessage(HashLookupModuleFactory.class, "HashLookupModuleFactory.moduleDescription.text"); } @Override From dfd97722f9e1d5d7d90b74c32a3d3401c2fc35b9 Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dgrove" Date: Thu, 26 Jul 2018 23:08:46 -0400 Subject: [PATCH 212/287] Put SleuthkitCase object back in constructor. --- .../modules/hashdatabase/HashDbIngestModule.java | 13 +++++++++---- .../hashdatabase/HashLookupModuleFactory.java | 7 ++++++- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbIngestModule.java b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbIngestModule.java index 46165e34fa..ee3ba1c089 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbIngestModule.java +++ b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbIngestModule.java @@ -48,6 +48,7 @@ import org.sleuthkit.datamodel.BlackboardAttribute; import org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE; import org.sleuthkit.datamodel.HashHitInfo; import org.sleuthkit.datamodel.HashUtility; +import org.sleuthkit.datamodel.SleuthkitCase; import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.datamodel.TskData; import org.sleuthkit.datamodel.TskException; @@ -66,6 +67,7 @@ public class HashDbIngestModule implements FileIngestModule { private static final Logger logger = Logger.getLogger(HashDbIngestModule.class.getName()); private static final int MAX_COMMENT_SIZE = 500; private final IngestServices services = IngestServices.getInstance(); + private final SleuthkitCase skCase; private final HashDbManager hashDbManager = HashDbManager.getInstance(); private final HashLookupModuleSettings settings; private final List knownBadHashSets = new ArrayList<>(); @@ -100,9 +102,12 @@ public class HashDbIngestModule implements FileIngestModule { * object is used to configure the module. * * @param settings The module settings. + * + * @throws NoCurrentCaseException If there is no open case. */ - HashDbIngestModule(HashLookupModuleSettings settings) { + HashDbIngestModule(HashLookupModuleSettings settings) throws NoCurrentCaseException { this.settings = settings; + skCase = Case.getCurrentCaseThrows().getSleuthkitCase(); } @Override @@ -122,7 +127,7 @@ public class HashDbIngestModule implements FileIngestModule { if (knownBadHashSets.isEmpty()) { services.postMessage(IngestMessage.createWarningMessage( HashLookupModuleFactory.getModuleName(), - NbBundle.getMessage(this.getClass(), "HashDbIngestModule.noKnownBadHashDbSetMsg"), + Bundle.HashDbIngestModule_noKnownBadHashDbSetMsg(), Bundle.HashDbIngestModule_knownBadFileSearchWillNotExecuteWarn())); } @@ -265,11 +270,11 @@ public class HashDbIngestModule implements FileIngestModule { List attributesList = new ArrayList<>(); attributesList.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_SET_NAME, HashLookupModuleFactory.getModuleName(), hashSetName)); try { - org.sleuthkit.datamodel.Blackboard tskBlackboard = Case.getCurrentCaseThrows().getSleuthkitCase().getBlackboard(); + org.sleuthkit.datamodel.Blackboard tskBlackboard = skCase.getBlackboard(); if (tskBlackboard.artifactExists(file, BlackboardArtifact.ARTIFACT_TYPE.TSK_HASHSET_HIT, attributesList) == false) { postHashSetHitToBlackboard(file, md5Hash, hashSetName, comment, db.getSendIngestMessages()); } - } catch (NoCurrentCaseException | TskCoreException ex) { + } catch (TskCoreException ex) { logger.log(Level.SEVERE, String.format( "A problem occurred while checking for existing artifacts for file '%s' (id=%d).", name, fileId), ex); //NON-NLS services.postMessage(IngestMessage.createErrorMessage( diff --git a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashLookupModuleFactory.java b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashLookupModuleFactory.java index fc9ab24521..2a20eb8900 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashLookupModuleFactory.java +++ b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashLookupModuleFactory.java @@ -20,6 +20,7 @@ package org.sleuthkit.autopsy.modules.hashdatabase; import org.openide.util.NbBundle; import org.openide.util.lookup.ServiceProvider; +import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; import org.sleuthkit.autopsy.coreutils.Version; import org.sleuthkit.autopsy.ingest.IngestModuleFactoryAdapter; import org.sleuthkit.autopsy.ingest.FileIngestModule; @@ -108,6 +109,10 @@ public class HashLookupModuleFactory extends IngestModuleFactoryAdapter { throw new IllegalArgumentException(NbBundle.getMessage(this.getClass(), "HashLookupModuleFactory.getIngestJobSettingsPanel.exception.msg")); } - return new HashDbIngestModule((HashLookupModuleSettings) settings); + try { + return new HashDbIngestModule((HashLookupModuleSettings) settings); + } catch (NoCurrentCaseException ex) { + throw new IllegalArgumentException("Exception while getting open case.", ex); + } } } From d01f254d6bd58ce27aefa2e978f25405b9918dc6 Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dgrove" Date: Thu, 26 Jul 2018 23:16:30 -0400 Subject: [PATCH 213/287] Typo fixed. --- .../autopsy/modules/hashdatabase/HashLookupModuleFactory.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashLookupModuleFactory.java b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashLookupModuleFactory.java index 2a20eb8900..af27157fd8 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashLookupModuleFactory.java +++ b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashLookupModuleFactory.java @@ -107,7 +107,7 @@ public class HashLookupModuleFactory extends IngestModuleFactoryAdapter { public FileIngestModule createFileIngestModule(IngestModuleIngestJobSettings settings) { if (!(settings instanceof HashLookupModuleSettings)) { throw new IllegalArgumentException(NbBundle.getMessage(this.getClass(), - "HashLookupModuleFactory.getIngestJobSettingsPanel.exception.msg")); + "HashLookupModuleFactory.createFileIngestModule.exception.msg")); } try { return new HashDbIngestModule((HashLookupModuleSettings) settings); From b9dc69ad455ccda0c34ebc47b7122a17971f20d1 Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dsmyda" Date: Fri, 27 Jul 2018 11:55:24 -0400 Subject: [PATCH 214/287] Updated the regex in FileUtil.escapeFileName function to remove ascii control characters --- Core/src/org/sleuthkit/autopsy/coreutils/FileUtil.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/coreutils/FileUtil.java b/Core/src/org/sleuthkit/autopsy/coreutils/FileUtil.java index 4c742acfac..5b432124ba 100644 --- a/Core/src/org/sleuthkit/autopsy/coreutils/FileUtil.java +++ b/Core/src/org/sleuthkit/autopsy/coreutils/FileUtil.java @@ -169,7 +169,7 @@ public class FileUtil { public static String escapeFileName(String fileName) { //for now escaping /:"*?<>| (not valid in file name, at least on Windows) //with underscores. We are only keeping \ as it could be part of the path. - return fileName.replaceAll("[/:\"*?<>|]+", "_"); + return fileName.replaceAll("[\\p{Cntrl}/:\"*?<>|]+", "_"); } /** From cd502079f6f24419335f08dfa039c047e164c6f6 Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Fri, 27 Jul 2018 10:55:09 -0600 Subject: [PATCH 215/287] rename --- .../commonfilesearch/AbstractCommonAttributeInstance.java | 2 +- .../commonfilesearch/CentralRepoCommonAttributeInstance.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeInstance.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeInstance.java index abb7a1e683..61e8aee1f4 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeInstance.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeInstance.java @@ -145,7 +145,7 @@ public abstract class AbstractCommonAttributeInstance { * @return the appropriate leaf node for the results tree * @throws TskCoreException */ - static DisplayableItemNode createInstance(CorrelationAttribute attribute, AbstractFile abstractFile, String currentCaseName) throws TskCoreException { + static DisplayableItemNode createNode(CorrelationAttribute attribute, AbstractFile abstractFile, String currentCaseName) throws TskCoreException { DisplayableItemNode leafNode; CorrelationAttributeInstance attributeInstance = attribute.getInstances().get(0); diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepoCommonAttributeInstance.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepoCommonAttributeInstance.java index 68e795d37b..9babcbb831 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepoCommonAttributeInstance.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepoCommonAttributeInstance.java @@ -117,7 +117,7 @@ final public class CentralRepoCommonAttributeInstance extends AbstractCommonAttr this.setCurrentAttributeInst(corrAttr); AbstractFile abstractFileForAttributeInstance = this.getAbstractFile(); - DisplayableItemNode generatedInstNode = AbstractCommonAttributeInstance.createInstance(corrAttr, abstractFileForAttributeInstance, currCaseDbName); + DisplayableItemNode generatedInstNode = AbstractCommonAttributeInstance.createNode(corrAttr, abstractFileForAttributeInstance, currCaseDbName); attrInstNodeList.add(generatedInstNode); } catch (TskCoreException ex) { From 490d8df3e7fdfd5443a5bf19cceaeb9f3217ab90 Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dgrove" Date: Mon, 30 Jul 2018 10:52:47 -0400 Subject: [PATCH 216/287] Preventing duplicate keyword hits. --- .../autopsy/keywordsearch/LuceneQuery.java | 63 +++++++++++------- .../autopsy/keywordsearch/QueryResults.java | 11 +++- .../autopsy/keywordsearch/RegexQuery.java | 66 +++++++++++-------- 3 files changed, 87 insertions(+), 53 deletions(-) diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/LuceneQuery.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/LuceneQuery.java index e13531da26..fadc2f5107 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/LuceneQuery.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/LuceneQuery.java @@ -32,6 +32,8 @@ import org.apache.solr.client.solrj.response.QueryResponse; import org.apache.solr.common.SolrDocument; import org.apache.solr.common.SolrDocumentList; import org.apache.solr.common.params.CursorMarkParams; +import org.sleuthkit.autopsy.casemodule.Case; +import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; import org.sleuthkit.autopsy.coreutils.EscapeUtil; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.Version; @@ -40,6 +42,7 @@ import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE; import org.sleuthkit.datamodel.BlackboardAttribute; import org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE; import org.sleuthkit.datamodel.Content; +import org.sleuthkit.datamodel.SleuthkitCase; import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.datamodel.TskException; @@ -203,15 +206,44 @@ class LuceneQuery implements KeywordSearchQuery { * @param listName The name of the keyword list that contained the * keyword for which the hit was found. * - * - * @return The newly created artifact or null if there was a problem - * creating it. + * @return The newly created artifact, or null if one wasn't created due to + * either the artifact already existing or an error while trying to + * create it. */ @Override public BlackboardArtifact postKeywordHitToBlackboard(Content content, Keyword foundKeyword, KeywordHit hit, String snippet, String listName) { final String MODULE_NAME = KeywordSearchModuleFactory.getModuleName(); - Collection attributes = new ArrayList<>(); + List attributesList = new ArrayList<>(); + attributesList.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_KEYWORD, MODULE_NAME, foundKeyword.getSearchTerm())); + if (originalKeyword != null) { + BlackboardAttribute.ATTRIBUTE_TYPE selType = originalKeyword.getArtifactAttributeType(); + if (selType != null) { + attributesList.add(new BlackboardAttribute(selType, MODULE_NAME, foundKeyword.getSearchTerm())); + } + + if (originalKeyword.searchTermIsWholeWord()) { + attributesList.add(new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD_SEARCH_TYPE, MODULE_NAME, KeywordSearch.QueryType.LITERAL.ordinal())); + } else { + attributesList.add(new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD_SEARCH_TYPE, MODULE_NAME, KeywordSearch.QueryType.SUBSTRING.ordinal())); + } + } + if (StringUtils.isNotBlank(listName)) { + attributesList.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_SET_NAME, MODULE_NAME, listName)); + } + + try { + SleuthkitCase tskCase = Case.getCurrentCaseThrows().getSleuthkitCase(); + org.sleuthkit.datamodel.Blackboard tskBlackboard = tskCase.getBlackboard(); + if (tskBlackboard.artifactExists(content, BlackboardArtifact.ARTIFACT_TYPE.TSK_KEYWORD_HIT, attributesList)) { + return null; + } + } catch (NoCurrentCaseException | TskCoreException ex) { + logger.log(Level.SEVERE, String.format( + "A problem occurred while checking for existing artifacts for file '%s' (id=%d).", + content.getName(), content.getId()), ex); //NON-NLS + } + BlackboardArtifact bba; try { bba = content.newArtifact(ARTIFACT_TYPE.TSK_KEYWORD_HIT); @@ -221,32 +253,15 @@ class LuceneQuery implements KeywordSearchQuery { } if (snippet != null) { - attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_KEYWORD_PREVIEW, MODULE_NAME, snippet)); - } - attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_KEYWORD, MODULE_NAME, foundKeyword.getSearchTerm())); - if (StringUtils.isNotBlank(listName)) { - attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_SET_NAME, MODULE_NAME, listName)); - } - - if (originalKeyword != null) { - BlackboardAttribute.ATTRIBUTE_TYPE selType = originalKeyword.getArtifactAttributeType(); - if (selType != null) { - attributes.add(new BlackboardAttribute(selType, MODULE_NAME, foundKeyword.getSearchTerm())); - } - - if (originalKeyword.searchTermIsWholeWord()) { - attributes.add(new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD_SEARCH_TYPE, MODULE_NAME, KeywordSearch.QueryType.LITERAL.ordinal())); - } else { - attributes.add(new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD_SEARCH_TYPE, MODULE_NAME, KeywordSearch.QueryType.SUBSTRING.ordinal())); - } + attributesList.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_KEYWORD_PREVIEW, MODULE_NAME, snippet)); } hit.getArtifactID().ifPresent(artifactID - -> attributes.add(new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT, MODULE_NAME, artifactID)) + -> attributesList.add(new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT, MODULE_NAME, artifactID)) ); try { - bba.addAttributes(attributes); //write out to bb + bba.addAttributes(attributesList); //write out to bb return bba; } catch (TskCoreException e) { logger.log(Level.WARNING, "Error adding bb attributes to artifact", e); //NON-NLS diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/QueryResults.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/QueryResults.java index e27a01b063..3b7dd81fa0 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/QueryResults.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/QueryResults.java @@ -41,6 +41,7 @@ import org.sleuthkit.autopsy.ingest.ModuleDataEvent; import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardAttribute; +import org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE; import org.sleuthkit.datamodel.Content; import org.sleuthkit.datamodel.SleuthkitCase; import org.sleuthkit.datamodel.TskCoreException; @@ -65,7 +66,7 @@ class QueryResults { * and publishing an event to notify subscribers of the blackboard posts. * * The KeywordSearchQuery is used to do the blackboard posts. - * + * * @param query The query. */ QueryResults(KeywordSearchQuery query) { @@ -220,8 +221,14 @@ class QueryResults { } /* - * Post an artifact for the hit to the blackboard. + * Create an artifact if it is determined that one hasn't been + * created yet. */ + if (content == null) { + logger.log(Level.WARNING, "Cannot add artifact for keyword hit to blackboard without a Content object."); //NON-NLS + continue; // Cycle to the next KeywordHit. + } + BlackboardArtifact artifact = query.postKeywordHitToBlackboard(content, keyword, hit, snippet, query.getKeywordList().getName()); /* diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/RegexQuery.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/RegexQuery.java index cb640e20bd..1706cdef60 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/RegexQuery.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/RegexQuery.java @@ -55,6 +55,7 @@ import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE; import org.sleuthkit.datamodel.BlackboardAttribute; import org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE; import org.sleuthkit.datamodel.Content; +import org.sleuthkit.datamodel.SleuthkitCase; import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.datamodel.TskData; @@ -74,7 +75,7 @@ import org.sleuthkit.datamodel.TskData; */ final class RegexQuery implements KeywordSearchQuery { - public static final Logger LOGGER = Logger.getLogger(RegexQuery.class.getName()); + public static final Logger logger = Logger.getLogger(RegexQuery.class.getName()); /** * Lucene regular expressions do not support the following Java predefined @@ -213,7 +214,7 @@ final class RegexQuery implements KeywordSearchQuery { hitsForKeyword.add(hit); } } catch (TskCoreException ex) { - LOGGER.log(Level.SEVERE, "Error creating keyword hits", ex); //NON-NLS + logger.log(Level.SEVERE, "Error creating keyword hits", ex); //NON-NLS } } @@ -223,7 +224,7 @@ final class RegexQuery implements KeywordSearchQuery { } cursorMark = nextCursorMark; } catch (KeywordSearchModuleException ex) { - LOGGER.log(Level.SEVERE, "Error executing Regex Solr Query: " + keywordString, ex); //NON-NLS + logger.log(Level.SEVERE, "Error executing Regex Solr Query: " + keywordString, ex); //NON-NLS MessageNotifyUtil.Notify.error(NbBundle.getMessage(Server.class, "Server.query.exception.msg", keywordString), ex.getCause().getMessage()); } } @@ -437,18 +438,38 @@ final class RegexQuery implements KeywordSearchQuery { * @param listName The name of the keyword list that contained the * keyword for which the hit was found. * - * - * @return The newly created artifact or null if there was a problem - * creating it. + * @return The newly created artifact, or null if one wasn't created due to + * either the artifact already existing or an error while trying to + * create it. */ @Override public BlackboardArtifact postKeywordHitToBlackboard(Content content, Keyword foundKeyword, KeywordHit hit, String snippet, String listName) { final String MODULE_NAME = KeywordSearchModuleFactory.getModuleName(); if (content == null) { - LOGGER.log(Level.WARNING, "Error adding artifact for keyword hit to blackboard"); //NON-NLS + logger.log(Level.WARNING, "Error adding artifact for keyword hit to blackboard"); //NON-NLS return null; } + + List attributesList = new ArrayList<>(); + attributesList.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_KEYWORD, MODULE_NAME, foundKeyword.getSearchTerm())); + attributesList.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_KEYWORD_SEARCH_TYPE, MODULE_NAME, KeywordSearch.QueryType.REGEX.ordinal())); + attributesList.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_KEYWORD_REGEXP, MODULE_NAME, getQueryString())); + if (StringUtils.isNotBlank(listName)) { + attributesList.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_SET_NAME, MODULE_NAME, listName)); + } + + try { + SleuthkitCase tskCase = Case.getCurrentCaseThrows().getSleuthkitCase(); + org.sleuthkit.datamodel.Blackboard tskBlackboard = tskCase.getBlackboard(); + if (tskBlackboard.artifactExists(content, BlackboardArtifact.ARTIFACT_TYPE.TSK_KEYWORD_HIT, attributesList)) { + return null; + } + } catch (NoCurrentCaseException | TskCoreException ex) { + logger.log(Level.SEVERE, String.format( + "A problem occurred while checking for existing artifacts for file '%s' (id=%d).", + content.getName(), content.getId()), ex); //NON-NLS + } /* * Credit Card number hits are handled differently @@ -463,36 +484,27 @@ final class RegexQuery implements KeywordSearchQuery { * regex attributes */ BlackboardArtifact newArtifact; - Collection attributes = new ArrayList<>(); - - attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_KEYWORD, MODULE_NAME, foundKeyword.getSearchTerm())); - attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_KEYWORD_REGEXP, MODULE_NAME, getQueryString())); try { newArtifact = content.newArtifact(ARTIFACT_TYPE.TSK_KEYWORD_HIT); } catch (TskCoreException ex) { - LOGGER.log(Level.SEVERE, "Error adding artifact for keyword hit to blackboard", ex); //NON-NLS + logger.log(Level.SEVERE, "Error adding artifact for keyword hit to blackboard", ex); //NON-NLS return null; } - if (StringUtils.isNotBlank(listName)) { - attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_SET_NAME, MODULE_NAME, listName)); - } if (snippet != null) { - attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_KEYWORD_PREVIEW, MODULE_NAME, snippet)); + attributesList.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_KEYWORD_PREVIEW, MODULE_NAME, snippet)); } hit.getArtifactID().ifPresent(artifactID - -> attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT, MODULE_NAME, artifactID)) + -> attributesList.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT, MODULE_NAME, artifactID)) ); - attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_KEYWORD_SEARCH_TYPE, MODULE_NAME, KeywordSearch.QueryType.REGEX.ordinal())); - try { - newArtifact.addAttributes(attributes); + newArtifact.addAttributes(attributesList); return newArtifact; } catch (TskCoreException e) { - LOGGER.log(Level.SEVERE, "Error adding bb attributes for terms search artifact", e); //NON-NLS + logger.log(Level.SEVERE, "Error adding bb attributes for terms search artifact", e); //NON-NLS return null; } } @@ -502,7 +514,7 @@ final class RegexQuery implements KeywordSearchQuery { final String MODULE_NAME = KeywordSearchModuleFactory.getModuleName(); if (originalKeyword.getArtifactAttributeType() != ATTRIBUTE_TYPE.TSK_CARD_NUMBER) { - LOGGER.log(Level.SEVERE, "Keyword hit is not a credit card number"); //NON-NLS + logger.log(Level.SEVERE, "Keyword hit is not a credit card number"); //NON-NLS return; } /* @@ -525,13 +537,13 @@ final class RegexQuery implements KeywordSearchQuery { if (ccnAttribute == null || StringUtils.isBlank(ccnAttribute.getValueString())) { if (hit.isArtifactHit()) { - LOGGER.log(Level.SEVERE, String.format("Failed to parse credit card account number for artifact keyword hit: term = %s, snippet = '%s', artifact id = %d", foundKeyword.getSearchTerm(), hit.getSnippet(), hit.getArtifactID().get())); //NON-NLS + logger.log(Level.SEVERE, String.format("Failed to parse credit card account number for artifact keyword hit: term = %s, snippet = '%s', artifact id = %d", foundKeyword.getSearchTerm(), hit.getSnippet(), hit.getArtifactID().get())); //NON-NLS } else { try { - LOGGER.log(Level.SEVERE, String.format("Failed to parse credit card account number for content keyword hit: term = %s, snippet = '%s', object id = %d", foundKeyword.getSearchTerm(), hit.getSnippet(), hit.getContentID())); //NON-NLS + logger.log(Level.SEVERE, String.format("Failed to parse credit card account number for content keyword hit: term = %s, snippet = '%s', object id = %d", foundKeyword.getSearchTerm(), hit.getSnippet(), hit.getContentID())); //NON-NLS } catch (TskCoreException ex) { - LOGGER.log(Level.SEVERE, String.format("Failed to parse credit card account number for content keyword hit: term = %s, snippet = '%s' ", foundKeyword.getSearchTerm(), hit.getSnippet())); //NON-NLS - LOGGER.log(Level.SEVERE, "There was a error getting contentID for keyword hit.", ex); //NON-NLS + logger.log(Level.SEVERE, String.format("Failed to parse credit card account number for content keyword hit: term = %s, snippet = '%s' ", foundKeyword.getSearchTerm(), hit.getSnippet())); //NON-NLS + logger.log(Level.SEVERE, "There was a error getting contentID for keyword hit.", ex); //NON-NLS } } return; @@ -599,7 +611,7 @@ final class RegexQuery implements KeywordSearchQuery { ccAccountInstance.addAttributes(attributes); } catch (TskCoreException | NoCurrentCaseException ex) { - LOGGER.log(Level.SEVERE, "Error creating CCN account instance", ex); //NON-NLS + logger.log(Level.SEVERE, "Error creating CCN account instance", ex); //NON-NLS } From dd1bfc106d353f46c1470fcc13f916aeff9b75a7 Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dgrove" Date: Tue, 31 Jul 2018 10:38:16 -0400 Subject: [PATCH 217/287] Cleanup. --- .../autopsy/keywordsearch/QueryResults.java | 11 ++--------- .../autopsy/keywordsearch/RegexQuery.java | 17 ++++++++--------- 2 files changed, 10 insertions(+), 18 deletions(-) diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/QueryResults.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/QueryResults.java index 3b7dd81fa0..e27a01b063 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/QueryResults.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/QueryResults.java @@ -41,7 +41,6 @@ import org.sleuthkit.autopsy.ingest.ModuleDataEvent; import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardAttribute; -import org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE; import org.sleuthkit.datamodel.Content; import org.sleuthkit.datamodel.SleuthkitCase; import org.sleuthkit.datamodel.TskCoreException; @@ -66,7 +65,7 @@ class QueryResults { * and publishing an event to notify subscribers of the blackboard posts. * * The KeywordSearchQuery is used to do the blackboard posts. - * + * * @param query The query. */ QueryResults(KeywordSearchQuery query) { @@ -221,14 +220,8 @@ class QueryResults { } /* - * Create an artifact if it is determined that one hasn't been - * created yet. + * Post an artifact for the hit to the blackboard. */ - if (content == null) { - logger.log(Level.WARNING, "Cannot add artifact for keyword hit to blackboard without a Content object."); //NON-NLS - continue; // Cycle to the next KeywordHit. - } - BlackboardArtifact artifact = query.postKeywordHitToBlackboard(content, keyword, hit, snippet, query.getKeywordList().getName()); /* diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/RegexQuery.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/RegexQuery.java index 1706cdef60..9d2717a586 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/RegexQuery.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/RegexQuery.java @@ -36,7 +36,6 @@ import org.apache.solr.client.solrj.response.QueryResponse; import org.apache.solr.common.SolrDocument; import org.apache.solr.common.SolrDocumentList; import org.apache.solr.common.params.CursorMarkParams; -import org.openide.util.Exceptions; import org.openide.util.NbBundle; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; @@ -450,6 +449,14 @@ final class RegexQuery implements KeywordSearchQuery { logger.log(Level.WARNING, "Error adding artifact for keyword hit to blackboard"); //NON-NLS return null; } + + /* + * Credit Card number hits are handled differently + */ + if (originalKeyword.getArtifactAttributeType() == ATTRIBUTE_TYPE.TSK_CARD_NUMBER) { + createCCNAccount(content, foundKeyword, hit, snippet, listName); + return null; + } List attributesList = new ArrayList<>(); attributesList.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_KEYWORD, MODULE_NAME, foundKeyword.getSearchTerm())); @@ -470,14 +477,6 @@ final class RegexQuery implements KeywordSearchQuery { "A problem occurred while checking for existing artifacts for file '%s' (id=%d).", content.getName(), content.getId()), ex); //NON-NLS } - - /* - * Credit Card number hits are handled differently - */ - if (originalKeyword.getArtifactAttributeType() == ATTRIBUTE_TYPE.TSK_CARD_NUMBER) { - createCCNAccount(content, foundKeyword, hit, snippet, listName); - return null; - } /* * Create a "plain vanilla" keyword hit artifact with keyword and From 3fadd00b45f5084d96f431db501b217db1809534 Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dgrove" Date: Tue, 31 Jul 2018 10:56:21 -0400 Subject: [PATCH 218/287] Additional cleanup. --- .../org/sleuthkit/autopsy/keywordsearch/LuceneQuery.java | 7 ++++--- .../org/sleuthkit/autopsy/keywordsearch/RegexQuery.java | 5 +++-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/LuceneQuery.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/LuceneQuery.java index fadc2f5107..b3065dcad6 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/LuceneQuery.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/LuceneQuery.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2011-2017 Basis Technology Corp. + * Copyright 2011-2018 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -37,6 +37,7 @@ import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; import org.sleuthkit.autopsy.coreutils.EscapeUtil; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.Version; +import org.sleuthkit.datamodel.Blackboard; import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE; import org.sleuthkit.datamodel.BlackboardAttribute; @@ -234,8 +235,8 @@ class LuceneQuery implements KeywordSearchQuery { try { SleuthkitCase tskCase = Case.getCurrentCaseThrows().getSleuthkitCase(); - org.sleuthkit.datamodel.Blackboard tskBlackboard = tskCase.getBlackboard(); - if (tskBlackboard.artifactExists(content, BlackboardArtifact.ARTIFACT_TYPE.TSK_KEYWORD_HIT, attributesList)) { + Blackboard blackboard = tskCase.getBlackboard(); + if (blackboard.artifactExists(content, BlackboardArtifact.ARTIFACT_TYPE.TSK_KEYWORD_HIT, attributesList)) { return null; } } catch (NoCurrentCaseException | TskCoreException ex) { diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/RegexQuery.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/RegexQuery.java index 9d2717a586..102682c4fe 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/RegexQuery.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/RegexQuery.java @@ -49,6 +49,7 @@ import static org.sleuthkit.autopsy.keywordsearch.TermsComponentQuery.KEYWORD_SE import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.Account; import org.sleuthkit.datamodel.AccountFileInstance; +import org.sleuthkit.datamodel.Blackboard; import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE; import org.sleuthkit.datamodel.BlackboardAttribute; @@ -468,8 +469,8 @@ final class RegexQuery implements KeywordSearchQuery { try { SleuthkitCase tskCase = Case.getCurrentCaseThrows().getSleuthkitCase(); - org.sleuthkit.datamodel.Blackboard tskBlackboard = tskCase.getBlackboard(); - if (tskBlackboard.artifactExists(content, BlackboardArtifact.ARTIFACT_TYPE.TSK_KEYWORD_HIT, attributesList)) { + Blackboard blackboard = tskCase.getBlackboard(); + if (blackboard.artifactExists(content, BlackboardArtifact.ARTIFACT_TYPE.TSK_KEYWORD_HIT, attributesList)) { return null; } } catch (NoCurrentCaseException | TskCoreException ex) { From f0a87e43e50c01b2c63c9fa38e01f326e5b69955 Mon Sep 17 00:00:00 2001 From: Andrew Ziehl Date: Tue, 31 Jul 2018 08:14:41 -0700 Subject: [PATCH 219/287] Add code commments for IntraCasePanel in conjuction with the previous bugfix. --- .../autopsy/commonfilesearch/IntraCasePanel.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCasePanel.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCasePanel.java index 397cf04098..5296c89c31 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCasePanel.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCasePanel.java @@ -28,8 +28,10 @@ import org.openide.util.NbBundle; import org.sleuthkit.autopsy.coreutils.Logger; /** - * - * @author bsweeney + * UI controls for Common Files Search scenario where the user intends to find + * common files between datasources. It is an inner panel which provides the ability + * to select all datasources or a single datasource from a dropdown list of + * sources in the current case. */ public class IntraCasePanel extends javax.swing.JPanel { @@ -41,6 +43,8 @@ public class IntraCasePanel extends javax.swing.JPanel { private boolean singleDataSource; private String selectedDataSource; private ComboBoxModel dataSourcesList = new DataSourceComboBoxModel(); + + // A map of data source Ids to their string names for the current case. private final Map dataSourceMap; private CommonAttributePanel parent; From 137aae131dfcd8a525f13cf62275ad9be4c162ec Mon Sep 17 00:00:00 2001 From: Andrew Ziehl Date: Tue, 31 Jul 2018 09:17:27 -0700 Subject: [PATCH 220/287] Sqlite where cluase wasn't passed in. --- .../autopsy/centralrepository/datamodel/SqliteEamDb.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java index 300451cdbd..74d0c36a66 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java @@ -747,7 +747,7 @@ final class SqliteEamDb extends AbstractSqlEamDb { public void processInstanceTableWhere(CorrelationAttribute.Type type, String whereClause, InstanceTableCallback instanceTableCallback) throws EamDbException { try { acquireSharedLock(); - super.processInstanceTable(type, instanceTableCallback); + super.processInstanceTableWhere(type, whereClause, instanceTableCallback); } finally { releaseSharedLock(); } From 8d3aeff77fcf24ffc04fb451e2497f4a732a7cbc Mon Sep 17 00:00:00 2001 From: Brian Sweeney Date: Tue, 31 Jul 2018 11:00:13 -0600 Subject: [PATCH 221/287] codacy suggestions --- .../commonfilesearch/CentralRepoCommonAttributeInstance.java | 2 +- .../org/sleuthkit/autopsy/commonfilesearch/IntraCasePanel.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepoCommonAttributeInstance.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepoCommonAttributeInstance.java index 9babcbb831..0e70722b6d 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepoCommonAttributeInstance.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepoCommonAttributeInstance.java @@ -45,7 +45,7 @@ final public class CentralRepoCommonAttributeInstance extends AbstractCommonAttr private static final Logger LOGGER = Logger.getLogger(CentralRepoCommonAttributeInstance.class.getName()); private final Integer crFileId; private CorrelationAttribute currentAttribute; - private Map dataSourceNameToIdMap; + private final Map dataSourceNameToIdMap; CentralRepoCommonAttributeInstance(Integer attrInstId, Map dataSourceIdToNameMap) { super(); diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCasePanel.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCasePanel.java index 89036d1824..9f9335104c 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCasePanel.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCasePanel.java @@ -41,7 +41,7 @@ public class IntraCasePanel extends javax.swing.JPanel { private boolean singleDataSource; private String selectedDataSource; private ComboBoxModel dataSourcesList = new DataSourceComboBoxModel(); - private Map dataSourceMap; + private final Map dataSourceMap; private String errorMessage; From 075b76e8bf6d0b274b35da38678c172d06a04d0c Mon Sep 17 00:00:00 2001 From: Andrew Ziehl Date: Tue, 31 Jul 2018 11:46:44 -0700 Subject: [PATCH 222/287] logic overhaul to reduce manipulation and building of hashmaps. --- .../AbstractCommonAttributeInstance.java | 5 ++- .../CentralRepoCommonAttributeInstance.java | 4 +- .../InterCaseSearchResultsProcessor.java | 45 ++++++++++++++++++- 3 files changed, 48 insertions(+), 6 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeInstance.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeInstance.java index 6f445ca0a3..96741efc0d 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeInstance.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeInstance.java @@ -19,6 +19,7 @@ */ package org.sleuthkit.autopsy.commonfilesearch; +import java.util.HashMap; import java.util.Map; import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance; import org.sleuthkit.autopsy.datamodel.DisplayableItemNode; @@ -70,9 +71,9 @@ public abstract class AbstractCommonAttributeInstance { * @param cachedFiles storage for abstract files which have been used * already so we can avoid extra roundtrips to the case db */ - AbstractCommonAttributeInstance(Map cachedFiles) { + AbstractCommonAttributeInstance() { this.abstractFileObjectId = -1L; - this.cachedFiles = cachedFiles; + this.cachedFiles = new HashMap<>(); this.caseName = ""; this.dataSource = ""; } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepoCommonAttributeInstance.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepoCommonAttributeInstance.java index e720cef635..dd2ff9e2b7 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepoCommonAttributeInstance.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepoCommonAttributeInstance.java @@ -45,8 +45,8 @@ final public class CentralRepoCommonAttributeInstance extends AbstractCommonAttr private final Integer crFileId; private CorrelationAttributeInstance currentAttributeInstance; - CentralRepoCommonAttributeInstance(Integer attrInstId, Map cachedFiles) { - super(cachedFiles); + CentralRepoCommonAttributeInstance(Integer attrInstId) { + super(); this.crFileId = attrInstId; } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseSearchResultsProcessor.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseSearchResultsProcessor.java index 8416bbd856..8298089d4e 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseSearchResultsProcessor.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseSearchResultsProcessor.java @@ -20,8 +20,10 @@ package org.sleuthkit.autopsy.commonfilesearch; import java.sql.ResultSet; import java.sql.SQLException; +import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.logging.Level; import org.openide.util.Exceptions; @@ -32,7 +34,11 @@ 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.datamodel.InstanceTableCallback; +import static org.sleuthkit.autopsy.commonfilesearch.AbstractCommonAttributeSearcher.collateMatchesByNumberOfInstances; import org.sleuthkit.autopsy.coreutils.Logger; +import static org.sleuthkit.autopsy.timeline.datamodel.eventtype.ArtifactEventType.LOGGER; +import org.sleuthkit.datamodel.AbstractFile; +import org.sleuthkit.datamodel.HashUtility; /** * Used to process and return CorrelationCase md5s from the EamDB for @@ -123,14 +129,49 @@ final class InterCaseSearchResultsProcessor { @Override public void process(ResultSet resultSet) { + Map> instanceCollatedCommonFiles = new HashMap<>(); + try { + String previousRowMd5 = ""; + EamDb dbManager = EamDb.getInstance(); + CommonAttributeValue commonAttributeValue = null; while (resultSet.next()) { int resultId = InstanceTableCallback.getId(resultSet); - intercaseCommonValuesMap.put(resultId, InstanceTableCallback.getValue(resultSet)); - intercaseCommonCasesMap.put(resultId, InstanceTableCallback.getCaseId(resultSet)); + String md5Value = InstanceTableCallback.getValue(resultSet); + if (md5Value == null || HashUtility.isNoDataMd5(md5Value)) { + continue; + } + int caseId = InstanceTableCallback.getCaseId(resultSet); + CorrelationCase autopsyCrCase = dbManager.getCaseById(caseId); + final String correlationCaseDisplayName = autopsyCrCase.getDisplayName(); + + if(commonAttributeValue == null) { + commonAttributeValue = new CommonAttributeValue(md5Value); + } + // we don't *have* all the information for the rows in the CR, + // so we need to consult the present case via the SleuthkitCase object + // Later, when the FileInstanceNodde is built. Therefore, build node generators for now. + if (!md5Value.equals(previousRowMd5)) { + int size = commonAttributeValue.getInstanceCount(); + if (instanceCollatedCommonFiles.containsKey(size)) { + instanceCollatedCommonFiles.get(size).add(commonAttributeValue); + } else { + ArrayList value = new ArrayList<>(); + value.add(commonAttributeValue); + instanceCollatedCommonFiles.put(size, value); + } + + commonAttributeValue = new CommonAttributeValue(md5Value); + previousRowMd5 = md5Value; + } + AbstractCommonAttributeInstance searchResult = new CentralRepoCommonAttributeInstance(resultId); + commonAttributeValue.addFileInstanceMetadata(searchResult, correlationCaseDisplayName); + } } catch (SQLException ex) { Exceptions.printStackTrace(ex); + } catch (EamDbException ex) { + LOGGER.log(Level.WARNING, "Error getting artifact instances from database.", ex); // NON-NLS } } From 6ee9ed54bd30c5c2b244b291f8789fe46a16ed3c Mon Sep 17 00:00:00 2001 From: Andrew Ziehl Date: Tue, 31 Jul 2018 15:20:35 -0700 Subject: [PATCH 223/287] cleanup logic, functionally complete --- .../AllInterCaseCommonAttributeSearcher.java | 4 +- .../InterCaseCommonAttributeSearcher.java | 52 ------------------- .../InterCaseSearchResultsProcessor.java | 26 +++++++--- .../commonfilesearch/IntraCasePanel.java | 4 +- ...ingleInterCaseCommonAttributeSearcher.java | 6 +-- 5 files changed, 24 insertions(+), 68 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllInterCaseCommonAttributeSearcher.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllInterCaseCommonAttributeSearcher.java index 74e3aabb2a..f1ae2781f1 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllInterCaseCommonAttributeSearcher.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllInterCaseCommonAttributeSearcher.java @@ -40,9 +40,7 @@ public class AllInterCaseCommonAttributeSearcher extends InterCaseCommonAttribut @Override public CommonAttributeSearchResults findFiles() throws TskCoreException, NoCurrentCaseException, SQLException, EamDbException { InterCaseSearchResultsProcessor eamDbAttrInst = new InterCaseSearchResultsProcessor(); - eamDbAttrInst.findInterCaseCommonAttributeValues(Case.getCurrentCase()); - Map> interCaseCommonFiles = gatherIntercaseResults(eamDbAttrInst.getIntercaseCommonValuesMap(), eamDbAttrInst.getIntercaseCommonCasesMap()); - + Map> interCaseCommonFiles = eamDbAttrInst.findInterCaseCommonAttributeValues(Case.getCurrentCase()); return new CommonAttributeSearchResults(interCaseCommonFiles); } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearcher.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearcher.java index a5c5f642b7..f6307c0158 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearcher.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearcher.java @@ -54,58 +54,6 @@ abstract class InterCaseCommonAttributeSearcher extends AbstractCommonAttributeS dbManager = EamDb.getInstance(); } - /** - * @param artifactInstances all 'common files' in central repo - * @param commonValues matches must ultimately have appeared in this - * collection - * @return collated map of instance counts to lists of matches - */ - Map> gatherIntercaseResults(Map commonValues, Map commonFileCases) { - - // keyis string of value - Map interCaseCommonFiles = new HashMap<>(); - - for (int commonAttrId : commonValues.keySet()) { - - String md5 = commonValues.get(commonAttrId); - if (md5 == null || HashUtility.isNoDataMd5(md5)) { - continue; - } - Map fileCache = new HashMap<>(); - - try { - int caseId = commonFileCases.get(commonAttrId); - CorrelationCase autopsyCrCase = dbManager.getCaseById(caseId); - final String correlationCaseDisplayName = autopsyCrCase.getDisplayName(); - // we don't *have* all the information for the rows in the CR, - // so we need to consult the present case via the SleuthkitCase object - // Later, when the FileInstanceNodde is built. Therefore, build node generators for now. - - if (interCaseCommonFiles.containsKey(md5)) { - //Add to intercase metaData - final CommonAttributeValue commonAttributeValue = interCaseCommonFiles.get(md5); - - AbstractCommonAttributeInstance searchResult = new CentralRepoCommonAttributeInstance(commonAttrId, fileCache); - commonAttributeValue.addFileInstanceMetadata(searchResult, correlationCaseDisplayName); - - } else { - CommonAttributeValue commonAttributeValue = new CommonAttributeValue(md5); - interCaseCommonFiles.put(md5, commonAttributeValue); - - AbstractCommonAttributeInstance searchResult = new CentralRepoCommonAttributeInstance(commonAttrId, fileCache); - commonAttributeValue.addFileInstanceMetadata(searchResult, correlationCaseDisplayName); - - } - } catch (Exception ex) { - LOGGER.log(Level.WARNING, "Error getting artifact instances from database.", ex); // NON-NLS - } - } - - Map> instanceCollatedCommonFiles = collateMatchesByNumberOfInstances(interCaseCommonFiles); - - return instanceCollatedCommonFiles; - } - protected CorrelationCase getCorrelationCaseFromId(int correlationCaseId) throws EamDbException { for (CorrelationCase cCase : this.dbManager.getCases()) { if (cCase.getID() == correlationCaseId) { diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseSearchResultsProcessor.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseSearchResultsProcessor.java index 8298089d4e..b12b4b1b57 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseSearchResultsProcessor.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseSearchResultsProcessor.java @@ -34,10 +34,7 @@ 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.datamodel.InstanceTableCallback; -import static org.sleuthkit.autopsy.commonfilesearch.AbstractCommonAttributeSearcher.collateMatchesByNumberOfInstances; import org.sleuthkit.autopsy.coreutils.Logger; -import static org.sleuthkit.autopsy.timeline.datamodel.eventtype.ArtifactEventType.LOGGER; -import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.HashUtility; /** @@ -81,17 +78,17 @@ final class InterCaseSearchResultsProcessor { * * @param currentCase The current TSK Case. */ - void findInterCaseCommonAttributeValues(Case currentCase) { + Map> findInterCaseCommonAttributeValues(Case currentCase) { try { InterCaseCommonAttributesCallback instancetableCallback = new InterCaseCommonAttributesCallback(); EamDb DbManager = EamDb.getInstance(); CorrelationAttribute.Type fileType = DbManager.getCorrelationTypeById(CorrelationAttribute.FILES_TYPE_ID); DbManager.processCaseInstancesTable(fileType, DbManager.getCase(currentCase), instancetableCallback); - + return instancetableCallback.getInstanceCollatedCommonFiles(); } catch (EamDbException ex) { LOGGER.log(Level.SEVERE, "Error accessing EamDb processing CaseInstancesTable.", ex); } - + return new HashMap<>(); } /** @@ -102,15 +99,17 @@ final class InterCaseSearchResultsProcessor { * @param currentCase The current TSK Case. * @param singleCase The case of interest. Matches must exist in this case. */ - void findSingleInterCaseCommonAttributeValues(Case currentCase, CorrelationCase singleCase) { + Map> findSingleInterCaseCommonAttributeValues(Case currentCase, CorrelationCase singleCase) { try { InterCaseCommonAttributesCallback instancetableCallback = new InterCaseCommonAttributesCallback(); EamDb DbManager = EamDb.getInstance(); CorrelationAttribute.Type fileType = DbManager.getCorrelationTypeById(CorrelationAttribute.FILES_TYPE_ID); DbManager.processSingleCaseInstancesTable(fileType, DbManager.getCase(currentCase), singleCase, instancetableCallback); + return instancetableCallback.getInstanceCollatedCommonFiles(); } catch (EamDbException ex) { LOGGER.log(Level.SEVERE, "Error accessing EamDb processing CaseInstancesTable.", ex); } + return new HashMap<>(); } Map getIntercaseCommonValuesMap() { @@ -127,17 +126,23 @@ final class InterCaseSearchResultsProcessor { */ private class InterCaseCommonAttributesCallback implements InstanceTableCallback { + final Map> instanceCollatedCommonFiles = new HashMap<>(); + @Override public void process(ResultSet resultSet) { - Map> instanceCollatedCommonFiles = new HashMap<>(); + try { String previousRowMd5 = ""; EamDb dbManager = EamDb.getInstance(); CommonAttributeValue commonAttributeValue = null; while (resultSet.next()) { + int resultId = InstanceTableCallback.getId(resultSet); String md5Value = InstanceTableCallback.getValue(resultSet); + if(previousRowMd5.isEmpty()) { + previousRowMd5 = md5Value; + } if (md5Value == null || HashUtility.isNoDataMd5(md5Value)) { continue; } @@ -173,6 +178,11 @@ final class InterCaseSearchResultsProcessor { } catch (EamDbException ex) { LOGGER.log(Level.WARNING, "Error getting artifact instances from database.", ex); // NON-NLS } + + } + + Map> getInstanceCollatedCommonFiles() { + return Collections.unmodifiableMap(instanceCollatedCommonFiles); } } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCasePanel.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCasePanel.java index c88537cb17..9b243445ca 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCasePanel.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCasePanel.java @@ -20,6 +20,7 @@ package org.sleuthkit.autopsy.commonfilesearch; import java.util.Collections; +import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; import javax.swing.ComboBoxModel; @@ -40,7 +41,7 @@ public class IntraCasePanel extends javax.swing.JPanel { private boolean singleDataSource; private String selectedDataSource; private ComboBoxModel dataSourcesList = new DataSourceComboBoxModel(); - private Map dataSourceMap; + private final Map dataSourceMap; private CommonAttributePanel parent; private String errorMessage; @@ -51,6 +52,7 @@ public class IntraCasePanel extends javax.swing.JPanel { public IntraCasePanel() { initComponents(); this.errorMessage = ""; + dataSourceMap = new HashMap<>(); } public void setParent(CommonAttributePanel parent){ diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/SingleInterCaseCommonAttributeSearcher.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/SingleInterCaseCommonAttributeSearcher.java index 9486a9e43c..5c5954d431 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/SingleInterCaseCommonAttributeSearcher.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/SingleInterCaseCommonAttributeSearcher.java @@ -70,11 +70,9 @@ public class SingleInterCaseCommonAttributeSearcher extends InterCaseCommonAttri return this.findFiles(cCase); } - protected CommonAttributeSearchResults findFiles(CorrelationCase correlationCase) throws TskCoreException, NoCurrentCaseException, SQLException, EamDbException { - + CommonAttributeSearchResults findFiles(CorrelationCase correlationCase) throws TskCoreException, NoCurrentCaseException, SQLException, EamDbException { InterCaseSearchResultsProcessor eamDbAttrInst = new InterCaseSearchResultsProcessor(); - eamDbAttrInst.findSingleInterCaseCommonAttributeValues(Case.getCurrentCase(), correlationCase); - Map> interCaseCommonFiles = gatherIntercaseResults(eamDbAttrInst.getIntercaseCommonValuesMap(), eamDbAttrInst.getIntercaseCommonCasesMap()); + Map> interCaseCommonFiles = eamDbAttrInst.findSingleInterCaseCommonAttributeValues(Case.getCurrentCase(), correlationCase); return new CommonAttributeSearchResults(interCaseCommonFiles); } From 35d5df5ebc7940ca0cf81cd48f9ed2dce833ad57 Mon Sep 17 00:00:00 2001 From: Andrew Ziehl Date: Tue, 31 Jul 2018 15:32:32 -0700 Subject: [PATCH 224/287] Cleanup excess fields. --- .../InterCaseSearchResultsProcessor.java | 40 +++++-------------- 1 file changed, 11 insertions(+), 29 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseSearchResultsProcessor.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseSearchResultsProcessor.java index b12b4b1b57..31dccb80ef 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseSearchResultsProcessor.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseSearchResultsProcessor.java @@ -26,7 +26,6 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.logging.Level; -import org.openide.util.Exceptions; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttribute; import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationCase; @@ -45,11 +44,6 @@ final class InterCaseSearchResultsProcessor { private static final Logger LOGGER = Logger.getLogger(CommonAttributePanel.class.getName()); - // maps row ID to value - private final Map intercaseCommonValuesMap = new HashMap<>(); - // maps row ID to case ID - private final Map intercaseCommonCasesMap = new HashMap<>(); - /** * Finds a single CorrelationAttribute given an id. * @@ -112,14 +106,6 @@ final class InterCaseSearchResultsProcessor { return new HashMap<>(); } - Map getIntercaseCommonValuesMap() { - return Collections.unmodifiableMap(intercaseCommonValuesMap); - } - - Map getIntercaseCommonCasesMap() { - return Collections.unmodifiableMap(intercaseCommonCasesMap); - } - /** * Callback to use with findInterCaseCommonAttributeValues which generates a * list of md5s for common files search @@ -127,11 +113,9 @@ final class InterCaseSearchResultsProcessor { private class InterCaseCommonAttributesCallback implements InstanceTableCallback { final Map> instanceCollatedCommonFiles = new HashMap<>(); - + @Override public void process(ResultSet resultSet) { - - try { String previousRowMd5 = ""; EamDb dbManager = EamDb.getInstance(); @@ -140,7 +124,7 @@ final class InterCaseSearchResultsProcessor { int resultId = InstanceTableCallback.getId(resultSet); String md5Value = InstanceTableCallback.getValue(resultSet); - if(previousRowMd5.isEmpty()) { + if (previousRowMd5.isEmpty()) { previousRowMd5 = md5Value; } if (md5Value == null || HashUtility.isNoDataMd5(md5Value)) { @@ -149,13 +133,10 @@ final class InterCaseSearchResultsProcessor { int caseId = InstanceTableCallback.getCaseId(resultSet); CorrelationCase autopsyCrCase = dbManager.getCaseById(caseId); final String correlationCaseDisplayName = autopsyCrCase.getDisplayName(); - - if(commonAttributeValue == null) { + + if (commonAttributeValue == null) { commonAttributeValue = new CommonAttributeValue(md5Value); } - // we don't *have* all the information for the rows in the CR, - // so we need to consult the present case via the SleuthkitCase object - // Later, when the FileInstanceNodde is built. Therefore, build node generators for now. if (!md5Value.equals(previousRowMd5)) { int size = commonAttributeValue.getInstanceCount(); if (instanceCollatedCommonFiles.containsKey(size)) { @@ -169,18 +150,19 @@ final class InterCaseSearchResultsProcessor { commonAttributeValue = new CommonAttributeValue(md5Value); previousRowMd5 = md5Value; } + // we don't *have* all the information for the rows in the CR, + // so we need to consult the present case via the SleuthkitCase object + // Later, when the FileInstanceNode is built. Therefore, build node generators for now. AbstractCommonAttributeInstance searchResult = new CentralRepoCommonAttributeInstance(resultId); commonAttributeValue.addFileInstanceMetadata(searchResult, correlationCaseDisplayName); } - } catch (SQLException ex) { - Exceptions.printStackTrace(ex); - } catch (EamDbException ex) { + } catch (SQLException | EamDbException ex) { LOGGER.log(Level.WARNING, "Error getting artifact instances from database.", ex); // NON-NLS } - + } - + Map> getInstanceCollatedCommonFiles() { return Collections.unmodifiableMap(instanceCollatedCommonFiles); } @@ -212,7 +194,7 @@ final class InterCaseSearchResultsProcessor { } } catch (SQLException | EamDbException ex) { - Exceptions.printStackTrace(ex); + LOGGER.log(Level.WARNING, "Error getting single correlation artifact instance from database.", ex); // NON-NLS } } From 9163256cd33769532ed06ae2b8754139ba2fd652 Mon Sep 17 00:00:00 2001 From: Andrew Ziehl Date: Tue, 31 Jul 2018 15:54:33 -0700 Subject: [PATCH 225/287] Refactoring --- .../InterCaseSearchResultsProcessor.java | 53 +++++++++++-------- 1 file changed, 30 insertions(+), 23 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseSearchResultsProcessor.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseSearchResultsProcessor.java index 31dccb80ef..2a1845a36a 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseSearchResultsProcessor.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseSearchResultsProcessor.java @@ -114,12 +114,15 @@ final class InterCaseSearchResultsProcessor { final Map> instanceCollatedCommonFiles = new HashMap<>(); + private CommonAttributeValue commonAttributeValue = null; + private String previousRowMd5 = ""; + @Override public void process(ResultSet resultSet) { try { - String previousRowMd5 = ""; + EamDb dbManager = EamDb.getInstance(); - CommonAttributeValue commonAttributeValue = null; + while (resultSet.next()) { int resultId = InstanceTableCallback.getId(resultSet); @@ -134,27 +137,7 @@ final class InterCaseSearchResultsProcessor { CorrelationCase autopsyCrCase = dbManager.getCaseById(caseId); final String correlationCaseDisplayName = autopsyCrCase.getDisplayName(); - if (commonAttributeValue == null) { - commonAttributeValue = new CommonAttributeValue(md5Value); - } - if (!md5Value.equals(previousRowMd5)) { - int size = commonAttributeValue.getInstanceCount(); - if (instanceCollatedCommonFiles.containsKey(size)) { - instanceCollatedCommonFiles.get(size).add(commonAttributeValue); - } else { - ArrayList value = new ArrayList<>(); - value.add(commonAttributeValue); - instanceCollatedCommonFiles.put(size, value); - } - - commonAttributeValue = new CommonAttributeValue(md5Value); - previousRowMd5 = md5Value; - } - // we don't *have* all the information for the rows in the CR, - // so we need to consult the present case via the SleuthkitCase object - // Later, when the FileInstanceNode is built. Therefore, build node generators for now. - AbstractCommonAttributeInstance searchResult = new CentralRepoCommonAttributeInstance(resultId); - commonAttributeValue.addFileInstanceMetadata(searchResult, correlationCaseDisplayName); + countAndAddCommonAttributes(md5Value, resultId, correlationCaseDisplayName); } } catch (SQLException | EamDbException ex) { @@ -163,6 +146,30 @@ final class InterCaseSearchResultsProcessor { } + private void countAndAddCommonAttributes(String md5Value, int resultId, String correlationCaseDisplayName) { + if (commonAttributeValue == null) { + commonAttributeValue = new CommonAttributeValue(md5Value); + } + if (!md5Value.equals(previousRowMd5)) { + int size = commonAttributeValue.getInstanceCount(); + if (instanceCollatedCommonFiles.containsKey(size)) { + instanceCollatedCommonFiles.get(size).add(commonAttributeValue); + } else { + ArrayList value = new ArrayList<>(); + value.add(commonAttributeValue); + instanceCollatedCommonFiles.put(size, value); + } + + commonAttributeValue = new CommonAttributeValue(md5Value); + previousRowMd5 = md5Value; + } + // we don't *have* all the information for the rows in the CR, + // so we need to consult the present case via the SleuthkitCase object + // Later, when the FileInstanceNode is built. Therefore, build node generators for now. + AbstractCommonAttributeInstance searchResult = new CentralRepoCommonAttributeInstance(resultId); + commonAttributeValue.addFileInstanceMetadata(searchResult, correlationCaseDisplayName); + } + Map> getInstanceCollatedCommonFiles() { return Collections.unmodifiableMap(instanceCollatedCommonFiles); } From fee2e8126459322c0c8cbb44829165ce6847b187 Mon Sep 17 00:00:00 2001 From: Eugene Livis Date: Wed, 1 Aug 2018 10:44:41 -0400 Subject: [PATCH 226/287] Removed empty space in UI --- .../autopsy/keywordsearch/DropdownSingleTermSearchPanel.form | 2 +- .../autopsy/keywordsearch/DropdownSingleTermSearchPanel.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/DropdownSingleTermSearchPanel.form b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/DropdownSingleTermSearchPanel.form index 81630d6fa5..95baf22255 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/DropdownSingleTermSearchPanel.form +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/DropdownSingleTermSearchPanel.form @@ -76,7 +76,7 @@ - + diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/DropdownSingleTermSearchPanel.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/DropdownSingleTermSearchPanel.java index 1f6744cced..fc81c092c9 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/DropdownSingleTermSearchPanel.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/DropdownSingleTermSearchPanel.java @@ -307,7 +307,7 @@ public class DropdownSingleTermSearchPanel extends AdHocSearchPanel { .addComponent(ingestIndexLabel)) .addComponent(keywordTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 296, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(dataSourceCheckBox)) - .addContainerGap(39, Short.MAX_VALUE)) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) From a1c4db14bd55b1c9567f2886a7698a5b7707c1d2 Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dgrove" Date: Thu, 2 Aug 2018 10:22:08 -0400 Subject: [PATCH 227/287] Codacy issues resolved. --- .../contentviewer/DataContentViewerOtherCases.java | 1 - .../contentviewer/DataContentViewerOtherCasesTableModel.java | 2 ++ 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/DataContentViewerOtherCases.java b/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/DataContentViewerOtherCases.java index 635605a904..6579b15e08 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/DataContentViewerOtherCases.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/DataContentViewerOtherCases.java @@ -49,7 +49,6 @@ import javax.swing.JPanel; import javax.swing.filechooser.FileNameExtensionFilter; import javax.swing.table.TableCellRenderer; import javax.swing.table.TableColumn; -import javax.swing.table.TableColumnModel; import org.joda.time.DateTimeZone; import org.joda.time.LocalDateTime; import org.openide.nodes.Node; diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/DataContentViewerOtherCasesTableModel.java b/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/DataContentViewerOtherCasesTableModel.java index 9ae79259c2..1f04f1f478 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/DataContentViewerOtherCasesTableModel.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/DataContentViewerOtherCasesTableModel.java @@ -172,6 +172,8 @@ public class DataContentViewerOtherCasesTableModel extends AbstractTableModel { case COMMENT: value = nodeData.getComment(); break; + default: // This shouldn't occur! Use default "No data" value. + break; } return value; } From 8aba921666c74b8fb817af405b8c6e6d1849fcda Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dsmyda" Date: Thu, 2 Aug 2018 12:17:48 -0400 Subject: [PATCH 228/287] Functional SevenZipExtractor using standard interface. SevenZipException exception handling during extract vs extractSlow still untested --- .../SevenZipExtractor.java | 371 +++++++++++++----- 1 file changed, 267 insertions(+), 104 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/modules/embeddedfileextractor/SevenZipExtractor.java b/Core/src/org/sleuthkit/autopsy/modules/embeddedfileextractor/SevenZipExtractor.java index ee9415ddca..a959345ca6 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/embeddedfileextractor/SevenZipExtractor.java +++ b/Core/src/org/sleuthkit/autopsy/modules/embeddedfileextractor/SevenZipExtractor.java @@ -25,22 +25,27 @@ import java.io.OutputStream; import java.nio.file.Files; import java.nio.file.Paths; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.Date; import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.logging.Level; import net.sf.sevenzipjbinding.ArchiveFormat; import static net.sf.sevenzipjbinding.ArchiveFormat.RAR; +import net.sf.sevenzipjbinding.ExtractAskMode; import net.sf.sevenzipjbinding.ISequentialOutStream; import net.sf.sevenzipjbinding.ISevenZipInArchive; import net.sf.sevenzipjbinding.SevenZip; import net.sf.sevenzipjbinding.SevenZipException; import net.sf.sevenzipjbinding.SevenZipNativeInitializationException; -import net.sf.sevenzipjbinding.simple.ISimpleInArchive; -import net.sf.sevenzipjbinding.simple.ISimpleInArchiveItem; import net.sf.sevenzipjbinding.ExtractOperationResult; +import net.sf.sevenzipjbinding.IArchiveExtractCallback; +import net.sf.sevenzipjbinding.ICryptoGetTextPassword; +import net.sf.sevenzipjbinding.PropID; import org.netbeans.api.progress.ProgressHandle; import org.openide.util.NbBundle; import org.openide.util.NbBundle.Messages; @@ -167,19 +172,22 @@ class SevenZipExtractor { * * @return true if potential zip bomb, false otherwise */ - private boolean isZipBombArchiveItemCheck(AbstractFile archiveFile, ISimpleInArchiveItem archiveFileItem, ConcurrentHashMap depthMap, String escapedFilePath) { + private boolean isZipBombArchiveItemCheck(AbstractFile archiveFile, ISevenZipInArchive inArchive, int inArchiveItemIndex, ConcurrentHashMap depthMap, String escapedFilePath) { try { - final Long archiveItemSize = archiveFileItem.getSize(); + final Long archiveItemSize = (Long) inArchive.getProperty( + inArchiveItemIndex, PropID.SIZE); //skip the check for small files if (archiveItemSize == null || archiveItemSize < MIN_COMPRESSION_RATIO_SIZE) { return false; } - final Long archiveItemPackedSize = archiveFileItem.getPackedSize(); + final Long archiveItemPackedSize = (Long) inArchive.getProperty( + inArchiveItemIndex, PropID.PACKED_SIZE); if (archiveItemPackedSize == null || archiveItemPackedSize <= 0) { - logger.log(Level.WARNING, "Cannot getting compression ratio, cannot detect if zipbomb: {0}, item: {1}", new Object[]{archiveFile.getName(), archiveFileItem.getPath()}); //NON-NLS + logger.log(Level.WARNING, "Cannot getting compression ratio, cannot detect if zipbomb: {0}, item: {1}", //NON-NLS + new Object[]{archiveFile.getName(), (String) inArchive.getProperty(inArchiveItemIndex, PropID.PATH)}); //NON-NLS return false; } @@ -366,8 +374,9 @@ class SevenZipExtractor { * * @throws SevenZipException */ - private String getPathInArchive(ISimpleInArchiveItem item, int itemNumber, AbstractFile archiveFile) throws SevenZipException { - String pathInArchive = item.getPath(); + private String getPathInArchive(ISevenZipInArchive archive, int inArchiveItemIndex, AbstractFile archiveFile) throws SevenZipException { + String pathInArchive = (String) archive.getProperty( + inArchiveItemIndex, PropID.PATH); if (pathInArchive == null || pathInArchive.isEmpty()) { //some formats (.tar.gz) may not be handled correctly -- file in archive has no name/path @@ -400,7 +409,7 @@ class SevenZipExtractor { } } if (useName == null) { - pathInArchive = "/" + archName + "/" + Integer.toString(itemNumber); + pathInArchive = "/" + archName + "/" + Integer.toString(inArchiveItemIndex); } else { pathInArchive = "/" + useName; } @@ -428,69 +437,6 @@ class SevenZipExtractor { return node == null ? null : archiveFilePath + "/" + node.getFileName(); } - /** - * Unpack an archive item to the disk using a password if specified. - * - * @param item - the archive item to unpack - * @param unpackedNode - the unpackedNode to add derivedInfo to - * @param password - the password for the archive, null if not - * used - * @param freeDiskSpace - the amount of free disk space - * @param uniqueExtractedName - the name of the file to extract the item to - * - * @return unpackedNode - the updated unpackedNode - * - * @throws SevenZipException - */ - private SevenZipExtractor.UnpackedTree.UnpackedNode unpackNode(ISimpleInArchiveItem item, SevenZipExtractor.UnpackedTree.UnpackedNode unpackedNode, String password, long freeDiskSpace, String uniqueExtractedName) throws SevenZipException { - //unpack locally if a file - final String localAbsPath = moduleDirAbsolute + File.separator + uniqueExtractedName; - final String localRelPath = moduleDirRelative + File.separator + uniqueExtractedName; - final Date createTime = item.getCreationTime(); - final Date accessTime = item.getLastAccessTime(); - final Date writeTime = item.getLastWriteTime(); - final long createtime = createTime == null ? 0L : createTime.getTime() / 1000; - final long modtime = writeTime == null ? 0L : writeTime.getTime() / 1000; - final long accesstime = accessTime == null ? 0L : accessTime.getTime() / 1000; - SevenZipExtractor.UnpackStream unpackStream = null; - boolean isDir = item.isFolder(); - if (!isDir) { - try { - // NOTE: item.getSize() may return null in case of certain - // archiving formats. Eg: BZ2 - if (item.getSize() != null) { - unpackStream = new SevenZipExtractor.KnownSizeUnpackStream(localAbsPath, item.getSize()); - } else { - unpackStream = new SevenZipExtractor.UnknownSizeUnpackStream(localAbsPath, freeDiskSpace); - } - ExtractOperationResult result; - if (password == null) { - result = item.extractSlow(unpackStream); - } else { - result = item.extractSlow(unpackStream, password); - } - if (result != ExtractOperationResult.OK) { - logger.log(Level.WARNING, "Extraction of : {0} encountered error {1}", new Object[]{localAbsPath, result}); //NON-NLS - return null; - } - - } catch (SevenZipException e) { - //could be something unexpected with this file, move on - logger.log(Level.WARNING, "Could not extract file from archive: " + localAbsPath, e); //NON-NLS - } finally { - if (unpackStream != null) { - //record derived data in unode, to be traversed later after unpacking the archive - unpackedNode.addDerivedInfo(unpackStream.getSize(), !isDir, - 0L, createtime, accesstime, modtime, localRelPath); - unpackStream.close(); - } - } - } else { // this is a directory, size is always 0 - unpackedNode.addDerivedInfo(0, !isDir, 0L, createtime, accesstime, modtime, localRelPath); - } - return unpackedNode; - } - /** * Unpack the file to local folder and return a list of derived files * @@ -530,6 +476,8 @@ class SevenZipExtractor { List unpackedFiles = Collections.emptyList(); ISevenZipInArchive inArchive = null; + Map archiveDetailsMap = new LinkedHashMap<>(); + SevenZipContentReadStream stream = null; final ProgressHandle progress = ProgressHandle.createHandle(Bundle.EmbeddedFileExtractorIngestModule_ArchiveExtractor_moduleName()); //recursion depth check for zip bomb @@ -590,7 +538,7 @@ class SevenZipExtractor { logger.log(Level.INFO, "Count of items in archive: {0}: {1}", new Object[]{escapedArchiveFilePath, numItems}); //NON-NLS progress.start(numItems); progressStarted = true; - final ISimpleInArchive simpleInArchive = inArchive.getSimpleInterface(); + progress.progress(archiveFile.getName() + ": Analyzing archive metadata and creating local files"); //setup the archive local root folder final String uniqueArchiveFileName = FileUtil.escapeFileName(EmbeddedFileExtractorIngestModule.getUniqueName(archiveFile)); @@ -614,25 +562,22 @@ class SevenZipExtractor { //currently getFreeDiskSpace always returns DISK_FREE_SPACE_UNKNOWN freeDiskSpace = IngestMonitor.DISK_FREE_SPACE_UNKNOWN; } - //unpack and process every item in archive - int itemNumber = 0; - for (ISimpleInArchiveItem item : simpleInArchive.getArchiveItems()) { - String pathInArchive = getPathInArchive(item, itemNumber, archiveFile); + for (int inArchiveItemIndex = 0; inArchiveItemIndex < numItems; inArchiveItemIndex++) { + String pathInArchive = getPathInArchive(inArchive, inArchiveItemIndex, archiveFile); + String archiveItemPath = (String) inArchive.getProperty( + inArchiveItemIndex, PropID.PATH); + Long archiveItemSize = (Long) inArchive.getProperty( + inArchiveItemIndex, PropID.SIZE); - //query for path in db - ++itemNumber; - - //check if possible zip bomb - if (isZipBombArchiveItemCheck(archiveFile, item, depthMap, escapedArchiveFilePath)) { + if (isZipBombArchiveItemCheck(archiveFile, inArchive, inArchiveItemIndex, depthMap, escapedArchiveFilePath)) { unpackSuccessful = false; return unpackSuccessful; } - SevenZipExtractor.UnpackedTree.UnpackedNode unpackedNode = unpackedTree.addNode(pathInArchive); - //update progress bar - progress.progress(archiveFile.getName() + ": " + item.getPath(), processedItems); - final boolean isEncrypted = item.isEncrypted(); + SevenZipExtractor.UnpackedTree.UnpackedNode unpackedNode = unpackedTree.addNode(pathInArchive); + + final boolean isEncrypted = (Boolean) inArchive.getProperty(inArchiveItemIndex, PropID.ENCRYPTED); if (isEncrypted && password == null) { logger.log(Level.WARNING, "Skipping encrypted file in archive: {0}", pathInArchive); //NON-NLS @@ -642,20 +587,21 @@ class SevenZipExtractor { } else { fullEncryption = false; } + // NOTE: item.getSize() may return null in case of certain // archiving formats. Eg: BZ2 //check if unpacking this file will result in out of disk space //this is additional to zip bomb prevention mechanism - if (freeDiskSpace != IngestMonitor.DISK_FREE_SPACE_UNKNOWN && item.getSize() != null && item.getSize() > 0) { //if free space is known and file is not empty. - long newDiskSpace = freeDiskSpace - item.getSize(); + if (freeDiskSpace != IngestMonitor.DISK_FREE_SPACE_UNKNOWN && archiveItemSize != null && archiveItemSize > 0) { //if free space is known and file is not empty. + long newDiskSpace = freeDiskSpace - archiveItemSize; if (newDiskSpace < MIN_FREE_DISK_SPACE) { String msg = NbBundle.getMessage(SevenZipExtractor.class, "EmbeddedFileExtractorIngestModule.ArchiveExtractor.unpack.notEnoughDiskSpace.msg", - escapedArchiveFilePath, item.getPath()); + escapedArchiveFilePath, archiveItemPath); String details = NbBundle.getMessage(SevenZipExtractor.class, "EmbeddedFileExtractorIngestModule.ArchiveExtractor.unpack.notEnoughDiskSpace.details"); services.postMessage(IngestMessage.createErrorMessage(EmbeddedFileExtractorModuleFactory.getModuleName(), msg, details)); - logger.log(Level.INFO, "Skipping archive item due to insufficient disk space: {0}, {1}", new String[]{escapedArchiveFilePath, item.getPath()}); //NON-NLS + logger.log(Level.INFO, "Skipping archive item due to insufficient disk space: {0}, {1}", new String[]{escapedArchiveFilePath, archiveItemPath}); //NON-NLS logger.log(Level.INFO, "Available disk space: {0}", new Object[]{freeDiskSpace}); //NON-NLS unpackSuccessful = false; continue; //skip this file @@ -664,42 +610,61 @@ class SevenZipExtractor { freeDiskSpace = newDiskSpace; } } - final String uniqueExtractedName = FileUtil.escapeFileName(uniqueArchiveFileName + File.separator + (item.getItemIndex() / 1000) + File.separator + item.getItemIndex() + "_" + new File(pathInArchive).getName()); + final String uniqueExtractedName = FileUtil.escapeFileName(uniqueArchiveFileName + File.separator + (inArchiveItemIndex / 1000) + File.separator + inArchiveItemIndex + "_" + new File(pathInArchive).getName()); + final String localAbsPath = moduleDirAbsolute + File.separator + uniqueExtractedName; + final String localRelPath = moduleDirRelative + File.separator + uniqueExtractedName; //create local dirs and empty files before extracted - File localFile = new java.io.File(moduleDirAbsolute + File.separator + uniqueExtractedName); + File localFile = new java.io.File(localAbsPath); //cannot rely on files in top-bottom order if (!localFile.exists()) { try { - if (item.isFolder()) { + if ((Boolean) inArchive.getProperty( + inArchiveItemIndex, PropID.IS_FOLDER)) { localFile.mkdirs(); } else { localFile.getParentFile().mkdirs(); try { localFile.createNewFile(); } catch (IOException e) { - logger.log(Level.SEVERE, "Error creating extracted file: " + localFile.getAbsolutePath(), e); //NON-NLS + logger.log(Level.SEVERE, "Error creating extracted file: " + + localFile.getAbsolutePath(), e); //NON-NLS } } } catch (SecurityException e) { - logger.log(Level.SEVERE, "Error setting up output path for unpacked file: {0}", pathInArchive); //NON-NLS + logger.log(Level.SEVERE, "Error setting up output path for unpacked file: {0}", + pathInArchive); //NON-NLS //TODO consider bail out / msg to the user } } // skip the rest of this loop if we couldn't create the file + //continue will skip details from being added to the map if (localFile.exists() == false) { continue; } - //find this node in the hierarchy, create if neede; - unpackedNode = unpackNode(item, unpackedNode, password, - freeDiskSpace, uniqueExtractedName); - if (unpackedNode == null) { - unpackSuccessful = false; - } - //update units for progress bar - ++processedItems; + //Store archiveItemIndex with local paths and unpackedNode reference. + //Necessary for the extract call back to write the current archive + //file to the correct disk location and to correctly update it's + //corresponding unpackedNode + archiveDetailsMap.put(inArchiveItemIndex, new InArchiveItemDetails( + unpackedNode, localAbsPath, localRelPath)); } + + int[] extractionIndices = getExtractableFilesFromArchiveDetails(archiveDetailsMap); + + StandardIArchiveExtractCallback archiveCallBack + = new StandardIArchiveExtractCallback( + inArchive, archiveFile, progress, + archiveDetailsMap, password, freeDiskSpace); + + //According to the documentation, indices in sorted order are optimal + //for efficiency. Hence, the LinkedHashMap and linear processing of + //inArchiveItemIndex. + inArchive.extract(extractionIndices, false, archiveCallBack); + + unpackSuccessful = unpackSuccessful & archiveCallBack.getSuccessFlag(); + // add them to the DB. We wait until the end so that we have the metadata on all of the // intermediate nodes since the order is not guaranteed try { @@ -799,6 +764,21 @@ class SevenZipExtractor { return unpackSuccessful; } + /** + * Produce a list of archive indices needed for the call to extract, which + * will open the archive and begin unpacking the files. + */ + private int[] getExtractableFilesFromArchiveDetails( + Map archiveDetailsMap) { + + Integer[] wrappedExtractionIndices = archiveDetailsMap.keySet() + .toArray(new Integer[archiveDetailsMap.size()]); + + return Arrays.stream(wrappedExtractionIndices) + .mapToInt(Integer::intValue) + .toArray(); + } + /** * Stream used to unpack the archive to local file */ @@ -933,6 +913,188 @@ class SevenZipExtractor { } } + /** + * Wrapper for necessary details used in StandardIArchiveExtractCallback + */ + private static class InArchiveItemDetails { + + private SevenZipExtractor.UnpackedTree.UnpackedNode unpackedNode; + private String localAbsPath; + private String localRelPath; + + public InArchiveItemDetails( + SevenZipExtractor.UnpackedTree.UnpackedNode unpackedNode, + String localAbsPath, String localRelPath) { + this.unpackedNode = unpackedNode; + this.localAbsPath = localAbsPath; + this.localRelPath = localRelPath; + } + + public SevenZipExtractor.UnpackedTree.UnpackedNode getUnpackedNode() { + return unpackedNode; + } + + public String getLocalAbsPath() { + return localAbsPath; + } + + public String getLocalRelPath() { + return localRelPath; + } + } + + /** + * Call back class used by extract to expand archive files. This is the most + * efficient way to process according to the sevenzip binding documentation. + */ + private static class StandardIArchiveExtractCallback + implements IArchiveExtractCallback, ICryptoGetTextPassword { + + private int inArchiveItemIndex; + private ISevenZipInArchive inArchive; + private SevenZipExtractor.UnpackStream unpackStream = null; + private long freeDiskSpace; + private Map archiveDetailsMap; + private ProgressHandle progressHandle; + private AbstractFile archiveFile; + + private long createTimeInSeconds; + private long modTimeInSeconds; + private long accessTimeInSeconds; + + private boolean skipExtraction; + private String password; + + private boolean unpackSuccessful = true; + + public StandardIArchiveExtractCallback(ISevenZipInArchive inArchive, + AbstractFile archiveFile, ProgressHandle progressHandle, + Map archiveDetailsMap, + String password, long freeDiskSpace) { + + this.inArchive = inArchive; + this.freeDiskSpace = freeDiskSpace; + this.progressHandle = progressHandle; + this.archiveFile = archiveFile; + this.archiveDetailsMap = archiveDetailsMap; + this.password = password; + } + + @Override + public ISequentialOutStream getStream( + int i, ExtractAskMode EAM) throws SevenZipException { + + inArchiveItemIndex = i; + + skipExtraction = (Boolean) inArchive + .getProperty(inArchiveItemIndex, PropID.IS_FOLDER); + if (skipExtraction || EAM != ExtractAskMode.EXTRACT) { + return null; + } + + final Long archiveItemSize = (Long) inArchive.getProperty( + inArchiveItemIndex, PropID.SIZE); + final String localAbsPath = archiveDetailsMap.get( + inArchiveItemIndex).getLocalAbsPath(); + + if (archiveItemSize != null) { + unpackStream = new SevenZipExtractor.KnownSizeUnpackStream( + localAbsPath, archiveItemSize); + } else { + unpackStream = new SevenZipExtractor.UnknownSizeUnpackStream( + localAbsPath, freeDiskSpace); + } + + return unpackStream; + } + + @Override + public void prepareOperation(ExtractAskMode eam) throws SevenZipException { + final Date createTime = (Date) inArchive.getProperty( + inArchiveItemIndex, PropID.CREATION_TIME); + final Date accessTime = (Date) inArchive.getProperty( + inArchiveItemIndex, PropID.LAST_ACCESS_TIME); + final Date writeTime = (Date) inArchive.getProperty( + inArchiveItemIndex, PropID.LAST_WRITE_TIME); + + createTimeInSeconds = createTime == null ? 0L + : createTime.getTime() / 1000; + modTimeInSeconds = writeTime == null ? 0L + : writeTime.getTime() / 1000; + accessTimeInSeconds = accessTime == null ? 0L + : accessTime.getTime() / 1000; + } + + /** + * Pull necessary details from map to appropriately update unpackedNode + * info and provide useful logging messages. + * + * + * @param EOR - ExtractOperationResult + * + * @throws SevenZipException + */ + @Override + public void setOperationResult(ExtractOperationResult EOR) throws SevenZipException { + final SevenZipExtractor.UnpackedTree.UnpackedNode unpackedNode + = archiveDetailsMap.get(inArchiveItemIndex).getUnpackedNode(); + final String localRelPath = archiveDetailsMap.get( + inArchiveItemIndex).getLocalRelPath(); + final String localAbsPath = archiveDetailsMap.get( + inArchiveItemIndex).getLocalAbsPath(); + + progressHandle.progress(archiveFile.getName() + ": " + + (String) inArchive.getProperty(inArchiveItemIndex, PropID.PATH), + inArchiveItemIndex); + + if (skipExtraction) { + unpackedNode.addDerivedInfo(0, + !(Boolean) inArchive.getProperty(inArchiveItemIndex, PropID.IS_FOLDER), + 0L, createTimeInSeconds, accessTimeInSeconds, modTimeInSeconds, + localRelPath); + return; + } + + //TODO - causes unpack to be unsuccessful, implement fix. + if (EOR != ExtractOperationResult.OK) { + logger.log(Level.WARNING, "Extraction of : {0} encountered error {1}", //NON-NLS + new Object[]{localAbsPath, EOR}); + unpackSuccessful = false; + } + + //record derived data in unode, to be traversed later after unpacking the archive + unpackedNode.addDerivedInfo(unpackStream.getSize(), + !(Boolean) inArchive.getProperty(inArchiveItemIndex, PropID.IS_FOLDER), + 0L, createTimeInSeconds, accessTimeInSeconds, modTimeInSeconds, localRelPath); + + unpackStream.close(); + } + + @Override + public void setTotal(long l) throws SevenZipException { + } + + @Override + public void setCompleted(long l) throws SevenZipException { + } + + /** + * Called when opening encrypted archive files. + * + * @return - Password supplied by user + * + * @throws SevenZipException + */ + @Override + public String cryptoGetTextPassword() throws SevenZipException { + return password; + } + + public boolean getSuccessFlag() { + return unpackSuccessful; + } + } + /** * Representation of the files in the archive. Used to track of local tree * file hierarchy, archive depth, and files created to easily and reliably @@ -1290,7 +1452,8 @@ class SevenZipExtractor { } /** - * Set the flag which identifies whether this file has been determined to be a zip bomb to true. + * Set the flag which identifies whether this file has been determined + * to be a zip bomb to true. */ synchronized void flagAsZipBomb() { flaggedAsZipBomb = true; From b1d242ace39b127584869bb13b608b6428a5549c Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dsmyda" Date: Thu, 2 Aug 2018 12:22:43 -0400 Subject: [PATCH 229/287] Fixed //NON-NLS comment to be inline with the logger messages --- .../modules/embeddedfileextractor/SevenZipExtractor.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/modules/embeddedfileextractor/SevenZipExtractor.java b/Core/src/org/sleuthkit/autopsy/modules/embeddedfileextractor/SevenZipExtractor.java index a959345ca6..ca1dd28233 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/embeddedfileextractor/SevenZipExtractor.java +++ b/Core/src/org/sleuthkit/autopsy/modules/embeddedfileextractor/SevenZipExtractor.java @@ -627,12 +627,12 @@ class SevenZipExtractor { try { localFile.createNewFile(); } catch (IOException e) { - logger.log(Level.SEVERE, "Error creating extracted file: " - + localFile.getAbsolutePath(), e); //NON-NLS + logger.log(Level.SEVERE, "Error creating extracted file: "//NON-NLS + + localFile.getAbsolutePath(), e); } } } catch (SecurityException e) { - logger.log(Level.SEVERE, "Error setting up output path for unpacked file: {0}", + logger.log(Level.SEVERE, "Error setting up output path for unpacked file: {0}", //NON-NLS pathInArchive); //NON-NLS //TODO consider bail out / msg to the user } From 74bf4bd272c5cb2d85aa589fd48510853fc4aee6 Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Thu, 2 Aug 2018 14:14:24 -0400 Subject: [PATCH 230/287] 3964 - change name of new image to reflect naming schema in 3771 --- Core/build.xml | 2 +- .../src/org/sleuthkit/autopsy/ingest/EmbeddedFileTest.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Core/build.xml b/Core/build.xml index 322fe961ff..aa654b0f36 100644 --- a/Core/build.xml +++ b/Core/build.xml @@ -86,7 +86,7 @@ - + diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/ingest/EmbeddedFileTest.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/ingest/EmbeddedFileTest.java index 0bb8144527..7af0a429d8 100755 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/ingest/EmbeddedFileTest.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/ingest/EmbeddedFileTest.java @@ -47,7 +47,7 @@ import org.sleuthkit.datamodel.TskCoreException; public class EmbeddedFileTest extends NbTestCase { private static final String CASE_NAME = "EmbeddedFileTest"; - private final Path IMAGE_PATH = Paths.get(this.getDataDir().toString(), "EmbeddedIM_img2_v1.vhd"); + private final Path IMAGE_PATH = Paths.get(this.getDataDir().toString(), "EmbeddedIM_img1_v2.vhd"); public static final String HASH_VALUE = "098f6bcd4621d373cade4e832627b4f6"; private static final int DEEP_FOLDER_COUNT = 25; private Case openCase; From 44849b30a90794ba1fae5d124e743faf6f6a632f Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Thu, 2 Aug 2018 14:25:04 -0400 Subject: [PATCH 231/287] Update TableReportGenerator.java --- Core/src/org/sleuthkit/autopsy/report/TableReportGenerator.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/report/TableReportGenerator.java b/Core/src/org/sleuthkit/autopsy/report/TableReportGenerator.java index ff1479cd86..804696e8db 100644 --- a/Core/src/org/sleuthkit/autopsy/report/TableReportGenerator.java +++ b/Core/src/org/sleuthkit/autopsy/report/TableReportGenerator.java @@ -59,7 +59,7 @@ import org.sleuthkit.datamodel.TagName; import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.datamodel.TskData; -class TableReportGenerator { +class TableReportGenerator { private final List artifactTypes = new ArrayList<>(); private final HashSet tagNamesFilter = new HashSet<>(); From 56a713120b6f1b52da6f6accabfedf66516c72a8 Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dgrove" Date: Thu, 2 Aug 2018 15:12:21 -0400 Subject: [PATCH 232/287] Cleanup. --- .../autopsy/directorytree/ExtractAction.java | 115 ++++++++----- .../directorytree/ExtractUnallocAction.java | 151 ++++++++++-------- 2 files changed, 153 insertions(+), 113 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/directorytree/ExtractAction.java b/Core/src/org/sleuthkit/autopsy/directorytree/ExtractAction.java index 2f45e44331..1f50859bb8 100644 --- a/Core/src/org/sleuthkit/autopsy/directorytree/ExtractAction.java +++ b/Core/src/org/sleuthkit/autopsy/directorytree/ExtractAction.java @@ -25,7 +25,9 @@ import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import java.util.Iterator; +import java.util.List; import java.util.Set; +import java.util.concurrent.ExecutionException; import java.util.logging.Level; import javax.swing.AbstractAction; import javax.swing.JFileChooser; @@ -33,7 +35,6 @@ import javax.swing.JOptionPane; import javax.swing.SwingWorker; import org.netbeans.api.progress.ProgressHandle; import org.openide.util.Cancellable; -import org.openide.util.Exceptions; import org.openide.util.NbBundle; import org.openide.util.Utilities; import org.sleuthkit.autopsy.casemodule.Case; @@ -44,8 +45,6 @@ import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil; import org.sleuthkit.autopsy.datamodel.ContentUtils; import org.sleuthkit.autopsy.datamodel.ContentUtils.ExtractFscContentVisitor; import org.sleuthkit.datamodel.AbstractFile; -import org.sleuthkit.datamodel.Content; -import org.sleuthkit.datamodel.TskCoreException; /** * Extracts AbstractFiles to a location selected by the user. @@ -66,6 +65,9 @@ public final class ExtractAction extends AbstractAction { return instance; } + /** + * Private constructor for the action. + */ private ExtractAction() { super(NbBundle.getMessage(ExtractAction.class, "ExtractAction.title.extractFiles.text")); } @@ -94,16 +96,16 @@ public final class ExtractAction extends AbstractAction { /** * Called when user has selected a single file to extract * - * @param e + * @param event * @param selectedFile Selected file */ - @NbBundle.Messages ({"ExtractAction.noOpenCase.errMsg=No open case available."}) - private void extractFile(ActionEvent e, AbstractFile selectedFile) { + @NbBundle.Messages({"ExtractAction.noOpenCase.errMsg=No open case available."}) + private void extractFile(ActionEvent event, AbstractFile selectedFile) { Case openCase; try { openCase = Case.getCurrentCaseThrows(); } catch (NoCurrentCaseException ex) { - JOptionPane.showMessageDialog((Component) e.getSource(), Bundle.ExtractAction_noOpenCase_errMsg()); + JOptionPane.showMessageDialog((Component) event.getSource(), Bundle.ExtractAction_noOpenCase_errMsg()); logger.log(Level.INFO, "Exception while getting open case.", ex); //NON-NLS return; } @@ -111,60 +113,70 @@ public final class ExtractAction extends AbstractAction { fileChooser.setCurrentDirectory(new File(openCase.getExportDirectory())); // If there is an attribute name, change the ":". Otherwise the extracted file will be hidden fileChooser.setSelectedFile(new File(FileUtil.escapeFileName(selectedFile.getName()))); - if (fileChooser.showSaveDialog((Component) e.getSource()) == JFileChooser.APPROVE_OPTION) { + if (fileChooser.showSaveDialog((Component) event.getSource()) == JFileChooser.APPROVE_OPTION) { ArrayList fileExtractionTasks = new ArrayList<>(); fileExtractionTasks.add(new FileExtractionTask(selectedFile, fileChooser.getSelectedFile())); - runExtractionTasks(e, fileExtractionTasks); + runExtractionTasks(event, fileExtractionTasks); } } /** * Called when a user has selected multiple files to extract * - * @param e + * @param event * @param selectedFiles Selected files */ - private void extractFiles(ActionEvent e, Collection selectedFiles) { + private void extractFiles(ActionEvent event, Collection selectedFiles) { Case openCase; try { openCase = Case.getCurrentCaseThrows(); } catch (NoCurrentCaseException ex) { - JOptionPane.showMessageDialog((Component) e.getSource(), Bundle.ExtractAction_noOpenCase_errMsg()); + JOptionPane.showMessageDialog((Component) event.getSource(), Bundle.ExtractAction_noOpenCase_errMsg()); logger.log(Level.INFO, "Exception while getting open case.", ex); //NON-NLS return; } JFileChooser folderChooser = new JFileChooser(); folderChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); folderChooser.setCurrentDirectory(new File(openCase.getExportDirectory())); - if (folderChooser.showSaveDialog((Component) e.getSource()) == JFileChooser.APPROVE_OPTION) { + if (folderChooser.showSaveDialog((Component) event.getSource()) == JFileChooser.APPROVE_OPTION) { File destinationFolder = folderChooser.getSelectedFile(); if (!destinationFolder.exists()) { try { destinationFolder.mkdirs(); } catch (Exception ex) { - JOptionPane.showMessageDialog((Component) e.getSource(), NbBundle.getMessage(this.getClass(), + JOptionPane.showMessageDialog((Component) event.getSource(), NbBundle.getMessage(this.getClass(), "ExtractAction.extractFiles.cantCreateFolderErr.msg")); logger.log(Level.INFO, "Unable to create folder(s) for user " + destinationFolder.getAbsolutePath(), ex); //NON-NLS return; } } - /* get the unique set of files from the list. A user once reported extraction taking - * days because it was extracting the same PST file 20k times. They selected 20k - * email messages in the tree and chose to extract them. */ + /* + * get the unique set of files from the list. A user once reported + * extraction taking days because it was extracting the same PST + * file 20k times. They selected 20k email messages in the tree and + * chose to extract them. + */ Set uniqueFiles = new HashSet<>(selectedFiles); - + // make a task for each file ArrayList fileExtractionTasks = new ArrayList<>(); for (AbstractFile source : uniqueFiles) { // If there is an attribute name, change the ":". Otherwise the extracted file will be hidden fileExtractionTasks.add(new FileExtractionTask(source, new File(destinationFolder, source.getId() + "-" + FileUtil.escapeFileName(source.getName())))); } - runExtractionTasks(e, fileExtractionTasks); + runExtractionTasks(event, fileExtractionTasks); } } - private void runExtractionTasks(ActionEvent e, ArrayList fileExtractionTasks) { + /** + * Execute a series of file extraction tasks. + * + * @param event ActionEvent whose source will be used for + * centering popup dialogs. + * @param fileExtractionTasks List of file extraction tasks. + */ + private void runExtractionTasks(ActionEvent event, List fileExtractionTasks) { // verify all of the sources and destinations are OK for (Iterator it = fileExtractionTasks.iterator(); it.hasNext();) { @@ -177,16 +189,16 @@ public final class ExtractAction extends AbstractAction { } /* - * This code assumes that each destination is unique. We previously satisfied - * that by adding the unique ID. + * This code assumes that each destination is unique. We previously + * satisfied that by adding the unique ID. */ if (task.destination.exists()) { - if (JOptionPane.showConfirmDialog((Component) e.getSource(), + if (JOptionPane.showConfirmDialog((Component) event.getSource(), NbBundle.getMessage(this.getClass(), "ExtractAction.confDlg.destFileExist.msg", task.destination.getAbsolutePath()), NbBundle.getMessage(this.getClass(), "ExtractAction.confDlg.destFileExist.title"), JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION) { if (!FileUtil.deleteFileDir(task.destination)) { - JOptionPane.showMessageDialog((Component) e.getSource(), + JOptionPane.showMessageDialog((Component) event.getSource(), NbBundle.getMessage(this.getClass(), "ExtractAction.msgDlg.cantOverwriteFile.msg", task.destination.getAbsolutePath())); it.remove(); } @@ -210,11 +222,20 @@ public final class ExtractAction extends AbstractAction { } } + /** + * Stores source and destination for file extraction. + */ private class FileExtractionTask { AbstractFile source; File destination; + /** + * Create an instance of the FileExtractionTask. + * + * @param source The file to be extracted. + * @param destination The destination for the extraction. + */ FileExtractionTask(AbstractFile source, File destination) { this.source = source; this.destination = destination; @@ -226,11 +247,16 @@ public final class ExtractAction extends AbstractAction { */ private class FileExtracter extends SwingWorker { - private Logger logger = Logger.getLogger(FileExtracter.class.getName()); + private final Logger logger = Logger.getLogger(FileExtracter.class.getName()); private ProgressHandle progress; - private ArrayList extractionTasks; + private final List extractionTasks; - FileExtracter(ArrayList extractionTasks) { + /** + * Create an instance of the FileExtracter. + * + * @param extractionTasks List of file extraction tasks. + */ + FileExtracter(List extractionTasks) { this.extractionTasks = extractionTasks; } @@ -275,7 +301,7 @@ public final class ExtractAction extends AbstractAction { boolean msgDisplayed = false; try { super.get(); - } catch (Exception ex) { + } catch (InterruptedException | ExecutionException ex) { logger.log(Level.SEVERE, "Fatal error during file extraction", ex); //NON-NLS MessageNotifyUtil.Message.info( NbBundle.getMessage(this.getClass(), "ExtractAction.done.notifyMsg.extractErr", ex.getMessage())); @@ -289,22 +315,23 @@ public final class ExtractAction extends AbstractAction { } } - private int calculateProgressBarWorkUnits(AbstractFile file) { - int workUnits = 0; - if (file.isFile()) { - workUnits += file.getSize(); - } else { - try { - for (Content child : file.getChildren()) { - if (child instanceof AbstractFile) { - workUnits += calculateProgressBarWorkUnits((AbstractFile) child); - } - } - } catch (TskCoreException ex) { - logger.log(Level.SEVERE, "Could not get children of content", ex); //NON-NLS - } - } - return workUnits; + /** + * Calculate the number of work units for the progress bar. + * + * @param file File whose children will be reviewed to get the number of + * work units. + * + * @return The number of work units. + */ + /* + * private int calculateProgressBarWorkUnits(AbstractFile file) { int + * workUnits = 0; if (file.isFile()) { workUnits += file.getSize(); } + * else { try { for (Content child : file.getChildren()) { if (child + * instanceof AbstractFile) { workUnits += + * calculateProgressBarWorkUnits((AbstractFile) child); } } } catch + * (TskCoreException ex) { logger.log(Level.SEVERE, "Could not get + * children of content", ex); //NON-NLS } } return workUnits; } + */ } } diff --git a/Core/src/org/sleuthkit/autopsy/directorytree/ExtractUnallocAction.java b/Core/src/org/sleuthkit/autopsy/directorytree/ExtractUnallocAction.java index b0729d24c6..74c7ee1f64 100644 --- a/Core/src/org/sleuthkit/autopsy/directorytree/ExtractUnallocAction.java +++ b/Core/src/org/sleuthkit/autopsy/directorytree/ExtractUnallocAction.java @@ -61,6 +61,7 @@ import org.sleuthkit.datamodel.VolumeSystem; * Extracts all the unallocated space as a single file */ final class ExtractUnallocAction extends AbstractAction { + private static final Logger logger = Logger.getLogger(ExtractUnallocAction.class.getName()); private final List filesToExtract = new ArrayList<>(); @@ -69,19 +70,32 @@ final class ExtractUnallocAction extends AbstractAction { private long currentImage = 0L; private final boolean isImage; - public ExtractUnallocAction(String title, Volume volume){ + /** + * Create an instance of ExtractUnallocAction with a volume. + * + * @param title The title + * @param volume The volume set for extraction. + */ + public ExtractUnallocAction(String title, Volume volume) { super(title); isImage = false; try { OutputFileData outputFileData = new OutputFileData(volume); filesToExtract.add(outputFileData); - } catch (NoCurrentCaseException ex) { + } catch (NoCurrentCaseException ex) { logger.log(Level.SEVERE, "Exception while getting open case.", ex); setEnabled(false); } - + } + /** + * Create an instance of ExtractUnallocAction with an image. + * + * @param title The title. + * @param image The image set for extraction. + * @throws NoCurrentCaseException If no case is open. + */ public ExtractUnallocAction(String title, Image image) throws NoCurrentCaseException { super(title); isImage = true; @@ -101,17 +115,17 @@ final class ExtractUnallocAction extends AbstractAction { * Writes the unallocated files to * $CaseDir/Export/ImgName-Unalloc-ImgObjectID-VolumeID.dat * - * @param e + * @param event */ @NbBundle.Messages({"# {0} - fileName", - "ExtractUnallocAction.volumeInProgress=Already extracting unallocated space into {0} - will skip this volume", - "ExtractUnallocAction.volumeError=Error extracting unallocated space from volume", - "ExtractUnallocAction.noFiles=No unallocated files found on volume", - "ExtractUnallocAction.imageError=Error extracting unallocated space from image", - "ExtractUnallocAction.noOpenCase.errMsg=No open case available."}) + "ExtractUnallocAction.volumeInProgress=Already extracting unallocated space into {0} - will skip this volume", + "ExtractUnallocAction.volumeError=Error extracting unallocated space from volume", + "ExtractUnallocAction.noFiles=No unallocated files found on volume", + "ExtractUnallocAction.imageError=Error extracting unallocated space from image", + "ExtractUnallocAction.noOpenCase.errMsg=No open case available."}) @Override - public void actionPerformed(ActionEvent e) { - if (filesToExtract != null && filesToExtract.size() > 0) { + public void actionPerformed(ActionEvent event) { + if (filesToExtract != null && filesToExtract.isEmpty() == false) { // This check doesn't absolutely guarantee that the image won't be in progress when we make the worker, // but in general it will suffice. if (isImage && isImageInProgress(currentImage)) { @@ -150,15 +164,15 @@ final class ExtractUnallocAction extends AbstractAction { NbBundle.getMessage(this.getClass(), "ExtractUnallocAction.dlgTitle.selectDirToSaveTo.msg")); fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); fileChooser.setAcceptAllFileFilterUsed(false); - int returnValue = fileChooser.showSaveDialog((Component) e.getSource()); + int returnValue = fileChooser.showSaveDialog((Component) event.getSource()); if (returnValue == JFileChooser.APPROVE_OPTION) { String destination = fileChooser.getSelectedFile().getPath(); for (OutputFileData outputFileData : filesToExtract) { outputFileData.setPath(destination); - - if (outputFileData.layoutFiles != null && outputFileData.layoutFiles.size() > 0 && (! isVolumeInProgress(outputFileData.getFileName()))) { + + if (outputFileData.layoutFiles != null && outputFileData.layoutFiles.size() > 0 && (!isVolumeInProgress(outputFileData.getFileName()))) { //Format for single Unalloc File is ImgName-Unalloc-ImgObjectID-VolumeID.dat - + // Check if there is already a file with this name if (outputFileData.fileInstance.exists()) { int res = JOptionPane.showConfirmDialog(new Frame(), NbBundle.getMessage(this.getClass(), @@ -172,22 +186,22 @@ final class ExtractUnallocAction extends AbstractAction { copyList.remove(outputFileData); } } - + if (!isImage & !copyList.isEmpty()) { - try{ + try { ExtractUnallocWorker worker = new ExtractUnallocWorker(outputFileData); worker.execute(); - } catch (Exception ex){ - logger.log(Level.WARNING, "Already extracting unallocated space into " + outputFileData.getFileName()); + } catch (TskCoreException ex) { + logger.log(Level.WARNING, "Already extracting unallocated space into {0}", outputFileData.getFileName()); MessageNotifyUtil.Message.info(NbBundle.getMessage(this.getClass(), "ExtractUnallocAction.volumeInProgress", outputFileData.getFileName())); } } } else { // The output file for this volume could not be created for one of the following reasons - if (outputFileData.layoutFiles == null){ + if (outputFileData.layoutFiles == null) { MessageNotifyUtil.Message.info(NbBundle.getMessage(this.getClass(), "ExtractUnallocAction.volumeError")); logger.log(Level.SEVERE, "Tried to get unallocated content but the list of unallocated files was null"); //NON-NLS - } else if (outputFileData.layoutFiles.isEmpty()){ + } else if (outputFileData.layoutFiles.isEmpty()) { MessageNotifyUtil.Message.info(NbBundle.getMessage(this.getClass(), "ExtractUnallocAction.noFiles")); logger.log(Level.WARNING, "No unallocated files found in volume"); //NON-NLS copyList.remove(outputFileData); @@ -198,16 +212,16 @@ final class ExtractUnallocAction extends AbstractAction { } } } - + // This needs refactoring. The idea seems to be that we'll take advantage of the loop above to // check whether each output file exists but wait until this point to make a worker // to extract everything (the worker in the above loop doesn't get created because isImage is true) // It's also unclear to me why we need the two separate worker types. if (isImage && !copyList.isEmpty()) { - try{ + try { ExtractUnallocWorker worker = new ExtractUnallocWorker(copyList); worker.execute(); - } catch (Exception ex){ + } catch (Exception ex) { logger.log(Level.WARNING, "Error creating ExtractUnallocWorker", ex); MessageNotifyUtil.Message.info(NbBundle.getMessage(this.getClass(), "ExtractUnallocAction.imageError")); } @@ -220,16 +234,16 @@ final class ExtractUnallocAction extends AbstractAction { /** * Gets all the unallocated files in a given Content. * - * @param c Content to get Unallocated Files from + * @param content Content to get Unallocated Files from * * @return A list if it didn't crash List may be empty. */ - private List getUnallocFiles(Content c) { - UnallocVisitor uv = new UnallocVisitor(); + private List getUnallocFiles(Content content) { + UnallocVisitor unallocVisitor = new UnallocVisitor(); try { - for (Content contentChild : c.getChildren()) { + for (Content contentChild : content.getChildren()) { if (contentChild instanceof AbstractContent) { - return contentChild.accept(uv); //call on first non-artifact child added to database + return contentChild.accept(unallocVisitor); //call on first non-artifact child added to database } } } catch (TskCoreException tce) { @@ -237,38 +251,37 @@ final class ExtractUnallocAction extends AbstractAction { } return Collections.emptyList(); } - + synchronized static private void addVolumeInProgress(String volumeOutputFileName) throws TskCoreException { - if(volumesInProgress.contains(volumeOutputFileName)){ + if (volumesInProgress.contains(volumeOutputFileName)) { throw new TskCoreException("Already writing unallocated space to " + volumeOutputFileName); - } + } volumesInProgress.add(volumeOutputFileName); } - - synchronized static private void removeVolumeInProgress(String volumeOutputFileName){ + + synchronized static private void removeVolumeInProgress(String volumeOutputFileName) { volumesInProgress.remove(volumeOutputFileName); } - - synchronized static private boolean isVolumeInProgress(String volumeOutputFileName){ + + synchronized static private boolean isVolumeInProgress(String volumeOutputFileName) { return volumesInProgress.contains(volumeOutputFileName); } - - synchronized static private void addImageInProgress(Long id) throws TskCoreException { - if(imagesInProgress.contains(id)){ - throw new TskCoreException("Image " + id + " is in use"); - } - imagesInProgress.add(id); + + synchronized static private void addImageInProgress(Long objId) throws TskCoreException { + if (imagesInProgress.contains(objId)) { + throw new TskCoreException("Image " + objId + " is in use"); + } + imagesInProgress.add(objId); } - - synchronized static private void removeImageInProgress(Long id){ - imagesInProgress.remove(id); - } - - synchronized static private boolean isImageInProgress(Long id){ - return imagesInProgress.contains(id); + + synchronized static private void removeImageInProgress(Long objId) { + imagesInProgress.remove(objId); } - - + + synchronized static private boolean isImageInProgress(Long objId) { + return imagesInProgress.contains(objId); + } + /** * Private class for dispatching the file IO in a background thread. */ @@ -276,9 +289,9 @@ final class ExtractUnallocAction extends AbstractAction { private ProgressHandle progress; private boolean canceled = false; - private List outputFileDataList = new ArrayList<>(); + private final List outputFileDataList = new ArrayList<>(); private File currentlyProcessing; - private int totalSizeinMegs; + private final int totalSizeinMegs; long totalBytes = 0; ExtractUnallocWorker(OutputFileData outputFileData) throws TskCoreException { @@ -291,32 +304,32 @@ final class ExtractUnallocAction extends AbstractAction { ExtractUnallocWorker(List outputFileDataList) throws TskCoreException { addImageInProgress(currentImage); - + //Getting the total megs this worker is going to be doing for (OutputFileData outputFileData : outputFileDataList) { - try{ + try { // If a volume is locked, skip it but continue trying to process any other requested volumes addVolumeInProgress(outputFileData.getFileName()); totalBytes += outputFileData.getSizeInBytes(); this.outputFileDataList.add(outputFileData); - } catch (TskCoreException ex){ - logger.log(Level.WARNING, "Already extracting data into " + outputFileData.getFileName()); + } catch (TskCoreException ex) { + logger.log(Level.WARNING, "Already extracting data into {0}", outputFileData.getFileName()); } } - + // If we don't have anything to output (because of locking), throw an exception - if(this.outputFileDataList.isEmpty()){ + if (this.outputFileDataList.isEmpty()) { throw new TskCoreException("No unallocated files can be extracted"); } - + totalSizeinMegs = toMb(totalBytes); } private int toMb(long bytes) { if (bytes > 1024 && (bytes / 1024.0) <= Double.MAX_VALUE) { - double Mb = ((bytes / 1024.0) / 1024.0);//Bytes -> Megabytes - if (Mb <= Integer.MAX_VALUE) { - return (int) Math.ceil(Mb); + double megabytes = ((bytes / 1024.0) / 1024.0);//Bytes -> Megabytes + if (megabytes <= Integer.MAX_VALUE) { + return (int) Math.ceil(megabytes); } } return 0; @@ -347,7 +360,7 @@ final class ExtractUnallocAction extends AbstractAction { int mbs = 0; //Increments every 128th tick of kbs for (OutputFileData outputFileData : this.outputFileDataList) { currentlyProcessing = outputFileData.getFile(); - logger.log(Level.INFO, "Writing Unalloc file to " + currentlyProcessing.getPath()); //NON-NLS + logger.log(Level.INFO, "Writing Unalloc file to {0}", currentlyProcessing.getPath()); //NON-NLS OutputStream outputStream = new FileOutputStream(currentlyProcessing); long bytes = 0; int i = 0; @@ -374,9 +387,9 @@ final class ExtractUnallocAction extends AbstractAction { if (canceled) { outputFileData.getFile().delete(); - logger.log(Level.INFO, "Canceled extraction of " + outputFileData.getFileName() + " and deleted file"); //NON-NLS + logger.log(Level.INFO, "Canceled extraction of {0} and deleted file", outputFileData.getFileName()); //NON-NLS } else { - logger.log(Level.INFO, "Finished writing unalloc file " + outputFileData.getFile().getPath()); //NON-NLS + logger.log(Level.INFO, "Finished writing unalloc file {0}", outputFileData.getFile().getPath()); //NON-NLS } } progress.finish(); @@ -589,7 +602,7 @@ final class ExtractUnallocAction extends AbstractAction { */ private class OutputFileData { - private List layoutFiles; + private final List layoutFiles; private final long sizeInBytes; private long volumeId; private long imageId; @@ -601,7 +614,7 @@ final class ExtractUnallocAction extends AbstractAction { * Contingency constructor in event no VolumeSystem exists on an Image. * * @param img Image file to be analyzed - * + * * @throws NoCurrentCaseException if there is no open case. */ OutputFileData(Image img) throws NoCurrentCaseException { @@ -619,7 +632,7 @@ final class ExtractUnallocAction extends AbstractAction { * Default constructor for extracting info from Volumes. * * @param volume Volume file to be analyzed - * + * * @throws NoCurrentCaseException if there is no open case. */ OutputFileData(Volume volume) throws NoCurrentCaseException { From 0c571ab20ece0fb87b29e7ca7539f7ea59bd2e14 Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dgrove" Date: Thu, 2 Aug 2018 15:27:27 -0400 Subject: [PATCH 233/287] Added user-defined path for extraction. --- .../autopsy/directorytree/ExtractAction.java | 66 ++++++++++++++++--- .../directorytree/ExtractUnallocAction.java | 44 ++++++++++++- 2 files changed, 99 insertions(+), 11 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/directorytree/ExtractAction.java b/Core/src/org/sleuthkit/autopsy/directorytree/ExtractAction.java index 2f45e44331..b0b847d1a6 100644 --- a/Core/src/org/sleuthkit/autopsy/directorytree/ExtractAction.java +++ b/Core/src/org/sleuthkit/autopsy/directorytree/ExtractAction.java @@ -33,7 +33,6 @@ import javax.swing.JOptionPane; import javax.swing.SwingWorker; import org.netbeans.api.progress.ProgressHandle; import org.openide.util.Cancellable; -import org.openide.util.Exceptions; import org.openide.util.NbBundle; import org.openide.util.Utilities; import org.sleuthkit.autopsy.casemodule.Case; @@ -54,6 +53,8 @@ public final class ExtractAction extends AbstractAction { private Logger logger = Logger.getLogger(ExtractAction.class.getName()); + private String userDefinedExportPath; + // This class is a singleton to support multi-selection of nodes, since // org.openide.nodes.NodeOp.findActions(Node[] nodes) will only pick up an Action if every // node in the array returns a reference to the same action object from Node.getActions(boolean). @@ -97,7 +98,7 @@ public final class ExtractAction extends AbstractAction { * @param e * @param selectedFile Selected file */ - @NbBundle.Messages ({"ExtractAction.noOpenCase.errMsg=No open case available."}) + @NbBundle.Messages({"ExtractAction.noOpenCase.errMsg=No open case available."}) private void extractFile(ActionEvent e, AbstractFile selectedFile) { Case openCase; try { @@ -108,10 +109,12 @@ public final class ExtractAction extends AbstractAction { return; } JFileChooser fileChooser = new JFileChooser(); - fileChooser.setCurrentDirectory(new File(openCase.getExportDirectory())); + fileChooser.setCurrentDirectory(new File(getExportDirectory(openCase))); // If there is an attribute name, change the ":". Otherwise the extracted file will be hidden fileChooser.setSelectedFile(new File(FileUtil.escapeFileName(selectedFile.getName()))); if (fileChooser.showSaveDialog((Component) e.getSource()) == JFileChooser.APPROVE_OPTION) { + updateExportDirectory(fileChooser.getSelectedFile().getParent(), openCase); + ArrayList fileExtractionTasks = new ArrayList<>(); fileExtractionTasks.add(new FileExtractionTask(selectedFile, fileChooser.getSelectedFile())); runExtractionTasks(e, fileExtractionTasks); @@ -135,7 +138,7 @@ public final class ExtractAction extends AbstractAction { } JFileChooser folderChooser = new JFileChooser(); folderChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); - folderChooser.setCurrentDirectory(new File(openCase.getExportDirectory())); + folderChooser.setCurrentDirectory(new File(getExportDirectory(openCase))); if (folderChooser.showSaveDialog((Component) e.getSource()) == JFileChooser.APPROVE_OPTION) { File destinationFolder = folderChooser.getSelectedFile(); if (!destinationFolder.exists()) { @@ -148,12 +151,16 @@ public final class ExtractAction extends AbstractAction { return; } } + updateExportDirectory(destinationFolder.getPath(), openCase); - /* get the unique set of files from the list. A user once reported extraction taking - * days because it was extracting the same PST file 20k times. They selected 20k - * email messages in the tree and chose to extract them. */ + /* + * get the unique set of files from the list. A user once reported + * extraction taking days because it was extracting the same PST + * file 20k times. They selected 20k email messages in the tree and + * chose to extract them. + */ Set uniqueFiles = new HashSet<>(selectedFiles); - + // make a task for each file ArrayList fileExtractionTasks = new ArrayList<>(); for (AbstractFile source : uniqueFiles) { @@ -164,6 +171,45 @@ public final class ExtractAction extends AbstractAction { } } + /** + * Get the export directory path. + * + * @param openCase The current case. + * + * @return The export directory path. + */ + private String getExportDirectory(Case openCase) { + String caseExportPath = openCase.getExportDirectory(); + + if (userDefinedExportPath == null) { + return caseExportPath; + } + + File file = new File(userDefinedExportPath); + if (file.exists() == false || file.isDirectory() == false) { + return caseExportPath; + } + + return userDefinedExportPath; + } + + /** + * Update the default export directory. If the directory path matches the + * case export directory, then the directory used will always match the + * export directory of any given case. Otherwise, the path last used will be + * saved. + * + * @param exportPath The export path. + * @param openCase The current case. + */ + private void updateExportDirectory(String exportPath, Case openCase) { + if (exportPath.equalsIgnoreCase(openCase.getExportDirectory())) { + userDefinedExportPath = null; + } else { + userDefinedExportPath = exportPath; + } + } + private void runExtractionTasks(ActionEvent e, ArrayList fileExtractionTasks) { // verify all of the sources and destinations are OK @@ -177,8 +223,8 @@ public final class ExtractAction extends AbstractAction { } /* - * This code assumes that each destination is unique. We previously satisfied - * that by adding the unique ID. + * This code assumes that each destination is unique. We previously + * satisfied that by adding the unique ID. */ if (task.destination.exists()) { if (JOptionPane.showConfirmDialog((Component) e.getSource(), diff --git a/Core/src/org/sleuthkit/autopsy/directorytree/ExtractUnallocAction.java b/Core/src/org/sleuthkit/autopsy/directorytree/ExtractUnallocAction.java index b0729d24c6..83fe882e45 100644 --- a/Core/src/org/sleuthkit/autopsy/directorytree/ExtractUnallocAction.java +++ b/Core/src/org/sleuthkit/autopsy/directorytree/ExtractUnallocAction.java @@ -66,6 +66,7 @@ final class ExtractUnallocAction extends AbstractAction { private final List filesToExtract = new ArrayList<>(); private static final Set volumesInProgress = new HashSet<>(); private static final Set imagesInProgress = new HashSet<>(); + private static String userDefinedExportPath; private long currentImage = 0L; private final boolean isImage; @@ -145,7 +146,7 @@ final class ExtractUnallocAction extends AbstractAction { } }; - fileChooser.setCurrentDirectory(new File(openCase.getExportDirectory())); + fileChooser.setCurrentDirectory(new File(getExportDirectory(openCase))); fileChooser.setDialogTitle( NbBundle.getMessage(this.getClass(), "ExtractUnallocAction.dlgTitle.selectDirToSaveTo.msg")); fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); @@ -153,6 +154,9 @@ final class ExtractUnallocAction extends AbstractAction { int returnValue = fileChooser.showSaveDialog((Component) e.getSource()); if (returnValue == JFileChooser.APPROVE_OPTION) { String destination = fileChooser.getSelectedFile().getPath(); + + updateExportDirectory(destination, openCase); + for (OutputFileData outputFileData : filesToExtract) { outputFileData.setPath(destination); @@ -214,7 +218,45 @@ final class ExtractUnallocAction extends AbstractAction { } } } + } + + /** + * Get the export directory path. + * + * @param openCase The current case. + * + * @return The export directory path. + */ + private String getExportDirectory(Case openCase) { + String caseExportPath = openCase.getExportDirectory(); + if (userDefinedExportPath == null) { + return caseExportPath; + } + + File file = new File(userDefinedExportPath); + if (file.exists() == false || file.isDirectory() == false) { + return caseExportPath; + } + + return userDefinedExportPath; + } + + /** + * Update the default export directory. If the directory path matches the + * case export directory, then the directory used will always match the + * export directory of any given case. Otherwise, the path last used will be + * saved. + * + * @param exportPath The export path. + * @param openCase The current case. + */ + private void updateExportDirectory(String exportPath, Case openCase) { + if (exportPath.equalsIgnoreCase(openCase.getExportDirectory())) { + userDefinedExportPath = null; + } else { + userDefinedExportPath = exportPath; + } } /** From 21fc9a67a952300e4b2bd556ce42b175540da706 Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Thu, 2 Aug 2018 16:08:21 -0400 Subject: [PATCH 234/287] 3964 adjust failure messages for zip bomb test to give more context --- .../autopsy/ingest/EmbeddedFileTest.java | 32 ++++++++++--------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/ingest/EmbeddedFileTest.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/ingest/EmbeddedFileTest.java index 7af0a429d8..995aac1818 100755 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/ingest/EmbeddedFileTest.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/ingest/EmbeddedFileTest.java @@ -96,43 +96,45 @@ public class EmbeddedFileTest extends NbTestCase { public void testEncryptionAndZipBomb() { try { - List results = openCase.getSleuthkitCase().findAllFilesWhere("name LIKE '%%'"); - String protectedName1 = "password_protected.zip"; - String protectedName2 = "level1_protected.zip"; - String protectedName3 = "42.zip"; - String depthZipBomb = "DepthTriggerZipBomb.zip"; - String ratioZipBomb = "RatioTriggerZipBomb.zip"; + List results = openCase.getSleuthkitCase().findAllFilesWhere("name LIKE '%%'"); + final String zipBombSetName = "Possible Zip Bomb"; + final String protectedName1 = "password_protected.zip"; + final String protectedName2 = "level1_protected.zip"; + final String protectedName3 = "42.zip"; + final String depthZipBomb = "DepthTriggerZipBomb.zip"; + final String ratioZipBomb = "RatioTriggerZipBomb.zip"; int zipBombs = 0; - assertEquals(2221, results.size()); + assertEquals("The number of files in the test image has changed", 2221, results.size()); int passwdProtectedZips = 0; for (AbstractFile file : results) { //.zip file has artifact TSK_ENCRYPTION_DETECTED if (file.getName().equalsIgnoreCase(protectedName1) || file.getName().equalsIgnoreCase(protectedName2) || file.getName().equalsIgnoreCase(protectedName3)){ ArrayList artifacts = file.getAllArtifacts(); - assertEquals(1, artifacts.size()); + assertEquals("Password protected zip file " + file.getName() + " has incorrect number of artifacts", 1, artifacts.size()); for (BlackboardArtifact artifact : artifacts) { - assertEquals(artifact.getArtifactTypeID(), BlackboardArtifact.ARTIFACT_TYPE.TSK_ENCRYPTION_DETECTED.getTypeID()); + assertEquals("Artifact for password protected zip file " + file.getName() + " has incorrect type ID", artifact.getArtifactTypeID(), BlackboardArtifact.ARTIFACT_TYPE.TSK_ENCRYPTION_DETECTED.getTypeID()); passwdProtectedZips++; } } else if (file.getName().equalsIgnoreCase(depthZipBomb) || file.getName().equalsIgnoreCase(ratioZipBomb)){ ArrayList artifacts = file.getAllArtifacts(); - assertEquals(1, artifacts.size()); + assertEquals("Zip bomb " + file.getName() + " has incorrect number of artifacts", 1, artifacts.size()); for (BlackboardArtifact artifact : artifacts) { - assertEquals(artifact.getArtifactTypeID(), BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT.getTypeID()); + assertEquals("Artifact for Zip bomb " + file.getName() + " has incorrect type ID", artifact.getArtifactTypeID(), BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT.getTypeID()); BlackboardAttribute attribute = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME)); - assertNotNull("Possible Zip Bomb", attribute); + assertNotNull("No attribute found for artifact on zip bomb " + file.getName(), attribute); + assertEquals("Interesting artifact on file, " + file.getName() + ", does not reflect it being a zip bomb", zipBombSetName, attribute.getDisplayString()); zipBombs++; } } else {//No other files have artifact defined - assertEquals(0, file.getAllArtifacts().size()); + assertEquals("Unexpected file, " + file.getName() + ", has artifacts", 0, file.getAllArtifacts().size()); } } //Make sure 3 password protected zip files have been tested: password_protected.zip, level1_protected.zip and 42.zip that we download for bomb testing. - assertEquals(3, passwdProtectedZips); + assertEquals("Unexpected number of artifacts reflecting password protected zip files found", 3, passwdProtectedZips); //Make sure 2 zip bomb files have been tested: DepthTriggerZipBomb.zip and RatioTriggerZipBomb.zip. - assertEquals(2, zipBombs); + assertEquals("Unexpected number of artifacts reflecting zip bombs found", 2, zipBombs); } catch (TskCoreException ex) { Exceptions.printStackTrace(ex); Assert.fail(ex); From f5ac4a8635595bf97b7db08633af41dcea99e3e8 Mon Sep 17 00:00:00 2001 From: rishwanth1995 Date: Thu, 2 Aug 2018 16:24:12 -0400 Subject: [PATCH 235/287] live autopsy folder warning --- .../autopsy/casemodule/Bundle.properties | 2 + .../casemodule/NewCaseVisualPanel1.java | 11 ++++- .../autopsy/core/AutopsyOptionProcessor.java | 48 +++++++++++++++++++ .../autopsy/core/RuntimeProperties.java | 15 ++++++ .../autopsy/coreutils/PathValidator.java | 14 ++++-- .../CreateLiveTriageDriveAction.java | 2 +- 6 files changed, 87 insertions(+), 5 deletions(-) create mode 100644 Core/src/org/sleuthkit/autopsy/core/AutopsyOptionProcessor.java diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/Bundle.properties b/Core/src/org/sleuthkit/autopsy/casemodule/Bundle.properties index 9c04508c1f..aa8efe676d 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/casemodule/Bundle.properties @@ -147,6 +147,8 @@ UpdateRecentCases.menuItem.clearRecentCases.text=Clear Recent Cases UpdateRecentCases.menuItem.empty=-Empty- AddImageWizardIngestConfigPanel.CANCEL_BUTTON.text=Cancel NewCaseVisualPanel1.CaseFolderOnCDriveError.text=Warning: Path to multi-user case folder is on \"C:\" drive +NewCaseVisualPanel1.CaseFolderOnInternalDriveWindowsError.text=Warning Path to case folder is on \"C:\" drive. Create case folder in external drive +NewCaseVisualPanel1.CaseFolderOnInternalDriveLinuxError.text=Warning Path to case folder is not in /media or /mnt drive. Create folder in external drive CollaborationMonitor.addingDataSourceStatus.msg={0} adding data source CollaborationMonitor.analyzingDataSourceStatus.msg={0} analyzing {1} MissingImageDialog.lbWarning.text= diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/NewCaseVisualPanel1.java b/Core/src/org/sleuthkit/autopsy/casemodule/NewCaseVisualPanel1.java index 6959883de1..2257573cb7 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/NewCaseVisualPanel1.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/NewCaseVisualPanel1.java @@ -29,6 +29,7 @@ import javax.swing.event.DocumentListener; import org.sleuthkit.autopsy.casemodule.Case.CaseType; import org.sleuthkit.autopsy.core.UserPreferences; import org.sleuthkit.autopsy.coreutils.PathValidator; +import org.sleuthkit.autopsy.coreutils.PlatformUtil; /** * The JPanel for the first page of the new case wizard. @@ -156,9 +157,17 @@ final class NewCaseVisualPanel1 extends JPanel implements DocumentListener { caseParentDirWarningLabel.setText(NbBundle.getMessage(this.getClass(), "NewCaseVisualPanel1.CaseFolderOnCDriveError.text")); } + /** + * Check the base case directory if it can persist data and show a + * warning if it is a wrong choice + */ if(!PathValidator.isCasedataPersistable(parentDir)){ caseParentDirWarningLabel.setVisible(true); - caseParentDirWarningLabel.setText("Please make the case directory in a mounted drive to save case progress"); + if(PlatformUtil.isWindowsOS()){ + caseParentDirWarningLabel.setText(NbBundle.getMessage(this.getClass(), "NewCaseVisualPanel1.CaseFolderOnInternalDriveWindowsError.text" )); + } else if(System.getProperty("os.name").toLowerCase().contains("nux")) { + caseParentDirWarningLabel.setText(NbBundle.getMessage(this.getClass(), "NewCaseVisualPanel1.CaseFolderOnInternalDriveLinuxError.text")); + } } /** diff --git a/Core/src/org/sleuthkit/autopsy/core/AutopsyOptionProcessor.java b/Core/src/org/sleuthkit/autopsy/core/AutopsyOptionProcessor.java new file mode 100644 index 0000000000..20882da110 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/core/AutopsyOptionProcessor.java @@ -0,0 +1,48 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package org.sleuthkit.autopsy.core; + +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.logging.Level; +import java.util.logging.Logger; +import org.netbeans.api.sendopts.CommandException; +import org.netbeans.spi.sendopts.Env; +import org.netbeans.spi.sendopts.Option; +import org.netbeans.spi.sendopts.OptionProcessor; +import org.openide.util.lookup.ServiceProvider; + +/** + * This class can be used to add command line options to Autopsy + * + */ +@ServiceProvider(service=OptionProcessor.class) +public class AutopsyOptionProcessor extends OptionProcessor { + + private static final Logger logger = Logger.getLogger(AutopsyOptionProcessor.class.getName()); + private final Option liveAutopsyOption = Option.withoutArgument('l', "liveAutopsy"); + + + @Override + protected Set