start on data artifact node and three panel dao

This commit is contained in:
Greg DiCristofaro 2021-10-04 14:27:38 -04:00
parent 306c045fbe
commit 1bf360f2cc
2 changed files with 1272 additions and 56 deletions

File diff suppressed because it is too large Load Diff

View File

@ -7,10 +7,34 @@ package org.sleuthkit.autopsy.datamodel;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.ExecutionException;
import java.util.stream.Collectors;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.Blackboard;
import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.BlackboardAttribute;
import org.sleuthkit.datamodel.Content;
import org.sleuthkit.datamodel.DataArtifact;
import org.sleuthkit.datamodel.HostAddress;
import org.sleuthkit.datamodel.Image;
import org.sleuthkit.datamodel.OsAccount;
import org.sleuthkit.datamodel.Pool;
import org.sleuthkit.datamodel.SleuthkitCase;
import org.sleuthkit.datamodel.TskCoreException;
import org.sleuthkit.datamodel.TskData;
import org.sleuthkit.datamodel.Volume;
import org.sleuthkit.datamodel.VolumeSystem;
/**
*
@ -18,19 +42,127 @@ import org.sleuthkit.datamodel.BlackboardArtifact;
*/
public class ThreePanelDAO {
private static ThreePanelDAO instance = null;
public synchronized static ThreePanelDAO getInstance() {
if (instance == null) {
instance = new ThreePanelDAO();
}
return instance;
}
private final Cache<TableCacheKey, DataArtifactTableDTO> tableCache = CacheBuilder.newBuilder().maximumSize(1000).build();
private DataArtifactTableDTO fetchDataArtifactsForTable(TableCacheKey cacheKey) {
// GVDTODO
private SleuthkitCase getCase() throws NoCurrentCaseException {
return Case.getCurrentCaseThrows().getSleuthkitCase();
}
private DataArtifactTableDTO fetchDataArtifactsForTable(TableCacheKey cacheKey) throws NoCurrentCaseException, TskCoreException {
SleuthkitCase skCase = getCase();
Blackboard blackboard = skCase.getBlackboard();
Long dataSourceId = cacheKey.getDataSourceId();
BlackboardArtifact.Type artType = cacheKey.getArtifactType();
// get data artifacts
List<DataArtifact> arts = (dataSourceId != null)
? blackboard.getDataArtifacts(artType.getTypeID(), dataSourceId)
: blackboard.getDataArtifacts(artType.getTypeID());
// determine all different attribute types present as well as row data for each artifact
Set<BlackboardAttribute.Type> attributeTypes = new HashSet<>();
List<DataArtifactRow> rows = new ArrayList<>();
for (DataArtifact artifact : arts) {
long id = artifact.getId();
Map<String, Object> attributeValues = new HashMap<>();
for (BlackboardAttribute attr : artifact.getAttributes()) {
attributeTypes.add(attr.getAttributeType());
attributeValues.put(attr.getAttributeType().getTypeName(), getAttrValue(attr));
}
Object linkedId = attributeValues.get(BlackboardAttribute.Type.TSK_PATH_ID.getTypeName());
AbstractFile linkedFile = linkedId instanceof Long && ((Long) linkedId) >= 0
? skCase.getAbstractFileById((Long) linkedId)
: null;
Content srcContent = artifact.getParent();
String srcContentTypeName = getSourceObjType(srcContent);
rows.add(new DataArtifactRow(id, attributeValues, srcContent, srcContentTypeName, linkedFile));
}
List<BlackboardAttribute.Type> attributeTypeSortedList = attributeTypes.stream()
.sorted((a, b) -> a.getDisplayName().compareToIgnoreCase(b.getDisplayName()))
.collect(Collectors.toList());
return new DataArtifactTableDTO(artType, attributeTypeSortedList, rows);
}
/**
* Returns a displayable type string for the given content object.
*
* If the content object is a artifact of a custom type then this method may
* cause a DB call BlackboardArtifact.getType
*
* @param source The object to determine the type of.
*
* @return A string representing the content type.
*/
private String getSourceObjType(Content source) throws TskCoreException {
if (source instanceof BlackboardArtifact) {
BlackboardArtifact srcArtifact = (BlackboardArtifact) source;
return srcArtifact.getType().getDisplayName();
} else if (source instanceof Volume) {
return TskData.ObjectType.VOL.toString();
} else if (source instanceof AbstractFile) {
return TskData.ObjectType.ABSTRACTFILE.toString();
} else if (source instanceof Image) {
return TskData.ObjectType.IMG.toString();
} else if (source instanceof VolumeSystem) {
return TskData.ObjectType.VS.toString();
} else if (source instanceof OsAccount) {
return TskData.ObjectType.OS_ACCOUNT.toString();
} else if (source instanceof HostAddress) {
return TskData.ObjectType.HOST_ADDRESS.toString();
} else if (source instanceof Pool) {
return TskData.ObjectType.POOL.toString();
}
return "";
}
private Object getAttrValue(BlackboardAttribute attr) {
switch (attr.getAttributeType().getValueType()) {
case BYTE:
return attr.getValueBytes();
case DATETIME:
new Date(attr.getValueLong() * 1000);
case DOUBLE:
return attr.getValueDouble();
case INTEGER:
return attr.getValueInt();
case JSON:
return attr.getValueString();
case LONG:
return attr.getValueLong();
case STRING:
return attr.getValueString();
default:
throw new IllegalArgumentException("Unknown attribute type value type: " + attr.getAttributeType().getValueType());
}
}
public DataArtifactTableDTO getDataArtifactsForTable(BlackboardArtifact.Type artType, Long dataSourceId) throws ExecutionException {
if (artType == null || artType.getCategory() != BlackboardArtifact.Category.DATA_ARTIFACT) {
throw new IllegalArgumentException(MessageFormat.format("Illegal data. "
+ "Artifact type must be non-null and data artifact. "
+ "Received {0}", artType));
}
TableCacheKey cacheKey = new TableCacheKey(artType, dataSourceId);
return tableCache.get(cacheKey, () -> fetchDataArtifactsForTable(cacheKey));
}
public void dropTableCache() {
tableCache.invalidateAll();
}
@ -40,6 +172,7 @@ public class ThreePanelDAO {
}
private static class TableCacheKey {
private final BlackboardArtifact.Type artifactType;
private final Long dataSourceId;
@ -85,69 +218,70 @@ public class ThreePanelDAO {
return true;
}
}
public static class ColumnKey {
private final String key;
private final String displayName;
private final String description;
public ColumnKey(String key, String displayName, String description) {
this.key = key;
this.displayName = displayName;
this.description = description;
}
public String getKey() {
return key;
}
public String getDisplayName() {
return displayName;
}
public String getDescription() {
return description;
}
}
public static class DataArtifactIntrinsicData {
// GVDTODO
}
public static class DataArtifactRow {
private final List<Object> rowData;
private final DataArtifactIntrinsicData intrinsicData;
public DataArtifactRow(List<Object> rowData, DataArtifactIntrinsicData intrinsicData) {
this.rowData = rowData;
this.intrinsicData = intrinsicData;
private final long id;
private final Map<String, Object> attributeValues;
private final Content srcContent;
private final String srcContentTypeName;
private final Content linkedFile;
private String dataSourceName;
public DataArtifactRow(long id, Map<String, Object> attributeValues, Content srcContent, String srcContentTypeName, Content linkedFile) {
this.id = id;
this.attributeValues = attributeValues;
this.srcContent = srcContent;
this.srcContentTypeName = srcContentTypeName;
this.linkedFile = linkedFile;
}
public List<Object> getRowData() {
return rowData;
public long getId() {
return id;
}
public DataArtifactIntrinsicData getIntrinsicData() {
return intrinsicData;
}
public Map<String, Object> getAttributeValues() {
return attributeValues;
}
public Content getSrcContent() {
return srcContent;
}
public String getSrcContentTypeName() {
return srcContentTypeName;
}
public Content getLinkedFile() {
return linkedFile;
}
public String getDataSourceName() {
return dataSourceName;
}
}
public static class DataArtifactTableDTO {
private final List<ColumnKey> columnHeaders;
private final BlackboardArtifact.Type artifactType;
private final List<BlackboardAttribute.Type> attributeTypes;
private final List<DataArtifactRow> rows;
public DataArtifactTableDTO(List<ColumnKey> columnHeaders, List<DataArtifactRow> rows) {
this.columnHeaders = columnHeaders;
public DataArtifactTableDTO(BlackboardArtifact.Type artifactType, List<BlackboardAttribute.Type> attributeKeys, List<DataArtifactRow> rows) {
this.artifactType = artifactType;
this.attributeTypes = attributeKeys;
this.rows = rows;
}
public List<ColumnKey> getColumnHeaders() {
return columnHeaders;
public BlackboardArtifact.Type getArtifactType() {
return artifactType;
}
public List<BlackboardAttribute.Type> getAttributeTypes() {
return attributeTypes;
}
public List<DataArtifactRow> getRows() {