19package org.sleuthkit.autopsy.datamodel.accounts;
21import com.google.common.collect.Range;
22import com.google.common.collect.RangeMap;
23import com.google.common.collect.TreeRangeMap;
24import com.google.common.eventbus.EventBus;
25import com.google.common.eventbus.Subscribe;
26import java.awt.event.ActionEvent;
27import java.beans.PropertyChangeEvent;
28import java.beans.PropertyChangeListener;
29import java.sql.ResultSet;
30import java.sql.SQLException;
31import java.util.ArrayList;
32import java.util.Arrays;
33import java.util.Collection;
34import java.util.Collections;
35import java.util.EnumSet;
36import java.util.HashMap;
37import java.util.HashSet;
40import java.util.Objects;
41import java.util.Optional;
43import java.util.function.Function;
44import java.util.logging.Level;
45import java.util.stream.Collectors;
46import java.util.stream.Stream;
47import javax.annotation.Nonnull;
48import javax.annotation.concurrent.Immutable;
49import javax.swing.AbstractAction;
50import javax.swing.Action;
51import javax.swing.SwingUtilities;
52import org.apache.commons.lang3.StringUtils;
53import org.openide.nodes.ChildFactory;
54import org.openide.nodes.Children;
55import org.openide.nodes.Node;
56import org.openide.nodes.NodeNotFoundException;
57import org.openide.nodes.NodeOp;
58import org.openide.nodes.Sheet;
59import org.openide.util.NbBundle;
60import org.openide.util.Utilities;
61import org.openide.util.WeakListeners;
62import org.openide.util.lookup.Lookups;
63import org.sleuthkit.autopsy.casemodule.Case;
64import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
65import org.sleuthkit.autopsy.corecomponents.DataResultTopComponent;
66import org.sleuthkit.autopsy.coreutils.Logger;
67import org.sleuthkit.autopsy.datamodel.AutopsyItemVisitor;
68import org.sleuthkit.autopsy.datamodel.AutopsyVisitableItem;
69import org.sleuthkit.autopsy.datamodel.BlackboardArtifactNode;
70import org.sleuthkit.autopsy.datamodel.CreditCards;
71import org.sleuthkit.autopsy.datamodel.DataModelActionsFactory;
72import org.sleuthkit.autopsy.datamodel.DisplayableItemNode;
73import org.sleuthkit.autopsy.datamodel.DisplayableItemNodeVisitor;
74import org.sleuthkit.autopsy.datamodel.Artifacts.UpdatableCountTypeNode;
75import org.sleuthkit.autopsy.datamodel.NodeProperty;
76import org.sleuthkit.autopsy.directorytree.DirectoryTreeTopComponent;
77import org.sleuthkit.autopsy.ingest.IngestManager;
78import org.sleuthkit.autopsy.ingest.ModuleDataEvent;
79import org.sleuthkit.datamodel.AbstractFile;
80import org.sleuthkit.datamodel.Account;
81import org.sleuthkit.datamodel.BlackboardArtifact;
82import org.sleuthkit.datamodel.BlackboardArtifact.Type;
83import static org.sleuthkit.datamodel.BlackboardArtifact.Type.TSK_ACCOUNT;
84import org.sleuthkit.datamodel.BlackboardAttribute;
85import org.sleuthkit.datamodel.Content;
86import org.sleuthkit.datamodel.DataArtifact;
87import org.sleuthkit.datamodel.SleuthkitCase;
88import org.sleuthkit.datamodel.TskCoreException;
89import org.sleuthkit.datamodel.TskData.DbType;
98 private static final String
ICON_BASE_PATH =
"/org/sleuthkit/autopsy/images/";
101 private static final String
DISPLAY_NAME = Bundle.Accounts_RootNode_displayName();
103 @NbBundle.Messages(
"AccountsRootNode.name=Accounts")
104 final public static String
NAME = Bundle.AccountsRootNode_name();
137 this.filteringDSObjId = objId;
146 return visitor.
visit(
this);
157 return showRejected ?
" " :
" AND blackboard_artifacts.review_status_id != " + BlackboardArtifact.ReviewStatus.REJECTED.getID() +
" ";
168 return " AND blackboard_artifacts.data_source_obj_id = " +
filteringDSObjId +
" ";
192 private abstract class ObservingChildren<X>
extends ChildFactory.Detachable<X> {
198 ObservingChildren() {
237 @NbBundle.Messages({
"Accounts.RootNode.displayName=Communication Accounts"})
248 this.setIconBaseWithExtension(
"org/sleuthkit/autopsy/images/accounts.png");
258 return visitor.
visit(
this);
263 return getClass().getName();
268 String accountTypesInUseQuery
269 =
"SELECT COUNT(*) AS count\n"
271 +
" SELECT MIN(blackboard_attributes.value_text) AS account_type\n"
272 +
" FROM blackboard_artifacts\n"
273 +
" LEFT JOIN blackboard_attributes ON blackboard_artifacts.artifact_id = blackboard_attributes.artifact_id\n"
274 +
" WHERE blackboard_artifacts.artifact_type_id = " + TSK_ACCOUNT.getTypeID() +
"\n"
275 +
" AND blackboard_attributes.attribute_type_id = " + BlackboardAttribute.Type.TSK_ACCOUNT_TYPE.getTypeID() +
"\n"
276 +
" AND blackboard_attributes.value_text IS NOT NULL\n"
278 +
" -- group by artifact_id to ensure only one account type per artifact\n"
279 +
" GROUP BY blackboard_artifacts.artifact_id\n"
283 ResultSet resultSet = executeQuery.getResultSet()) {
285 if (resultSet.next()) {
286 return resultSet.getLong(
"count");
290 LOGGER.log(Level.SEVERE,
"Error querying for count of all account types", ex);
301 private class AccountTypeResults {
303 private final Map<String, Long>
counts =
new HashMap<>();
305 AccountTypeResults() {
317 Long getCount(String accountType) {
318 return counts.get(accountType);
326 List<String> getTypes() {
327 List<String> types =
new ArrayList<>(
counts.keySet());
328 Collections.sort(types);
336 String accountTypesInUseQuery
337 =
"SELECT res.account_type, COUNT(*) AS count\n"
339 +
" SELECT MIN(blackboard_attributes.value_text) AS account_type\n"
340 +
" FROM blackboard_artifacts\n"
341 +
" LEFT JOIN blackboard_attributes ON blackboard_artifacts.artifact_id = blackboard_attributes.artifact_id\n"
342 +
" WHERE blackboard_artifacts.artifact_type_id = " + TSK_ACCOUNT.getTypeID() +
"\n"
343 +
" AND blackboard_attributes.attribute_type_id = " + BlackboardAttribute.Type.TSK_ACCOUNT_TYPE.getTypeID() +
"\n"
345 +
" -- group by artifact_id to ensure only one account type per artifact\n"
346 +
" GROUP BY blackboard_artifacts.artifact_id\n"
348 +
"GROUP BY res.account_type";
351 ResultSet resultSet = executeQuery.getResultSet()) {
354 while (resultSet.next()) {
355 String accountType = resultSet.getString(
"account_type");
356 Long count = resultSet.getLong(
"count");
357 counts.put(accountType, count);
360 LOGGER.log(Level.SEVERE,
"Error querying for account_types", ex);
374 private final PropertyChangeListener
pcl =
new PropertyChangeListener() {
376 public void propertyChange(PropertyChangeEvent evt) {
377 String eventType = evt.getPropertyName();
394 if (
null != eventData
421 private final PropertyChangeListener
weakPcl = WeakListeners.propertyChange(
pcl,
null);
451 return new Node[]{node};
457 if (Account.Type.CREDIT_CARD.getTypeName().equals(accountTypeName)) {
463 if (accountType !=
null) {
467 LOGGER.log(Level.SEVERE,
"Unknown account type '" + accountTypeName +
"' found - account will not be displayed.\n"
468 +
"Account type names must match an entry in the display_name column of the account_types table.\n"
469 +
"Accounts should be created using the CommunicationManager API.");
472 LOGGER.log(Level.SEVERE,
"Error getting display name for account type. ", ex);
506 private final PropertyChangeListener
pcl =
new PropertyChangeListener() {
508 public void propertyChange(PropertyChangeEvent evt) {
509 String eventType = evt.getPropertyName();
526 if (
null != eventData
552 private final PropertyChangeListener
weakPcl = WeakListeners.propertyChange(
pcl,
null);
572 =
"SELECT blackboard_artifacts.artifact_obj_id "
573 +
" FROM blackboard_artifacts "
574 +
" JOIN blackboard_attributes ON blackboard_artifacts.artifact_id = blackboard_attributes.artifact_id "
575 +
" WHERE blackboard_artifacts.artifact_type_id = " + BlackboardArtifact.Type.TSK_ACCOUNT.getTypeID()
576 +
" AND blackboard_attributes.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ACCOUNT_TYPE.getTypeID()
577 +
" AND blackboard_attributes.value_text = '" +
accountType.getTypeName() +
"'"
581 ResultSet rs = results.getResultSet();) {
582 List<Long> tempList =
new ArrayList<>();
584 tempList.add(rs.getLong(
"artifact_obj_id"));
586 list.addAll(tempList);
588 LOGGER.log(Level.SEVERE,
"Error querying for account artifacts.", ex);
599 LOGGER.log(Level.SEVERE,
"Error get black board artifact with id " + t, ex);
629 this.setIconBaseWithExtension(iconPath !=
null && iconPath.charAt(0) ==
'/' ? iconPath.substring(1) : iconPath);
641 return visitor.
visit(
this);
646 return getClass().getName();
678 private final PropertyChangeListener
pcl =
new PropertyChangeListener() {
680 public void propertyChange(PropertyChangeEvent evt) {
681 String eventType = evt.getPropertyName();
698 if (
null != eventData
724 private final PropertyChangeListener
weakPcl = WeakListeners.propertyChange(
pcl,
null);
752 super.removeNotify();
759 protected boolean createKeys(List<CreditCardViewMode> list) {
788 super(Children.create(
new ViewModeFactory(),
true), Lookups.singleton(Account.Type.CREDIT_CARD.getDisplayName()));
789 setName(Account.Type.CREDIT_CARD.getDisplayName());
790 this.setIconBaseWithExtension(
"org/sleuthkit/autopsy/images/credit-cards.png");
798 setName(String.format(
"%s (%d)", Account.Type.CREDIT_CARD.getDisplayName(),
accountTypeResults.getCount(Account.Type.CREDIT_CARD.getTypeName())));
818 return visitor.
visit(
this);
823 return getClass().getName();
829 private final PropertyChangeListener
pcl =
new PropertyChangeListener() {
831 public void propertyChange(PropertyChangeEvent evt) {
832 String eventType = evt.getPropertyName();
849 if (
null != eventData
875 private final PropertyChangeListener
weakPcl = WeakListeners.propertyChange(
pcl,
null);
909 =
"SELECT blackboard_artifacts.obj_id,"
910 +
" solr_attribute.value_text AS solr_document_id, ";
912 query +=
" string_agg(blackboard_artifacts.artifact_id::character varying, ',') AS artifact_IDs, "
913 +
" string_agg(blackboard_artifacts.review_status_id::character varying, ',') AS review_status_ids, ";
915 query +=
" GROUP_CONCAT(blackboard_artifacts.artifact_id) AS artifact_IDs, "
916 +
" GROUP_CONCAT(blackboard_artifacts.review_status_id) AS review_status_ids, ";
918 query +=
" COUNT( blackboard_artifacts.artifact_id) AS hits "
919 +
" FROM blackboard_artifacts "
920 +
" LEFT JOIN blackboard_attributes as solr_attribute ON blackboard_artifacts.artifact_id = solr_attribute.artifact_id "
921 +
" AND solr_attribute.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD_SEARCH_DOCUMENT_ID.getTypeID()
922 +
" LEFT JOIN blackboard_attributes as account_type ON blackboard_artifacts.artifact_id = account_type.artifact_id "
923 +
" AND account_type.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ACCOUNT_TYPE.getTypeID()
924 +
" AND account_type.value_text = '" + Account.Type.CREDIT_CARD.getTypeName() +
"'"
925 +
" WHERE blackboard_artifacts.artifact_type_id = " + BlackboardArtifact.Type.TSK_ACCOUNT.getTypeID()
928 +
" GROUP BY blackboard_artifacts.obj_id, solr_document_id "
929 +
" ORDER BY hits DESC ";
931 ResultSet resultSet = results.getResultSet();) {
932 while (resultSet.next()) {
933 long file_id = resultSet.getLong(
"obj_id");
935 if (abstractFileById !=
null) {
939 resultSet.getString(
"solr_document_id"),
940 unGroupConcat(resultSet.getString(
"artifact_IDs"), Long::valueOf),
941 resultSet.getLong(
"hits"),
942 new HashSet<>(unGroupConcat(resultSet.getString(
"review_status_ids"), reviewStatusID -> BlackboardArtifact.ReviewStatus.withID(Integer.valueOf(reviewStatusID))))));
945 }
catch (TskCoreException | SQLException ex) {
946 LOGGER.log(Level.SEVERE,
"Error querying for files with ccn hits.", ex);
950 LOGGER.log(Level.SEVERE,
"Error getting case.", ex);
959 List<Object> lookupContents =
new ArrayList<>();
963 AbstractFile abstractFileById = key.getFile();
964 lookupContents.add(abstractFileById);
965 return new Node[]{
new FileWithCCNNode(key, abstractFileById, lookupContents.toArray())};
967 LOGGER.log(Level.SEVERE,
"Error getting content for file with ccn hits.", ex);
986 this.setIconBaseWithExtension(
"org/sleuthkit/autopsy/images/file-icon.png");
991 "# {0} - number of children",
992 "Accounts.ByFileNode.displayName=By File ({0})"})
995 =
"SELECT count(*) FROM ( SELECT count(*) AS documents "
996 +
" FROM blackboard_artifacts "
997 +
" LEFT JOIN blackboard_attributes as solr_attribute ON blackboard_artifacts.artifact_id = solr_attribute.artifact_id "
998 +
" AND solr_attribute.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD_SEARCH_DOCUMENT_ID.getTypeID()
999 +
" LEFT JOIN blackboard_attributes as account_type ON blackboard_artifacts.artifact_id = account_type.artifact_id "
1000 +
" AND account_type.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ACCOUNT_TYPE.getTypeID()
1001 +
" AND account_type.value_text = '" + Account.Type.CREDIT_CARD.getTypeName() +
"'"
1002 +
" WHERE blackboard_artifacts.artifact_type_id = " + BlackboardArtifact.Type.TSK_ACCOUNT.getTypeID()
1005 +
" GROUP BY blackboard_artifacts.obj_id, solr_attribute.value_text ) AS foo";
1007 ResultSet resultSet = results.getResultSet();) {
1008 while (resultSet.next()) {
1010 setDisplayName(Bundle.Accounts_ByFileNode_displayName(resultSet.getLong(
"count")));
1012 setDisplayName(Bundle.Accounts_ByFileNode_displayName(resultSet.getLong(
"count(*)")));
1016 LOGGER.log(Level.SEVERE,
"Error querying for files with ccn hits.", ex);
1028 return visitor.
visit(
this);
1033 return getClass().getName();
1047 final private class BINFactory extends ObservingChildren<BinResult> {
1049 private final PropertyChangeListener
pcl =
new PropertyChangeListener() {
1051 public void propertyChange(PropertyChangeEvent evt) {
1052 String eventType = evt.getPropertyName();
1069 if (
null != eventData
1095 private final PropertyChangeListener
weakPcl = WeakListeners.propertyChange(
pcl,
null);
1128 RangeMap<Integer, BinResult> binRanges = TreeRangeMap.create();
1131 =
"SELECT SUBSTR(blackboard_attributes.value_text,1,8) AS BIN, "
1132 +
" COUNT(blackboard_artifacts.artifact_id) AS count "
1133 +
" FROM blackboard_artifacts "
1134 +
" JOIN blackboard_attributes ON blackboard_artifacts.artifact_id = blackboard_attributes.artifact_id"
1135 +
" WHERE blackboard_artifacts.artifact_type_id = " + BlackboardArtifact.Type.TSK_ACCOUNT.getTypeID()
1136 +
" AND blackboard_attributes.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_CARD_NUMBER.getTypeID()
1142 ResultSet resultSet = results.getResultSet();) {
1144 while (resultSet.next()) {
1145 final Integer bin = Integer.valueOf(resultSet.getString(
"BIN"));
1146 long count = resultSet.getLong(
"count");
1149 BinResult previousResult = binRanges.get(bin);
1151 if (previousResult !=
null) {
1152 binRanges.remove(Range.closed(previousResult.getBINStart(), previousResult.getBINEnd()));
1153 count += previousResult.getCount();
1156 if (binRange ==
null) {
1157 binRanges.put(Range.closed(bin, bin),
new BinResult(count, bin, bin));
1162 binRanges.asMapOfRanges().values().forEach(list::add);
1164 LOGGER.log(Level.SEVERE,
"Error querying for BINs.", ex);
1172 return new Node[]{
new BINNode(key)};
1185 @NbBundle.Messages(
"Accounts.ByBINNode.name=By BIN")
1187 super(Children.create(
new BINFactory(),
true), Lookups.singleton(Bundle.Accounts_ByBINNode_name()));
1188 setName(Bundle.Accounts_ByBINNode_name());
1190 this.setIconBaseWithExtension(
"org/sleuthkit/autopsy/images/bank.png");
1194 @NbBundle.Messages({
1195 "# {0} - number of children",
1196 "Accounts.ByBINNode.displayName=By BIN ({0})"})
1199 =
"SELECT count(distinct SUBSTR(blackboard_attributes.value_text,1,8)) AS BINs "
1200 +
" FROM blackboard_artifacts "
1201 +
" JOIN blackboard_attributes ON blackboard_artifacts.artifact_id = blackboard_attributes.artifact_id"
1202 +
" WHERE blackboard_artifacts.artifact_type_id = " + BlackboardArtifact.Type.TSK_ACCOUNT.getTypeID()
1203 +
" AND blackboard_attributes.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_CARD_NUMBER.getTypeID()
1207 ResultSet resultSet = results.getResultSet();) {
1208 while (resultSet.next()) {
1209 setDisplayName(Bundle.Accounts_ByBINNode_displayName(resultSet.getLong(
"BINs")));
1212 LOGGER.log(Level.SEVERE,
"Error querying for BINs.", ex);
1223 return visitor.
visit(
this);
1228 return getClass().getName();
1252 hash = 79 * hash + (int) (this.
objID ^ (this.
objID >>> 32));
1254 hash = 79 * hash + Objects.hashCode(this.
artifactIDs);
1255 hash = 79 * hash + (int) (this.
hits ^ (this.
hits >>> 32));
1256 hash = 79 * hash + Objects.hashCode(this.
statuses);
1268 if (getClass() != obj.getClass()) {
1281 if (!Objects.equals(
this.artifactIDs, other.
artifactIDs)) {
1284 if (!Objects.equals(
this.statuses, other.
statuses)) {
1294 private final Set<BlackboardArtifact.ReviewStatus>
statuses;
1299 this.keywordSearchDocID = solrDocID;
1349 return Collections.unmodifiableSet(
statuses);
1352 AbstractFile getFile() {
1373 static <X> List<X> unGroupConcat(String groupConcat, Function<String, X> mapper) {
1374 return StringUtils.isBlank(groupConcat) ? Collections.emptyList()
1375 : Stream.of(groupConcat.split(
","))
1377 .collect(Collectors.toList());
1397 @NbBundle.Messages({
1398 "# {0} - raw file name",
1399 "# {1} - solr chunk id",
1400 "Accounts.FileWithCCNNode.unallocatedSpaceFile.displayName={0}_chunk_{1}"})
1402 super(Children.LEAF, Lookups.fixed(lookupContents));
1406 : Bundle.Accounts_FileWithCCNNode_unallocatedSpaceFile_displayName(content.getName(), StringUtils.substringAfter(key.
getkeywordSearchDocID(),
"_"));
1418 return visitor.
visit(
this);
1423 return getClass().getName();
1427 @NbBundle.Messages({
1428 "Accounts.FileWithCCNNode.nameProperty.displayName=File",
1429 "Accounts.FileWithCCNNode.accountsProperty.displayName=Accounts",
1430 "Accounts.FileWithCCNNode.statusProperty.displayName=Status",
1431 "Accounts.FileWithCCNNode.noDescription=no description"})
1433 Sheet sheet = super.createSheet();
1434 Sheet.Set propSet = sheet.get(Sheet.PROPERTIES);
1435 if (propSet ==
null) {
1436 propSet = Sheet.createPropertiesSet();
1440 propSet.put(
new NodeProperty<>(Bundle.Accounts_FileWithCCNNode_nameProperty_displayName(),
1441 Bundle.Accounts_FileWithCCNNode_nameProperty_displayName(),
1442 Bundle.Accounts_FileWithCCNNode_noDescription(),
1444 propSet.put(
new NodeProperty<>(Bundle.Accounts_FileWithCCNNode_accountsProperty_displayName(),
1445 Bundle.Accounts_FileWithCCNNode_accountsProperty_displayName(),
1446 Bundle.Accounts_FileWithCCNNode_noDescription(),
1448 propSet.put(
new NodeProperty<>(Bundle.Accounts_FileWithCCNNode_statusProperty_displayName(),
1449 Bundle.Accounts_FileWithCCNNode_statusProperty_displayName(),
1450 Bundle.Accounts_FileWithCCNNode_noDescription(),
1451 fileKey.getStatuses().stream()
1452 .map(BlackboardArtifact.ReviewStatus::getDisplayName)
1453 .collect(Collectors.joining(
", "))));
1460 Action[]
actions = super.getActions(context);
1461 ArrayList<Action> arrayList =
new ArrayList<>();
1465 LOGGER.log(Level.SEVERE,
"Error gettung content by id", ex);
1470 arrayList.add(
null);
1471 arrayList.addAll(Arrays.asList(
actions));
1472 return arrayList.toArray(
new Action[arrayList.size()]);
1500 =
"SELECT blackboard_artifacts.artifact_obj_id "
1501 +
" FROM blackboard_artifacts "
1502 +
" JOIN blackboard_attributes ON blackboard_artifacts.artifact_id = blackboard_attributes.artifact_id "
1503 +
" WHERE blackboard_artifacts.artifact_type_id = " + BlackboardArtifact.Type.TSK_ACCOUNT.getTypeID()
1504 +
" AND blackboard_attributes.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_CARD_NUMBER.getTypeID()
1505 +
" AND blackboard_attributes.value_text >= '" +
bin.getBINStart() +
"' AND blackboard_attributes.value_text < '" + (
bin.getBINEnd() + 1) +
"'"
1508 +
" ORDER BY blackboard_attributes.value_text";
1510 ResultSet rs = results.getResultSet();) {
1515 LOGGER.log(Level.SEVERE,
"Error querying for account artifacts.", ex);
1528 if (bin.getBINStart() == bin.getBINEnd()) {
1529 return Integer.toString(bin.getBINStart());
1531 return bin.getBINStart() +
"-" + StringUtils.difference(bin.getBINStart() +
"", bin.getBINEnd() +
"");
1547 this.setIconBaseWithExtension(
"org/sleuthkit/autopsy/images/bank.png");
1564 =
"SELECT count(blackboard_artifacts.artifact_id ) AS count"
1565 +
" FROM blackboard_artifacts "
1566 +
" JOIN blackboard_attributes ON blackboard_artifacts.artifact_id = blackboard_attributes.artifact_id "
1567 +
" WHERE blackboard_artifacts.artifact_type_id = " + BlackboardArtifact.Type.TSK_ACCOUNT.getTypeID()
1568 +
" AND blackboard_attributes.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_CARD_NUMBER.getTypeID()
1569 +
" AND blackboard_attributes.value_text >= '" +
bin.getBINStart() +
"' AND blackboard_attributes.value_text < '" + (
bin.getBINEnd() + 1) +
"'"
1573 ResultSet resultSet = results.getResultSet();) {
1574 while (resultSet.next()) {
1578 LOGGER.log(Level.SEVERE,
"Error querying for account artifacts.", ex);
1591 return visitor.
visit(
this);
1596 return getClass().getName();
1600 Sheet.Set sheetSet = sheet.get(Sheet.PROPERTIES);
1601 if (sheetSet ==
null) {
1602 sheetSet = Sheet.createPropertiesSet();
1603 sheet.put(sheetSet);
1609 @NbBundle.Messages({
1610 "Accounts.BINNode.binProperty.displayName=Bank Identifier Number",
1611 "Accounts.BINNode.accountsProperty.displayName=Accounts",
1612 "Accounts.BINNode.cardTypeProperty.displayName=Payment Card Type",
1613 "Accounts.BINNode.schemeProperty.displayName=Credit Card Scheme",
1614 "Accounts.BINNode.brandProperty.displayName=Brand",
1615 "Accounts.BINNode.bankProperty.displayName=Bank",
1616 "Accounts.BINNode.bankCityProperty.displayName=Bank City",
1617 "Accounts.BINNode.bankCountryProperty.displayName=Bank Country",
1618 "Accounts.BINNode.bankPhoneProperty.displayName=Bank Phone #",
1619 "Accounts.BINNode.bankURLProperty.displayName=Bank URL",
1620 "Accounts.BINNode.noDescription=no description"})
1622 Sheet sheet = super.createSheet();
1625 properties.put(
new NodeProperty<>(Bundle.Accounts_BINNode_binProperty_displayName(),
1626 Bundle.Accounts_BINNode_binProperty_displayName(),
1627 Bundle.Accounts_BINNode_noDescription(),
1629 properties.put(
new NodeProperty<>(Bundle.Accounts_BINNode_accountsProperty_displayName(),
1630 Bundle.Accounts_BINNode_accountsProperty_displayName(), Bundle.Accounts_BINNode_noDescription(),
1634 if (
bin.hasDetails()) {
1635 bin.getCardType().ifPresent(cardType -> properties.put(
new NodeProperty<>(Bundle.Accounts_BINNode_cardTypeProperty_displayName(),
1636 Bundle.Accounts_BINNode_cardTypeProperty_displayName(), Bundle.Accounts_BINNode_noDescription(),
1638 bin.getScheme().ifPresent(scheme -> properties.put(
new NodeProperty<>(Bundle.Accounts_BINNode_schemeProperty_displayName(),
1639 Bundle.Accounts_BINNode_schemeProperty_displayName(), Bundle.Accounts_BINNode_noDescription(),
1641 bin.getBrand().ifPresent(brand -> properties.put(
new NodeProperty<>(Bundle.Accounts_BINNode_brandProperty_displayName(),
1642 Bundle.Accounts_BINNode_brandProperty_displayName(), Bundle.Accounts_BINNode_noDescription(),
1644 bin.getBankName().ifPresent(bankName -> properties.put(
new NodeProperty<>(Bundle.Accounts_BINNode_bankProperty_displayName(),
1645 Bundle.Accounts_BINNode_bankProperty_displayName(), Bundle.Accounts_BINNode_noDescription(),
1647 bin.getBankCity().ifPresent(bankCity -> properties.put(
new NodeProperty<>(Bundle.Accounts_BINNode_bankCityProperty_displayName(),
1648 Bundle.Accounts_BINNode_bankCityProperty_displayName(), Bundle.Accounts_BINNode_noDescription(),
1650 bin.getCountry().ifPresent(country -> properties.put(
new NodeProperty<>(Bundle.Accounts_BINNode_bankCountryProperty_displayName(),
1651 Bundle.Accounts_BINNode_bankCountryProperty_displayName(), Bundle.Accounts_BINNode_noDescription(),
1653 bin.getBankPhoneNumber().ifPresent(phoneNumber -> properties.put(
new NodeProperty<>(Bundle.Accounts_BINNode_bankPhoneProperty_displayName(),
1654 Bundle.Accounts_BINNode_bankPhoneProperty_displayName(), Bundle.Accounts_BINNode_noDescription(),
1656 bin.getBankURL().ifPresent(url -> properties.put(
new NodeProperty<>(Bundle.Accounts_BINNode_bankURLProperty_displayName(),
1657 Bundle.Accounts_BINNode_bankURLProperty_displayName(), Bundle.Accounts_BINNode_noDescription(),
1664 SwingUtilities.invokeLater(() -> {
1681 hash = 97 * hash + this.
binEnd;
1694 if (getClass() != obj.getClass()) {
1725 this.binRange =
null;
1742 boolean hasDetails() {
1763 return binRange.getBankPhoneNumber();
1797 super(
artifact,
"org/sleuthkit/autopsy/images/credit-card.png");
1799 setName(Long.toString(
this.artifact.getArtifactID()));
1806 List<Action> actionsList =
new ArrayList<>();
1807 actionsList.addAll(Arrays.asList(super.getActions(context)));
1812 return actionsList.toArray(
new Action[actionsList.size()]);
1817 Sheet sheet = super.createSheet();
1818 Sheet.Set properties = sheet.get(Sheet.PROPERTIES);
1819 if (properties ==
null) {
1820 properties = Sheet.createPropertiesSet();
1821 sheet.put(properties);
1823 properties.put(
new NodeProperty<>(Bundle.Accounts_FileWithCCNNode_statusProperty_displayName(),
1824 Bundle.Accounts_FileWithCCNNode_statusProperty_displayName(),
1825 Bundle.Accounts_FileWithCCNNode_noDescription(),
1826 artifact.getReviewStatus().getDisplayName()));
1835 event.artifacts.stream().filter((art) -> (art.getArtifactID() ==
this.artifact.getArtifactID())).map((_item) -> {
1837 }).forEachOrdered((_item) -> {
1843 SwingUtilities.invokeLater(() -> {
1851 private final class ToggleShowRejected
extends AbstractAction {
1853 @NbBundle.Messages(
"ToggleShowRejected.name=Show Rejected Results")
1854 ToggleShowRejected() {
1855 super(Bundle.ToggleShowRejected_name());
1892 List<String[]> selectedPaths = Utilities.actionsGlobalContext().lookupAll(Node.class).stream()
1894 String[] createPath;
1901 List<Node> siblings = Arrays.asList(node.getParentNode().getChildren().getNodes());
1902 if (siblings.size() > 1) {
1903 int indexOf = siblings.indexOf(node);
1905 Node sibling = indexOf > 0
1906 ? siblings.get(indexOf - 1)
1907 : siblings.get(Integer.max(indexOf + 1, siblings.size() - 1));
1908 createPath = NodeOp.createPath(sibling,
null);
1918 createPath = NodeOp.createPath(node,
null);
1921 return Arrays.copyOfRange(createPath, 1, createPath.length);
1923 .filter(Objects::nonNull)
1924 .collect(Collectors.toList());
1927 final Collection<? extends BlackboardArtifact> artifacts = Utilities.actionsGlobalContext().lookupAll(BlackboardArtifact.class);
1928 artifacts.forEach(artifact -> {
1931 }
catch (TskCoreException ex) {
1932 LOGGER.log(Level.SEVERE,
"Error changing artifact review status.", ex);
1939 final Node rootNode = directoryListing.
getRootNode();
1942 List<Node> toArray =
new ArrayList<>();
1943 selectedPaths.forEach(path -> {
1945 toArray.add(NodeOp.findPath(rootNode, path));
1946 }
catch (NodeNotFoundException ex) {
1951 directoryListing.
setSelectedNodes(toArray.toArray(
new Node[toArray.size()]));
1957 @NbBundle.Messages({
"ApproveAccountsAction.name=Approve Accounts"})
1959 super(Bundle.ApproveAccountsAction_name(), BlackboardArtifact.ReviewStatus.APPROVED);
1965 @NbBundle.Messages({
"RejectAccountsAction.name=Reject Accounts"})
1967 super(Bundle.RejectAccountsAction_name(), BlackboardArtifact.ReviewStatus.REJECTED);
1971 static private class ReviewStatusChangeEvent {
1973 Collection<? extends BlackboardArtifact> artifacts;
1974 BlackboardArtifact.ReviewStatus newReviewStatus;
1976 ReviewStatusChangeEvent(Collection<? extends BlackboardArtifact> artifacts, BlackboardArtifact.ReviewStatus newReviewStatus) {
1977 this.artifacts = artifacts;
1978 this.newReviewStatus = newReviewStatus;
1989 if (type.equals(Account.Type.CREDIT_CARD)) {
1991 }
else if (type.equals(Account.Type.DEVICE)) {
1993 }
else if (type.equals(Account.Type.EMAIL)) {
1995 }
else if (type.equals(Account.Type.FACEBOOK)) {
1997 }
else if (type.equals(Account.Type.INSTAGRAM)) {
1999 }
else if (type.equals(Account.Type.MESSAGING_APP)) {
2001 }
else if (type.equals(Account.Type.PHONE)) {
2003 }
else if (type.equals(Account.Type.TWITTER)) {
2005 }
else if (type.equals(Account.Type.WEBSITE)) {
2007 }
else if (type.equals(Account.Type.WHATSAPP)) {
static void removeEventTypeSubscriber(Set< Events > eventTypes, PropertyChangeListener subscriber)
SleuthkitCase getSleuthkitCase()
static Case getCurrentCaseThrows()
static void addEventTypeSubscriber(Set< Events > eventTypes, PropertyChangeListener subscriber)
void setSelectedNodes(Node[] selected)
synchronized static Logger getLogger(String name)
void setName(String name)
UpdatableCountTypeNode(Children children, Lookup lookup, String baseName, long filteringDSObjId, BlackboardArtifact.Type... types)
final long filteringDSObjId
BlackboardArtifactNode(BlackboardArtifact artifact, String iconPath)
static synchronized BankIdentificationNumber getBINInfo(int bin)
static List< Action > getActions(File file, boolean isArtifactSource)
DisplayableItemNode(Children children)
Action[] getActions(boolean context)
AccountArtifactNode(BlackboardArtifact artifact)
final BlackboardArtifact artifact
Node[] getNodeArr(Node node)
Node[] createNodesForKey(String accountTypeName)
final PropertyChangeListener pcl
boolean createKeys(List< String > list)
final PropertyChangeListener weakPcl
final Map< String, Long > counts
long fetchChildCount(SleuthkitCase skCase)
final PropertyChangeListener weakPcl
Node[] createNodesForKey(BinResult key)
final PropertyChangeListener pcl
boolean createKeys(List< BinResult > list)
Sheet.Set getPropertySet(Sheet sheet)
Optional< String > getScheme()
Optional< String > getCardType()
Optional< String > getBankCity()
Optional< String > getBrand()
boolean equals(Object obj)
Optional< String > getBankName()
Optional< String > getBankURL()
BinResult(long count, int start, int end)
BinResult(long count, @Nonnull BINRange binRange)
Optional< String > getCountry()
Optional< String > getBankPhoneNumber()
Optional< Integer > getNumberLength()
CreditCardNumberAccountTypeNode()
Node[] createNodesForKey(DataArtifact artifact)
boolean createKeys(List< DataArtifact > list)
CreditCardNumberFactory(BinResult bin)
DefaultAccountFactory(Account.Type accountType)
final PropertyChangeListener pcl
final PropertyChangeListener weakPcl
final Account.Type accountType
boolean createKeys(List< Long > list)
Node[] createNodesForKey(Long t)
final Account.Type accountType
DefaultAccountTypeNode(Account.Type accountType)
final PropertyChangeListener pcl
final PropertyChangeListener weakPcl
Node[] createNodesForKey(FileWithCCN key)
boolean createKeys(List< FileWithCCN > list)
Set< BlackboardArtifact.ReviewStatus > getStatuses()
List< Long > getArtifactIDs()
String getkeywordSearchDocID()
boolean equals(Object obj)
final List< Long > artifactIDs
final Set< BlackboardArtifact.ReviewStatus > statuses
final String keywordSearchDocID
FileWithCCN(AbstractFile file, long objID, String solrDocID, List< Long > artifactIDs, long hits, Set< BlackboardArtifact.ReviewStatus > statuses)
Action[] getActions(boolean context)
final FileWithCCN fileKey
FileWithCCNNode(FileWithCCN key, Content content, Object[] lookupContents)
abstract boolean createKeys(List< X > list)
ReviewStatusAction(String displayName, BlackboardArtifact.ReviewStatus newStatus)
final BlackboardArtifact.ReviewStatus newStatus
void actionPerformed(ActionEvent e)
void actionPerformed(ActionEvent e)
Node[] createNodesForKey(CreditCardViewMode key)
boolean createKeys(List< CreditCardViewMode > list)
final PropertyChangeListener pcl
final PropertyChangeListener weakPcl
final EventBus reviewStatusBus
String getBinRangeString(BinResult bin)
static String getIconFilePath(Account.Type type)
final RejectAccounts rejectActionInstance
static final Set< IngestManager.IngestModuleEvent > INGEST_MODULE_EVENTS_OF_INTEREST
Action newToggleShowRejectedAction()
final ApproveAccounts approveActionInstance
static final Logger LOGGER
void setShowRejected(boolean showRejected)
static final Set< IngestManager.IngestJobEvent > INGEST_JOB_EVENTS_OF_INTEREST
static final String DISPLAY_NAME
final AccountTypeResults accountTypeResults
String getRejectedArtifactFilterClause()
final long filteringDSObjId
static final String ICON_BASE_PATH
String getFilterByDataSourceClause()
DataResultTopComponent getDirectoryListing()
static synchronized DirectoryTreeTopComponent findInstance()
static synchronized IngestManager getInstance()
void removeIngestModuleEventListener(final PropertyChangeListener listener)
void removeIngestJobEventListener(final PropertyChangeListener listener)
void addIngestModuleEventListener(final PropertyChangeListener listener)
void addIngestJobEventListener(final PropertyChangeListener listener)
BlackboardArtifact.Type getBlackboardArtifactType()
T visit(DataSourceFilesNode in)