Merge pull request #6994 from gdicristofaro/7591-aggregateScoreResultsTable

7591 aggregate score results table
This commit is contained in:
Richard Cordovano 2021-05-27 14:12:16 -04:00 committed by GitHub
commit 6329b402a7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 162 additions and 327 deletions

View File

@ -87,6 +87,7 @@ import org.sleuthkit.autopsy.datamodel.BaseChildFactory;
import org.sleuthkit.autopsy.datamodel.BaseChildFactory.PageChangeEvent; import org.sleuthkit.autopsy.datamodel.BaseChildFactory.PageChangeEvent;
import org.sleuthkit.autopsy.datamodel.BaseChildFactory.PageCountChangeEvent; import org.sleuthkit.autopsy.datamodel.BaseChildFactory.PageCountChangeEvent;
import org.sleuthkit.autopsy.datamodel.BaseChildFactory.PageSizeChangeEvent; import org.sleuthkit.autopsy.datamodel.BaseChildFactory.PageSizeChangeEvent;
import org.sleuthkit.datamodel.Score.Significance;
/** /**
* A tabular result viewer that displays the children of the given root node * A tabular result viewer that displays the children of the given root node
@ -1263,6 +1264,29 @@ public class DataResultViewerTable extends AbstractDataResultViewer {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
/**
* Returns the icon denoted by the Score's Significance.
* @param significance The Score's Significance.
* @return The icon (or null) related to that significance.
*/
private ImageIcon getIcon(Significance significance) {
if (significance == null) {
return null;
}
switch (significance) {
case NOTABLE:
return NOTABLE_ICON_SCORE;
case LIKELY_NOTABLE:
return INTERESTING_SCORE_ICON;
case LIKELY_NONE:
case NONE:
case UNKNOWN:
default:
return null;
}
}
@Override @Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
Component component = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); Component component = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
@ -1283,19 +1307,8 @@ public class DataResultViewerTable extends AbstractDataResultViewer {
switchValue = value; switchValue = value;
} }
setText(""); setText("");
if ((switchValue instanceof Score)) { if ((switchValue instanceof org.sleuthkit.datamodel.Score)) {
setIcon(getIcon(((org.sleuthkit.datamodel.Score) switchValue).getSignificance()));
switch ((Score) switchValue) {
case INTERESTING_SCORE:
setIcon(INTERESTING_SCORE_ICON);
break;
case NOTABLE_SCORE:
setIcon(NOTABLE_ICON_SCORE);
break;
case NO_SCORE:
default:
setIcon(null);
}
} else { } else {
setIcon(null); setIcon(null);
} }

View File

