updates to navigate to os account

This commit is contained in:
Greg DiCristofaro 2021-09-03 08:43:26 -04:00
parent 0f9f12ae65
commit 3c82ec2e30
3 changed files with 151 additions and 18 deletions

View File

@ -63,10 +63,20 @@ public final class OsAccounts implements AutopsyVisitableItem {
private static final String ICON_PATH = "org/sleuthkit/autopsy/images/os-account.png";
private static final SimpleDateFormat DATE_FORMATTER = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z");
private static final String REALM_DATA_AVAILABLE_EVENT = "REALM_DATA_AVAILABLE_EVENT";
private static final String LIST_NAME = Bundle.OsAccount_listNode_name();
private SleuthkitCase skCase;
private final long filteringDSObjId;
/**
* Returns the name of the OsAccountListNode to be used for id purposes.
*
* @return The name of the OsAccountListNode to be used for id purposes.
*/
public static String getListName() {
return LIST_NAME;
}
public OsAccounts(SleuthkitCase skCase) {
this(skCase, 0);
}
@ -94,8 +104,8 @@ public final class OsAccounts implements AutopsyVisitableItem {
*/
public OsAccountListNode() {
super(Children.create(new OsAccountNodeFactory(), true));
setName(Bundle.OsAccount_listNode_name());
setDisplayName(Bundle.OsAccount_listNode_name());
setName(LIST_NAME);
setDisplayName(LIST_NAME);
setIconBaseWithExtension("org/sleuthkit/autopsy/images/os-account.png");
}

View File

@ -257,6 +257,54 @@ public class DataResultFilterNode extends FilterNode {
}
}
/**
* An action that navigates to an artifact.
*/
private static class ViewArtifactAction extends AbstractAction {
private final BlackboardArtifact artifact;
/**
* Main constructor.
*
* @param artifact The artifact to navigate to in the action.
* @param displayName The display name of the menu item.
*/
ViewArtifactAction(BlackboardArtifact artifact, String displayName) {
super(displayName);
this.artifact = artifact;
}
@Override
public void actionPerformed(ActionEvent e) {
DirectoryTreeTopComponent.findInstance().viewArtifact(artifact);
}
}
/**
* An action that navigates to an os account.
*/
private static class ViewOsAccountAction extends AbstractAction {
private final OsAccount osAccount;
/**
* Main constructor.
*
* @param osAccount The os account to navigate to in the action.
* @param displayName The display name of the menu item.
*/
ViewOsAccountAction(OsAccount osAccount, String displayName) {
super(displayName);
this.osAccount = osAccount;
}
@Override
public void actionPerformed(ActionEvent e) {
DirectoryTreeTopComponent.findInstance().viewOsAccount(osAccount);
}
}
/**
* Get the menu action for view source X (file, data artifact, os account)
* for an analysis result.
@ -271,22 +319,27 @@ public class DataResultFilterNode extends FilterNode {
"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"
"DataResultFilterNode_getViewSourceDisplayName_type_OSAccount=OS Account"
})
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();
private static Action getContentNavigateAction(Content content) {
if (content instanceof DataArtifact) {
return new ViewArtifactAction(
(DataArtifact) content,
Bundle.DataResultFilterNode_getViewSourceDisplayName_baseMessage(
Bundle.DataResultFilterNode_getViewSourceDisplayName_type_DataArtifact()));
} else if (content instanceof OsAccount) {
type = Bundle.DataResultFilterNode_getViewSourceDisplayName_type_OSAccount();
return new ViewOsAccountAction(
(OsAccount) content,
Bundle.DataResultFilterNode_getViewSourceDisplayName_baseMessage(
Bundle.DataResultFilterNode_getViewSourceDisplayName_type_OSAccount()));
} else if (content instanceof AbstractFile) {
return new ViewContextAction(
Bundle.DataResultFilterNode_getViewSourceDisplayName_baseMessage(
Bundle.DataResultFilterNode_getViewSourceDisplayName_type_File()),
content);
} else {
return null;
}
String menuDisplayName = Bundle.DataResultFilterNode_getViewSourceDisplayName_baseMessage(type);
return new ViewContextAction(menuDisplayName, content);
}
@NbBundle.Messages("DataResultFilterNode.viewSourceArtifact.text=View Source Result")
@ -311,7 +364,10 @@ public class DataResultFilterNode extends FilterNode {
}
if (ban.getArtifact() instanceof AnalysisResult) {
actionsList.add(getResultViewContext(ban.getSourceContent()));
Action contentNavigateAction = getContentNavigateAction(ban.getSourceContent());
if (contentNavigateAction != null) {
actionsList.add(contentNavigateAction);
}
} else {
// if the artifact links to another file, add an action to go to
// that file

View File

@ -83,6 +83,7 @@ import org.sleuthkit.autopsy.datamodel.InterestingHits;
import org.sleuthkit.autopsy.datamodel.KeywordHits;
import org.sleuthkit.autopsy.datamodel.AutopsyTreeChildFactory;
import org.sleuthkit.autopsy.datamodel.DataArtifacts;
import org.sleuthkit.autopsy.datamodel.OsAccounts;
import org.sleuthkit.autopsy.datamodel.PersonNode;
import org.sleuthkit.autopsy.datamodel.Tags;
import org.sleuthkit.autopsy.datamodel.ViewsNode;
@ -95,6 +96,7 @@ import org.sleuthkit.datamodel.BlackboardAttribute;
import org.sleuthkit.datamodel.Content;
import org.sleuthkit.datamodel.DataSource;
import org.sleuthkit.datamodel.Host;
import org.sleuthkit.datamodel.OsAccount;
import org.sleuthkit.datamodel.Person;
import org.sleuthkit.datamodel.TskCoreException;
@ -1220,6 +1222,71 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat
.findFirst();
}
/**
* Does depth-first search to find os account list node where the provided os account is a child.
* @param node The node.
* @param osAccount The os account.
* @return The parent list node of the os account if found or empty if not.
*/
private Optional<Node> getOsAccountListNode(Node node, OsAccount osAccount) {
if (node == null) {
return Optional.empty();
} else if (node.getLookup().lookup(Host.class) != null
|| node.getLookup().lookup(Person.class) != null
|| PersonNode.getUnknownPersonId().equals(node.getLookup().lookup(String.class))
|| node.getLookup().lookup(DataSource.class) != null) {
return Stream.of(node.getChildren().getNodes(true))
.map(childNode -> getOsAccountListNode(childNode, osAccount))
.filter(Optional::isPresent)
.map(Optional::get)
.findFirst();
} else if (OsAccounts.getListName().equals(node.getName())) {
boolean isOsAccountParent = Stream.of(node.getChildren().getNodes(true))
.filter(osAcctNd -> {
OsAccount osAcctOfNd = osAcctNd.getLookup().lookup(OsAccount.class);
return osAcctOfNd != null && osAcctOfNd.getId() == osAccount.getId();
})
.findFirst()
.isPresent();
return isOsAccountParent ? Optional.of(node) : Optional.empty();
} else {
return Optional.empty();
}
}
/**
* Navigates to the os account if the os account is found in the tree.
* @param osAccount The os account.
*/
void viewOsAccount(OsAccount osAccount) {
Optional<Node> osAccountListNodeOpt = Stream.of(em.getRootContext().getChildren().getNodes(true))
.map(nd -> getOsAccountListNode(nd, osAccount))
.filter(Optional::isPresent)
.map(Optional::get)
.findFirst();
if (!osAccountListNodeOpt.isPresent()) {
return;
}
Node osAccountListNode = osAccountListNodeOpt.get();
DisplayableItemNode undecoratedParentNode = (DisplayableItemNode) ((DirectoryTreeFilterNode) osAccountListNode).getOriginal();
undecoratedParentNode.setChildNodeSelectionInfo((osAcctNd) -> {
OsAccount osAcctOfNd = osAcctNd.getLookup().lookup(OsAccount.class);
return osAcctOfNd != null && osAcctOfNd.getId() == osAccount.getId();
});
getTree().expandNode(osAccountListNode);
try {
em.setExploredContextAndSelection(osAccountListNode, new Node[]{osAccountListNode});
} catch (PropertyVetoException ex) {
LOGGER.log(Level.WARNING, "Property Veto: ", ex); //NON-NLS
}
}
/**
* Attempts to retrieve the artifact type for the given artifact type id.
*