diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllCommonFiles.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllCommonFiles.java new file mode 100644 index 0000000000..9175e80837 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllCommonFiles.java @@ -0,0 +1,41 @@ +/* + * + * 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 org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; +import org.sleuthkit.datamodel.TskCoreException; + +/** + * Constructs a CommonFilesMetaData for all DataSources in the case. + */ +public class AllCommonFiles extends CommonFilesMetaData { + + AllCommonFiles() throws TskCoreException, SQLException, NoCurrentCaseException{ + super(); + } + + private final String whereClause = "md5 in (select md5 from tsk_files where (known != 1 OR known IS NULL) GROUP BY md5 HAVING COUNT(*) > 1) order by md5"; + + @Override + protected String getSqlWhereClause() { + return this.whereClause; + } +} diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/Bundle.properties b/Core/src/org/sleuthkit/autopsy/commonfilesearch/Bundle.properties index 008339c8e0..a92b778132 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/Bundle.properties @@ -1 +1,3 @@ -CommonFilesPanel.searchButton.text=Search \ No newline at end of file +CommonFilesPanel.searchButton.text=Search +CommonFilesPanel.withinDataSourceRadioButton.text=Within a Data Source +CommonFilesPanel.allDataSourcesRadioButton.text=Across All Data Sources \ No newline at end of file diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesMetaData.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesMetaData.java index ded94e0668..ff6c4cd418 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesMetaData.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesMetaData.java @@ -33,10 +33,11 @@ import org.sleuthkit.datamodel.SleuthkitCase; import org.sleuthkit.datamodel.TskCoreException; /** - * Utility and wrapper around data required for Common Files Search results + * Utility and wrapper around data required for Common Files Search results. + * Subclass this to implement different selections of files from the case. */ -public class CommonFilesMetaData { - +abstract class CommonFilesMetaData { + private final Map> parentNodes; private final Map dataSourceIdToNameMap; @@ -48,12 +49,10 @@ public class CommonFilesMetaData { this.sleuthkitCase = Case.getOpenCase().getSleuthkitCase(); - this.loadDataSourcesMap(); - - this.collateFiles(); - + this.loadDataSourcesMap(); } + //TODO chopping block - this will be passed in through the constructor eventually private void loadDataSourcesMap() throws SQLException, TskCoreException { try ( @@ -68,15 +67,22 @@ public class CommonFilesMetaData { } } - public Map> getFilesMap() { + Map> getFilesMap() { return Collections.unmodifiableMap(this.parentNodes); } - public Map getDataSourceIdToNameMap() { + Map getDataSourceIdToNameMap() { return Collections.unmodifiableMap(dataSourceIdToNameMap); } - private void collateFiles() throws TskCoreException { + /** + * Sorts files in selection into a parent/child hierarchy where actual files + * are nested beneath a parent node which represents the common match. + * + * @return returns a reference to itself for ease of use. + * @throws TskCoreException + */ + CommonFilesMetaData collateFiles() throws TskCoreException { List files = this.sleuthkitCase.findAllFilesWhere(getSqlWhereClause()); @@ -100,14 +106,26 @@ public class CommonFilesMetaData { children.add(file); } } + + return this; } - //TODO subclass this type and make this abstract - protected String getSqlWhereClause() { - return "md5 in (select md5 from tsk_files where (known != 1 OR known IS NULL) GROUP BY md5 HAVING COUNT(*) > 1) order by md5"; - } + /** + * Implement this in order to specify which files are selected into this + * CommonFilesMetaData and passed along to the view. + * + * No SQL-side de-duping should be performed. Results should be ordered by MD5. + * + * @return a SQL WHERE clause to be used in common files selection + */ + protected abstract String getSqlWhereClause(); - public List getChildrenForFile(AbstractFile t) { + /** + * + * @param t + * @return + */ + List getChildrenForFile(AbstractFile t) { return this.parentNodes.get(t); } } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.form b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.form index 9b548bd529..c49e4ee07f 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.form +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.form @@ -33,7 +33,7 @@ - + diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java index 97f78ced18..fefc494a84 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonFilesPanel.java @@ -19,7 +19,10 @@ package org.sleuthkit.autopsy.commonfilesearch; import java.awt.event.ActionListener; +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; @@ -29,6 +32,7 @@ import javax.swing.SwingWorker; import javax.swing.event.ListDataListener; import org.openide.util.NbBundle; import org.openide.windows.TopComponent; +import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; import org.sleuthkit.autopsy.corecomponents.DataResultTopComponent; import org.sleuthkit.autopsy.corecomponents.TableFilterNode; @@ -36,6 +40,8 @@ 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; /** @@ -129,9 +135,6 @@ public final class CommonFilesPanel extends javax.swing.JPanel { @SuppressWarnings("FinallyDiscardsException") protected CommonFilesMetaData doInBackground() throws TskCoreException, NoCurrentCaseException, SQLException { - /*Case currentCase = Case.getOpenCase(); - SleuthkitCase tskDb = currentCase.getSleuthkitCase(); - if(singleDataSource) { Long selectedObjId = 0L; for (Entry dataSource : dataSourceMap.entrySet()) { @@ -140,10 +143,10 @@ public final class CommonFilesPanel extends javax.swing.JPanel { break; } } - return tskDb.findAllFilesWhere("md5 in (select md5 from tsk_files where data_source_obj_id="+ selectedObjId +" and (known != 1 OR known IS NULL) GROUP BY md5 HAVING COUNT(*) > 1) AND data_source_obj_id="+ selectedObjId +" order by md5"); - } - return tskDb.findAllFilesWhere("md5 in (select md5 from tsk_files where (known != 1 OR known IS NULL) GROUP BY md5 HAVING COUNT(*) > 1) order by md5");*/ - return new CommonFilesMetaData(); + return new SingleDataSourceCommonFiles(selectedObjId).collateFiles(); + } else { + return new AllCommonFiles().collateFiles(); + } } @Override diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/SingleDataSourceCommonFiles.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/SingleDataSourceCommonFiles.java new file mode 100644 index 0000000000..31b7b67967 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/SingleDataSourceCommonFiles.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.sql.SQLException; +import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; +import org.sleuthkit.datamodel.TskCoreException; + +/** + * Constructs CommonFilesMetaData for files within the given DataSource. + */ +public class SingleDataSourceCommonFiles extends CommonFilesMetaData { + + private final String whereClause; + + SingleDataSourceCommonFiles(long dataSourceId) throws TskCoreException, SQLException, NoCurrentCaseException{ + super(); + + Object[] args = new String[] {Long.toString(dataSourceId), Long.toString(dataSourceId)}; + this.whereClause = String.format( + "md5 in (select md5 from tsk_files where data_source_obj_id=%s and (known != 1 OR known IS NULL) GROUP BY md5 HAVING COUNT(*) > 1) AND data_source_obj_id=%s order by md5", + args); + } + + @Override + protected String getSqlWhereClause() { + return this.whereClause; + } +}