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;
77 import org.
sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE;
91 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();
126 public Accounts(SleuthkitCase skCase,
long objId) {
128 this.filteringDSObjId = objId;
136 return visitor.
visit(
this);
147 return showRejected ?
" " :
" AND blackboard_artifacts.review_status_id != " + BlackboardArtifact.ReviewStatus.REJECTED.getID() +
" ";
157 if (filteringDSObjId > 0) {
158 return " AND blackboard_artifacts.data_source_obj_id = " + filteringDSObjId +
" ";
197 abstract protected boolean createKeys(List<X> list);
212 super.removeNotify();
227 @NbBundle.Messages({
"Accounts.RootNode.displayName=Accounts"})
233 setDisplayName(Bundle.Accounts_RootNode_displayName());
234 this.setIconBaseWithExtension(
"org/sleuthkit/autopsy/images/accounts.png");
244 return visitor.
visit(
this);
249 return getClass().getName();
262 private final PropertyChangeListener
pcl =
new PropertyChangeListener() {
264 public void propertyChange(PropertyChangeEvent evt) {
265 String eventType = evt.getPropertyName();
282 if (null != eventData
284 reviewStatusBus.post(eventData);
305 if (evt.getNewValue() == null) {
327 String accountTypesInUseQuery
328 =
"SELECT DISTINCT blackboard_attributes.value_text as account_type "
329 +
" FROM blackboard_artifacts "
330 +
" JOIN blackboard_attributes ON blackboard_artifacts.artifact_id = blackboard_attributes.artifact_id "
331 +
" WHERE blackboard_attributes.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ACCOUNT_TYPE.getTypeID()
334 try (SleuthkitCase.CaseDbQuery executeQuery = skCase.executeQuery(accountTypesInUseQuery);
335 ResultSet resultSet = executeQuery.getResultSet()) {
336 while (resultSet.next()) {
337 String accountType = resultSet.getString(
"account_type");
338 list.add(accountType);
340 }
catch (TskCoreException | SQLException ex) {
341 LOGGER.log(Level.SEVERE,
"Error querying for account_types", ex);
350 if (Account.Type.CREDIT_CARD.getTypeName().equals(acountTypeName)) {
355 Account.Type accountType = skCase.getCommunicationsManager().getAccountType(acountTypeName);
357 }
catch (TskCoreException ex) {
358 LOGGER.log(Level.SEVERE,
"Error getting display name for account type. ", ex);
370 super.removeNotify();
392 private final PropertyChangeListener
pcl =
new PropertyChangeListener() {
394 public void propertyChange(PropertyChangeEvent evt) {
395 String eventType = evt.getPropertyName();
412 if (null != eventData
414 reviewStatusBus.post(eventData);
436 if (evt.getNewValue() == null) {
457 super.removeNotify();
463 =
"SELECT blackboard_artifacts.artifact_id "
464 +
" FROM blackboard_artifacts "
465 +
" JOIN blackboard_attributes ON blackboard_artifacts.artifact_id = blackboard_attributes.artifact_id "
466 +
" WHERE blackboard_artifacts.artifact_type_id = " + BlackboardArtifact.ARTIFACT_TYPE.TSK_ACCOUNT.getTypeID()
467 +
" AND blackboard_attributes.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ACCOUNT_TYPE.getTypeID()
468 +
" AND blackboard_attributes.value_text = '" +
accountType.getTypeName() +
"'"
471 try (SleuthkitCase.CaseDbQuery results = skCase.executeQuery(query);
472 ResultSet rs = results.getResultSet();) {
474 list.add(rs.getLong(
"artifact_id"));
476 }
catch (TskCoreException | SQLException ex) {
477 LOGGER.log(Level.SEVERE,
"Error querying for account artifacts.", ex);
487 }
catch (TskCoreException ex) {
488 LOGGER.log(Level.SEVERE,
"Error get black board artifact with id " + t, ex);
525 return visitor.
visit(
this);
530 return getClass().getName();
544 private final PropertyChangeListener pcl =
new PropertyChangeListener() {
546 public void propertyChange(PropertyChangeEvent evt) {
547 String eventType = evt.getPropertyName();
564 if (null != eventData
566 reviewStatusBus.post(eventData);
588 if (evt.getNewValue() == null) {
621 super.removeNotify();
628 protected boolean createKeys(List<CreditCardViewMode> list) {
657 super(Children.create(
new ViewModeFactory(),
true), Lookups.singleton(Account.Type.CREDIT_CARD.getDisplayName()));
658 setName(Account.Type.CREDIT_CARD.getDisplayName());
659 this.setIconBaseWithExtension(
"org/sleuthkit/autopsy/images/credit-cards.png");
669 return visitor.
visit(
this);
674 return getClass().getName();
680 private final PropertyChangeListener pcl =
new PropertyChangeListener() {
682 public void propertyChange(PropertyChangeEvent evt) {
683 String eventType = evt.getPropertyName();
700 if (null != eventData
702 reviewStatusBus.post(eventData);
724 if (evt.getNewValue() == null) {
745 super.removeNotify();
763 =
"SELECT blackboard_artifacts.obj_id,"
764 +
" solr_attribute.value_text AS solr_document_id, ";
765 if (skCase.getDatabaseType().equals(DbType.POSTGRESQL)) {
766 query +=
" string_agg(blackboard_artifacts.artifact_id::character varying, ',') AS artifact_IDs, "
767 +
" string_agg(blackboard_artifacts.review_status_id::character varying, ',') AS review_status_ids, ";
769 query +=
" GROUP_CONCAT(blackboard_artifacts.artifact_id) AS artifact_IDs, "
770 +
" GROUP_CONCAT(blackboard_artifacts.review_status_id) AS review_status_ids, ";
772 query +=
" COUNT( blackboard_artifacts.artifact_id) AS hits "
773 +
" FROM blackboard_artifacts "
774 +
" LEFT JOIN blackboard_attributes as solr_attribute ON blackboard_artifacts.artifact_id = solr_attribute.artifact_id "
775 +
" AND solr_attribute.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD_SEARCH_DOCUMENT_ID.getTypeID()
776 +
" LEFT JOIN blackboard_attributes as account_type ON blackboard_artifacts.artifact_id = account_type.artifact_id "
777 +
" AND account_type.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ACCOUNT_TYPE.getTypeID()
778 +
" AND account_type.value_text = '" + Account.Type.CREDIT_CARD.getTypeName() +
"'"
779 +
" WHERE blackboard_artifacts.artifact_type_id = " + BlackboardArtifact.ARTIFACT_TYPE.TSK_ACCOUNT.getTypeID()
782 +
" GROUP BY blackboard_artifacts.obj_id, solr_document_id "
783 +
" ORDER BY hits DESC ";
784 try (SleuthkitCase.CaseDbQuery results = skCase.executeQuery(query);
785 ResultSet resultSet = results.getResultSet();) {
786 while (resultSet.next()) {
788 resultSet.getLong(
"obj_id"),
789 resultSet.getString(
"solr_document_id"),
790 unGroupConcat(resultSet.getString(
"artifact_IDs"), Long::valueOf),
791 resultSet.getLong(
"hits"),
792 new HashSet<>(unGroupConcat(resultSet.getString(
"review_status_ids"), reviewStatusID -> BlackboardArtifact.ReviewStatus.withID(Integer.valueOf(reviewStatusID))))));
794 }
catch (TskCoreException | SQLException ex) {
795 LOGGER.log(Level.SEVERE,
"Error querying for files with ccn hits.", ex);
805 List<Object> lookupContents =
new ArrayList<>();
807 lookupContents.add(skCase.getBlackboardArtifact(artId));
809 AbstractFile abstractFileById = skCase.getAbstractFileById(key.
getObjID());
810 lookupContents.add(abstractFileById);
811 return new Node[]{
new FileWithCCNNode(key, abstractFileById, lookupContents.toArray())};
812 }
catch (TskCoreException ex) {
813 LOGGER.log(Level.SEVERE,
"Error getting content for file with ccn hits.", ex);
832 this.setIconBaseWithExtension(
"org/sleuthkit/autopsy/images/file-icon.png");
833 reviewStatusBus.register(
this);
837 "# {0} - number of children",
838 "Accounts.ByFileNode.displayName=By File ({0})"})
841 =
"SELECT count(*) FROM ( SELECT count(*) AS documents "
842 +
" FROM blackboard_artifacts "
843 +
" LEFT JOIN blackboard_attributes as solr_attribute ON blackboard_artifacts.artifact_id = solr_attribute.artifact_id "
844 +
" AND solr_attribute.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD_SEARCH_DOCUMENT_ID.getTypeID()
845 +
" LEFT JOIN blackboard_attributes as account_type ON blackboard_artifacts.artifact_id = account_type.artifact_id "
846 +
" AND account_type.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ACCOUNT_TYPE.getTypeID()
847 +
" AND account_type.value_text = '" + Account.Type.CREDIT_CARD.getTypeName() +
"'"
848 +
" WHERE blackboard_artifacts.artifact_type_id = " + BlackboardArtifact.ARTIFACT_TYPE.TSK_ACCOUNT.getTypeID()
851 +
" GROUP BY blackboard_artifacts.obj_id, solr_attribute.value_text ) AS foo";
852 try (SleuthkitCase.CaseDbQuery results = skCase.executeQuery(query);
853 ResultSet resultSet = results.getResultSet();) {
854 while (resultSet.next()) {
855 if (skCase.getDatabaseType().equals(DbType.POSTGRESQL)) {
856 setDisplayName(Bundle.Accounts_ByFileNode_displayName(resultSet.getLong(
"count")));
858 setDisplayName(Bundle.Accounts_ByFileNode_displayName(resultSet.getLong(
"count(*)")));
861 }
catch (TskCoreException | SQLException ex) {
862 LOGGER.log(Level.SEVERE,
"Error querying for files with ccn hits.", ex);
874 return visitor.
visit(
this);
879 return getClass().getName();
895 private final PropertyChangeListener pcl =
new PropertyChangeListener() {
897 public void propertyChange(PropertyChangeEvent evt) {
898 String eventType = evt.getPropertyName();
915 if (null != eventData
917 reviewStatusBus.post(eventData);
938 && (evt.getNewValue() == null)) {
959 super.removeNotify();
977 RangeMap<Integer, BinResult> binRanges = TreeRangeMap.create();
980 =
"SELECT SUBSTR(blackboard_attributes.value_text,1,8) AS BIN, "
981 +
" COUNT(blackboard_artifacts.artifact_id) AS count "
982 +
" FROM blackboard_artifacts "
983 +
" JOIN blackboard_attributes ON blackboard_artifacts.artifact_id = blackboard_attributes.artifact_id"
984 +
" WHERE blackboard_artifacts.artifact_type_id = " + BlackboardArtifact.ARTIFACT_TYPE.TSK_ACCOUNT.getTypeID()
985 +
" AND blackboard_attributes.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_CARD_NUMBER.getTypeID()
990 try (SleuthkitCase.CaseDbQuery results = skCase.executeQuery(query);
991 ResultSet resultSet = results.getResultSet();) {
993 while (resultSet.next()) {
994 final Integer bin = Integer.valueOf(resultSet.getString(
"BIN"));
995 long count = resultSet.getLong(
"count");
998 BinResult previousResult = binRanges.get(bin);
1000 if (previousResult != null) {
1001 binRanges.remove(Range.closed(previousResult.getBINStart(), previousResult.getBINEnd()));
1002 count += previousResult.getCount();
1005 if (binRange == null) {
1006 binRanges.put(Range.closed(bin, bin),
new BinResult(count, bin, bin));
1011 binRanges.asMapOfRanges().values().forEach(list::add);
1012 }
catch (TskCoreException | SQLException ex) {
1013 LOGGER.log(Level.SEVERE,
"Error querying for BINs.", ex);
1021 return new Node[]{
new BINNode(key)};
1034 @NbBundle.Messages(
"Accounts.ByBINNode.name=By BIN")
1036 super(Children.create(
new BINFactory(),
true), Lookups.singleton(Bundle.Accounts_ByBINNode_name()));
1037 setName(Bundle.Accounts_ByBINNode_name());
1038 updateDisplayName();
1039 this.setIconBaseWithExtension(
"org/sleuthkit/autopsy/images/bank.png");
1040 reviewStatusBus.register(
this);
1043 @NbBundle.Messages({
1044 "# {0} - number of children",
1045 "Accounts.ByBINNode.displayName=By BIN ({0})"})
1048 =
"SELECT count(distinct SUBSTR(blackboard_attributes.value_text,1,8)) AS BINs "
1049 +
" FROM blackboard_artifacts "
1050 +
" JOIN blackboard_attributes ON blackboard_artifacts.artifact_id = blackboard_attributes.artifact_id"
1051 +
" WHERE blackboard_artifacts.artifact_type_id = " + BlackboardArtifact.ARTIFACT_TYPE.TSK_ACCOUNT.getTypeID()
1052 +
" AND blackboard_attributes.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_CARD_NUMBER.getTypeID()
1055 try (SleuthkitCase.CaseDbQuery results = skCase.executeQuery(query);
1056 ResultSet resultSet = results.getResultSet();) {
1057 while (resultSet.next()) {
1058 setDisplayName(Bundle.Accounts_ByBINNode_displayName(resultSet.getLong(
"BINs")));
1060 }
catch (TskCoreException | SQLException ex) {
1061 LOGGER.log(Level.SEVERE,
"Error querying for BINs.", ex);
1072 return visitor.
visit(
this);
1077 return getClass().getName();
1082 updateDisplayName();
1087 updateDisplayName();
1101 hash = 79 * hash + (int) (this.objID ^ (this.objID >>> 32));
1102 hash = 79 * hash + Objects.hashCode(this.keywordSearchDocID);
1103 hash = 79 * hash + Objects.hashCode(this.artifactIDs);
1104 hash = 79 * hash + (int) (this.hits ^ (this.hits >>> 32));
1105 hash = 79 * hash + Objects.hashCode(this.statuses);
1117 if (getClass() != obj.getClass()) {
1121 if (this.objID != other.
objID) {
1124 if (this.hits != other.
hits) {
1130 if (!Objects.equals(
this.artifactIDs, other.
artifactIDs)) {
1133 if (!Objects.equals(
this.statuses, other.
statuses)) {
1143 private final Set<BlackboardArtifact.ReviewStatus>
statuses;
1145 private FileWithCCN(
long objID, String solrDocID, List<Long> artifactIDs,
long hits, Set<BlackboardArtifact.ReviewStatus> statuses) {
1147 this.keywordSearchDocID = solrDocID;
1148 this.artifactIDs = artifactIDs;
1150 this.statuses = statuses;
1169 return keywordSearchDocID;
1178 return Collections.unmodifiableList(artifactIDs);
1196 return Collections.unmodifiableSet(statuses);
1216 static <X> List<X> unGroupConcat(String groupConcat, Function<String, X> mapper) {
1217 return StringUtils.isBlank(groupConcat) ? Collections.emptyList()
1218 : Stream.of(groupConcat.split(
","))
1220 .collect(Collectors.toList());
1240 @NbBundle.Messages({
1241 "# {0} - raw file name",
1242 "# {1} - solr chunk id",
1243 "Accounts.FileWithCCNNode.unallocatedSpaceFile.displayName={0}_chunk_{1}"})
1245 super(Children.LEAF, Lookups.fixed(lookupContents));
1249 : Bundle.Accounts_FileWithCCNNode_unallocatedSpaceFile_displayName(content.getName(), StringUtils.substringAfter(key.
getkeywordSearchDocID(),
"_"));
1250 setName(fileName + key.
getObjID());
1251 setDisplayName(fileName);
1261 return visitor.
visit(
this);
1266 return getClass().getName();
1270 @NbBundle.Messages({
1271 "Accounts.FileWithCCNNode.nameProperty.displayName=File",
1272 "Accounts.FileWithCCNNode.accountsProperty.displayName=Accounts",
1273 "Accounts.FileWithCCNNode.statusProperty.displayName=Status",
1274 "Accounts.FileWithCCNNode.noDescription=no description"})
1276 Sheet sheet = super.createSheet();
1277 Sheet.Set propSet = sheet.get(Sheet.PROPERTIES);
1278 if (propSet == null) {
1279 propSet = Sheet.createPropertiesSet();
1283 propSet.put(
new NodeProperty<>(Bundle.Accounts_FileWithCCNNode_nameProperty_displayName(),
1284 Bundle.Accounts_FileWithCCNNode_nameProperty_displayName(),
1285 Bundle.Accounts_FileWithCCNNode_noDescription(),
1287 propSet.put(
new NodeProperty<>(Bundle.Accounts_FileWithCCNNode_accountsProperty_displayName(),
1288 Bundle.Accounts_FileWithCCNNode_accountsProperty_displayName(),
1289 Bundle.Accounts_FileWithCCNNode_noDescription(),
1291 propSet.put(
new NodeProperty<>(Bundle.Accounts_FileWithCCNNode_statusProperty_displayName(),
1292 Bundle.Accounts_FileWithCCNNode_statusProperty_displayName(),
1293 Bundle.Accounts_FileWithCCNNode_noDescription(),
1295 .map(BlackboardArtifact.ReviewStatus::getDisplayName)
1296 .collect(Collectors.joining(
", "))));
1303 Action[] actions = super.getActions(context);
1304 ArrayList<Action> arrayList =
new ArrayList<>();
1305 arrayList.addAll(Arrays.asList(actions));
1308 }
catch (TskCoreException ex) {
1309 LOGGER.log(Level.SEVERE,
"Error gettung content by id", ex);
1312 arrayList.add(approveActionInstance);
1313 arrayList.add(rejectActionInstance);
1315 return arrayList.toArray(
new Action[arrayList.size()]);
1343 =
"SELECT blackboard_artifacts.artifact_id "
1344 +
" FROM blackboard_artifacts "
1345 +
" JOIN blackboard_attributes ON blackboard_artifacts.artifact_id = blackboard_attributes.artifact_id "
1346 +
" WHERE blackboard_artifacts.artifact_type_id = " + BlackboardArtifact.ARTIFACT_TYPE.TSK_ACCOUNT.getTypeID()
1347 +
" AND blackboard_attributes.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_CARD_NUMBER.getTypeID()
1348 +
" AND blackboard_attributes.value_text >= '" + bin.getBINStart() +
"' AND blackboard_attributes.value_text < '" + (bin.getBINEnd() + 1) +
"'"
1351 +
" ORDER BY blackboard_attributes.value_text";
1352 try (SleuthkitCase.CaseDbQuery results = skCase.executeQuery(query);
1353 ResultSet rs = results.getResultSet();) {
1355 list.add(rs.getLong(
"artifact_id"));
1357 }
catch (TskCoreException | SQLException ex) {
1358 LOGGER.log(Level.SEVERE,
"Error querying for account artifacts.", ex);
1366 if (skCase == null) {
1371 BlackboardArtifact art = skCase.getBlackboardArtifact(artifactID);
1373 }
catch (TskCoreException ex) {
1374 LOGGER.log(Level.SEVERE,
"Error creating BlackboardArtifactNode for artifact with ID " + artifactID, ex);
1381 if (bin.getBINStart() == bin.getBINEnd()) {
1382 return Integer.toString(bin.getBINStart());
1384 return bin.getBINStart() +
"-" + StringUtils.difference(bin.getBINStart() +
"", bin.getBINEnd() +
"");
1399 updateDisplayName();
1400 this.setIconBaseWithExtension(
"org/sleuthkit/autopsy/images/bank.png");
1401 reviewStatusBus.register(
this);
1406 updateDisplayName();
1412 updateDisplayName();
1417 =
"SELECT count(blackboard_artifacts.artifact_id ) AS count"
1418 +
" FROM blackboard_artifacts "
1419 +
" JOIN blackboard_attributes ON blackboard_artifacts.artifact_id = blackboard_attributes.artifact_id "
1420 +
" WHERE blackboard_artifacts.artifact_type_id = " + BlackboardArtifact.ARTIFACT_TYPE.TSK_ACCOUNT.getTypeID()
1421 +
" AND blackboard_attributes.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_CARD_NUMBER.getTypeID()
1422 +
" AND blackboard_attributes.value_text >= '" + bin.getBINStart() +
"' AND blackboard_attributes.value_text < '" + (bin.getBINEnd() + 1) +
"'"
1425 try (SleuthkitCase.CaseDbQuery results = skCase.executeQuery(query);
1426 ResultSet resultSet = results.getResultSet();) {
1427 while (resultSet.next()) {
1428 setDisplayName(
getBinRangeString(bin) +
" (" + resultSet.getLong(
"count") +
")");
1430 }
catch (TskCoreException | SQLException ex) {
1431 LOGGER.log(Level.SEVERE,
"Error querying for account artifacts.", ex);
1444 return visitor.
visit(
this);
1449 return getClass().getName();
1453 Sheet.Set sheetSet = sheet.get(Sheet.PROPERTIES);
1454 if (sheetSet == null) {
1455 sheetSet = Sheet.createPropertiesSet();
1456 sheet.put(sheetSet);
1462 @NbBundle.Messages({
1463 "Accounts.BINNode.binProperty.displayName=Bank Identifier Number",
1464 "Accounts.BINNode.accountsProperty.displayName=Accounts",
1465 "Accounts.BINNode.cardTypeProperty.displayName=Payment Card Type",
1466 "Accounts.BINNode.schemeProperty.displayName=Credit Card Scheme",
1467 "Accounts.BINNode.brandProperty.displayName=Brand",
1468 "Accounts.BINNode.bankProperty.displayName=Bank",
1469 "Accounts.BINNode.bankCityProperty.displayName=Bank City",
1470 "Accounts.BINNode.bankCountryProperty.displayName=Bank Country",
1471 "Accounts.BINNode.bankPhoneProperty.displayName=Bank Phone #",
1472 "Accounts.BINNode.bankURLProperty.displayName=Bank URL",
1473 "Accounts.BINNode.noDescription=no description"})
1475 Sheet sheet = super.createSheet();
1476 Sheet.Set properties = getPropertySet(sheet);
1478 properties.put(
new NodeProperty<>(Bundle.Accounts_BINNode_binProperty_displayName(),
1479 Bundle.Accounts_BINNode_binProperty_displayName(),
1480 Bundle.Accounts_BINNode_noDescription(),
1482 properties.put(
new NodeProperty<>(Bundle.Accounts_BINNode_accountsProperty_displayName(),
1483 Bundle.Accounts_BINNode_accountsProperty_displayName(), Bundle.Accounts_BINNode_noDescription(),
1487 if (bin.hasDetails()) {
1488 bin.
getCardType().ifPresent(cardType -> properties.put(
new NodeProperty<>(Bundle.Accounts_BINNode_cardTypeProperty_displayName(),
1489 Bundle.Accounts_BINNode_cardTypeProperty_displayName(), Bundle.Accounts_BINNode_noDescription(),
1491 bin.
getScheme().ifPresent(scheme -> properties.put(
new NodeProperty<>(Bundle.Accounts_BINNode_schemeProperty_displayName(),
1492 Bundle.Accounts_BINNode_schemeProperty_displayName(), Bundle.Accounts_BINNode_noDescription(),
1494 bin.
getBrand().ifPresent(brand -> properties.put(
new NodeProperty<>(Bundle.Accounts_BINNode_brandProperty_displayName(),
1495 Bundle.Accounts_BINNode_brandProperty_displayName(), Bundle.Accounts_BINNode_noDescription(),
1497 bin.
getBankName().ifPresent(bankName -> properties.put(
new NodeProperty<>(Bundle.Accounts_BINNode_bankProperty_displayName(),
1498 Bundle.Accounts_BINNode_bankProperty_displayName(), Bundle.Accounts_BINNode_noDescription(),
1500 bin.
getBankCity().ifPresent(bankCity -> properties.put(
new NodeProperty<>(Bundle.Accounts_BINNode_bankCityProperty_displayName(),
1501 Bundle.Accounts_BINNode_bankCityProperty_displayName(), Bundle.Accounts_BINNode_noDescription(),
1503 bin.
getCountry().ifPresent(country -> properties.put(
new NodeProperty<>(Bundle.Accounts_BINNode_bankCountryProperty_displayName(),
1504 Bundle.Accounts_BINNode_bankCountryProperty_displayName(), Bundle.Accounts_BINNode_noDescription(),
1507 Bundle.Accounts_BINNode_bankPhoneProperty_displayName(), Bundle.Accounts_BINNode_noDescription(),
1509 bin.
getBankURL().ifPresent(url -> properties.put(
new NodeProperty<>(Bundle.Accounts_BINNode_bankURLProperty_displayName(),
1510 Bundle.Accounts_BINNode_bankURLProperty_displayName(), Bundle.Accounts_BINNode_noDescription(),
1517 this.setSheet(createSheet());
1532 hash = 97 * hash + this.binEnd;
1533 hash = 97 * hash + this.binStart;
1545 if (getClass() != obj.getClass()) {
1549 if (this.binEnd != other.
binEnd) {
1552 if (this.binStart != other.
binStart) {
1569 this.binRange = binRange;
1570 binStart = binRange.getBINstart();
1571 binEnd = binRange.getBINend();
1576 this.binRange = null;
1593 boolean hasDetails() {
1594 return binRange != null;
1648 super(artifact,
"org/sleuthkit/autopsy/images/credit-card.png");
1649 this.artifact = artifact;
1650 setName(Long.toString(
this.artifact.getArtifactID()));
1652 reviewStatusBus.register(
this);
1657 List<Action> actionsList =
new ArrayList<>();
1658 actionsList.addAll(Arrays.asList(super.getActions(context)));
1660 actionsList.add(approveActionInstance);
1661 actionsList.add(rejectActionInstance);
1663 return actionsList.toArray(
new Action[actionsList.size()]);
1668 Sheet sheet = super.createSheet();
1669 Sheet.Set properties = sheet.get(Sheet.PROPERTIES);
1670 if (properties == null) {
1671 properties = Sheet.createPropertiesSet();
1672 sheet.put(properties);
1674 properties.put(
new NodeProperty<>(Bundle.Accounts_FileWithCCNNode_statusProperty_displayName(),
1675 Bundle.Accounts_FileWithCCNNode_statusProperty_displayName(),
1676 Bundle.Accounts_FileWithCCNNode_noDescription(),
1677 artifact.getReviewStatus().getDisplayName()));
1686 event.artifacts.stream().filter((art) -> (art.getArtifactID() == this.artifact.getArtifactID())).map((_item) -> {
1688 }).forEachOrdered((_item) -> {
1694 this.setSheet(createSheet());
1702 @NbBundle.Messages(
"ToggleShowRejected.name=Show Rejected Results")
1704 super(Bundle.ToggleShowRejected_name());
1730 this.newStatus = newStatus;
1741 List<String[]> selectedPaths = Utilities.actionsGlobalContext().lookupAll(Node.class).stream()
1743 String[] createPath;
1749 if (newStatus == BlackboardArtifact.ReviewStatus.REJECTED && showRejected ==
false) {
1750 List<Node> siblings = Arrays.asList(node.getParentNode().getChildren().getNodes());
1751 if (siblings.size() > 1) {
1752 int indexOf = siblings.indexOf(node);
1754 Node sibling = indexOf > 0
1755 ? siblings.get(indexOf - 1)
1756 : siblings.get(Integer.max(indexOf + 1, siblings.size() - 1));
1757 createPath = NodeOp.createPath(sibling, null);
1767 createPath = NodeOp.createPath(node, null);
1770 return Arrays.copyOfRange(createPath, 1, createPath.length);
1772 .filter(Objects::nonNull)
1773 .collect(Collectors.toList());
1776 final Collection<? extends BlackboardArtifact> artifacts = Utilities.actionsGlobalContext().lookupAll(BlackboardArtifact.class);
1777 artifacts.forEach(artifact -> {
1779 artifact.setReviewStatus(newStatus);
1780 }
catch (TskCoreException ex) {
1781 LOGGER.log(Level.SEVERE,
"Error changing artifact review status.", ex);
1785 reviewStatusBus.post(
new ReviewStatusChangeEvent(artifacts, newStatus));
1787 final DataResultTopComponent directoryListing = DirectoryTreeTopComponent.findInstance().getDirectoryListing();
1788 final Node rootNode = directoryListing.getRootNode();
1791 List<Node> toArray =
new ArrayList<>();
1792 selectedPaths.forEach(path -> {
1794 toArray.add(NodeOp.findPath(rootNode, path));
1795 }
catch (NodeNotFoundException ex) {
1800 directoryListing.setSelectedNodes(toArray.toArray(
new Node[toArray.size()]));
1806 @NbBundle.Messages({
"ApproveAccountsAction.name=Approve Accounts"})
1808 super(Bundle.ApproveAccountsAction_name(), BlackboardArtifact.ReviewStatus.APPROVED);
1814 @NbBundle.Messages({
"RejectAccountsAction.name=Reject Accounts"})
1816 super(Bundle.RejectAccountsAction_name(), BlackboardArtifact.ReviewStatus.REJECTED);
1822 Collection<? extends BlackboardArtifact> artifacts;
1823 BlackboardArtifact.ReviewStatus newReviewStatus;
1825 ReviewStatusChangeEvent(Collection<? extends BlackboardArtifact> artifacts, BlackboardArtifact.ReviewStatus newReviewStatus) {
1826 this.artifacts = artifacts;
1827 this.newReviewStatus = newReviewStatus;
1838 if (type.equals(Account.Type.CREDIT_CARD)) {
1839 return ICON_BASE_PATH +
"credit-card.png";
1840 }
else if (type.equals(Account.Type.DEVICE)) {
1841 return ICON_BASE_PATH +
"image.png";
1842 }
else if (type.equals(Account.Type.EMAIL)) {
1843 return ICON_BASE_PATH +
"email.png";
1844 }
else if (type.equals(Account.Type.FACEBOOK)) {
1845 return ICON_BASE_PATH +
"facebook.png";
1846 }
else if (type.equals(Account.Type.INSTAGRAM)) {
1847 return ICON_BASE_PATH +
"instagram.png";
1848 }
else if (type.equals(Account.Type.MESSAGING_APP)) {
1849 return ICON_BASE_PATH +
"messaging.png";
1850 }
else if (type.equals(Account.Type.PHONE)) {
1851 return ICON_BASE_PATH +
"phone.png";
1852 }
else if (type.equals(Account.Type.TWITTER)) {
1853 return ICON_BASE_PATH +
"twitter.png";
1854 }
else if (type.equals(Account.Type.WEBSITE)) {
1855 return ICON_BASE_PATH +
"web-file.png";
1856 }
else if (type.equals(Account.Type.WHATSAPP)) {
1857 return ICON_BASE_PATH +
"WhatsApp.png";
1860 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
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
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 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)