Merge pull request #4880 from wschaeferB/5019-PopulateOccurrencesColumn

5019 populate occurrences column
This commit is contained in:
Richard Cordovano 2019-06-12 15:36:21 -04:00 committed by GitHub
commit dd529b0def
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 56 additions and 26 deletions

View File

@ -396,15 +396,15 @@ public abstract class AbstractAbstractFileNode<T extends AbstractFile> extends A
"# {0} - occurenceCount", "# {0} - occurenceCount",
"AbstractAbstractFileNode.createSheet.count.description=There were {0} datasource(s) found with occurences of the MD5 correlation value"}) "AbstractAbstractFileNode.createSheet.count.description=There were {0} datasource(s) found with occurences of the MD5 correlation value"})
@Override @Override
protected Pair<Long, String> getCountPropertyAndDescription(CorrelationAttributeInstance attribute, String defaultDescription) { protected Pair<Long, String> getCountPropertyAndDescription(CorrelationAttributeInstance.Type attributeType, String attributeValue, String defaultDescription) {
Long count = -1L; //The column renderer will not display negative values, negative value used when count unavailble to preserve sorting Long count = -1L; //The column renderer will not display negative values, negative value used when count unavailble to preserve sorting
String description = defaultDescription; String description = defaultDescription;
try { try {
//don't perform the query if there is no correlation value //don't perform the query if there is no correlation value
if (attribute != null && StringUtils.isNotBlank(attribute.getCorrelationValue())) { if (attributeType != null && StringUtils.isNotBlank(attributeValue)) {
count = EamDb.getInstance().getCountUniqueCaseDataSourceTuplesHavingTypeValue(attribute.getCorrelationType(), attribute.getCorrelationValue()); count = EamDb.getInstance().getCountUniqueCaseDataSourceTuplesHavingTypeValue(attributeType, attributeValue);
description = Bundle.AbstractAbstractFileNode_createSheet_count_description(count); description = Bundle.AbstractAbstractFileNode_createSheet_count_description(count);
} else if (attribute != null) { } else if (attributeType != null) {
description = Bundle.AbstractAbstractFileNode_createSheet_count_hashLookupNotRun_description(); description = Bundle.AbstractAbstractFileNode_createSheet_count_hashLookupNotRun_description();
} }
} catch (EamDbException ex) { } catch (EamDbException ex) {

View File

@ -35,6 +35,7 @@ import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance; import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance;
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance.Type;
import org.sleuthkit.autopsy.corecomponents.DataResultViewerTable; import org.sleuthkit.autopsy.corecomponents.DataResultViewerTable;
import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE; import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE;
@ -353,11 +354,12 @@ public abstract class AbstractContentNode<T extends Content> extends ContentNode
/** /**
* Returns occurrences/count property for the node. * Returns occurrences/count property for the node.
* *
* @param attribute correlation attribute instance * @param attributeType the type of the attribute to count
* @param attributeValue the value of the attribute to count
* @param defaultDescription a description to use when none is determined by * @param defaultDescription a description to use when none is determined by
* the getCountPropertyAndDescription method * the getCountPropertyAndDescription method
* *
* @return count property for the underlying content of the node. * @return count property for the underlying content of the node.
*/ */
abstract protected Pair<Long, String> getCountPropertyAndDescription(CorrelationAttributeInstance attribute, String defaultDescription); abstract protected Pair<Long, String> getCountPropertyAndDescription(Type attributeType, String attributeValue, String defaultDescription);
} }

View File

@ -52,6 +52,7 @@ import org.sleuthkit.autopsy.casemodule.events.CommentChangedEvent;
import org.sleuthkit.autopsy.casemodule.events.ContentTagAddedEvent; import org.sleuthkit.autopsy.casemodule.events.ContentTagAddedEvent;
import org.sleuthkit.autopsy.casemodule.events.ContentTagDeletedEvent; import org.sleuthkit.autopsy.casemodule.events.ContentTagDeletedEvent;
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance; import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance;
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance.Type;
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeNormalizationException; import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeNormalizationException;
import org.sleuthkit.autopsy.centralrepository.datamodel.EamArtifactUtil; import org.sleuthkit.autopsy.centralrepository.datamodel.EamArtifactUtil;
import org.sleuthkit.autopsy.centralrepository.datamodel.EamDb; import org.sleuthkit.autopsy.centralrepository.datamodel.EamDb;
@ -751,7 +752,7 @@ public class BlackboardArtifactNode extends AbstractContentNode<BlackboardArtifa
"BlackboardArtifactNode.createSheet.count.description=There were {0} datasource(s) found with occurrences of the correlation value of type {1}"}) "BlackboardArtifactNode.createSheet.count.description=There were {0} datasource(s) found with occurrences of the correlation value of type {1}"})
@Deprecated @Deprecated
protected final void addCountProperty(Sheet.Set sheetSet, CorrelationAttributeInstance attribute) { protected final void addCountProperty(Sheet.Set sheetSet, CorrelationAttributeInstance attribute) {
Pair<Long, String> countAndDescription = getCountPropertyAndDescription(attribute, Bundle.BlackboardArtifactNode_createSheet_count_noCorrelationAttributes_description()); Pair<Long, String> countAndDescription = getCountPropertyAndDescription(attribute.getCorrelationType(), attribute.getCorrelationValue(), Bundle.BlackboardArtifactNode_createSheet_count_noCorrelationAttributes_description());
sheetSet.put( sheetSet.put(
new NodeProperty<>(Bundle.BlackboardArtifactNode_createSheet_count_name(), Bundle.BlackboardArtifactNode_createSheet_count_displayName(), countAndDescription.getRight(), countAndDescription.getLeft())); new NodeProperty<>(Bundle.BlackboardArtifactNode_createSheet_count_name(), Bundle.BlackboardArtifactNode_createSheet_count_displayName(), countAndDescription.getRight(), countAndDescription.getLeft()));
} }
@ -759,22 +760,24 @@ public class BlackboardArtifactNode extends AbstractContentNode<BlackboardArtifa
/** /**
* Gets the Occurrences property for the node. * Gets the Occurrences property for the node.
* *
* @param attribute correlation attribute instance * @param attributeType the type of the attribute to count
* @param defaultDescription * @param attributeValue the value of the attribute to count
* @param defaultDescription a description to use when none is determined by
* the getCountPropertyAndDescription method
* *
* @return count and description * @return count and description
* *
*/ */
@Override @Override
protected Pair<Long, String> getCountPropertyAndDescription(CorrelationAttributeInstance attribute, String defaultDescription) { protected Pair<Long, String> getCountPropertyAndDescription(Type attributeType, String attributeValue, String defaultDescription) {
Long count = -1L; Long count = -1L;
String description = defaultDescription; String description = defaultDescription;
try { try {
//don't perform the query if there is no correlation value //don't perform the query if there is no correlation value
if (attribute != null && StringUtils.isNotBlank(attribute.getCorrelationValue())) { if (attributeType != null && StringUtils.isNotBlank(attributeValue)) {
count = EamDb.getInstance().getCountUniqueCaseDataSourceTuplesHavingTypeValue(attribute.getCorrelationType(), attribute.getCorrelationValue()); count = EamDb.getInstance().getCountUniqueCaseDataSourceTuplesHavingTypeValue(attributeType, attributeValue);
description = Bundle.BlackboardArtifactNode_createSheet_count_description(count, attribute.getCorrelationType().getDisplayName()); description = Bundle.BlackboardArtifactNode_createSheet_count_description(count, attributeType.getDisplayName());
} else if (attribute != null) { } else if (attributeType != null) {
description = Bundle.BlackboardArtifactNode_createSheet_count_noCorrelationValues_description(); description = Bundle.BlackboardArtifactNode_createSheet_count_noCorrelationValues_description();
} }
} catch (EamDbException ex) { } catch (EamDbException ex) {

View File

@ -22,13 +22,19 @@ import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener; import java.beans.PropertyChangeListener;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
import java.util.List; import java.util.List;
import java.util.logging.Level;
import org.openide.util.NbBundle.Messages; import org.openide.util.NbBundle.Messages;
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance; import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance;
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance.Type;
import org.sleuthkit.autopsy.centralrepository.datamodel.EamArtifactUtil; import org.sleuthkit.autopsy.centralrepository.datamodel.EamArtifactUtil;
import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException;
import org.sleuthkit.autopsy.core.UserPreferences; import org.sleuthkit.autopsy.core.UserPreferences;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.events.AutopsyEvent; import org.sleuthkit.autopsy.events.AutopsyEvent;
import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.Tag; import org.sleuthkit.datamodel.Tag;
import org.sleuthkit.datamodel.TskCoreException;
/** /**
* Background task to get Score, Comment and Occurrences values for an Abstract * Background task to get Score, Comment and Occurrences values for an Abstract
@ -39,6 +45,7 @@ class GetSCOTask implements Runnable {
private final WeakReference<AbstractContentNode<?>> weakNodeRef; private final WeakReference<AbstractContentNode<?>> weakNodeRef;
private final PropertyChangeListener listener; private final PropertyChangeListener listener;
private static final Logger logger = Logger.getLogger(GetSCOTask.class.getName());
GetSCOTask(WeakReference<AbstractContentNode<?>> weakContentRef, PropertyChangeListener listener) { GetSCOTask(WeakReference<AbstractContentNode<?>> weakContentRef, PropertyChangeListener listener) {
this.weakNodeRef = weakContentRef; this.weakNodeRef = weakContentRef;
@ -63,8 +70,10 @@ class GetSCOTask implements Runnable {
SCOData scoData = new SCOData(); SCOData scoData = new SCOData();
scoData.setScoreAndDescription(contentNode.getScorePropertyAndDescription(tags)); scoData.setScoreAndDescription(contentNode.getScorePropertyAndDescription(tags));
scoData.setComment(contentNode.getCommentProperty(tags, fileAttribute)); scoData.setComment(contentNode.getCommentProperty(tags, fileAttribute));
if (!UserPreferences.hideCentralRepoCommentsAndOccurrences()) { if (!UserPreferences.hideCentralRepoCommentsAndOccurrences()) {
CorrelationAttributeInstance occurrencesAttribute = null; Type type = null;
String value = null;
String description = Bundle.GetSCOTask_occurrences_defaultDescription(); String description = Bundle.GetSCOTask_occurrences_defaultDescription();
if (contentNode instanceof BlackboardArtifactNode) { if (contentNode instanceof BlackboardArtifactNode) {
BlackboardArtifact bbArtifact = ((BlackboardArtifactNode) contentNode).getArtifact(); BlackboardArtifact bbArtifact = ((BlackboardArtifactNode) contentNode).getArtifact();
@ -77,7 +86,14 @@ class GetSCOTask implements Runnable {
|| bbArtifact.getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_OBJECT_DETECTED.getTypeID() || bbArtifact.getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_OBJECT_DETECTED.getTypeID()
|| bbArtifact.getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_EXT_MISMATCH_DETECTED.getTypeID() || bbArtifact.getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_EXT_MISMATCH_DETECTED.getTypeID()
|| bbArtifact.getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_HASHSET_HIT.getTypeID()) { || bbArtifact.getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_HASHSET_HIT.getTypeID()) {
occurrencesAttribute = fileAttribute; try {
if (bbArtifact.getParent() instanceof AbstractFile) {
type = CorrelationAttributeInstance.getDefaultCorrelationTypes().get(CorrelationAttributeInstance.FILES_TYPE_ID);
value = ((AbstractFile) bbArtifact.getParent()).getMd5Hash();
}
} catch (TskCoreException | EamDbException ex) {
logger.log(Level.WARNING, "Unable to get correlation type or value to determine value for O column for artifact", ex);
}
} else { } else {
List<CorrelationAttributeInstance> listOfPossibleAttributes = EamArtifactUtil.makeInstancesFromBlackboardArtifact(bbArtifact, false); List<CorrelationAttributeInstance> listOfPossibleAttributes = EamArtifactUtil.makeInstancesFromBlackboardArtifact(bbArtifact, false);
if (listOfPossibleAttributes.size() > 1) { if (listOfPossibleAttributes.size() > 1) {
@ -85,18 +101,25 @@ class GetSCOTask implements Runnable {
description = Bundle.GetSCOTask_occurrences_multipleProperties(); description = Bundle.GetSCOTask_occurrences_multipleProperties();
} else if (!listOfPossibleAttributes.isEmpty()) { } else if (!listOfPossibleAttributes.isEmpty()) {
//there should only be one item in the list //there should only be one item in the list
occurrencesAttribute = listOfPossibleAttributes.get(0); type = listOfPossibleAttributes.get(0).getCorrelationType();
value = listOfPossibleAttributes.get(0).getCorrelationValue();
} }
} }
} else { } else if (contentNode.getContent() instanceof AbstractFile) {
//use the file instance correlation attribute if the node is not a BlackboardArtifactNode //use the file instance correlation attribute if the node is not a BlackboardArtifactNode
occurrencesAttribute = fileAttribute; try {
type = CorrelationAttributeInstance.getDefaultCorrelationTypes().get(CorrelationAttributeInstance.FILES_TYPE_ID);
value = ((AbstractFile) contentNode.getContent()).getMd5Hash();
} catch (EamDbException ex) {
logger.log(Level.WARNING, "Unable to get correlation type to determine value for O column for file", ex);
}
} }
scoData.setCountAndDescription(contentNode.getCountPropertyAndDescription(occurrencesAttribute, description)); scoData.setCountAndDescription(contentNode.getCountPropertyAndDescription(type, value, description));
} }
// signal SCO data is available. // signal SCO data is available.
if (listener != null) { if (listener
!= null) {
listener.propertyChange(new PropertyChangeEvent( listener.propertyChange(new PropertyChangeEvent(
AutopsyEvent.SourceType.LOCAL.toString(), AutopsyEvent.SourceType.LOCAL.toString(),
AbstractAbstractFileNode.NodeSpecificEvents.SCO_AVAILABLE.toString(), AbstractAbstractFileNode.NodeSpecificEvents.SCO_AVAILABLE.toString(),

View File

@ -314,14 +314,15 @@ public class ImageNode extends AbstractContentNode<Image> {
* *
* Null implementation of an abstract method. * Null implementation of an abstract method.
* *
* @param attribute correlation attribute instance * @param attributeType the type of the attribute to count
* @param attributeValue the value of the attribute to coun
* @param defaultDescription a description to use when none is determined by * @param defaultDescription a description to use when none is determined by
* the getCountPropertyAndDescription method * the getCountPropertyAndDescription method
* *
* @return count property for the underlying content of the node. * @return count property for the underlying content of the node.
*/ */
@Override @Override
protected Pair<Long, String> getCountPropertyAndDescription(CorrelationAttributeInstance attribute, String defaultDescription) { protected Pair<Long, String> getCountPropertyAndDescription(CorrelationAttributeInstance.Type attributeType, String attributeValue, String defaultDescription) {
return Pair.of(-1L, NO_DESCR); return Pair.of(-1L, NO_DESCR);
} }
} }

View File

@ -279,14 +279,15 @@ public class VolumeNode extends AbstractContentNode<Volume> {
* *
* Null implementation of an abstract method. * Null implementation of an abstract method.
* *
* @param attribute correlation attribute instance * @param attributeType the type of the attribute to count
* @param attributeValue the value of the attribute to coun
* @param defaultDescription a description to use when none is determined by * @param defaultDescription a description to use when none is determined by
* the getCountPropertyAndDescription method * the getCountPropertyAndDescription method
* *
* @return count property for the underlying content of the node. * @return count property for the underlying content of the node.
*/ */
@Override @Override
protected Pair<Long, String> getCountPropertyAndDescription(CorrelationAttributeInstance attribute, String defaultDescription) { protected Pair<Long, String> getCountPropertyAndDescription(CorrelationAttributeInstance.Type attributeType, String attributeValue, String defaultDescription) {
return Pair.of(-1L, NO_DESCR); return Pair.of(-1L, NO_DESCR);
} }
} }