Merge pull request #2827 from wschaeferB/1895-ContextMenuForKeyValueNodes

1895 context menu for key value nodes
This commit is contained in:
Richard Cordovano 2017-06-09 12:48:40 -04:00 committed by GitHub
commit 6fb8a8fcbe
3 changed files with 95 additions and 13 deletions

View File

@ -1,7 +1,7 @@
/* /*
* Autopsy Forensic Browser * Autopsy Forensic Browser
* *
* Copyright 2011-2014 Basis Technology Corp. * Copyright 2011-2017 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org * Contact: carrier <at> sleuthkit <dot> org
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -18,13 +18,18 @@
*/ */
package org.sleuthkit.autopsy.datamodel; package org.sleuthkit.autopsy.datamodel;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map; import java.util.Map;
import javax.swing.Action;
import org.openide.nodes.AbstractNode; import org.openide.nodes.AbstractNode;
import org.openide.nodes.Children; import org.openide.nodes.Children;
import org.openide.nodes.Sheet; import org.openide.nodes.Sheet;
import org.openide.util.Lookup; import org.openide.util.Lookup;
import org.openide.util.NbBundle; import org.openide.util.NbBundle;
import org.openide.util.lookup.Lookups; import org.openide.util.lookup.Lookups;
import org.sleuthkit.autopsy.timeline.actions.ViewFileInTimelineAction;
import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.AbstractFile;
/** /**
@ -93,4 +98,26 @@ public class KeyValueNode extends AbstractNode {
return s; return s;
} }
/**
* Right click action for the nodes that we want to pass to the directory
* table and the output view.
*
* @param popup
*
* @return actions
*/
@Override
public Action[] getActions(boolean popup) {
List<Action> actions = new ArrayList<>();
actions.addAll(Arrays.asList(super.getActions(popup)));
//if this artifact has associated content, add the action to view the content in the timeline
AbstractFile file = getLookup().lookup(AbstractFile.class);
if (null != file) {
actions.add(ViewFileInTimelineAction.createViewSourceFileAction(file));
}
actions.add(null); // creates a menu separator
return actions.toArray(new Action[actions.size()]);
}
} }

View File

