19 package org.sleuthkit.autopsy.datamodel.accounts;
21 import com.google.common.collect.Range;
22 import com.google.common.collect.RangeMap;
23 import com.google.common.collect.TreeRangeMap;
24 import com.google.common.eventbus.EventBus;
25 import com.google.common.eventbus.Subscribe;
26 import java.awt.event.ActionEvent;
27 import java.beans.PropertyChangeEvent;
28 import java.beans.PropertyChangeListener;
29 import java.sql.ResultSet;
30 import java.sql.SQLException;
31 import java.util.ArrayList;
32 import java.util.Arrays;
33 import java.util.Collection;
34 import java.util.Collections;
35 import java.util.EnumSet;
36 import java.util.HashMap;
37 import java.util.HashSet;
38 import java.util.List;
40 import java.util.Objects;
41 import java.util.Optional;
43 import java.util.function.Function;
44 import java.util.logging.Level;
45 import java.util.stream.Collectors;
46 import java.util.stream.Stream;
47 import javax.annotation.Nonnull;
48 import javax.annotation.concurrent.Immutable;
49 import javax.swing.AbstractAction;
50 import javax.swing.Action;
51 import org.apache.commons.lang3.StringUtils;
52 import org.openide.nodes.ChildFactory;
53 import org.openide.nodes.Children;
54 import org.openide.nodes.Node;
55 import org.openide.nodes.NodeNotFoundException;
56 import org.openide.nodes.NodeOp;
57 import org.openide.nodes.Sheet;
58 import org.openide.util.NbBundle;
59 import org.openide.util.Utilities;
60 import org.openide.util.lookup.Lookups;
79 import org.
sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE;
93 private static final String
ICON_BASE_PATH =
"/org/sleuthkit/autopsy/images/";
97 @NbBundle.Messages(
"AccountsRootNode.name=Accounts")
98 final public static String
NAME = Bundle.AccountsRootNode_name();
131 public Accounts(SleuthkitCase skCase,
long objId) {
133 this.filteringDSObjId = objId;
142 return visitor.
visit(
this);
153 return showRejected ?
" " :
" AND blackboard_artifacts.review_status_id != " + BlackboardArtifact.ReviewStatus.REJECTED.getID() +
" ";
163 if (filteringDSObjId > 0) {
164 return " AND blackboard_artifacts.data_source_obj_id = " + filteringDSObjId +
" ";
203 abstract protected boolean createKeys(List<X> list);
218 super.removeNotify();
233 @NbBundle.Messages({
"Accounts.RootNode.displayName=Accounts"})
239 setDisplayName(Bundle.Accounts_RootNode_displayName());
240 this.setIconBaseWithExtension(
"org/sleuthkit/autopsy/images/accounts.png");
250 return visitor.
visit(
this);
255 return getClass().getName();
263 private final Map<String, Long>
counts =
new HashMap<>();
274 Long getCount(String accountType) {
275 return counts.get(accountType);
282 List<String> getTypes() {
283 List<String> types =
new ArrayList<>(counts.keySet());
284 Collections.sort(types);
292 String accountTypesInUseQuery
293 =
"SELECT blackboard_attributes.value_text as account_type, COUNT(*) as count "
294 +
" FROM blackboard_artifacts "
295 +
" JOIN blackboard_attributes ON blackboard_artifacts.artifact_id = blackboard_attributes.artifact_id "
296 +
" WHERE blackboard_artifacts.artifact_type_id = " + BlackboardArtifact.ARTIFACT_TYPE.TSK_ACCOUNT.getTypeID()
297 +
" AND blackboard_attributes.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ACCOUNT_TYPE.getTypeID()
299 +
" GROUP BY blackboard_attributes.value_text ";
301 try (SleuthkitCase.CaseDbQuery executeQuery = skCase.executeQuery(accountTypesInUseQuery);
302 ResultSet resultSet = executeQuery.getResultSet()) {
305 while (resultSet.next()) {
306 String accountType = resultSet.getString(
"account_type");
307 Long count = resultSet.getLong(
"count");
308 counts.put(accountType, count);
310 }
catch (TskCoreException | SQLException ex) {
311 LOGGER.log(Level.SEVERE,
"Error querying for account_types", ex);
325 private final PropertyChangeListener
pcl =
new PropertyChangeListener() {
327 public void propertyChange(PropertyChangeEvent evt) {
328 String eventType = evt.getPropertyName();
345 if (null != eventData
347 accountTypeResults.
update();
348 reviewStatusBus.post(eventData);
369 if (evt.getNewValue() == null) {
391 list.addAll(accountTypeResults.getTypes());
402 reviewStatusBus.register(node);
403 return new Node[]{node};
409 if (Account.Type.CREDIT_CARD.getTypeName().equals(acountTypeName)) {
414 Account.Type accountType = skCase.getCommunicationsManager().getAccountType(acountTypeName);
416 }
catch (TskCoreException ex) {
417 LOGGER.log(Level.SEVERE,
"Error getting display name for account type. ", ex);
429 super.removeNotify();
451 private final PropertyChangeListener
pcl =
new PropertyChangeListener() {
453 public void propertyChange(PropertyChangeEvent evt) {
454 String eventType = evt.getPropertyName();
471 if (null != eventData
473 reviewStatusBus.post(eventData);
495 if (evt.getNewValue() == null) {
516 super.removeNotify();
522 =
"SELECT blackboard_artifacts.artifact_id "
523 +
" FROM blackboard_artifacts "
524 +
" JOIN blackboard_attributes ON blackboard_artifacts.artifact_id = blackboard_attributes.artifact_id "
525 +
" WHERE blackboard_artifacts.artifact_type_id = " + BlackboardArtifact.ARTIFACT_TYPE.TSK_ACCOUNT.getTypeID()
526 +
" AND blackboard_attributes.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ACCOUNT_TYPE.getTypeID()
527 +
" AND blackboard_attributes.value_text = '" + accountType.getTypeName() +
"'"
530 try (SleuthkitCase.CaseDbQuery results = skCase.executeQuery(query);
531 ResultSet rs = results.getResultSet();) {
533 list.add(rs.getLong(
"artifact_id"));
535 }
catch (TskCoreException | SQLException ex) {
536 LOGGER.log(Level.SEVERE,
"Error querying for account artifacts.", ex);
546 }
catch (TskCoreException ex) {
547 LOGGER.log(Level.SEVERE,
"Error get black board artifact with id " + t, ex);
573 super(Children.create(
new DefaultAccountFactory(accountType),
true), Lookups.singleton(accountType));
576 this.setIconBaseWithExtension(iconPath != null && iconPath.charAt(0) ==
'/' ? iconPath.substring(1) : iconPath);
587 return visitor.
visit(
this);
592 return getClass().getName();
610 setName(String.format(
"%s (%d)", accountType.getDisplayName(), accountTypeResults.getCount(accountType.getTypeName())));
624 private final PropertyChangeListener pcl =
new PropertyChangeListener() {
626 public void propertyChange(PropertyChangeEvent evt) {
627 String eventType = evt.getPropertyName();
644 if (null != eventData
646 reviewStatusBus.post(eventData);
668 if (evt.getNewValue() == null) {
701 super.removeNotify();
708 protected boolean createKeys(List<CreditCardViewMode> list) {
737 super(Children.create(
new ViewModeFactory(),
true), Lookups.singleton(Account.Type.CREDIT_CARD.getDisplayName()));
738 setName(Account.Type.CREDIT_CARD.getDisplayName());
739 this.setIconBaseWithExtension(
"org/sleuthkit/autopsy/images/credit-cards.png");
746 setName(String.format(
"%s (%d)", Account.Type.CREDIT_CARD.getDisplayName(), accountTypeResults.getCount(Account.Type.CREDIT_CARD.getTypeName())));
766 return visitor.
visit(
this);
771 return getClass().getName();
777 private final PropertyChangeListener pcl =
new PropertyChangeListener() {
779 public void propertyChange(PropertyChangeEvent evt) {
780 String eventType = evt.getPropertyName();
797 if (null != eventData
799 reviewStatusBus.post(eventData);
821 if (evt.getNewValue() == null) {
842 super.removeNotify();
860 =
"SELECT blackboard_artifacts.obj_id,"
861 +
" solr_attribute.value_text AS solr_document_id, ";
862 if (skCase.getDatabaseType().equals(DbType.POSTGRESQL)) {
863 query +=
" string_agg(blackboard_artifacts.artifact_id::character varying, ',') AS artifact_IDs, "
864 +
" string_agg(blackboard_artifacts.review_status_id::character varying, ',') AS review_status_ids, ";
866 query +=
" GROUP_CONCAT(blackboard_artifacts.artifact_id) AS artifact_IDs, "
867 +
" GROUP_CONCAT(blackboard_artifacts.review_status_id) AS review_status_ids, ";
869 query +=
" COUNT( blackboard_artifacts.artifact_id) AS hits "
870 +
" FROM blackboard_artifacts "
871 +
" LEFT JOIN blackboard_attributes as solr_attribute ON blackboard_artifacts.artifact_id = solr_attribute.artifact_id "
872 +
" AND solr_attribute.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD_SEARCH_DOCUMENT_ID.getTypeID()
873 +
" LEFT JOIN blackboard_attributes as account_type ON blackboard_artifacts.artifact_id = account_type.artifact_id "
874 +
" AND account_type.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ACCOUNT_TYPE.getTypeID()
875 +
" AND account_type.value_text = '" + Account.Type.CREDIT_CARD.getTypeName() +
"'"
876 +
" WHERE blackboard_artifacts.artifact_type_id = " + BlackboardArtifact.ARTIFACT_TYPE.TSK_ACCOUNT.getTypeID()
879 +
" GROUP BY blackboard_artifacts.obj_id, solr_document_id "
880 +
" ORDER BY hits DESC ";
881 try (SleuthkitCase.CaseDbQuery results = skCase.executeQuery(query);
882 ResultSet resultSet = results.getResultSet();) {
883 while (resultSet.next()) {
885 resultSet.getLong(
"obj_id"),
886 resultSet.getString(
"solr_document_id"),
887 unGroupConcat(resultSet.getString(
"artifact_IDs"), Long::valueOf),
888 resultSet.getLong(
"hits"),
889 new HashSet<>(unGroupConcat(resultSet.getString(
"review_status_ids"), reviewStatusID -> BlackboardArtifact.ReviewStatus.withID(Integer.valueOf(reviewStatusID))))));
891 }
catch (TskCoreException | SQLException ex) {
892 LOGGER.log(Level.SEVERE,
"Error querying for files with ccn hits.", ex);
902 List<Object> lookupContents =
new ArrayList<>();
904 lookupContents.add(skCase.getBlackboardArtifact(artId));
906 AbstractFile abstractFileById = skCase.getAbstractFileById(key.
getObjID());
907 lookupContents.add(abstractFileById);
908 return new Node[]{
new FileWithCCNNode(key, abstractFileById, lookupContents.toArray())};
909 }
catch (TskCoreException ex) {
910 LOGGER.log(Level.SEVERE,
"Error getting content for file with ccn hits.", ex);
929 this.setIconBaseWithExtension(
"org/sleuthkit/autopsy/images/file-icon.png");
930 reviewStatusBus.register(
this);
934 "# {0} - number of children",
935 "Accounts.ByFileNode.displayName=By File ({0})"})
938 =
"SELECT count(*) FROM ( SELECT count(*) AS documents "
939 +
" FROM blackboard_artifacts "
940 +
" LEFT JOIN blackboard_attributes as solr_attribute ON blackboard_artifacts.artifact_id = solr_attribute.artifact_id "
941 +
" AND solr_attribute.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD_SEARCH_DOCUMENT_ID.getTypeID()
942 +
" LEFT JOIN blackboard_attributes as account_type ON blackboard_artifacts.artifact_id = account_type.artifact_id "
943 +
" AND account_type.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ACCOUNT_TYPE.getTypeID()
944 +
" AND account_type.value_text = '" + Account.Type.CREDIT_CARD.getTypeName() +
"'"
945 +
" WHERE blackboard_artifacts.artifact_type_id = " + BlackboardArtifact.ARTIFACT_TYPE.TSK_ACCOUNT.getTypeID()
948 +
" GROUP BY blackboard_artifacts.obj_id, solr_attribute.value_text ) AS foo";
949 try (SleuthkitCase.CaseDbQuery results = skCase.executeQuery(query);
950 ResultSet resultSet = results.getResultSet();) {
951 while (resultSet.next()) {
952 if (skCase.getDatabaseType().equals(DbType.POSTGRESQL)) {
953 setDisplayName(Bundle.Accounts_ByFileNode_displayName(resultSet.getLong(
"count")));
955 setDisplayName(Bundle.Accounts_ByFileNode_displayName(resultSet.getLong(
"count(*)")));
958 }
catch (TskCoreException | SQLException ex) {
959 LOGGER.log(Level.SEVERE,
"Error querying for files with ccn hits.", ex);
971 return visitor.
visit(
this);
976 return getClass().getName();
992 private final PropertyChangeListener pcl =
new PropertyChangeListener() {
994 public void propertyChange(PropertyChangeEvent evt) {
995 String eventType = evt.getPropertyName();
1012 if (null != eventData
1014 reviewStatusBus.post(eventData);
1035 && (evt.getNewValue() == null)) {
1056 super.removeNotify();
1074 RangeMap<Integer, BinResult> binRanges = TreeRangeMap.create();
1077 =
"SELECT SUBSTR(blackboard_attributes.value_text,1,8) AS BIN, "
1078 +
" COUNT(blackboard_artifacts.artifact_id) AS count "
1079 +
" FROM blackboard_artifacts "
1080 +
" JOIN blackboard_attributes ON blackboard_artifacts.artifact_id = blackboard_attributes.artifact_id"
1081 +
" WHERE blackboard_artifacts.artifact_type_id = " + BlackboardArtifact.ARTIFACT_TYPE.TSK_ACCOUNT.getTypeID()
1082 +
" AND blackboard_attributes.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_CARD_NUMBER.getTypeID()
1087 try (SleuthkitCase.CaseDbQuery results = skCase.executeQuery(query);
1088 ResultSet resultSet = results.getResultSet();) {
1090 while (resultSet.next()) {
1091 final Integer bin = Integer.valueOf(resultSet.getString(
"BIN"));
1092 long count = resultSet.getLong(
"count");
1095 BinResult previousResult = binRanges.get(bin);
1097 if (previousResult != null) {
1098 binRanges.remove(Range.closed(previousResult.getBINStart(), previousResult.getBINEnd()));
1099 count += previousResult.getCount();
1102 if (binRange == null) {
1103 binRanges.put(Range.closed(bin, bin),
new BinResult(count, bin, bin));
1108 binRanges.asMapOfRanges().values().forEach(list::add);
1109 }
catch (TskCoreException | SQLException ex) {
1110 LOGGER.log(Level.SEVERE,
"Error querying for BINs.", ex);
1118 return new Node[]{
new BINNode(key)};
1131 @NbBundle.Messages(
"Accounts.ByBINNode.name=By BIN")
1133 super(Children.create(
new BINFactory(),
true), Lookups.singleton(Bundle.Accounts_ByBINNode_name()));
1134 setName(Bundle.Accounts_ByBINNode_name());
1135 updateDisplayName();
1136 this.setIconBaseWithExtension(
"org/sleuthkit/autopsy/images/bank.png");
1137 reviewStatusBus.register(
this);
1140 @NbBundle.Messages({
1141 "# {0} - number of children",
1142 "Accounts.ByBINNode.displayName=By BIN ({0})"})
1145 =
"SELECT count(distinct SUBSTR(blackboard_attributes.value_text,1,8)) AS BINs "
1146 +
" FROM blackboard_artifacts "
1147 +
" JOIN blackboard_attributes ON blackboard_artifacts.artifact_id = blackboard_attributes.artifact_id"
1148 +
" WHERE blackboard_artifacts.artifact_type_id = " + BlackboardArtifact.ARTIFACT_TYPE.TSK_ACCOUNT.getTypeID()
1149 +
" AND blackboard_attributes.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_CARD_NUMBER.getTypeID()
1152 try (SleuthkitCase.CaseDbQuery results = skCase.executeQuery(query);
1153 ResultSet resultSet = results.getResultSet();) {
1154 while (resultSet.next()) {
1155 setDisplayName(Bundle.Accounts_ByBINNode_displayName(resultSet.getLong(
"BINs")));
1157 }
catch (TskCoreException | SQLException ex) {
1158 LOGGER.log(Level.SEVERE,
"Error querying for BINs.", ex);
1169 return visitor.
visit(
this);
1174 return getClass().getName();
1179 updateDisplayName();
1184 updateDisplayName();
1198 hash = 79 * hash + (int) (this.objID ^ (this.objID >>> 32));
1199 hash = 79 * hash + Objects.hashCode(this.keywordSearchDocID);
1200 hash = 79 * hash + Objects.hashCode(this.artifactIDs);
1201 hash = 79 * hash + (int) (this.hits ^ (this.hits >>> 32));
1202 hash = 79 * hash + Objects.hashCode(this.statuses);
1214 if (getClass() != obj.getClass()) {
1218 if (this.objID != other.
objID) {
1221 if (this.hits != other.
hits) {
1227 if (!Objects.equals(
this.artifactIDs, other.
artifactIDs)) {
1230 if (!Objects.equals(
this.statuses, other.
statuses)) {
1240 private final Set<BlackboardArtifact.ReviewStatus>
statuses;
1242 private FileWithCCN(
long objID, String solrDocID, List<Long> artifactIDs,
long hits, Set<BlackboardArtifact.ReviewStatus> statuses) {
1244 this.keywordSearchDocID = solrDocID;
1245 this.artifactIDs = artifactIDs;
1247 this.statuses = statuses;
1266 return keywordSearchDocID;
1275 return Collections.unmodifiableList(artifactIDs);
1293 return Collections.unmodifiableSet(statuses);
1313 static <X> List<X> unGroupConcat(String groupConcat, Function<String, X> mapper) {
1314 return StringUtils.isBlank(groupConcat) ? Collections.emptyList()
1315 : Stream.of(groupConcat.split(
","))
1317 .collect(Collectors.toList());
1337 @NbBundle.Messages({
1338 "# {0} - raw file name",
1339 "# {1} - solr chunk id",
1340 "Accounts.FileWithCCNNode.unallocatedSpaceFile.displayName={0}_chunk_{1}"})
1342 super(Children.LEAF, Lookups.fixed(lookupContents));
1346 : Bundle.Accounts_FileWithCCNNode_unallocatedSpaceFile_displayName(content.getName(), StringUtils.substringAfter(key.
getkeywordSearchDocID(),
"_"));
1347 setName(fileName + key.
getObjID());
1348 setDisplayName(fileName);
1358 return visitor.
visit(
this);
1363 return getClass().getName();
1367 @NbBundle.Messages({
1368 "Accounts.FileWithCCNNode.nameProperty.displayName=File",
1369 "Accounts.FileWithCCNNode.accountsProperty.displayName=Accounts",
1370 "Accounts.FileWithCCNNode.statusProperty.displayName=Status",
1371 "Accounts.FileWithCCNNode.noDescription=no description"})
1373 Sheet sheet = super.createSheet();
1374 Sheet.Set propSet = sheet.get(Sheet.PROPERTIES);
1375 if (propSet == null) {
1376 propSet = Sheet.createPropertiesSet();
1380 propSet.put(
new NodeProperty<>(Bundle.Accounts_FileWithCCNNode_nameProperty_displayName(),
1381 Bundle.Accounts_FileWithCCNNode_nameProperty_displayName(),
1382 Bundle.Accounts_FileWithCCNNode_noDescription(),
1384 propSet.put(
new NodeProperty<>(Bundle.Accounts_FileWithCCNNode_accountsProperty_displayName(),
1385 Bundle.Accounts_FileWithCCNNode_accountsProperty_displayName(),
1386 Bundle.Accounts_FileWithCCNNode_noDescription(),
1388 propSet.put(
new NodeProperty<>(Bundle.Accounts_FileWithCCNNode_statusProperty_displayName(),
1389 Bundle.Accounts_FileWithCCNNode_statusProperty_displayName(),
1390 Bundle.Accounts_FileWithCCNNode_noDescription(),
1392 .map(BlackboardArtifact.ReviewStatus::getDisplayName)
1393 .collect(Collectors.joining(
", "))));
1400 Action[] actions = super.getActions(context);
1401 ArrayList<Action> arrayList =
new ArrayList<>();
1402 arrayList.addAll(Arrays.asList(actions));
1405 }
catch (TskCoreException ex) {
1406 LOGGER.log(Level.SEVERE,
"Error gettung content by id", ex);
1409 arrayList.add(approveActionInstance);
1410 arrayList.add(rejectActionInstance);
1412 return arrayList.toArray(
new Action[arrayList.size()]);
1440 =
"SELECT blackboard_artifacts.artifact_id "
1441 +
" FROM blackboard_artifacts "
1442 +
" JOIN blackboard_attributes ON blackboard_artifacts.artifact_id = blackboard_attributes.artifact_id "
1443 +
" WHERE blackboard_artifacts.artifact_type_id = " + BlackboardArtifact.ARTIFACT_TYPE.TSK_ACCOUNT.getTypeID()
1444 +
" AND blackboard_attributes.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_CARD_NUMBER.getTypeID()
1445 +
" AND blackboard_attributes.value_text >= '" + bin.getBINStart() +
"' AND blackboard_attributes.value_text < '" + (bin.getBINEnd() + 1) +
"'"
1448 +
" ORDER BY blackboard_attributes.value_text";
1449 try (SleuthkitCase.CaseDbQuery results = skCase.executeQuery(query);
1450 ResultSet rs = results.getResultSet();) {
1452 list.add(rs.getLong(
"artifact_id"));
1454 }
catch (TskCoreException | SQLException ex) {
1455 LOGGER.log(Level.SEVERE,
"Error querying for account artifacts.", ex);
1463 if (skCase == null) {
1468 BlackboardArtifact art = skCase.getBlackboardArtifact(artifactID);
1470 }
catch (TskCoreException ex) {
1471 LOGGER.log(Level.SEVERE,
"Error creating BlackboardArtifactNode for artifact with ID " + artifactID, ex);
1478 if (bin.getBINStart() == bin.getBINEnd()) {
1479 return Integer.toString(bin.getBINStart());
1481 return bin.getBINStart() +
"-" + StringUtils.difference(bin.getBINStart() +
"", bin.getBINEnd() +
"");
1496 updateDisplayName();
1497 this.setIconBaseWithExtension(
"org/sleuthkit/autopsy/images/bank.png");
1498 reviewStatusBus.register(
this);
1503 updateDisplayName();
1509 updateDisplayName();
1514 =
"SELECT count(blackboard_artifacts.artifact_id ) AS count"
1515 +
" FROM blackboard_artifacts "
1516 +
" JOIN blackboard_attributes ON blackboard_artifacts.artifact_id = blackboard_attributes.artifact_id "
1517 +
" WHERE blackboard_artifacts.artifact_type_id = " + BlackboardArtifact.ARTIFACT_TYPE.TSK_ACCOUNT.getTypeID()
1518 +
" AND blackboard_attributes.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_CARD_NUMBER.getTypeID()
1519 +
" AND blackboard_attributes.value_text >= '" + bin.getBINStart() +
"' AND blackboard_attributes.value_text < '" + (bin.getBINEnd() + 1) +
"'"
1522 try (SleuthkitCase.CaseDbQuery results = skCase.executeQuery(query);
1523 ResultSet resultSet = results.getResultSet();) {
1524 while (resultSet.next()) {
1525 setDisplayName(
getBinRangeString(bin) +
" (" + resultSet.getLong(
"count") +
")");
1527 }
catch (TskCoreException | SQLException ex) {
1528 LOGGER.log(Level.SEVERE,
"Error querying for account artifacts.", ex);
1541 return visitor.
visit(
this);
1546 return getClass().getName();
1550 Sheet.Set sheetSet = sheet.get(Sheet.PROPERTIES);
1551 if (sheetSet == null) {
1552 sheetSet = Sheet.createPropertiesSet();
1553 sheet.put(sheetSet);
1559 @NbBundle.Messages({
1560 "Accounts.BINNode.binProperty.displayName=Bank Identifier Number",
1561 "Accounts.BINNode.accountsProperty.displayName=Accounts",
1562 "Accounts.BINNode.cardTypeProperty.displayName=Payment Card Type",
1563 "Accounts.BINNode.schemeProperty.displayName=Credit Card Scheme",
1564 "Accounts.BINNode.brandProperty.displayName=Brand",
1565 "Accounts.BINNode.bankProperty.displayName=Bank",
1566 "Accounts.BINNode.bankCityProperty.displayName=Bank City",
1567 "Accounts.BINNode.bankCountryProperty.displayName=Bank Country",
1568 "Accounts.BINNode.bankPhoneProperty.displayName=Bank Phone #",
1569 "Accounts.BINNode.bankURLProperty.displayName=Bank URL",
1570 "Accounts.BINNode.noDescription=no description"})
1572 Sheet sheet = super.createSheet();
1573 Sheet.Set properties = getPropertySet(sheet);
1575 properties.put(
new NodeProperty<>(Bundle.Accounts_BINNode_binProperty_displayName(),
1576 Bundle.Accounts_BINNode_binProperty_displayName(),
1577 Bundle.Accounts_BINNode_noDescription(),
1579 properties.put(
new NodeProperty<>(Bundle.Accounts_BINNode_accountsProperty_displayName(),
1580 Bundle.Accounts_BINNode_accountsProperty_displayName(), Bundle.Accounts_BINNode_noDescription(),
1584 if (bin.hasDetails()) {
1585 bin.
getCardType().ifPresent(cardType -> properties.put(
new NodeProperty<>(Bundle.Accounts_BINNode_cardTypeProperty_displayName(),
1586 Bundle.Accounts_BINNode_cardTypeProperty_displayName(), Bundle.Accounts_BINNode_noDescription(),
1588 bin.
getScheme().ifPresent(scheme -> properties.put(
new NodeProperty<>(Bundle.Accounts_BINNode_schemeProperty_displayName(),
1589 Bundle.Accounts_BINNode_schemeProperty_displayName(), Bundle.Accounts_BINNode_noDescription(),
1591 bin.
getBrand().ifPresent(brand -> properties.put(
new NodeProperty<>(Bundle.Accounts_BINNode_brandProperty_displayName(),
1592 Bundle.Accounts_BINNode_brandProperty_displayName(), Bundle.Accounts_BINNode_noDescription(),
1594 bin.
getBankName().ifPresent(bankName -> properties.put(
new NodeProperty<>(Bundle.Accounts_BINNode_bankProperty_displayName(),
1595 Bundle.Accounts_BINNode_bankProperty_displayName(), Bundle.Accounts_BINNode_noDescription(),
1597 bin.
getBankCity().ifPresent(bankCity -> properties.put(
new NodeProperty<>(Bundle.Accounts_BINNode_bankCityProperty_displayName(),
1598 Bundle.Accounts_BINNode_bankCityProperty_displayName(), Bundle.Accounts_BINNode_noDescription(),
1600 bin.
getCountry().ifPresent(country -> properties.put(
new NodeProperty<>(Bundle.Accounts_BINNode_bankCountryProperty_displayName(),
1601 Bundle.Accounts_BINNode_bankCountryProperty_displayName(), Bundle.Accounts_BINNode_noDescription(),
1604 Bundle.Accounts_BINNode_bankPhoneProperty_displayName(), Bundle.Accounts_BINNode_noDescription(),
1606 bin.
getBankURL().ifPresent(url -> properties.put(
new NodeProperty<>(Bundle.Accounts_BINNode_bankURLProperty_displayName(),
1607 Bundle.Accounts_BINNode_bankURLProperty_displayName(), Bundle.Accounts_BINNode_noDescription(),
1614 this.setSheet(createSheet());
1629 hash = 97 * hash + this.binEnd;
1630 hash = 97 * hash + this.binStart;
1642 if (getClass() != obj.getClass()) {
1646 if (this.binEnd != other.
binEnd) {
1649 if (this.binStart != other.
binStart) {
1666 this.binRange = binRange;
1667 binStart = binRange.getBINstart();
1668 binEnd = binRange.getBINend();
1673 this.binRange = null;
1690 boolean hasDetails() {
1691 return binRange != null;
1745 super(artifact,
"org/sleuthkit/autopsy/images/credit-card.png");
1746 this.artifact = artifact;
1747 setName(Long.toString(
this.artifact.getArtifactID()));
1749 reviewStatusBus.register(
this);
1754 List<Action> actionsList =
new ArrayList<>();
1755 actionsList.addAll(Arrays.asList(super.getActions(context)));
1757 actionsList.add(approveActionInstance);
1758 actionsList.add(rejectActionInstance);
1760 return actionsList.toArray(
new Action[actionsList.size()]);
1765 Sheet sheet = super.createSheet();
1766 Sheet.Set properties = sheet.get(Sheet.PROPERTIES);
1767 if (properties == null) {
1768 properties = Sheet.createPropertiesSet();
1769 sheet.put(properties);
1771 properties.put(
new NodeProperty<>(Bundle.Accounts_FileWithCCNNode_statusProperty_displayName(),
1772 Bundle.Accounts_FileWithCCNNode_statusProperty_displayName(),
1773 Bundle.Accounts_FileWithCCNNode_noDescription(),
1774 artifact.getReviewStatus().getDisplayName()));
1783 event.artifacts.stream().filter((art) -> (art.getArtifactID() == this.artifact.getArtifactID())).map((_item) -> {
1785 }).forEachOrdered((_item) -> {
1791 this.setSheet(createSheet());
1799 @NbBundle.Messages(
"ToggleShowRejected.name=Show Rejected Results")
1801 super(Bundle.ToggleShowRejected_name());
1827 this.newStatus = newStatus;
1838 List<String[]> selectedPaths = Utilities.actionsGlobalContext().lookupAll(Node.class).stream()
1840 String[] createPath;
1846 if (newStatus == BlackboardArtifact.ReviewStatus.REJECTED && showRejected ==
false) {
1847 List<Node> siblings = Arrays.asList(node.getParentNode().getChildren().getNodes());
1848 if (siblings.size() > 1) {
1849 int indexOf = siblings.indexOf(node);
1851 Node sibling = indexOf > 0
1852 ? siblings.get(indexOf - 1)
1853 : siblings.get(Integer.max(indexOf + 1, siblings.size() - 1));
1854 createPath = NodeOp.createPath(sibling, null);
1864 createPath = NodeOp.createPath(node, null);
1867 return Arrays.copyOfRange(createPath, 1, createPath.length);
1869 .filter(Objects::nonNull)
1870 .collect(Collectors.toList());
1873 final Collection<? extends BlackboardArtifact> artifacts = Utilities.actionsGlobalContext().lookupAll(BlackboardArtifact.class);
1874 artifacts.forEach(artifact -> {
1876 artifact.setReviewStatus(newStatus);
1877 }
catch (TskCoreException ex) {
1878 LOGGER.log(Level.SEVERE,
"Error changing artifact review status.", ex);
1882 reviewStatusBus.post(
new ReviewStatusChangeEvent(artifacts, newStatus));
1884 final DataResultTopComponent directoryListing = DirectoryTreeTopComponent.findInstance().getDirectoryListing();
1885 final Node rootNode = directoryListing.getRootNode();
1888 List<Node> toArray =
new ArrayList<>();
1889 selectedPaths.forEach(path -> {
1891 toArray.add(NodeOp.findPath(rootNode, path));
1892 }
catch (NodeNotFoundException ex) {
1897 directoryListing.setSelectedNodes(toArray.toArray(
new Node[toArray.size()]));
1903 @NbBundle.Messages({
"ApproveAccountsAction.name=Approve Accounts"})
1905 super(Bundle.ApproveAccountsAction_name(), BlackboardArtifact.ReviewStatus.APPROVED);
1911 @NbBundle.Messages({
"RejectAccountsAction.name=Reject Accounts"})
1913 super(Bundle.RejectAccountsAction_name(), BlackboardArtifact.ReviewStatus.REJECTED);
1919 Collection<? extends BlackboardArtifact> artifacts;
1920 BlackboardArtifact.ReviewStatus newReviewStatus;
1922 ReviewStatusChangeEvent(Collection<? extends BlackboardArtifact> artifacts, BlackboardArtifact.ReviewStatus newReviewStatus) {
1923 this.artifacts = artifacts;
1924 this.newReviewStatus = newReviewStatus;
1935 if (type.equals(Account.Type.CREDIT_CARD)) {
1936 return ICON_BASE_PATH +
"credit-card.png";
1937 }
else if (type.equals(Account.Type.DEVICE)) {
1938 return ICON_BASE_PATH +
"image.png";
1939 }
else if (type.equals(Account.Type.EMAIL)) {
1940 return ICON_BASE_PATH +
"email.png";
1941 }
else if (type.equals(Account.Type.FACEBOOK)) {
1942 return ICON_BASE_PATH +
"facebook.png";
1943 }
else if (type.equals(Account.Type.INSTAGRAM)) {
1944 return ICON_BASE_PATH +
"instagram.png";
1945 }
else if (type.equals(Account.Type.MESSAGING_APP)) {
1946 return ICON_BASE_PATH +
"messaging.png";
1947 }
else if (type.equals(Account.Type.PHONE)) {
1948 return ICON_BASE_PATH +
"phone.png";
1949 }
else if (type.equals(Account.Type.TWITTER)) {
1950 return ICON_BASE_PATH +
"twitter.png";
1951 }
else if (type.equals(Account.Type.WEBSITE)) {
1952 return ICON_BASE_PATH +
"web-file.png";
1953 }
else if (type.equals(Account.Type.WHATSAPP)) {
1954 return ICON_BASE_PATH +
"WhatsApp.png";
1957 return ICON_BASE_PATH +
"face.png";
CreditCardNumberFactory(BinResult bin)
static final Set< IngestManager.IngestModuleEvent > INGEST_MODULE_EVENTS_OF_INTEREST
final BlackboardArtifact.ReviewStatus newStatus
boolean createKeys(List< CreditCardViewMode > list)
DefaultAccountFactory(Account.Type accountType)
BlackboardArtifact.Type getBlackboardArtifactType()
void removeIngestModuleEventListener(final PropertyChangeListener listener)
Optional< Integer > getNumberLength()
Node[] createNodesForKey(Long t)
Optional< String > getCountry()
final BlackboardArtifact artifact
static synchronized IngestManager getInstance()
String getBinRangeString(BinResult bin)
static final Logger LOGGER
Node[] createNodesForKey(BinResult key)
Optional< String > getBankPhoneNumber()
Set< BlackboardArtifact.ReviewStatus > getStatuses()
void setShowRejected(boolean showRejected)
Optional< String > getCountry()
Sheet.Set getPropertySet(Sheet sheet)
Optional< String > getBankCity()
final String keywordSearchDocID
static List< Action > getActions(File file, boolean isArtifactSource)
Optional< String > getBankName()
final EventBus reviewStatusBus
String getRejectedArtifactFilterClause()
final RejectAccounts rejectActionInstance
final Account.Type accountType
List< Long > getArtifactIDs()
boolean createKeys(List< String > list)
abstract boolean createKeys(List< X > list)
AccountArtifactNode(BlackboardArtifact artifact)
static synchronized BankIdentificationNumber getBINInfo(int bin)
Node[] getNodeArr(Node node)
Node[] createNodesForKey(Long artifactID)
Action[] getActions(boolean context)
Node[] createNodesForKey(FileWithCCN key)
static String getIconFilePath(Account.Type type)
boolean createKeys(List< FileWithCCN > list)
final Account.Type accountType
Optional< String > getBankURL()
boolean createKeys(List< Long > list)
final Map< String, Long > counts
final ApproveAccounts approveActionInstance
final long filteringDSObjId
T visit(DataSourcesNode in)
Node[] createNodesForKey(CreditCardViewMode key)
void removeIngestJobEventListener(final PropertyChangeListener listener)
Optional< String > getScheme()
final Set< BlackboardArtifact.ReviewStatus > statuses
Optional< String > getBrand()
boolean equals(Object obj)
CreditCardNumberAccountTypeNode()
void addIngestJobEventListener(final PropertyChangeListener listener)
DefaultAccountTypeNode(Account.Type accountType)
Optional< String > getBankURL()
String getkeywordSearchDocID()
Optional< Integer > getNumberLength()
BinResult(long count,@Nonnull BINRange binRange)
Action newToggleShowRejectedAction()
Optional< String > getBrand()
Node[] createNodesForKey(String acountTypeName)
boolean createKeys(List< Long > list)
FileWithCCNNode(FileWithCCN key, Content content, Object[] lookupContents)
Action[] getActions(boolean context)
final List< Long > artifactIDs
FileWithCCN(long objID, String solrDocID, List< Long > artifactIDs, long hits, Set< BlackboardArtifact.ReviewStatus > statuses)
void actionPerformed(ActionEvent e)
boolean createKeys(List< BinResult > list)
Optional< String > getBankCity()
Optional< String > getCardType()
final FileWithCCN fileKey
BinResult(long count, int start, int end)
void addIngestModuleEventListener(final PropertyChangeListener listener)
synchronized static Logger getLogger(String name)
Accounts(SleuthkitCase skCase, long objId)
static Case getCurrentCaseThrows()
final PropertyChangeListener pcl
static void addEventTypeSubscriber(Set< Events > eventTypes, PropertyChangeListener subscriber)
final AccountTypeResults accountTypeResults
final PropertyChangeListener pcl
boolean equals(Object obj)
static final Set< IngestManager.IngestJobEvent > INGEST_JOB_EVENTS_OF_INTEREST
ReviewStatusAction(String displayName, BlackboardArtifact.ReviewStatus newStatus)
static final String ICON_BASE_PATH
static void removeEventTypeSubscriber(Set< Events > eventTypes, PropertyChangeListener subscriber)
void actionPerformed(ActionEvent e)
String getFilterByDataSourceClause()
Optional< String > getScheme()
Optional< String > getBankName()
Optional< String > getBankPhoneNumber()
Optional< String > getCardType()
Accounts(SleuthkitCase skCase)