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.logging.Logger;
44 import java.util.stream.Collectors;
45 import java.util.stream.Stream;
46 import javax.annotation.Nonnull;
47 import javax.annotation.concurrent.Immutable;
48 import javax.swing.AbstractAction;
49 import javax.swing.Action;
50 import org.apache.commons.lang3.StringUtils;
51 import org.openide.nodes.ChildFactory;
52 import org.openide.nodes.Children;
53 import org.openide.nodes.Node;
54 import org.openide.nodes.NodeNotFoundException;
55 import org.openide.nodes.NodeOp;
56 import org.openide.nodes.Sheet;
57 import org.openide.util.Exceptions;
58 import org.openide.util.NbBundle;
59 import org.openide.util.Utilities;
60 import org.openide.util.lookup.Lookups;
78 import org.
sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE;
91 private static final Logger
LOGGER = Logger.getLogger(
Accounts.class.getName());
93 @NbBundle.Messages(
"AccountsRootNode.name=Accounts")
94 final public static String
NAME = Bundle.AccountsRootNode_name();
121 return v.
visit(
this);
132 return showRejected ?
" " :
" AND blackboard_artifacts.review_status_id != " + BlackboardArtifact.ReviewStatus.REJECTED.getID() +
" ";
166 abstract protected boolean createKeys(List<X> list);
181 super.removeNotify();
196 @NbBundle.Messages({
"Accounts.RootNode.displayName=Accounts"})
202 setDisplayName(Bundle.Accounts_RootNode_displayName());
203 this.setIconBaseWithExtension(
"org/sleuthkit/autopsy/images/accounts.png");
213 return v.
visit(
this);
218 return getClass().getName();
231 private final PropertyChangeListener
pcl =
new PropertyChangeListener() {
233 public void propertyChange(PropertyChangeEvent evt) {
234 String eventType = evt.getPropertyName();
251 if (null != eventData
253 reviewStatusBus.post(eventData);
255 }
catch (IllegalStateException notUsed) {
269 }
catch (IllegalStateException notUsed) {
274 if (evt.getNewValue() == null) {
296 try (SleuthkitCase.CaseDbQuery executeQuery = skCase.executeQuery(
297 "SELECT DISTINCT blackboard_attributes.value_text as account_type "
298 +
" FROM blackboard_attributes "
299 +
" WHERE blackboard_attributes.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ACCOUNT_TYPE.getTypeID());
300 ResultSet resultSet = executeQuery.getResultSet()) {
301 while (resultSet.next()) {
302 String accountType = resultSet.getString(
"account_type");
303 list.add(accountType);
305 }
catch (TskCoreException | SQLException ex) {
306 LOGGER.log(Level.SEVERE,
"Error querying for account_types", ex);
315 String accountType = key;
316 if (accountType.equals(Account.Type.CREDIT_CARD.getTypeName())) {
319 String accountTypeDisplayname;
321 accountTypeDisplayname = skCase.getCommunicationsManager().getAccountType(accountType).getDisplayName();
322 }
catch (TskCoreException ex) {
323 LOGGER.log(Level.SEVERE,
"Error getting display name for account type. ", ex);
324 accountTypeDisplayname = accountType;
337 super.removeNotify();
359 private final PropertyChangeListener
pcl =
new PropertyChangeListener() {
361 public void propertyChange(PropertyChangeEvent evt) {
362 String eventType = evt.getPropertyName();
379 if (null != eventData
381 reviewStatusBus.post(eventData);
383 }
catch (IllegalStateException notUsed) {
398 }
catch (IllegalStateException notUsed) {
403 if (evt.getNewValue() == null) {
422 super.removeNotify();
428 =
"SELECT blackboard_artifacts.artifact_id "
429 +
" FROM blackboard_artifacts "
430 +
" JOIN blackboard_attributes ON blackboard_artifacts.artifact_id = blackboard_attributes.artifact_id "
431 +
" WHERE blackboard_artifacts.artifact_type_id = " + BlackboardArtifact.ARTIFACT_TYPE.TSK_ACCOUNT.getTypeID()
432 +
" AND blackboard_attributes.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ACCOUNT_TYPE.getTypeID()
433 +
" AND blackboard_attributes.value_text = '" + accountTypeName +
"'"
435 try (SleuthkitCase.CaseDbQuery results = skCase.executeQuery(query);
436 ResultSet rs = results.getResultSet();) {
438 list.add(rs.getLong(
"artifact_id"));
440 }
catch (TskCoreException | SQLException ex) {
441 LOGGER.log(Level.SEVERE,
"Error querying for account artifacts.", ex);
451 }
catch (TskCoreException ex) {
452 LOGGER.log(Level.SEVERE,
"Error get black board artifact with id " + t, ex);
477 super(Children.create(
new DefaultAccountFactory(accountTypeName),
true), Lookups.singleton(accountTypeDisplayName));
478 setName(accountTypeDisplayName);
479 this.setIconBaseWithExtension(
"org/sleuthkit/autopsy/images/credit-cards.png");
489 return v.
visit(
this);
494 return getClass().getName();
508 private final PropertyChangeListener pcl =
new PropertyChangeListener() {
510 public void propertyChange(PropertyChangeEvent evt) {
511 String eventType = evt.getPropertyName();
528 if (null != eventData
530 reviewStatusBus.post(eventData);
532 }
catch (IllegalStateException notUsed) {
547 }
catch (IllegalStateException notUsed) {
552 if (evt.getNewValue() == null) {
583 super.removeNotify();
590 protected boolean createKeys(List<CreditCardViewMode> list) {
619 super(Children.create(
new ViewModeFactory(),
true), Lookups.singleton(Account.Type.CREDIT_CARD.getDisplayName()));
620 setName(Account.Type.CREDIT_CARD.getDisplayName());
621 this.setIconBaseWithExtension(
"org/sleuthkit/autopsy/images/credit-cards.png");
631 return v.
visit(
this);
636 return getClass().getName();
642 private final PropertyChangeListener pcl =
new PropertyChangeListener() {
644 public void propertyChange(PropertyChangeEvent evt) {
645 String eventType = evt.getPropertyName();
662 if (null != eventData
664 reviewStatusBus.post(eventData);
666 }
catch (IllegalStateException notUsed) {
681 }
catch (IllegalStateException notUsed) {
686 if (evt.getNewValue() == null) {
705 super.removeNotify();
723 =
"SELECT blackboard_artifacts.obj_id,"
724 +
" solr_attribute.value_text AS solr_document_id, ";
725 if (skCase.getDatabaseType().equals(DbType.POSTGRESQL)) {
726 query +=
" string_agg(blackboard_artifacts.artifact_id::character varying, ',') AS artifact_IDs, "
727 +
" string_agg(blackboard_artifacts.review_status_id::character varying, ',') AS review_status_ids, ";
729 query +=
" GROUP_CONCAT(blackboard_artifacts.artifact_id) AS artifact_IDs, "
730 +
" GROUP_CONCAT(blackboard_artifacts.review_status_id) AS review_status_ids, ";
732 query +=
" COUNT( blackboard_artifacts.artifact_id) AS hits "
733 +
" FROM blackboard_artifacts "
734 +
" LEFT JOIN blackboard_attributes as solr_attribute ON blackboard_artifacts.artifact_id = solr_attribute.artifact_id "
735 +
" AND solr_attribute.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD_SEARCH_DOCUMENT_ID.getTypeID()
736 +
" LEFT JOIN blackboard_attributes as account_type ON blackboard_artifacts.artifact_id = account_type.artifact_id "
737 +
" AND account_type.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ACCOUNT_TYPE.getTypeID()
738 +
" AND account_type.value_text = '" + Account.Type.CREDIT_CARD.getTypeName() +
"'"
739 +
" WHERE blackboard_artifacts.artifact_type_id = " + BlackboardArtifact.ARTIFACT_TYPE.TSK_ACCOUNT.getTypeID()
741 +
" GROUP BY blackboard_artifacts.obj_id, solr_document_id "
742 +
" ORDER BY hits DESC ";
743 try (SleuthkitCase.CaseDbQuery results = skCase.executeQuery(query);
744 ResultSet rs = results.getResultSet();) {
747 rs.getLong(
"obj_id"),
748 rs.getString(
"solr_document_id"),
749 unGroupConcat(rs.getString(
"artifact_IDs"), Long::valueOf),
751 new HashSet<>(unGroupConcat(rs.getString(
"review_status_ids"),
id -> BlackboardArtifact.ReviewStatus.withID(Integer.valueOf(
id))))));
753 }
catch (TskCoreException | SQLException ex) {
754 LOGGER.log(Level.SEVERE,
"Error querying for files with ccn hits.", ex);
764 List<Object> lookupContents =
new ArrayList<>();
766 lookupContents.add(skCase.getBlackboardArtifact(artId));
768 AbstractFile abstractFileById = skCase.getAbstractFileById(key.
getObjID());
769 lookupContents.add(abstractFileById);
770 return new Node[]{
new FileWithCCNNode(key, abstractFileById, lookupContents.toArray())};
771 }
catch (TskCoreException ex) {
772 LOGGER.log(Level.SEVERE,
"Error getting content for file with ccn hits.", ex);
791 this.setIconBaseWithExtension(
"org/sleuthkit/autopsy/images/file-icon.png");
792 reviewStatusBus.register(
this);
796 "# {0} - number of children",
797 "Accounts.ByFileNode.displayName=By File ({0})"})
800 =
"SELECT count(*) FROM ( SELECT count(*) AS documents "
801 +
" FROM blackboard_artifacts "
802 +
" LEFT JOIN blackboard_attributes as solr_attribute ON blackboard_artifacts.artifact_id = solr_attribute.artifact_id "
803 +
" AND solr_attribute.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD_SEARCH_DOCUMENT_ID.getTypeID()
804 +
" LEFT JOIN blackboard_attributes as account_type ON blackboard_artifacts.artifact_id = account_type.artifact_id "
805 +
" AND account_type.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ACCOUNT_TYPE.getTypeID()
806 +
" AND account_type.value_text = '" + Account.Type.CREDIT_CARD.getTypeName() +
"'"
807 +
" WHERE blackboard_artifacts.artifact_type_id = " + BlackboardArtifact.ARTIFACT_TYPE.TSK_ACCOUNT.getTypeID()
809 +
" GROUP BY blackboard_artifacts.obj_id, solr_attribute.value_text ) AS foo";
810 try (SleuthkitCase.CaseDbQuery results = skCase.executeQuery(query);
811 ResultSet rs = results.getResultSet();) {
813 if (skCase.getDatabaseType().equals(DbType.POSTGRESQL)) {
814 setDisplayName(Bundle.Accounts_ByFileNode_displayName(rs.getLong(
"count")));
816 setDisplayName(Bundle.Accounts_ByFileNode_displayName(rs.getLong(
"count(*)")));
819 }
catch (TskCoreException | SQLException ex) {
820 LOGGER.log(Level.SEVERE,
"Error querying for files with ccn hits.", ex);
832 return v.
visit(
this);
837 return getClass().getName();
853 private final PropertyChangeListener pcl =
new PropertyChangeListener() {
855 public void propertyChange(PropertyChangeEvent evt) {
856 String eventType = evt.getPropertyName();
873 if (null != eventData
875 reviewStatusBus.post(eventData);
877 }
catch (IllegalStateException notUsed) {
892 }
catch (IllegalStateException notUsed) {
897 if (evt.getNewValue() == null) {
916 super.removeNotify();
934 RangeMap<Integer, BinResult> binRanges = TreeRangeMap.create();
937 =
"SELECT SUBSTR(blackboard_attributes.value_text,1,8) AS BIN, "
938 +
" COUNT(blackboard_artifacts.artifact_id) AS count "
939 +
" FROM blackboard_artifacts "
940 +
" JOIN blackboard_attributes ON blackboard_artifacts.artifact_id = blackboard_attributes.artifact_id"
941 +
" WHERE blackboard_artifacts.artifact_type_id = " + BlackboardArtifact.ARTIFACT_TYPE.TSK_ACCOUNT.getTypeID()
942 +
" AND blackboard_attributes.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_CARD_NUMBER.getTypeID()
946 try (SleuthkitCase.CaseDbQuery results = skCase.executeQuery(query)) {
947 ResultSet resultSet = results.getResultSet();
949 while (resultSet.next()) {
950 final Integer bin = Integer.valueOf(resultSet.getString(
"BIN"));
951 long count = resultSet.getLong(
"count");
954 BinResult previousResult = binRanges.get(bin);
956 if (previousResult != null) {
957 binRanges.remove(Range.closed(previousResult.getBINStart(), previousResult.getBINEnd()));
958 count += previousResult.getCount();
961 if (binRange != null) {
964 binRanges.put(Range.closed(bin, bin),
new BinResult(count, bin, bin));
967 binRanges.asMapOfRanges().values().forEach(list::add);
968 }
catch (TskCoreException | SQLException ex) {
969 LOGGER.log(Level.SEVERE,
"Error querying for BINs.", ex);
978 return new Node[]{
new BINNode(key)};
991 @NbBundle.Messages(
"Accounts.ByBINNode.name=By BIN")
993 super(Children.create(
new BINFactory(),
true), Lookups.singleton(Bundle.Accounts_ByBINNode_name()));
994 setName(Bundle.Accounts_ByBINNode_name());
996 this.setIconBaseWithExtension(
"org/sleuthkit/autopsy/images/bank.png");
997 reviewStatusBus.register(
this);
1000 @NbBundle.Messages({
1001 "# {0} - number of children",
1002 "Accounts.ByBINNode.displayName=By BIN ({0})"})
1005 =
"SELECT count(distinct SUBSTR(blackboard_attributes.value_text,1,8)) AS BINs "
1006 +
" FROM blackboard_artifacts "
1007 +
" JOIN blackboard_attributes ON blackboard_artifacts.artifact_id = blackboard_attributes.artifact_id"
1008 +
" WHERE blackboard_artifacts.artifact_type_id = " + BlackboardArtifact.ARTIFACT_TYPE.TSK_ACCOUNT.getTypeID()
1009 +
" AND blackboard_attributes.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_CARD_NUMBER.getTypeID()
1011 try (SleuthkitCase.CaseDbQuery results = skCase.executeQuery(query)) {
1012 ResultSet resultSet = results.getResultSet();
1013 while (resultSet.next()) {
1014 setDisplayName(Bundle.Accounts_ByBINNode_displayName(resultSet.getLong(
"BINs")));
1016 }
catch (TskCoreException | SQLException ex) {
1017 LOGGER.log(Level.SEVERE,
"Error querying for BINs.", ex);
1028 return v.
visit(
this);
1033 return getClass().getName();
1038 updateDisplayName();
1043 updateDisplayName();
1057 hash = 79 * hash + (int) (this.objID ^ (this.objID >>> 32));
1058 hash = 79 * hash + Objects.hashCode(this.keywordSearchDocID);
1059 hash = 79 * hash + Objects.hashCode(this.artifactIDs);
1060 hash = 79 * hash + (int) (this.hits ^ (this.hits >>> 32));
1061 hash = 79 * hash + Objects.hashCode(this.statuses);
1073 if (getClass() != obj.getClass()) {
1077 if (this.objID != other.
objID) {
1080 if (this.hits != other.
hits) {
1086 if (!Objects.equals(
this.artifactIDs, other.
artifactIDs)) {
1089 if (!Objects.equals(
this.statuses, other.
statuses)) {
1099 private final Set<BlackboardArtifact.ReviewStatus>
statuses;
1101 private FileWithCCN(
long objID, String solrDocID, List<Long> artifactIDs,
long hits, Set<BlackboardArtifact.ReviewStatus> statuses) {
1103 this.keywordSearchDocID = solrDocID;
1104 this.artifactIDs = artifactIDs;
1106 this.statuses = statuses;
1125 return keywordSearchDocID;
1172 static <X> List<X> unGroupConcat(String groupConcat, Function<String, X> mapper) {
1173 return StringUtils.isBlank(groupConcat) ? Collections.emptyList()
1174 : Stream.of(groupConcat.split(
","))
1176 .collect(Collectors.toList());
1195 @NbBundle.Messages({
1196 "# {0} - raw file name",
1197 "# {1} - solr chunk id",
1198 "Accounts.FileWithCCNNode.unallocatedSpaceFile.displayName={0}_chunk_{1}"})
1200 super(Children.LEAF, Lookups.fixed(lookupContents));
1204 : Bundle.Accounts_FileWithCCNNode_unallocatedSpaceFile_displayName(content.getName(), StringUtils.substringAfter(key.
getkeywordSearchDocID(),
"_"));
1205 setName(fileName + key.
getObjID());
1206 setDisplayName(fileName);
1216 return v.
visit(
this);
1221 return getClass().getName();
1225 @NbBundle.Messages({
1226 "Accounts.FileWithCCNNode.nameProperty.displayName=File",
1227 "Accounts.FileWithCCNNode.accountsProperty.displayName=Accounts",
1228 "Accounts.FileWithCCNNode.statusProperty.displayName=Status",
1229 "Accounts.FileWithCCNNode.noDescription=no description"})
1231 Sheet s = super.createSheet();
1232 Sheet.Set ss = s.get(Sheet.PROPERTIES);
1234 ss = Sheet.createPropertiesSet();
1238 ss.put(
new NodeProperty<>(Bundle.Accounts_FileWithCCNNode_nameProperty_displayName(),
1239 Bundle.Accounts_FileWithCCNNode_nameProperty_displayName(),
1240 Bundle.Accounts_FileWithCCNNode_noDescription(),
1242 ss.put(
new NodeProperty<>(Bundle.Accounts_FileWithCCNNode_accountsProperty_displayName(),
1243 Bundle.Accounts_FileWithCCNNode_accountsProperty_displayName(),
1244 Bundle.Accounts_FileWithCCNNode_noDescription(),
1246 ss.put(
new NodeProperty<>(Bundle.Accounts_FileWithCCNNode_statusProperty_displayName(),
1247 Bundle.Accounts_FileWithCCNNode_statusProperty_displayName(),
1248 Bundle.Accounts_FileWithCCNNode_noDescription(),
1250 .map(BlackboardArtifact.ReviewStatus::getDisplayName)
1251 .collect(Collectors.joining(
", "))));
1258 Action[] actions = super.getActions(context);
1259 ArrayList<Action> arrayList =
new ArrayList<>();
1260 arrayList.addAll(Arrays.asList(actions));
1263 }
catch (TskCoreException ex) {
1264 LOGGER.log(Level.SEVERE,
"Error gettung content by id", ex);
1267 arrayList.add(approveActionInstance);
1268 arrayList.add(rejectActionInstance);
1270 return arrayList.toArray(
new Action[arrayList.size()]);
1298 =
"SELECT blackboard_artifacts.artifact_id "
1299 +
" FROM blackboard_artifacts "
1300 +
" JOIN blackboard_attributes ON blackboard_artifacts.artifact_id = blackboard_attributes.artifact_id "
1301 +
" WHERE blackboard_artifacts.artifact_type_id = " + BlackboardArtifact.ARTIFACT_TYPE.TSK_ACCOUNT.getTypeID()
1302 +
" AND blackboard_attributes.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_CARD_NUMBER.getTypeID()
1303 +
" AND blackboard_attributes.value_text >= '" + bin.getBINStart() +
"' AND blackboard_attributes.value_text < '" + (bin.getBINEnd() + 1) +
"'"
1305 +
" ORDER BY blackboard_attributes.value_text";
1306 try (SleuthkitCase.CaseDbQuery results = skCase.executeQuery(query);
1307 ResultSet rs = results.getResultSet();) {
1309 list.add(rs.getLong(
"artifact_id"));
1311 }
catch (TskCoreException | SQLException ex) {
1312 LOGGER.log(Level.SEVERE,
"Error querying for account artifacts.", ex);
1320 if (skCase == null) {
1325 BlackboardArtifact art = skCase.getBlackboardArtifact(artifactID);
1327 }
catch (TskCoreException ex) {
1328 LOGGER.log(Level.SEVERE,
"Error creating BlackboardArtifactNode for artifact with ID " + artifactID, ex);
1335 if (bin.getBINStart() == bin.getBINEnd()) {
1336 return Integer.toString(bin.getBINStart());
1338 return bin.getBINStart() +
"-" + StringUtils.difference(bin.getBINStart() +
"", bin.getBINEnd() +
"");
1353 updateDisplayName();
1354 this.setIconBaseWithExtension(
"org/sleuthkit/autopsy/images/bank.png");
1355 reviewStatusBus.register(
this);
1360 updateDisplayName();
1366 updateDisplayName();
1371 =
"SELECT count(blackboard_artifacts.artifact_id ) AS count"
1372 +
" FROM blackboard_artifacts "
1373 +
" JOIN blackboard_attributes ON blackboard_artifacts.artifact_id = blackboard_attributes.artifact_id "
1374 +
" WHERE blackboard_artifacts.artifact_type_id = " + BlackboardArtifact.ARTIFACT_TYPE.TSK_ACCOUNT.getTypeID()
1375 +
" AND blackboard_attributes.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_CARD_NUMBER.getTypeID()
1376 +
" AND blackboard_attributes.value_text >= '" + bin.getBINStart() +
"' AND blackboard_attributes.value_text < '" + (bin.getBINEnd() + 1) +
"'"
1378 try (SleuthkitCase.CaseDbQuery results = skCase.executeQuery(query);
1379 ResultSet rs = results.getResultSet();) {
1383 }
catch (TskCoreException | SQLException ex) {
1384 LOGGER.log(Level.SEVERE,
"Error querying for account artifacts.", ex);
1397 return v.
visit(
this);
1402 return getClass().getName();
1406 Sheet.Set ss = s.get(Sheet.PROPERTIES);
1408 ss = Sheet.createPropertiesSet();
1415 @NbBundle.Messages({
1416 "Accounts.BINNode.binProperty.displayName=Bank Identifier Number",
1417 "Accounts.BINNode.accountsProperty.displayName=Accounts",
1418 "Accounts.BINNode.cardTypeProperty.displayName=Payment Card Type",
1419 "Accounts.BINNode.schemeProperty.displayName=Credit Card Scheme",
1420 "Accounts.BINNode.brandProperty.displayName=Brand",
1421 "Accounts.BINNode.bankProperty.displayName=Bank",
1422 "Accounts.BINNode.bankCityProperty.displayName=Bank City",
1423 "Accounts.BINNode.bankCountryProperty.displayName=Bank Country",
1424 "Accounts.BINNode.bankPhoneProperty.displayName=Bank Phone #",
1425 "Accounts.BINNode.bankURLProperty.displayName=Bank URL",
1426 "Accounts.BINNode.noDescription=no description"})
1428 Sheet sheet = super.createSheet();
1429 Sheet.Set properties = getPropertySet(sheet);
1431 properties.put(
new NodeProperty<>(Bundle.Accounts_BINNode_binProperty_displayName(),
1432 Bundle.Accounts_BINNode_binProperty_displayName(),
1433 Bundle.Accounts_BINNode_noDescription(),
1435 properties.put(
new NodeProperty<>(Bundle.Accounts_BINNode_accountsProperty_displayName(),
1436 Bundle.Accounts_BINNode_accountsProperty_displayName(), Bundle.Accounts_BINNode_noDescription(),
1440 if (bin.hasDetails()) {
1441 bin.
getCardType().ifPresent(cardType -> properties.put(
new NodeProperty<>(Bundle.Accounts_BINNode_cardTypeProperty_displayName(),
1442 Bundle.Accounts_BINNode_cardTypeProperty_displayName(), Bundle.Accounts_BINNode_noDescription(),
1444 bin.
getScheme().ifPresent(scheme -> properties.put(
new NodeProperty<>(Bundle.Accounts_BINNode_schemeProperty_displayName(),
1445 Bundle.Accounts_BINNode_schemeProperty_displayName(), Bundle.Accounts_BINNode_noDescription(),
1447 bin.
getBrand().ifPresent(brand -> properties.put(
new NodeProperty<>(Bundle.Accounts_BINNode_brandProperty_displayName(),
1448 Bundle.Accounts_BINNode_brandProperty_displayName(), Bundle.Accounts_BINNode_noDescription(),
1450 bin.
getBankName().ifPresent(bankName -> properties.put(
new NodeProperty<>(Bundle.Accounts_BINNode_bankProperty_displayName(),
1451 Bundle.Accounts_BINNode_bankProperty_displayName(), Bundle.Accounts_BINNode_noDescription(),
1453 bin.
getBankCity().ifPresent(bankCity -> properties.put(
new NodeProperty<>(Bundle.Accounts_BINNode_bankCityProperty_displayName(),
1454 Bundle.Accounts_BINNode_bankCityProperty_displayName(), Bundle.Accounts_BINNode_noDescription(),
1456 bin.
getCountry().ifPresent(country -> properties.put(
new NodeProperty<>(Bundle.Accounts_BINNode_bankCountryProperty_displayName(),
1457 Bundle.Accounts_BINNode_bankCountryProperty_displayName(), Bundle.Accounts_BINNode_noDescription(),
1460 Bundle.Accounts_BINNode_bankPhoneProperty_displayName(), Bundle.Accounts_BINNode_noDescription(),
1462 bin.
getBankURL().ifPresent(url -> properties.put(
new NodeProperty<>(Bundle.Accounts_BINNode_bankURLProperty_displayName(),
1463 Bundle.Accounts_BINNode_bankURLProperty_displayName(), Bundle.Accounts_BINNode_noDescription(),
1470 this.setSheet(createSheet());
1485 hash = 97 * hash + this.binEnd;
1486 hash = 97 * hash + this.binStart;
1498 if (getClass() != obj.getClass()) {
1502 if (this.binEnd != other.
binEnd) {
1505 if (this.binStart != other.
binStart) {
1522 this.binRange = binRange;
1523 binStart = binRange.getBINstart();
1524 binEnd = binRange.getBINend();
1529 this.binRange = null;
1546 boolean hasDetails() {
1547 return binRange != null;
1601 super(artifact,
"org/sleuthkit/autopsy/images/credit-card.png");
1602 this.artifact = artifact;
1603 setName(
"" + this.artifact.getArtifactID());
1605 reviewStatusBus.register(
this);
1610 List<Action> actionsList =
new ArrayList<>();
1611 actionsList.addAll(Arrays.asList(super.getActions(context)));
1613 actionsList.add(approveActionInstance);
1614 actionsList.add(rejectActionInstance);
1616 return actionsList.toArray(
new Action[actionsList.size()]);
1621 Sheet sheet = super.createSheet();
1622 Sheet.Set properties = sheet.get(Sheet.PROPERTIES);
1623 if (properties == null) {
1624 properties = Sheet.createPropertiesSet();
1625 sheet.put(properties);
1627 properties.put(
new NodeProperty<>(Bundle.Accounts_FileWithCCNNode_statusProperty_displayName(),
1628 Bundle.Accounts_FileWithCCNNode_statusProperty_displayName(),
1629 Bundle.Accounts_FileWithCCNNode_noDescription(),
1630 artifact.getReviewStatus().getDisplayName()));
1639 event.artifacts.stream().filter((art) -> (art.getArtifactID() == this.artifact.getArtifactID())).map((_item) -> {
1641 }).forEachOrdered((_item) -> {
1647 this.setSheet(createSheet());
1654 @NbBundle.Messages(
"ToggleShowRejected.name=Show Rejected Results")
1656 super(Bundle.ToggleShowRejected_name());
1672 this.newStatus = newStatus;
1681 List<String[]> selectedPaths = Utilities.actionsGlobalContext().lookupAll(Node.class).stream()
1683 String[] createPath;
1689 if (newStatus == BlackboardArtifact.ReviewStatus.REJECTED && showRejected ==
false) {
1690 List<Node> siblings = Arrays.asList(node.getParentNode().getChildren().getNodes());
1691 if (siblings.size() > 1) {
1692 int indexOf = siblings.indexOf(node);
1694 Node sibling = indexOf > 0
1695 ? siblings.get(indexOf - 1)
1696 : siblings.get(Integer.max(indexOf + 1, siblings.size() - 1));
1697 createPath = NodeOp.createPath(sibling, null);
1705 createPath = NodeOp.createPath(node, null);
1708 return Arrays.copyOfRange(createPath, 1, createPath.length);
1710 .filter(Objects::nonNull)
1711 .collect(Collectors.toList());
1714 final Collection<? extends BlackboardArtifact> artifacts = Utilities.actionsGlobalContext().lookupAll(BlackboardArtifact.class);
1715 artifacts.forEach(artifact -> {
1717 artifact.setReviewStatus(newStatus);
1718 }
catch (TskCoreException ex) {
1719 LOGGER.log(Level.SEVERE,
"Error changing artifact review status.", ex);
1723 reviewStatusBus.post(
new ReviewStatusChangeEvent(artifacts, newStatus));
1725 final DataResultTopComponent directoryListing = DirectoryTreeTopComponent.findInstance().getDirectoryListing();
1726 final Node rootNode = directoryListing.getRootNode();
1729 List<Node> toArray =
new ArrayList<>();
1730 selectedPaths.forEach(path -> {
1732 toArray.add(NodeOp.findPath(rootNode, path));
1733 }
catch (NodeNotFoundException ex) {
1738 directoryListing.setSelectedNodes(toArray.toArray(
new Node[toArray.size()]));
1744 @NbBundle.Messages({
"ApproveAccountsAction.name=Approve Accounts"})
1746 super(Bundle.ApproveAccountsAction_name(), BlackboardArtifact.ReviewStatus.APPROVED);
1752 @NbBundle.Messages({
"RejectAccountsAction.name=Reject Accounts"})
1754 super(Bundle.RejectAccountsAction_name(), BlackboardArtifact.ReviewStatus.REJECTED);
1760 Collection<? extends BlackboardArtifact> artifacts;
1761 BlackboardArtifact.ReviewStatus newReviewStatus;
1763 public ReviewStatusChangeEvent(Collection<? extends BlackboardArtifact> artifacts, BlackboardArtifact.ReviewStatus newReviewStatus) {
1764 this.artifacts = artifacts;
1765 this.newReviewStatus = newReviewStatus;
CreditCardNumberFactory(BinResult bin)
final BlackboardArtifact.ReviewStatus newStatus
boolean createKeys(List< CreditCardViewMode > list)
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()
Optional< String > getCountry()
Optional< String > getBankCity()
final String keywordSearchDocID
static List< Action > getActions(File file, boolean isArtifactSource)
Optional< String > getBankName()
final EventBus reviewStatusBus
String getRejectedArtifactFilterClause()
Sheet.Set getPropertySet(Sheet s)
Node[] createNodesForKey(String key)
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)
final String accountTypeName
Node[] createNodesForKey(Long artifactID)
Action[] getActions(boolean context)
Node[] createNodesForKey(FileWithCCN key)
boolean createKeys(List< FileWithCCN > list)
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()
boolean equals(Object obj)
CreditCardNumberAccountTypeNode()
void addIngestJobEventListener(final PropertyChangeListener listener)
Optional< String > getBankURL()
String getkeywordSearchDocID()
ReviewStatusChangeEvent(Collection<?extends BlackboardArtifact > artifacts, BlackboardArtifact.ReviewStatus newReviewStatus)
Optional< Integer > getNumberLength()
BinResult(long count,@Nonnull BINRange binRange)
Action newToggleShowRejectedAction()
Optional< String > getBrand()
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)
static Case getCurrentCase()
DefaultAccountFactory(String accountTypeName)
DefaultAccountTypeNode(String accountTypeName, String accountTypeDisplayName)
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 void removeEventTypeSubscriber(Set< Events > eventTypes, PropertyChangeListener subscriber)
void actionPerformed(ActionEvent e)
Optional< String > getScheme()
Optional< String > getBankName()
Optional< String > getBankPhoneNumber()
Optional< String > getCardType()
Accounts(SleuthkitCase skCase)