@ -29,6 +29,9 @@ import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.Content; import org.sleuthkit.datamodel.Content;
import org.sleuthkit.datamodel.ContentVisitor; import org.sleuthkit.datamodel.ContentVisitor;
import org.sleuthkit.datamodel.Directory; import org.sleuthkit.datamodel.Directory;
import org.sleuthkit.datamodel.LayoutFile;
import org.sleuthkit.datamodel.SlackFile;
import org.sleuthkit.datamodel.VirtualDirectory;
/** /**
* Searches for FsContent Files with the same MD5 hash as the given Node's * Searches for FsContent Files with the same MD5 hash as the given Node's
@ -90,6 +93,22 @@ public class HashDbSearchAction extends CallableSystemAction implements HashSear
protected AbstractFile defaultVisit(Content cntnt) { protected AbstractFile defaultVisit(Content cntnt) {
return null; return null;
} }
@Override
public AbstractFile visit(LayoutFile lf) {
// layout files do not have times
return lf;
}
@Override
public AbstractFile visit(SlackFile f) {
return f;
}
@Override
public AbstractFile visit(VirtualDirectory dir) {
return ContentUtils.isDotDirectory(dir) ? null : dir;
}
} }
/** /**
@ -100,7 +119,7 @@ public class HashDbSearchAction extends CallableSystemAction implements HashSear
@Override @Override
public void performAction() { public void performAction() {
// Make sure at least 1 file has an md5 hash // Make sure at least 1 file has an md5 hash
if (HashDbSearcher.countFilesMd5Hashed() > 0) { if (file != null && HashDbSearcher.countFilesMd5Hashed() > 0) {
doSearch(); doSearch();
} else { } else {
JOptionPane.showMessageDialog(null, JOptionPane.showMessageDialog(null,

View File

@ -19,6 +19,7 @@
package org.sleuthkit.autopsy.keywordsearch; package org.sleuthkit.autopsy.keywordsearch;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
@ -42,7 +43,13 @@ import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.Content; import org.sleuthkit.datamodel.Content;
import org.sleuthkit.datamodel.ContentVisitor; import org.sleuthkit.datamodel.ContentVisitor;
import org.sleuthkit.datamodel.DerivedFile; import org.sleuthkit.datamodel.DerivedFile;
import org.sleuthkit.datamodel.Directory;
import org.sleuthkit.datamodel.File; import org.sleuthkit.datamodel.File;
import org.sleuthkit.datamodel.LayoutFile;
import org.sleuthkit.datamodel.LocalFile;
import org.sleuthkit.datamodel.SlackFile;
import org.sleuthkit.datamodel.TskData;
import org.sleuthkit.datamodel.VirtualDirectory;
/** /**
* *
@ -92,7 +99,7 @@ class KeywordSearchFilterNode extends FilterNode {
public Action[] getActions(boolean popup) { public Action[] getActions(boolean popup) {
List<Action> actions = new ArrayList<>(); List<Action> actions = new ArrayList<>();
actions.addAll(Arrays.asList(super.getActions(popup)));
Content content = this.getOriginal().getLookup().lookup(Content.class); Content content = this.getOriginal().getLookup().lookup(Content.class);
actions.addAll(content.accept(new GetPopupActionsContentVisitor())); actions.addAll(content.accept(new GetPopupActionsContentVisitor()));
@ -103,37 +110,66 @@ class KeywordSearchFilterNode extends FilterNode {
@Override @Override
public List<Action> visit(File f) { public List<Action> visit(File f) {
return getFileActions(); return getFileActions(true);
} }
@Override @Override
public List<Action> visit(DerivedFile f) { public List<Action> visit(DerivedFile f) {
return getFileActions(); return getFileActions(true);
} }
private List<Action> getFileActions() { @Override
public List<Action> visit(Directory d) {
return getFileActions(false);
}
@Override
public List<Action> visit(LayoutFile lf) {
//we want hashsearch enabled on carved files but not unallocated blocks
boolean enableHashSearch = (lf.getType() == TskData.TSK_DB_FILES_TYPE_ENUM.CARVED);
return getFileActions(enableHashSearch);
}
@Override
public List<Action> visit(LocalFile lf) {
return getFileActions(true);
}
@Override
public List<Action> visit(SlackFile f) {
return getFileActions(false);
}
@Override
public List<Action> visit(VirtualDirectory dir) {
return getFileActions(false);
}
private List<Action> getFileActions(boolean enableHashSearch) {
List<Action> actionsList = new ArrayList<>(); List<Action> actionsList = new ArrayList<>();
actionsList.add(new NewWindowViewAction(NbBundle.getMessage(this.getClass(), "KeywordSearchFilterNode.getFileActions.viewInNewWinActionLbl"), KeywordSearchFilterNode.this)); actionsList.add(new NewWindowViewAction(NbBundle.getMessage(this.getClass(), "KeywordSearchFilterNode.getFileActions.viewInNewWinActionLbl"), KeywordSearchFilterNode.this));
actionsList.add(new ExternalViewerAction(NbBundle.getMessage(this.getClass(), "KeywordSearchFilterNode.getFileActions.openExternViewActLbl"), getOriginal())); actionsList.add(new ExternalViewerAction(NbBundle.getMessage(this.getClass(), "KeywordSearchFilterNode.getFileActions.openExternViewActLbl"), getOriginal()));
actionsList.add(null); actionsList.add(null);
actionsList.add(ExtractAction.getInstance()); actionsList.add(ExtractAction.getInstance());
actionsList.add(new HashSearchAction(NbBundle.getMessage(this.getClass(), "KeywordSearchFilterNode.getFileActions.searchSameMd5"), getOriginal())); Action hashSearchAction = new HashSearchAction(NbBundle.getMessage(this.getClass(), "KeywordSearchFilterNode.getFileActions.searchSameMd5"), getOriginal());
hashSearchAction.setEnabled(enableHashSearch);
actionsList.add(hashSearchAction);
actionsList.add(null); // creates a menu separator actionsList.add(null); // creates a menu separator
actionsList.add(AddContentTagAction.getInstance()); actionsList.add(AddContentTagAction.getInstance());
final Collection<AbstractFile> selectedFilesList = final Collection<AbstractFile> selectedFilesList
new HashSet<>(Utilities.actionsGlobalContext().lookupAll(AbstractFile.class)); = new HashSet<>(Utilities.actionsGlobalContext().lookupAll(AbstractFile.class));
if(selectedFilesList.size() == 1) { if (selectedFilesList.size() == 1) {
actionsList.add(DeleteFileContentTagAction.getInstance()); actionsList.add(DeleteFileContentTagAction.getInstance());
} }
actionsList.addAll(ContextMenuExtensionPoint.getActions()); actionsList.addAll(ContextMenuExtensionPoint.getActions());
return actionsList; return actionsList;
} }
@Override @Override
protected List<Action> defaultVisit(Content c) { protected List<Action> defaultVisit(Content c) {
return new ArrayList<>(); return getFileActions(false);
} }
} }
} }