@ -46,7 +46,6 @@ import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoException;
import org.sleuthkit.autopsy.core.UserPreferences; import org.sleuthkit.autopsy.core.UserPreferences;
import org.sleuthkit.autopsy.corecomponents.DataResultViewerTable; import org.sleuthkit.autopsy.corecomponents.DataResultViewerTable;
import org.sleuthkit.autopsy.corecomponents.DataResultViewerTable.HasCommentStatus; import org.sleuthkit.autopsy.corecomponents.DataResultViewerTable.HasCommentStatus;
import org.sleuthkit.autopsy.corecomponents.DataResultViewerTable.Score;
import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.Logger;
import static org.sleuthkit.autopsy.datamodel.Bundle.*; import static org.sleuthkit.autopsy.datamodel.Bundle.*;
import static org.sleuthkit.autopsy.datamodel.AbstractAbstractFileNode.AbstractFilePropertyType.*; import static org.sleuthkit.autopsy.datamodel.AbstractAbstractFileNode.AbstractFilePropertyType.*;
@ -59,14 +58,13 @@ import org.sleuthkit.autopsy.texttranslation.NoServiceProviderException;
import org.sleuthkit.autopsy.texttranslation.TextTranslationService; import org.sleuthkit.autopsy.texttranslation.TextTranslationService;
import org.sleuthkit.autopsy.texttranslation.TranslationException; import org.sleuthkit.autopsy.texttranslation.TranslationException;
import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.Content; import org.sleuthkit.datamodel.Content;
import org.sleuthkit.datamodel.ContentTag; import org.sleuthkit.datamodel.ContentTag;
import org.sleuthkit.datamodel.Tag; import org.sleuthkit.datamodel.Tag;
import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.datamodel.TskCoreException;
import org.sleuthkit.datamodel.TskData;
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository;
import org.sleuthkit.autopsy.texttranslation.utils.FileNameTranslationUtil; import org.sleuthkit.autopsy.texttranslation.utils.FileNameTranslationUtil;
import org.sleuthkit.datamodel.Score;
/** /**
* An abstract node that encapsulates AbstractFile data * An abstract node that encapsulates AbstractFile data
@ -432,43 +430,6 @@ public abstract class AbstractAbstractFileNode<T extends AbstractFile> extends A
return Pair.of(count, description); return Pair.of(count, description);
} }
@NbBundle.Messages({
"AbstractAbstractFileNode.createSheet.score.displayName=S",
"AbstractAbstractFileNode.createSheet.notableFile.description=File recognized as notable.",
"AbstractAbstractFileNode.createSheet.interestingResult.description=File has interesting result associated with it.",
"AbstractAbstractFileNode.createSheet.taggedFile.description=File has been tagged.",
"AbstractAbstractFileNode.createSheet.notableTaggedFile.description=File tagged with notable tag.",
"AbstractAbstractFileNode.createSheet.noScore.description=No score"})
@Override
protected Pair<DataResultViewerTable.Score, String> getScorePropertyAndDescription(List<Tag> tags) {
DataResultViewerTable.Score score = DataResultViewerTable.Score.NO_SCORE;
String description = Bundle.AbstractAbstractFileNode_createSheet_noScore_description();
if (content.getKnown() == TskData.FileKnown.BAD) {
score = DataResultViewerTable.Score.NOTABLE_SCORE;
description = Bundle.AbstractAbstractFileNode_createSheet_notableFile_description();
}
try {
if (score == DataResultViewerTable.Score.NO_SCORE && !content.getArtifacts(BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT).isEmpty()) {
score = DataResultViewerTable.Score.INTERESTING_SCORE;
description = Bundle.AbstractAbstractFileNode_createSheet_interestingResult_description();
}
} catch (TskCoreException ex) {
logger.log(Level.WARNING, "Error getting artifacts for file: " + content.getName(), ex);
}
if (!tags.isEmpty() && (score == DataResultViewerTable.Score.NO_SCORE || score == DataResultViewerTable.Score.INTERESTING_SCORE)) {
score = DataResultViewerTable.Score.INTERESTING_SCORE;
description = Bundle.AbstractAbstractFileNode_createSheet_taggedFile_description();
for (Tag tag : tags) {
if (tag.getName().getKnownStatus() == TskData.FileKnown.BAD) {
score = DataResultViewerTable.Score.NOTABLE_SCORE;
description = Bundle.AbstractAbstractFileNode_createSheet_notableTaggedFile_description();
break;
}
}
}
return Pair.of(score, description);
}
@NbBundle.Messages({ @NbBundle.Messages({
"AbstractAbstractFileNode.createSheet.comment.displayName=C"}) "AbstractAbstractFileNode.createSheet.comment.displayName=C"})
@Override @Override

View File

@ -32,14 +32,17 @@ import org.openide.nodes.Sheet;
import org.openide.util.lookup.Lookups; import org.openide.util.lookup.Lookups;
import org.openide.util.Lookup; import org.openide.util.Lookup;
import org.openide.util.NbBundle; import org.openide.util.NbBundle;
import org.openide.util.NbBundle.Messages;
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.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.AnalysisResult;
import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE; import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE;
import org.sleuthkit.datamodel.Content; import org.sleuthkit.datamodel.Content;
import org.sleuthkit.datamodel.Score;
import org.sleuthkit.datamodel.SleuthkitCase; import org.sleuthkit.datamodel.SleuthkitCase;
import org.sleuthkit.datamodel.Tag; import org.sleuthkit.datamodel.Tag;
import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.datamodel.TskCoreException;
@ -57,7 +60,7 @@ public abstract class AbstractContentNode<T extends Content> extends ContentNode
/** /**
* Underlying Sleuth Kit Content object * Underlying Sleuth Kit Content object
*/ */
T content; protected final T content;
private static final Logger logger = Logger.getLogger(AbstractContentNode.class.getName()); private static final Logger logger = Logger.getLogger(AbstractContentNode.class.getName());
/** /**
@ -339,7 +342,26 @@ public abstract class AbstractContentNode<T extends Content> extends ContentNode
* *
* @return Score property for the underlying content of the node. * @return Score property for the underlying content of the node.
*/ */
abstract protected Pair<DataResultViewerTable.Score, String> getScorePropertyAndDescription(List<Tag> tags); @Messages({
"# {0} - significanceDisplayName",
"AbstractContentNode_getScorePropertyAndDescription_description=Has an {0} analysis result score"
})
protected Pair<Score, String> getScorePropertyAndDescription(List<Tag> tags) {
Score score = Score.SCORE_UNKNOWN;
try {
if (content instanceof AnalysisResult) {
score = ((AnalysisResult) content).getScore();
} else {
score = this.content.getAggregateScore();
}
} catch (TskCoreException ex) {
logger.log(Level.WARNING, "Unable to get aggregate score for content with id: " + this.content.getId(), ex);
}
String significanceDisplay = score.getSignificance().getDisplayName();
String description = Bundle.AbstractContentNode_getScorePropertyAndDescription_description(significanceDisplay);
return Pair.of(score, description);
}
/** /**
* Returns comment property for the node. * Returns comment property for the node.

View File

@ -50,6 +50,7 @@ import org.sleuthkit.datamodel.TskCoreException;
import org.sleuthkit.autopsy.guiutils.RefreshThrottler; import org.sleuthkit.autopsy.guiutils.RefreshThrottler;
import org.sleuthkit.datamodel.BlackboardArtifact.Category; import org.sleuthkit.datamodel.BlackboardArtifact.Category;
import org.python.google.common.collect.Sets; import org.python.google.common.collect.Sets;
import org.sleuthkit.datamodel.Blackboard;
import static org.sleuthkit.datamodel.BlackboardArtifact.Type.TSK_ACCOUNT; import static org.sleuthkit.datamodel.BlackboardArtifact.Type.TSK_ACCOUNT;
import static org.sleuthkit.datamodel.BlackboardArtifact.Type.TSK_DATA_SOURCE_USAGE; import static org.sleuthkit.datamodel.BlackboardArtifact.Type.TSK_DATA_SOURCE_USAGE;
import static org.sleuthkit.datamodel.BlackboardArtifact.Type.TSK_EMAIL_MSG; import static org.sleuthkit.datamodel.BlackboardArtifact.Type.TSK_EMAIL_MSG;
@ -644,17 +645,32 @@ public class Artifacts {
@Override @Override
protected List<BlackboardArtifact> makeKeys() { protected List<BlackboardArtifact> makeKeys() {
try { try {
List<BlackboardArtifact> arts; List<? extends BlackboardArtifact> arts;
arts = (filteringDSObjId > 0) Blackboard blackboard = Case.getCurrentCaseThrows().getSleuthkitCase().getBlackboard();
? Case.getCurrentCaseThrows().getSleuthkitCase().getBlackboard().getArtifacts(type.getTypeID(), filteringDSObjId) switch (this.type.getCategory()) {
: Case.getCurrentCaseThrows().getSleuthkitCase().getBlackboardArtifacts(type.getTypeID());
case ANALYSIS_RESULT:
arts = (filteringDSObjId > 0)
? blackboard.getAnalysisResultsByType(type.getTypeID(), filteringDSObjId)
: blackboard.getAnalysisResultsByType(type.getTypeID());
break;
case DATA_ARTIFACT:
default:
arts = (filteringDSObjId > 0)
? blackboard.getDataArtifacts(type.getTypeID(), filteringDSObjId)
: blackboard.getDataArtifacts(type.getTypeID());
break;
}
for (BlackboardArtifact art : arts) { for (BlackboardArtifact art : arts) {
//Cache attributes while we are off the EDT. //Cache attributes while we are off the EDT.
//See JIRA-5969 //See JIRA-5969
art.getAttributes(); art.getAttributes();
} }
return arts;
@SuppressWarnings("unchecked")
List<BlackboardArtifact> toRet = (List<BlackboardArtifact>)(List<?>)arts;
return toRet;
} catch (NoCurrentCaseException ex) { } catch (NoCurrentCaseException ex) {
logger.log(Level.WARNING, "Trying to access case when no case is open.", ex); //NON-NLS logger.log(Level.WARNING, "Trying to access case when no case is open.", ex); //NON-NLS
} catch (TskCoreException ex) { } catch (TskCoreException ex) {

View File

@ -59,12 +59,10 @@ import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeUti
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoException; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoException;
import org.sleuthkit.autopsy.core.UserPreferences; import org.sleuthkit.autopsy.core.UserPreferences;
import org.sleuthkit.autopsy.corecomponents.DataResultViewerTable; import org.sleuthkit.autopsy.corecomponents.DataResultViewerTable;
import org.sleuthkit.autopsy.corecomponents.DataResultViewerTable.Score;
import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.Logger;
import static org.sleuthkit.autopsy.datamodel.DisplayableItemNode.findLinked; import static org.sleuthkit.autopsy.datamodel.DisplayableItemNode.findLinked;
import org.sleuthkit.autopsy.corecomponents.DataResultViewerTable.HasCommentStatus; import org.sleuthkit.autopsy.corecomponents.DataResultViewerTable.HasCommentStatus;
import static org.sleuthkit.autopsy.datamodel.AbstractContentNode.backgroundTasksPool; import static org.sleuthkit.autopsy.datamodel.AbstractContentNode.backgroundTasksPool;
import org.sleuthkit.autopsy.modules.hashdatabase.HashDbManager;
import org.sleuthkit.autopsy.timeline.actions.ViewArtifactInTimelineAction; import org.sleuthkit.autopsy.timeline.actions.ViewArtifactInTimelineAction;
import org.sleuthkit.autopsy.timeline.actions.ViewFileInTimelineAction; import org.sleuthkit.autopsy.timeline.actions.ViewFileInTimelineAction;
import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.AbstractFile;
@ -75,12 +73,12 @@ import org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE;
import org.sleuthkit.datamodel.Content; import org.sleuthkit.datamodel.Content;
import org.sleuthkit.datamodel.Tag; import org.sleuthkit.datamodel.Tag;
import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.datamodel.TskCoreException;
import org.sleuthkit.datamodel.TskData;
import org.sleuthkit.autopsy.datamodel.utils.IconsUtil; import org.sleuthkit.autopsy.datamodel.utils.IconsUtil;
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository;
import static org.sleuthkit.autopsy.datamodel.AbstractContentNode.NO_DESCR; import static org.sleuthkit.autopsy.datamodel.AbstractContentNode.NO_DESCR;
import org.sleuthkit.autopsy.texttranslation.TextTranslationService; import org.sleuthkit.autopsy.texttranslation.TextTranslationService;
import org.sleuthkit.autopsy.datamodel.utils.FileNameTransTask; import org.sleuthkit.autopsy.datamodel.utils.FileNameTransTask;
import org.sleuthkit.datamodel.Score;
/** /**
* A BlackboardArtifactNode is an AbstractNode implementation that can be used * A BlackboardArtifactNode is an AbstractNode implementation that can be used
@ -843,94 +841,6 @@ public class BlackboardArtifactNode extends AbstractContentNode<BlackboardArtifa
return status; return status;
} }
/**
* Computes the value of the score property ("S" in S, C, O) for the
* artifact represented by this node. The score property indicates whether
* the artifact or its source content is notable or interesting.
*
* IMPORTANT: Notability takes precedence when computing the score.
*
* A red icon will be displayed in the property sheet if the hash of the
* source file has been found in a notable hash set or if either the
* artifact or its source content has been tagged with a notable tag. A
* yellow icon will be displayed if the source file belongs to an
* interesting file set or either the artifact or its source content has
* been tagged with a non-notable tag.
*
* @param tags The tags that have been applied to the artifact and its
* source content.
*
* @return The value of the score property as an enum element and a
* description string for dislpay in a tool tip.
*/
@Override
protected Pair<DataResultViewerTable.Score, String> getScorePropertyAndDescription(List<Tag> tags) {
/*
* Is the artifact's source content marked as notable?
*/
Score score = Score.NO_SCORE;
String description = Bundle.BlackboardArtifactNode_createSheet_noScore_description();
if (srcContent instanceof AbstractFile) {
if (((AbstractFile) srcContent).getKnown() == TskData.FileKnown.BAD) {
score = Score.NOTABLE_SCORE;
description = Bundle.BlackboardArtifactNode_createSheet_notableFile_description();
}
}
/*
* If the artifact is a hash set hit, is the hash set a notable hashes
* hash set?
*/
if (score == Score.NO_SCORE && artifact.getArtifactTypeID() == ARTIFACT_TYPE.TSK_HASHSET_HIT.getTypeID()) {
try {
BlackboardAttribute attr = artifact.getAttribute(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_SET_NAME));
List<HashDbManager.HashDb> notableHashsets = HashDbManager.getInstance().getKnownBadFileHashSets();
for (HashDbManager.HashDb hashDb : notableHashsets) {
if (hashDb.getHashSetName().equals(attr.getValueString())) {
score = Score.NOTABLE_SCORE;
description = Bundle.BlackboardArtifactNode_createSheet_notableFile_description();
break;
}
}
} catch (TskCoreException ex) {
logger.log(Level.SEVERE, MessageFormat.format("Error getting TSK_SET_NAME attribute for TSK_HASHSET_HIT artifact (artifact objID={0})", artifact.getId()), ex);
}
}
/*
* Is the artifact's source content notable?
*/
if (score == Score.NO_SCORE) {
try {
if (!srcContent.getArtifacts(BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_ARTIFACT_HIT).isEmpty()) {
score = Score.INTERESTING_SCORE;
description = Bundle.BlackboardArtifactNode_createSheet_interestingResult_description();
}
} catch (TskCoreException ex) {
logger.log(Level.SEVERE, MessageFormat.format("Error getting TSK_INTERESTING_ARTIFACT_HIT artifacts for source content (artifact objID={0})", artifact.getId()), ex);
}
}
/*
* Analyze any tags applied to the artifact or its source content. If
* there are tags, tha artifact is at least interesting. If one of the
* tags is a notable tag, the artifact is notable.
*/
if (tags.size() > 0 && (score == Score.NO_SCORE || score == Score.INTERESTING_SCORE)) {
score = Score.INTERESTING_SCORE;
description = Bundle.BlackboardArtifactNode_createSheet_taggedItem_description();
for (Tag tag : tags) {
if (tag.getName().getKnownStatus() == TskData.FileKnown.BAD) {
score = Score.NOTABLE_SCORE;
description = Bundle.BlackboardArtifactNode_createSheet_notableTaggedItem_description();
break;
}
}
}
return Pair.of(score, description);
}
/** /**
* Computes the value of the other occurrences property ("O" in S, C, O) for * Computes the value of the other occurrences property ("O" in S, C, O) for
* the artifact represented by this node. The value of the other occurrences * the artifact represented by this node. The value of the other occurrences
@ -1146,7 +1056,7 @@ public class BlackboardArtifactNode extends AbstractContentNode<BlackboardArtifa
"BlackboardArtifactNode.createSheet.noScore.description=No score"}) "BlackboardArtifactNode.createSheet.noScore.description=No score"})
@Deprecated @Deprecated
protected final void addScorePropertyAndDescription(Sheet.Set sheetSet, List<Tag> tags) { protected final void addScorePropertyAndDescription(Sheet.Set sheetSet, List<Tag> tags) {
Pair<DataResultViewerTable.Score, String> scoreAndDescription = getScorePropertyAndDescription(tags); Pair<Score, String> scoreAndDescription = getScorePropertyAndDescription(tags);
sheetSet.put(new NodeProperty<>(Bundle.BlackboardArtifactNode_createSheet_score_name(), Bundle.BlackboardArtifactNode_createSheet_score_displayName(), scoreAndDescription.getRight(), scoreAndDescription.getLeft())); sheetSet.put(new NodeProperty<>(Bundle.BlackboardArtifactNode_createSheet_score_name(), Bundle.BlackboardArtifactNode_createSheet_score_displayName(), scoreAndDescription.getRight(), scoreAndDescription.getLeft()));
} }

View File

@ -9,13 +9,7 @@ AbstractAbstractFileNode.createSheet.count.description=There were {0} datasource
AbstractAbstractFileNode.createSheet.count.displayName=O AbstractAbstractFileNode.createSheet.count.displayName=O
AbstractAbstractFileNode.createSheet.count.hashLookupNotRun.description=Hash lookup had not been run on this file when the column was populated AbstractAbstractFileNode.createSheet.count.hashLookupNotRun.description=Hash lookup had not been run on this file when the column was populated
AbstractAbstractFileNode.createSheet.count.name=O AbstractAbstractFileNode.createSheet.count.name=O
AbstractAbstractFileNode.createSheet.interestingResult.description=File has interesting result associated with it.
AbstractAbstractFileNode.createSheet.noScore.description=No score
AbstractAbstractFileNode.createSheet.notableFile.description=File recognized as notable.
AbstractAbstractFileNode.createSheet.notableTaggedFile.description=File tagged with notable tag.
AbstractAbstractFileNode.createSheet.score.displayName=S
AbstractAbstractFileNode.createSheet.score.name=S AbstractAbstractFileNode.createSheet.score.name=S
AbstractAbstractFileNode.createSheet.taggedFile.description=File has been tagged.
AbstractAbstractFileNode.extensionColLbl=Extension AbstractAbstractFileNode.extensionColLbl=Extension
AbstractAbstractFileNode.flagsDirColLbl=Flags(Dir) AbstractAbstractFileNode.flagsDirColLbl=Flags(Dir)
AbstractAbstractFileNode.flagsMetaColLbl=Flags(Meta) AbstractAbstractFileNode.flagsMetaColLbl=Flags(Meta)
@ -38,6 +32,8 @@ AbstractAbstractFileNode.typeMetaColLbl=Type(Meta)
AbstractAbstractFileNode.useridColLbl=UserID AbstractAbstractFileNode.useridColLbl=UserID
AbstractContentNode.nodescription=no description AbstractContentNode.nodescription=no description
AbstractContentNode.valueLoading=value loading AbstractContentNode.valueLoading=value loading
# {0} - significanceDisplayName
AbstractContentNode_getScorePropertyAndDescription_description=Has an {0} analysis result score
AbstractFsContentNode.noDesc.text=no description AbstractFsContentNode.noDesc.text=no description
AnalysisResults_name=Analysis Results AnalysisResults_name=Analysis Results
ArtifactStringContent.attrsTableHeader.sources=Source(s) ArtifactStringContent.attrsTableHeader.sources=Source(s)

View File

@ -50,6 +50,7 @@ import org.sleuthkit.datamodel.SleuthkitCase;
import org.sleuthkit.datamodel.SleuthkitCase.CaseDbQuery; import org.sleuthkit.datamodel.SleuthkitCase.CaseDbQuery;
import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.datamodel.TskCoreException;
import org.sleuthkit.autopsy.datamodel.Artifacts.UpdatableCountTypeNode; import org.sleuthkit.autopsy.datamodel.Artifacts.UpdatableCountTypeNode;
import org.sleuthkit.datamodel.DataArtifact;
/** /**
* Support for TSK_EMAIL_MSG nodes and displaying emails in the directory tree. * Support for TSK_EMAIL_MSG nodes and displaying emails in the directory tree.
@ -161,7 +162,7 @@ public class EmailExtracted implements AutopsyVisitableItem {
int pathAttrId = BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PATH.getTypeID(); int pathAttrId = BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PATH.getTypeID();
String query = "SELECT \n" String query = "SELECT \n"
+ " art.artifact_id AS artifact_id,\n" + " art.artifact_obj_id AS artifact_obj_id,\n"
+ " (SELECT value_text FROM blackboard_attributes attr\n" + " (SELECT value_text FROM blackboard_attributes attr\n"
+ " WHERE attr.artifact_id = art.artifact_id AND attr.attribute_type_id = " + pathAttrId + "\n" + " WHERE attr.artifact_id = art.artifact_id AND attr.attribute_type_id = " + pathAttrId + "\n"
+ " LIMIT 1) AS value_text\n" + " LIMIT 1) AS value_text\n"
@ -176,14 +177,14 @@ public class EmailExtracted implements AutopsyVisitableItem {
try (CaseDbQuery dbQuery = skCase.executeQuery(query)) { try (CaseDbQuery dbQuery = skCase.executeQuery(query)) {
ResultSet resultSet = dbQuery.getResultSet(); ResultSet resultSet = dbQuery.getResultSet();
while (resultSet.next()) { while (resultSet.next()) {
Long artifactId = resultSet.getLong("artifact_id"); Long artifactObjId = resultSet.getLong("artifact_obj_id");
Map<String, String> accountFolderMap = parsePath(resultSet.getString("value_text")); Map<String, String> accountFolderMap = parsePath(resultSet.getString("value_text"));
String account = accountFolderMap.get(MAIL_ACCOUNT); String account = accountFolderMap.get(MAIL_ACCOUNT);
String folder = accountFolderMap.get(MAIL_FOLDER); String folder = accountFolderMap.get(MAIL_FOLDER);
Map<String, List<Long>> folders = newMapping.computeIfAbsent(account, (str) -> new LinkedHashMap<>()); Map<String, List<Long>> folders = newMapping.computeIfAbsent(account, (str) -> new LinkedHashMap<>());
List<Long> messages = folders.computeIfAbsent(folder, (str) -> new ArrayList<>()); List<Long> messages = folders.computeIfAbsent(folder, (str) -> new ArrayList<>());
messages.add(artifactId); messages.add(artifactObjId);
} }
} catch (TskCoreException | SQLException ex) { } catch (TskCoreException | SQLException ex) {
logger.log(Level.WARNING, "Cannot initialize email extraction: ", ex); //NON-NLS logger.log(Level.WARNING, "Cannot initialize email extraction: ", ex); //NON-NLS
@ -499,7 +500,7 @@ public class EmailExtracted implements AutopsyVisitableItem {
/** /**
* Node representing mail folder content (mail messages) * Node representing mail folder content (mail messages)
*/ */
private class MessageFactory extends BaseChildFactory<BlackboardArtifact> implements Observer { private class MessageFactory extends BaseChildFactory<DataArtifact> implements Observer {
private final String accountName; private final String accountName;
private final String folderName; private final String folderName;
@ -512,7 +513,7 @@ public class EmailExtracted implements AutopsyVisitableItem {
} }
@Override @Override
protected Node createNodeForKey(BlackboardArtifact art) { protected Node createNodeForKey(DataArtifact art) {
return new BlackboardArtifactNode(art); return new BlackboardArtifactNode(art);
} }
@ -522,13 +523,13 @@ public class EmailExtracted implements AutopsyVisitableItem {
} }
@Override @Override
protected List<BlackboardArtifact> makeKeys() { protected List<DataArtifact> makeKeys() {
List<BlackboardArtifact> keys = new ArrayList<>(); List<DataArtifact> keys = new ArrayList<>();
if (skCase != null) { if (skCase != null) {
emailResults.getArtifactIds(accountName, folderName).forEach((id) -> { emailResults.getArtifactIds(accountName, folderName).forEach((id) -> {
try { try {
BlackboardArtifact art = skCase.getBlackboardArtifact(id); DataArtifact art = skCase.getBlackboard().getDataArtifactById(id);
//Cache attributes while we are off the EDT. //Cache attributes while we are off the EDT.
//See JIRA-5969 //See JIRA-5969
art.getAttributes(); art.getAttributes();

View File

@ -52,6 +52,7 @@ import org.sleuthkit.datamodel.SleuthkitCase;
import org.sleuthkit.datamodel.SleuthkitCase.CaseDbQuery; import org.sleuthkit.datamodel.SleuthkitCase.CaseDbQuery;
import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.datamodel.TskCoreException;
import org.sleuthkit.autopsy.datamodel.Artifacts.UpdatableCountTypeNode; import org.sleuthkit.autopsy.datamodel.Artifacts.UpdatableCountTypeNode;
import org.sleuthkit.datamodel.AnalysisResult;
/** /**
* Hash set hits node support. Inner classes have all of the nodes in the tree. * Hash set hits node support. Inner classes have all of the nodes in the tree.
@ -136,7 +137,7 @@ public class HashsetHits implements AutopsyVisitableItem {
int setNameId = ATTRIBUTE_TYPE.TSK_SET_NAME.getTypeID(); int setNameId = ATTRIBUTE_TYPE.TSK_SET_NAME.getTypeID();
int artId = TSK_HASHSET_HIT.getTypeID(); int artId = TSK_HASHSET_HIT.getTypeID();
String query = "SELECT value_text,blackboard_attributes.artifact_id,attribute_type_id " //NON-NLS String query = "SELECT value_text,blackboard_artifacts.artifact_obj_id,attribute_type_id " //NON-NLS
+ "FROM blackboard_attributes,blackboard_artifacts WHERE " //NON-NLS + "FROM blackboard_attributes,blackboard_artifacts WHERE " //NON-NLS
+ "attribute_type_id=" + setNameId //NON-NLS + "attribute_type_id=" + setNameId //NON-NLS
+ " AND blackboard_attributes.artifact_id=blackboard_artifacts.artifact_id" //NON-NLS + " AND blackboard_attributes.artifact_id=blackboard_artifacts.artifact_id" //NON-NLS
@ -150,11 +151,11 @@ public class HashsetHits implements AutopsyVisitableItem {
synchronized (hashSetHitsMap) { synchronized (hashSetHitsMap) {
while (resultSet.next()) { while (resultSet.next()) {
String setName = resultSet.getString("value_text"); //NON-NLS String setName = resultSet.getString("value_text"); //NON-NLS
long artifactId = resultSet.getLong("artifact_id"); //NON-NLS long artifactObjId = resultSet.getLong("artifact_obj_id"); //NON-NLS
if (!hashSetHitsMap.containsKey(setName)) { if (!hashSetHitsMap.containsKey(setName)) {
hashSetHitsMap.put(setName, new HashSet<>()); hashSetHitsMap.put(setName, new HashSet<>());
} }
hashSetHitsMap.get(setName).add(artifactId); hashSetHitsMap.get(setName).add(artifactObjId);
} }
} }
} catch (TskCoreException | SQLException ex) { } catch (TskCoreException | SQLException ex) {
@ -380,10 +381,10 @@ public class HashsetHits implements AutopsyVisitableItem {
/** /**
* Creates the nodes for the hits in a given set. * Creates the nodes for the hits in a given set.
*/ */
private class HitFactory extends BaseChildFactory<BlackboardArtifact> implements Observer { private class HitFactory extends BaseChildFactory<AnalysisResult> implements Observer {
private final String hashsetName; private final String hashsetName;
private final Map<Long, BlackboardArtifact> artifactHits = new HashMap<>(); private final Map<Long, AnalysisResult> artifactHits = new HashMap<>();
private HitFactory(String hashsetName) { private HitFactory(String hashsetName) {
super(hashsetName); super(hashsetName);
@ -401,7 +402,7 @@ public class HashsetHits implements AutopsyVisitableItem {
} }
@Override @Override
protected Node createNodeForKey(BlackboardArtifact key) { protected Node createNodeForKey(AnalysisResult key) {
return new BlackboardArtifactNode(key); return new BlackboardArtifactNode(key);
} }
@ -411,13 +412,13 @@ public class HashsetHits implements AutopsyVisitableItem {
} }
@Override @Override
protected List<BlackboardArtifact> makeKeys() { protected List<AnalysisResult> makeKeys() {
if (skCase != null) { if (skCase != null) {
hashsetResults.getArtifactIds(hashsetName).forEach((id) -> { hashsetResults.getArtifactIds(hashsetName).forEach((id) -> {
try { try {
if (!artifactHits.containsKey(id)) { if (!artifactHits.containsKey(id)) {
BlackboardArtifact art = skCase.getBlackboardArtifact(id); AnalysisResult art = skCase.getBlackboard().getAnalysisResultById(id);
//Cache attributes while we are off the EDT. //Cache attributes while we are off the EDT.
//See JIRA-5969 //See JIRA-5969
art.getAttributes(); art.getAttributes();

View File

@ -282,20 +282,6 @@ public class ImageNode extends AbstractContentNode<Image> {
return null; return null;
} }
/**
* Returns Score property for the node.
*
* Null implementation of an abstract method.
*
* @param tags list of tags.
*
* @return Score property for the underlying content of the node.
*/
@Override
protected Pair<DataResultViewerTable.Score, String> getScorePropertyAndDescription(List<Tag> tags) {
return Pair.of(DataResultViewerTable.Score.NO_SCORE, NO_DESCR);
}
/** /**
* Returns comment property for the node. * Returns comment property for the node.
* *

View File

@ -51,6 +51,7 @@ import org.sleuthkit.datamodel.SleuthkitCase;
import org.sleuthkit.datamodel.SleuthkitCase.CaseDbQuery; import org.sleuthkit.datamodel.SleuthkitCase.CaseDbQuery;
import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.datamodel.TskCoreException;
import org.sleuthkit.autopsy.datamodel.Artifacts.UpdatableCountTypeNode; import org.sleuthkit.autopsy.datamodel.Artifacts.UpdatableCountTypeNode;
import org.sleuthkit.datamodel.AnalysisResult;
public class InterestingHits implements AutopsyVisitableItem { public class InterestingHits implements AutopsyVisitableItem {
@ -129,7 +130,7 @@ public class InterestingHits implements AutopsyVisitableItem {
int setNameId = BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME.getTypeID(); int setNameId = BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME.getTypeID();
int artId = artType.getTypeID(); int artId = artType.getTypeID();
String query = "SELECT value_text,blackboard_attributes.artifact_id,attribute_type_id " //NON-NLS String query = "SELECT value_text,blackboard_artifacts.artifact_obj_id,attribute_type_id " //NON-NLS
+ "FROM blackboard_attributes,blackboard_artifacts WHERE " //NON-NLS + "FROM blackboard_attributes,blackboard_artifacts WHERE " //NON-NLS
+ "attribute_type_id=" + setNameId //NON-NLS + "attribute_type_id=" + setNameId //NON-NLS
+ " AND blackboard_attributes.artifact_id=blackboard_artifacts.artifact_id" //NON-NLS + " AND blackboard_attributes.artifact_id=blackboard_artifacts.artifact_id" //NON-NLS
@ -143,13 +144,13 @@ public class InterestingHits implements AutopsyVisitableItem {
ResultSet resultSet = dbQuery.getResultSet(); ResultSet resultSet = dbQuery.getResultSet();
while (resultSet.next()) { while (resultSet.next()) {
String value = resultSet.getString("value_text"); //NON-NLS String value = resultSet.getString("value_text"); //NON-NLS
long artifactId = resultSet.getLong("artifact_id"); //NON-NLS long artifactObjId = resultSet.getLong("artifact_obj_id"); //NON-NLS
if (!interestingItemsMap.containsKey(value)) { if (!interestingItemsMap.containsKey(value)) {
interestingItemsMap.put(value, new LinkedHashMap<>()); interestingItemsMap.put(value, new LinkedHashMap<>());
interestingItemsMap.get(value).put(BlackboardArtifact.Type.TSK_INTERESTING_FILE_HIT.getDisplayName(), new HashSet<>()); interestingItemsMap.get(value).put(BlackboardArtifact.Type.TSK_INTERESTING_FILE_HIT.getDisplayName(), new HashSet<>());
interestingItemsMap.get(value).put(BlackboardArtifact.Type.TSK_INTERESTING_ARTIFACT_HIT.getDisplayName(), new HashSet<>()); interestingItemsMap.get(value).put(BlackboardArtifact.Type.TSK_INTERESTING_ARTIFACT_HIT.getDisplayName(), new HashSet<>());
} }
interestingItemsMap.get(value).get(artType.getDisplayName()).add(artifactId); interestingItemsMap.get(value).get(artType.getDisplayName()).add(artifactObjId);
} }
} }
} catch (TskCoreException | SQLException ex) { } catch (TskCoreException | SQLException ex) {
@ -459,11 +460,11 @@ public class InterestingHits implements AutopsyVisitableItem {
} }
} }
private class HitFactory extends BaseChildFactory<BlackboardArtifact> implements Observer { private class HitFactory extends BaseChildFactory<AnalysisResult> implements Observer {
private final String setName; private final String setName;
private final String typeName; private final String typeName;
private final Map<Long, BlackboardArtifact> artifactHits = new HashMap<>(); private final Map<Long, AnalysisResult> artifactHits = new HashMap<>();
private HitFactory(String setName, String typeName) { private HitFactory(String setName, String typeName) {
/** /**
@ -478,13 +479,13 @@ public class InterestingHits implements AutopsyVisitableItem {
} }
@Override @Override
protected List<BlackboardArtifact> makeKeys() { protected List<AnalysisResult> makeKeys() {
if (skCase != null) { if (skCase != null) {
interestingResults.getArtifactIds(setName, typeName).forEach((id) -> { interestingResults.getArtifactIds(setName, typeName).forEach((id) -> {
try { try {
if (!artifactHits.containsKey(id)) { if (!artifactHits.containsKey(id)) {
BlackboardArtifact art = skCase.getBlackboardArtifact(id); AnalysisResult art = skCase.getBlackboard().getAnalysisResultById(id);
//Cache attributes while we are off the EDT. //Cache attributes while we are off the EDT.
//See JIRA-5969 //See JIRA-5969
art.getAttributes(); art.getAttributes();
@ -501,7 +502,7 @@ public class InterestingHits implements AutopsyVisitableItem {
} }
@Override @Override
protected Node createNodeForKey(BlackboardArtifact art) { protected Node createNodeForKey(AnalysisResult art) {
return new BlackboardArtifactNode(art); return new BlackboardArtifactNode(art);
} }

View File

@ -57,6 +57,7 @@ import org.sleuthkit.datamodel.SleuthkitCase.CaseDbQuery;
import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.datamodel.TskCoreException;
import static org.sleuthkit.datamodel.BlackboardArtifact.Type.TSK_KEYWORD_HIT; import static org.sleuthkit.datamodel.BlackboardArtifact.Type.TSK_KEYWORD_HIT;
import org.sleuthkit.autopsy.datamodel.Artifacts.UpdatableCountTypeNode; import org.sleuthkit.autopsy.datamodel.Artifacts.UpdatableCountTypeNode;
import org.sleuthkit.datamodel.AnalysisResult;
/** /**
* Keyword hits node support * Keyword hits node support
@ -91,7 +92,7 @@ public class KeywordHits implements AutopsyVisitableItem {
*/ */
private static final String KEYWORD_HIT_ATTRIBUTES_QUERY = "SELECT blackboard_attributes.value_text, "//NON-NLS private static final String KEYWORD_HIT_ATTRIBUTES_QUERY = "SELECT blackboard_attributes.value_text, "//NON-NLS
+ "blackboard_attributes.value_int32, "//NON-NLS + "blackboard_attributes.value_int32, "//NON-NLS
+ "blackboard_attributes.artifact_id, " //NON-NLS + "blackboard_artifacts.artifact_obj_id, " //NON-NLS
+ "blackboard_attributes.attribute_type_id "//NON-NLS + "blackboard_attributes.attribute_type_id "//NON-NLS
+ "FROM blackboard_attributes, blackboard_artifacts "//NON-NLS + "FROM blackboard_attributes, blackboard_artifacts "//NON-NLS
+ "WHERE blackboard_attributes.artifact_id = blackboard_artifacts.artifact_id "//NON-NLS + "WHERE blackboard_attributes.artifact_id = blackboard_artifacts.artifact_id "//NON-NLS
@ -349,12 +350,12 @@ public class KeywordHits implements AutopsyVisitableItem {
try (CaseDbQuery dbQuery = skCase.executeQuery(queryStr)) { try (CaseDbQuery dbQuery = skCase.executeQuery(queryStr)) {
ResultSet resultSet = dbQuery.getResultSet(); ResultSet resultSet = dbQuery.getResultSet();
while (resultSet.next()) { while (resultSet.next()) {
long artifactId = resultSet.getLong("artifact_id"); //NON-NLS long artifactObjId = resultSet.getLong("artifact_obj_id"); //NON-NLS
long typeId = resultSet.getLong("attribute_type_id"); //NON-NLS long typeId = resultSet.getLong("attribute_type_id"); //NON-NLS
String valueStr = resultSet.getString("value_text"); //NON-NLS String valueStr = resultSet.getString("value_text"); //NON-NLS
//get the map of attributes for this artifact //get the map of attributes for this artifact
Map<Long, String> attributesByTypeMap = artifactIds.computeIfAbsent(artifactId, ai -> new LinkedHashMap<>()); Map<Long, String> attributesByTypeMap = artifactIds.computeIfAbsent(artifactObjId, ai -> new LinkedHashMap<>());
if (StringUtils.isNotEmpty(valueStr)) { if (StringUtils.isNotEmpty(valueStr)) {
attributesByTypeMap.put(typeId, valueStr); attributesByTypeMap.put(typeId, valueStr);
} else { } else {
@ -858,7 +859,7 @@ public class KeywordHits implements AutopsyVisitableItem {
"KeywordHits.createNodeForKey.chgTime.name=ChangeTime", "KeywordHits.createNodeForKey.chgTime.name=ChangeTime",
"KeywordHits.createNodeForKey.chgTime.displayName=Change Time", "KeywordHits.createNodeForKey.chgTime.displayName=Change Time",
"KeywordHits.createNodeForKey.chgTime.desc=Change Time"}) "KeywordHits.createNodeForKey.chgTime.desc=Change Time"})
private BlackboardArtifactNode createBlackboardArtifactNode(BlackboardArtifact art) { private BlackboardArtifactNode createBlackboardArtifactNode(AnalysisResult art) {
if (skCase == null) { if (skCase == null) {
return null; return null;
} }
@ -905,12 +906,12 @@ public class KeywordHits implements AutopsyVisitableItem {
/** /**
* Creates nodes for individual files that had hits * Creates nodes for individual files that had hits
*/ */
private class HitsFactory extends BaseChildFactory<BlackboardArtifact> implements Observer { private class HitsFactory extends BaseChildFactory<AnalysisResult> implements Observer {
private final String keyword; private final String keyword;
private final String setName; private final String setName;
private final String instance; private final String instance;
private final Map<Long, BlackboardArtifact> artifactHits = new HashMap<>(); private final Map<Long, AnalysisResult> artifactHits = new HashMap<>();
private HitsFactory(String setName, String keyword, String instance) { private HitsFactory(String setName, String keyword, String instance) {
/** /**
@ -926,12 +927,12 @@ public class KeywordHits implements AutopsyVisitableItem {
} }
@Override @Override
protected List<BlackboardArtifact> makeKeys() { protected List<AnalysisResult> makeKeys() {
if (skCase != null) { if (skCase != null) {
keywordResults.getArtifactIds(setName, keyword, instance).forEach((id) -> { keywordResults.getArtifactIds(setName, keyword, instance).forEach((id) -> {
try { try {
if (!artifactHits.containsKey(id)) { if (!artifactHits.containsKey(id)) {
BlackboardArtifact art = skCase.getBlackboardArtifact(id); AnalysisResult art = skCase.getBlackboard().getAnalysisResultById(id);
//Cache attributes while we are off the EDT. //Cache attributes while we are off the EDT.
//See JIRA-5969 //See JIRA-5969
art.getAttributes(); art.getAttributes();
@ -948,7 +949,7 @@ public class KeywordHits implements AutopsyVisitableItem {
} }
@Override @Override
protected Node createNodeForKey(BlackboardArtifact art) { protected Node createNodeForKey(AnalysisResult art) {
return createBlackboardArtifactNode(art); return createBlackboardArtifactNode(art);
} }

View File

@ -333,11 +333,6 @@ public final class OsAccounts implements AutopsyVisitableItem {
return null; return null;
} }
@Override
protected Pair<DataResultViewerTable.Score, String> getScorePropertyAndDescription(List<Tag> tags) {
return null;
}
@Override @Override
protected DataResultViewerTable.HasCommentStatus getCommentProperty(List<Tag> tags, CorrelationAttributeInstance attribute) { protected DataResultViewerTable.HasCommentStatus getCommentProperty(List<Tag> tags, CorrelationAttributeInstance attribute) {
return DataResultViewerTable.HasCommentStatus.NO_COMMENT; return DataResultViewerTable.HasCommentStatus.NO_COMMENT;

View File

@ -156,20 +156,6 @@ public class PoolNode extends AbstractContentNode<Pool> {
return null; return null;
} }
/**
* Returns Score property for the node.
*
* Null implementation of an abstract method.
*
* @param tags list of tags.
*
* @return Score property for the underlying content of the node.
*/
@Override
protected Pair<DataResultViewerTable.Score, String> getScorePropertyAndDescription(List<Tag> tags) {
return Pair.of(DataResultViewerTable.Score.NO_SCORE, NO_DESCR);
}
/** /**
* Returns comment property for the node. * Returns comment property for the node.
* *

View File

@ -20,6 +20,7 @@ package org.sleuthkit.autopsy.datamodel;
import org.apache.commons.lang3.tuple.Pair; import org.apache.commons.lang3.tuple.Pair;
import org.sleuthkit.autopsy.corecomponents.DataResultViewerTable; import org.sleuthkit.autopsy.corecomponents.DataResultViewerTable;
import org.sleuthkit.datamodel.Score;
/** /**
* Container to bag the S C & O data for an abstract file node. * Container to bag the S C & O data for an abstract file node.
@ -27,11 +28,11 @@ import org.sleuthkit.autopsy.corecomponents.DataResultViewerTable;
*/ */
class SCOData { class SCOData {
private Pair<DataResultViewerTable.Score, String> scoreAndDescription = null; private Pair<Score, String> scoreAndDescription = null;
private DataResultViewerTable.HasCommentStatus comment = null; private DataResultViewerTable.HasCommentStatus comment = null;
private Pair<Long, String> countAndDescription = null; private Pair<Long, String> countAndDescription = null;
Pair<DataResultViewerTable.Score, String> getScoreAndDescription() { Pair<Score, String> getScoreAndDescription() {
return scoreAndDescription; return scoreAndDescription;
} }
@ -43,7 +44,7 @@ class SCOData {
return countAndDescription; return countAndDescription;
} }
void setScoreAndDescription(Pair<DataResultViewerTable.Score, String> scoreAndDescription) { void setScoreAndDescription(Pair<Score, String> scoreAndDescription) {
this.scoreAndDescription = scoreAndDescription; this.scoreAndDescription = scoreAndDescription;
} }
void setComment(DataResultViewerTable.HasCommentStatus comment) { void setComment(DataResultViewerTable.HasCommentStatus comment) {

View File

@ -138,20 +138,6 @@ public class UnsupportedContentNode extends AbstractContentNode<UnsupportedConte
return null; return null;
} }
/**
* Returns Score property for the node.
*
* Null implementation of an abstract method.
*
* @param tags list of tags.
*
* @return Score property for the underlying content of the node.
*/
@Override
protected Pair<DataResultViewerTable.Score, String> getScorePropertyAndDescription(List<Tag> tags) {
return Pair.of(DataResultViewerTable.Score.NO_SCORE, NO_DESCR);
}
/** /**
* Returns comment property for the node. * Returns comment property for the node.
* *

View File

@ -258,20 +258,6 @@ public class VolumeNode extends AbstractContentNode<Volume> {
return null; return null;
} }
/**
* Returns Score property for the node.
*
* Null implementation of an abstract method.
*
* @param tags list of tags.
*
* @return Score property for the underlying content of the node.
*/
@Override
protected Pair<DataResultViewerTable.Score, String> getScorePropertyAndDescription(List<Tag> tags) {
return Pair.of(DataResultViewerTable.Score.NO_SCORE, NO_DESCR);
}
/** /**
* Returns comment property for the node. * Returns comment property for the node.
* *

View File

@ -81,6 +81,7 @@ import org.sleuthkit.datamodel.BlackboardArtifact.Type;
import static org.sleuthkit.datamodel.BlackboardArtifact.Type.TSK_ACCOUNT; import static org.sleuthkit.datamodel.BlackboardArtifact.Type.TSK_ACCOUNT;
import org.sleuthkit.datamodel.BlackboardAttribute; import org.sleuthkit.datamodel.BlackboardAttribute;
import org.sleuthkit.datamodel.Content; import org.sleuthkit.datamodel.Content;
import org.sleuthkit.datamodel.DataArtifact;
import org.sleuthkit.datamodel.SleuthkitCase; import org.sleuthkit.datamodel.SleuthkitCase;
import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.datamodel.TskCoreException;
import org.sleuthkit.datamodel.TskData.DbType; import org.sleuthkit.datamodel.TskData.DbType;
@ -569,7 +570,7 @@ final public class Accounts implements AutopsyVisitableItem {
@Override @Override
protected boolean createKeys(List<Long> list) { protected boolean createKeys(List<Long> list) {
String query String query
= "SELECT blackboard_artifacts.artifact_id " //NON-NLS = "SELECT blackboard_artifacts.artifact_obj_id " //NON-NLS
+ " FROM blackboard_artifacts " //NON-NLS + " FROM blackboard_artifacts " //NON-NLS
+ " JOIN blackboard_attributes ON blackboard_artifacts.artifact_id = blackboard_attributes.artifact_id " //NON-NLS + " JOIN blackboard_attributes ON blackboard_artifacts.artifact_id = blackboard_attributes.artifact_id " //NON-NLS
+ " WHERE blackboard_artifacts.artifact_type_id = " + BlackboardArtifact.Type.TSK_ACCOUNT.getTypeID() //NON-NLS + " WHERE blackboard_artifacts.artifact_type_id = " + BlackboardArtifact.Type.TSK_ACCOUNT.getTypeID() //NON-NLS
@ -581,7 +582,7 @@ final public class Accounts implements AutopsyVisitableItem {
ResultSet rs = results.getResultSet();) { ResultSet rs = results.getResultSet();) {
List<Long> tempList = new ArrayList<>(); List<Long> tempList = new ArrayList<>();
while (rs.next()) { while (rs.next()) {
tempList.add(rs.getLong("artifact_id")); // NON-NLS tempList.add(rs.getLong("artifact_obj_id")); // NON-NLS
} }
list.addAll(tempList); list.addAll(tempList);
} catch (TskCoreException | SQLException ex) { } catch (TskCoreException | SQLException ex) {
@ -594,7 +595,7 @@ final public class Accounts implements AutopsyVisitableItem {
@Override @Override
protected Node[] createNodesForKey(Long t) { protected Node[] createNodesForKey(Long t) {
try { try {
return new Node[]{new BlackboardArtifactNode(skCase.getBlackboardArtifact(t))}; return new Node[]{new BlackboardArtifactNode(skCase.getBlackboard().getDataArtifactById(t))};
} catch (TskCoreException ex) { } catch (TskCoreException ex) {
LOGGER.log(Level.SEVERE, "Error get black board artifact with id " + t, ex); LOGGER.log(Level.SEVERE, "Error get black board artifact with id " + t, ex);
return new Node[0]; return new Node[0];
@ -1520,7 +1521,7 @@ final public class Accounts implements AutopsyVisitableItem {
} }
try { try {
BlackboardArtifact art = skCase.getBlackboardArtifact(artifactID); DataArtifact art = skCase.getBlackboard().getDataArtifactById(artifactID);
return new Node[]{new AccountArtifactNode(art)}; return new Node[]{new AccountArtifactNode(art)};
} catch (TskCoreException ex) { } catch (TskCoreException ex) {
LOGGER.log(Level.SEVERE, "Error creating BlackboardArtifactNode for artifact with ID " + artifactID, ex); //NON-NLS LOGGER.log(Level.SEVERE, "Error creating BlackboardArtifactNode for artifact with ID " + artifactID, ex); //NON-NLS

View File

@ -58,10 +58,8 @@ FileSorter.SortingMethod.keywordlist.displayName=Keyword List Names
FileSorter.SortingMethod.pageViews.displayName=Page Views FileSorter.SortingMethod.pageViews.displayName=Page Views
ResultDomain_getDefaultCategory=Uncategorized ResultDomain_getDefaultCategory=Uncategorized
ResultDomain_noAccountTypes=Unknown ResultDomain_noAccountTypes=Unknown
ResultFile.score.interestingResult.description=At least one instance of the file has an interesting result associated with it. # {0} - significanceDisplayName
ResultFile.score.notableFile.description=At least one instance of the file was recognized as notable. ResultFile_updateScoreAndDescription_description=Has an {0} analysis result score
ResultFile.score.notableTaggedFile.description=At least one instance of the file is tagged with a notable tag.
ResultFile.score.taggedFile.description=At least one instance of the file has been tagged.
SearchData.AttributeType.Domain.displayName=Domain SearchData.AttributeType.Domain.displayName=Domain
SearchData.FileSize.100kbto1mb=: 100KB-1MB SearchData.FileSize.100kbto1mb=: 100KB-1MB
SearchData.FileSize.100mbto1gb=: 100MB-1GB SearchData.FileSize.100mbto1gb=: 100MB-1GB

View File

@ -23,18 +23,15 @@ import org.sleuthkit.datamodel.AbstractFile;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.logging.Level;
import org.openide.util.NbBundle; 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.corecomponents.DataResultViewerTable; import org.sleuthkit.autopsy.corecomponents.DataResultViewerTable;
import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.Logger;
import static org.sleuthkit.autopsy.discovery.search.SearchData.Type.OTHER; import static org.sleuthkit.autopsy.discovery.search.SearchData.Type.OTHER;
import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.Content; import org.sleuthkit.datamodel.Content;
import org.sleuthkit.datamodel.ContentTag;
import org.sleuthkit.datamodel.HashUtility; import org.sleuthkit.datamodel.HashUtility;
import org.sleuthkit.datamodel.Tag; import org.sleuthkit.datamodel.Score;
import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.datamodel.TskCoreException;
import org.sleuthkit.datamodel.TskData; import org.sleuthkit.datamodel.TskData;
@ -49,7 +46,7 @@ public class ResultFile extends Result {
private final List<String> interestingSetNames; private final List<String> interestingSetNames;
private final List<String> objectDetectedNames; private final List<String> objectDetectedNames;
private final List<AbstractFile> instances = new ArrayList<>(); private final List<AbstractFile> instances = new ArrayList<>();
private DataResultViewerTable.Score currentScore = DataResultViewerTable.Score.NO_SCORE; private Score currentScore = Score.SCORE_UNKNOWN;
private String scoreDescription = null; private String scoreDescription = null;
private boolean deleted = false; private boolean deleted = false;
private Type fileType; private Type fileType;
@ -108,7 +105,7 @@ public class ResultFile extends Result {
* *
* @return The score of this ResultFile. * @return The score of this ResultFile.
*/ */
public DataResultViewerTable.Score getScore() { public Score getScore() {
return currentScore; return currentScore;
} }
@ -286,56 +283,22 @@ public class ResultFile extends Result {
} }
} }
/**
* Get all tags from the case database that are associated with the file
*
* @return a list of tags that are associated with the file
*/
private List<ContentTag> getContentTagsFromDatabase(AbstractFile file) {
List<ContentTag> tags = new ArrayList<>();
try {
tags.addAll(Case.getCurrentCaseThrows().getServices().getTagsManager().getContentTagsByContent(file));
} catch (TskCoreException | NoCurrentCaseException ex) {
logger.log(Level.SEVERE, "Failed to get tags for file " + file.getName(), ex);
}
return tags;
}
@NbBundle.Messages({ @NbBundle.Messages({
"ResultFile.score.notableFile.description=At least one instance of the file was recognized as notable.", "# {0} - significanceDisplayName",
"ResultFile.score.interestingResult.description=At least one instance of the file has an interesting result associated with it.", "ResultFile_updateScoreAndDescription_description=Has an {0} analysis result score"
"ResultFile.score.taggedFile.description=At least one instance of the file has been tagged.", })
"ResultFile.score.notableTaggedFile.description=At least one instance of the file is tagged with a notable tag."})
private void updateScoreAndDescription(AbstractFile file) { private void updateScoreAndDescription(AbstractFile file) {
if (currentScore == DataResultViewerTable.Score.NOTABLE_SCORE) { Score score = Score.SCORE_UNKNOWN;
//already notable can return
return;
}
if (file.getKnown() == TskData.FileKnown.BAD) {
currentScore = DataResultViewerTable.Score.NOTABLE_SCORE;
scoreDescription = Bundle.ResultFile_score_notableFile_description();
return;
}
try { try {
if (currentScore == DataResultViewerTable.Score.NO_SCORE && !file.getArtifacts(BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT).isEmpty()) { score = Case.getCurrentCaseThrows().getSleuthkitCase().getScoringManager().getAggregateScore(file.getId());
currentScore = DataResultViewerTable.Score.INTERESTING_SCORE; } catch (NoCurrentCaseException | TskCoreException ex) {
scoreDescription = Bundle.ResultFile_score_interestingResult_description();
}
} catch (TskCoreException ex) {
logger.log(Level.WARNING, "Error getting artifacts for file: " + file.getName(), ex);
}
List<ContentTag> tags = getContentTagsFromDatabase(file);
if (!tags.isEmpty()) {
currentScore = DataResultViewerTable.Score.INTERESTING_SCORE;
scoreDescription = Bundle.ResultFile_score_taggedFile_description();
for (Tag tag : tags) {
if (tag.getName().getKnownStatus() == TskData.FileKnown.BAD) {
currentScore = DataResultViewerTable.Score.NOTABLE_SCORE;
scoreDescription = Bundle.ResultFile_score_notableTaggedFile_description();
return;
}
}
} }
this.currentScore = score;
String significanceDisplay = score.getSignificance().getDisplayName();
this.scoreDescription = Bundle.ResultFile_updateScoreAndDescription_description(significanceDisplay);
} }
/** /**

View File

@ -60,6 +60,7 @@ import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.BlackboardAttribute; import org.sleuthkit.datamodel.BlackboardAttribute;
import org.sleuthkit.datamodel.DataSource; import org.sleuthkit.datamodel.DataSource;
import org.sleuthkit.datamodel.IngestJobInfo; import org.sleuthkit.datamodel.IngestJobInfo;
import org.sleuthkit.datamodel.Score;
import org.sleuthkit.datamodel.SleuthkitCase; import org.sleuthkit.datamodel.SleuthkitCase;
import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.datamodel.TskCoreException;
@ -208,21 +209,31 @@ final class DiscoveryUiUtils {
*/ */
@ThreadConfined(type = ThreadConfined.ThreadType.AWT) @ThreadConfined(type = ThreadConfined.ThreadType.AWT)
static void setScoreIcon(ResultFile resultFile, javax.swing.JLabel scoreLabel) { static void setScoreIcon(ResultFile resultFile, javax.swing.JLabel scoreLabel) {
switch (resultFile.getScore()) { ImageIcon icon = null;
case NOTABLE_SCORE:
scoreLabel.setIcon(NOTABLE_SCORE_ICON); Score score = resultFile.getScore();
break; if (score != null && score.getSignificance() != null) {
case INTERESTING_SCORE: switch (score.getSignificance()) {
scoreLabel.setIcon(INTERESTING_SCORE_ICON); case NOTABLE:
break; icon = NOTABLE_SCORE_ICON;
case NO_SCORE: // empty case - this is interpreted as an intentional fall-through break;
default: case LIKELY_NOTABLE:
scoreLabel.setIcon(null); icon = INTERESTING_SCORE_ICON;
break; break;
case LIKELY_NONE:
case NONE:
case UNKNOWN:
default:
icon = null;
break;
}
} }
scoreLabel.setIcon(icon);
scoreLabel.setToolTipText(resultFile.getScoreDescription()); scoreLabel.setToolTipText(resultFile.getScoreDescription());
} }
/** /**
* Get the size of the icons used by the UI. * Get the size of the icons used by the UI.
* *