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)