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();) {
532 List<Long> tempList =
new ArrayList<>();
534 tempList.add(rs.getLong(
"artifact_id"));
536 list.addAll(tempList);
537 }
catch (TskCoreException | SQLException ex) {
538 LOGGER.log(Level.SEVERE,
"Error querying for account artifacts.", ex);
548 }
catch (TskCoreException ex) {
549 LOGGER.log(Level.SEVERE,
"Error get black board artifact with id " + t, ex);
575 super(Children.create(
new DefaultAccountFactory(accountType),
true), Lookups.singleton(accountType));
578 this.setIconBaseWithExtension(iconPath != null && iconPath.charAt(0) ==
'/' ? iconPath.substring(1) : iconPath);
589 return visitor.
visit(
this);
594 return getClass().getName();
612 setName(String.format(
"%s (%d)", accountType.getDisplayName(), accountTypeResults.getCount(accountType.getTypeName())));
626 private final PropertyChangeListener pcl =
new PropertyChangeListener() {
628 public void propertyChange(PropertyChangeEvent evt) {
629 String eventType = evt.getPropertyName();
646 if (null != eventData
648 reviewStatusBus.post(eventData);
670 if (evt.getNewValue() == null) {
703 super.removeNotify();
710 protected boolean createKeys(List<CreditCardViewMode> list) {
739 super(Children.create(
new ViewModeFactory(),
true), Lookups.singleton(Account.Type.CREDIT_CARD.getDisplayName()));
740 setName(Account.Type.CREDIT_CARD.getDisplayName());
741 this.setIconBaseWithExtension(
"org/sleuthkit/autopsy/images/credit-cards.png");
748 setName(String.format(
"%s (%d)", Account.Type.CREDIT_CARD.getDisplayName(), accountTypeResults.getCount(Account.Type.CREDIT_CARD.getTypeName())));
768 return visitor.
visit(
this);
773 return getClass().getName();
779 private final PropertyChangeListener pcl =
new PropertyChangeListener() {
781 public void propertyChange(PropertyChangeEvent evt) {
782 String eventType = evt.getPropertyName();
799 if (null != eventData
801 reviewStatusBus.post(eventData);
823 if (evt.getNewValue() == null) {
844 super.removeNotify();
862 =
"SELECT blackboard_artifacts.obj_id,"
863 +
" solr_attribute.value_text AS solr_document_id, ";
864 if (skCase.getDatabaseType().equals(DbType.POSTGRESQL)) {
865 query +=
" string_agg(blackboard_artifacts.artifact_id::character varying, ',') AS artifact_IDs, "
866 +
" string_agg(blackboard_artifacts.review_status_id::character varying, ',') AS review_status_ids, ";
868 query +=
" GROUP_CONCAT(blackboard_artifacts.artifact_id) AS artifact_IDs, "
869 +
" GROUP_CONCAT(blackboard_artifacts.review_status_id) AS review_status_ids, ";
871 query +=
" COUNT( blackboard_artifacts.artifact_id) AS hits "
872 +
" FROM blackboard_artifacts "
873 +
" LEFT JOIN blackboard_attributes as solr_attribute ON blackboard_artifacts.artifact_id = solr_attribute.artifact_id "
874 +
" AND solr_attribute.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD_SEARCH_DOCUMENT_ID.getTypeID()
875 +
" LEFT JOIN blackboard_attributes as account_type ON blackboard_artifacts.artifact_id = account_type.artifact_id "
876 +
" AND account_type.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ACCOUNT_TYPE.getTypeID()
877 +
" AND account_type.value_text = '" + Account.Type.CREDIT_CARD.getTypeName() +
"'"
878 +
" WHERE blackboard_artifacts.artifact_type_id = " + BlackboardArtifact.ARTIFACT_TYPE.TSK_ACCOUNT.getTypeID()
881 +
" GROUP BY blackboard_artifacts.obj_id, solr_document_id "
882 +
" ORDER BY hits DESC ";
883 try (SleuthkitCase.CaseDbQuery results = skCase.executeQuery(query);
884 ResultSet resultSet = results.getResultSet();) {
885 while (resultSet.next()) {
887 resultSet.getLong(
"obj_id"),
888 resultSet.getString(
"solr_document_id"),
889 unGroupConcat(resultSet.getString(
"artifact_IDs"), Long::valueOf),
890 resultSet.getLong(
"hits"),
891 new HashSet<>(unGroupConcat(resultSet.getString(
"review_status_ids"), reviewStatusID -> BlackboardArtifact.ReviewStatus.withID(Integer.valueOf(reviewStatusID))))));
893 }
catch (TskCoreException | SQLException ex) {
894 LOGGER.log(Level.SEVERE,
"Error querying for files with ccn hits.", ex);
904 List<Object> lookupContents =
new ArrayList<>();
906 lookupContents.add(skCase.getBlackboardArtifact(artId));
908 AbstractFile abstractFileById = skCase.getAbstractFileById(key.
getObjID());
909 lookupContents.add(abstractFileById);
910 return new Node[]{
new FileWithCCNNode(key, abstractFileById, lookupContents.toArray())};
911 }
catch (TskCoreException ex) {
912 LOGGER.log(Level.SEVERE,
"Error getting content for file with ccn hits.", ex);
931 this.setIconBaseWithExtension(
"org/sleuthkit/autopsy/images/file-icon.png");
932 reviewStatusBus.register(
this);
936 "# {0} - number of children",
937 "Accounts.ByFileNode.displayName=By File ({0})"})
940 =
"SELECT count(*) FROM ( SELECT count(*) AS documents "
941 +
" FROM blackboard_artifacts "
942 +
" LEFT JOIN blackboard_attributes as solr_attribute ON blackboard_artifacts.artifact_id = solr_attribute.artifact_id "
943 +
" AND solr_attribute.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD_SEARCH_DOCUMENT_ID.getTypeID()
944 +
" LEFT JOIN blackboard_attributes as account_type ON blackboard_artifacts.artifact_id = account_type.artifact_id "
945 +
" AND account_type.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ACCOUNT_TYPE.getTypeID()
946 +
" AND account_type.value_text = '" + Account.Type.CREDIT_CARD.getTypeName() +
"'"
947 +
" WHERE blackboard_artifacts.artifact_type_id = " + BlackboardArtifact.ARTIFACT_TYPE.TSK_ACCOUNT.getTypeID()
950 +
" GROUP BY blackboard_artifacts.obj_id, solr_attribute.value_text ) AS foo";
951 try (SleuthkitCase.CaseDbQuery results = skCase.executeQuery(query);
952 ResultSet resultSet = results.getResultSet();) {
953 while (resultSet.next()) {
954 if (skCase.getDatabaseType().equals(DbType.POSTGRESQL)) {
955 setDisplayName(Bundle.Accounts_ByFileNode_displayName(resultSet.getLong(
"count")));
957 setDisplayName(Bundle.Accounts_ByFileNode_displayName(resultSet.getLong(
"count(*)")));
960 }
catch (TskCoreException | SQLException ex) {
961 LOGGER.log(Level.SEVERE,
"Error querying for files with ccn hits.", ex);
973 return visitor.
visit(
this);
978 return getClass().getName();
994 private final PropertyChangeListener pcl =
new PropertyChangeListener() {
996 public void propertyChange(PropertyChangeEvent evt) {
997 String eventType = evt.getPropertyName();
1014 if (null != eventData
1016 reviewStatusBus.post(eventData);
1037 && (evt.getNewValue() == null)) {
1058 super.removeNotify();
1076 RangeMap<Integer, BinResult> binRanges = TreeRangeMap.create();
1079 =
"SELECT SUBSTR(blackboard_attributes.value_text,1,8) AS BIN, "
1080 +
" COUNT(blackboard_artifacts.artifact_id) AS count "
1081 +
" FROM blackboard_artifacts "
1082 +
" JOIN blackboard_attributes ON blackboard_artifacts.artifact_id = blackboard_attributes.artifact_id"
1083 +
" WHERE blackboard_artifacts.artifact_type_id = " + BlackboardArtifact.ARTIFACT_TYPE.TSK_ACCOUNT.getTypeID()
1084 +
" AND blackboard_attributes.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_CARD_NUMBER.getTypeID()
1089 try (SleuthkitCase.CaseDbQuery results = skCase.executeQuery(query);
1090 ResultSet resultSet = results.getResultSet();) {
1092 while (resultSet.next()) {
1093 final Integer bin = Integer.valueOf(resultSet.getString(
"BIN"));
1094 long count = resultSet.getLong(
"count");
1097 BinResult previousResult = binRanges.get(bin);
1099 if (previousResult != null) {
1100 binRanges.remove(Range.closed(previousResult.getBINStart(), previousResult.getBINEnd()));
1101 count += previousResult.getCount();
1104 if (binRange == null) {
1105 binRanges.put(Range.closed(bin, bin),
new BinResult(count, bin, bin));
1110 binRanges.asMapOfRanges().values().forEach(list::add);
1111 }
catch (TskCoreException | SQLException ex) {
1112 LOGGER.log(Level.SEVERE,
"Error querying for BINs.", ex);
1120 return new Node[]{
new BINNode(key)};
1133 @NbBundle.Messages(
"Accounts.ByBINNode.name=By BIN")
1135 super(Children.create(
new BINFactory(),
true), Lookups.singleton(Bundle.Accounts_ByBINNode_name()));
1136 setName(Bundle.Accounts_ByBINNode_name());
1137 updateDisplayName();
1138 this.setIconBaseWithExtension(
"org/sleuthkit/autopsy/images/bank.png");
1139 reviewStatusBus.register(
this);
1142 @NbBundle.Messages({
1143 "# {0} - number of children",
1144 "Accounts.ByBINNode.displayName=By BIN ({0})"})
1147 =
"SELECT count(distinct SUBSTR(blackboard_attributes.value_text,1,8)) AS BINs "
1148 +
" FROM blackboard_artifacts "
1149 +
" JOIN blackboard_attributes ON blackboard_artifacts.artifact_id = blackboard_attributes.artifact_id"
1150 +
" WHERE blackboard_artifacts.artifact_type_id = " + BlackboardArtifact.ARTIFACT_TYPE.TSK_ACCOUNT.getTypeID()
1151 +
" AND blackboard_attributes.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_CARD_NUMBER.getTypeID()
1154 try (SleuthkitCase.CaseDbQuery results = skCase.executeQuery(query);
1155 ResultSet resultSet = results.getResultSet();) {
1156 while (resultSet.next()) {
1157 setDisplayName(Bundle.Accounts_ByBINNode_displayName(resultSet.getLong(
"BINs")));
1159 }
catch (TskCoreException | SQLException ex) {
1160 LOGGER.log(Level.SEVERE,
"Error querying for BINs.", ex);
1171 return visitor.
visit(
this);
1176 return getClass().getName();
1181 updateDisplayName();
1186 updateDisplayName();
1200 hash = 79 * hash + (int) (this.objID ^ (this.objID >>> 32));
1201 hash = 79 * hash + Objects.hashCode(this.keywordSearchDocID);
1202 hash = 79 * hash + Objects.hashCode(this.artifactIDs);
1203 hash = 79 * hash + (int) (this.hits ^ (this.hits >>> 32));
1204 hash = 79 * hash + Objects.hashCode(this.statuses);
1216 if (getClass() != obj.getClass()) {
1220 if (this.objID != other.
objID) {
1223 if (this.hits != other.
hits) {
1229 if (!Objects.equals(
this.artifactIDs, other.
artifactIDs)) {
1232 if (!Objects.equals(
this.statuses, other.
statuses)) {
1242 private final Set<BlackboardArtifact.ReviewStatus>
statuses;
1244 private FileWithCCN(
long objID, String solrDocID, List<Long> artifactIDs,
long hits, Set<BlackboardArtifact.ReviewStatus> statuses) {
1246 this.keywordSearchDocID = solrDocID;
1247 this.artifactIDs = artifactIDs;
1249 this.statuses = statuses;
1268 return keywordSearchDocID;
1277 return Collections.unmodifiableList(artifactIDs);
1295 return Collections.unmodifiableSet(statuses);
1315 static <X> List<X> unGroupConcat(String groupConcat, Function<String, X> mapper) {
1316 return StringUtils.isBlank(groupConcat) ? Collections.emptyList()
1317 : Stream.of(groupConcat.split(
","))
1319 .collect(Collectors.toList());
1339 @NbBundle.Messages({
1340 "# {0} - raw file name",
1341 "# {1} - solr chunk id",
1342 "Accounts.FileWithCCNNode.unallocatedSpaceFile.displayName={0}_chunk_{1}"})
1344 super(Children.LEAF, Lookups.fixed(lookupContents));
1348 : Bundle.Accounts_FileWithCCNNode_unallocatedSpaceFile_displayName(content.getName(), StringUtils.substringAfter(key.
getkeywordSearchDocID(),
"_"));
1349 setName(fileName + key.
getObjID());
1350 setDisplayName(fileName);
1360 return visitor.
visit(
this);
1365 return getClass().getName();
1369 @NbBundle.Messages({
1370 "Accounts.FileWithCCNNode.nameProperty.displayName=File",
1371 "Accounts.FileWithCCNNode.accountsProperty.displayName=Accounts",
1372 "Accounts.FileWithCCNNode.statusProperty.displayName=Status",
1373 "Accounts.FileWithCCNNode.noDescription=no description"})
1375 Sheet sheet = super.createSheet();
1376 Sheet.Set propSet = sheet.get(Sheet.PROPERTIES);
1377 if (propSet == null) {
1378 propSet = Sheet.createPropertiesSet();
1382 propSet.put(
new NodeProperty<>(Bundle.Accounts_FileWithCCNNode_nameProperty_displayName(),
1383 Bundle.Accounts_FileWithCCNNode_nameProperty_displayName(),
1384 Bundle.Accounts_FileWithCCNNode_noDescription(),
1386 propSet.put(
new NodeProperty<>(Bundle.Accounts_FileWithCCNNode_accountsProperty_displayName(),
1387 Bundle.Accounts_FileWithCCNNode_accountsProperty_displayName(),
1388 Bundle.Accounts_FileWithCCNNode_noDescription(),
1390 propSet.put(
new NodeProperty<>(Bundle.Accounts_FileWithCCNNode_statusProperty_displayName(),
1391 Bundle.Accounts_FileWithCCNNode_statusProperty_displayName(),
1392 Bundle.Accounts_FileWithCCNNode_noDescription(),
1394 .map(BlackboardArtifact.ReviewStatus::getDisplayName)
1395 .collect(Collectors.joining(
", "))));
1402 Action[] actions = super.getActions(context);
1403 ArrayList<Action> arrayList =
new ArrayList<>();
1404 arrayList.addAll(Arrays.asList(actions));
1407 }
catch (TskCoreException ex) {
1408 LOGGER.log(Level.SEVERE,
"Error gettung content by id", ex);
1411 arrayList.add(approveActionInstance);
1412 arrayList.add(rejectActionInstance);
1414 return arrayList.toArray(
new Action[arrayList.size()]);
1442 =
"SELECT blackboard_artifacts.artifact_id "
1443 +
" FROM blackboard_artifacts "
1444 +
" JOIN blackboard_attributes ON blackboard_artifacts.artifact_id = blackboard_attributes.artifact_id "
1445 +
" WHERE blackboard_artifacts.artifact_type_id = " + BlackboardArtifact.ARTIFACT_TYPE.TSK_ACCOUNT.getTypeID()
1446 +
" AND blackboard_attributes.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_CARD_NUMBER.getTypeID()
1447 +
" AND blackboard_attributes.value_text >= '" + bin.getBINStart() +
"' AND blackboard_attributes.value_text < '" + (bin.getBINEnd() + 1) +
"'"
1450 +
" ORDER BY blackboard_attributes.value_text";
1451 try (SleuthkitCase.CaseDbQuery results = skCase.executeQuery(query);
1452 ResultSet rs = results.getResultSet();) {
1454 list.add(rs.getLong(
"artifact_id"));
1456 }
catch (TskCoreException | SQLException ex) {
1457 LOGGER.log(Level.SEVERE,
"Error querying for account artifacts.", ex);
1465 if (skCase == null) {
1470 BlackboardArtifact art = skCase.getBlackboardArtifact(artifactID);
1472 }
catch (TskCoreException ex) {
1473 LOGGER.log(Level.SEVERE,
"Error creating BlackboardArtifactNode for artifact with ID " + artifactID, ex);
1480 if (bin.getBINStart() == bin.getBINEnd()) {
1481 return Integer.toString(bin.getBINStart());
1483 return bin.getBINStart() +
"-" + StringUtils.difference(bin.getBINStart() +
"", bin.getBINEnd() +
"");
1498 updateDisplayName();
1499 this.setIconBaseWithExtension(
"org/sleuthkit/autopsy/images/bank.png");
1500 reviewStatusBus.register(
this);
1505 updateDisplayName();
1511 updateDisplayName();
1516 =
"SELECT count(blackboard_artifacts.artifact_id ) AS count"
1517 +
" FROM blackboard_artifacts "
1518 +
" JOIN blackboard_attributes ON blackboard_artifacts.artifact_id = blackboard_attributes.artifact_id "
1519 +
" WHERE blackboard_artifacts.artifact_type_id = " + BlackboardArtifact.ARTIFACT_TYPE.TSK_ACCOUNT.getTypeID()
1520 +
" AND blackboard_attributes.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_CARD_NUMBER.getTypeID()
1521 +
" AND blackboard_attributes.value_text >= '" + bin.getBINStart() +
"' AND blackboard_attributes.value_text < '" + (bin.getBINEnd() + 1) +
"'"
1524 try (SleuthkitCase.CaseDbQuery results = skCase.executeQuery(query);
1525 ResultSet resultSet = results.getResultSet();) {
1526 while (resultSet.next()) {
1527 setDisplayName(
getBinRangeString(bin) +
" (" + resultSet.getLong(
"count") +
")");
1529 }
catch (TskCoreException | SQLException ex) {
1530 LOGGER.log(Level.SEVERE,
"Error querying for account artifacts.", ex);
1543 return visitor.
visit(
this);
1548 return getClass().getName();
1552 Sheet.Set sheetSet = sheet.get(Sheet.PROPERTIES);
1553 if (sheetSet == null) {
1554 sheetSet = Sheet.createPropertiesSet();
1555 sheet.put(sheetSet);
1561 @NbBundle.Messages({
1562 "Accounts.BINNode.binProperty.displayName=Bank Identifier Number",
1563 "Accounts.BINNode.accountsProperty.displayName=Accounts",
1564 "Accounts.BINNode.cardTypeProperty.displayName=Payment Card Type",
1565 "Accounts.BINNode.schemeProperty.displayName=Credit Card Scheme",
1566 "Accounts.BINNode.brandProperty.displayName=Brand",
1567 "Accounts.BINNode.bankProperty.displayName=Bank",
1568 "Accounts.BINNode.bankCityProperty.displayName=Bank City",
1569 "Accounts.BINNode.bankCountryProperty.displayName=Bank Country",
1570 "Accounts.BINNode.bankPhoneProperty.displayName=Bank Phone #",
1571 "Accounts.BINNode.bankURLProperty.displayName=Bank URL",
1572 "Accounts.BINNode.noDescription=no description"})
1574 Sheet sheet = super.createSheet();
1575 Sheet.Set properties = getPropertySet(sheet);
1577 properties.put(
new NodeProperty<>(Bundle.Accounts_BINNode_binProperty_displayName(),
1578 Bundle.Accounts_BINNode_binProperty_displayName(),
1579 Bundle.Accounts_BINNode_noDescription(),
1581 properties.put(
new NodeProperty<>(Bundle.Accounts_BINNode_accountsProperty_displayName(),
1582 Bundle.Accounts_BINNode_accountsProperty_displayName(), Bundle.Accounts_BINNode_noDescription(),
1586 if (bin.hasDetails()) {
1587 bin.
getCardType().ifPresent(cardType -> properties.put(
new NodeProperty<>(Bundle.Accounts_BINNode_cardTypeProperty_displayName(),
1588 Bundle.Accounts_BINNode_cardTypeProperty_displayName(), Bundle.Accounts_BINNode_noDescription(),
1590 bin.
getScheme().ifPresent(scheme -> properties.put(
new NodeProperty<>(Bundle.Accounts_BINNode_schemeProperty_displayName(),
1591 Bundle.Accounts_BINNode_schemeProperty_displayName(), Bundle.Accounts_BINNode_noDescription(),
1593 bin.
getBrand().ifPresent(brand -> properties.put(
new NodeProperty<>(Bundle.Accounts_BINNode_brandProperty_displayName(),
1594 Bundle.Accounts_BINNode_brandProperty_displayName(), Bundle.Accounts_BINNode_noDescription(),
1596 bin.
getBankName().ifPresent(bankName -> properties.put(
new NodeProperty<>(Bundle.Accounts_BINNode_bankProperty_displayName(),
1597 Bundle.Accounts_BINNode_bankProperty_displayName(), Bundle.Accounts_BINNode_noDescription(),
1599 bin.
getBankCity().ifPresent(bankCity -> properties.put(
new NodeProperty<>(Bundle.Accounts_BINNode_bankCityProperty_displayName(),
1600 Bundle.Accounts_BINNode_bankCityProperty_displayName(), Bundle.Accounts_BINNode_noDescription(),
1602 bin.
getCountry().ifPresent(country -> properties.put(
new NodeProperty<>(Bundle.Accounts_BINNode_bankCountryProperty_displayName(),
1603 Bundle.Accounts_BINNode_bankCountryProperty_displayName(), Bundle.Accounts_BINNode_noDescription(),
1606 Bundle.Accounts_BINNode_bankPhoneProperty_displayName(), Bundle.Accounts_BINNode_noDescription(),
1608 bin.
getBankURL().ifPresent(url -> properties.put(
new NodeProperty<>(Bundle.Accounts_BINNode_bankURLProperty_displayName(),
1609 Bundle.Accounts_BINNode_bankURLProperty_displayName(), Bundle.Accounts_BINNode_noDescription(),
1616 this.setSheet(createSheet());
1631 hash = 97 * hash + this.binEnd;
1632 hash = 97 * hash + this.binStart;
1644 if (getClass() != obj.getClass()) {
1648 if (this.binEnd != other.
binEnd) {
1651 if (this.binStart != other.
binStart) {
1668 this.binRange = binRange;
1669 binStart = binRange.getBINstart();
1670 binEnd = binRange.getBINend();
1675 this.binRange = null;
1692 boolean hasDetails() {
1693 return binRange != null;
1747 super(artifact,
"org/sleuthkit/autopsy/images/credit-card.png");
1748 this.artifact = artifact;
1749 setName(Long.toString(
this.artifact.getArtifactID()));
1751 reviewStatusBus.register(
this);
1756 List<Action> actionsList =
new ArrayList<>();
1757 actionsList.addAll(Arrays.asList(super.getActions(context)));
1759 actionsList.add(approveActionInstance);
1760 actionsList.add(rejectActionInstance);
1762 return actionsList.toArray(
new Action[actionsList.size()]);
1767 Sheet sheet = super.createSheet();
1768 Sheet.Set properties = sheet.get(Sheet.PROPERTIES);
1769 if (properties == null) {
1770 properties = Sheet.createPropertiesSet();
1771 sheet.put(properties);
1773 properties.put(
new NodeProperty<>(Bundle.Accounts_FileWithCCNNode_statusProperty_displayName(),
1774 Bundle.Accounts_FileWithCCNNode_statusProperty_displayName(),
1775 Bundle.Accounts_FileWithCCNNode_noDescription(),
1776 artifact.getReviewStatus().getDisplayName()));
1785 event.artifacts.stream().filter((art) -> (art.getArtifactID() == this.artifact.getArtifactID())).map((_item) -> {
1787 }).forEachOrdered((_item) -> {
1793 this.setSheet(createSheet());
1801 @NbBundle.Messages(
"ToggleShowRejected.name=Show Rejected Results")
1803 super(Bundle.ToggleShowRejected_name());
1829 this.newStatus = newStatus;
1840 List<String[]> selectedPaths = Utilities.actionsGlobalContext().lookupAll(Node.class).stream()
1842 String[] createPath;
1848 if (newStatus == BlackboardArtifact.ReviewStatus.REJECTED && showRejected ==
false) {
1849 List<Node> siblings = Arrays.asList(node.getParentNode().getChildren().getNodes());
1850 if (siblings.size() > 1) {
1851 int indexOf = siblings.indexOf(node);
1853 Node sibling = indexOf > 0
1854 ? siblings.get(indexOf - 1)
1855 : siblings.get(Integer.max(indexOf + 1, siblings.size() - 1));
1856 createPath = NodeOp.createPath(sibling, null);
1866 createPath = NodeOp.createPath(node, null);
1869 return Arrays.copyOfRange(createPath, 1, createPath.length);
1871 .filter(Objects::nonNull)
1872 .collect(Collectors.toList());
1875 final Collection<? extends BlackboardArtifact> artifacts = Utilities.actionsGlobalContext().lookupAll(BlackboardArtifact.class);
1876 artifacts.forEach(artifact -> {
1878 artifact.setReviewStatus(newStatus);
1879 }
catch (TskCoreException ex) {
1880 LOGGER.log(Level.SEVERE,
"Error changing artifact review status.", ex);
1884 reviewStatusBus.post(
new ReviewStatusChangeEvent(artifacts, newStatus));
1886 final DataResultTopComponent directoryListing = DirectoryTreeTopComponent.findInstance().getDirectoryListing();
1887 final Node rootNode = directoryListing.getRootNode();
1890 List<Node> toArray =
new ArrayList<>();
1891 selectedPaths.forEach(path -> {
1893 toArray.add(NodeOp.findPath(rootNode, path));
1894 }
catch (NodeNotFoundException ex) {
1899 directoryListing.setSelectedNodes(toArray.toArray(
new Node[toArray.size()]));
1905 @NbBundle.Messages({
"ApproveAccountsAction.name=Approve Accounts"})
1907 super(Bundle.ApproveAccountsAction_name(), BlackboardArtifact.ReviewStatus.APPROVED);
1913 @NbBundle.Messages({
"RejectAccountsAction.name=Reject Accounts"})
1915 super(Bundle.RejectAccountsAction_name(), BlackboardArtifact.ReviewStatus.REJECTED);
1921 Collection<? extends BlackboardArtifact> artifacts;
1922 BlackboardArtifact.ReviewStatus newReviewStatus;
1924 ReviewStatusChangeEvent(Collection<? extends BlackboardArtifact> artifacts, BlackboardArtifact.ReviewStatus newReviewStatus) {
1925 this.artifacts = artifacts;
1926 this.newReviewStatus = newReviewStatus;
1937 if (type.equals(Account.Type.CREDIT_CARD)) {
1938 return ICON_BASE_PATH +
"credit-card.png";
1939 }
else if (type.equals(Account.Type.DEVICE)) {
1940 return ICON_BASE_PATH +
"image.png";
1941 }
else if (type.equals(Account.Type.EMAIL)) {
1942 return ICON_BASE_PATH +
"email.png";
1943 }
else if (type.equals(Account.Type.FACEBOOK)) {
1944 return ICON_BASE_PATH +
"facebook.png";
1945 }
else if (type.equals(Account.Type.INSTAGRAM)) {
1946 return ICON_BASE_PATH +
"instagram.png";
1947 }
else if (type.equals(Account.Type.MESSAGING_APP)) {
1948 return ICON_BASE_PATH +
"messaging.png";
1949 }
else if (type.equals(Account.Type.PHONE)) {
1950 return ICON_BASE_PATH +
"phone.png";
1951 }
else if (type.equals(Account.Type.TWITTER)) {
1952 return ICON_BASE_PATH +
"twitter.png";
1953 }
else if (type.equals(Account.Type.WEBSITE)) {
1954 return ICON_BASE_PATH +
"web-file.png";
1955 }
else if (type.equals(Account.Type.WHATSAPP)) {
1956 return ICON_BASE_PATH +
"WhatsApp.png";
1959 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)