changes to support view source

This commit is contained in:
Greg DiCristofaro 2021-09-02 20:33:27 -04:00
parent 1422a704b1
commit 0f9f12ae65
5 changed files with 106 additions and 53 deletions

View File

@ -43,6 +43,7 @@ import org.apache.commons.lang3.tuple.Pair;
import org.openide.nodes.Sheet;
import org.openide.util.Lookup;
import org.openide.util.NbBundle;
import org.openide.util.NbBundle.Messages;
import org.openide.util.WeakListeners;
import org.openide.util.lookup.Lookups;
import org.sleuthkit.autopsy.casemodule.Case;
@ -81,6 +82,7 @@ import org.sleuthkit.autopsy.texttranslation.TextTranslationService;
import org.sleuthkit.autopsy.datamodel.utils.FileNameTransTask;
import org.sleuthkit.datamodel.AnalysisResult;
import org.sleuthkit.datamodel.BlackboardArtifact.Category;
import org.sleuthkit.datamodel.DataArtifact;
import org.sleuthkit.datamodel.Score;
/**
@ -315,7 +317,9 @@ public class BlackboardArtifactNode extends AbstractContentNode<BlackboardArtifa
/**
* Returns the artifact type of the artifact.
*
* @param artifact The artifact.
*
* @return The artifact type or null if no type could be retrieved.
*/
private static BlackboardArtifact.Type getType(BlackboardArtifact artifact) {
@ -437,6 +441,19 @@ public class BlackboardArtifactNode extends AbstractContentNode<BlackboardArtifa
return this.artifact;
}
/**
* Returns the source content of the artifact.
*
* @return The source content of the artifact.
*/
@Beta
public Content getSourceContent() {
return this.srcContent;
}
@NbBundle.Messages({
"BlackboardArtifactNode_getActions_viewSourceDataArtifact=View Source Data Artifact in Timeline... "
})
@Override
public Action[] getActions(boolean context) {
List<Action> actionsList = new ArrayList<>();
@ -447,8 +464,8 @@ public class BlackboardArtifactNode extends AbstractContentNode<BlackboardArtifa
* action to view it in the timeline.
*/
try {
if (ViewArtifactInTimelineAction.hasSupportedTimeStamp(artifact) &&
// don't show ViewArtifactInTimelineAction for AnalysisResults.
if (ViewArtifactInTimelineAction.hasSupportedTimeStamp(artifact)
&& // don't show ViewArtifactInTimelineAction for AnalysisResults.
(!(this.artifact instanceof AnalysisResult))) {
actionsList.add(new ViewArtifactInTimelineAction(artifact));
@ -476,10 +493,17 @@ public class BlackboardArtifactNode extends AbstractContentNode<BlackboardArtifa
* If the source content of the artifact represented by this node is a
* file, add an action to view the file in the data source tree.
*/
AbstractFile file = getLookup().lookup(AbstractFile.class
);
if (null != file) {
actionsList.add(ViewFileInTimelineAction.createViewSourceFileAction(file));
if (this.srcContent instanceof AbstractFile) {
actionsList.add(ViewFileInTimelineAction.createViewSourceFileAction((AbstractFile) this.srcContent));
} else if (this.srcContent instanceof DataArtifact) {
try {
if (ViewArtifactInTimelineAction.hasSupportedTimeStamp((DataArtifact) this.srcContent)) {
actionsList.add(new ViewArtifactInTimelineAction((DataArtifact) this.srcContent,
Bundle.BlackboardArtifactNode_getActions_viewSourceDataArtifact()));
}
} catch (TskCoreException ex) {
logger.log(Level.SEVERE, MessageFormat.format("Error getting source data artifact timestamp (artifact objID={0})", this.srcContent.getId()), ex); //NON-NLS
}
}
return actionsList.toArray(new Action[actionsList.size()]);

View File

@ -78,6 +78,7 @@ BlackboardArtifactNode.createSheet.srcFile.origDisplayName=Original Name
BlackboardArtifactNode.createSheet.srcFile.origName=Original Name
BlackboardArtifactNode.createSheet.taggedItem.description=Result or associated file has been tagged.
BlackboardArtifactNode.createSheet.tags.displayName=Tags
BlackboardArtifactNode_getActions_viewSourceDataArtifact=View Source Data Artifact in Timeline...
BlackboardArtifactTagNode.createSheet.userName.text=User Name
BlackboardArtifactTagNode.viewSourceArtifact.text=View Source Result
Category.five=CAT-5: Non-pertinent

View File

@ -5,6 +5,12 @@ CSVWriter.progress.cancelling=Cancelling
CSVWriter.progress.extracting=Exporting to CSV file
CTL_DirectoryTreeTopComponent=Directory Tree
DataResultFilterNode.viewSourceArtifact.text=View Source Result
# {0} - contentType
DataResultFilterNode_getViewSourceDisplayName_baseMessage=View Source {0}
DataResultFilterNode_getViewSourceDisplayName_type_DataArtifact=Data Artifact
DataResultFilterNode_getViewSourceDisplayName_type_File=File
DataResultFilterNode_getViewSourceDisplayName_type_OSAccount=OS Account
DataResultFilterNode_getViewSourceDisplayName_type_Unknown=Content
# {0} - dataSourceCount
DirectoryTreeTopComponent.componentOpened.groupDataSources.text=This case contains {0} data sources. Would you like to group by data source for faster loading?
DirectoryTreeTopComponent.componentOpened.groupDataSources.title=Group by data source?

View File

@ -63,9 +63,9 @@ import org.sleuthkit.autopsy.datamodel.Reports;
import org.sleuthkit.autopsy.datamodel.SlackFileNode;
import org.sleuthkit.autopsy.commonpropertiessearch.CaseDBCommonAttributeInstanceNode;
import org.sleuthkit.autopsy.datamodel.VirtualDirectoryNode;
import static org.sleuthkit.autopsy.directorytree.Bundle.DataResultFilterNode_viewSourceArtifact_text;
import org.sleuthkit.autopsy.modules.embeddedfileextractor.ExtractArchiveWithPasswordAction;
import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.AnalysisResult;
import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.BlackboardAttribute;
import org.sleuthkit.datamodel.Content;
@ -80,6 +80,7 @@ import org.sleuthkit.datamodel.TskException;
import org.sleuthkit.datamodel.VirtualDirectory;
import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE;
import org.sleuthkit.datamodel.DataArtifact;
import org.sleuthkit.datamodel.OsAccount;
import org.sleuthkit.datamodel.Report;
import org.sleuthkit.datamodel.TskCoreException;
@ -256,6 +257,38 @@ public class DataResultFilterNode extends FilterNode {
}
}
/**
* Get the menu action for view source X (file, data artifact, os account)
* for an analysis result.
*
* @param content The content to navigate to.
*
* @return The ViewContextAction that will navigate to the specified content
* in the results / tree view to be used with an analysis result.
*/
@NbBundle.Messages({
"# {0} - contentType",
"DataResultFilterNode_getViewSourceDisplayName_baseMessage=View Source {0}",
"DataResultFilterNode_getViewSourceDisplayName_type_File=File",
"DataResultFilterNode_getViewSourceDisplayName_type_DataArtifact=Data Artifact",
"DataResultFilterNode_getViewSourceDisplayName_type_OSAccount=OS Account",
"DataResultFilterNode_getViewSourceDisplayName_type_Unknown=Content"
})
private static ViewContextAction getResultViewContext(Content content) {
String type = Bundle.DataResultFilterNode_getViewSourceDisplayName_type_Unknown();
if (content instanceof AbstractFile) {
type = Bundle.DataResultFilterNode_getViewSourceDisplayName_type_File();
} else if (content instanceof DataArtifact) {
type = Bundle.DataResultFilterNode_getViewSourceDisplayName_type_DataArtifact();
} else if (content instanceof OsAccount) {
type = Bundle.DataResultFilterNode_getViewSourceDisplayName_type_OSAccount();
}
String menuDisplayName = Bundle.DataResultFilterNode_getViewSourceDisplayName_baseMessage(type);
return new ViewContextAction(menuDisplayName, content);
}
@NbBundle.Messages("DataResultFilterNode.viewSourceArtifact.text=View Source Result")
/**
* Uses the default nodes actions per node, adds some custom ones and
@ -277,32 +310,8 @@ public class DataResultFilterNode extends FilterNode {
actionsList.add(a);
}
//Add seperator between the decorated actions and the actions from the node itself.
actionsList.add(null);
BlackboardArtifact ba = ban.getLookup().lookup(BlackboardArtifact.class);
final int artifactTypeID = ba.getArtifactTypeID();
if (artifactTypeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_HASHSET_HIT.getTypeID()
|| artifactTypeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_KEYWORD_HIT.getTypeID()) {
if (ban.getLookup().lookup(AbstractFile.class) != null) {
// We only want the "View File in Directory" actions if we have a file...it is
// possible that we have a keyword hit on a Report.
actionsList.add(new ViewContextAction(
NbBundle.getMessage(this.getClass(), "DataResultFilterNode.action.viewFileInDir.text"), ban));
}
} else if (artifactTypeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_ARTIFACT_HIT.getTypeID()) {
try {
if (ba.getAttribute(BlackboardAttribute.Type.TSK_ASSOCIATED_ARTIFACT) != null) {
//action to go to the source artifact
actionsList.add(new ViewSourceArtifactAction(DataResultFilterNode_viewSourceArtifact_text(), ba));
// action to go to the source file of the artifact
actionsList.add(new ViewContextAction(
NbBundle.getMessage(this.getClass(), "DataResultFilterNode.action.viewSrcFileInDir.text"), ban));
}
} catch (TskCoreException ex) {
LOGGER.log(Level.WARNING, "Error looking up attributes for artifact with ID=" + ba.getId());
}
if (ban.getArtifact() instanceof AnalysisResult) {
actionsList.add(getResultViewContext(ban.getSourceContent()));
} else {
// if the artifact links to another file, add an action to go to
// that file
@ -490,7 +499,7 @@ public class DataResultFilterNode extends FilterNode {
public AbstractAction visit(BlackboardArtifactNode ban) {
Action preferredAction = ban.getPreferredAction();
if(preferredAction instanceof AbstractAction) {
if (preferredAction instanceof AbstractAction) {
return (AbstractAction) preferredAction;
}
@ -567,7 +576,7 @@ public class DataResultFilterNode extends FilterNode {
// is a DirectoryTreeFilterNode that wraps the dataModelNode. We need
// to set that wrapped node as the selection and root context of the
// directory tree explorer manager (sourceEm)
if(sourceEm == null || sourceEm.getSelectedNodes().length == 0) {
if (sourceEm == null || sourceEm.getSelectedNodes().length == 0) {
return null;
}
final Node currentSelectionInDirectoryTree = sourceEm.getSelectedNodes()[0];
@ -610,7 +619,7 @@ public class DataResultFilterNode extends FilterNode {
* @return
*/
private AbstractAction openParent(AbstractNode node) {
if(sourceEm == null) {
if (sourceEm == null) {
return null;
}
// @@@ Why do we ignore node?

View File

@ -40,9 +40,22 @@ public final class ViewArtifactInTimelineAction extends AbstractAction {
private final BlackboardArtifact artifact;
/**
* Constructor.
* @param artifact The artifact to navigate to in the timeline.
*/
@NbBundle.Messages({"ViewArtifactInTimelineAction.displayName=View Result in Timeline... "})
public ViewArtifactInTimelineAction(BlackboardArtifact artifact) {
super(Bundle.ViewArtifactInTimelineAction_displayName());
this(artifact, Bundle.ViewArtifactInTimelineAction_displayName());
}
/**
* Constructor.
* @param artifact The artifact to navigate to in the timeline.
* @param displayName The display name for the action.
*/
public ViewArtifactInTimelineAction(BlackboardArtifact artifact, String displayName) {
super(displayName);
this.artifact = artifact;
// If timeline functionality is not available this action is disabled.
if ("false".equals(ModuleSettings.getConfigSetting("timeline", "enable_timeline"))) {