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/"; 
 
   93     @NbBundle.Messages(
"AccountsRootNode.name=Accounts")
 
   94     final public static String 
NAME = Bundle.AccountsRootNode_name();
 
  119         return visitor.
visit(
this);
 
  130         return showRejected ? 
" " : 
" AND blackboard_artifacts.review_status_id != " + BlackboardArtifact.ReviewStatus.REJECTED.getID() + 
" "; 
 
  164         abstract protected boolean createKeys(List<X> list);
 
  179             super.removeNotify();
 
  194     @NbBundle.Messages({
"Accounts.RootNode.displayName=Accounts"})
 
  200             setDisplayName(Bundle.Accounts_RootNode_displayName());
 
  201             this.setIconBaseWithExtension(
"org/sleuthkit/autopsy/images/accounts.png");    
 
  211             return visitor.
visit(
this);
 
  216             return getClass().getName();
 
  229         private final PropertyChangeListener 
pcl = 
new PropertyChangeListener() {
 
  231             public void propertyChange(PropertyChangeEvent evt) {
 
  232                 String eventType = evt.getPropertyName();
 
  249                         if (null != eventData
 
  251                             reviewStatusBus.post(eventData);
 
  272                     if (evt.getNewValue() == null) {
 
  294             try (SleuthkitCase.CaseDbQuery executeQuery = skCase.executeQuery(
 
  295                     "SELECT DISTINCT blackboard_attributes.value_text as account_type " 
  296                     + 
" FROM blackboard_attributes " 
  297                     + 
" WHERE blackboard_attributes.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ACCOUNT_TYPE.getTypeID());
 
  298                     ResultSet resultSet = executeQuery.getResultSet()) {
 
  299                 while (resultSet.next()) {
 
  300                     String accountType = resultSet.getString(
"account_type");
 
  301                     list.add(accountType);
 
  303             } 
catch (TskCoreException | SQLException ex) {
 
  304                 LOGGER.log(Level.SEVERE, 
"Error querying for account_types", ex);
 
  313             if (Account.Type.CREDIT_CARD.getTypeName().equals(acountTypeName)) {
 
  318                     Account.Type accountType = skCase.getCommunicationsManager().getAccountType(acountTypeName);
 
  320                 } 
catch (TskCoreException ex) {
 
  321                     LOGGER.log(Level.SEVERE, 
"Error getting display name for account type. ", ex);
 
  333             super.removeNotify();
 
  355         private final PropertyChangeListener 
pcl = 
new PropertyChangeListener() {
 
  357             public void propertyChange(PropertyChangeEvent evt) {
 
  358                 String eventType = evt.getPropertyName();
 
  375                         if (null != eventData
 
  377                             reviewStatusBus.post(eventData);
 
  399                     if (evt.getNewValue() == null) {
 
  420             super.removeNotify();
 
  426                     "SELECT blackboard_artifacts.artifact_id "  
  427                     + 
" FROM blackboard_artifacts "  
  428                     + 
"      JOIN blackboard_attributes ON blackboard_artifacts.artifact_id = blackboard_attributes.artifact_id "  
  429                     + 
" WHERE blackboard_artifacts.artifact_type_id = " + BlackboardArtifact.ARTIFACT_TYPE.TSK_ACCOUNT.getTypeID() 
 
  430                     + 
"     AND blackboard_attributes.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ACCOUNT_TYPE.getTypeID() 
 
  431                     + 
"     AND blackboard_attributes.value_text = '" + 
accountType.getTypeName() + 
"'"  
  433             try (SleuthkitCase.CaseDbQuery results = skCase.executeQuery(query);
 
  434                     ResultSet rs = results.getResultSet();) {
 
  436                     list.add(rs.getLong(
"artifact_id")); 
 
  438             } 
catch (TskCoreException | SQLException ex) {
 
  439                 LOGGER.log(Level.SEVERE, 
"Error querying for account artifacts.", ex); 
 
  449             } 
catch (TskCoreException ex) {
 
  450                 LOGGER.log(Level.SEVERE, 
"Error get black board artifact with id " + t, ex);
 
  487             return visitor.
visit(
this);
 
  492             return getClass().getName();
 
  506         private final PropertyChangeListener pcl = 
new PropertyChangeListener() {
 
  508             public void propertyChange(PropertyChangeEvent evt) {
 
  509                 String eventType = evt.getPropertyName();
 
  526                         if (null != eventData
 
  528                             reviewStatusBus.post(eventData);
 
  550                     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 visitor.
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);
 
  686                     if (evt.getNewValue() == null) {
 
  707             super.removeNotify();
 
  725                     "SELECT blackboard_artifacts.obj_id,"  
  726                     + 
"      solr_attribute.value_text AS solr_document_id, "; 
 
  727             if (skCase.getDatabaseType().equals(DbType.POSTGRESQL)) {
 
  728                 query += 
"      string_agg(blackboard_artifacts.artifact_id::character varying, ',') AS artifact_IDs, "  
  729                         + 
"      string_agg(blackboard_artifacts.review_status_id::character varying, ',') AS review_status_ids, ";
 
  731                 query += 
"      GROUP_CONCAT(blackboard_artifacts.artifact_id) AS artifact_IDs, "  
  732                         + 
"      GROUP_CONCAT(blackboard_artifacts.review_status_id) AS review_status_ids, ";
 
  734             query += 
"      COUNT( blackboard_artifacts.artifact_id) AS hits  "  
  735                     + 
" FROM blackboard_artifacts "  
  736                     + 
" LEFT JOIN blackboard_attributes as solr_attribute ON blackboard_artifacts.artifact_id = solr_attribute.artifact_id "  
  737                     + 
"                                AND solr_attribute.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD_SEARCH_DOCUMENT_ID.getTypeID() 
 
  738                     + 
" LEFT JOIN blackboard_attributes as account_type ON blackboard_artifacts.artifact_id = account_type.artifact_id "  
  739                     + 
"                                AND account_type.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ACCOUNT_TYPE.getTypeID() 
 
  740                     + 
"                                AND account_type.value_text = '" + Account.Type.CREDIT_CARD.getTypeName() + 
"'"  
  741                     + 
" WHERE blackboard_artifacts.artifact_type_id = " + BlackboardArtifact.ARTIFACT_TYPE.TSK_ACCOUNT.getTypeID() 
 
  743                     + 
" GROUP BY blackboard_artifacts.obj_id, solr_document_id "  
  744                     + 
" ORDER BY hits DESC ";  
 
  745             try (SleuthkitCase.CaseDbQuery results = skCase.executeQuery(query);
 
  746                     ResultSet resultSet = results.getResultSet();) {
 
  747                 while (resultSet.next()) {
 
  749                             resultSet.getLong(
"obj_id"), 
 
  750                             resultSet.getString(
"solr_document_id"), 
 
  751                             unGroupConcat(resultSet.getString(
"artifact_IDs"), Long::valueOf), 
 
  752                             resultSet.getLong(
"hits"), 
 
  753                             new HashSet<>(unGroupConcat(resultSet.getString(
"review_status_ids"), reviewStatusID -> BlackboardArtifact.ReviewStatus.withID(Integer.valueOf(reviewStatusID))))));  
 
  755             } 
catch (TskCoreException | SQLException ex) {
 
  756                 LOGGER.log(Level.SEVERE, 
"Error querying for files with ccn hits.", ex); 
 
  766                 List<Object> lookupContents = 
new ArrayList<>();
 
  768                     lookupContents.add(skCase.getBlackboardArtifact(artId));
 
  770                 AbstractFile abstractFileById = skCase.getAbstractFileById(key.
getObjID());
 
  771                 lookupContents.add(abstractFileById);
 
  772                 return new Node[]{
new FileWithCCNNode(key, abstractFileById, lookupContents.toArray())};
 
  773             } 
catch (TskCoreException ex) {
 
  774                 LOGGER.log(Level.SEVERE, 
"Error getting content for file with ccn hits.", ex); 
 
  793             this.setIconBaseWithExtension(
"org/sleuthkit/autopsy/images/file-icon.png");   
 
  794             reviewStatusBus.register(
this);
 
  798             "# {0} - number of children",
 
  799             "Accounts.ByFileNode.displayName=By File ({0})"})
 
  802                     "SELECT count(*) FROM ( SELECT count(*) AS documents " 
  803                     + 
" FROM blackboard_artifacts "  
  804                     + 
" LEFT JOIN blackboard_attributes as solr_attribute ON blackboard_artifacts.artifact_id = solr_attribute.artifact_id "  
  805                     + 
"                                AND solr_attribute.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD_SEARCH_DOCUMENT_ID.getTypeID() 
 
  806                     + 
" LEFT JOIN blackboard_attributes as account_type ON blackboard_artifacts.artifact_id = account_type.artifact_id "  
  807                     + 
"                                AND account_type.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ACCOUNT_TYPE.getTypeID() 
 
  808                     + 
"                                AND account_type.value_text = '" + Account.Type.CREDIT_CARD.getTypeName() + 
"'"  
  809                     + 
" WHERE blackboard_artifacts.artifact_type_id = " + BlackboardArtifact.ARTIFACT_TYPE.TSK_ACCOUNT.getTypeID() 
 
  811                     + 
" GROUP BY blackboard_artifacts.obj_id, solr_attribute.value_text ) AS foo";
 
  812             try (SleuthkitCase.CaseDbQuery results = skCase.executeQuery(query);
 
  813                     ResultSet resultSet = results.getResultSet();) {
 
  814                 while (resultSet.next()) {
 
  815                     if (skCase.getDatabaseType().equals(DbType.POSTGRESQL)) {
 
  816                         setDisplayName(Bundle.Accounts_ByFileNode_displayName(resultSet.getLong(
"count")));
 
  818                         setDisplayName(Bundle.Accounts_ByFileNode_displayName(resultSet.getLong(
"count(*)")));
 
  821             } 
catch (TskCoreException | SQLException ex) {
 
  822                 LOGGER.log(Level.SEVERE, 
"Error querying for files with ccn hits.", ex); 
 
  834             return visitor.
visit(
this);
 
  839             return getClass().getName();
 
  855         private final PropertyChangeListener pcl = 
new PropertyChangeListener() {
 
  857             public void propertyChange(PropertyChangeEvent evt) {
 
  858                 String eventType = evt.getPropertyName();
 
  875                         if (null != eventData
 
  877                             reviewStatusBus.post(eventData);
 
  898                         && (evt.getNewValue() == null)) {
 
  919             super.removeNotify();
 
  937             RangeMap<Integer, BinResult> binRanges = TreeRangeMap.create();
 
  940                     "SELECT SUBSTR(blackboard_attributes.value_text,1,8) AS BIN, "  
  941                     + 
"     COUNT(blackboard_artifacts.artifact_id) AS count "  
  942                     + 
" FROM blackboard_artifacts "  
  943                     + 
"      JOIN blackboard_attributes ON blackboard_artifacts.artifact_id = blackboard_attributes.artifact_id"  
  944                     + 
" WHERE blackboard_artifacts.artifact_type_id = " + BlackboardArtifact.ARTIFACT_TYPE.TSK_ACCOUNT.getTypeID() 
 
  945                     + 
"     AND blackboard_attributes.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_CARD_NUMBER.getTypeID() 
 
  949             try (SleuthkitCase.CaseDbQuery results = skCase.executeQuery(query);
 
  950                     ResultSet resultSet = results.getResultSet();) {
 
  952                 while (resultSet.next()) {
 
  953                     final Integer bin = Integer.valueOf(resultSet.getString(
"BIN"));
 
  954                     long count = resultSet.getLong(
"count");
 
  957                     BinResult previousResult = binRanges.get(bin);
 
  959                     if (previousResult != null) {
 
  960                         binRanges.remove(Range.closed(previousResult.getBINStart(), previousResult.getBINEnd()));
 
  961                         count += previousResult.getCount();
 
  964                     if (binRange == null) {
 
  965                         binRanges.put(Range.closed(bin, bin), 
new BinResult(count, bin, bin));
 
  970                 binRanges.asMapOfRanges().values().forEach(list::add);
 
  971             } 
catch (TskCoreException | SQLException ex) {
 
  972                 LOGGER.log(Level.SEVERE, 
"Error querying for BINs.", ex); 
 
  980             return new Node[]{
new BINNode(key)};
 
  993         @NbBundle.Messages(
"Accounts.ByBINNode.name=By BIN")
 
  995             super(Children.create(
new BINFactory(), 
true), Lookups.singleton(Bundle.Accounts_ByBINNode_name()));
 
  996             setName(Bundle.Accounts_ByBINNode_name());  
 
  998             this.setIconBaseWithExtension(
"org/sleuthkit/autopsy/images/bank.png");   
 
  999             reviewStatusBus.register(
this);
 
 1002         @NbBundle.Messages({
 
 1003             "# {0} - number of children",
 
 1004             "Accounts.ByBINNode.displayName=By BIN ({0})"})
 
 1007                     "SELECT count(distinct SUBSTR(blackboard_attributes.value_text,1,8)) AS BINs "  
 1008                     + 
" FROM blackboard_artifacts "  
 1009                     + 
"      JOIN blackboard_attributes ON blackboard_artifacts.artifact_id = blackboard_attributes.artifact_id"  
 1010                     + 
" WHERE blackboard_artifacts.artifact_type_id = " + BlackboardArtifact.ARTIFACT_TYPE.TSK_ACCOUNT.getTypeID() 
 
 1011                     + 
"     AND blackboard_attributes.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_CARD_NUMBER.getTypeID() 
 
 1013             try (SleuthkitCase.CaseDbQuery results = skCase.executeQuery(query);
 
 1014                     ResultSet resultSet = results.getResultSet();) {
 
 1015                 while (resultSet.next()) {
 
 1016                     setDisplayName(Bundle.Accounts_ByBINNode_displayName(resultSet.getLong(
"BINs")));
 
 1018             } 
catch (TskCoreException | SQLException ex) {
 
 1019                 LOGGER.log(Level.SEVERE, 
"Error querying for BINs.", ex); 
 
 1030             return visitor.
visit(
this);
 
 1035             return getClass().getName();
 
 1040             updateDisplayName();
 
 1045             updateDisplayName();
 
 1059             hash = 79 * hash + (int) (this.objID ^ (this.objID >>> 32));
 
 1060             hash = 79 * hash + Objects.hashCode(this.keywordSearchDocID);
 
 1061             hash = 79 * hash + Objects.hashCode(this.artifactIDs);
 
 1062             hash = 79 * hash + (int) (this.hits ^ (this.hits >>> 32));
 
 1063             hash = 79 * hash + Objects.hashCode(this.statuses);
 
 1075             if (getClass() != obj.getClass()) {
 
 1079             if (this.objID != other.
objID) {
 
 1082             if (this.hits != other.
hits) {
 
 1088             if (!Objects.equals(
this.artifactIDs, other.
artifactIDs)) {
 
 1091             if (!Objects.equals(
this.statuses, other.
statuses)) {
 
 1101         private final Set<BlackboardArtifact.ReviewStatus> 
statuses;
 
 1103         private FileWithCCN(
long objID, String solrDocID, List<Long> artifactIDs, 
long hits, Set<BlackboardArtifact.ReviewStatus> statuses) {
 
 1105             this.keywordSearchDocID = solrDocID;
 
 1106             this.artifactIDs = artifactIDs;
 
 1108             this.statuses = statuses;
 
 1127             return keywordSearchDocID;
 
 1174     static <X> List<X> unGroupConcat(String groupConcat, Function<String, X> mapper) {
 
 1175         return StringUtils.isBlank(groupConcat) ? Collections.emptyList()
 
 1176                 : Stream.of(groupConcat.split(
",")) 
 
 1178                         .collect(Collectors.toList());
 
 1198         @NbBundle.Messages({
 
 1199             "# {0} - raw file name",
 
 1200             "# {1} - solr chunk id",
 
 1201             "Accounts.FileWithCCNNode.unallocatedSpaceFile.displayName={0}_chunk_{1}"})
 
 1203             super(Children.LEAF, Lookups.fixed(lookupContents));
 
 1207                     : Bundle.Accounts_FileWithCCNNode_unallocatedSpaceFile_displayName(content.getName(), StringUtils.substringAfter(key.
getkeywordSearchDocID(), 
"_")); 
 
 1208             setName(fileName + key.
getObjID());
 
 1209             setDisplayName(fileName);
 
 1219             return visitor.
visit(
this);
 
 1224             return getClass().getName();
 
 1228         @NbBundle.Messages({
 
 1229             "Accounts.FileWithCCNNode.nameProperty.displayName=File",
 
 1230             "Accounts.FileWithCCNNode.accountsProperty.displayName=Accounts",
 
 1231             "Accounts.FileWithCCNNode.statusProperty.displayName=Status",
 
 1232             "Accounts.FileWithCCNNode.noDescription=no description"})
 
 1234             Sheet sheet = super.createSheet();
 
 1235             Sheet.Set propSet = sheet.get(Sheet.PROPERTIES);
 
 1236             if (propSet == null) {
 
 1237                 propSet = Sheet.createPropertiesSet();
 
 1241             propSet.put(
new NodeProperty<>(Bundle.Accounts_FileWithCCNNode_nameProperty_displayName(),
 
 1242                     Bundle.Accounts_FileWithCCNNode_nameProperty_displayName(),
 
 1243                     Bundle.Accounts_FileWithCCNNode_noDescription(),
 
 1245             propSet.put(
new NodeProperty<>(Bundle.Accounts_FileWithCCNNode_accountsProperty_displayName(),
 
 1246                     Bundle.Accounts_FileWithCCNNode_accountsProperty_displayName(),
 
 1247                     Bundle.Accounts_FileWithCCNNode_noDescription(),
 
 1249             propSet.put(
new NodeProperty<>(Bundle.Accounts_FileWithCCNNode_statusProperty_displayName(),
 
 1250                     Bundle.Accounts_FileWithCCNNode_statusProperty_displayName(),
 
 1251                     Bundle.Accounts_FileWithCCNNode_noDescription(),
 
 1253                             .map(BlackboardArtifact.ReviewStatus::getDisplayName)
 
 1254                             .collect(Collectors.joining(
", ")))); 
 
 1261             Action[] actions = super.getActions(context);
 
 1262             ArrayList<Action> arrayList = 
new ArrayList<>();
 
 1263             arrayList.addAll(Arrays.asList(actions));
 
 1266             } 
catch (TskCoreException ex) {
 
 1267                 LOGGER.log(Level.SEVERE, 
"Error gettung content by id", ex);
 
 1270             arrayList.add(approveActionInstance);
 
 1271             arrayList.add(rejectActionInstance);
 
 1273             return arrayList.toArray(
new Action[arrayList.size()]);
 
 1301                     "SELECT blackboard_artifacts.artifact_id "  
 1302                     + 
" FROM blackboard_artifacts "  
 1303                     + 
"      JOIN blackboard_attributes ON blackboard_artifacts.artifact_id = blackboard_attributes.artifact_id "  
 1304                     + 
" WHERE blackboard_artifacts.artifact_type_id = " + BlackboardArtifact.ARTIFACT_TYPE.TSK_ACCOUNT.getTypeID() 
 
 1305                     + 
"     AND blackboard_attributes.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_CARD_NUMBER.getTypeID() 
 
 1306                     + 
"     AND blackboard_attributes.value_text >= '" + bin.getBINStart() + 
"' AND  blackboard_attributes.value_text < '" + (bin.getBINEnd() + 1) + 
"'"  
 1308                     + 
" ORDER BY blackboard_attributes.value_text"; 
 
 1309             try (SleuthkitCase.CaseDbQuery results = skCase.executeQuery(query);
 
 1310                     ResultSet rs = results.getResultSet();) {
 
 1312                     list.add(rs.getLong(
"artifact_id")); 
 
 1314             } 
catch (TskCoreException | SQLException ex) {
 
 1315                 LOGGER.log(Level.SEVERE, 
"Error querying for account artifacts.", ex); 
 
 1323             if (skCase == null) {
 
 1328                 BlackboardArtifact art = skCase.getBlackboardArtifact(artifactID);
 
 1330             } 
catch (TskCoreException ex) {
 
 1331                 LOGGER.log(Level.SEVERE, 
"Error creating BlackboardArtifactNode for artifact with ID " + artifactID, ex);   
 
 1338         if (bin.getBINStart() == bin.getBINEnd()) {
 
 1339             return Integer.toString(bin.getBINStart());
 
 1341             return bin.getBINStart() + 
"-" + StringUtils.difference(bin.getBINStart() + 
"", bin.getBINEnd() + 
"");
 
 1354             updateDisplayName();
 
 1355             this.setIconBaseWithExtension(
"org/sleuthkit/autopsy/images/bank.png");   
 
 1356             reviewStatusBus.register(
this);
 
 1361             updateDisplayName();
 
 1367             updateDisplayName();
 
 1372                     "SELECT count(blackboard_artifacts.artifact_id ) AS count"  
 1373                     + 
" FROM blackboard_artifacts "  
 1374                     + 
"      JOIN blackboard_attributes ON blackboard_artifacts.artifact_id = blackboard_attributes.artifact_id "  
 1375                     + 
" WHERE blackboard_artifacts.artifact_type_id = " + BlackboardArtifact.ARTIFACT_TYPE.TSK_ACCOUNT.getTypeID() 
 
 1376                     + 
"     AND blackboard_attributes.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_CARD_NUMBER.getTypeID() 
 
 1377                     + 
"     AND blackboard_attributes.value_text >= '" + bin.getBINStart() + 
"' AND  blackboard_attributes.value_text < '" + (bin.getBINEnd() + 1) + 
"'"  
 1379             try (SleuthkitCase.CaseDbQuery results = skCase.executeQuery(query);
 
 1380                     ResultSet resultSet = results.getResultSet();) {
 
 1381                 while (resultSet.next()) {
 
 1382                     setDisplayName(
getBinRangeString(bin) + 
" (" + resultSet.getLong(
"count") + 
")"); 
 
 1384             } 
catch (TskCoreException | SQLException ex) {
 
 1385                 LOGGER.log(Level.SEVERE, 
"Error querying for account artifacts.", ex); 
 
 1398             return visitor.
visit(
this);
 
 1403             return getClass().getName();
 
 1407             Sheet.Set sheetSet = sheet.get(Sheet.PROPERTIES);
 
 1408             if (sheetSet == null) {
 
 1409                 sheetSet = Sheet.createPropertiesSet();
 
 1410                 sheet.put(sheetSet);
 
 1416         @NbBundle.Messages({
 
 1417             "Accounts.BINNode.binProperty.displayName=Bank Identifier Number",
 
 1418             "Accounts.BINNode.accountsProperty.displayName=Accounts",
 
 1419             "Accounts.BINNode.cardTypeProperty.displayName=Payment Card Type",
 
 1420             "Accounts.BINNode.schemeProperty.displayName=Credit Card Scheme",
 
 1421             "Accounts.BINNode.brandProperty.displayName=Brand",
 
 1422             "Accounts.BINNode.bankProperty.displayName=Bank",
 
 1423             "Accounts.BINNode.bankCityProperty.displayName=Bank City",
 
 1424             "Accounts.BINNode.bankCountryProperty.displayName=Bank Country",
 
 1425             "Accounts.BINNode.bankPhoneProperty.displayName=Bank Phone #",
 
 1426             "Accounts.BINNode.bankURLProperty.displayName=Bank URL",
 
 1427             "Accounts.BINNode.noDescription=no description"})
 
 1429             Sheet sheet = super.createSheet();
 
 1430             Sheet.Set properties = getPropertySet(sheet);
 
 1432             properties.put(
new NodeProperty<>(Bundle.Accounts_BINNode_binProperty_displayName(),
 
 1433                     Bundle.Accounts_BINNode_binProperty_displayName(),
 
 1434                     Bundle.Accounts_BINNode_noDescription(),
 
 1436             properties.put(
new NodeProperty<>(Bundle.Accounts_BINNode_accountsProperty_displayName(),
 
 1437                     Bundle.Accounts_BINNode_accountsProperty_displayName(), Bundle.Accounts_BINNode_noDescription(),
 
 1441             if (bin.hasDetails()) {
 
 1442                 bin.
getCardType().ifPresent(cardType -> properties.put(
new NodeProperty<>(Bundle.Accounts_BINNode_cardTypeProperty_displayName(),
 
 1443                         Bundle.Accounts_BINNode_cardTypeProperty_displayName(), Bundle.Accounts_BINNode_noDescription(),
 
 1445                 bin.
getScheme().ifPresent(scheme -> properties.put(
new NodeProperty<>(Bundle.Accounts_BINNode_schemeProperty_displayName(),
 
 1446                         Bundle.Accounts_BINNode_schemeProperty_displayName(), Bundle.Accounts_BINNode_noDescription(),
 
 1448                 bin.
getBrand().ifPresent(brand -> properties.put(
new NodeProperty<>(Bundle.Accounts_BINNode_brandProperty_displayName(),
 
 1449                         Bundle.Accounts_BINNode_brandProperty_displayName(), Bundle.Accounts_BINNode_noDescription(),
 
 1451                 bin.
getBankName().ifPresent(bankName -> properties.put(
new NodeProperty<>(Bundle.Accounts_BINNode_bankProperty_displayName(),
 
 1452                         Bundle.Accounts_BINNode_bankProperty_displayName(), Bundle.Accounts_BINNode_noDescription(),
 
 1454                 bin.
getBankCity().ifPresent(bankCity -> properties.put(
new NodeProperty<>(Bundle.Accounts_BINNode_bankCityProperty_displayName(),
 
 1455                         Bundle.Accounts_BINNode_bankCityProperty_displayName(), Bundle.Accounts_BINNode_noDescription(),
 
 1457                 bin.
getCountry().ifPresent(country -> properties.put(
new NodeProperty<>(Bundle.Accounts_BINNode_bankCountryProperty_displayName(),
 
 1458                         Bundle.Accounts_BINNode_bankCountryProperty_displayName(), Bundle.Accounts_BINNode_noDescription(),
 
 1461                         Bundle.Accounts_BINNode_bankPhoneProperty_displayName(), Bundle.Accounts_BINNode_noDescription(),
 
 1463                 bin.
getBankURL().ifPresent(url -> properties.put(
new NodeProperty<>(Bundle.Accounts_BINNode_bankURLProperty_displayName(),
 
 1464                         Bundle.Accounts_BINNode_bankURLProperty_displayName(), Bundle.Accounts_BINNode_noDescription(),
 
 1471             this.setSheet(createSheet());
 
 1486             hash = 97 * hash + this.binEnd;
 
 1487             hash = 97 * hash + this.binStart;
 
 1499             if (getClass() != obj.getClass()) {
 
 1503             if (this.binEnd != other.
binEnd) {
 
 1506             if (this.binStart != other.
binStart) {
 
 1521             this.binRange = binRange;
 
 1522             binStart = binRange.getBINstart();
 
 1523             binEnd = binRange.getBINend();
 
 1528             this.binRange = null;
 
 1545         boolean hasDetails() {
 
 1546             return binRange != null;
 
 1600             super(artifact, 
"org/sleuthkit/autopsy/images/credit-card.png");   
 
 1601             this.artifact = artifact;
 
 1602             setName(Long.toString(
this.artifact.getArtifactID()));
 
 1604             reviewStatusBus.register(
this);
 
 1609             List<Action> actionsList = 
new ArrayList<>();
 
 1610             actionsList.addAll(Arrays.asList(super.getActions(context)));
 
 1612             actionsList.add(approveActionInstance);
 
 1613             actionsList.add(rejectActionInstance);
 
 1615             return actionsList.toArray(
new Action[actionsList.size()]);
 
 1620             Sheet sheet = super.createSheet();
 
 1621             Sheet.Set properties = sheet.get(Sheet.PROPERTIES);
 
 1622             if (properties == null) {
 
 1623                 properties = Sheet.createPropertiesSet();
 
 1624                 sheet.put(properties);
 
 1626             properties.put(
new NodeProperty<>(Bundle.Accounts_FileWithCCNNode_statusProperty_displayName(),
 
 1627                     Bundle.Accounts_FileWithCCNNode_statusProperty_displayName(),
 
 1628                     Bundle.Accounts_FileWithCCNNode_noDescription(),
 
 1629                     artifact.getReviewStatus().getDisplayName()));
 
 1638             event.artifacts.stream().filter((art) -> (art.getArtifactID() == this.artifact.getArtifactID())).map((_item) -> {
 
 1640             }).forEachOrdered((_item) -> {
 
 1646             this.setSheet(createSheet());
 
 1653         @NbBundle.Messages(
"ToggleShowRejected.name=Show Rejected Results")
 
 1655             super(Bundle.ToggleShowRejected_name());
 
 1671             this.newStatus = newStatus;
 
 1680             List<String[]> selectedPaths = Utilities.actionsGlobalContext().lookupAll(Node.class).stream()
 
 1682                         String[] createPath;
 
 1688                         if (newStatus == BlackboardArtifact.ReviewStatus.REJECTED && showRejected == 
false) {
 
 1689                             List<Node> siblings = Arrays.asList(node.getParentNode().getChildren().getNodes());
 
 1690                             if (siblings.size() > 1) {
 
 1691                                 int indexOf = siblings.indexOf(node);
 
 1693                                 Node sibling = indexOf > 0
 
 1694                                         ? siblings.get(indexOf - 1)
 
 1695                                         : siblings.get(Integer.max(indexOf + 1, siblings.size() - 1));
 
 1696                                 createPath = NodeOp.createPath(sibling, null);
 
 1704                             createPath = NodeOp.createPath(node, null);
 
 1707                         return Arrays.copyOfRange(createPath, 1, createPath.length);
 
 1709                     .filter(Objects::nonNull)
 
 1710                     .collect(Collectors.toList());
 
 1713             final Collection<? extends BlackboardArtifact> artifacts = Utilities.actionsGlobalContext().lookupAll(BlackboardArtifact.class);
 
 1714             artifacts.forEach(artifact -> {
 
 1716                     artifact.setReviewStatus(newStatus);
 
 1717                 } 
catch (TskCoreException ex) {
 
 1718                     LOGGER.log(Level.SEVERE, 
"Error changing artifact review status.", ex); 
 
 1722             reviewStatusBus.post(
new ReviewStatusChangeEvent(artifacts, newStatus));
 
 1724             final DataResultTopComponent directoryListing = DirectoryTreeTopComponent.findInstance().getDirectoryListing();
 
 1725             final Node rootNode = directoryListing.getRootNode();
 
 1728             List<Node> toArray = 
new ArrayList<>();
 
 1729             selectedPaths.forEach(path -> {
 
 1731                     toArray.add(NodeOp.findPath(rootNode, path));
 
 1732                 } 
catch (NodeNotFoundException ex) { 
 
 1737             directoryListing.setSelectedNodes(toArray.toArray(
new Node[toArray.size()]));
 
 1743         @NbBundle.Messages({
"ApproveAccountsAction.name=Approve Accounts"})
 
 1745             super(Bundle.ApproveAccountsAction_name(), BlackboardArtifact.ReviewStatus.APPROVED);
 
 1751         @NbBundle.Messages({
"RejectAccountsAction.name=Reject Accounts"})
 
 1753             super(Bundle.RejectAccountsAction_name(), BlackboardArtifact.ReviewStatus.REJECTED);
 
 1759         Collection<? extends BlackboardArtifact> artifacts;
 
 1760         BlackboardArtifact.ReviewStatus newReviewStatus;
 
 1762         ReviewStatusChangeEvent(Collection<? extends BlackboardArtifact> artifacts, BlackboardArtifact.ReviewStatus newReviewStatus) {
 
 1763             this.artifacts = artifacts;
 
 1764             this.newReviewStatus = newReviewStatus;
 
 1775         if (type.equals(Account.Type.CREDIT_CARD)) {
 
 1776             return ICON_BASE_PATH + 
"credit-card.png";
 
 1777         } 
else if (type.equals(Account.Type.DEVICE)) {
 
 1778             return ICON_BASE_PATH + 
"image.png";
 
 1779         } 
else if (type.equals(Account.Type.EMAIL)) {
 
 1780             return ICON_BASE_PATH + 
"email.png";
 
 1781         } 
else if (type.equals(Account.Type.FACEBOOK)) {
 
 1782             return ICON_BASE_PATH + 
"facebook.png";
 
 1783         } 
else if (type.equals(Account.Type.INSTAGRAM)) {
 
 1784             return ICON_BASE_PATH + 
"instagram.png";
 
 1785         } 
else if (type.equals(Account.Type.MESSAGING_APP)) {
 
 1786             return ICON_BASE_PATH + 
"messaging.png";
 
 1787         } 
else if (type.equals(Account.Type.PHONE)) {
 
 1788             return ICON_BASE_PATH + 
"phone.png";
 
 1789         } 
else if (type.equals(Account.Type.TWITTER)) {
 
 1790             return ICON_BASE_PATH + 
"twitter.png";
 
 1791         } 
else if (type.equals(Account.Type.WEBSITE)) {
 
 1792             return ICON_BASE_PATH + 
"web-file.png";
 
 1793         } 
else if (type.equals(Account.Type.WHATSAPP)) {
 
 1794             return ICON_BASE_PATH + 
"WhatsApp.png";
 
 1797             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()
 
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()
 
static Case getOpenCase()
 
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()
 
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)
 
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)
 
Optional< String > getScheme()
 
Optional< String > getBankName()
 
Optional< String > getBankPhoneNumber()
 
Optional< String > getCardType()
 
Accounts(SleuthkitCase skCase)