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.

This commit is contained in:
Andrew Ziehl 2018-06-01 10:01:33 -07:00
parent 4c529e2973
commit c78662885c
4 changed files with 70 additions and 64 deletions

View File

@ -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<CorrelationAttributeCommonInstance> getArtifactInstancesByCaseValues(CorrelationCase correlationCase, Collection<String> values) throws EamDbException {
public List<CorrelationAttributeCommonInstance> getArtifactInstancesByCaseValues(CorrelationCase correlationCase, Collection<String> 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<String>();
}
Connection conn = connect();
List<CorrelationAttributeCommonInstance> 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

View File

@ -233,7 +233,7 @@ public interface EamDb {
*
* @return List of artifact instances for a given list of MD5 values
*/
List<CorrelationAttributeCommonInstance> getArtifactInstancesByCaseValues(CorrelationCase correlationCase, Collection<String> values) throws EamDbException;
List<CorrelationAttributeCommonInstance> getArtifactInstancesByCaseValues(CorrelationCase correlationCase, Collection<String> values, int currentCaseId) throws EamDbException;
/**
* Retrieves eamArtifact instances from the database that are associated

View File

@ -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<CorrelationAttributeCommonInstance> getArtifactInstancesByCaseValues(CorrelationCase correlationCase, Collection<String> values) throws EamDbException {
public List<CorrelationAttributeCommonInstance> getArtifactInstancesByCaseValues(CorrelationCase correlationCase, Collection<String> values, int currentCaseId) throws EamDbException {
try {
acquireSharedLock();
return super.getArtifactInstancesByCaseValues(correlationCase, values);
return super.getArtifactInstancesByCaseValues(correlationCase, values, currentCaseId);
} finally {
releaseSharedLock();
}

View File

@ -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<String, Md5Metadata> currentCaseMetadata = getMetadataForCurrentCase();
Collection<String> values = currentCaseMetadata.keySet();
int currentCaseId;
Map<String, Md5Metadata> interCaseCommonFiles = new HashMap<>();
try {
Collection<CorrelationAttributeCommonInstance> artifactInstances = dbManager.getArtifactInstancesByCaseValues(correlationCase, values).stream()
// Need to include current Cases results for specific case comparison
currentCaseId = dbManager.getCase(Case.getCurrentCase()).getID();
Collection<CorrelationAttributeCommonInstance> 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<String, Md5Metadata> gatherIntercaseResults(Collection<CorrelationAttributeCommonInstance> artifactInstances, Map<String, Md5Metadata> commonFiles) {
Map<String, Md5Metadata> interCaseCommonFiles = new HashMap<String, Md5Metadata>();
Map<String, Md5Metadata> interCaseCommonFiles = new HashMap<>();
for (CorrelationAttributeCommonInstance instance : artifactInstances) {