1
0
mirror of https://github.com/elisspace/autopsy.git synced 2026-09-03 22:39:56 +00:00

Merge branch '3802_group_tree_by_datasource' of https://github.com/raman-bt/autopsy into 3802_group_tree_by_datasource

This commit is contained in:
Raman
2018-05-23 15:16:31 -04:00
13 changed files with 443 additions and 39 deletions

View File

@@ -20,6 +20,8 @@ package org.sleuthkit.autopsy.casemodule.services;
import java.io.Closeable;
import java.io.IOException;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
@@ -36,6 +38,8 @@ import org.sleuthkit.datamodel.BlackboardArtifactTag;
import org.sleuthkit.datamodel.Content;
import org.sleuthkit.datamodel.ContentTag;
import org.sleuthkit.datamodel.SleuthkitCase;
import org.sleuthkit.datamodel.SleuthkitCase.CaseDbQuery;
import org.sleuthkit.datamodel.Tag;
import org.sleuthkit.datamodel.TagName;
import org.sleuthkit.datamodel.TskCoreException;
import org.sleuthkit.datamodel.TskData;
@@ -157,6 +161,47 @@ public class TagsManager implements Closeable {
return caseDb.getTagNamesInUse();
}
/**
* Selects all of the rows from the tag_names table in the case database for
* which there is at least one matching row in the content_tags or
* blackboard_artifact_tags tables, for the given datasource object id.
*
* @return A list, possibly empty, of TagName data transfer objects (DTOs)
* for the rows.
*
* @throws TskCoreException
*/
public List<TagName> getTagNamesInUse(long dsObjId) throws TskCoreException {
ArrayList<TagName> tagNames = new ArrayList<>();
String queryStr = "SELECT * FROM tag_names "
+ "WHERE tag_name_id IN "
+ "( SELECT content_tags.tag_name_id as tag_name_id "
+ "FROM content_tags as content_tags, tsk_files as tsk_files"
+ " WHERE content_tags.obj_id = tsk_files.obj_id"
+ " AND tsk_files.data_source_obj_id = " + dsObjId
+ " UNION "
+ "SELECT artifact_tags.tag_name_id as tag_name_id "
+ " FROM blackboard_artifact_tags as artifact_tags, blackboard_artifacts AS arts "
+ " WHERE artifact_tags.artifact_id = arts.artifact_id"
+ " AND arts.data_source_obj_id = " + dsObjId
+ " )";
try (CaseDbQuery query = caseDb.executeQuery(queryStr);) {
ResultSet resultSet = query.getResultSet();
while (resultSet.next()) {
tagNames.add(new TagName(resultSet.getLong("tag_name_id"), resultSet.getString("display_name"),
resultSet.getString("description"), TagName.HTML_COLOR.getColorByName(resultSet.getString("color")),
TskData.FileKnown.valueOf(resultSet.getByte("knownStatus")))); //NON-NLS
}
return tagNames;
} catch (SQLException | TskCoreException ex) {
throw new TskCoreException("Failed to get tag names in use for data source objID : " + dsObjId, ex);
}
}
/**
* Gets a map of tag display names to tag name entries in the case database.
* It has keys for the display names of the standard tag types, the current
@@ -392,6 +437,46 @@ public class TagsManager implements Closeable {
return caseDb.getContentTagsCountByTagName(tagName);
}
/**
* Gets content tags count by tag name, for the given data source
*
* @param tagName The representation of the desired tag type in the case
* database, which can be obtained by calling getTagNames and/or addTagName.
*
* @param dsObjId data source object id
*
* @return A count of the content tags with the specified tag name, and for
* the given data source
*
* @throws TskCoreException If there is an error getting the tags count from
* the case database.
*/
public long getContentTagsCountByTagName(TagName tagName, long dsObjId) throws TskCoreException {
if (tagName.getId() == Tag.ID_NOT_SET) {
throw new TskCoreException("TagName object is invalid, id not set");
}
String queryStr =
"SELECT COUNT(*) AS count "
+ " FROM content_tags as content_tags, tsk_files as tsk_files "
+ " WHERE content_tags.obj_id = tsk_files.obj_id"
+ " AND tsk_files.data_source_obj_id = " + dsObjId
+ " AND content_tags.tag_name_id = " + tagName.getId();
try (CaseDbQuery query = caseDb.executeQuery(queryStr);) {
ResultSet resultSet = query.getResultSet();
if (resultSet.next()) {
return resultSet.getLong("count");
} else {
throw new TskCoreException("Error getting content_tags row count for tag name (tag_name_id = " + tagName.getId() + ")" + " for dsObjId = " + dsObjId );
}
} catch (SQLException | TskCoreException ex) {
throw new TskCoreException("Failed to get content_tags row count for tag_name_id = " + tagName.getId() + "data source objID : " + dsObjId, ex);
}
}
/**
* Gets a content tag by tag id.
*
@@ -421,6 +506,48 @@ public class TagsManager implements Closeable {
return caseDb.getContentTagsByTagName(tagName);
}
/**
* Gets content tags by tag name, for the given data source.
*
* @param tagName The tag name of interest.
*
* @param dsObjId
*
* @return A list, possibly empty, of the content tags with the specified
* tag name, and for the given data source.
*
* @throws TskCoreException If there is an error getting the tags from the
* case database.
*/
public List<ContentTag> getContentTagsByTagName(TagName tagName, long dsObjId) throws TskCoreException {
if (tagName.getId() == Tag.ID_NOT_SET) {
throw new TskCoreException("TagName object is invalid, id not set");
}
String queryStr =
"SELECT * "
+ " FROM content_tags as content_tags, tsk_files as tsk_files "
+ " WHERE content_tags.obj_id = tsk_files.obj_id"
+ " AND tsk_files.data_source_obj_id = " + dsObjId
+ " AND content_tags.tag_name_id = " + tagName.getId();
try (CaseDbQuery query = caseDb.executeQuery(queryStr);) {
ResultSet resultSet = query.getResultSet();
ArrayList<ContentTag> tags = new ArrayList<>();
while (resultSet.next()) {
ContentTag tag = new ContentTag(resultSet.getLong("tag_id"), caseDb.getContentById(resultSet.getLong("obj_id")),
tagName, resultSet.getString("comment"), resultSet.getLong("begin_byte_offset"), resultSet.getLong("end_byte_offset")); //NON-NLS
tags.add(tag);
}
resultSet.close();
return tags;
} catch (SQLException | TskCoreException ex) {
throw new TskCoreException("Failed to get content_tags row count for tag_name_id = " + tagName.getId() + "data source objID : " + dsObjId, ex);
}
}
/**
* Gets content tags count by content.
*
@@ -522,6 +649,45 @@ public class TagsManager implements Closeable {
return caseDb.getBlackboardArtifactTagsCountByTagName(tagName);
}
/**
* Gets an artifact tags count by tag name, for the given data source.
*
* @param tagName The representation of the desired tag type in the case
* database, which can be obtained by calling getTagNames
* and/or addTagName.
* @param dsObjId
*
* @return A count of the artifact tags with the specified tag name,
* for the given data source.
*
* @throws TskCoreException If there is an error getting the tags count from
* the case database.
*/
public long getBlackboardArtifactTagsCountByTagName(TagName tagName, long dsObjId) throws TskCoreException {
if (tagName.getId() == Tag.ID_NOT_SET) {
throw new TskCoreException("TagName object is invalid, id not set");
}
String queryStr = "SELECT COUNT(*) AS count "
+ " FROM blackboard_artifact_tags as artifact_tags, blackboard_artifacts AS arts "
+ " WHERE artifact_tags.artifact_id = arts.artifact_id"
+ " AND artifact_tags.tag_name_id = " + tagName.getId()
+ " AND arts.data_source_obj_id = " + dsObjId
;
try (CaseDbQuery query = Case.getCurrentCaseThrows().getSleuthkitCase().executeQuery(queryStr);) {
ResultSet resultSet = query.getResultSet();
if (resultSet.next()) {
return resultSet.getLong("count");
} else {
throw new TskCoreException("Error getting blackboard_artifact_tags row count for tag name (tag_name_id = " + tagName.getId() + ")" + " for dsObjId = " + dsObjId);
}
} catch (SQLException | TskCoreException | NoCurrentCaseException ex) {
throw new TskCoreException("Failed to get blackboard_artifact_tags row count for tag_name_id = " + tagName.getId() + "data source objID : " + dsObjId, ex);
}
}
/**
* Gets an artifact tag by tag id.
*
@@ -553,6 +719,49 @@ public class TagsManager implements Closeable {
return caseDb.getBlackboardArtifactTagsByTagName(tagName);
}
/**
* Gets artifact tags by tag name, for specified data source.
*
* @param tagName The representation of the desired tag type in the case
* database, which can be obtained by calling getTagNames
* and/or addTagName.
* @param dsObjId
*
* @return A list, possibly empty, of the artifact tags with the specified
* tag name, for the specified data source.
*
* @throws TskCoreException If there is an error getting the tags from the
* case database.
*/
public List<BlackboardArtifactTag> getBlackboardArtifactTagsByTagName(TagName tagName, long dsObjId) throws TskCoreException {
if (tagName.getId() == Tag.ID_NOT_SET) {
throw new TskCoreException("TagName object is invalid, id not set");
}
String queryStr = "SELECT * "
+ " FROM blackboard_artifact_tags as artifact_tags, blackboard_artifacts AS arts "
+ " WHERE artifact_tags.artifact_id = arts.artifact_id"
+ " AND artifact_tags.tag_name_id = " + tagName.getId()
+ " AND arts.data_source_obj_id = " + dsObjId
;
try (CaseDbQuery query = Case.getCurrentCaseThrows().getSleuthkitCase().executeQuery(queryStr);) {
ResultSet resultSet = query.getResultSet();
ArrayList<BlackboardArtifactTag> tags = new ArrayList<>();
while (resultSet.next()) {
BlackboardArtifact artifact = caseDb.getBlackboardArtifact(resultSet.getLong("artifact_id")); //NON-NLS
Content content = caseDb.getContentById(artifact.getObjectID());
BlackboardArtifactTag tag = new BlackboardArtifactTag(resultSet.getLong("tag_id"),
artifact, content, tagName, resultSet.getString("comment")); //NON-NLS
tags.add(tag);
}
return tags;
} catch (SQLException | TskCoreException | NoCurrentCaseException ex) {
throw new TskCoreException("Failed to get blackboard_artifact_tags row count for tag_name_id = " + tagName.getId() + "data source objID : " + dsObjId, ex);
}
}
/**
* Gets artifact tags for a particular artifact.
*

View File

@@ -192,7 +192,7 @@ abstract class AbstractContentChildren<T> extends Keys<T> {
@Override
public AbstractNode visit(Tags tagsNodeKey) {
return tagsNodeKey.new RootNode();
return tagsNodeKey.new RootNode(tagsNodeKey.filteringDataSourceObjId());
}
@Override
@@ -211,9 +211,8 @@ abstract class AbstractContentChildren<T> extends Keys<T> {
}
@Override
public AbstractNode visit(Results r) {
// RAMAN TBD JIRA-3763: pass dsObjID down here
return new ResultsNode(r.getSleuthkitCase());
public AbstractNode visit(Results results) {
return new ResultsNode(results.getSleuthkitCase(), results.filteringDataSourceObjId() );
}
@Override

View File

@@ -76,8 +76,8 @@ public class DataSourceGroupingNode extends DisplayableItemNode {
return new RootContentChildren(Arrays.asList(
new DataSources(dsObjId),
new Views(Case.getCurrentCaseThrows().getSleuthkitCase(), dsObjId),
new Results(Case.getCurrentCaseThrows().getSleuthkitCase()), // RAMAN TBD JIRA-3763: pass down dsObjId
new Tags() ) // RAMAN TBD JIRA-3762 : pass down dsObjId
new Results(Case.getCurrentCaseThrows().getSleuthkitCase(), dsObjId),
new Tags(dsObjId) )
);

View File

@@ -40,6 +40,7 @@ import org.openide.util.NbBundle;
import org.openide.util.lookup.Lookups;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
import org.sleuthkit.autopsy.core.UserPreferences;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.ingest.IngestManager;
import org.sleuthkit.autopsy.ingest.ModuleDataEvent;
@@ -86,10 +87,29 @@ public class EmailExtracted implements AutopsyVisitableItem {
}
private SleuthkitCase skCase;
private final EmailResults emailResults;
private final long datasourceObjId;
/**
* Constructor
*
* @param skCase Case DB
*/
public EmailExtracted(SleuthkitCase skCase) {
this(skCase, 0);
}
/**
* Constructor
*
* @param skCase Case DB
* @param objId Object id of the data source
*
*/
public EmailExtracted(SleuthkitCase skCase, long objId) {
this.skCase = skCase;
this.datasourceObjId = objId;
emailResults = new EmailResults();
}
@@ -141,6 +161,9 @@ public class EmailExtracted implements AutopsyVisitableItem {
+ "attribute_type_id=" + pathAttrId //NON-NLS
+ " AND blackboard_attributes.artifact_id=blackboard_artifacts.artifact_id" //NON-NLS
+ " AND blackboard_artifacts.artifact_type_id=" + artId; //NON-NLS
if (UserPreferences.groupItemsInTreeByDatasource()) {
query += " AND blackboard_artifacts.data_source_obj_id = " + datasourceObjId;
}
try (CaseDbQuery dbQuery = skCase.executeQuery(query)) {
ResultSet resultSet = dbQuery.getResultSet();

View File

@@ -39,6 +39,7 @@ import org.sleuthkit.autopsy.core.UserPreferences;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.ingest.IngestManager;
import org.sleuthkit.autopsy.ingest.ModuleDataEvent;
import org.sleuthkit.datamodel.Blackboard;
import org.sleuthkit.datamodel.BlackboardArtifact;
import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_ACCOUNT;
import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_EMAIL_MSG;
@@ -58,6 +59,7 @@ import org.sleuthkit.datamodel.TskException;
public class ExtractedContent implements AutopsyVisitableItem {
private SleuthkitCase skCase; // set to null after case has been closed
private Blackboard blackboard;
public static final String NAME = NbBundle.getMessage(RootNode.class, "ExtractedContentNode.name.text");
private final long datasourceObjId;
@@ -79,6 +81,7 @@ public class ExtractedContent implements AutopsyVisitableItem {
public ExtractedContent(SleuthkitCase skCase, long objId) {
this.skCase = skCase;
this.datasourceObjId = objId;
this.blackboard = new Blackboard(skCase);
}
@Override
@@ -288,8 +291,10 @@ public class ExtractedContent implements AutopsyVisitableItem {
//TEST COMMENT
if (skCase != null) {
try {
// RAMAN TBD JIRA-3763: filter on datasource obj id
List<BlackboardArtifact.Type> types = skCase.getArtifactTypesInUse();
List<BlackboardArtifact.Type> types = (UserPreferences.groupItemsInTreeByDatasource()) ?
blackboard.getArtifactTypesInUseByDataSource(datasourceObjId) :
skCase.getArtifactTypesInUse() ;
types.removeAll(doNotShow);
Collections.sort(types,
new Comparator<BlackboardArtifact.Type>() {
@@ -352,7 +357,7 @@ public class ExtractedContent implements AutopsyVisitableItem {
// "getBlackboardArtifactCount()" method to skCase
try {
this.childCount = UserPreferences.groupItemsInTreeByDatasource() ?
skCase.getBlackboardArtifactsCount(type.getTypeID(), datasourceObjId) :
blackboard.getBlackboardArtifactsCountByDataSource(type.getTypeID(), datasourceObjId) :
skCase.getBlackboardArtifactsTypeCount(type.getTypeID());
} catch (TskException ex) {
Logger.getLogger(TypeNode.class.getName())
@@ -477,7 +482,7 @@ public class ExtractedContent implements AutopsyVisitableItem {
try {
List<BlackboardArtifact> arts =
UserPreferences.groupItemsInTreeByDatasource() ?
skCase.getBlackboardArtifacts(TSK_ACCOUNT, datasourceObjId) :
blackboard.getBlackboardArtifactsByDataSource(type.getTypeID(), datasourceObjId) :
skCase.getBlackboardArtifacts(type.getTypeID());
list.addAll(arts);
} catch (TskException ex) {

View File

@@ -42,6 +42,7 @@ import org.openide.util.NbBundle;
import org.openide.util.lookup.Lookups;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
import org.sleuthkit.autopsy.core.UserPreferences;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.ingest.IngestManager;
import org.sleuthkit.autopsy.ingest.ModuleDataEvent;
@@ -63,9 +64,29 @@ public class HashsetHits implements AutopsyVisitableItem {
private static final Logger logger = Logger.getLogger(HashsetHits.class.getName());
private SleuthkitCase skCase;
private final HashsetResults hashsetResults;
private final long datasourceObjId;
/**
* Constructor
*
* @param skCase Case DB
*
*/
public HashsetHits(SleuthkitCase skCase) {
this(skCase, 0);
}
/**
* Constructor
*
* @param skCase Case DB
* @param objId Object id of the data source
*
*/
public HashsetHits(SleuthkitCase skCase, long objId) {
this.skCase = skCase;
this.datasourceObjId = objId;
hashsetResults = new HashsetResults();
}
@@ -120,7 +141,10 @@ public class HashsetHits implements AutopsyVisitableItem {
+ "attribute_type_id=" + setNameId //NON-NLS
+ " AND blackboard_attributes.artifact_id=blackboard_artifacts.artifact_id" //NON-NLS
+ " AND blackboard_artifacts.artifact_type_id=" + artId; //NON-NLS
if (UserPreferences.groupItemsInTreeByDatasource()) {
query += " AND blackboard_artifacts.data_source_obj_id = " + datasourceObjId;
}
try (CaseDbQuery dbQuery = skCase.executeQuery(query)) {
ResultSet resultSet = dbQuery.getResultSet();
synchronized (hashSetHitsMap) {

View File

@@ -42,6 +42,7 @@ import org.openide.util.NbBundle;
import org.openide.util.lookup.Lookups;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
import org.sleuthkit.autopsy.core.UserPreferences;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.ingest.IngestManager;
import org.sleuthkit.autopsy.ingest.ModuleDataEvent;
@@ -59,9 +60,28 @@ public class InterestingHits implements AutopsyVisitableItem {
private static final Logger logger = Logger.getLogger(InterestingHits.class.getName());
private SleuthkitCase skCase;
private final InterestingResults interestingResults = new InterestingResults();
private final long datasourceObjId;
/**
* Constructor
*
* @param skCase Case DB
*
*/
public InterestingHits(SleuthkitCase skCase) {
this(skCase, 0);
}
/**
* Constructor
*
* @param skCase Case DB
* @param objId Object id of the data source
*
*/
public InterestingHits(SleuthkitCase skCase, long objId) {
this.skCase = skCase;
this.datasourceObjId = objId;
interestingResults.update();
}
@@ -112,6 +132,9 @@ public class InterestingHits implements AutopsyVisitableItem {
+ "attribute_type_id=" + setNameId //NON-NLS
+ " AND blackboard_attributes.artifact_id=blackboard_artifacts.artifact_id" //NON-NLS
+ " AND blackboard_artifacts.artifact_type_id=" + artId; //NON-NLS
if (UserPreferences.groupItemsInTreeByDatasource()) {
query += " AND blackboard_artifacts.data_source_obj_id = " + datasourceObjId;
}
try (CaseDbQuery dbQuery = skCase.executeQuery(query)) {
synchronized (interestingItemsMap) {

View File

@@ -44,6 +44,7 @@ import org.openide.util.NbBundle;
import org.openide.util.lookup.Lookups;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
import org.sleuthkit.autopsy.core.UserPreferences;
import org.sleuthkit.autopsy.coreutils.Logger;
import static org.sleuthkit.autopsy.datamodel.Bundle.*;
import org.sleuthkit.autopsy.ingest.IngestManager;
@@ -73,6 +74,7 @@ public class KeywordHits implements AutopsyVisitableItem {
private SleuthkitCase skCase;
private final KeywordResults keywordResults;
private final long datasourceObjId;
/**
* String used in the instance MAP so that exact matches and substring can
@@ -81,6 +83,7 @@ public class KeywordHits implements AutopsyVisitableItem {
*/
private static final String DEFAULT_INSTANCE_NAME = "DEFAULT_INSTANCE_NAME";
/**
* query attributes table for the ones that we need for the tree
*/
@@ -101,8 +104,25 @@ public class KeywordHits implements AutopsyVisitableItem {
return (instances.size() == 1) && (instances.get(0).equals(DEFAULT_INSTANCE_NAME));
}
public KeywordHits(SleuthkitCase skCase) {
/**
* Constructor
*
* @param skCase Case DB
*/
KeywordHits(SleuthkitCase skCase) {
this(skCase, 0);
}
/**
* Constructor
*
* @param skCase Case DB
* @param objId Object id of the data source
*
*/
public KeywordHits(SleuthkitCase skCase, long objId) {
this.skCase = skCase;
this.datasourceObjId = objId;
keywordResults = new KeywordResults();
}
@@ -300,7 +320,12 @@ public class KeywordHits implements AutopsyVisitableItem {
return;
}
try (CaseDbQuery dbQuery = skCase.executeQuery(KEYWORD_HIT_ATTRIBUTES_QUERY)) {
String queryStr = KEYWORD_HIT_ATTRIBUTES_QUERY;
if (UserPreferences.groupItemsInTreeByDatasource()) {
queryStr += " AND blackboard_artifacts.data_source_obj_id = " + datasourceObjId;
}
try (CaseDbQuery dbQuery = skCase.executeQuery(queryStr)) {
ResultSet resultSet = dbQuery.getResultSet();
while (resultSet.next()) {
long artifactId = resultSet.getLong("artifact_id"); //NON-NLS

View File

@@ -26,11 +26,17 @@ import org.sleuthkit.datamodel.SleuthkitCase;
public class Results implements AutopsyVisitableItem {
private SleuthkitCase skCase;
private final long datasourceObjId;
public Results(SleuthkitCase skCase) {
this.skCase = skCase;
this(skCase, 0);
}
public Results(SleuthkitCase skCase, long dsObjId) {
this.skCase = skCase;
this.datasourceObjId = dsObjId;
}
@Override
public <T> T accept(AutopsyItemVisitor<T> visitor) {
return visitor.visit(this);
@@ -39,4 +45,8 @@ public class Results implements AutopsyVisitableItem {
public SleuthkitCase getSleuthkitCase() {
return skCase;
}
long filteringDataSourceObjId() {
return datasourceObjId;
}
}

View File

@@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2011-2016 Basis Technology Corp.
* Copyright 2011-2018 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -39,14 +39,14 @@ public class ResultsNode extends DisplayableItemNode {
public ResultsNode(SleuthkitCase sleuthkitCase, long dsObjId) {
super(
// RAMAN TBD JIRA-3763: pass down dsObjId to each of these subnodes
new RootContentChildren(Arrays.asList(
new ExtractedContent(sleuthkitCase),
new KeywordHits(sleuthkitCase),
new HashsetHits(sleuthkitCase),
new EmailExtracted(sleuthkitCase),
new InterestingHits(sleuthkitCase),
new Accounts(sleuthkitCase) )
new ExtractedContent(sleuthkitCase, dsObjId ),
new KeywordHits(sleuthkitCase, dsObjId),
new HashsetHits(sleuthkitCase, dsObjId),
new EmailExtracted(sleuthkitCase, dsObjId),
new InterestingHits(sleuthkitCase, dsObjId ),
new Accounts(sleuthkitCase, dsObjId) )
),
Lookups.singleton(NAME));
setName(NAME);

View File

@@ -22,12 +22,10 @@ import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.EnumSet;
import java.util.List;
import java.util.Observable;
import java.util.Observer;
import java.util.Set;
import java.util.logging.Level;
import org.openide.nodes.ChildFactory;
import org.openide.nodes.Node;

View File

@@ -36,6 +36,7 @@ import org.openide.util.lookup.Lookups;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
import org.sleuthkit.autopsy.casemodule.services.TagsManager;
import org.sleuthkit.autopsy.core.UserPreferences;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.ingest.IngestManager;
import org.sleuthkit.datamodel.BlackboardArtifactTag;
@@ -57,6 +58,20 @@ public class Tags implements AutopsyVisitableItem {
private final String DISPLAY_NAME = NbBundle.getMessage(RootNode.class, "TagsNode.displayName.text");
private final String ICON_PATH = "org/sleuthkit/autopsy/images/tag-folder-blue-icon-16.png"; //NON-NLS
private final long datasourceObjId;
Tags() {
this(0);
}
Tags(long dsObjId) {
this.datasourceObjId = dsObjId;
}
long filteringDataSourceObjId() {
return this.datasourceObjId;
}
@Override
public <T> T accept(AutopsyItemVisitor<T> visitor) {
return visitor.visit(this);
@@ -83,11 +98,13 @@ public class Tags implements AutopsyVisitableItem {
*/
public class RootNode extends DisplayableItemNode {
public RootNode() {
super(Children.create(new TagNameNodeFactory(), true), Lookups.singleton(DISPLAY_NAME));
public RootNode(long objId) {
super(Children.create(new TagNameNodeFactory(objId), true), Lookups.singleton(DISPLAY_NAME));
super.setName(DISPLAY_NAME);
super.setDisplayName(DISPLAY_NAME);
this.setIconBaseWithExtension(ICON_PATH);
}
@Override
@@ -121,6 +138,8 @@ public class Tags implements AutopsyVisitableItem {
private class TagNameNodeFactory extends ChildFactory.Detachable<TagName> implements Observer {
private final long datasourceObjId;
private final Set<Case.Events> CASE_EVENTS_OF_INTEREST = EnumSet.of(Case.Events.BLACKBOARD_ARTIFACT_TAG_ADDED,
Case.Events.BLACKBOARD_ARTIFACT_TAG_DELETED,
Case.Events.CONTENT_TAG_ADDED,
@@ -176,6 +195,15 @@ public class Tags implements AutopsyVisitableItem {
}
};
/**
* Constructor
* @param objId data source object id
*/
TagNameNodeFactory(long objId) {
this.datasourceObjId = objId;
}
@Override
protected void addNotify() {
IngestManager.getInstance().addIngestJobEventListener(pcl);
@@ -196,7 +224,11 @@ public class Tags implements AutopsyVisitableItem {
@Override
protected boolean createKeys(List<TagName> keys) {
try {
List<TagName> tagNamesInUse = Case.getCurrentCaseThrows().getServices().getTagsManager().getTagNamesInUse();
List<TagName> tagNamesInUse = UserPreferences.groupItemsInTreeByDatasource() ?
Case.getCurrentCaseThrows().getServices().getTagsManager().getTagNamesInUse(datasourceObjId) :
Case.getCurrentCaseThrows().getServices().getTagsManager().getTagNamesInUse()
;
Collections.sort(tagNamesInUse);
keys.addAll(tagNamesInUse);
} catch (TskCoreException | NoCurrentCaseException ex) {
@@ -244,8 +276,15 @@ public class Tags implements AutopsyVisitableItem {
long tagsCount = 0;
try {
TagsManager tm = Case.getCurrentCaseThrows().getServices().getTagsManager();
tagsCount = tm.getContentTagsCountByTagName(tagName);
tagsCount += tm.getBlackboardArtifactTagsCountByTagName(tagName);
if (UserPreferences.groupItemsInTreeByDatasource()) {
tagsCount = tm.getContentTagsCountByTagName(tagName, datasourceObjId);
tagsCount += tm.getBlackboardArtifactTagsCountByTagName(tagName, datasourceObjId);
}
else {
tagsCount = tm.getContentTagsCountByTagName(tagName);
tagsCount += tm.getBlackboardArtifactTagsCountByTagName(tagName);
}
} catch (TskCoreException | NoCurrentCaseException ex) {
Logger.getLogger(TagNameNode.class.getName()).log(Level.SEVERE, "Failed to get tags count for " + tagName.getDisplayName() + " tag name", ex); //NON-NLS
}
@@ -348,7 +387,9 @@ public class Tags implements AutopsyVisitableItem {
private void updateDisplayName() {
long tagsCount = 0;
try {
tagsCount = Case.getCurrentCaseThrows().getServices().getTagsManager().getContentTagsCountByTagName(tagName);
tagsCount = UserPreferences.groupItemsInTreeByDatasource() ?
Case.getCurrentCaseThrows().getServices().getTagsManager().getContentTagsCountByTagName(tagName, datasourceObjId) :
Case.getCurrentCaseThrows().getServices().getTagsManager().getContentTagsCountByTagName(tagName);
} catch (TskCoreException | NoCurrentCaseException ex) {
Logger.getLogger(ContentTagTypeNode.class.getName()).log(Level.SEVERE, "Failed to get content tags count for " + tagName.getDisplayName() + " tag name", ex); //NON-NLS
}
@@ -403,7 +444,11 @@ public class Tags implements AutopsyVisitableItem {
protected boolean createKeys(List<ContentTag> keys) {
// Use the content tags bearing the specified tag name as the keys.
try {
keys.addAll(Case.getCurrentCaseThrows().getServices().getTagsManager().getContentTagsByTagName(tagName));
List<ContentTag> contentTags = UserPreferences.groupItemsInTreeByDatasource() ?
Case.getCurrentCaseThrows().getServices().getTagsManager().getContentTagsByTagName(tagName, datasourceObjId) :
Case.getCurrentCaseThrows().getServices().getTagsManager().getContentTagsByTagName(tagName);
keys.addAll(contentTags);
} catch (TskCoreException | NoCurrentCaseException ex) {
Logger.getLogger(ContentTagNodeFactory.class.getName()).log(Level.SEVERE, "Failed to get tag names", ex); //NON-NLS
}
@@ -447,7 +492,9 @@ public class Tags implements AutopsyVisitableItem {
private void updateDisplayName() {
long tagsCount = 0;
try {
tagsCount = Case.getCurrentCaseThrows().getServices().getTagsManager().getBlackboardArtifactTagsCountByTagName(tagName);
tagsCount = UserPreferences.groupItemsInTreeByDatasource() ?
Case.getCurrentCaseThrows().getServices().getTagsManager().getBlackboardArtifactTagsCountByTagName(tagName, datasourceObjId) :
Case.getCurrentCaseThrows().getServices().getTagsManager().getBlackboardArtifactTagsCountByTagName(tagName);
} catch (TskCoreException | NoCurrentCaseException ex) {
Logger.getLogger(BlackboardArtifactTagTypeNode.class.getName()).log(Level.SEVERE, "Failed to get blackboard artifact tags count for " + tagName.getDisplayName() + " tag name", ex); //NON-NLS
}
@@ -502,7 +549,10 @@ public class Tags implements AutopsyVisitableItem {
protected boolean createKeys(List<BlackboardArtifactTag> keys) {
try {
// Use the blackboard artifact tags bearing the specified tag name as the keys.
keys.addAll(Case.getCurrentCaseThrows().getServices().getTagsManager().getBlackboardArtifactTagsByTagName(tagName));
List<BlackboardArtifactTag> artifactTags = UserPreferences.groupItemsInTreeByDatasource() ?
Case.getCurrentCaseThrows().getServices().getTagsManager().getBlackboardArtifactTagsByTagName(tagName, datasourceObjId) :
Case.getCurrentCaseThrows().getServices().getTagsManager().getBlackboardArtifactTagsByTagName(tagName);
keys.addAll(artifactTags);
} catch (TskCoreException | NoCurrentCaseException ex) {
Logger.getLogger(BlackboardArtifactTagNodeFactory.class.getName()).log(Level.SEVERE, "Failed to get tag names", ex); //NON-NLS
}

View File

@@ -58,6 +58,7 @@ import org.openide.util.Utilities;
import org.openide.util.lookup.Lookups;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
import org.sleuthkit.autopsy.core.UserPreferences;
import org.sleuthkit.autopsy.corecomponents.DataResultTopComponent;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.datamodel.AutopsyItemVisitor;
@@ -94,6 +95,8 @@ final public class Accounts implements AutopsyVisitableItem {
final public static String NAME = Bundle.AccountsRootNode_name();
private SleuthkitCase skCase;
private final long datasourceObjId;
private final EventBus reviewStatusBus = new EventBus("ReviewStatusBus");
/* Should rejected accounts be shown in the accounts section of the tree. */
@@ -108,12 +111,24 @@ final public class Accounts implements AutopsyVisitableItem {
* @param skCase The SleuthkitCase object to use for db queries.
*/
public Accounts(SleuthkitCase skCase) {
this(skCase, 0);
}
/**
* Constructor
*
* @param skCase The SleuthkitCase object to use for db queries.
* @param objId Object id of the data source
*/
public Accounts(SleuthkitCase skCase, long objId) {
this.skCase = skCase;
this.datasourceObjId = objId;
this.rejectActionInstance = new RejectAccounts();
this.approveActionInstance = new ApproveAccounts();
}
@Override
public <T> T accept(AutopsyItemVisitor<T> visitor) {
return visitor.visit(this);
@@ -130,6 +145,18 @@ final public class Accounts implements AutopsyVisitableItem {
return showRejected ? " " : " AND blackboard_artifacts.review_status_id != " + BlackboardArtifact.ReviewStatus.REJECTED.getID() + " "; //NON-NLS
}
/**
* Returns the clause to filter artifacts by data source.
*
* @return A clause that will or will not filter artifacts by datasource
* based on the UserPreferences groupItemsInTreeByDatasource setting
*/
private String getFilterByDataSourceClause() {
return (UserPreferences.groupItemsInTreeByDatasource()) ?
" AND blackboard_artifacts.data_source_obj_id = " + datasourceObjId + " "
: " ";
}
/**
* Gets a new Action that when invoked toggles showing rejected artifacts on
* or off.
@@ -291,10 +318,14 @@ final public class Accounts implements AutopsyVisitableItem {
@Override
protected boolean createKeys(List<String> list) {
try (SleuthkitCase.CaseDbQuery executeQuery = skCase.executeQuery(
"SELECT DISTINCT blackboard_attributes.value_text as account_type "
+ " FROM blackboard_attributes "
+ " WHERE blackboard_attributes.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ACCOUNT_TYPE.getTypeID());
String accountTypesInUseQuery =
"SELECT DISTINCT blackboard_attributes.value_text as account_type "
+ " FROM blackboard_artifacts " //NON-NLS
+ " JOIN blackboard_attributes ON blackboard_artifacts.artifact_id = blackboard_attributes.artifact_id " //NON-NLS
+ " WHERE blackboard_attributes.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ACCOUNT_TYPE.getTypeID()
+ getFilterByDataSourceClause();
try (SleuthkitCase.CaseDbQuery executeQuery = skCase.executeQuery(accountTypesInUseQuery );
ResultSet resultSet = executeQuery.getResultSet()) {
while (resultSet.next()) {
String accountType = resultSet.getString("account_type");
@@ -429,6 +460,7 @@ final public class Accounts implements AutopsyVisitableItem {
+ " WHERE blackboard_artifacts.artifact_type_id = " + BlackboardArtifact.ARTIFACT_TYPE.TSK_ACCOUNT.getTypeID() //NON-NLS
+ " AND blackboard_attributes.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ACCOUNT_TYPE.getTypeID() //NON-NLS
+ " AND blackboard_attributes.value_text = '" + accountType.getTypeName() + "'" //NON-NLS
+ getFilterByDataSourceClause()
+ getRejectedArtifactFilterClause(); //NON-NLS
try (SleuthkitCase.CaseDbQuery results = skCase.executeQuery(query);
ResultSet rs = results.getResultSet();) {
@@ -739,6 +771,7 @@ final public class Accounts implements AutopsyVisitableItem {
+ " AND account_type.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ACCOUNT_TYPE.getTypeID() //NON-NLS
+ " AND account_type.value_text = '" + Account.Type.CREDIT_CARD.getTypeName() + "'" //NON-NLS
+ " WHERE blackboard_artifacts.artifact_type_id = " + BlackboardArtifact.ARTIFACT_TYPE.TSK_ACCOUNT.getTypeID() //NON-NLS
+ getFilterByDataSourceClause()
+ getRejectedArtifactFilterClause()
+ " GROUP BY blackboard_artifacts.obj_id, solr_document_id " //NON-NLS
+ " ORDER BY hits DESC "; //NON-NLS
@@ -807,6 +840,7 @@ final public class Accounts implements AutopsyVisitableItem {
+ " AND account_type.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ACCOUNT_TYPE.getTypeID() //NON-NLS
+ " AND account_type.value_text = '" + Account.Type.CREDIT_CARD.getTypeName() + "'" //NON-NLS
+ " WHERE blackboard_artifacts.artifact_type_id = " + BlackboardArtifact.ARTIFACT_TYPE.TSK_ACCOUNT.getTypeID() //NON-NLS
+ getFilterByDataSourceClause()
+ getRejectedArtifactFilterClause()
+ " GROUP BY blackboard_artifacts.obj_id, solr_attribute.value_text ) AS foo";
try (SleuthkitCase.CaseDbQuery results = skCase.executeQuery(query);
@@ -943,6 +977,7 @@ final public class Accounts implements AutopsyVisitableItem {
+ " JOIN blackboard_attributes ON blackboard_artifacts.artifact_id = blackboard_attributes.artifact_id" //NON-NLS
+ " WHERE blackboard_artifacts.artifact_type_id = " + BlackboardArtifact.ARTIFACT_TYPE.TSK_ACCOUNT.getTypeID() //NON-NLS
+ " AND blackboard_attributes.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_CARD_NUMBER.getTypeID() //NON-NLS
+ getFilterByDataSourceClause()
+ getRejectedArtifactFilterClause()
+ " GROUP BY BIN " //NON-NLS
+ " ORDER BY BIN "; //NON-NLS
@@ -1009,6 +1044,7 @@ final public class Accounts implements AutopsyVisitableItem {
+ " JOIN blackboard_attributes ON blackboard_artifacts.artifact_id = blackboard_attributes.artifact_id" //NON-NLS
+ " WHERE blackboard_artifacts.artifact_type_id = " + BlackboardArtifact.ARTIFACT_TYPE.TSK_ACCOUNT.getTypeID() //NON-NLS
+ " AND blackboard_attributes.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_CARD_NUMBER.getTypeID() //NON-NLS
+ getFilterByDataSourceClause()
+ getRejectedArtifactFilterClause(); //NON-NLS
try (SleuthkitCase.CaseDbQuery results = skCase.executeQuery(query);
ResultSet resultSet = results.getResultSet();) {
@@ -1304,6 +1340,7 @@ final public class Accounts implements AutopsyVisitableItem {
+ " WHERE blackboard_artifacts.artifact_type_id = " + BlackboardArtifact.ARTIFACT_TYPE.TSK_ACCOUNT.getTypeID() //NON-NLS
+ " AND blackboard_attributes.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_CARD_NUMBER.getTypeID() //NON-NLS
+ " AND blackboard_attributes.value_text >= '" + bin.getBINStart() + "' AND blackboard_attributes.value_text < '" + (bin.getBINEnd() + 1) + "'" //NON-NLS
+ getFilterByDataSourceClause()
+ getRejectedArtifactFilterClause()
+ " ORDER BY blackboard_attributes.value_text"; //NON-NLS
try (SleuthkitCase.CaseDbQuery results = skCase.executeQuery(query);
@@ -1375,6 +1412,7 @@ final public class Accounts implements AutopsyVisitableItem {
+ " WHERE blackboard_artifacts.artifact_type_id = " + BlackboardArtifact.ARTIFACT_TYPE.TSK_ACCOUNT.getTypeID() //NON-NLS
+ " AND blackboard_attributes.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_CARD_NUMBER.getTypeID() //NON-NLS
+ " AND blackboard_attributes.value_text >= '" + bin.getBINStart() + "' AND blackboard_attributes.value_text < '" + (bin.getBINEnd() + 1) + "'" //NON-NLS
+ getFilterByDataSourceClause()
+ getRejectedArtifactFilterClause();
try (SleuthkitCase.CaseDbQuery results = skCase.executeQuery(query);
ResultSet resultSet = results.getResultSet();) {