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.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;
75 import org.
sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE;
88 private static final Logger
LOGGER = Logger.getLogger(
Accounts.class.getName());
90 @NbBundle.Messages(
"AccountsRootNode.name=Accounts")
91 final public static String
NAME = Bundle.AccountsRootNode_name();
118 return v.
visit(
this);
129 return showRejected ?
" " :
" AND blackboard_artifacts.review_status_id != " + BlackboardArtifact.ReviewStatus.REJECTED.getID() +
" ";
163 abstract protected Collection<X>
createKeys();
185 super.removeNotify();
200 @NbBundle.Messages({
"Accounts.RootNode.displayName=Accounts"})
212 private final PropertyChangeListener pcl =
new PropertyChangeListener() {
214 public void propertyChange(PropertyChangeEvent evt) {
215 String eventType = evt.getPropertyName();
233 if (null != eventData
235 reviewStatusBus.post(eventData);
237 }
catch (IllegalStateException notUsed) {
251 }
catch (IllegalStateException notUsed) {
256 if (evt.getNewValue() == null) {
278 List<String> list =
new ArrayList<>();
279 try (SleuthkitCase.CaseDbQuery executeQuery = skCase.executeQuery(
280 "SELECT DISTINCT blackboard_attributes.value_text as account_type "
281 +
" FROM blackboard_attributes "
282 +
" WHERE blackboard_attributes.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ACCOUNT_TYPE.getTypeID());
283 ResultSet resultSet = executeQuery.getResultSet()) {
284 while (resultSet.next()) {
285 String accountType = resultSet.getString(
"account_type");
286 list.add(accountType);
288 }
catch (TskCoreException | SQLException ex) {
289 LOGGER.log(Level.SEVERE,
"Error querying for account_types", ex);
297 Account.Type accountType = Account.Type.valueOf(key);
298 switch (accountType) {
304 }
catch (IllegalArgumentException ex) {
305 LOGGER.log(Level.WARNING,
"Unknown account type: {0}", key);
316 super.removeNotify();
331 super(Children.LEAF, Lookups.singleton(
Accounts.this));
332 setChildren(Children.createLazy(AccountTypeFactory::new));
334 setDisplayName(Bundle.Accounts_RootNode_displayName());
335 this.setIconBaseWithExtension(
"org/sleuthkit/autopsy/images/accounts.png");
345 return v.
visit(
this);
350 return getClass().getName();
369 List<Long> list =
new ArrayList<>();
371 =
"SELECT blackboard_artifacts.artifact_id "
372 +
" FROM blackboard_artifacts "
373 +
" JOIN blackboard_attributes ON blackboard_artifacts.artifact_id = blackboard_attributes.artifact_id "
374 +
" WHERE blackboard_artifacts.artifact_type_id = " + BlackboardArtifact.ARTIFACT_TYPE.TSK_ACCOUNT.getTypeID()
375 +
" AND blackboard_attributes.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ACCOUNT_TYPE.getTypeID()
376 +
" AND blackboard_attributes.value_text = '" + accountTypeName +
"'"
378 try (SleuthkitCase.CaseDbQuery results = skCase.executeQuery(query);
379 ResultSet rs = results.getResultSet();) {
381 list.add(rs.getLong(
"artifact_id"));
383 }
catch (TskCoreException | SQLException ex) {
384 LOGGER.log(Level.SEVERE,
"Error querying for account artifacts.", ex);
393 }
catch (TskCoreException ex) {
394 LOGGER.log(Level.SEVERE,
"Error get black board artifact with id " + t, ex);
413 super(Children.LEAF);
415 setChildren(Children.createLazy(DefaultAccountFactory::new));
416 setName(accountTypeName);
417 this.setIconBaseWithExtension(
"org/sleuthkit/autopsy/images/credit-cards.png");
427 return v.
visit(
this);
432 return getClass().getName();
486 super(Children.LEAF);
488 setName(Account.Type.CREDIT_CARD.getDisplayName());
489 this.setIconBaseWithExtension(
"org/sleuthkit/autopsy/images/credit-cards.png");
499 return v.
visit(
this);
504 return getClass().getName();
533 List<FileWithCCN> list =
new ArrayList<>();
535 =
"SELECT blackboard_artifacts.obj_id,"
536 +
" solr_attribute.value_text AS solr_document_id, ";
537 if(skCase.getDatabaseType().equals(DbType.POSTGRESQL)){
538 query +=
" string_agg(blackboard_artifacts.artifact_id::character varying, ',') AS artifact_IDs, "
539 +
" string_agg(blackboard_artifacts.review_status_id::character varying, ',') AS review_status_ids, ";
541 query +=
" GROUP_CONCAT(blackboard_artifacts.artifact_id) AS artifact_IDs, "
542 +
" GROUP_CONCAT(blackboard_artifacts.review_status_id) AS review_status_ids, ";
544 query +=
" COUNT( blackboard_artifacts.artifact_id) AS hits "
545 +
" FROM blackboard_artifacts "
546 +
" LEFT JOIN blackboard_attributes as solr_attribute ON blackboard_artifacts.artifact_id = solr_attribute.artifact_id "
547 +
" AND solr_attribute.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD_SEARCH_DOCUMENT_ID.getTypeID()
548 +
" LEFT JOIN blackboard_attributes as account_type ON blackboard_artifacts.artifact_id = account_type.artifact_id "
549 +
" AND account_type.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ACCOUNT_TYPE.getTypeID()
550 +
" AND account_type.value_text = '" + Account.Type.CREDIT_CARD.name() +
"'"
551 +
" WHERE blackboard_artifacts.artifact_type_id = " + BlackboardArtifact.ARTIFACT_TYPE.TSK_ACCOUNT.getTypeID()
553 +
" GROUP BY blackboard_artifacts.obj_id, solr_document_id "
554 +
" ORDER BY hits DESC ";
555 try (SleuthkitCase.CaseDbQuery results = skCase.executeQuery(query);
556 ResultSet rs = results.getResultSet();) {
559 rs.getLong(
"obj_id"),
560 rs.getString(
"solr_document_id"),
561 unGroupConcat(rs.getString(
"artifact_IDs"), Long::valueOf),
563 new HashSet<>(unGroupConcat(rs.getString(
"review_status_ids"),
id -> BlackboardArtifact.ReviewStatus.withID(Integer.valueOf(
id))))));
565 }
catch (TskCoreException | SQLException ex) {
566 LOGGER.log(Level.SEVERE,
"Error querying for files with ccn hits.", ex);
576 List<Object> lookupContents =
new ArrayList<>();
578 lookupContents.add(skCase.getBlackboardArtifact(artId));
580 AbstractFile abstractFileById = skCase.getAbstractFileById(key.
getObjID());
581 lookupContents.add(abstractFileById);
582 return new Node[]{
new FileWithCCNNode(key, abstractFileById, lookupContents.toArray())};
583 }
catch (TskCoreException ex) {
584 LOGGER.log(Level.SEVERE,
"Error getting content for file with ccn hits.", ex);
591 super(Children.LEAF);
592 setChildren(Children.createLazy(FileWithCCNFactory::new));
595 this.setIconBaseWithExtension(
"org/sleuthkit/autopsy/images/file-icon.png");
596 reviewStatusBus.register(
this);
600 "# {0} - number of children",
601 "Accounts.ByFileNode.displayName=By File ({0})"})
604 =
"SELECT count(*) FROM ( SELECT count(*) AS documents "
605 +
" FROM blackboard_artifacts "
606 +
" LEFT JOIN blackboard_attributes as solr_attribute ON blackboard_artifacts.artifact_id = solr_attribute.artifact_id "
607 +
" AND solr_attribute.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD_SEARCH_DOCUMENT_ID.getTypeID()
608 +
" LEFT JOIN blackboard_attributes as account_type ON blackboard_artifacts.artifact_id = account_type.artifact_id "
609 +
" AND account_type.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ACCOUNT_TYPE.getTypeID()
610 +
" AND account_type.value_text = '" + Account.Type.CREDIT_CARD.name() +
"'"
611 +
" WHERE blackboard_artifacts.artifact_type_id = " + BlackboardArtifact.ARTIFACT_TYPE.TSK_ACCOUNT.getTypeID()
613 +
" GROUP BY blackboard_artifacts.obj_id, solr_attribute.value_text ) AS foo";
614 try (SleuthkitCase.CaseDbQuery results = skCase.executeQuery(query);
615 ResultSet rs = results.getResultSet();) {
617 if(skCase.getDatabaseType().equals(DbType.POSTGRESQL)){
618 setDisplayName(Bundle.Accounts_ByFileNode_displayName(rs.getLong(
"count")));
620 setDisplayName(Bundle.Accounts_ByFileNode_displayName(rs.getLong(
"count(*)")));
623 }
catch (TskCoreException | SQLException ex) {
624 LOGGER.log(Level.SEVERE,
"Error querying for files with ccn hits.", ex);
636 return v.
visit(
this);
641 return getClass().getName();
680 List<BinResult> list =
new ArrayList<>();
682 RangeMap<Integer, BinResult> binRanges = TreeRangeMap.create();
685 =
"SELECT SUBSTR(blackboard_attributes.value_text,1,8) AS BIN, "
686 +
" COUNT(blackboard_artifacts.artifact_id) AS count "
687 +
" FROM blackboard_artifacts "
688 +
" JOIN blackboard_attributes ON blackboard_artifacts.artifact_id = blackboard_attributes.artifact_id"
689 +
" WHERE blackboard_artifacts.artifact_type_id = " + BlackboardArtifact.ARTIFACT_TYPE.TSK_ACCOUNT.getTypeID()
690 +
" AND blackboard_attributes.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_CARD_NUMBER.getTypeID()
694 try (SleuthkitCase.CaseDbQuery results = skCase.executeQuery(query)) {
695 ResultSet resultSet = results.getResultSet();
697 while (resultSet.next()) {
698 final Integer bin = Integer.valueOf(resultSet.getString(
"BIN"));
699 long count = resultSet.getLong(
"count");
702 BinResult previousResult = binRanges.get(bin);
704 if (previousResult != null) {
705 binRanges.remove(Range.closed(previousResult.getBINStart(), previousResult.getBINEnd()));
706 count += previousResult.getCount();
709 if (binRange != null) {
712 binRanges.put(Range.closed(bin, bin),
new BinResult(count, bin, bin));
715 binRanges.asMapOfRanges().values().forEach(list::add);
716 }
catch (TskCoreException | SQLException ex) {
717 LOGGER.log(Level.SEVERE,
"Error querying for BINs.", ex);
725 return new Node[]{
new BINNode(key)};
729 @NbBundle.Messages(
"Accounts.ByBINNode.name=By BIN")
731 super(Children.LEAF);
732 setChildren(Children.createLazy(BINFactory::new));
733 setName(Bundle.Accounts_ByBINNode_name());
735 this.setIconBaseWithExtension(
"org/sleuthkit/autopsy/images/bank.png");
736 reviewStatusBus.register(
this);
740 "# {0} - number of children",
741 "Accounts.ByBINNode.displayName=By BIN ({0})"})
744 =
"SELECT count(distinct SUBSTR(blackboard_attributes.value_text,1,8)) AS BINs "
745 +
" FROM blackboard_artifacts "
746 +
" JOIN blackboard_attributes ON blackboard_artifacts.artifact_id = blackboard_attributes.artifact_id"
747 +
" WHERE blackboard_artifacts.artifact_type_id = " + BlackboardArtifact.ARTIFACT_TYPE.TSK_ACCOUNT.getTypeID()
748 +
" AND blackboard_attributes.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_CARD_NUMBER.getTypeID()
750 try (SleuthkitCase.CaseDbQuery results = skCase.executeQuery(query)) {
751 ResultSet resultSet = results.getResultSet();
752 while (resultSet.next()) {
753 setDisplayName(Bundle.Accounts_ByBINNode_displayName(resultSet.getLong(
"BINs")));
755 }
catch (TskCoreException | SQLException ex) {
756 LOGGER.log(Level.SEVERE,
"Error querying for BINs.", ex);
767 return v.
visit(
this);
772 return getClass().getName();
796 hash = 79 * hash + (int) (this.objID ^ (this.objID >>> 32));
797 hash = 79 * hash + Objects.hashCode(this.keywordSearchDocID);
798 hash = 79 * hash + Objects.hashCode(this.artifactIDs);
799 hash = 79 * hash + (int) (this.hits ^ (this.hits >>> 32));
800 hash = 79 * hash + Objects.hashCode(this.statuses);
812 if (getClass() != obj.getClass()) {
816 if (this.objID != other.
objID) {
819 if (this.hits != other.
hits) {
825 if (!Objects.equals(
this.artifactIDs, other.
artifactIDs)) {
828 if (!Objects.equals(
this.statuses, other.
statuses)) {
838 private final Set<BlackboardArtifact.ReviewStatus>
statuses;
840 private FileWithCCN(
long objID, String solrDocID, List<Long> artifactIDs,
long hits, Set<BlackboardArtifact.ReviewStatus> statuses) {
842 this.keywordSearchDocID = solrDocID;
843 this.artifactIDs = artifactIDs;
845 this.statuses = statuses;
864 return keywordSearchDocID;
911 static <X> List<X> unGroupConcat(String groupConcat, Function<String, X> mapper) {
912 return StringUtils.isBlank(groupConcat) ? Collections.emptyList()
913 : Stream.of(groupConcat.split(
","))
915 .collect(Collectors.toList());
936 "# {0} - raw file name",
937 "# {1} - solr chunk id",
938 "Accounts.FileWithCCNNode.unallocatedSpaceFile.displayName={0}_chunk_{1}"})
940 super(Children.LEAF, Lookups.fixed(lookupContents));
944 : Bundle.Accounts_FileWithCCNNode_unallocatedSpaceFile_displayName(content.getName(), StringUtils.substringAfter(key.
getkeywordSearchDocID(),
"_"));
946 setDisplayName(fileName);
956 return v.
visit(
this);
961 return getClass().getName();
966 "Accounts.FileWithCCNNode.nameProperty.displayName=File",
967 "Accounts.FileWithCCNNode.accountsProperty.displayName=Accounts",
968 "Accounts.FileWithCCNNode.statusProperty.displayName=Status",
969 "Accounts.FileWithCCNNode.noDescription=no description"})
971 Sheet s = super.createSheet();
972 Sheet.Set ss = s.get(Sheet.PROPERTIES);
974 ss = Sheet.createPropertiesSet();
978 ss.put(
new NodeProperty<>(Bundle.Accounts_FileWithCCNNode_nameProperty_displayName(),
979 Bundle.Accounts_FileWithCCNNode_nameProperty_displayName(),
980 Bundle.Accounts_FileWithCCNNode_noDescription(),
982 ss.put(
new NodeProperty<>(Bundle.Accounts_FileWithCCNNode_accountsProperty_displayName(),
983 Bundle.Accounts_FileWithCCNNode_accountsProperty_displayName(),
984 Bundle.Accounts_FileWithCCNNode_noDescription(),
986 ss.put(
new NodeProperty<>(Bundle.Accounts_FileWithCCNNode_statusProperty_displayName(),
987 Bundle.Accounts_FileWithCCNNode_statusProperty_displayName(),
988 Bundle.Accounts_FileWithCCNNode_noDescription(),
990 .map(BlackboardArtifact.ReviewStatus::getDisplayName)
991 .collect(Collectors.joining(
", "))));
998 Action[] actions = super.getActions(context);
999 ArrayList<Action> arrayList =
new ArrayList<>();
1000 arrayList.addAll(Arrays.asList(actions));
1003 }
catch (TskCoreException ex) {
1004 LOGGER.log(Level.SEVERE,
"Error gettung content by id", ex);
1007 arrayList.add(approveActionInstance);
1008 arrayList.add(rejectActionInstance);
1010 return arrayList.toArray(
new Action[arrayList.size()]);
1026 event.artifacts.stream().map(BlackboardArtifact::getArtifactID).forEach(this::refreshKey);
1037 List<Long> list =
new ArrayList<>();
1040 =
"SELECT blackboard_artifacts.artifact_id "
1041 +
" FROM blackboard_artifacts "
1042 +
" JOIN blackboard_attributes ON blackboard_artifacts.artifact_id = blackboard_attributes.artifact_id "
1043 +
" WHERE blackboard_artifacts.artifact_type_id = " + BlackboardArtifact.ARTIFACT_TYPE.TSK_ACCOUNT.getTypeID()
1044 +
" AND blackboard_attributes.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_CARD_NUMBER.getTypeID()
1045 +
" AND blackboard_attributes.value_text >= '" + bin.getBINStart() +
"' AND blackboard_attributes.value_text < '" + (bin.getBINEnd() + 1) +
"'"
1047 +
" ORDER BY blackboard_attributes.value_text";
1048 try (SleuthkitCase.CaseDbQuery results = skCase.executeQuery(query);
1049 ResultSet rs = results.getResultSet();) {
1051 list.add(rs.getLong(
"artifact_id"));
1053 }
catch (TskCoreException | SQLException ex) {
1054 LOGGER.log(Level.SEVERE,
"Error querying for account artifacts.", ex);
1062 if (skCase == null) {
1067 BlackboardArtifact art = skCase.getBlackboardArtifact(artifactID);
1069 }
catch (TskCoreException ex) {
1070 LOGGER.log(Level.WARNING,
"Error creating BlackboardArtifactNode for artifact with ID " + artifactID, ex);
1078 super(Children.LEAF);
1080 setChildren(Children.createLazy(CreditCardNumberFactory::new));
1081 setName(getBinRangeString());
1082 updateDisplayName();
1083 this.setIconBaseWithExtension(
"org/sleuthkit/autopsy/images/bank.png");
1084 reviewStatusBus.register(
this);
1089 updateDisplayName();
1094 updateDisplayName();
1099 =
"SELECT count(blackboard_artifacts.artifact_id ) AS count"
1100 +
" FROM blackboard_artifacts "
1101 +
" JOIN blackboard_attributes ON blackboard_artifacts.artifact_id = blackboard_attributes.artifact_id "
1102 +
" WHERE blackboard_artifacts.artifact_type_id = " + BlackboardArtifact.ARTIFACT_TYPE.TSK_ACCOUNT.getTypeID()
1103 +
" AND blackboard_attributes.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_CARD_NUMBER.getTypeID()
1104 +
" AND blackboard_attributes.value_text >= '" + bin.getBINStart() +
"' AND blackboard_attributes.value_text < '" + (bin.getBINEnd() + 1) +
"'"
1106 try (SleuthkitCase.CaseDbQuery results = skCase.executeQuery(query);
1107 ResultSet rs = results.getResultSet();) {
1109 setDisplayName(getBinRangeString() +
" (" + rs.getLong(
"count") +
")");
1111 }
catch (TskCoreException | SQLException ex) {
1112 LOGGER.log(Level.SEVERE,
"Error querying for account artifacts.", ex);
1119 if (bin.getBINStart() == bin.getBINEnd()) {
1120 return Integer.toString(bin.getBINStart());
1122 return bin.getBINStart() +
"-" + StringUtils.difference(bin.getBINStart() +
"", bin.getBINEnd() +
"");
1133 return v.
visit(
this);
1138 return getClass().getName();
1142 Sheet.Set ss = s.get(Sheet.PROPERTIES);
1144 ss = Sheet.createPropertiesSet();
1151 @NbBundle.Messages({
1152 "Accounts.BINNode.binProperty.displayName=Bank Identifier Number",
1153 "Accounts.BINNode.accountsProperty.displayName=Accounts",
1154 "Accounts.BINNode.cardTypeProperty.displayName=Payment Card Type",
1155 "Accounts.BINNode.schemeProperty.displayName=Credit Card Scheme",
1156 "Accounts.BINNode.brandProperty.displayName=Brand",
1157 "Accounts.BINNode.bankProperty.displayName=Bank",
1158 "Accounts.BINNode.bankCityProperty.displayName=Bank City",
1159 "Accounts.BINNode.bankCountryProperty.displayName=Bank Country",
1160 "Accounts.BINNode.bankPhoneProperty.displayName=Bank Phone #",
1161 "Accounts.BINNode.bankURLProperty.displayName=Bank URL",
1162 "Accounts.BINNode.noDescription=no description"})
1164 Sheet sheet = super.createSheet();
1165 Sheet.Set properties = getPropertySet(sheet);
1167 properties.put(
new NodeProperty<>(Bundle.Accounts_BINNode_binProperty_displayName(),
1168 Bundle.Accounts_BINNode_binProperty_displayName(),
1169 Bundle.Accounts_BINNode_noDescription(),
1170 getBinRangeString()));
1171 properties.put(
new NodeProperty<>(Bundle.Accounts_BINNode_accountsProperty_displayName(),
1172 Bundle.Accounts_BINNode_accountsProperty_displayName(), Bundle.Accounts_BINNode_noDescription(),
1176 if (bin.hasDetails()) {
1177 bin.
getCardType().ifPresent(cardType -> properties.put(
new NodeProperty<>(Bundle.Accounts_BINNode_cardTypeProperty_displayName(),
1178 Bundle.Accounts_BINNode_cardTypeProperty_displayName(), Bundle.Accounts_BINNode_noDescription(),
1180 bin.
getScheme().ifPresent(scheme -> properties.put(
new NodeProperty<>(Bundle.Accounts_BINNode_schemeProperty_displayName(),
1181 Bundle.Accounts_BINNode_schemeProperty_displayName(), Bundle.Accounts_BINNode_noDescription(),
1183 bin.
getBrand().ifPresent(brand -> properties.put(
new NodeProperty<>(Bundle.Accounts_BINNode_brandProperty_displayName(),
1184 Bundle.Accounts_BINNode_brandProperty_displayName(), Bundle.Accounts_BINNode_noDescription(),
1186 bin.
getBankName().ifPresent(bankName -> properties.put(
new NodeProperty<>(Bundle.Accounts_BINNode_bankProperty_displayName(),
1187 Bundle.Accounts_BINNode_bankProperty_displayName(), Bundle.Accounts_BINNode_noDescription(),
1189 bin.
getBankCity().ifPresent(bankCity -> properties.put(
new NodeProperty<>(Bundle.Accounts_BINNode_bankCityProperty_displayName(),
1190 Bundle.Accounts_BINNode_bankCityProperty_displayName(), Bundle.Accounts_BINNode_noDescription(),
1192 bin.
getCountry().ifPresent(country -> properties.put(
new NodeProperty<>(Bundle.Accounts_BINNode_bankCountryProperty_displayName(),
1193 Bundle.Accounts_BINNode_bankCountryProperty_displayName(), Bundle.Accounts_BINNode_noDescription(),
1196 Bundle.Accounts_BINNode_bankPhoneProperty_displayName(), Bundle.Accounts_BINNode_noDescription(),
1198 bin.
getBankURL().ifPresent(url -> properties.put(
new NodeProperty<>(Bundle.Accounts_BINNode_bankURLProperty_displayName(),
1199 Bundle.Accounts_BINNode_bankURLProperty_displayName(), Bundle.Accounts_BINNode_noDescription(),
1216 hash = 97 * hash + this.binEnd;
1217 hash = 97 * hash + this.binStart;
1229 if (getClass() != obj.getClass()) {
1233 if (this.binEnd != other.
binEnd) {
1236 if (this.binStart != other.
binStart) {
1253 this.binRange = binRange;
1254 binStart = binRange.getBINstart();
1255 binEnd = binRange.getBINend();
1260 this.binRange = null;
1277 boolean hasDetails() {
1278 return binRange != null;
1332 super(artifact,
"org/sleuthkit/autopsy/images/credit-card.png");
1333 this.artifact = artifact;
1334 setName(
"" + this.artifact.getArtifactID());
1339 List<Action> actionsList =
new ArrayList<>();
1340 actionsList.addAll(Arrays.asList(super.getActions(context)));
1342 actionsList.add(approveActionInstance);
1343 actionsList.add(rejectActionInstance);
1345 return actionsList.toArray(
new Action[actionsList.size()]);
1350 Sheet sheet = super.createSheet();
1351 Sheet.Set properties = sheet.get(Sheet.PROPERTIES);
1352 if (properties == null) {
1353 properties = Sheet.createPropertiesSet();
1354 sheet.put(properties);
1356 properties.put(
new NodeProperty<>(Bundle.Accounts_FileWithCCNNode_statusProperty_displayName(),
1357 Bundle.Accounts_FileWithCCNNode_statusProperty_displayName(),
1358 Bundle.Accounts_FileWithCCNNode_noDescription(),
1359 artifact.getReviewStatus().getDisplayName()));
1367 @NbBundle.Messages(
"ToggleShowRejected.name=Show Rejected Results")
1369 super(Bundle.ToggleShowRejected_name());
1385 this.newStatus = newStatus;
1394 List<String[]> selectedPaths = Utilities.actionsGlobalContext().lookupAll(Node.class).stream()
1396 String[] createPath;
1402 if (newStatus == BlackboardArtifact.ReviewStatus.REJECTED && showRejected ==
false) {
1403 List<Node> siblings = Arrays.asList(node.getParentNode().getChildren().getNodes());
1404 if (siblings.size() > 1) {
1405 int indexOf = siblings.indexOf(node);
1407 Node sibling = indexOf > 0
1408 ? siblings.get(indexOf - 1)
1409 : siblings.get(Integer.max(indexOf + 1, siblings.size() - 1));
1410 createPath = NodeOp.createPath(sibling, null);
1418 createPath = NodeOp.createPath(node, null);
1421 return Arrays.copyOfRange(createPath, 1, createPath.length);
1423 .filter(Objects::nonNull)
1424 .collect(Collectors.toList());
1427 final Collection<? extends BlackboardArtifact> artifacts = Utilities.actionsGlobalContext().lookupAll(BlackboardArtifact.class);
1428 artifacts.forEach(artifact -> {
1430 skCase.setReviewStatus(artifact, newStatus);
1431 }
catch (TskCoreException ex) {
1432 LOGGER.log(Level.SEVERE,
"Error changing artifact review status.", ex);
1436 reviewStatusBus.post(
new ReviewStatusChangeEvent(artifacts, newStatus));
1438 final DataResultTopComponent directoryListing = DirectoryTreeTopComponent.findInstance().getDirectoryListing();
1439 final Node rootNode = directoryListing.getRootNode();
1442 List<Node> toArray =
new ArrayList<>();
1443 selectedPaths.forEach(path -> {
1445 toArray.add(NodeOp.findPath(rootNode, path));
1446 }
catch (NodeNotFoundException ex) {
1451 directoryListing.setSelectedNodes(toArray.toArray(
new Node[toArray.size()]));
1457 @NbBundle.Messages({
"ApproveAccountsAction.name=Approve Accounts"})
1459 super(Bundle.ApproveAccountsAction_name(), BlackboardArtifact.ReviewStatus.APPROVED);
1465 @NbBundle.Messages({
"RejectAccountsAction.name=Reject Accounts"})
1467 super(Bundle.RejectAccountsAction_name(), BlackboardArtifact.ReviewStatus.REJECTED);
1473 Collection<? extends BlackboardArtifact> artifacts;
1474 BlackboardArtifact.ReviewStatus newReviewStatus;
1476 public ReviewStatusChangeEvent(Collection<? extends BlackboardArtifact> artifacts, BlackboardArtifact.ReviewStatus newReviewStatus) {
1477 this.artifacts = artifacts;
1478 this.newReviewStatus = newReviewStatus;
List< CreditCardViewMode > createKeys()
final BlackboardArtifact.ReviewStatus newStatus
BlackboardArtifact.Type getBlackboardArtifactType()
void removeIngestModuleEventListener(final PropertyChangeListener listener)
Optional< Integer > getNumberLength()
Optional< String > getCountry()
Node[] createNodes(FileWithCCN key)
final BlackboardArtifact artifact
abstract Collection< X > createKeys()
static synchronized IngestManager getInstance()
List< Long > createKeys()
static final Logger LOGGER
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()
final String accountTypeName
Sheet.Set getPropertySet(Sheet s)
final RejectAccounts rejectActionInstance
List< Long > getArtifactIDs()
AccountArtifactNode(BlackboardArtifact artifact)
static synchronized BankIdentificationNumber getBINInfo(int bin)
Action[] getActions(boolean context)
Optional< String > getBankURL()
Node[] createNodes(BinResult key)
final ApproveAccounts approveActionInstance
T visit(DataSourcesNode in)
List< BinResult > createKeys()
void removeIngestJobEventListener(final PropertyChangeListener listener)
Optional< String > getScheme()
Node[] createNodes(String key)
final Set< BlackboardArtifact.ReviewStatus > statuses
Optional< String > getBrand()
Collection< Long > createKeys()
Node[] createNodes(Long t)
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()
String getBinRangeString()
FileWithCCNNode(FileWithCCN key, Content content, Object[] lookupContents)
Action[] getActions(boolean context)
final List< Long > artifactIDs
DefaultAccountTypeNode(String accountTypeName)
Node[] createNodes(Long artifactID)
FileWithCCN(long objID, String solrDocID, List< Long > artifactIDs, long hits, Set< BlackboardArtifact.ReviewStatus > statuses)
List< FileWithCCN > createKeys()
void actionPerformed(ActionEvent e)
Optional< String > getBankCity()
Node[] createNodes(CreditCardViewMode key)
Optional< String > getCardType()
final FileWithCCN fileKey
BinResult(long count, int start, int end)
void addIngestModuleEventListener(final PropertyChangeListener listener)
static Case getCurrentCase()
static void addEventTypeSubscriber(Set< Events > eventTypes, PropertyChangeListener subscriber)
List< String > createKeys()
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)