From a39419393da3bf4f331b64b5d11e9aa52fd06adc Mon Sep 17 00:00:00 2001 From: millmanorama Date: Mon, 26 Sep 2016 14:04:41 +0200 Subject: [PATCH] introduce datamodel._private package and move some interfaces and classes there; create basic generic support for other account types; some renaming for clarity --- .../datamodel/AbstractContentChildren.java | 5 + .../sleuthkit/autopsy/datamodel/BINMap.java | 98 ------ .../datamodel/BlackboardArtifactNode.java | 42 +-- .../autopsy/datamodel/Bundle.properties | 11 - .../autopsy/datamodel/CreditCards.java | 171 +++++++++++ .../autopsy/datamodel/DataSources.java | 3 + .../autopsy/datamodel/DeletedContent.java | 2 + .../datamodel/DisplayableItemNodeVisitor.java | 7 + .../autopsy/datamodel/EmailExtracted.java | 2 + .../autopsy/datamodel/ExtractedContent.java | 2 + .../sleuthkit/autopsy/datamodel/FileSize.java | 2 + .../autopsy/datamodel/FileTypeNode.java | 1 + .../autopsy/datamodel/FileTypesNode.java | 1 + .../autopsy/datamodel/HashsetHits.java | 2 + .../autopsy/datamodel/InterestingHits.java | 2 + .../autopsy/datamodel/KeywordHits.java | 2 + .../datamodel/RecentFilesChildren.java | 1 + .../datamodel/RecentFilesFilterChildren.java | 2 +- .../datamodel/RecentFilesFilterNode.java | 2 +- .../sleuthkit/autopsy/datamodel/Reports.java | 2 + .../sleuthkit/autopsy/datamodel/Results.java | 2 + .../autopsy/datamodel/ResultsNode.java | 1 + .../org/sleuthkit/autopsy/datamodel/Tags.java | 2 + .../sleuthkit/autopsy/datamodel/Views.java | 2 + .../autopsy/datamodel/ViewsNode.java | 1 + .../datamodel/{ => _private}/Accounts.java | 289 +++++++++--------- .../{ => _private}/AutopsyItemVisitor.java | 17 +- .../{ => _private}/AutopsyVisitableItem.java | 5 +- .../datamodel/_private/Bundle.properties | 12 + .../FileTypeExtensionFilters.java | 34 +-- .../datamodel/{ => _private}/RecentFiles.java | 4 +- .../directorytree/DataResultFilterNode.java | 2 +- .../DirectoryTreeTopComponent.java | 2 +- .../keywordsearch/ExtractedContentViewer.java | 2 +- .../keywordsearch/TermComponentQuery.java | 25 +- 35 files changed, 444 insertions(+), 316 deletions(-) delete mode 100644 Core/src/org/sleuthkit/autopsy/datamodel/BINMap.java create mode 100644 Core/src/org/sleuthkit/autopsy/datamodel/CreditCards.java rename Core/src/org/sleuthkit/autopsy/datamodel/{ => _private}/Accounts.java (85%) rename Core/src/org/sleuthkit/autopsy/datamodel/{ => _private}/AutopsyItemVisitor.java (85%) rename Core/src/org/sleuthkit/autopsy/datamodel/{ => _private}/AutopsyVisitableItem.java (91%) create mode 100644 Core/src/org/sleuthkit/autopsy/datamodel/_private/Bundle.properties rename Core/src/org/sleuthkit/autopsy/datamodel/{ => _private}/FileTypeExtensionFilters.java (90%) rename Core/src/org/sleuthkit/autopsy/datamodel/{ => _private}/RecentFiles.java (96%) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractContentChildren.java b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractContentChildren.java index 701367e9ba..86f247395e 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractContentChildren.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractContentChildren.java @@ -18,6 +18,11 @@ */ package org.sleuthkit.autopsy.datamodel; +import org.sleuthkit.autopsy.datamodel._private.Accounts; +import org.sleuthkit.autopsy.datamodel._private.FileTypeExtensionFilters; +import org.sleuthkit.autopsy.datamodel._private.RecentFiles; +import org.sleuthkit.autopsy.datamodel._private.AutopsyItemVisitor; +import org.sleuthkit.autopsy.datamodel._private.AutopsyVisitableItem; import org.openide.nodes.AbstractNode; import org.openide.nodes.Children.Keys; import org.openide.nodes.Node; diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/BINMap.java b/Core/src/org/sleuthkit/autopsy/datamodel/BINMap.java deleted file mode 100644 index 5a4f99154e..0000000000 --- a/Core/src/org/sleuthkit/autopsy/datamodel/BINMap.java +++ /dev/null @@ -1,98 +0,0 @@ -package org.sleuthkit.autopsy.datamodel; - -import com.google.common.collect.Range; -import com.google.common.collect.RangeMap; -import com.google.common.collect.TreeRangeMap; -import java.io.IOException; -import java.io.InputStreamReader; -import java.util.logging.Level; -import java.util.logging.Logger; -import javax.annotation.concurrent.GuardedBy; -import org.apache.commons.csv.CSVFormat; -import org.apache.commons.csv.CSVParser; -import org.apache.commons.csv.CSVRecord; -import org.apache.commons.lang3.StringUtils; -import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil; - -public class BINMap { - - private static final Logger LOGGER = Logger.getLogger(BINMap.class.getName()); - /** - * Range Map from a (ranges of) B/IINs to data model object with details of - * the B/IIN, ie, bank name, phone, url, visa/amex/mastercard/..., - */ - @GuardedBy("Accounts.class") - private final static RangeMap iinRanges = TreeRangeMap.create(); - - /** - * Flag for if we have loaded the IINs from the file already. - */ - @GuardedBy("Accounts.class") - private static boolean iinsLoaded = false; - - /** - * Load the IIN range information from disk. If the map has already been - * initialized, don't load again. - */ - synchronized private static void loadIINRanges() { - if (iinsLoaded == false) { - try { - InputStreamReader in = new InputStreamReader(Accounts.class.getResourceAsStream("ranges.csv")); //NON-NLS - CSVParser rangesParser = CSVFormat.RFC4180.withFirstRecordAsHeader().parse(in); - - //parse each row and add to range map - for (CSVRecord record : rangesParser) { - - /** - * Because ranges.csv allows both 6 and (the newer) 8 digit - * IINs, but we need a consistent length for the range map, - * we pad all the numbers out to 8 digits - */ - String start = StringUtils.rightPad(record.get("iin_start"), 8, "0"); //pad start with 0's //NON-NLS - - //if there is no end listed, use start, since ranges will be closed. - String end = StringUtils.defaultIfBlank(record.get("iin_end"), start); //NON-NLS - end = StringUtils.rightPad(end, 8, "99"); //pad end with 9's //NON-NLS - - final String numberLength = record.get("number_length"); //NON-NLS - - try { - Accounts.IINRange iinRange = new Accounts.IINRange(Integer.parseInt(start), - Integer.parseInt(end), - StringUtils.isBlank(numberLength) ? null : Integer.valueOf(numberLength), - record.get("scheme"), //NON-NLS - record.get("brand"), //NON-NLS - record.get("type"), //NON-NLS - record.get("country"), //NON-NLS - record.get("bank_name"), //NON-NLS - record.get("bank_url"), //NON-NLS - record.get("bank_phone"), //NON-NLS - record.get("bank_city")); //NON-NLS - - iinRanges.put(Range.closed(iinRange.getIINstart(), iinRange.getIINend()), iinRange); - - } catch (NumberFormatException numberFormatException) { - LOGGER.log(Level.WARNING, "Failed to parse IIN range: " + record.toString(), numberFormatException); //NON-NLS - } - iinsLoaded = true; - } - } catch (IOException ex) { - LOGGER.log(Level.WARNING, "Failed to load IIN ranges form ranges.csv", ex); //NON-NLS - MessageNotifyUtil.Notify.warn("Credit Card Number Discovery", "There was an error loading Bank Identification Number information. Accounts will not have their BINs identified."); - } - } - } - - /** - * Get an IINInfo object with details about the given IIN - * - * @param iin the IIN to get details of. - * - * @return - */ - synchronized static public Accounts.IINInfo getIINInfo(int iin) { - loadIINRanges(); - return iinRanges.get(iin); - } - -} diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java index fbc17420b2..788d6969ec 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java @@ -185,13 +185,13 @@ public class BlackboardArtifactNode extends DisplayableItemNode { ss = Sheet.createPropertiesSet(); s.put(ss); } - final String NO_DESCR = NbBundle.getMessage(this.getClass(), "BlackboardArtifactNode.noDesc.text"); + final String NO_DESCR = NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.noDesc.text"); Map map = new LinkedHashMap<>(); fillPropertyMap(map, artifact); - ss.put(new NodeProperty<>(NbBundle.getMessage(this.getClass(), "BlackboardArtifactNode.createSheet.srcFile.name"), - NbBundle.getMessage(this.getClass(), "BlackboardArtifactNode.createSheet.srcFile.displayName"), + ss.put(new NodeProperty<>(NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.srcFile.name"), + NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.srcFile.displayName"), NO_DESCR, this.getDisplayName())); @@ -222,13 +222,13 @@ public class BlackboardArtifactNode extends DisplayableItemNode { actualMimeType = ""; //NON-NLS } } - ss.put(new NodeProperty<>(NbBundle.getMessage(this.getClass(), "BlackboardArtifactNode.createSheet.ext.name"), - NbBundle.getMessage(this.getClass(), "BlackboardArtifactNode.createSheet.ext.displayName"), + ss.put(new NodeProperty<>(NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.ext.name"), + NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.ext.displayName"), NO_DESCR, ext)); ss.put(new NodeProperty<>( - NbBundle.getMessage(this.getClass(), "BlackboardArtifactNode.createSheet.mimeType.name"), - NbBundle.getMessage(this.getClass(), "BlackboardArtifactNode.createSheet.mimeType.displayName"), + NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.mimeType.name"), + NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.mimeType.displayName"), NO_DESCR, actualMimeType)); } @@ -243,32 +243,32 @@ public class BlackboardArtifactNode extends DisplayableItemNode { if (sourcePath.isEmpty() == false) { ss.put(new NodeProperty<>( - NbBundle.getMessage(this.getClass(), "BlackboardArtifactNode.createSheet.filePath.name"), - NbBundle.getMessage(this.getClass(), "BlackboardArtifactNode.createSheet.filePath.displayName"), + NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.filePath.name"), + NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.filePath.displayName"), NO_DESCR, sourcePath)); } if (Arrays.asList(SHOW_FILE_METADATA).contains(artifactTypeId)) { AbstractFile file = associated instanceof AbstractFile ? (AbstractFile) associated : null; - ss.put(new NodeProperty<>(NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.fileModifiedTime.name"), - NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.fileModifiedTime.displayName"), + ss.put(new NodeProperty<>(NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileModifiedTime.name"), + NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileModifiedTime.displayName"), "", file != null ? ContentUtils.getStringTime(file.getMtime(), file) : "")); - ss.put(new NodeProperty<>(NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.fileChangedTime.name"), - NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.fileChangedTime.displayName"), + ss.put(new NodeProperty<>(NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileChangedTime.name"), + NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileChangedTime.displayName"), "", file != null ? ContentUtils.getStringTime(file.getCtime(), file) : "")); - ss.put(new NodeProperty<>(NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.fileAccessedTime.name"), - NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.fileAccessedTime.displayName"), + ss.put(new NodeProperty<>(NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileAccessedTime.name"), + NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileAccessedTime.displayName"), "", file != null ? ContentUtils.getStringTime(file.getAtime(), file) : "")); - ss.put(new NodeProperty<>(NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.fileCreatedTime.name"), - NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.fileCreatedTime.displayName"), + ss.put(new NodeProperty<>(NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileCreatedTime.name"), + NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileCreatedTime.displayName"), "", file != null ? ContentUtils.getStringTime(file.getCrtime(), file) : "")); - ss.put(new NodeProperty<>(NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.fileSize.name"), - NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.fileSize.displayName"), + ss.put(new NodeProperty<>(NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileSize.name"), + NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileSize.displayName"), "", associated.getSize())); } @@ -287,8 +287,8 @@ public class BlackboardArtifactNode extends DisplayableItemNode { if (dataSourceStr.isEmpty() == false) { ss.put(new NodeProperty<>( - NbBundle.getMessage(this.getClass(), "BlackboardArtifactNode.createSheet.dataSrc.name"), - NbBundle.getMessage(this.getClass(), "BlackboardArtifactNode.createSheet.dataSrc.displayName"), + NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.dataSrc.name"), + NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.dataSrc.displayName"), NO_DESCR, dataSourceStr)); } diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/Bundle.properties b/Core/src/org/sleuthkit/autopsy/datamodel/Bundle.properties index 7eb9bc14f4..3c24e02283 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/datamodel/Bundle.properties @@ -118,17 +118,6 @@ FileSize.createSheet.filterType.displayName=Filter Type FileSize.createSheet.filterType.desc=no description FileSize.exception.notSupported.msg=Not supported for this type of Displayable Item\: {0} FileTypeChildren.exception.notSupported.msg=Not supported for this type of Displayable Item\: {0} -FileTypeExtensionFilters.tskImgFilter.text=Images -FileTypeExtensionFilters.tskVideoFilter.text=Videos -FileTypeExtensionFilters.tskAudioFilter.text=Audio -FileTypeExtensionFilters.tskArchiveFilter.text=Archives -FileTypeExtensionFilters.tskDocumentFilter.text=Documents -FileTypeExtensionFilters.tskExecFilter.text=Executable -FileTypeExtensionFilters.autDocHtmlFilter.text=HTML -FileTypeExtensionFilters.autDocOfficeFilter.text=Office -FileTypeExtensionFilters.autoDocPdfFilter.text=PDF -FileTypeExtensionFilters.autDocTxtFilter.text=Plain Text -FileTypeExtensionFilters.autDocRtfFilter.text=Rich Text FileTypeNode.createSheet.filterType.name=Filter Type FileTypeNode.createSheet.filterType.displayName=Filter Type FileTypeNode.createSheet.filterType.desc=no description diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/CreditCards.java b/Core/src/org/sleuthkit/autopsy/datamodel/CreditCards.java new file mode 100644 index 0000000000..17593d8547 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/datamodel/CreditCards.java @@ -0,0 +1,171 @@ +package org.sleuthkit.autopsy.datamodel; + +import com.google.common.collect.Range; +import com.google.common.collect.RangeMap; +import com.google.common.collect.TreeRangeMap; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.Optional; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.annotation.concurrent.GuardedBy; +import org.apache.commons.csv.CSVFormat; +import org.apache.commons.csv.CSVParser; +import org.apache.commons.csv.CSVRecord; +import org.apache.commons.lang3.StringUtils; +import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil; +import org.sleuthkit.autopsy.datamodel._private.Accounts; + +public class CreditCards { + + //Interface for objects that provide details about one or more BINs. + static public interface BankIdentificationNumber { + + /** + * Get the city of the issuer. + * + * @return the city of the issuer. + */ + Optional getBankCity(); + + /** + * Get the name of the issuer. + * + * @return the name of the issuer. + */ + Optional getBankName(); + + /** + * Get the phone number of the issuer. + * + * @return the phone number of the issuer. + */ + Optional getBankPhoneNumber(); + + /** + * Get the URL of the issuer. + * + * @return the URL of the issuer. + */ + Optional getBankURL(); + + /** + * Get the brand of this BIN range. + * + * @return the brand of this BIN range. + */ + Optional getBrand(); + + /** + * Get the type of card (credit vs debit) for this BIN range. + * + * @return the type of cards in this BIN range. + */ + Optional getCardType(); + + /** + * Get the country of the issuer. + * + * @return the country of the issuer. + */ + Optional getCountry(); + + /** + * Get the length of account numbers in this BIN range. + * + * NOTE: the length is currently unused, and not in the data file for + * any ranges. It could be quite helpfull for validation... + * + * @return the length of account numbers in this BIN range. Or an empty + * Optional if the length is unknown. + * + */ + Optional getNumberLength(); + + /** + * Get the scheme this BIN range uses to amex,visa,mastercard, etc + * + * @return the scheme this BIN range uses. + */ + Optional getScheme(); + } + + private static final Logger LOGGER = Logger.getLogger(CreditCards.class.getName()); + /** + * Range Map from a (ranges of) BINs to data model object with details of + * the BIN, ie, bank name, phone, url, visa/amex/mastercard/..., + */ + @GuardedBy("CreditCards.class") + private final static RangeMap binRanges = TreeRangeMap.create(); + + /** + * Flag for if we have loaded the BINs from the file already. + */ + @GuardedBy("CreditCards.class") + private static boolean binsLoaded = false; + + /** + * Load the BIN range information from disk. If the map has already been + * initialized, don't load again. + */ + synchronized private static void loadBINRanges() { + if (binsLoaded == false) { + try { + InputStreamReader in = new InputStreamReader(CreditCards.class.getResourceAsStream("ranges.csv")); //NON-NLS + CSVParser rangesParser = CSVFormat.RFC4180.withFirstRecordAsHeader().parse(in); + + //parse each row and add to range map + for (CSVRecord record : rangesParser) { + + /** + * Because ranges.csv allows both 6 and (the newer) 8 digit + * BINs, but we need a consistent length for the range map, + * we pad all the numbers out to 8 digits + */ + String start = StringUtils.rightPad(record.get("iin_start"), 8, "0"); //pad start with 0's //NON-NLS + + //if there is no end listed, use start, since ranges will be closed. + String end = StringUtils.defaultIfBlank(record.get("iin_end"), start); //NON-NLS + end = StringUtils.rightPad(end, 8, "99"); //pad end with 9's //NON-NLS + + final String numberLength = record.get("number_length"); //NON-NLS + + try { + Accounts.BINRange binRange = new Accounts.BINRange(Integer.parseInt(start), + Integer.parseInt(end), + StringUtils.isBlank(numberLength) ? null : Integer.valueOf(numberLength), + record.get("scheme"), //NON-NLS + record.get("brand"), //NON-NLS + record.get("type"), //NON-NLS + record.get("country"), //NON-NLS + record.get("bank_name"), //NON-NLS + record.get("bank_url"), //NON-NLS + record.get("bank_phone"), //NON-NLS + record.get("bank_city")); //NON-NLS + + binRanges.put(Range.closed(binRange.getBINstart(), binRange.getBINend()), binRange); + + } catch (NumberFormatException numberFormatException) { + LOGGER.log(Level.WARNING, "Failed to parse BIN range: " + record.toString(), numberFormatException); //NON-NLS + } + binsLoaded = true; + } + } catch (IOException ex) { + LOGGER.log(Level.WARNING, "Failed to load BIN ranges form ranges.csv", ex); //NON-NLS + MessageNotifyUtil.Notify.warn("Credit Card Number Discovery", "There was an error loading Bank Identification Number information. Accounts will not have their BINs identified."); + } + } + } + + /** + * Get an BINInfo object with details about the given BIN + * + * @param bin the BIN to get details of. + * + * @return + */ + synchronized static public BankIdentificationNumber getBINInfo(int bin) { + loadBINRanges(); + return binRanges.get(bin); + } +} diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/DataSources.java b/Core/src/org/sleuthkit/autopsy/datamodel/DataSources.java index e7aa3d8fe4..3ddb6a158d 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/DataSources.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/DataSources.java @@ -18,6 +18,9 @@ */ package org.sleuthkit.autopsy.datamodel; +import org.sleuthkit.autopsy.datamodel._private.AutopsyItemVisitor; +import org.sleuthkit.autopsy.datamodel._private.AutopsyVisitableItem; + /** * Root node to store the data sources in a case */ diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/DeletedContent.java b/Core/src/org/sleuthkit/autopsy/datamodel/DeletedContent.java index 3a1e70b164..92b75059b9 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/DeletedContent.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/DeletedContent.java @@ -18,6 +18,8 @@ */ package org.sleuthkit.autopsy.datamodel; +import org.sleuthkit.autopsy.datamodel._private.AutopsyItemVisitor; +import org.sleuthkit.autopsy.datamodel._private.AutopsyVisitableItem; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.ArrayList; diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/DisplayableItemNodeVisitor.java b/Core/src/org/sleuthkit/autopsy/datamodel/DisplayableItemNodeVisitor.java index 14171a6201..45a5abc66e 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/DisplayableItemNodeVisitor.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/DisplayableItemNodeVisitor.java @@ -22,6 +22,7 @@ import org.sleuthkit.autopsy.datamodel.DeletedContent.DeletedContentsChildren.De import org.sleuthkit.autopsy.datamodel.DeletedContent.DeletedContentsNode; import org.sleuthkit.autopsy.datamodel.FileSize.FileSizeRootChildren.FileSizeNode; import org.sleuthkit.autopsy.datamodel.FileSize.FileSizeRootNode; +import org.sleuthkit.autopsy.datamodel._private.Accounts; /** * Visitor pattern that goes over all nodes in the directory tree. This includes @@ -137,6 +138,8 @@ public interface DisplayableItemNodeVisitor { T visit(Accounts.BINNode binNode); + T visit(Accounts.DefaultAccountTypeNode node); + /** * Visitor with an implementable default behavior for all types. Override * specific visit types to not use the default behavior. @@ -378,5 +381,9 @@ public interface DisplayableItemNodeVisitor { public T visit(Accounts.BINNode node) { return defaultVisit(node); } + @Override + public T visit(Accounts.DefaultAccountTypeNode node) { + return defaultVisit(node); + } } } diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/EmailExtracted.java b/Core/src/org/sleuthkit/autopsy/datamodel/EmailExtracted.java index 89e8c5b217..b9626d5646 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/EmailExtracted.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/EmailExtracted.java @@ -18,6 +18,8 @@ */ package org.sleuthkit.autopsy.datamodel; +import org.sleuthkit.autopsy.datamodel._private.AutopsyItemVisitor; +import org.sleuthkit.autopsy.datamodel._private.AutopsyVisitableItem; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.sql.ResultSet; diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/ExtractedContent.java b/Core/src/org/sleuthkit/autopsy/datamodel/ExtractedContent.java index 4a420f926d..561e96d510 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/ExtractedContent.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/ExtractedContent.java @@ -18,6 +18,8 @@ */ package org.sleuthkit.autopsy.datamodel; +import org.sleuthkit.autopsy.datamodel._private.AutopsyItemVisitor; +import org.sleuthkit.autopsy.datamodel._private.AutopsyVisitableItem; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.ArrayList; diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/FileSize.java b/Core/src/org/sleuthkit/autopsy/datamodel/FileSize.java index c5fee7d696..88ac89bdc9 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/FileSize.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/FileSize.java @@ -18,6 +18,8 @@ */ package org.sleuthkit.autopsy.datamodel; +import org.sleuthkit.autopsy.datamodel._private.AutopsyItemVisitor; +import org.sleuthkit.autopsy.datamodel._private.AutopsyVisitableItem; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.ArrayList; diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/FileTypeNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/FileTypeNode.java index e1b7553aba..e03b2ac924 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/FileTypeNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/FileTypeNode.java @@ -18,6 +18,7 @@ */ package org.sleuthkit.autopsy.datamodel; +import org.sleuthkit.autopsy.datamodel._private.FileTypeExtensionFilters; import java.util.List; import java.util.Observable; import java.util.Observer; diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/FileTypesNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/FileTypesNode.java index 3bbbf0b63c..86913224e1 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/FileTypesNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/FileTypesNode.java @@ -18,6 +18,7 @@ */ package org.sleuthkit.autopsy.datamodel; +import org.sleuthkit.autopsy.datamodel._private.FileTypeExtensionFilters; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.Arrays; diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/HashsetHits.java b/Core/src/org/sleuthkit/autopsy/datamodel/HashsetHits.java index 2264b95ac6..ab2d6c2492 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/HashsetHits.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/HashsetHits.java @@ -18,6 +18,8 @@ */ package org.sleuthkit.autopsy.datamodel; +import org.sleuthkit.autopsy.datamodel._private.AutopsyItemVisitor; +import org.sleuthkit.autopsy.datamodel._private.AutopsyVisitableItem; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.sql.ResultSet; diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/InterestingHits.java b/Core/src/org/sleuthkit/autopsy/datamodel/InterestingHits.java index b07f5568c0..57239561ba 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/InterestingHits.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/InterestingHits.java @@ -18,6 +18,8 @@ */ package org.sleuthkit.autopsy.datamodel; +import org.sleuthkit.autopsy.datamodel._private.AutopsyItemVisitor; +import org.sleuthkit.autopsy.datamodel._private.AutopsyVisitableItem; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.sql.ResultSet; diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/KeywordHits.java b/Core/src/org/sleuthkit/autopsy/datamodel/KeywordHits.java index 319d9ecf9f..8b155ccf32 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/KeywordHits.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/KeywordHits.java @@ -18,6 +18,8 @@ */ package org.sleuthkit.autopsy.datamodel; +import org.sleuthkit.autopsy.datamodel._private.AutopsyItemVisitor; +import org.sleuthkit.autopsy.datamodel._private.AutopsyVisitableItem; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.sql.ResultSet; diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/RecentFilesChildren.java b/Core/src/org/sleuthkit/autopsy/datamodel/RecentFilesChildren.java index 391a49f757..d7665b2157 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/RecentFilesChildren.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/RecentFilesChildren.java @@ -18,6 +18,7 @@ */ package org.sleuthkit.autopsy.datamodel; +import org.sleuthkit.autopsy.datamodel._private.RecentFiles; import java.sql.ResultSet; import java.sql.SQLException; import java.util.Arrays; diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/RecentFilesFilterChildren.java b/Core/src/org/sleuthkit/autopsy/datamodel/RecentFilesFilterChildren.java index c6c9c72471..903028abed 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/RecentFilesFilterChildren.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/RecentFilesFilterChildren.java @@ -28,7 +28,7 @@ import org.sleuthkit.autopsy.coreutils.Logger; import org.openide.nodes.AbstractNode; import org.openide.nodes.ChildFactory; import org.openide.nodes.Node; -import org.sleuthkit.autopsy.datamodel.RecentFiles.RecentFilesFilter; +import org.sleuthkit.autopsy.datamodel._private.RecentFiles.RecentFilesFilter; import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.Content; import org.sleuthkit.datamodel.ContentVisitor; diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/RecentFilesFilterNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/RecentFilesFilterNode.java index e9d8fe6b63..e4ab6811cf 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/RecentFilesFilterNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/RecentFilesFilterNode.java @@ -25,7 +25,7 @@ import org.sleuthkit.autopsy.coreutils.Logger; import org.openide.nodes.Children; import org.openide.nodes.Sheet; import org.openide.util.lookup.Lookups; -import org.sleuthkit.autopsy.datamodel.RecentFiles.RecentFilesFilter; +import org.sleuthkit.autopsy.datamodel._private.RecentFiles.RecentFilesFilter; import org.sleuthkit.datamodel.SleuthkitCase; /** diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/Reports.java b/Core/src/org/sleuthkit/autopsy/datamodel/Reports.java index 7a4f581966..5bb16c5602 100755 --- a/Core/src/org/sleuthkit/autopsy/datamodel/Reports.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/Reports.java @@ -18,6 +18,8 @@ */ package org.sleuthkit.autopsy.datamodel; +import org.sleuthkit.autopsy.datamodel._private.AutopsyItemVisitor; +import org.sleuthkit.autopsy.datamodel._private.AutopsyVisitableItem; import java.awt.Desktop; import java.awt.event.ActionEvent; import java.beans.PropertyChangeEvent; diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/Results.java b/Core/src/org/sleuthkit/autopsy/datamodel/Results.java index 61e9ad626e..60f0247f97 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/Results.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/Results.java @@ -18,6 +18,8 @@ */ package org.sleuthkit.autopsy.datamodel; +import org.sleuthkit.autopsy.datamodel._private.AutopsyItemVisitor; +import org.sleuthkit.autopsy.datamodel._private.AutopsyVisitableItem; import org.sleuthkit.datamodel.SleuthkitCase; /** diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/ResultsNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/ResultsNode.java index aa4688dea0..31bd236ade 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/ResultsNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/ResultsNode.java @@ -18,6 +18,7 @@ */ package org.sleuthkit.autopsy.datamodel; +import org.sleuthkit.autopsy.datamodel._private.Accounts; import java.util.Arrays; import org.openide.nodes.Sheet; import org.openide.util.NbBundle; diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/Tags.java b/Core/src/org/sleuthkit/autopsy/datamodel/Tags.java index ac85cd8787..1ab1e72ad0 100755 --- a/Core/src/org/sleuthkit/autopsy/datamodel/Tags.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/Tags.java @@ -18,6 +18,8 @@ */ package org.sleuthkit.autopsy.datamodel; +import org.sleuthkit.autopsy.datamodel._private.AutopsyItemVisitor; +import org.sleuthkit.autopsy.datamodel._private.AutopsyVisitableItem; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.Collections; diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/Views.java b/Core/src/org/sleuthkit/autopsy/datamodel/Views.java index 4a9dee9886..4e5ef0f027 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/Views.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/Views.java @@ -18,6 +18,8 @@ */ package org.sleuthkit.autopsy.datamodel; +import org.sleuthkit.autopsy.datamodel._private.AutopsyItemVisitor; +import org.sleuthkit.autopsy.datamodel._private.AutopsyVisitableItem; import org.sleuthkit.datamodel.SleuthkitCase; /** diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/ViewsNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/ViewsNode.java index 4919594378..6f7ec0f2c5 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/ViewsNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/ViewsNode.java @@ -18,6 +18,7 @@ */ package org.sleuthkit.autopsy.datamodel; +import org.sleuthkit.autopsy.datamodel._private.FileTypeExtensionFilters; import java.util.Arrays; import org.openide.nodes.Sheet; import org.openide.util.NbBundle; diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/Accounts.java b/Core/src/org/sleuthkit/autopsy/datamodel/_private/Accounts.java similarity index 85% rename from Core/src/org/sleuthkit/autopsy/datamodel/Accounts.java rename to Core/src/org/sleuthkit/autopsy/datamodel/_private/Accounts.java index d203e07925..9b87639c35 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/Accounts.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/_private/Accounts.java @@ -16,7 +16,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.sleuthkit.autopsy.datamodel; +package org.sleuthkit.autopsy.datamodel._private; import com.google.common.collect.Range; import com.google.common.collect.RangeMap; @@ -46,7 +46,6 @@ import javax.annotation.concurrent.Immutable; import javax.swing.AbstractAction; import javax.swing.Action; import org.apache.commons.lang3.StringUtils; -import org.openide.nodes.AbstractNode; import org.openide.nodes.ChildFactory; import org.openide.nodes.Children; import org.openide.nodes.Node; @@ -55,11 +54,18 @@ import org.openide.util.Exceptions; import org.openide.util.NbBundle; import org.openide.util.lookup.Lookups; import org.sleuthkit.autopsy.casemodule.Case; +import org.sleuthkit.autopsy.datamodel.BlackboardArtifactNode; +import org.sleuthkit.autopsy.datamodel.CreditCards; +import org.sleuthkit.autopsy.datamodel.DataModelActionsFactory; +import org.sleuthkit.autopsy.datamodel.DisplayableItemNode; +import org.sleuthkit.autopsy.datamodel.DisplayableItemNodeVisitor; +import org.sleuthkit.autopsy.datamodel.NodeProperty; import org.sleuthkit.autopsy.ingest.IngestManager; import org.sleuthkit.autopsy.ingest.ModuleDataEvent; import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.Account; import org.sleuthkit.datamodel.BlackboardArtifact; +import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE; import org.sleuthkit.datamodel.BlackboardAttribute; import org.sleuthkit.datamodel.Content; import org.sleuthkit.datamodel.SleuthkitCase; @@ -69,10 +75,9 @@ import org.sleuthkit.datamodel.TskCoreException; * AutopsyVisitableItem for the Accounts section of the tree. All nodes, * factories, and data objects related to accounts are inner classes. */ -public class Accounts extends Observable implements AutopsyVisitableItem { +final public class Accounts extends Observable implements AutopsyVisitableItem { private static final Logger LOGGER = Logger.getLogger(Accounts.class.getName()); - private static final BlackboardArtifact.Type ACCOUNT_TYPE = new BlackboardArtifact.Type(BlackboardArtifact.ARTIFACT_TYPE.TSK_ACCOUNT); @NbBundle.Messages("AccountsRootNode.name=Accounts") final public static String NAME = Bundle.AccountsRootNode_name(); @@ -88,7 +93,7 @@ public class Accounts extends Observable implements AutopsyVisitableItem { * * @param skCase The SleuthkitCase object to use for db queries. */ - Accounts(SleuthkitCase skCase) { + public Accounts(SleuthkitCase skCase) { this.skCase = skCase; } @@ -128,89 +133,17 @@ public class Accounts extends Observable implements AutopsyVisitableItem { return new ToggleShowRejected(); } - //Interface for objects that provide details about one or more IINs. - static public interface IINInfo { - - /** - * Get the city of the issuer. - * - * @return the city of the issuer. - */ - Optional getBankCity(); - - /** - * Get the name of the issuer. - * - * @return the name of the issuer. - */ - Optional getBankName(); - - /** - * Get the phone number of the issuer. - * - * @return the phone number of the issuer. - */ - Optional getBankPhoneNumber(); - - /** - * Get the URL of the issuer. - * - * @return the URL of the issuer. - */ - Optional getBankURL(); - - /** - * Get the brand of this IIN range. - * - * @return the brand of this IIN range. - */ - Optional getBrand(); - - /** - * Get the type of card (credit vs debit) for this IIN range. - * - * @return the type of cards in this IIN range. - */ - Optional getCardType(); - - /** - * Get the country of the issuer. - * - * @return the country of the issuer. - */ - Optional getCountry(); - - /** - * Get the length of account numbers in this IIN range. - * - * NOTE: the length is currently unused, and not in the data file for - * any ranges. It could be quite helpfull for validation... - * - * @return the length of account numbers in this IIN range. Or an empty - * Optional if the length is unknown. - * - */ - Optional getNumberLength(); - - /** - * Get the scheme this IIN range uses to, eg amex,visa,mastercard, etc - * - * @return the scheme this IIN range uses. - */ - Optional getScheme(); - } - /** - * Details of a range of Issuer/Bank Identifiaction Number(s) (IIN/BIN) used - * by a bank. + * Details of a range of Bank Identification Number(s) (BIN) used * by a + * bank. */ @Immutable - static class IINRange implements IINInfo { + public static class BINRange implements CreditCards.BankIdentificationNumber { - private final int IINStart; //start of IIN range, 8 digits - private final int IINEnd; // end (incluse ) of IIN rnage, 8 digits + private final int BINStart; //start of BIN range, 8 digits + private final int BINEnd; // end (incluse ) of BIN rnage, 8 digits - private final Integer numberLength; // the length of accounts numbers with this IIN, currently unused + private final Integer numberLength; // the length of accounts numbers with this BIN, currently unused /** * AMEX, VISA, MASTERCARD, DINERS, DISCOVER, UNIONPAY @@ -231,12 +164,12 @@ public class Accounts extends Observable implements AutopsyVisitableItem { /** * Constructor * - * @param IIN_start the first IIN in the range, must be 8 digits - * @param IIN_end the last(inclusive) IIN in the range, must be 8 + * @param BIN_start the first BIN in the range, must be 8 digits + * @param BIN_end the last(inclusive) BIN in the range, must be 8 * digits - * @param number_length the length of account numbers in this IIN range + * @param number_length the length of account numbers in this BIN range * @param scheme amex/visa/mastercard/etc - * @param brand the brand of this IIN range + * @param brand the brand of this BIN range * @param type credit vs debit * @param country the country of the issuer * @param bank_name the name of the issuer @@ -244,9 +177,9 @@ public class Accounts extends Observable implements AutopsyVisitableItem { * @param bank_phone the phone number of the issuer * @param bank_city the city of the issuer */ - IINRange(int IIN_start, int IIN_end, Integer number_length, String scheme, String brand, String type, String country, String bank_name, String bank_url, String bank_phone, String bank_city) { - this.IINStart = IIN_start; - this.IINEnd = IIN_end; + public BINRange(int BIN_start, int BIN_end, Integer number_length, String scheme, String brand, String type, String country, String bank_name, String bank_url, String bank_phone, String bank_city) { + this.BINStart = BIN_start; + this.BINEnd = BIN_end; this.numberLength = number_length; this.scheme = StringUtils.defaultIfBlank(scheme, null); @@ -260,21 +193,21 @@ public class Accounts extends Observable implements AutopsyVisitableItem { } /** - * Get the first IIN in this range + * Get the first BIN in this range * - * @return the first IIN in this range. + * @return the first BIN in this range. */ - int getIINstart() { - return IINStart; + public int getBINstart() { + return BINStart; } /** - * Get the last (inclusive) IIN in this range. + * Get the last (inclusive) BIN in this range. * - * @return the last (inclusive) IIN in this range. + * @return the last (inclusive) BIN in this range. */ - int getIINend() { - return IINEnd; + public int getBINend() { + return BINEnd; } @Override @@ -354,7 +287,7 @@ public class Accounts extends Observable implements AutopsyVisitableItem { @NbBundle.Messages({"Accounts.RootNode.displayName=Accounts"}) public class AccountsRootNode extends DisplayableItemNode { - AccountsRootNode() { + public AccountsRootNode() { super(Children.create(new AccountTypeFactory(), true), Lookups.singleton(Accounts.this)); super.setName(Accounts.NAME); super.setDisplayName(Bundle.Accounts_RootNode_displayName()); @@ -403,7 +336,8 @@ public class Accounts extends Observable implements AutopsyVisitableItem { * for the event to have a null oldValue. */ ModuleDataEvent eventData = (ModuleDataEvent) evt.getOldValue(); - if (null != eventData && ACCOUNT_TYPE.equals(eventData.getBlackboardArtifactType())) { + if (null != eventData + && eventData.getBlackboardArtifactType().getTypeID() == ARTIFACT_TYPE.TSK_ACCOUNT.getTypeID()) { Accounts.this.update(); } } catch (IllegalStateException notUsed) { @@ -443,7 +377,8 @@ public class Accounts extends Observable implements AutopsyVisitableItem { + " WHERE blackboard_attributes.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ACCOUNT_TYPE.getTypeID()); ResultSet resultSet = executeQuery.getResultSet()) { while (resultSet.next()) { - list.add(resultSet.getString("account_type")); + String accountType = resultSet.getString("account_type"); + list.add(accountType); } } catch (TskCoreException | SQLException ex) { Exceptions.printStackTrace(ex); @@ -454,15 +389,18 @@ public class Accounts extends Observable implements AutopsyVisitableItem { @Override protected Node createNodeForKey(String key) { - if (key.equals( /** - * This is a secret handshake with - * org.sleuthkit.autopsy.keywordsearch.TermComponentQuery - */ - Account.Type.CREDIT_CARD.name())) { - return new CreditCardNumberAccountTypeNode(key); - } else { + try { + Account.Type accountType = Account.Type.valueOf(key); + switch (accountType) { + case CREDIT_CARD: + return new CreditCardNumberAccountTypeNode(); + default: + return new DefaultAccountTypeNode(key); + } + } catch (IllegalArgumentException ex) { + LOGGER.log(Level.WARNING, "Unknown account type: " + key); //Flesh out what happens with other account types here. - return new AbstractNode(Children.LEAF); + return new DefaultAccountTypeNode(key); } } @@ -484,6 +422,67 @@ public class Accounts extends Observable implements AutopsyVisitableItem { } } + private class DefaultAccountFactory extends ChildFactory.Detachable { + + private final String accountTypeName; + + public DefaultAccountFactory(String accountTypeName) { + this.accountTypeName = accountTypeName; + } + + @Override + protected boolean createKeys(List list) { + + String query + = "SELECT blackboard_artifacts.artifact_id " //NON-NLS + + " FROM blackboard_artifacts " //NON-NLS + + " JOIN blackboard_attributes ON blackboard_artifacts.artifact_id = blackboard_attributes.artifact_id " //NON-NLS + + " WHERE blackboard_artifacts.artifact_type_id = " + BlackboardArtifact.ARTIFACT_TYPE.TSK_ACCOUNT.getTypeID() //NON-NLS + + " AND blackboard_attributes.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ACCOUNT_TYPE.getTypeID() //NON-NLS + + " AND blackboard_attributes.value_text = '" + accountTypeName + "'" //NON-NLS + + getRejectedArtifactFilterClause(); //NON-NLS + try (SleuthkitCase.CaseDbQuery results = skCase.executeQuery(query); + ResultSet rs = results.getResultSet();) { + while (rs.next()) { + list.add(rs.getLong("artifact_id")); //NON-NLS + } + } catch (TskCoreException | SQLException ex) { + LOGGER.log(Level.SEVERE, "Error querying for account artifacts.", ex); //NON-NLS + return false; + } + return true; + } + + @Override + protected Node createNodeForKey(Long t) { + try { + return new BlackboardArtifactNode(skCase.getBlackboardArtifact(t)); + } catch (TskCoreException ex) { + LOGGER.log(Level.SEVERE, "Error get black board artifact with id " + t, ex); + return null; + } + } + } + + public class DefaultAccountTypeNode extends DisplayableItemNode { + + private DefaultAccountTypeNode(String accountTypeName) { + super(Children.create(new DefaultAccountFactory(accountTypeName), true)); + super.setName(accountTypeName); + this.setIconBaseWithExtension("org/sleuthkit/autopsy/images/credit-cards.png"); //NON-NLS + } + + @Override + public boolean isLeafTypeNode() { + return true; + } + + @Override + public T accept(DisplayableItemNodeVisitor v) { + return v.visit(this); + } + } + /** * Node for an account type. * @@ -491,9 +490,9 @@ public class Accounts extends Observable implements AutopsyVisitableItem { */ public class CreditCardNumberAccountTypeNode extends DisplayableItemNode { - private CreditCardNumberAccountTypeNode(String accountTypeName) { + private CreditCardNumberAccountTypeNode() { super(Children.create(new ViewModeFactory(), true)); - super.setName(accountTypeName); + super.setName(Account.Type.CREDIT_CARD.getDisplayName()); this.setIconBaseWithExtension("org/sleuthkit/autopsy/images/credit-cards.png"); //NON-NLS } @@ -874,10 +873,10 @@ public class Accounts extends Observable implements AutopsyVisitableItem { } private String getBinRangeString() { - if (bin.getIINStart() == bin.getIINEnd()) { - return Integer.toString(bin.getIINStart()); + if (bin.getBINStart() == bin.getBINEnd()) { + return Integer.toString(bin.getBINStart()); } else { - return bin.getIINStart() + "-" + StringUtils.difference(bin.getIINStart() + "", bin.getIINEnd() + ""); + return bin.getBINStart() + "-" + StringUtils.difference(bin.getBINStart() + "", bin.getBINEnd() + ""); } } @@ -981,16 +980,16 @@ public class Accounts extends Observable implements AutopsyVisitableItem { final Integer bin = Integer.valueOf(resultSet.getString("BIN")); long count = resultSet.getLong("count"); - IINRange iinRange = (IINRange) BINMap.getIINInfo(bin); + BINRange binRange = (BINRange) CreditCards.getBINInfo(bin); BinResult previousResult = ranges.get(bin); if (previousResult != null) { - ranges.remove(Range.closed(previousResult.getIINStart(), previousResult.getIINEnd())); + ranges.remove(Range.closed(previousResult.getBINStart(), previousResult.getBINEnd())); count += previousResult.getCount(); } - if (iinRange != null) { - ranges.put(Range.closed(iinRange.getIINstart(), iinRange.getIINend()), new BinResult(count, iinRange)); + if (binRange != null) { + ranges.put(Range.closed(binRange.getBINstart(), binRange.getBINend()), new BinResult(count, binRange)); } else { ranges.put(Range.closed(bin, bin), new BinResult(count, bin, bin)); } @@ -1014,37 +1013,37 @@ public class Accounts extends Observable implements AutopsyVisitableItem { * accounts found with the BIN. */ @Immutable - static private class BinResult implements IINInfo { + static private class BinResult implements CreditCards.BankIdentificationNumber { /** * The number of accounts with this BIN */ private final long count; - private final IINRange iinRange; - private final int iinEnd; - private final int iinStart; + private final BINRange binRange; + private final int binEnd; + private final int binStart; - private BinResult(long count, @Nonnull IINRange iinRange) { + private BinResult(long count, @Nonnull BINRange binRange) { this.count = count; - this.iinRange = iinRange; - iinStart = iinRange.getIINstart(); - iinEnd = iinRange.getIINend(); + this.binRange = binRange; + binStart = binRange.getBINstart(); + binEnd = binRange.getBINend(); } private BinResult(long count, int start, int end) { this.count = count; - this.iinRange = null; - iinStart = start; - iinEnd = end; + this.binRange = null; + binStart = start; + binEnd = end; } - int getIINStart() { - return iinStart; + int getBINStart() { + return binStart; } - int getIINEnd() { - return iinEnd; + int getBINEnd() { + return binEnd; } public long getCount() { @@ -1052,52 +1051,52 @@ public class Accounts extends Observable implements AutopsyVisitableItem { } boolean hasDetails() { - return iinRange != null; + return binRange != null; } @Override public Optional getNumberLength() { - return iinRange.getNumberLength(); + return binRange.getNumberLength(); } @Override public Optional getBankCity() { - return iinRange.getBankCity(); + return binRange.getBankCity(); } @Override public Optional getBankName() { - return iinRange.getBankName(); + return binRange.getBankName(); } @Override public Optional getBankPhoneNumber() { - return iinRange.getBankPhoneNumber(); + return binRange.getBankPhoneNumber(); } @Override public Optional getBankURL() { - return iinRange.getBankURL(); + return binRange.getBankURL(); } @Override public Optional getBrand() { - return iinRange.getBrand(); + return binRange.getBrand(); } @Override public Optional getCardType() { - return iinRange.getCardType(); + return binRange.getCardType(); } @Override public Optional getCountry() { - return iinRange.getCountry(); + return binRange.getCountry(); } @Override public Optional getScheme() { - return iinRange.getScheme(); + return binRange.getScheme(); } } @@ -1121,7 +1120,7 @@ public class Accounts extends Observable implements AutopsyVisitableItem { + " JOIN blackboard_attributes ON blackboard_artifacts.artifact_id = blackboard_attributes.artifact_id " //NON-NLS + " WHERE blackboard_artifacts.artifact_type_id = " + BlackboardArtifact.ARTIFACT_TYPE.TSK_ACCOUNT.getTypeID() //NON-NLS + " AND blackboard_attributes.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_CREDIT_CARD_NUMBER.getTypeID() //NON-NLS - + " AND blackboard_attributes.value_text >= \"" + bin.getIINStart() + "\" AND blackboard_attributes.value_text < \"" + (bin.getIINEnd() + 1) + "\"" //NON-NLS + + " AND blackboard_attributes.value_text >= \"" + bin.getBINStart() + "\" AND blackboard_attributes.value_text < \"" + (bin.getBINEnd() + 1) + "\"" //NON-NLS + getRejectedArtifactFilterClause() + " ORDER BY blackboard_attributes.value_text"; //NON-NLS try (SleuthkitCase.CaseDbQuery results = skCase.executeQuery(query); @@ -1187,7 +1186,7 @@ public class Accounts extends Observable implements AutopsyVisitableItem { } } - final class ToggleShowRejected extends AbstractAction { + private final class ToggleShowRejected extends AbstractAction { @NbBundle.Messages("ToggleShowRejected.name=Show Rejcted Results") ToggleShowRejected() { diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/AutopsyItemVisitor.java b/Core/src/org/sleuthkit/autopsy/datamodel/_private/AutopsyItemVisitor.java similarity index 85% rename from Core/src/org/sleuthkit/autopsy/datamodel/AutopsyItemVisitor.java rename to Core/src/org/sleuthkit/autopsy/datamodel/_private/AutopsyItemVisitor.java index ceb390e88e..bf6e2246ea 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/AutopsyItemVisitor.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/_private/AutopsyItemVisitor.java @@ -16,14 +16,27 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.sleuthkit.autopsy.datamodel; +package org.sleuthkit.autopsy.datamodel._private; + +import org.sleuthkit.autopsy.datamodel.DataSources; +import org.sleuthkit.autopsy.datamodel.DeletedContent; +import org.sleuthkit.autopsy.datamodel.EmailExtracted; +import org.sleuthkit.autopsy.datamodel.ExtractedContent; +import org.sleuthkit.autopsy.datamodel.FileSize; +import org.sleuthkit.autopsy.datamodel.HashsetHits; +import org.sleuthkit.autopsy.datamodel.InterestingHits; +import org.sleuthkit.autopsy.datamodel.KeywordHits; +import org.sleuthkit.autopsy.datamodel.Reports; +import org.sleuthkit.autopsy.datamodel.Results; +import org.sleuthkit.autopsy.datamodel.Tags; +import org.sleuthkit.autopsy.datamodel.Views; /** * This visitor goes over the AutopsyVisitableItems, which are currently the * nodes in the tree that are structural and not nodes that are from * Sleuthkit-based data model objects. */ -interface AutopsyItemVisitor { +public interface AutopsyItemVisitor { T visit(DataSources i); diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/AutopsyVisitableItem.java b/Core/src/org/sleuthkit/autopsy/datamodel/_private/AutopsyVisitableItem.java similarity index 91% rename from Core/src/org/sleuthkit/autopsy/datamodel/AutopsyVisitableItem.java rename to Core/src/org/sleuthkit/autopsy/datamodel/_private/AutopsyVisitableItem.java index a8efccb494..3eb949ff01 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/AutopsyVisitableItem.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/_private/AutopsyVisitableItem.java @@ -16,13 +16,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.sleuthkit.autopsy.datamodel; +package org.sleuthkit.autopsy.datamodel._private; +; /** * AutopsyVisitableItems are the nodes in the directory tree that are for * structure only. They are not associated with content objects. */ -interface AutopsyVisitableItem { +public interface AutopsyVisitableItem { /** * visitor pattern support diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/_private/Bundle.properties b/Core/src/org/sleuthkit/autopsy/datamodel/_private/Bundle.properties new file mode 100644 index 0000000000..dc778857c5 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/datamodel/_private/Bundle.properties @@ -0,0 +1,12 @@ +FileTypeExtensionFilters.tskImgFilter.text=Images +FileTypeExtensionFilters.tskVideoFilter.text=Videos +FileTypeExtensionFilters.tskAudioFilter.text=Audio +FileTypeExtensionFilters.tskArchiveFilter.text=Archives +FileTypeExtensionFilters.tskDocumentFilter.text=Documents +FileTypeExtensionFilters.tskExecFilter.text=Executable +FileTypeExtensionFilters.autDocHtmlFilter.text=HTML +FileTypeExtensionFilters.autDocOfficeFilter.text=Office +FileTypeExtensionFilters.autoDocPdfFilter.text=PDF +FileTypeExtensionFilters.autDocTxtFilter.text=Plain Text +FileTypeExtensionFilters.autDocRtfFilter.text=Rich Text + diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/FileTypeExtensionFilters.java b/Core/src/org/sleuthkit/autopsy/datamodel/_private/FileTypeExtensionFilters.java similarity index 90% rename from Core/src/org/sleuthkit/autopsy/datamodel/FileTypeExtensionFilters.java rename to Core/src/org/sleuthkit/autopsy/datamodel/_private/FileTypeExtensionFilters.java index 1e2dd473dd..09a650161d 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/FileTypeExtensionFilters.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/_private/FileTypeExtensionFilters.java @@ -16,20 +16,20 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.sleuthkit.autopsy.datamodel; +package org.sleuthkit.autopsy.datamodel._private; import java.util.Arrays; import java.util.List; - import org.openide.util.NbBundle; +import org.sleuthkit.autopsy.datamodel.FileTypeExtensions; import org.sleuthkit.datamodel.SleuthkitCase; /** * Filters database results by file extension. */ -class FileTypeExtensionFilters implements AutopsyVisitableItem { +public class FileTypeExtensionFilters implements AutopsyVisitableItem { - private SleuthkitCase skCase; + private final SleuthkitCase skCase; // root node filters public enum RootFilter implements AutopsyVisitableItem, SearchFilterInterface { @@ -53,10 +53,10 @@ class FileTypeExtensionFilters implements AutopsyVisitableItem { NbBundle.getMessage(FileTypeExtensionFilters.class, "FileTypeExtensionFilters.tskExecFilter.text"), Arrays.asList(".exe", ".dll", ".bat", ".cmd", ".com")); //NON-NLS - private int id; - private String name; - private String displayName; - private List filter; + private final int id; + private final String name; + private final String displayName; + private final List filter; private RootFilter(int id, String name, String displayName, List filter) { this.id = id; @@ -110,10 +110,10 @@ class FileTypeExtensionFilters implements AutopsyVisitableItem { NbBundle.getMessage(FileTypeExtensionFilters.class, "FileTypeExtensionFilters.autDocRtfFilter.text"), Arrays.asList(".rtf")); //NON-NLS - private int id; - private String name; - private String displayName; - private List filter; + private final int id; + private final String name; + private final String displayName; + private final List filter; private DocumentFilter(int id, String name, String displayName, List filter) { this.id = id; @@ -157,10 +157,10 @@ class FileTypeExtensionFilters implements AutopsyVisitableItem { ExecutableFilter_CMD(3, "ExecutableFilter_CMD", ".cmd", Arrays.asList(".cmd")), //NON-NLS ExecutableFilter_COM(4, "ExecutableFilter_COM", ".com", Arrays.asList(".com")); //NON-NLS - private int id; - private String name; - private String displayName; - private List filter; + private final int id; + private final String name; + private final String displayName; + private final List filter; private ExecutableFilter(int id, String name, String displayName, List filter) { this.id = id; @@ -208,7 +208,7 @@ class FileTypeExtensionFilters implements AutopsyVisitableItem { return this.skCase; } - interface SearchFilterInterface { + public interface SearchFilterInterface { public String getName(); diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/RecentFiles.java b/Core/src/org/sleuthkit/autopsy/datamodel/_private/RecentFiles.java similarity index 96% rename from Core/src/org/sleuthkit/autopsy/datamodel/RecentFiles.java rename to Core/src/org/sleuthkit/autopsy/datamodel/_private/RecentFiles.java index cc8b8424cb..d3163d579d 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/RecentFiles.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/_private/RecentFiles.java @@ -16,7 +16,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.sleuthkit.autopsy.datamodel; +package org.sleuthkit.autopsy.datamodel._private; import org.openide.util.NbBundle; import org.sleuthkit.datamodel.SleuthkitCase; @@ -25,7 +25,7 @@ import org.sleuthkit.datamodel.SleuthkitCase; * Recent files node support NOTE: As of june '15 we do not display this in the * tree. It can be added back when we have filtering in the results area. */ -class RecentFiles implements AutopsyVisitableItem { +public class RecentFiles implements AutopsyVisitableItem { SleuthkitCase skCase; diff --git a/Core/src/org/sleuthkit/autopsy/directorytree/DataResultFilterNode.java b/Core/src/org/sleuthkit/autopsy/directorytree/DataResultFilterNode.java index 33d15b14f9..5d7981b677 100755 --- a/Core/src/org/sleuthkit/autopsy/directorytree/DataResultFilterNode.java +++ b/Core/src/org/sleuthkit/autopsy/directorytree/DataResultFilterNode.java @@ -37,7 +37,7 @@ import org.sleuthkit.autopsy.coreutils.ContextMenuExtensionPoint; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.datamodel.AbstractAbstractFileNode.AbstractFilePropertyType; import org.sleuthkit.autopsy.datamodel.AbstractFsContentNode; -import org.sleuthkit.autopsy.datamodel.Accounts; +import org.sleuthkit.autopsy.datamodel._private.Accounts; import org.sleuthkit.autopsy.datamodel.BlackboardArtifactNode; import org.sleuthkit.autopsy.datamodel.DeletedContent.DeletedContentsChildren.DeletedContentNode; import org.sleuthkit.autopsy.datamodel.DeletedContent.DeletedContentsNode; diff --git a/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.java b/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.java index 987c2bc827..6db8d46a6e 100644 --- a/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.java +++ b/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.java @@ -57,7 +57,7 @@ import org.sleuthkit.autopsy.corecomponents.DataResultTopComponent; import org.sleuthkit.autopsy.corecomponents.TableFilterNode; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil; -import org.sleuthkit.autopsy.datamodel.Accounts; +import org.sleuthkit.autopsy.datamodel._private.Accounts; import org.sleuthkit.autopsy.datamodel.BlackboardArtifactNode; import org.sleuthkit.autopsy.datamodel.DataSources; import org.sleuthkit.autopsy.datamodel.DataSourcesNode; diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentViewer.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentViewer.java index 56ef0725d1..1de41b5eab 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentViewer.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentViewer.java @@ -140,7 +140,7 @@ public class ExtractedContentViewer implements DataContentViewer { */ for (BlackboardArtifact artifact : artifacts) { try { - BlackboardAttribute solrIDAttr = artifact.getAttribute(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_SOLR_DOCUMENT_ID)); + BlackboardAttribute solrIDAttr = artifact.getAttribute(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_KEYWORD_SEARCH_DOCUMENT_ID)); if (solrIDAttr != null) { String valueString = solrIDAttr.getValueString(); if (StringUtils.isNotBlank(valueString)) { diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TermComponentQuery.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TermComponentQuery.java index 0f7858448f..7888010d87 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TermComponentQuery.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TermComponentQuery.java @@ -34,8 +34,7 @@ import org.apache.solr.client.solrj.SolrQuery; import org.apache.solr.client.solrj.response.TermsResponse.Term; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.Version; -import org.sleuthkit.autopsy.datamodel.Accounts; -import org.sleuthkit.autopsy.datamodel.BINMap; +import org.sleuthkit.autopsy.datamodel.CreditCards; import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.Account; import org.sleuthkit.datamodel.BlackboardArtifact; @@ -214,26 +213,26 @@ final class TermComponentQuery implements KeywordSearchQuery { } String ccn = newArtifact.getAttribute(CREDIT_CARD_NUMBER).getValueString(); - final int iin = Integer.parseInt(ccn.substring(0, 8)); + final int bin = Integer.parseInt(ccn.substring(0, 8)); - Accounts.IINInfo iinInfo = BINMap.getIINInfo(iin); + CreditCards.BankIdentificationNumber binInfo = CreditCards.getBINInfo(bin); - if (iinInfo != null) { - iinInfo.getScheme().ifPresent(scheme + if (binInfo != null) { + binInfo.getScheme().ifPresent(scheme -> addAttributeSafe(newArtifact, ATTRIBUTE_TYPE.TSK_CREDIT_CARD_SCHEME, scheme)); - iinInfo.getCardType().ifPresent(cardType + binInfo.getCardType().ifPresent(cardType -> addAttributeSafe(newArtifact, ATTRIBUTE_TYPE.TSK_PAYMENT_CARD_TYPE, cardType)); - iinInfo.getBrand().ifPresent(brand + binInfo.getBrand().ifPresent(brand -> addAttributeSafe(newArtifact, ATTRIBUTE_TYPE.TSK_BRAND, brand)); - iinInfo.getBankName().ifPresent(bankName + binInfo.getBankName().ifPresent(bankName -> addAttributeSafe(newArtifact, ATTRIBUTE_TYPE.TSK_BANK_NAME, bankName)); - iinInfo.getBankPhoneNumber().ifPresent(phoneNumber + binInfo.getBankPhoneNumber().ifPresent(phoneNumber -> addAttributeSafe(newArtifact, ATTRIBUTE_TYPE.TSK_PHONE_NUMBER, phoneNumber)); - iinInfo.getBankURL().ifPresent(url + binInfo.getBankURL().ifPresent(url -> addAttributeSafe(newArtifact, ATTRIBUTE_TYPE.TSK_URL, url)); - iinInfo.getCountry().ifPresent(country + binInfo.getCountry().ifPresent(country -> addAttributeSafe(newArtifact, ATTRIBUTE_TYPE.TSK_COUNTRY, country)); - iinInfo.getBankCity().ifPresent(city + binInfo.getBankCity().ifPresent(city -> addAttributeSafe(newArtifact, ATTRIBUTE_TYPE.TSK_CITY, city)); } } else {