mirror of
https://github.com/elisspace/autopsy.git
synced 2026-09-06 02:24:30 +00:00
WIP towards view artifacts in timeline action
This commit is contained in:
@@ -6,20 +6,26 @@
|
||||
package org.sleuthkit.autopsy.datamodel;
|
||||
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.util.Collection;
|
||||
import java.util.LongSummaryStatistics;
|
||||
import java.util.stream.LongStream;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
import javax.swing.AbstractAction;
|
||||
import org.joda.time.Interval;
|
||||
import org.openide.util.Exceptions;
|
||||
import org.openide.util.Utilities;
|
||||
import org.openide.util.actions.SystemAction;
|
||||
import org.sleuthkit.autopsy.timeline.OpenTimelineAction;
|
||||
import org.sleuthkit.autopsy.timeline.datamodel.eventtype.ArtifactEventType;
|
||||
import org.sleuthkit.datamodel.AbstractFile;
|
||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||
import org.sleuthkit.datamodel.BlackboardAttribute;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class ViewInTimeLineAction extends AbstractAction {
|
||||
public class ViewInTimeLineAction extends AbstractAction {
|
||||
|
||||
// This class is a singleton to support multi-selection of nodes, since
|
||||
// org.openide.nodes.NodeOp.findActions(Node[] nodes) will only pick up an Action if every
|
||||
@@ -39,13 +45,28 @@ class ViewInTimeLineAction extends AbstractAction {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
Collection<? extends AbstractFile> selectedFiles = Utilities.actionsGlobalContext().lookupAll(AbstractFile.class);
|
||||
TreeSet<Long> timestamps = Utilities.actionsGlobalContext().lookupAll(AbstractFile.class).stream()
|
||||
.flatMap(file -> Stream.of(file.getAtime(), file.getCrtime(), file.getCtime(), file.getMtime()))
|
||||
.collect(Collectors.toCollection(TreeSet::new));
|
||||
|
||||
LongSummaryStatistics summaryStatistics = selectedFiles.stream()
|
||||
.flatMapToLong(file -> LongStream.of(file.getAtime(), file.getCrtime(), file.getCtime(), file.getMtime()))
|
||||
.summaryStatistics();
|
||||
//for each artifact, get all datetime attributes for that artifact type
|
||||
for (BlackboardArtifact bbart : Utilities.actionsGlobalContext().lookupAll(BlackboardArtifact.class)) {
|
||||
Set<BlackboardAttribute.ATTRIBUTE_TYPE> attributeTypes = ArtifactEventType.getAllArtifactEventTypes().stream()
|
||||
.filter(artEventType -> bbart.getArtifactTypeID() == artEventType.getArtifactType().getTypeID())
|
||||
.map(ArtifactEventType::getDateTimeAttrubuteType)
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
Interval interval = new Interval(summaryStatistics.getMin() * 1000, 1 + summaryStatistics.getMax() * 1000);
|
||||
for (BlackboardAttribute.ATTRIBUTE_TYPE type : attributeTypes) {
|
||||
try {
|
||||
Set<Long> collect1 = bbart.getAttributes(type).stream().map(BlackboardAttribute::getValueLong).collect(Collectors.toSet());
|
||||
timestamps.addAll(collect1);
|
||||
} catch (TskCoreException ex) {
|
||||
Exceptions.printStackTrace(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Interval interval = new Interval(timestamps.first() * 1000, 1 + timestamps.last() * 1000);
|
||||
|
||||
SystemAction.get(OpenTimelineAction.class).showTimeline(interval);
|
||||
}
|
||||
|
||||
@@ -66,8 +66,10 @@ import org.sleuthkit.autopsy.datamodel.RecentFilesFilterNode;
|
||||
import org.sleuthkit.autopsy.datamodel.RecentFilesNode;
|
||||
import org.sleuthkit.autopsy.datamodel.Reports;
|
||||
import org.sleuthkit.autopsy.datamodel.Tags;
|
||||
import org.sleuthkit.autopsy.datamodel.ViewInTimeLineAction;
|
||||
import org.sleuthkit.autopsy.datamodel.VirtualDirectoryNode;
|
||||
import org.sleuthkit.autopsy.datamodel.VolumeNode;
|
||||
import org.sleuthkit.autopsy.timeline.datamodel.eventtype.ArtifactEventType;
|
||||
import org.sleuthkit.datamodel.AbstractFile;
|
||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||
import org.sleuthkit.datamodel.BlackboardAttribute;
|
||||
@@ -77,6 +79,7 @@ import org.sleuthkit.datamodel.Directory;
|
||||
import org.sleuthkit.datamodel.File;
|
||||
import org.sleuthkit.datamodel.LayoutFile;
|
||||
import org.sleuthkit.datamodel.LocalFile;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
import org.sleuthkit.datamodel.TskException;
|
||||
import org.sleuthkit.datamodel.VirtualDirectory;
|
||||
|
||||
@@ -245,6 +248,21 @@ public class DataResultFilterNode extends FilterNode {
|
||||
actions.add(null);
|
||||
actions.add(AddBlackboardArtifactTagAction.getInstance());
|
||||
}
|
||||
|
||||
boolean hasTimeStamp = ArtifactEventType.getAllArtifactEventTypes().stream()
|
||||
.filter(artEventType -> artEventType.getArtifactType().getTypeID() == ba.getArtifactTypeID())
|
||||
.filter(artEventType -> {
|
||||
try {
|
||||
return ba.getAttributes(artEventType.getDateTimeAttrubuteType()).isEmpty() == false;
|
||||
} catch (TskCoreException ex) {
|
||||
Logger.getLogger(DataResultFilterNode.class.getName()).log(Level.WARNING, "Error retreiving blackboard arttributes from blackboard artifact.", ex);
|
||||
return false;
|
||||
}
|
||||
}).findAny().isPresent();
|
||||
if (hasTimeStamp){
|
||||
actions.add(ViewInTimeLineAction.getInstance());
|
||||
}
|
||||
|
||||
return actions;
|
||||
}
|
||||
|
||||
|
||||
@@ -21,8 +21,10 @@ package org.sleuthkit.autopsy.timeline.datamodel.eventtype;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.logging.Level;
|
||||
import java.util.stream.Collectors;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||
@@ -34,6 +36,13 @@ import org.sleuthkit.datamodel.TskCoreException;
|
||||
*/
|
||||
public interface ArtifactEventType extends EventType {
|
||||
|
||||
public static Set<ArtifactEventType> getAllArtifactEventTypes() {
|
||||
return allTypes.stream()
|
||||
.filter((EventType t) -> t instanceof ArtifactEventType)
|
||||
.map(ArtifactEventType.class::cast)
|
||||
.collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the Artifact type this event type is derived form, or null if
|
||||
* there is no artifact type (eg file system events)
|
||||
@@ -87,7 +96,8 @@ public interface ArtifactEventType extends EventType {
|
||||
|
||||
/**
|
||||
* bundles the per event information derived from a BlackBoard Artifact into
|
||||
* one object. Primarily used to have a single return value for {@link SubType#buildEventDescription(org.sleuthkit.datamodel.BlackboardArtifact).
|
||||
* one object. Primarily used to have a single return value for null null
|
||||
* null null {@link SubType#buildEventDescription(org.sleuthkit.datamodel.BlackboardArtifact).
|
||||
*/
|
||||
static class AttributeEventDescription {
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ import org.sleuthkit.autopsy.timeline.zooming.EventTypeZoomLevel;
|
||||
*/
|
||||
public interface EventType {
|
||||
|
||||
final static List<? extends EventType> allTypes = RootEventType.getInstance().getSubTypesRecusive();
|
||||
final static List<EventType> allTypes = RootEventType.getInstance().getSubTypesRecusive();
|
||||
|
||||
static Comparator<EventType> getComparator() {
|
||||
return Comparator.comparing(EventType.allTypes::indexOf);
|
||||
@@ -47,7 +47,7 @@ public interface EventType {
|
||||
}
|
||||
}
|
||||
|
||||
default List<? extends EventType> getSubTypesRecusive() {
|
||||
default List<EventType> getSubTypesRecusive() {
|
||||
ArrayList<EventType> flatList = new ArrayList<>();
|
||||
|
||||
for (EventType et : getSubTypes()) {
|
||||
@@ -56,6 +56,8 @@ public interface EventType {
|
||||
}
|
||||
return flatList;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @return the color used to represent this event type visually
|
||||
|
||||
@@ -443,7 +443,7 @@ public class EventsRepository {
|
||||
private final SleuthkitCase skCase;
|
||||
private final TagsManager tagsManager;
|
||||
|
||||
public DBPopulationWorker(Runnable postPopulationOperation) {
|
||||
DBPopulationWorker(Runnable postPopulationOperation) {
|
||||
progressDialog = new ProgressWindow(null, true, this);
|
||||
progressDialog.setVisible(true);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user