8070 analysis result content viewer short description

This commit is contained in:
Greg DiCristofaro 2021-09-30 12:30:14 -04:00
parent b940f38951
commit daa244f55a
2 changed files with 54 additions and 31 deletions

View File

@ -32,7 +32,6 @@ import org.sleuthkit.autopsy.contentviewers.analysisresults.AnalysisResultsViewM
import org.sleuthkit.autopsy.contentviewers.layout.ContentViewerHtmlStyles; import org.sleuthkit.autopsy.contentviewers.layout.ContentViewerHtmlStyles;
import org.sleuthkit.autopsy.coreutils.EscapeUtil; import org.sleuthkit.autopsy.coreutils.EscapeUtil;
import org.sleuthkit.datamodel.AnalysisResult; import org.sleuthkit.datamodel.AnalysisResult;
import org.sleuthkit.datamodel.Content;
import org.sleuthkit.datamodel.Score; import org.sleuthkit.datamodel.Score;
/** /**
@ -86,7 +85,7 @@ public class AnalysisResultsContentPanel extends javax.swing.JPanel {
Document document = Jsoup.parse(EMPTY_HTML); Document document = Jsoup.parse(EMPTY_HTML);
Element body = document.getElementsByTag("body").first(); Element body = document.getElementsByTag("body").first();
Optional<Element> panelHeader = appendPanelHeader(body, nodeResults.getContent(), nodeResults.getAggregateScore()); Optional<Element> panelHeader = appendPanelHeader(body, nodeResults.getItemName(), nodeResults.getAggregateScore());
// for each analysis result item, display the data. // for each analysis result item, display the data.
List<ResultDisplayAttributes> displayAttributes = nodeResults.getAnalysisResults(); List<ResultDisplayAttributes> displayAttributes = nodeResults.getAnalysisResults();
@ -126,30 +125,27 @@ public class AnalysisResultsContentPanel extends javax.swing.JPanel {
"AnalysisResultsContentPanel_aggregateScore_displayKey=Aggregate Score", "AnalysisResultsContentPanel_aggregateScore_displayKey=Aggregate Score",
"AnalysisResultsContentPanel_content_displayKey=Item" "AnalysisResultsContentPanel_content_displayKey=Item"
}) })
private Optional<Element> appendPanelHeader(Element parent, Optional<Content> content, Optional<Score> score) { private Optional<Element> appendPanelHeader(Element parent, Optional<String> itemName, Optional<Score> score) {
if (!content.isPresent() || !score.isPresent()) { // if no item name or score, don't display
if (!itemName.isPresent() || !score.isPresent()) {
return Optional.empty(); return Optional.empty();
} }
Element container = parent.appendElement("div"); Element container = parent.appendElement("div");
// if there is content append the name // if there is content append the name
content.ifPresent((c) -> {
container.appendElement("p") container.appendElement("p")
.attr("class", ContentViewerHtmlStyles.getTextClassName()) .attr("class", ContentViewerHtmlStyles.getTextClassName())
.text(MessageFormat.format("{0}: {1}", .text(MessageFormat.format("{0}: {1}",
Bundle.AnalysisResultsContentPanel_content_displayKey(), Bundle.AnalysisResultsContentPanel_content_displayKey(),
c.getName())); itemName.get()));
});
// if there is an aggregate score, append the value // if there is an aggregate score, append the value
score.ifPresent((s) -> {
container.appendElement("p") container.appendElement("p")
.attr("class", ContentViewerHtmlStyles.getTextClassName()) .attr("class", ContentViewerHtmlStyles.getTextClassName())
.text(MessageFormat.format("{0}: {1}", .text(MessageFormat.format("{0}: {1}",
Bundle.AnalysisResultsContentPanel_aggregateScore_displayKey(), Bundle.AnalysisResultsContentPanel_aggregateScore_displayKey(),
s.getSignificance().getDisplayName())); score.get().getSignificance().getDisplayName()));
});
return Optional.ofNullable(container); return Optional.ofNullable(container);
} }

View File

@ -33,6 +33,7 @@ import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.datamodel.AnalysisResultItem; import org.sleuthkit.autopsy.datamodel.AnalysisResultItem;
import org.sleuthkit.autopsy.datamodel.TskContentItem; import org.sleuthkit.autopsy.datamodel.TskContentItem;
import org.sleuthkit.datamodel.AnalysisResult; import org.sleuthkit.datamodel.AnalysisResult;
import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.Content; import org.sleuthkit.datamodel.Content;
import org.sleuthkit.datamodel.Score; import org.sleuthkit.datamodel.Score;
import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.datamodel.TskCoreException;
@ -93,7 +94,7 @@ public class AnalysisResultsViewModel {
private final List<ResultDisplayAttributes> analysisResults; private final List<ResultDisplayAttributes> analysisResults;
private final Optional<AnalysisResult> selectedResult; private final Optional<AnalysisResult> selectedResult;
private final Optional<Score> aggregateScore; private final Optional<Score> aggregateScore;
private final Optional<Content> content; private final Optional<String> itemName;
/** /**
* Constructor. * Constructor.
@ -103,12 +104,15 @@ public class AnalysisResultsViewModel {
* selected. * selected.
* @param aggregateScore The aggregate score or empty if no score. * @param aggregateScore The aggregate score or empty if no score.
* @param content The content associated with these results. * @param content The content associated with these results.
* @param itemName The name of the selected item to display to
* the user.
*/ */
NodeResults(List<ResultDisplayAttributes> analysisResults, Optional<AnalysisResult> selectedResult, Optional<Score> aggregateScore, Optional<Content> content) { NodeResults(List<ResultDisplayAttributes> analysisResults, Optional<AnalysisResult> selectedResult,
Optional<Score> aggregateScore, Optional<String> itemName) {
this.analysisResults = analysisResults; this.analysisResults = analysisResults;
this.selectedResult = selectedResult; this.selectedResult = selectedResult;
this.aggregateScore = aggregateScore; this.aggregateScore = aggregateScore;
this.content = content; this.itemName = itemName;
} }
/** /**
@ -139,14 +143,12 @@ public class AnalysisResultsViewModel {
} }
/** /**
* Returns the content associated with these results or empty if not * Returns the name of the selected item to display to the user.
* present.
* *
* @return The content associated with these results or empty if not * @return The name of the selected item to display to the user.
* present.
*/ */
Optional<Content> getContent() { Optional<String> getItemName() {
return content; return itemName;
} }
} }
@ -224,6 +226,25 @@ public class AnalysisResultsViewModel {
.collect(Collectors.toList()); .collect(Collectors.toList());
} }
/**
* Returns the item's name to display in the header for the panel.
*
* @param selectedContent The selected content.
*
* @return The name to use for the content.
*
* @throws TskCoreException
*/
private String getName(Content selectedContent) throws TskCoreException {
if (selectedContent == null) {
return null;
} else if (selectedContent instanceof BlackboardArtifact) {
return ((BlackboardArtifact) selectedContent).getShortDescription();
} else {
return selectedContent.getName();
}
}
/** /**
* Returns the view model data representing the analysis results to be * Returns the view model data representing the analysis results to be
* displayed for the node. * displayed for the node.
@ -237,13 +258,14 @@ public class AnalysisResultsViewModel {
return new NodeResults(Collections.emptyList(), Optional.empty(), Optional.empty(), Optional.empty()); return new NodeResults(Collections.emptyList(), Optional.empty(), Optional.empty(), Optional.empty());
} }
Content analyzedContent = null; String contentName = null;
AnalysisResult selectedAnalysisResult = null; AnalysisResult selectedAnalysisResult = null;
Score aggregateScore = null; Score aggregateScore = null;
List<AnalysisResult> analysisResults = Collections.emptyList(); List<AnalysisResult> analysisResults = Collections.emptyList();
long selectedObjectId = 0; long selectedObjectId = 0;
try { try {
AnalysisResultItem analysisResultItem = node.getLookup().lookup(AnalysisResultItem.class); AnalysisResultItem analysisResultItem = node.getLookup().lookup(AnalysisResultItem.class);
Content analyzedContent;
if (Objects.nonNull(analysisResultItem)) { if (Objects.nonNull(analysisResultItem)) {
/* /*
* The content represented by the Node is an analysis result. * The content represented by the Node is an analysis result.
@ -266,6 +288,8 @@ public class AnalysisResultsViewModel {
} }
aggregateScore = analyzedContent.getAggregateScore(); aggregateScore = analyzedContent.getAggregateScore();
analysisResults = analyzedContent.getAllAnalysisResults(); analysisResults = analyzedContent.getAllAnalysisResults();
contentName = getName(analyzedContent);
} catch (TskCoreException ex) { } catch (TskCoreException ex) {
logger.log(Level.SEVERE, String.format("Error getting analysis result data for selected Content (object ID=%d)", selectedObjectId), ex); logger.log(Level.SEVERE, String.format("Error getting analysis result data for selected Content (object ID=%d)", selectedObjectId), ex);
} }
@ -274,7 +298,10 @@ public class AnalysisResultsViewModel {
* Use the data collected above to construct the view model. * Use the data collected above to construct the view model.
*/ */
List<ResultDisplayAttributes> displayAttributes = getOrderedDisplayAttributes(analysisResults); List<ResultDisplayAttributes> displayAttributes = getOrderedDisplayAttributes(analysisResults);
return new NodeResults(displayAttributes, Optional.ofNullable(selectedAnalysisResult), Optional.ofNullable(aggregateScore), Optional.ofNullable(analyzedContent)); return new NodeResults(displayAttributes,
Optional.ofNullable(selectedAnalysisResult),
Optional.ofNullable(aggregateScore),
Optional.ofNullable(contentName));
} }
} }