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.HashSet;
37 import java.util.List;
38 import java.util.Objects;
39 import java.util.Optional;
41 import java.util.function.Function;
42 import java.util.logging.Level;
43 import java.util.stream.Collectors;
44 import java.util.stream.Stream;
45 import javax.annotation.Nonnull;
46 import javax.annotation.concurrent.Immutable;
47 import javax.swing.AbstractAction;
48 import javax.swing.Action;
49 import org.apache.commons.lang3.StringUtils;
50 import org.openide.nodes.ChildFactory;
51 import org.openide.nodes.Children;
52 import org.openide.nodes.Node;
53 import org.openide.nodes.NodeNotFoundException;
54 import org.openide.nodes.NodeOp;
55 import org.openide.nodes.Sheet;
56 import org.openide.util.NbBundle;
57 import org.openide.util.Utilities;
58 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/";
95 @NbBundle.Messages(
"AccountsRootNode.name=Accounts")
96 final public static String
NAME = Bundle.AccountsRootNode_name();
124 public Accounts(SleuthkitCase skCase,
long objId) {
126 this.datasourceObjId = objId;
135 return visitor.
visit(
this);
146 return showRejected ?
" " :
" AND blackboard_artifacts.review_status_id != " + BlackboardArtifact.ReviewStatus.REJECTED.getID() +
" ";
157 return " AND blackboard_artifacts.data_source_obj_id = " + datasourceObjId +
" ";
195 abstract protected boolean createKeys(List<X> list);
210 super.removeNotify();
225 @NbBundle.Messages({
"Accounts.RootNode.displayName=Accounts"})
231 setDisplayName(Bundle.Accounts_RootNode_displayName());
232 this.setIconBaseWithExtension(
"org/sleuthkit/autopsy/images/accounts.png");
242 return visitor.
visit(
this);
247 return getClass().getName();
260 private final PropertyChangeListener
pcl =
new PropertyChangeListener() {
262 public void propertyChange(PropertyChangeEvent evt) {
263 String eventType = evt.getPropertyName();
280 if (null != eventData
282 reviewStatusBus.post(eventData);
303 if (evt.getNewValue() == null) {
325 String accountTypesInUseQuery =
326 "SELECT DISTINCT blackboard_attributes.value_text as account_type "
327 +
" FROM blackboard_artifacts "
328 +
" JOIN blackboard_attributes ON blackboard_artifacts.artifact_id = blackboard_attributes.artifact_id "
329 +
" WHERE blackboard_attributes.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ACCOUNT_TYPE.getTypeID()
332 try (SleuthkitCase.CaseDbQuery executeQuery = skCase.executeQuery(accountTypesInUseQuery );
333 ResultSet resultSet = executeQuery.getResultSet()) {
334 while (resultSet.next()) {
335 String accountType = resultSet.getString(
"account_type");
336 list.add(accountType);
338 }
catch (TskCoreException | SQLException ex) {
339 LOGGER.log(Level.SEVERE,
"Error querying for account_types", ex);
348 if (Account.Type.CREDIT_CARD.getTypeName().equals(acountTypeName)) {
353 Account.Type accountType = skCase.getCommunicationsManager().getAccountType(acountTypeName);
355 }
catch (TskCoreException ex) {
356 LOGGER.log(Level.SEVERE,
"Error getting display name for account type. ", ex);
368 super.removeNotify();
390 private final PropertyChangeListener
pcl =
new PropertyChangeListener() {
392 public void propertyChange(PropertyChangeEvent evt) {
393 String eventType = evt.getPropertyName();
410 if (null != eventData
412 reviewStatusBus.post(eventData);
434 if (evt.getNewValue() == null) {
455 super.removeNotify();
461 "SELECT blackboard_artifacts.artifact_id "
462 +
" FROM blackboard_artifacts "
463 +
" JOIN blackboard_attributes ON blackboard_artifacts.artifact_id = blackboard_attributes.artifact_id "
464 +
" WHERE blackboard_artifacts.artifact_type_id = " + BlackboardArtifact.ARTIFACT_TYPE.TSK_ACCOUNT.getTypeID()
465 +
" AND blackboard_attributes.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ACCOUNT_TYPE.getTypeID()
466 +
" AND blackboard_attributes.value_text = '" +
accountType.getTypeName() +
"'"
469 try (SleuthkitCase.CaseDbQuery results = skCase.executeQuery(query);
470 ResultSet rs = results.getResultSet();) {
472 list.add(rs.getLong(
"artifact_id"));
474 }
catch (TskCoreException | SQLException ex) {
475 LOGGER.log(Level.SEVERE,
"Error querying for account artifacts.", ex);
485 }
catch (TskCoreException ex) {
486 LOGGER.log(Level.SEVERE,
"Error get black board artifact with id " + t, ex);
523 return visitor.
visit(
this);
528 return getClass().getName();
542 private final PropertyChangeListener pcl =
new PropertyChangeListener() {
544 public void propertyChange(PropertyChangeEvent evt) {
545 String eventType = evt.getPropertyName();
562 if (null != eventData
564 reviewStatusBus.post(eventData);
586 if (evt.getNewValue() == null) {
619 super.removeNotify();
626 protected boolean createKeys(List<CreditCardViewMode> list) {
655 super(Children.create(
new ViewModeFactory(),
true), Lookups.singleton(Account.Type.CREDIT_CARD.getDisplayName()));
656 setName(Account.Type.CREDIT_CARD.getDisplayName());
657 this.setIconBaseWithExtension(
"org/sleuthkit/autopsy/images/credit-cards.png");
667 return visitor.
visit(
this);
672 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
700 reviewStatusBus.post(eventData);
722 if (evt.getNewValue() == null) {
743 super.removeNotify();
761 "SELECT blackboard_artifacts.obj_id,"
762 +
" solr_attribute.value_text AS solr_document_id, ";
763 if (skCase.getDatabaseType().equals(DbType.POSTGRESQL)) {
764 query +=
" string_agg(blackboard_artifacts.artifact_id::character varying, ',') AS artifact_IDs, "
765 +
" string_agg(blackboard_artifacts.review_status_id::character varying, ',') AS review_status_ids, ";
767 query +=
" GROUP_CONCAT(blackboard_artifacts.artifact_id) AS artifact_IDs, "
768 +
" GROUP_CONCAT(blackboard_artifacts.review_status_id) AS review_status_ids, ";
770 query +=
" COUNT( blackboard_artifacts.artifact_id) AS hits "
771 +
" FROM blackboard_artifacts "
772 +
" LEFT JOIN blackboard_attributes as solr_attribute ON blackboard_artifacts.artifact_id = solr_attribute.artifact_id "
773 +
" AND solr_attribute.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD_SEARCH_DOCUMENT_ID.getTypeID()
774 +
" LEFT JOIN blackboard_attributes as account_type ON blackboard_artifacts.artifact_id = account_type.artifact_id "
775 +
" AND account_type.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ACCOUNT_TYPE.getTypeID()
776 +
" AND account_type.value_text = '" + Account.Type.CREDIT_CARD.getTypeName() +
"'"
777 +
" WHERE blackboard_artifacts.artifact_type_id = " + BlackboardArtifact.ARTIFACT_TYPE.TSK_ACCOUNT.getTypeID()
780 +
" GROUP BY blackboard_artifacts.obj_id, solr_document_id "
781 +
" ORDER BY hits DESC ";
782 try (SleuthkitCase.CaseDbQuery results = skCase.executeQuery(query);
783 ResultSet resultSet = results.getResultSet();) {
784 while (resultSet.next()) {
786 resultSet.getLong(
"obj_id"),
787 resultSet.getString(
"solr_document_id"),
788 unGroupConcat(resultSet.getString(
"artifact_IDs"), Long::valueOf),
789 resultSet.getLong(
"hits"),
790 new HashSet<>(unGroupConcat(resultSet.getString(
"review_status_ids"), reviewStatusID -> BlackboardArtifact.ReviewStatus.withID(Integer.valueOf(reviewStatusID))))));
792 }
catch (TskCoreException | SQLException ex) {
793 LOGGER.log(Level.SEVERE,
"Error querying for files with ccn hits.", ex);
803 List<Object> lookupContents =
new ArrayList<>();
805 lookupContents.add(skCase.getBlackboardArtifact(artId));
807 AbstractFile abstractFileById = skCase.getAbstractFileById(key.
getObjID());
808 lookupContents.add(abstractFileById);
809 return new Node[]{
new FileWithCCNNode(key, abstractFileById, lookupContents.toArray())};
810 }
catch (TskCoreException ex) {
811 LOGGER.log(Level.SEVERE,
"Error getting content for file with ccn hits.", ex);
830 this.setIconBaseWithExtension(
"org/sleuthkit/autopsy/images/file-icon.png");
831 reviewStatusBus.register(
this);
835 "# {0} - number of children",
836 "Accounts.ByFileNode.displayName=By File ({0})"})
839 "SELECT count(*) FROM ( SELECT count(*) AS documents "
840 +
" FROM blackboard_artifacts "
841 +
" LEFT JOIN blackboard_attributes as solr_attribute ON blackboard_artifacts.artifact_id = solr_attribute.artifact_id "
842 +
" AND solr_attribute.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD_SEARCH_DOCUMENT_ID.getTypeID()
843 +
" LEFT JOIN blackboard_attributes as account_type ON blackboard_artifacts.artifact_id = account_type.artifact_id "
844 +
" AND account_type.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ACCOUNT_TYPE.getTypeID()
845 +
" AND account_type.value_text = '" + Account.Type.CREDIT_CARD.getTypeName() +
"'"
846 +
" WHERE blackboard_artifacts.artifact_type_id = " + BlackboardArtifact.ARTIFACT_TYPE.TSK_ACCOUNT.getTypeID()
849 +
" GROUP BY blackboard_artifacts.obj_id, solr_attribute.value_text ) AS foo";
850 try (SleuthkitCase.CaseDbQuery results = skCase.executeQuery(query);
851 ResultSet resultSet = results.getResultSet();) {
852 while (resultSet.next()) {
853 if (skCase.getDatabaseType().equals(DbType.POSTGRESQL)) {
854 setDisplayName(Bundle.Accounts_ByFileNode_displayName(resultSet.getLong(
"count")));
856 setDisplayName(Bundle.Accounts_ByFileNode_displayName(resultSet.getLong(
"count(*)")));
859 }
catch (TskCoreException | SQLException ex) {
860 LOGGER.log(Level.SEVERE,
"Error querying for files with ccn hits.", ex);
872 return visitor.
visit(
this);
877 return getClass().getName();
893 private final PropertyChangeListener pcl =
new PropertyChangeListener() {
895 public void propertyChange(PropertyChangeEvent evt) {
896 String eventType = evt.getPropertyName();
913 if (null != eventData
915 reviewStatusBus.post(eventData);
936 && (evt.getNewValue() == null)) {
957 super.removeNotify();
975 RangeMap<Integer, BinResult> binRanges = TreeRangeMap.create();
978 "SELECT SUBSTR(blackboard_attributes.value_text,1,8) AS BIN, "
979 +
" COUNT(blackboard_artifacts.artifact_id) AS count "
980 +
" FROM blackboard_artifacts "
981 +
" JOIN blackboard_attributes ON blackboard_artifacts.artifact_id = blackboard_attributes.artifact_id"
982 +
" WHERE blackboard_artifacts.artifact_type_id = " + BlackboardArtifact.ARTIFACT_TYPE.TSK_ACCOUNT.getTypeID()
983 +
" AND blackboard_attributes.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_CARD_NUMBER.getTypeID()
988 try (SleuthkitCase.CaseDbQuery results = skCase.executeQuery(query);
989 ResultSet resultSet = results.getResultSet();) {
991 while (resultSet.next()) {
992 final Integer bin = Integer.valueOf(resultSet.getString(
"BIN"));
993 long count = resultSet.getLong(
"count");
996 BinResult previousResult = binRanges.get(bin);
998 if (previousResult != null) {
999 binRanges.remove(Range.closed(previousResult.getBINStart(), previousResult.getBINEnd()));
1000 count += previousResult.getCount();
1003 if (binRange == null) {
1004 binRanges.put(Range.closed(bin, bin),
new BinResult(count, bin, bin));
1009 binRanges.asMapOfRanges().values().forEach(list::add);
1010 }
catch (TskCoreException | SQLException ex) {
1011 LOGGER.log(Level.SEVERE,
"Error querying for BINs.", ex);
1019 return new Node[]{
new BINNode(key)};
1032 @NbBundle.Messages(
"Accounts.ByBINNode.name=By BIN")
1034 super(Children.create(
new BINFactory(),
true), Lookups.singleton(Bundle.Accounts_ByBINNode_name()));
1035 setName(Bundle.Accounts_ByBINNode_name());
1036 updateDisplayName();
1037 this.setIconBaseWithExtension(
"org/sleuthkit/autopsy/images/bank.png");
1038 reviewStatusBus.register(
this);
1041 @NbBundle.Messages({
1042 "# {0} - number of children",
1043 "Accounts.ByBINNode.displayName=By BIN ({0})"})
1046 "SELECT count(distinct SUBSTR(blackboard_attributes.value_text,1,8)) AS BINs "
1047 +
" FROM blackboard_artifacts "
1048 +
" JOIN blackboard_attributes ON blackboard_artifacts.artifact_id = blackboard_attributes.artifact_id"
1049 +
" WHERE blackboard_artifacts.artifact_type_id = " + BlackboardArtifact.ARTIFACT_TYPE.TSK_ACCOUNT.getTypeID()
1050 +
" AND blackboard_attributes.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_CARD_NUMBER.getTypeID()
1053 try (SleuthkitCase.CaseDbQuery results = skCase.executeQuery(query);
1054 ResultSet resultSet = results.getResultSet();) {
1055 while (resultSet.next()) {
1056 setDisplayName(Bundle.Accounts_ByBINNode_displayName(resultSet.getLong(
"BINs")));
1058 }
catch (TskCoreException | SQLException ex) {
1059 LOGGER.log(Level.SEVERE,
"Error querying for BINs.", ex);
1070 return visitor.
visit(
this);
1075 return getClass().getName();
1080 updateDisplayName();
1085 updateDisplayName();
1099 hash = 79 * hash + (int) (this.objID ^ (this.objID >>> 32));
1100 hash = 79 * hash + Objects.hashCode(this.keywordSearchDocID);
1101 hash = 79 * hash + Objects.hashCode(this.artifactIDs);
1102 hash = 79 * hash + (int) (this.hits ^ (this.hits >>> 32));
1103 hash = 79 * hash + Objects.hashCode(this.statuses);
1115 if (getClass() != obj.getClass()) {
1119 if (this.objID != other.
objID) {
1122 if (this.hits != other.
hits) {
1128 if (!Objects.equals(
this.artifactIDs, other.
artifactIDs)) {
1131 if (!Objects.equals(
this.statuses, other.
statuses)) {
1141 private final Set<BlackboardArtifact.ReviewStatus>
statuses;
1143 private FileWithCCN(
long objID, String solrDocID, List<Long> artifactIDs,
long hits, Set<BlackboardArtifact.ReviewStatus> statuses) {
1145 this.keywordSearchDocID = solrDocID;
1146 this.artifactIDs = artifactIDs;
1148 this.statuses = statuses;
1167 return keywordSearchDocID;
1214 static <X> List<X> unGroupConcat(String groupConcat, Function<String, X> mapper) {
1215 return StringUtils.isBlank(groupConcat) ? Collections.emptyList()
1216 : Stream.of(groupConcat.split(
","))
1218 .collect(Collectors.toList());
1238 @NbBundle.Messages({
1239 "# {0} - raw file name",
1240 "# {1} - solr chunk id",
1241 "Accounts.FileWithCCNNode.unallocatedSpaceFile.displayName={0}_chunk_{1}"})
1243 super(Children.LEAF, Lookups.fixed(lookupContents));
1247 : Bundle.Accounts_FileWithCCNNode_unallocatedSpaceFile_displayName(content.getName(), StringUtils.substringAfter(key.
getkeywordSearchDocID(),
"_"));
1248 setName(fileName + key.
getObjID());
1249 setDisplayName(fileName);
1259 return visitor.
visit(
this);
1264 return getClass().getName();
1268 @NbBundle.Messages({
1269 "Accounts.FileWithCCNNode.nameProperty.displayName=File",
1270 "Accounts.FileWithCCNNode.accountsProperty.displayName=Accounts",
1271 "Accounts.FileWithCCNNode.statusProperty.displayName=Status",
1272 "Accounts.FileWithCCNNode.noDescription=no description"})
1274 Sheet sheet = super.createSheet();
1275 Sheet.Set propSet = sheet.get(Sheet.PROPERTIES);
1276 if (propSet == null) {
1277 propSet = Sheet.createPropertiesSet();
1281 propSet.put(
new NodeProperty<>(Bundle.Accounts_FileWithCCNNode_nameProperty_displayName(),
1282 Bundle.Accounts_FileWithCCNNode_nameProperty_displayName(),
1283 Bundle.Accounts_FileWithCCNNode_noDescription(),
1285 propSet.put(
new NodeProperty<>(Bundle.Accounts_FileWithCCNNode_accountsProperty_displayName(),
1286 Bundle.Accounts_FileWithCCNNode_accountsProperty_displayName(),
1287 Bundle.Accounts_FileWithCCNNode_noDescription(),
1289 propSet.put(
new NodeProperty<>(Bundle.Accounts_FileWithCCNNode_statusProperty_displayName(),
1290 Bundle.Accounts_FileWithCCNNode_statusProperty_displayName(),
1291 Bundle.Accounts_FileWithCCNNode_noDescription(),
1293 .map(BlackboardArtifact.ReviewStatus::getDisplayName)
1294 .collect(Collectors.joining(
", "))));
1301 Action[] actions = super.getActions(context);
1302 ArrayList<Action> arrayList =
new ArrayList<>();
1303 arrayList.addAll(Arrays.asList(actions));
1306 }
catch (TskCoreException ex) {
1307 LOGGER.log(Level.SEVERE,
"Error gettung content by id", ex);
1310 arrayList.add(approveActionInstance);
1311 arrayList.add(rejectActionInstance);
1313 return arrayList.toArray(
new Action[arrayList.size()]);
1341 "SELECT blackboard_artifacts.artifact_id "
1342 +
" FROM blackboard_artifacts "
1343 +
" JOIN blackboard_attributes ON blackboard_artifacts.artifact_id = blackboard_attributes.artifact_id "
1344 +
" WHERE blackboard_artifacts.artifact_type_id = " + BlackboardArtifact.ARTIFACT_TYPE.TSK_ACCOUNT.getTypeID()
1345 +
" AND blackboard_attributes.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_CARD_NUMBER.getTypeID()
1346 +
" AND blackboard_attributes.value_text >= '" + bin.getBINStart() +
"' AND blackboard_attributes.value_text < '" + (bin.getBINEnd() + 1) +
"'"
1349 +
" ORDER BY blackboard_attributes.value_text";
1350 try (SleuthkitCase.CaseDbQuery results = skCase.executeQuery(query);
1351 ResultSet rs = results.getResultSet();) {
1353 list.add(rs.getLong(
"artifact_id"));
1355 }
catch (TskCoreException | SQLException ex) {
1356 LOGGER.log(Level.SEVERE,
"Error querying for account artifacts.", ex);
1364 if (skCase == null) {
1369 BlackboardArtifact art = skCase.getBlackboardArtifact(artifactID);
1371 }
catch (TskCoreException ex) {
1372 LOGGER.log(Level.SEVERE,
"Error creating BlackboardArtifactNode for artifact with ID " + artifactID, ex);
1379 if (bin.getBINStart() == bin.getBINEnd()) {
1380 return Integer.toString(bin.getBINStart());
1382 return bin.getBINStart() +
"-" + StringUtils.difference(bin.getBINStart() +
"", bin.getBINEnd() +
"");
1395 updateDisplayName();
1396 this.setIconBaseWithExtension(
"org/sleuthkit/autopsy/images/bank.png");
1397 reviewStatusBus.register(
this);
1402 updateDisplayName();
1408 updateDisplayName();
1413 "SELECT count(blackboard_artifacts.artifact_id ) AS count"
1414 +
" FROM blackboard_artifacts "
1415 +
" JOIN blackboard_attributes ON blackboard_artifacts.artifact_id = blackboard_attributes.artifact_id "
1416 +
" WHERE blackboard_artifacts.artifact_type_id = " + BlackboardArtifact.ARTIFACT_TYPE.TSK_ACCOUNT.getTypeID()
1417 +
" AND blackboard_attributes.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_CARD_NUMBER.getTypeID()
1418 +
" AND blackboard_attributes.value_text >= '" + bin.getBINStart() +
"' AND blackboard_attributes.value_text < '" + (bin.getBINEnd() + 1) +
"'"
1421 try (SleuthkitCase.CaseDbQuery results = skCase.executeQuery(query);
1422 ResultSet resultSet = results.getResultSet();) {
1423 while (resultSet.next()) {
1424 setDisplayName(
getBinRangeString(bin) +
" (" + resultSet.getLong(
"count") +
")");
1426 }
catch (TskCoreException | SQLException ex) {
1427 LOGGER.log(Level.SEVERE,
"Error querying for account artifacts.", ex);
1440 return visitor.
visit(
this);
1445 return getClass().getName();
1449 Sheet.Set sheetSet = sheet.get(Sheet.PROPERTIES);
1450 if (sheetSet == null) {
1451 sheetSet = Sheet.createPropertiesSet();
1452 sheet.put(sheetSet);
1458 @NbBundle.Messages({
1459 "Accounts.BINNode.binProperty.displayName=Bank Identifier Number",
1460 "Accounts.BINNode.accountsProperty.displayName=Accounts",
1461 "Accounts.BINNode.cardTypeProperty.displayName=Payment Card Type",
1462 "Accounts.BINNode.schemeProperty.displayName=Credit Card Scheme",
1463 "Accounts.BINNode.brandProperty.displayName=Brand",
1464 "Accounts.BINNode.bankProperty.displayName=Bank",
1465 "Accounts.BINNode.bankCityProperty.displayName=Bank City",
1466 "Accounts.BINNode.bankCountryProperty.displayName=Bank Country",
1467 "Accounts.BINNode.bankPhoneProperty.displayName=Bank Phone #",
1468 "Accounts.BINNode.bankURLProperty.displayName=Bank URL",
1469 "Accounts.BINNode.noDescription=no description"})
1471 Sheet sheet = super.createSheet();
1472 Sheet.Set properties = getPropertySet(sheet);
1474 properties.put(
new NodeProperty<>(Bundle.Accounts_BINNode_binProperty_displayName(),
1475 Bundle.Accounts_BINNode_binProperty_displayName(),
1476 Bundle.Accounts_BINNode_noDescription(),
1478 properties.put(
new NodeProperty<>(Bundle.Accounts_BINNode_accountsProperty_displayName(),
1479 Bundle.Accounts_BINNode_accountsProperty_displayName(), Bundle.Accounts_BINNode_noDescription(),
1483 if (bin.hasDetails()) {
1484 bin.
getCardType().ifPresent(cardType -> properties.put(
new NodeProperty<>(Bundle.Accounts_BINNode_cardTypeProperty_displayName(),
1485 Bundle.Accounts_BINNode_cardTypeProperty_displayName(), Bundle.Accounts_BINNode_noDescription(),
1487 bin.
getScheme().ifPresent(scheme -> properties.put(
new NodeProperty<>(Bundle.Accounts_BINNode_schemeProperty_displayName(),
1488 Bundle.Accounts_BINNode_schemeProperty_displayName(), Bundle.Accounts_BINNode_noDescription(),
1490 bin.
getBrand().ifPresent(brand -> properties.put(
new NodeProperty<>(Bundle.Accounts_BINNode_brandProperty_displayName(),
1491 Bundle.Accounts_BINNode_brandProperty_displayName(), Bundle.Accounts_BINNode_noDescription(),
1493 bin.
getBankName().ifPresent(bankName -> properties.put(
new NodeProperty<>(Bundle.Accounts_BINNode_bankProperty_displayName(),
1494 Bundle.Accounts_BINNode_bankProperty_displayName(), Bundle.Accounts_BINNode_noDescription(),
1496 bin.
getBankCity().ifPresent(bankCity -> properties.put(
new NodeProperty<>(Bundle.Accounts_BINNode_bankCityProperty_displayName(),
1497 Bundle.Accounts_BINNode_bankCityProperty_displayName(), Bundle.Accounts_BINNode_noDescription(),
1499 bin.
getCountry().ifPresent(country -> properties.put(
new NodeProperty<>(Bundle.Accounts_BINNode_bankCountryProperty_displayName(),
1500 Bundle.Accounts_BINNode_bankCountryProperty_displayName(), Bundle.Accounts_BINNode_noDescription(),
1503 Bundle.Accounts_BINNode_bankPhoneProperty_displayName(), Bundle.Accounts_BINNode_noDescription(),
1505 bin.
getBankURL().ifPresent(url -> properties.put(
new NodeProperty<>(Bundle.Accounts_BINNode_bankURLProperty_displayName(),
1506 Bundle.Accounts_BINNode_bankURLProperty_displayName(), Bundle.Accounts_BINNode_noDescription(),
1513 this.setSheet(createSheet());
1528 hash = 97 * hash + this.binEnd;
1529 hash = 97 * hash + this.binStart;
1541 if (getClass() != obj.getClass()) {
1545 if (this.binEnd != other.
binEnd) {
1548 if (this.binStart != other.
binStart) {
1563 this.binRange = binRange;
1564 binStart = binRange.getBINstart();
1565 binEnd = binRange.getBINend();
1570 this.binRange = null;
1587 boolean hasDetails() {
1588 return binRange != null;
1642 super(artifact,
"org/sleuthkit/autopsy/images/credit-card.png");
1643 this.artifact = artifact;
1644 setName(Long.toString(
this.artifact.getArtifactID()));
1646 reviewStatusBus.register(
this);
1651 List<Action> actionsList =
new ArrayList<>();
1652 actionsList.addAll(Arrays.asList(super.getActions(context)));
1654 actionsList.add(approveActionInstance);
1655 actionsList.add(rejectActionInstance);
1657 return actionsList.toArray(
new Action[actionsList.size()]);
1662 Sheet sheet = super.createSheet();
1663 Sheet.Set properties = sheet.get(Sheet.PROPERTIES);
1664 if (properties == null) {
1665 properties = Sheet.createPropertiesSet();
1666 sheet.put(properties);
1668 properties.put(
new NodeProperty<>(Bundle.Accounts_FileWithCCNNode_statusProperty_displayName(),
1669 Bundle.Accounts_FileWithCCNNode_statusProperty_displayName(),
1670 Bundle.Accounts_FileWithCCNNode_noDescription(),
1671 artifact.getReviewStatus().getDisplayName()));
1680 event.artifacts.stream().filter((art) -> (art.getArtifactID() == this.artifact.getArtifactID())).map((_item) -> {
1682 }).forEachOrdered((_item) -> {
1688 this.setSheet(createSheet());
1696 @NbBundle.Messages(
"ToggleShowRejected.name=Show Rejected Results")
1698 super(Bundle.ToggleShowRejected_name());
1724 this.newStatus = newStatus;
1733 List<String[]> selectedPaths = Utilities.actionsGlobalContext().lookupAll(Node.class).stream()
1735 String[] createPath;
1741 if (newStatus == BlackboardArtifact.ReviewStatus.REJECTED && showRejected ==
false) {
1742 List<Node> siblings = Arrays.asList(node.getParentNode().getChildren().getNodes());
1743 if (siblings.size() > 1) {
1744 int indexOf = siblings.indexOf(node);
1746 Node sibling = indexOf > 0
1747 ? siblings.get(indexOf - 1)
1748 : siblings.get(Integer.max(indexOf + 1, siblings.size() - 1));
1749 createPath = NodeOp.createPath(sibling, null);
1757 createPath = NodeOp.createPath(node, null);
1760 return Arrays.copyOfRange(createPath, 1, createPath.length);
1762 .filter(Objects::nonNull)
1763 .collect(Collectors.toList());
1766 final Collection<? extends BlackboardArtifact> artifacts = Utilities.actionsGlobalContext().lookupAll(BlackboardArtifact.class);
1767 artifacts.forEach(artifact -> {
1769 artifact.setReviewStatus(newStatus);
1770 }
catch (TskCoreException ex) {
1771 LOGGER.log(Level.SEVERE,
"Error changing artifact review status.", ex);
1775 reviewStatusBus.post(
new ReviewStatusChangeEvent(artifacts, newStatus));
1777 final DataResultTopComponent directoryListing = DirectoryTreeTopComponent.findInstance().getDirectoryListing();
1778 final Node rootNode = directoryListing.getRootNode();
1781 List<Node> toArray =
new ArrayList<>();
1782 selectedPaths.forEach(path -> {
1784 toArray.add(NodeOp.findPath(rootNode, path));
1785 }
catch (NodeNotFoundException ex) {
1790 directoryListing.setSelectedNodes(toArray.toArray(
new Node[toArray.size()]));
1796 @NbBundle.Messages({
"ApproveAccountsAction.name=Approve Accounts"})
1798 super(Bundle.ApproveAccountsAction_name(), BlackboardArtifact.ReviewStatus.APPROVED);
1804 @NbBundle.Messages({
"RejectAccountsAction.name=Reject Accounts"})
1806 super(Bundle.RejectAccountsAction_name(), BlackboardArtifact.ReviewStatus.REJECTED);
1812 Collection<? extends BlackboardArtifact> artifacts;
1813 BlackboardArtifact.ReviewStatus newReviewStatus;
1815 ReviewStatusChangeEvent(Collection<? extends BlackboardArtifact> artifacts, BlackboardArtifact.ReviewStatus newReviewStatus) {
1816 this.artifacts = artifacts;
1817 this.newReviewStatus = newReviewStatus;
1828 if (type.equals(Account.Type.CREDIT_CARD)) {
1829 return ICON_BASE_PATH +
"credit-card.png";
1830 }
else if (type.equals(Account.Type.DEVICE)) {
1831 return ICON_BASE_PATH +
"image.png";
1832 }
else if (type.equals(Account.Type.EMAIL)) {
1833 return ICON_BASE_PATH +
"email.png";
1834 }
else if (type.equals(Account.Type.FACEBOOK)) {
1835 return ICON_BASE_PATH +
"facebook.png";
1836 }
else if (type.equals(Account.Type.INSTAGRAM)) {
1837 return ICON_BASE_PATH +
"instagram.png";
1838 }
else if (type.equals(Account.Type.MESSAGING_APP)) {
1839 return ICON_BASE_PATH +
"messaging.png";
1840 }
else if (type.equals(Account.Type.PHONE)) {
1841 return ICON_BASE_PATH +
"phone.png";
1842 }
else if (type.equals(Account.Type.TWITTER)) {
1843 return ICON_BASE_PATH +
"twitter.png";
1844 }
else if (type.equals(Account.Type.WEBSITE)) {
1845 return ICON_BASE_PATH +
"web-file.png";
1846 }
else if (type.equals(Account.Type.WHATSAPP)) {
1847 return ICON_BASE_PATH +
"WhatsApp.png";
1850 throw new IllegalArgumentException(
"Unknown Account.Type: " + type.getTypeName());
CreditCardNumberFactory(BinResult bin)
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
List< Long > getArtifactIDs()
boolean createKeys(List< String > list)
abstract boolean createKeys(List< X > list)
AccountArtifactNode(BlackboardArtifact artifact)
static synchronized BankIdentificationNumber getBINInfo(int bin)
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 ApproveAccounts approveActionInstance
T visit(DataSourcesNode in)
Node[] createNodesForKey(CreditCardViewMode key)
void removeIngestJobEventListener(final PropertyChangeListener listener)
Optional< String > getScheme()
final Set< BlackboardArtifact.ReviewStatus > statuses
Optional< String > getBrand()
final long datasourceObjId
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)
static Boolean getGroupItemsInTreeByDataSource()
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 PropertyChangeListener pcl
boolean equals(Object obj)
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)