From 2fbfa5a00c07df8b8ed140d0cd13ff5a9f33d635 Mon Sep 17 00:00:00 2001 From: Raman Date: Thu, 24 Aug 2017 13:17:01 -0400 Subject: [PATCH 001/127] 851: Implement Accounts & Relationships framework --- .../autopsy/datamodel/accounts/Accounts.java | 16 ++++++++-------- .../directorytree/DirectoryTreeTopComponent.java | 2 +- .../autopsy/keywordsearch/RegexQuery.java | 2 +- .../keywordsearch/TermsComponentQuery.java | 2 +- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/accounts/Accounts.java b/Core/src/org/sleuthkit/autopsy/datamodel/accounts/Accounts.java index 6545ac0bef..1e9e56fe18 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/accounts/Accounts.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/accounts/Accounts.java @@ -293,13 +293,13 @@ final public class Accounts implements AutopsyVisitableItem { @Override protected Node[] createNodes(String key) { try { - Account.Type accountType = Account.Type.valueOf(key); - switch (accountType) { - case CREDIT_CARD: - return new Node[]{new CreditCardNumberAccountTypeNode()}; - default: - return new Node[]{new DefaultAccountTypeNode(key)}; + String accountType = key; + if (accountType.equals(Account.Type.CREDIT_CARD.getTypeName())) { + return new Node[]{new CreditCardNumberAccountTypeNode()}; + } else { + return new Node[]{new DefaultAccountTypeNode(key)}; } + } catch (IllegalArgumentException ex) { LOGGER.log(Level.WARNING, "Unknown account type: {0}", key); //Flesh out what happens with other account types here. @@ -546,7 +546,7 @@ final public class Accounts implements AutopsyVisitableItem { + " AND solr_attribute.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD_SEARCH_DOCUMENT_ID.getTypeID() //NON-NLS + " LEFT JOIN blackboard_attributes as account_type ON blackboard_artifacts.artifact_id = account_type.artifact_id " //NON-NLS + " AND account_type.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ACCOUNT_TYPE.getTypeID() //NON-NLS - + " AND account_type.value_text = '" + Account.Type.CREDIT_CARD.name() + "'" //NON-NLS + + " AND account_type.value_text = '" + Account.Type.CREDIT_CARD.getTypeName() + "'" //NON-NLS + " WHERE blackboard_artifacts.artifact_type_id = " + BlackboardArtifact.ARTIFACT_TYPE.TSK_ACCOUNT.getTypeID() //NON-NLS + getRejectedArtifactFilterClause() + " GROUP BY blackboard_artifacts.obj_id, solr_document_id " //NON-NLS @@ -606,7 +606,7 @@ final public class Accounts implements AutopsyVisitableItem { + " AND solr_attribute.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD_SEARCH_DOCUMENT_ID.getTypeID() //NON-NLS + " LEFT JOIN blackboard_attributes as account_type ON blackboard_artifacts.artifact_id = account_type.artifact_id " //NON-NLS + " AND account_type.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ACCOUNT_TYPE.getTypeID() //NON-NLS - + " AND account_type.value_text = '" + Account.Type.CREDIT_CARD.name() + "'" //NON-NLS + + " AND account_type.value_text = '" + Account.Type.CREDIT_CARD.getTypeName() + "'" //NON-NLS + " WHERE blackboard_artifacts.artifact_type_id = " + BlackboardArtifact.ARTIFACT_TYPE.TSK_ACCOUNT.getTypeID() //NON-NLS + getRejectedArtifactFilterClause() + " GROUP BY blackboard_artifacts.obj_id, solr_attribute.value_text ) AS foo"; diff --git a/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.java b/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.java index bfb98e5220..7ade29bf79 100644 --- a/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.java +++ b/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.java @@ -993,7 +993,7 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat return; } - if (accountType.equals(Account.Type.CREDIT_CARD.name())) { + if (accountType.equals(Account.Type.CREDIT_CARD.getTypeName())) { Node accountNode = accountRootChilds.findChild(Account.Type.CREDIT_CARD.getDisplayName()); if (accountNode == null) { return; diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/RegexQuery.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/RegexQuery.java index 45205b0ca7..60fe6d2895 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/RegexQuery.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/RegexQuery.java @@ -440,7 +440,7 @@ final class RegexQuery implements KeywordSearchQuery { * Parse the credit card account attributes from the snippet for the * hit. */ - attributes.add(new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ACCOUNT_TYPE, MODULE_NAME, Account.Type.CREDIT_CARD.name())); + attributes.add(new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ACCOUNT_TYPE, MODULE_NAME, Account.Type.CREDIT_CARD.getTypeName())); Map parsedTrackAttributeMap = new HashMap<>(); Matcher matcher = TermsComponentQuery.CREDIT_CARD_TRACK1_PATTERN.matcher(hit.getSnippet()); if (matcher.find()) { diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TermsComponentQuery.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TermsComponentQuery.java index f4413e3f2a..8be8cd4f37 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TermsComponentQuery.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TermsComponentQuery.java @@ -360,7 +360,7 @@ final class TermsComponentQuery implements KeywordSearchQuery { * Parse the credit card account attributes from the snippet for the * hit. */ - attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_ACCOUNT_TYPE, MODULE_NAME, Account.Type.CREDIT_CARD.name())); + attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_ACCOUNT_TYPE, MODULE_NAME, Account.Type.CREDIT_CARD.getTypeName())); Map parsedTrackAttributeMap = new HashMap<>(); Matcher matcher = CREDIT_CARD_TRACK1_PATTERN.matcher(hit.getSnippet()); if (matcher.find()) { From 569626888fb67f30d66dbac9c10f63d01eb12a67 Mon Sep 17 00:00:00 2001 From: Raman Date: Tue, 29 Aug 2017 13:22:41 -0400 Subject: [PATCH 002/127] 852: Use CommunicationsManager API ti create accounts & relationships when parsing email messages. --- .../ThunderbirdMboxFileIngestModule.java | 66 +++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/thunderbirdparser/src/org/sleuthkit/autopsy/thunderbirdparser/ThunderbirdMboxFileIngestModule.java b/thunderbirdparser/src/org/sleuthkit/autopsy/thunderbirdparser/ThunderbirdMboxFileIngestModule.java index 3b7d70d929..dd070a935d 100644 --- a/thunderbirdparser/src/org/sleuthkit/autopsy/thunderbirdparser/ThunderbirdMboxFileIngestModule.java +++ b/thunderbirdparser/src/org/sleuthkit/autopsy/thunderbirdparser/ThunderbirdMboxFileIngestModule.java @@ -21,8 +21,12 @@ package org.sleuthkit.autopsy.thunderbirdparser; import java.io.File; import java.io.IOException; import java.util.ArrayList; +import java.util.HashSet; import java.util.List; +import java.util.Set; import java.util.logging.Level; +import java.util.regex.Pattern; +import java.util.regex.Matcher; import org.openide.util.NbBundle; import org.openide.util.NbBundle.Messages; import org.sleuthkit.autopsy.casemodule.Case; @@ -40,6 +44,7 @@ import org.sleuthkit.autopsy.ingest.IngestServices; import org.sleuthkit.autopsy.ingest.ModuleContentEvent; 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.BlackboardAttribute; import org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE; @@ -47,6 +52,7 @@ import org.sleuthkit.datamodel.DerivedFile; import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.datamodel.TskData; import org.sleuthkit.datamodel.TskException; +import org.sleuthkit.datamodel.CommunicationsManager; /** * File-level ingest module that detects MBOX files based on signature. @@ -353,6 +359,24 @@ public final class ThunderbirdMboxFileIngestModule implements FileIngestModule { return files; } + /** + * Finds and returns a set of unique email addresses found in the input string + * + * @param input - input string, like the To/CC line from an email header + * + * @param Set: set of email addresses found in the input string + */ + private Set findEmailAddresess(String input) { + Pattern p = Pattern.compile("\\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,4}\\b", + Pattern.CASE_INSENSITIVE); + Matcher m = p.matcher(input); + Set emailAddresses = new HashSet(); + while (m.find()) { + emailAddresses.add( m.group()); + } + return emailAddresses; + } + /** * Add a blackboard artifact for the given email message. * @@ -376,6 +400,45 @@ public final class ThunderbirdMboxFileIngestModule implements FileIngestModule { long id = email.getId(); String localPath = email.getLocalPath(); + + + + List senderAddressList = new ArrayList<>(); + String senderAddress; + senderAddressList.addAll(findEmailAddresess(from)); + + Account senderAccount = null; + if (senderAddressList.size() == 1) { + senderAddress = senderAddressList.get(0); + try { + senderAccount = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().getOrCreateAccount(Account.Type.EMAIL, senderAddress, EmailParserModuleFactory.getModuleName(), abstractFile); + } + catch(TskCoreException ex) { + logger.log(Level.WARNING, "Failed to create account for email address " + from, ex); //NON-NLS + } + } + else { + logger.log(Level.WARNING, "Failed to find sender address, from "+ from); //NON-NLS + } + + List recipientAddresses = new ArrayList<>(); + recipientAddresses.addAll(findEmailAddresess(to)); + recipientAddresses.addAll(findEmailAddresess(cc)); + recipientAddresses.addAll(findEmailAddresess(bcc)); + + List recipientAccounts = new ArrayList<>(); + recipientAddresses.forEach((addr) -> { + try { + Account recipientAccount = + Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().getOrCreateAccount(Account.Type.EMAIL, addr, + EmailParserModuleFactory.getModuleName(), abstractFile); + recipientAccounts.add(recipientAccount); + } + catch(TskCoreException ex) { + logger.log(Level.WARNING, "Failed to create account for email address " + addr, ex); //NON-NLS + } + }); + if (headers.isEmpty() == false) { bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_HEADERS, EmailParserModuleFactory.getModuleName(), headers)); } @@ -425,6 +488,9 @@ public final class ThunderbirdMboxFileIngestModule implements FileIngestModule { bbart = abstractFile.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_EMAIL_MSG); bbart.addAttributes(bbattributes); + // Add account relationships + Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().addRelationships(senderAccount, recipientAccounts, bbart); + try { // index the artifact for keyword search blackboard.indexArtifact(bbart); From a289a7cc8317301f4de35835a983dc042495aa35 Mon Sep 17 00:00:00 2001 From: Raman Date: Fri, 1 Sep 2017 10:00:57 -0400 Subject: [PATCH 003/127] 851: Accounts & Messages framework - address Codacy issue. --- .../thunderbirdparser/ThunderbirdMboxFileIngestModule.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/thunderbirdparser/src/org/sleuthkit/autopsy/thunderbirdparser/ThunderbirdMboxFileIngestModule.java b/thunderbirdparser/src/org/sleuthkit/autopsy/thunderbirdparser/ThunderbirdMboxFileIngestModule.java index dd070a935d..e82972519e 100644 --- a/thunderbirdparser/src/org/sleuthkit/autopsy/thunderbirdparser/ThunderbirdMboxFileIngestModule.java +++ b/thunderbirdparser/src/org/sleuthkit/autopsy/thunderbirdparser/ThunderbirdMboxFileIngestModule.java @@ -52,7 +52,6 @@ import org.sleuthkit.datamodel.DerivedFile; import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.datamodel.TskData; import org.sleuthkit.datamodel.TskException; -import org.sleuthkit.datamodel.CommunicationsManager; /** * File-level ingest module that detects MBOX files based on signature. @@ -414,11 +413,11 @@ public final class ThunderbirdMboxFileIngestModule implements FileIngestModule { senderAccount = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().getOrCreateAccount(Account.Type.EMAIL, senderAddress, EmailParserModuleFactory.getModuleName(), abstractFile); } catch(TskCoreException ex) { - logger.log(Level.WARNING, "Failed to create account for email address " + from, ex); //NON-NLS + logger.log(Level.WARNING, "Failed to create account for email address " + senderAddress, ex); //NON-NLS } } else { - logger.log(Level.WARNING, "Failed to find sender address, from "+ from); //NON-NLS + logger.log(Level.WARNING, "Failed to find sender address, from = "+ from); //NON-NLS } List recipientAddresses = new ArrayList<>(); From 86de03969ff74de626ee5c964d3405bdcb9ad7df Mon Sep 17 00:00:00 2001 From: Raman Date: Wed, 6 Sep 2017 12:48:07 -0400 Subject: [PATCH 004/127] 853: Update Autopsy Python modules to use the CommunicationsManager api to create accounts & relationships --- InternalPythonModules/android/calllog.py | 17 ++++++++++++++++ InternalPythonModules/android/contact.py | 20 +++++++++++++++++++ InternalPythonModules/android/tangomessage.py | 9 +++++++++ InternalPythonModules/android/textmessage.py | 16 +++++++++++++++ InternalPythonModules/android/wwfmessage.py | 18 +++++++++++++++++ 5 files changed, 80 insertions(+) diff --git a/InternalPythonModules/android/calllog.py b/InternalPythonModules/android/calllog.py index 42e3a293a1..13bccac4f9 100644 --- a/InternalPythonModules/android/calllog.py +++ b/InternalPythonModules/android/calllog.py @@ -43,6 +43,7 @@ from org.sleuthkit.datamodel import BlackboardAttribute from org.sleuthkit.datamodel.BlackboardAttribute import ATTRIBUTE_TYPE from org.sleuthkit.datamodel import Content from org.sleuthkit.datamodel import TskCoreException +from org.sleuthkit.datamodel import Account import traceback import general @@ -81,6 +82,16 @@ class CallLogAnalyzer(general.AndroidComponentAnalyzer): def analyze(self, dataSource, fileManager, context): try: + + # Create a 'Device' account using the data source device id + datasourceObjId = dataSource.getDataSource().getId() + ds = Case.getCurrentCase().getSleuthkitCase().getDataSource(datasourceObjId) + deviceID = ds.getDeviceId() + + global deviceAccount + deviceAccount = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().getOrCreateAccount(Account.Type.DEVICE, deviceID, general.MODULE_NAME, dataSource) + + absFiles = fileManager.findFiles(dataSource, "logs.db") absFiles.addAll(fileManager.findFiles(dataSource, "contacts.db")) absFiles.addAll(fileManager.findFiles(dataSource, "contacts2.db")) @@ -130,6 +141,12 @@ class CallLogAnalyzer(general.AndroidComponentAnalyzer): artifact.addAttribute(BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DIRECTION, general.MODULE_NAME, directionString)) artifact.addAttribute(BlackboardAttribute(ATTRIBUTE_TYPE.TSK_NAME, general.MODULE_NAME, name)) + # Create an account + calllogAccount = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().getOrCreateAccount(Account.Type.PHONE, number, general.MODULE_NAME, abstractFile); + + # create relationship between accounts + Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().addRelationships(deviceAccount, [calllogAccount], artifact); + bbartifacts.append(artifact) try: diff --git a/InternalPythonModules/android/contact.py b/InternalPythonModules/android/contact.py index fe56cc1cbb..d41c3662dc 100644 --- a/InternalPythonModules/android/contact.py +++ b/InternalPythonModules/android/contact.py @@ -41,10 +41,12 @@ from org.sleuthkit.datamodel import BlackboardArtifact from org.sleuthkit.datamodel import BlackboardAttribute from org.sleuthkit.datamodel import Content from org.sleuthkit.datamodel import TskCoreException +from org.sleuthkit.datamodel import Account import traceback import general + """ Locates a variety of different contacts databases, parses them, and populates the blackboard. """ @@ -55,6 +57,15 @@ class ContactAnalyzer(general.AndroidComponentAnalyzer): def analyze(self, dataSource, fileManager, context): try: + + # Create a 'Device' account using the data source device id + datasourceObjId = dataSource.getDataSource().getId() + ds = Case.getCurrentCase().getSleuthkitCase().getDataSource(datasourceObjId) + deviceID = ds.getDeviceId() + + global deviceAccount + deviceAccount = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().getOrCreateAccount(Account.Type.DEVICE, deviceID, general.MODULE_NAME, dataSource) + absFiles = fileManager.findFiles(dataSource, "contacts.db") absFiles.addAll(fileManager.findFiles(dataSource, "contacts2.db")) if absFiles.isEmpty(): @@ -129,9 +140,18 @@ class ContactAnalyzer(general.AndroidComponentAnalyzer): artifact.addAttribute(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_NAME, general.MODULE_NAME, name)) if mimetype == "vnd.android.cursor.item/phone_v2": artifact.addAttribute(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER, general.MODULE_NAME, data1)) + acctType = Account.Type.PHONE else: artifact.addAttribute(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL, general.MODULE_NAME, data1)) + acctType = Account.Type.EMAIL + + # Create an account + contactAccount = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().getOrCreateAccount(acctType, data1, general.MODULE_NAME, abstractFile); + + # create relationship between accounts + Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().addRelationships(deviceAccount, [contactAccount], artifact); + oldName = name bbartifacts.append(artifact) diff --git a/InternalPythonModules/android/tangomessage.py b/InternalPythonModules/android/tangomessage.py index 04223f7fe1..6c775ba61f 100644 --- a/InternalPythonModules/android/tangomessage.py +++ b/InternalPythonModules/android/tangomessage.py @@ -55,6 +55,15 @@ class TangoMessageAnalyzer(general.AndroidComponentAnalyzer): def analyze(self, dataSource, fileManager, context): try: + # Create a 'Device' account using the data source device id + datasourceObjId = dataSource.getDataSource().getId() + ds = Case.getCurrentCase().getSleuthkitCase().getDataSource(datasourceObjId) + deviceID = ds.getDeviceId() + + global deviceAccount + deviceAccount = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().getOrCreateAccount(Account.Type.DEVICE, deviceID, general.MODULE_NAME, dataSource) + + absFiles = fileManager.findFiles(dataSource, "tc.db") for abstractFile in absFiles: try: diff --git a/InternalPythonModules/android/textmessage.py b/InternalPythonModules/android/textmessage.py index afca23cdf1..442d71ee95 100644 --- a/InternalPythonModules/android/textmessage.py +++ b/InternalPythonModules/android/textmessage.py @@ -42,6 +42,7 @@ from org.sleuthkit.datamodel import BlackboardArtifact from org.sleuthkit.datamodel import BlackboardAttribute from org.sleuthkit.datamodel import Content from org.sleuthkit.datamodel import TskCoreException +from org.sleuthkit.datamodel import Account import traceback import general @@ -56,6 +57,15 @@ class TextMessageAnalyzer(general.AndroidComponentAnalyzer): def analyze(self, dataSource, fileManager, context): try: + + # Create a 'Device' account using the data source device id + datasourceObjId = dataSource.getDataSource().getId() + ds = Case.getCurrentCase().getSleuthkitCase().getDataSource(datasourceObjId) + deviceID = ds.getDeviceId() + + global deviceAccount + deviceAccount = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().getOrCreateAccount(Account.Type.DEVICE, deviceID, general.MODULE_NAME, dataSource) + absFiles = fileManager.findFiles(dataSource, "mmssms.db") for abstractFile in absFiles: try: @@ -105,6 +115,12 @@ class TextMessageAnalyzer(general.AndroidComponentAnalyzer): artifact.addAttribute(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_TEXT, general.MODULE_NAME, body)) artifact.addAttribute(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_MESSAGE_TYPE, general.MODULE_NAME, "SMS Message")) + # Create an account + msgAccount = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().getOrCreateAccount(Account.Type.PHONE, address, general.MODULE_NAME, abstractFile); + + # create relationship between accounts + Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().addRelationships(deviceAccount, [msgAccount], artifact); + bbartifacts.append(artifact) try: # index the artifact for keyword search diff --git a/InternalPythonModules/android/wwfmessage.py b/InternalPythonModules/android/wwfmessage.py index 97f35869ed..ca458bdbd2 100644 --- a/InternalPythonModules/android/wwfmessage.py +++ b/InternalPythonModules/android/wwfmessage.py @@ -52,6 +52,18 @@ class WWFMessageAnalyzer(general.AndroidComponentAnalyzer): def analyze(self, dataSource, fileManager, context): try: + + global wwfAccountType + wwfAccountType = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().addAccountType("WWF", "Words with Friends") + + # Create a 'Device' account using the data source device id + datasourceObjId = dataSource.getDataSource().getId() + ds = Case.getCurrentCase().getSleuthkitCase().getDataSource(datasourceObjId) + deviceID = ds.getDeviceId() + + global deviceAccount + deviceAccount = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().getOrCreateAccount(Account.Type.DEVICE, deviceID, general.MODULE_NAME, dataSource) + absFiles = fileManager.findFiles(dataSource, "WordsFramework") for abstractFile in absFiles: try: @@ -95,6 +107,12 @@ class WWFMessageAnalyzer(general.AndroidComponentAnalyzer): artifact.addAttribute(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_TEXT, general.MODULE_NAME, message)) artifact.addAttribute(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_MESSAGE_TYPE, general.MODULE_NAME, "Words With Friends Message")) + # Create an account + wwfAccount = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().getOrCreateAccount(wwfAccountType, user_id, general.MODULE_NAME, abstractFile); + + # create relationship between accounts + Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().addRelationships(deviceAccount, [wwfAccount], artifact); + try: # index the artifact for keyword search blackboard = Case.getCurrentCase().getServices().getBlackboard() From eb4293e60dc46f247849befaa903964be654dea1 Mon Sep 17 00:00:00 2001 From: Raman Date: Wed, 6 Sep 2017 14:23:43 -0400 Subject: [PATCH 005/127] 853: Android python modules create accounts & relationships - fix Codacy issues in previous commit --- InternalPythonModules/android/calllog.py | 23 ++++++++-------- InternalPythonModules/android/contact.py | 27 ++++++++++--------- InternalPythonModules/android/tangomessage.py | 15 ++++++----- InternalPythonModules/android/textmessage.py | 22 ++++++++------- InternalPythonModules/android/wwfmessage.py | 27 ++++++++++--------- 5 files changed, 61 insertions(+), 53 deletions(-) diff --git a/InternalPythonModules/android/calllog.py b/InternalPythonModules/android/calllog.py index 13bccac4f9..d8ce3aa51e 100644 --- a/InternalPythonModules/android/calllog.py +++ b/InternalPythonModules/android/calllog.py @@ -48,6 +48,8 @@ from org.sleuthkit.datamodel import Account import traceback import general +deviceAccount = None + """ Locates a variety of different call log databases, parses them, and populates the blackboard. """ @@ -83,15 +85,14 @@ class CallLogAnalyzer(general.AndroidComponentAnalyzer): def analyze(self, dataSource, fileManager, context): try: - # Create a 'Device' account using the data source device id - datasourceObjId = dataSource.getDataSource().getId() - ds = Case.getCurrentCase().getSleuthkitCase().getDataSource(datasourceObjId) - deviceID = ds.getDeviceId() + # Create a 'Device' account using the data source device id + datasourceObjId = dataSource.getDataSource().getId() + ds = Case.getCurrentCase().getSleuthkitCase().getDataSource(datasourceObjId) + deviceID = ds.getDeviceId() - global deviceAccount + global deviceAccount deviceAccount = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().getOrCreateAccount(Account.Type.DEVICE, deviceID, general.MODULE_NAME, dataSource) - - + absFiles = fileManager.findFiles(dataSource, "logs.db") absFiles.addAll(fileManager.findFiles(dataSource, "contacts.db")) absFiles.addAll(fileManager.findFiles(dataSource, "contacts2.db")) @@ -141,11 +142,11 @@ class CallLogAnalyzer(general.AndroidComponentAnalyzer): artifact.addAttribute(BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DIRECTION, general.MODULE_NAME, directionString)) artifact.addAttribute(BlackboardAttribute(ATTRIBUTE_TYPE.TSK_NAME, general.MODULE_NAME, name)) - # Create an account - calllogAccount = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().getOrCreateAccount(Account.Type.PHONE, number, general.MODULE_NAME, abstractFile); + # Create an account + calllogAccount = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().getOrCreateAccount(Account.Type.PHONE, number, general.MODULE_NAME, abstractFile); - # create relationship between accounts - Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().addRelationships(deviceAccount, [calllogAccount], artifact); + # create relationship between accounts + Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().addRelationships(deviceAccount, [calllogAccount], artifact); bbartifacts.append(artifact) diff --git a/InternalPythonModules/android/contact.py b/InternalPythonModules/android/contact.py index d41c3662dc..f285b1ca1d 100644 --- a/InternalPythonModules/android/contact.py +++ b/InternalPythonModules/android/contact.py @@ -46,6 +46,7 @@ from org.sleuthkit.datamodel import Account import traceback import general +deviceAccount = None """ Locates a variety of different contacts databases, parses them, and populates the blackboard. @@ -57,13 +58,13 @@ class ContactAnalyzer(general.AndroidComponentAnalyzer): def analyze(self, dataSource, fileManager, context): try: - - # Create a 'Device' account using the data source device id - datasourceObjId = dataSource.getDataSource().getId() - ds = Case.getCurrentCase().getSleuthkitCase().getDataSource(datasourceObjId) - deviceID = ds.getDeviceId() + + # Create a 'Device' account using the data source device id + datasourceObjId = dataSource.getDataSource().getId() + ds = Case.getCurrentCase().getSleuthkitCase().getDataSource(datasourceObjId) + deviceID = ds.getDeviceId() - global deviceAccount + global deviceAccount deviceAccount = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().getOrCreateAccount(Account.Type.DEVICE, deviceID, general.MODULE_NAME, dataSource) absFiles = fileManager.findFiles(dataSource, "contacts.db") @@ -140,17 +141,17 @@ class ContactAnalyzer(general.AndroidComponentAnalyzer): artifact.addAttribute(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_NAME, general.MODULE_NAME, name)) if mimetype == "vnd.android.cursor.item/phone_v2": artifact.addAttribute(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER, general.MODULE_NAME, data1)) - acctType = Account.Type.PHONE + acctType = Account.Type.PHONE else: artifact.addAttribute(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL, general.MODULE_NAME, data1)) - acctType = Account.Type.EMAIL + acctType = Account.Type.EMAIL - - # Create an account - contactAccount = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().getOrCreateAccount(acctType, data1, general.MODULE_NAME, abstractFile); + + # Create an account + contactAccount = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().getOrCreateAccount(acctType, data1, general.MODULE_NAME, abstractFile); - # create relationship between accounts - Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().addRelationships(deviceAccount, [contactAccount], artifact); + # create relationship between accounts + Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().addRelationships(deviceAccount, [contactAccount], artifact); oldName = name diff --git a/InternalPythonModules/android/tangomessage.py b/InternalPythonModules/android/tangomessage.py index 6c775ba61f..fb90587b17 100644 --- a/InternalPythonModules/android/tangomessage.py +++ b/InternalPythonModules/android/tangomessage.py @@ -45,6 +45,8 @@ from org.sleuthkit.datamodel import TskCoreException import traceback import general +deviceAccount = None + """ Locates database for the Tango app and adds info to blackboard. """ @@ -55,15 +57,14 @@ class TangoMessageAnalyzer(general.AndroidComponentAnalyzer): def analyze(self, dataSource, fileManager, context): try: - # Create a 'Device' account using the data source device id - datasourceObjId = dataSource.getDataSource().getId() - ds = Case.getCurrentCase().getSleuthkitCase().getDataSource(datasourceObjId) - deviceID = ds.getDeviceId() + # Create a 'Device' account using the data source device id + datasourceObjId = dataSource.getDataSource().getId() + ds = Case.getCurrentCase().getSleuthkitCase().getDataSource(datasourceObjId) + deviceID = ds.getDeviceId() - global deviceAccount + global deviceAccount deviceAccount = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().getOrCreateAccount(Account.Type.DEVICE, deviceID, general.MODULE_NAME, dataSource) - - + absFiles = fileManager.findFiles(dataSource, "tc.db") for abstractFile in absFiles: try: diff --git a/InternalPythonModules/android/textmessage.py b/InternalPythonModules/android/textmessage.py index 442d71ee95..87898fca97 100644 --- a/InternalPythonModules/android/textmessage.py +++ b/InternalPythonModules/android/textmessage.py @@ -47,6 +47,8 @@ from org.sleuthkit.datamodel import Account import traceback import general +deviceAccount = None + """ Finds database with SMS/MMS messages and adds them to blackboard. """ @@ -58,14 +60,14 @@ class TextMessageAnalyzer(general.AndroidComponentAnalyzer): def analyze(self, dataSource, fileManager, context): try: - # Create a 'Device' account using the data source device id - datasourceObjId = dataSource.getDataSource().getId() - ds = Case.getCurrentCase().getSleuthkitCase().getDataSource(datasourceObjId) - deviceID = ds.getDeviceId() + # Create a 'Device' account using the data source device id + datasourceObjId = dataSource.getDataSource().getId() + ds = Case.getCurrentCase().getSleuthkitCase().getDataSource(datasourceObjId) + deviceID = ds.getDeviceId() - global deviceAccount + global deviceAccount deviceAccount = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().getOrCreateAccount(Account.Type.DEVICE, deviceID, general.MODULE_NAME, dataSource) - + absFiles = fileManager.findFiles(dataSource, "mmssms.db") for abstractFile in absFiles: try: @@ -115,11 +117,11 @@ class TextMessageAnalyzer(general.AndroidComponentAnalyzer): artifact.addAttribute(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_TEXT, general.MODULE_NAME, body)) artifact.addAttribute(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_MESSAGE_TYPE, general.MODULE_NAME, "SMS Message")) - # Create an account - msgAccount = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().getOrCreateAccount(Account.Type.PHONE, address, general.MODULE_NAME, abstractFile); + # Create an account + msgAccount = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().getOrCreateAccount(Account.Type.PHONE, address, general.MODULE_NAME, abstractFile); - # create relationship between accounts - Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().addRelationships(deviceAccount, [msgAccount], artifact); + # create relationship between accounts + Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().addRelationships(deviceAccount, [msgAccount], artifact); bbartifacts.append(artifact) try: diff --git a/InternalPythonModules/android/wwfmessage.py b/InternalPythonModules/android/wwfmessage.py index ca458bdbd2..4365c7df98 100644 --- a/InternalPythonModules/android/wwfmessage.py +++ b/InternalPythonModules/android/wwfmessage.py @@ -42,6 +42,9 @@ from org.sleuthkit.datamodel import TskCoreException import traceback import general +wwfAccountType = None +deviceAccount = None + """ Analyzes messages from Words With Friends """ @@ -53,17 +56,17 @@ class WWFMessageAnalyzer(general.AndroidComponentAnalyzer): def analyze(self, dataSource, fileManager, context): try: - global wwfAccountType - wwfAccountType = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().addAccountType("WWF", "Words with Friends") + global wwfAccountType + wwfAccountType = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().addAccountType("WWF", "Words with Friends") - # Create a 'Device' account using the data source device id - datasourceObjId = dataSource.getDataSource().getId() - ds = Case.getCurrentCase().getSleuthkitCase().getDataSource(datasourceObjId) - deviceID = ds.getDeviceId() + # Create a 'Device' account using the data source device id + datasourceObjId = dataSource.getDataSource().getId() + ds = Case.getCurrentCase().getSleuthkitCase().getDataSource(datasourceObjId) + deviceID = ds.getDeviceId() - global deviceAccount + global deviceAccount deviceAccount = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().getOrCreateAccount(Account.Type.DEVICE, deviceID, general.MODULE_NAME, dataSource) - + absFiles = fileManager.findFiles(dataSource, "WordsFramework") for abstractFile in absFiles: try: @@ -107,11 +110,11 @@ class WWFMessageAnalyzer(general.AndroidComponentAnalyzer): artifact.addAttribute(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_TEXT, general.MODULE_NAME, message)) artifact.addAttribute(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_MESSAGE_TYPE, general.MODULE_NAME, "Words With Friends Message")) - # Create an account - wwfAccount = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().getOrCreateAccount(wwfAccountType, user_id, general.MODULE_NAME, abstractFile); + # Create an account + wwfAccount = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().getOrCreateAccount(wwfAccountType, user_id, general.MODULE_NAME, abstractFile); - # create relationship between accounts - Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().addRelationships(deviceAccount, [wwfAccount], artifact); + # create relationship between accounts + Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().addRelationships(deviceAccount, [wwfAccount], artifact); try: # index the artifact for keyword search From 21a83dce635308e75dba9bf5c5fb86c8ef922684 Mon Sep 17 00:00:00 2001 From: Raman Date: Wed, 6 Sep 2017 14:40:23 -0400 Subject: [PATCH 006/127] 853: Android python modules create accounts & relationships - Fixing Codacy issues. --- InternalPythonModules/android/calllog.py | 2 +- InternalPythonModules/android/contact.py | 2 +- InternalPythonModules/android/tangomessage.py | 2 +- InternalPythonModules/android/textmessage.py | 2 +- InternalPythonModules/android/wwfmessage.py | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/InternalPythonModules/android/calllog.py b/InternalPythonModules/android/calllog.py index d8ce3aa51e..ce51edabfb 100644 --- a/InternalPythonModules/android/calllog.py +++ b/InternalPythonModules/android/calllog.py @@ -92,7 +92,7 @@ class CallLogAnalyzer(general.AndroidComponentAnalyzer): global deviceAccount deviceAccount = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().getOrCreateAccount(Account.Type.DEVICE, deviceID, general.MODULE_NAME, dataSource) - + absFiles = fileManager.findFiles(dataSource, "logs.db") absFiles.addAll(fileManager.findFiles(dataSource, "contacts.db")) absFiles.addAll(fileManager.findFiles(dataSource, "contacts2.db")) diff --git a/InternalPythonModules/android/contact.py b/InternalPythonModules/android/contact.py index f285b1ca1d..6a96675cd8 100644 --- a/InternalPythonModules/android/contact.py +++ b/InternalPythonModules/android/contact.py @@ -58,7 +58,7 @@ class ContactAnalyzer(general.AndroidComponentAnalyzer): def analyze(self, dataSource, fileManager, context): try: - + # Create a 'Device' account using the data source device id datasourceObjId = dataSource.getDataSource().getId() ds = Case.getCurrentCase().getSleuthkitCase().getDataSource(datasourceObjId) diff --git a/InternalPythonModules/android/tangomessage.py b/InternalPythonModules/android/tangomessage.py index fb90587b17..a8c713f83a 100644 --- a/InternalPythonModules/android/tangomessage.py +++ b/InternalPythonModules/android/tangomessage.py @@ -64,7 +64,7 @@ class TangoMessageAnalyzer(general.AndroidComponentAnalyzer): global deviceAccount deviceAccount = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().getOrCreateAccount(Account.Type.DEVICE, deviceID, general.MODULE_NAME, dataSource) - + absFiles = fileManager.findFiles(dataSource, "tc.db") for abstractFile in absFiles: try: diff --git a/InternalPythonModules/android/textmessage.py b/InternalPythonModules/android/textmessage.py index 87898fca97..38f0855a7c 100644 --- a/InternalPythonModules/android/textmessage.py +++ b/InternalPythonModules/android/textmessage.py @@ -67,7 +67,7 @@ class TextMessageAnalyzer(general.AndroidComponentAnalyzer): global deviceAccount deviceAccount = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().getOrCreateAccount(Account.Type.DEVICE, deviceID, general.MODULE_NAME, dataSource) - + absFiles = fileManager.findFiles(dataSource, "mmssms.db") for abstractFile in absFiles: try: diff --git a/InternalPythonModules/android/wwfmessage.py b/InternalPythonModules/android/wwfmessage.py index 4365c7df98..1c0c481be9 100644 --- a/InternalPythonModules/android/wwfmessage.py +++ b/InternalPythonModules/android/wwfmessage.py @@ -66,7 +66,7 @@ class WWFMessageAnalyzer(general.AndroidComponentAnalyzer): global deviceAccount deviceAccount = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().getOrCreateAccount(Account.Type.DEVICE, deviceID, general.MODULE_NAME, dataSource) - + absFiles = fileManager.findFiles(dataSource, "WordsFramework") for abstractFile in absFiles: try: From 942d703d331b15c4e79d5af4ccae6bfbe58b1199 Mon Sep 17 00:00:00 2001 From: Raman Date: Wed, 6 Sep 2017 14:49:21 -0400 Subject: [PATCH 007/127] Fix codacy issues --- InternalPythonModules/android/contact.py | 1 - 1 file changed, 1 deletion(-) diff --git a/InternalPythonModules/android/contact.py b/InternalPythonModules/android/contact.py index 6a96675cd8..345af36d8f 100644 --- a/InternalPythonModules/android/contact.py +++ b/InternalPythonModules/android/contact.py @@ -146,7 +146,6 @@ class ContactAnalyzer(general.AndroidComponentAnalyzer): artifact.addAttribute(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL, general.MODULE_NAME, data1)) acctType = Account.Type.EMAIL - # Create an account contactAccount = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().getOrCreateAccount(acctType, data1, general.MODULE_NAME, abstractFile); From 13e23cc24e06ff49f15dc6461527b6dba6f48f1d Mon Sep 17 00:00:00 2001 From: Raman Date: Wed, 6 Sep 2017 14:56:13 -0400 Subject: [PATCH 008/127] Fix Codacy issues --- InternalPythonModules/android/contact.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/InternalPythonModules/android/contact.py b/InternalPythonModules/android/contact.py index 345af36d8f..c863f2ba4e 100644 --- a/InternalPythonModules/android/contact.py +++ b/InternalPythonModules/android/contact.py @@ -151,7 +151,7 @@ class ContactAnalyzer(general.AndroidComponentAnalyzer): # create relationship between accounts Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().addRelationships(deviceAccount, [contactAccount], artifact); - + oldName = name bbartifacts.append(artifact) From 45ecf0bdfda0e7cab0b616b6e2b81135804f463c Mon Sep 17 00:00:00 2001 From: Raman Date: Thu, 7 Sep 2017 11:34:40 -0400 Subject: [PATCH 009/127] 853: Android python modules create accounts & relationships - fixed imports --- InternalPythonModules/android/tangomessage.py | 1 + InternalPythonModules/android/wwfmessage.py | 1 + 2 files changed, 2 insertions(+) diff --git a/InternalPythonModules/android/tangomessage.py b/InternalPythonModules/android/tangomessage.py index a8c713f83a..c9923e2d8f 100644 --- a/InternalPythonModules/android/tangomessage.py +++ b/InternalPythonModules/android/tangomessage.py @@ -41,6 +41,7 @@ from org.sleuthkit.datamodel import BlackboardArtifact from org.sleuthkit.datamodel import BlackboardAttribute from org.sleuthkit.datamodel import Content from org.sleuthkit.datamodel import TskCoreException +from org.sleuthkit.datamodel import Account import traceback import general diff --git a/InternalPythonModules/android/wwfmessage.py b/InternalPythonModules/android/wwfmessage.py index 1c0c481be9..90554866c5 100644 --- a/InternalPythonModules/android/wwfmessage.py +++ b/InternalPythonModules/android/wwfmessage.py @@ -38,6 +38,7 @@ from org.sleuthkit.datamodel import BlackboardArtifact from org.sleuthkit.datamodel import BlackboardAttribute from org.sleuthkit.datamodel import Content from org.sleuthkit.datamodel import TskCoreException +from org.sleuthkit.datamodel import Account import traceback import general From c0473d03628a0cbf3bcf5b65d0169920a4357add Mon Sep 17 00:00:00 2001 From: Raman Date: Fri, 15 Sep 2017 09:37:11 -0400 Subject: [PATCH 010/127] Address Codacy issues. --- .../ThunderbirdMboxFileIngestModule.java | 72 ++++++++----------- 1 file changed, 29 insertions(+), 43 deletions(-) diff --git a/thunderbirdparser/src/org/sleuthkit/autopsy/thunderbirdparser/ThunderbirdMboxFileIngestModule.java b/thunderbirdparser/src/org/sleuthkit/autopsy/thunderbirdparser/ThunderbirdMboxFileIngestModule.java index e82972519e..071d955f7d 100644 --- a/thunderbirdparser/src/org/sleuthkit/autopsy/thunderbirdparser/ThunderbirdMboxFileIngestModule.java +++ b/thunderbirdparser/src/org/sleuthkit/autopsy/thunderbirdparser/ThunderbirdMboxFileIngestModule.java @@ -21,6 +21,7 @@ package org.sleuthkit.autopsy.thunderbirdparser; import java.io.File; import java.io.IOException; import java.util.ArrayList; +import java.util.Collection; import java.util.HashSet; import java.util.List; import java.util.Set; @@ -399,9 +400,6 @@ public final class ThunderbirdMboxFileIngestModule implements FileIngestModule { long id = email.getId(); String localPath = email.getLocalPath(); - - - List senderAddressList = new ArrayList<>(); String senderAddress; senderAddressList.addAll(findEmailAddresess(from)); @@ -438,50 +436,27 @@ public final class ThunderbirdMboxFileIngestModule implements FileIngestModule { } }); - if (headers.isEmpty() == false) { - bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_HEADERS, EmailParserModuleFactory.getModuleName(), headers)); - } - if (from.isEmpty() == false) { - bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_EMAIL_FROM, EmailParserModuleFactory.getModuleName(), from)); - } - if (to.isEmpty() == false) { - bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_EMAIL_TO, EmailParserModuleFactory.getModuleName(), to)); - } - if (subject.isEmpty() == false) { - bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_SUBJECT, EmailParserModuleFactory.getModuleName(), subject)); - } - - if (dateL > 0) { - bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_RCVD, EmailParserModuleFactory.getModuleName(), dateL)); - bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_SENT, EmailParserModuleFactory.getModuleName(), dateL)); - } - if (body.isEmpty() == false) { - bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_EMAIL_CONTENT_PLAIN, EmailParserModuleFactory.getModuleName(), body)); - } + addEmailAttribute(headers, ATTRIBUTE_TYPE.TSK_HEADERS, bbattributes); + addEmailAttribute(from, ATTRIBUTE_TYPE.TSK_EMAIL_FROM, bbattributes); + addEmailAttribute(to, ATTRIBUTE_TYPE.TSK_EMAIL_TO, bbattributes); + addEmailAttribute(subject, ATTRIBUTE_TYPE.TSK_SUBJECT, bbattributes); - bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_MSG_ID, EmailParserModuleFactory.getModuleName(), ((id < 0L) ? NbBundle - .getMessage(this.getClass(), "ThunderbirdMboxFileIngestModule.notAvail") : String.valueOf(id)))); + addEmailAttribute(dateL, ATTRIBUTE_TYPE.TSK_DATETIME_RCVD, bbattributes); + addEmailAttribute(dateL, ATTRIBUTE_TYPE.TSK_DATETIME_SENT, bbattributes); - if (localPath.isEmpty() == false) { - bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PATH, EmailParserModuleFactory.getModuleName(), localPath)); - } else { - bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PATH, EmailParserModuleFactory.getModuleName(), "/foo/bar")); //NON-NLS - } + addEmailAttribute(body, ATTRIBUTE_TYPE.TSK_EMAIL_CONTENT_PLAIN, bbattributes); - if (cc.isEmpty() == false) { - bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_EMAIL_CC, EmailParserModuleFactory.getModuleName(), cc)); - } - if (bcc.isEmpty() == false) { - bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_EMAIL_BCC, EmailParserModuleFactory.getModuleName(), bcc)); - } + addEmailAttribute(((id < 0L) ? NbBundle.getMessage(this.getClass(), "ThunderbirdMboxFileIngestModule.notAvail") : String.valueOf(id)), + ATTRIBUTE_TYPE.TSK_MSG_ID, bbattributes); - if (bodyHTML.isEmpty() == false) { - bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_EMAIL_CONTENT_HTML, EmailParserModuleFactory.getModuleName(), bodyHTML)); - } - if (rtf.isEmpty() == false) { - bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_EMAIL_CONTENT_RTF, EmailParserModuleFactory.getModuleName(), rtf)); - } - + addEmailAttribute(((localPath.isEmpty() == false) ? localPath : "/foo/bar"), + ATTRIBUTE_TYPE.TSK_PATH, bbattributes); + + addEmailAttribute(cc, ATTRIBUTE_TYPE.TSK_EMAIL_CC, bbattributes); + addEmailAttribute(bodyHTML, ATTRIBUTE_TYPE.TSK_EMAIL_CONTENT_HTML, bbattributes); + addEmailAttribute(rtf, ATTRIBUTE_TYPE.TSK_EMAIL_CONTENT_RTF, bbattributes); + + try { bbart = abstractFile.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_EMAIL_MSG); @@ -504,6 +479,17 @@ public final class ThunderbirdMboxFileIngestModule implements FileIngestModule { return bbart; } + private void addEmailAttribute(String stringVal, ATTRIBUTE_TYPE attrType, Collection bbattributes) { + if (stringVal.isEmpty() == false) { + bbattributes.add(new BlackboardAttribute(attrType, EmailParserModuleFactory.getModuleName(), stringVal)); + } + } + private void addEmailAttribute(long longVal, ATTRIBUTE_TYPE attrType, Collection bbattributes) { + if (longVal > 0) { + bbattributes.add(new BlackboardAttribute(attrType, EmailParserModuleFactory.getModuleName(), longVal)); + } + } + void postErrorMessage(String subj, String details) { IngestMessage ingestMessage = IngestMessage.createErrorMessage(EmailParserModuleFactory.getModuleVersion(), subj, details); services.postMessage(ingestMessage); From 3649fb4497c30ec05fa0b670d73f35c9716445e9 Mon Sep 17 00:00:00 2001 From: Raman Date: Fri, 15 Sep 2017 11:14:17 -0400 Subject: [PATCH 011/127] Fix Codacy issue --- .../thunderbirdparser/ThunderbirdMboxFileIngestModule.java | 1 + 1 file changed, 1 insertion(+) diff --git a/thunderbirdparser/src/org/sleuthkit/autopsy/thunderbirdparser/ThunderbirdMboxFileIngestModule.java b/thunderbirdparser/src/org/sleuthkit/autopsy/thunderbirdparser/ThunderbirdMboxFileIngestModule.java index 071d955f7d..e9fa379ef2 100644 --- a/thunderbirdparser/src/org/sleuthkit/autopsy/thunderbirdparser/ThunderbirdMboxFileIngestModule.java +++ b/thunderbirdparser/src/org/sleuthkit/autopsy/thunderbirdparser/ThunderbirdMboxFileIngestModule.java @@ -501,5 +501,6 @@ public final class ThunderbirdMboxFileIngestModule implements FileIngestModule { @Override public void shutDown() { + // nothing to shut down } } From e5db6a6d16b2201f838007dbbd234be576b4c07c Mon Sep 17 00:00:00 2001 From: Raman Date: Thu, 21 Sep 2017 13:19:50 -0400 Subject: [PATCH 012/127] 850: New Contentviewer for Messages & Attachments --- Core/ivy.xml | 1 + Core/nbproject/project.properties | 3 + Core/nbproject/project.xml | 80 ++- .../autopsy/contentviewers/Bundle.properties | 21 + .../contentviewers/MessageContentViewer.form | 350 +++++++++++ .../contentviewers/MessageContentViewer.java | 562 ++++++++++++++++++ .../autopsy/contentviewers/Utilities.java | 8 + 7 files changed, 983 insertions(+), 42 deletions(-) create mode 100644 Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.form create mode 100644 Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java diff --git a/Core/ivy.xml b/Core/ivy.xml index b6cfe4a568..c3afd23afa 100755 --- a/Core/ivy.xml +++ b/Core/ivy.xml @@ -21,5 +21,6 @@ + diff --git a/Core/nbproject/project.properties b/Core/nbproject/project.properties index 30ce57d6f0..dc81a50d01 100755 --- a/Core/nbproject/project.properties +++ b/Core/nbproject/project.properties @@ -1,7 +1,10 @@ file.reference.activemq-all-5.11.1.jar=release/modules/ext/activemq-all-5.11.1.jar file.reference.c3p0-0.9.5.jar=release/modules/ext/c3p0-0.9.5.jar +file.reference.commons-dbcp2-2.1.1.jar=release\\modules\\ext\\commons-dbcp2-2.1.1.jar +file.reference.commons-pool2-2.4.2.jar=release\\modules\\ext\\commons-pool2-2.4.2.jar file.reference.jdom-2.0.5-contrib.jar=release/modules/ext/jdom-2.0.5-contrib.jar file.reference.jdom-2.0.5.jar=release/modules/ext/jdom-2.0.5.jar +file.reference.jsoup-1.10.3.jar=release/modules/ext/jsoup-1.10.3.jar file.reference.jython-standalone-2.7.0.jar=release/modules/ext/jython-standalone-2.7.0.jar file.reference.mchange-commons-java-0.2.9.jar=release/modules/ext/mchange-commons-java-0.2.9.jar file.reference.metadata-extractor-2.8.1.jar=release/modules/ext/metadata-extractor-2.8.1.jar diff --git a/Core/nbproject/project.xml b/Core/nbproject/project.xml index 0fa567cf00..b78e9fecdf 100755 --- a/Core/nbproject/project.xml +++ b/Core/nbproject/project.xml @@ -270,45 +270,53 @@ org.sleuthkit.autopsy.report org.sleuthkit.datamodel + + ext/xmpcore-5.1.2.jar + release/modules/ext/xmpcore-5.1.2.jar + + + ext/zookeeper-3.4.6.jar + release/modules/ext/zookeeper-3.4.6.jar + ext/jdom-2.0.5.jar release/modules/ext/jdom-2.0.5.jar - ext/postgresql-9.4.1211.jre7.jar - release/modules/ext/postgresql-9.4.1211.jre7.jar - - - ext/mchange-commons-java-0.2.9.jar - release/modules/ext/mchange-commons-java-0.2.9.jar - - - ext/c3p0-0.9.5.jar - release/modules/ext/c3p0-0.9.5.jar - - - ext/xmpcore-5.1.2.jar - release/modules/ext/xmpcore-5.1.2.jar + ext/tika-core-1.14.jar + release/modules/ext/tika-core-1.14.jar ext/StixLib.jar release/modules/ext/StixLib.jar + + ext/Tsk_DataModel_PostgreSQL.jar + release/modules/ext/Tsk_DataModel_PostgreSQL.jar + + + ext/curator-client-2.8.0.jar + release/modules/ext/curator-client-2.8.0.jar + ext/sqlite-jdbc-3.8.11.jar release/modules/ext/sqlite-jdbc-3.8.11.jar + + ext/activemq-all-5.11.1.jar + release/modules/ext/activemq-all-5.11.1.jar + ext/opencv-248.jar release/modules/ext/opencv-248.jar - ext/Rejistry-1.0-SNAPSHOT.jar - release/modules/ext/Rejistry-1.0-SNAPSHOT.jar + ext/curator-framework-2.8.0.jar + release/modules/ext/curator-framework-2.8.0.jar - ext/activemq-all-5.11.1.jar - release/modules/ext/activemq-all-5.11.1.jar + ext/commons-dbcp2-2.1.1.jar + release\modules\ext\commons-dbcp2-2.1.1.jar ext/Rejistry-1.0-SNAPSHOT.jar @@ -322,53 +330,41 @@ ext/sevenzipjbinding.jar release/modules/ext/sevenzipjbinding.jar + + ext/mchange-commons-java-0.2.9.jar + release/modules/ext/mchange-commons-java-0.2.9.jar + ext/sevenzipjbinding-AllPlatforms.jar release/modules/ext/sevenzipjbinding-AllPlatforms.jar - ext/tika-core-1.14.jar - release/modules/ext/tika-core-1.14.jar + ext/commons-pool2-2.4.2.jar + release\modules\ext\commons-pool2-2.4.2.jar ext/metadata-extractor-2.8.1.jar release/modules/ext/metadata-extractor-2.8.1.jar - ext/metadata-extractor-2.8.1.jar - release/modules/ext/metadata-extractor-2.8.1.jar + ext/jsoup-1.10.3.jar + release/modules/ext/jsoup-1.10.3.jar ext/jdom-2.0.5-contrib.jar release/modules/ext/jdom-2.0.5-contrib.jar - ext/Tsk_DataModel_PostgreSQL.jar - release/modules/ext/Tsk_DataModel_PostgreSQL.jar - - - ext/zookeeper-3.4.6.jar - release/modules/ext/zookeeper-3.4.6.jar - - - ext/curator-client-2.8.0.jar - release/modules/ext/curator-client-2.8.0.jar + ext/postgresql-9.4.1211.jre7.jar + release/modules/ext/postgresql-9.4.1211.jre7.jar ext/curator-recipes-2.8.0.jar release/modules/ext/curator-recipes-2.8.0.jar - ext/curator-framework-2.8.0.jar - release/modules/ext/curator-framework-2.8.0.jar - - - ext/commons-dbcp2-2.1.1.jar - release\modules\ext\commons-dbcp2-2.1.1.jar - - - ext/commons-pool2-2.4.2.jar - release\modules\ext\commons-pool2-2.4.2.jar + ext/c3p0-0.9.5.jar + release/modules/ext/c3p0-0.9.5.jar diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/Bundle.properties b/Core/src/org/sleuthkit/autopsy/contentviewers/Bundle.properties index f1a45c0a21..ed52040276 100755 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/Bundle.properties @@ -17,3 +17,24 @@ Metadata.toolTip=Displays metadata about the file. Metadata.nodeText.nonFilePassedIn=Non-file passed in Metadata.nodeText.text=From The Sleuth Kit istat Tool\: Metadata.nodeText.exceptionNotice.text=Error getting file metadata\: +MessageContentViewer.title=Message +MessageContentViewer.toolTip=Displays messages. +MessageContentViewer.jPanel2.TabConstraints.tabTitle=tab1 +MessageContentViewer.jPanel3.TabConstraints.tabTitle=tab2 +MessageContentViewer.jPanel4.TabConstraints.tabTitle=tab3 +MessageContentViewer.rtfbodyScrollPane.TabConstraints.tabTitle=RTF +MessageContentViewer.headersScrollPane.TabConstraints.tabTitle=Headers +MessageContentViewer.textbodyScrollPane.TabConstraints.tabTitle=Text +MessageContentViewer.fromText.text=from address goes here +MessageContentViewer.fromLabel.text=From: +MessageContentViewer.datetimeText.text=Right Anchored +MessageContentViewer.toText.text=to list goes here +MessageContentViewer.toLabel.text=To: +MessageContentViewer.ccText.text=cc list goes here +MessageContentViewer.subjectLabel.text=Subject: +MessageContentViewer.subjectText.text=jLabel6 +MessageContentViewer.directionText.text=direction +MessageContentViewer.ccLabel.text=CC: +MessageContentViewer.showImagesToggleButton.text=Show Images +MessageContentViewer.showImagesToggleButton.hide.text=Hide Images +MessageContentViewer.htmlbodyScrollPane.TabConstraints.tabTitle=HTML diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.form b/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.form new file mode 100644 index 0000000000..a83f08d765 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.form @@ -0,0 +1,350 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java b/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java new file mode 100644 index 0000000000..bdd07871fc --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java @@ -0,0 +1,562 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2013-2014 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.sleuthkit.autopsy.contentviewers; + +import java.awt.Component; +import java.util.logging.Level; +import org.openide.nodes.Node; +import org.openide.util.NbBundle; +import org.openide.util.lookup.ServiceProvider; +import org.sleuthkit.autopsy.corecomponentinterfaces.DataContentViewer; +import org.sleuthkit.autopsy.coreutils.Logger; +import org.sleuthkit.datamodel.BlackboardArtifact; +import org.sleuthkit.datamodel.BlackboardAttribute; +import org.sleuthkit.datamodel.TskCoreException; +import org.jsoup.Jsoup; +import org.jsoup.nodes.Document; + +/** + * Shows SMS/MMS/EMail messages + */ +@ServiceProvider(service = DataContentViewer.class, position = 4) +public class MessageContentViewer extends javax.swing.JPanel implements DataContentViewer { + + + private static final Logger LOGGER = Logger.getLogger(MessageContentViewer.class.getName()); + + private static final int HDR_TAB_INDEX = 0; + private static final int TEXT_TAB_INDEX = 1; + private static final int HTML_TAB_INDEX = 2; + private static final int RTF_TAB_INDEX = 3; + + private BlackboardArtifact artifact; // Artifact currently being displayed + + /** + * Creates new form MessageContentViewer + */ + public MessageContentViewer() { + initComponents(); + customizeComponents(); + } + + /** + * This method is called from within the constructor to initialize the form. + * WARNING: Do NOT modify this code. The content of this method is always + * regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // //GEN-BEGIN:initComponents + private void initComponents() { + + envelopePanel = new javax.swing.JPanel(); + fromLabel = new javax.swing.JLabel(); + datetimeText = new javax.swing.JLabel(); + fromText = new javax.swing.JLabel(); + toLabel = new javax.swing.JLabel(); + toText = new javax.swing.JLabel(); + ccLabel = new javax.swing.JLabel(); + ccText = new javax.swing.JLabel(); + subjectLabel = new javax.swing.JLabel(); + subjectText = new javax.swing.JLabel(); + directionText = new javax.swing.JLabel(); + msgbodyTabbedPane = new javax.swing.JTabbedPane(); + headersScrollPane = new javax.swing.JScrollPane(); + headersTextArea = new javax.swing.JTextArea(); + textbodyScrollPane = new javax.swing.JScrollPane(); + textbodyTextArea = new javax.swing.JTextArea(); + htmlbodyScrollPane = new javax.swing.JScrollPane(); + jPanel2 = new javax.swing.JPanel(); + jScrollPane2 = new javax.swing.JScrollPane(); + htmlbodyTextPane = new javax.swing.JTextPane(); + showImagesToggleButton = new javax.swing.JToggleButton(); + rtfbodyScrollPane = new javax.swing.JScrollPane(); + rtfbodyTextPane = new javax.swing.JTextPane(); + + setMinimumSize(new java.awt.Dimension(650, 546)); + + envelopePanel.setBackground(new java.awt.Color(204, 204, 204)); + + org.openide.awt.Mnemonics.setLocalizedText(fromLabel, org.openide.util.NbBundle.getMessage(MessageContentViewer.class, "MessageContentViewer.fromLabel.text")); // NOI18N + + org.openide.awt.Mnemonics.setLocalizedText(datetimeText, org.openide.util.NbBundle.getMessage(MessageContentViewer.class, "MessageContentViewer.datetimeText.text")); // NOI18N + + org.openide.awt.Mnemonics.setLocalizedText(fromText, org.openide.util.NbBundle.getMessage(MessageContentViewer.class, "MessageContentViewer.fromText.text")); // NOI18N + + org.openide.awt.Mnemonics.setLocalizedText(toLabel, org.openide.util.NbBundle.getMessage(MessageContentViewer.class, "MessageContentViewer.toLabel.text")); // NOI18N + + org.openide.awt.Mnemonics.setLocalizedText(toText, org.openide.util.NbBundle.getMessage(MessageContentViewer.class, "MessageContentViewer.toText.text")); // NOI18N + + org.openide.awt.Mnemonics.setLocalizedText(ccLabel, org.openide.util.NbBundle.getMessage(MessageContentViewer.class, "MessageContentViewer.ccLabel.text")); // NOI18N + + org.openide.awt.Mnemonics.setLocalizedText(ccText, org.openide.util.NbBundle.getMessage(MessageContentViewer.class, "MessageContentViewer.ccText.text")); // NOI18N + + org.openide.awt.Mnemonics.setLocalizedText(subjectLabel, org.openide.util.NbBundle.getMessage(MessageContentViewer.class, "MessageContentViewer.subjectLabel.text")); // NOI18N + + org.openide.awt.Mnemonics.setLocalizedText(subjectText, org.openide.util.NbBundle.getMessage(MessageContentViewer.class, "MessageContentViewer.subjectText.text")); // NOI18N + + org.openide.awt.Mnemonics.setLocalizedText(directionText, org.openide.util.NbBundle.getMessage(MessageContentViewer.class, "MessageContentViewer.directionText.text")); // NOI18N + + javax.swing.GroupLayout envelopePanelLayout = new javax.swing.GroupLayout(envelopePanel); + envelopePanel.setLayout(envelopePanelLayout); + envelopePanelLayout.setHorizontalGroup( + envelopePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(envelopePanelLayout.createSequentialGroup() + .addContainerGap() + .addGroup(envelopePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(envelopePanelLayout.createSequentialGroup() + .addGroup(envelopePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(fromLabel) + .addComponent(toLabel)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(envelopePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(fromText, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(toText, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addGroup(envelopePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(envelopePanelLayout.createSequentialGroup() + .addGap(8, 8, 8) + .addComponent(datetimeText)) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, envelopePanelLayout.createSequentialGroup() + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(directionText)))) + .addGroup(envelopePanelLayout.createSequentialGroup() + .addGroup(envelopePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(envelopePanelLayout.createSequentialGroup() + .addComponent(ccLabel) + .addGap(18, 18, 18) + .addComponent(ccText)) + .addGroup(envelopePanelLayout.createSequentialGroup() + .addComponent(subjectLabel) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(subjectText, javax.swing.GroupLayout.PREFERRED_SIZE, 400, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addGap(0, 0, Short.MAX_VALUE))) + .addContainerGap()) + ); + envelopePanelLayout.setVerticalGroup( + envelopePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(envelopePanelLayout.createSequentialGroup() + .addContainerGap() + .addGroup(envelopePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(fromLabel) + .addComponent(datetimeText) + .addComponent(fromText)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(envelopePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(toLabel) + .addComponent(toText) + .addComponent(directionText)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(envelopePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(ccLabel) + .addComponent(ccText)) + .addGap(18, 18, 18) + .addGroup(envelopePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(subjectLabel) + .addComponent(subjectText)) + .addContainerGap(24, Short.MAX_VALUE)) + ); + + headersTextArea.setEditable(false); + headersTextArea.setColumns(20); + headersTextArea.setRows(5); + headersScrollPane.setViewportView(headersTextArea); + + msgbodyTabbedPane.addTab(org.openide.util.NbBundle.getMessage(MessageContentViewer.class, "MessageContentViewer.headersScrollPane.TabConstraints.tabTitle"), headersScrollPane); // NOI18N + + textbodyTextArea.setEditable(false); + textbodyTextArea.setColumns(20); + textbodyTextArea.setRows(5); + textbodyScrollPane.setViewportView(textbodyTextArea); + + msgbodyTabbedPane.addTab(org.openide.util.NbBundle.getMessage(MessageContentViewer.class, "MessageContentViewer.textbodyScrollPane.TabConstraints.tabTitle"), textbodyScrollPane); // NOI18N + + htmlbodyTextPane.setEditable(false); + jScrollPane2.setViewportView(htmlbodyTextPane); + + org.openide.awt.Mnemonics.setLocalizedText(showImagesToggleButton, org.openide.util.NbBundle.getMessage(MessageContentViewer.class, "MessageContentViewer.showImagesToggleButton.text")); // NOI18N + showImagesToggleButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + showImagesToggleButtonActionPerformed(evt); + } + }); + + javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2); + jPanel2.setLayout(jPanel2Layout); + jPanel2Layout.setHorizontalGroup( + jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel2Layout.createSequentialGroup() + .addContainerGap(536, Short.MAX_VALUE) + .addComponent(showImagesToggleButton) + .addContainerGap()) + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel2Layout.createSequentialGroup() + .addContainerGap() + .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 623, Short.MAX_VALUE) + .addContainerGap())) + ); + jPanel2Layout.setVerticalGroup( + jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel2Layout.createSequentialGroup() + .addContainerGap() + .addComponent(showImagesToggleButton) + .addContainerGap(333, Short.MAX_VALUE)) + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel2Layout.createSequentialGroup() + .addGap(0, 34, Short.MAX_VALUE) + .addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 333, javax.swing.GroupLayout.PREFERRED_SIZE))) + ); + + htmlbodyScrollPane.setViewportView(jPanel2); + + msgbodyTabbedPane.addTab(org.openide.util.NbBundle.getMessage(MessageContentViewer.class, "MessageContentViewer.htmlbodyScrollPane.TabConstraints.tabTitle"), htmlbodyScrollPane); // NOI18N + + rtfbodyTextPane.setEditable(false); + rtfbodyScrollPane.setViewportView(rtfbodyTextPane); + + msgbodyTabbedPane.addTab(org.openide.util.NbBundle.getMessage(MessageContentViewer.class, "MessageContentViewer.rtfbodyScrollPane.TabConstraints.tabTitle"), rtfbodyScrollPane); // NOI18N + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addContainerGap() + .addComponent(envelopePanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addContainerGap()) + .addComponent(msgbodyTabbedPane) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addComponent(envelopePanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(msgbodyTabbedPane, javax.swing.GroupLayout.PREFERRED_SIZE, 397, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap()) + ); + }// //GEN-END:initComponents + + private void showImagesToggleButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_showImagesToggleButtonActionPerformed + + try { + BlackboardAttribute attr = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_CONTENT_HTML)); + if (attr != null && !attr.getValueString().isEmpty()) { + + if (showImagesToggleButton.isSelected()) { + showImagesToggleButton.setText(org.openide.util.NbBundle.getMessage(MessageContentViewer.class, "MessageContentViewer.showImagesToggleButton.hide.text")); + + this.htmlbodyTextPane.setText("" + attr.getValueString() + ""); + } + else { + showImagesToggleButton.setText(org.openide.util.NbBundle.getMessage(MessageContentViewer.class, "MessageContentViewer.showImagesToggleButton.text")); + + this.htmlbodyTextPane.setText("" + cleanseHTML(attr.getValueString()) + ""); + } + } + } catch (TskCoreException ex) { + LOGGER.log(Level.WARNING, "Failed to get attributes for email message.", ex); //NON-NLS + } + }//GEN-LAST:event_showImagesToggleButtonActionPerformed + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JLabel ccLabel; + private javax.swing.JLabel ccText; + private javax.swing.JLabel datetimeText; + private javax.swing.JLabel directionText; + private javax.swing.JPanel envelopePanel; + private javax.swing.JLabel fromLabel; + private javax.swing.JLabel fromText; + private javax.swing.JScrollPane headersScrollPane; + private javax.swing.JTextArea headersTextArea; + private javax.swing.JScrollPane htmlbodyScrollPane; + private javax.swing.JTextPane htmlbodyTextPane; + private javax.swing.JPanel jPanel2; + private javax.swing.JScrollPane jScrollPane2; + private javax.swing.JTabbedPane msgbodyTabbedPane; + private javax.swing.JScrollPane rtfbodyScrollPane; + private javax.swing.JTextPane rtfbodyTextPane; + private javax.swing.JToggleButton showImagesToggleButton; + private javax.swing.JLabel subjectLabel; + private javax.swing.JLabel subjectText; + private javax.swing.JScrollPane textbodyScrollPane; + private javax.swing.JTextArea textbodyTextArea; + private javax.swing.JLabel toLabel; + private javax.swing.JLabel toText; + // End of variables declaration//GEN-END:variables + + private void customizeComponents() { + // do any customizations here + Utilities.configureTextPaneAsHtml(htmlbodyTextPane); + Utilities.configureTextPaneAsRtf(rtfbodyTextPane); + + } + + @Override + public void setNode(Node node) { + + artifact = node.getLookup().lookup(BlackboardArtifact.class); + + if (artifact == null) { + return; + } + + if (artifact.getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_MESSAGE.getTypeID()) { + displayMsg(); + } + else if (artifact.getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_EMAIL_MSG.getTypeID()) { + displayEmailMsg(); + } + + } + + @Override + public String getTitle() { + return NbBundle.getMessage(this.getClass(), "MessageContentViewer.title"); + } + + @Override + public String getToolTip() { + return NbBundle.getMessage(this.getClass(), "MessageContentViewer.toolTip"); + } + + @Override + public DataContentViewer createInstance() { + return new MessageContentViewer(); + } + + @Override + public Component getComponent() { + return this; + } + + @Override + public void resetComponent() { + // reset all fields + } + + @Override + public boolean isSupported(Node node) { + BlackboardArtifact artifact = node.getLookup().lookup(BlackboardArtifact.class); + return ( (artifact != null) + && ((artifact.getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_EMAIL_MSG.getTypeID()) + || (artifact.getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_MESSAGE.getTypeID()))); + } + + @Override + public int isPreferred(Node node) { + + if ( isSupported(node)){ + return 6; + } + return 0; + } + + + private void displayEmailMsg() + { + directionText.setVisible(false); + + showImagesToggleButton.setVisible(false); + showImagesToggleButton.setText("Show Images"); + showImagesToggleButton.setSelected(false); + + try { + BlackboardAttribute attr = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_FROM)); + this.fromText.setText(attr.getValueString()); + + attr = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_TO)); + if (attr != null) { + this.toText.setText(attr.getValueString()); + } + + + attr = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_CC)); + if (attr != null && !attr.getValueString().isEmpty()) { + this.ccText.setVisible(true); + this.ccText.setText(attr.getValueString()); + } + else { + this.ccText.setVisible(false); + } + + attr = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SUBJECT)); + if (attr != null && !attr.getValueString().isEmpty()) { + this.subjectText.setVisible(true); + this.subjectText.setText(attr.getValueString()); + } + else { + this.subjectText.setVisible(false); + } + + attr = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_RCVD)); + if (attr != null && !attr.getDisplayString().isEmpty()) { + this.datetimeText.setVisible(true); + this.datetimeText.setText(attr.getDisplayString()); + } + else { + this.datetimeText.setVisible(false); + } + + int selectedTabIndex = -1; + attr = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_CONTENT_PLAIN)); + if (attr != null && !attr.getValueString().isEmpty()) { + this.textbodyTextArea.setVisible(true); + this.textbodyTextArea.setText(attr.getValueString()); + + msgbodyTabbedPane.setEnabledAt(TEXT_TAB_INDEX, true); + selectedTabIndex = TEXT_TAB_INDEX; + } + else { + msgbodyTabbedPane.setEnabledAt(TEXT_TAB_INDEX, false); + } + + attr = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_CONTENT_HTML)); + if (attr != null && !attr.getValueString().isEmpty()) { + + this.showImagesToggleButton.setVisible(true); + + + this.htmlbodyTextPane.setVisible(true); + this.htmlbodyTextPane.setText("" + cleanseHTML(attr.getValueString()) + ""); + //this.htmlbodyTextPane.setText(cleanseHTML(attr.getValueString())); + + msgbodyTabbedPane.setEnabledAt(HTML_TAB_INDEX, true); + selectedTabIndex = HTML_TAB_INDEX; + } + else { + msgbodyTabbedPane.setEnabledAt(HTML_TAB_INDEX, false); + this.htmlbodyTextPane.setVisible(false); + } + + attr = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_CONTENT_RTF)); + if (attr != null && !attr.getValueString().isEmpty()) { + + this.rtfbodyTextPane.setVisible(true); + this.rtfbodyTextPane.setText(attr.getValueString()); + + msgbodyTabbedPane.setEnabledAt(RTF_TAB_INDEX, true); + selectedTabIndex = RTF_TAB_INDEX; + } + else { + msgbodyTabbedPane.setEnabledAt(RTF_TAB_INDEX, false); + } + + attr = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_HEADERS)); + if (attr != null && !attr.getValueString().isEmpty()) { + this.headersTextArea.setVisible(true); + this.headersTextArea.setText(attr.getValueString()); + if (selectedTabIndex < 0) { + selectedTabIndex = HDR_TAB_INDEX; + } + } + else { + msgbodyTabbedPane.setEnabledAt(HDR_TAB_INDEX, false); + } + + msgbodyTabbedPane.setSelectedIndex(selectedTabIndex); + } + catch (TskCoreException ex) { + LOGGER.log(Level.WARNING, "Failed to get attributes for email message.", ex); //NON-NLS + } + } + + private void displayMsg() { + + this.ccText.setVisible(false); + this.showImagesToggleButton.setVisible(false); + msgbodyTabbedPane.setEnabledAt(HTML_TAB_INDEX, false); + msgbodyTabbedPane.setEnabledAt(RTF_TAB_INDEX, false); + msgbodyTabbedPane.setEnabledAt(HDR_TAB_INDEX, false); + + try { + + BlackboardAttribute attr = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_FROM)); + if (attr != null) { + this.fromText.setText(attr.getValueString()); + }else { + this.fromText.setVisible(false); + } + + attr = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_TO)); + if (attr != null) { + this.toText.setText(attr.getValueString()); + }else { + this.toText.setVisible(false); + } + + attr = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DIRECTION)); + if (attr != null) { + this.directionText.setText(attr.getValueString()); + }else { + this.directionText.setVisible(false); + } + + attr = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SUBJECT)); + if (attr != null && !attr.getValueString().isEmpty()) { + this.subjectText.setVisible(true); + this.subjectText.setText(attr.getValueString()); + } + else { + this.subjectText.setVisible(false); + } + + attr = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME)); + if (attr != null && !attr.getDisplayString().isEmpty()) { + this.datetimeText.setVisible(true); + this.datetimeText.setText(attr.getDisplayString()); + } + else { + this.datetimeText.setVisible(false); + } + + + attr = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_TEXT)); + if (attr != null && !attr.getValueString().isEmpty()) { + this.textbodyTextArea.setVisible(true); + this.textbodyTextArea.setText(attr.getValueString()); + + msgbodyTabbedPane.setEnabledAt(TEXT_TAB_INDEX, true); + } + else { + msgbodyTabbedPane.setEnabledAt(TEXT_TAB_INDEX, false); + } + msgbodyTabbedPane.setSelectedIndex(TEXT_TAB_INDEX); + } + catch (TskCoreException ex) { + LOGGER.log(Level.WARNING, "Failed to get attributes for message.", ex); //NON-NLS + } + + } + + /** + * Cleans out input HTML string + */ + private String cleanseHTML(String htmlInString) { + + Document doc = Jsoup.parse(htmlInString); + + // fix all img tags + doc.select("img[src]").forEach((img) -> { + img.attr("src", ""); + }); + + return doc.html(); + + } +} diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/Utilities.java b/Core/src/org/sleuthkit/autopsy/contentviewers/Utilities.java index 99a4f44585..96bc211890 100755 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/Utilities.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/Utilities.java @@ -21,6 +21,7 @@ package org.sleuthkit.autopsy.contentviewers; import javax.swing.JTextPane; import javax.swing.text.html.HTMLEditorKit; import javax.swing.text.html.StyleSheet; +import javax.swing.text.rtf.RTFEditorKit; /** * @@ -47,4 +48,11 @@ public class Utilities { styleSheet.addRule("th {font-family:Arial, 'ヒラギノ角ゴ Pro W3','Hiragino Kaku Gothic Pro','メイリオ',Meiryo,'MS Pゴシック','MS PGothic',sans-serif;font-size:14pt;overflow:hidden;padding-right:5px;padding-left:5px;font-weight:bold;}"); //NON-NLS styleSheet.addRule("p {font-family:Arial, 'ヒラギノ角ゴ Pro W3','Hiragino Kaku Gothic Pro','メイリオ',Meiryo,'MS Pゴシック','MS PGothic',sans-serif;font-size:14pt;}"); //NON-NLS } + + public static void configureTextPaneAsRtf(JTextPane pane) { + + pane.setContentType("text/html;charset=UTF-8"); //NON-NLS + RTFEditorKit rtfkit = new RTFEditorKit(); + pane.setEditorKit(rtfkit); + } } From 236ff62a94cdef0f48ced3a6797ea02c61f52c85 Mon Sep 17 00:00:00 2001 From: Raman Date: Mon, 2 Oct 2017 11:10:37 -0400 Subject: [PATCH 013/127] 857: Reconcile Unique Accounts with Credit Card Review - Added Account Instances - Use a orthogonal account_id as ID for Accounts, not an obj_id in tsk_objects - Addressed other review comments. --- .../autopsy/datamodel/accounts/Accounts.java | 4 +++- InternalPythonModules/android/calllog.py | 10 +++++----- InternalPythonModules/android/contact.py | 12 ++++++------ InternalPythonModules/android/tangomessage.py | 6 +++--- InternalPythonModules/android/textmessage.py | 10 +++++----- InternalPythonModules/android/wwfmessage.py | 10 +++++----- .../keywordsearch/ExtractedContentViewer.java | 9 ++++++++- .../autopsy/keywordsearch/RegexQuery.java | 7 +++++-- .../keywordsearch/TermsComponentQuery.java | 6 ++++-- .../ThunderbirdMboxFileIngestModule.java | 15 ++++++++------- 10 files changed, 52 insertions(+), 37 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/accounts/Accounts.java b/Core/src/org/sleuthkit/autopsy/datamodel/accounts/Accounts.java index 1c38b4080d..b27ffd9d38 100755 --- a/Core/src/org/sleuthkit/autopsy/datamodel/accounts/Accounts.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/accounts/Accounts.java @@ -71,6 +71,7 @@ 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.AccountInstance; import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE; import org.sleuthkit.datamodel.BlackboardAttribute; @@ -1427,7 +1428,8 @@ final public class Accounts implements AutopsyVisitableItem { final Collection artifacts = Utilities.actionsGlobalContext().lookupAll(BlackboardArtifact.class); artifacts.forEach(artifact -> { try { - skCase.setReviewStatus(artifact, newStatus); + AccountInstance accountInstance = skCase.getCommunicationsManager().getAccountInstance(artifact); + accountInstance.setReviewStatus(newStatus); } catch (TskCoreException ex) { LOGGER.log(Level.SEVERE, "Error changing artifact review status.", ex); //NON-NLS } diff --git a/InternalPythonModules/android/calllog.py b/InternalPythonModules/android/calllog.py index ce51edabfb..c487b7576e 100755 --- a/InternalPythonModules/android/calllog.py +++ b/InternalPythonModules/android/calllog.py @@ -48,7 +48,7 @@ from org.sleuthkit.datamodel import Account import traceback import general -deviceAccount = None +deviceAccountInstance = None """ Locates a variety of different call log databases, parses them, and populates the blackboard. @@ -90,8 +90,8 @@ class CallLogAnalyzer(general.AndroidComponentAnalyzer): ds = Case.getCurrentCase().getSleuthkitCase().getDataSource(datasourceObjId) deviceID = ds.getDeviceId() - global deviceAccount - deviceAccount = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().getOrCreateAccount(Account.Type.DEVICE, deviceID, general.MODULE_NAME, dataSource) + global deviceAccountInstance + deviceAccountInstance = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().createAccountInstance(Account.Type.DEVICE, deviceID, general.MODULE_NAME, dataSource) absFiles = fileManager.findFiles(dataSource, "logs.db") absFiles.addAll(fileManager.findFiles(dataSource, "contacts.db")) @@ -143,10 +143,10 @@ class CallLogAnalyzer(general.AndroidComponentAnalyzer): artifact.addAttribute(BlackboardAttribute(ATTRIBUTE_TYPE.TSK_NAME, general.MODULE_NAME, name)) # Create an account - calllogAccount = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().getOrCreateAccount(Account.Type.PHONE, number, general.MODULE_NAME, abstractFile); + calllogAccountInstance = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().createAccountInstance(Account.Type.PHONE, number, general.MODULE_NAME, abstractFile); # create relationship between accounts - Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().addRelationships(deviceAccount, [calllogAccount], artifact); + Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().addRelationships(deviceAccountInstance, [calllogAccount], artifact); bbartifacts.append(artifact) diff --git a/InternalPythonModules/android/contact.py b/InternalPythonModules/android/contact.py index c863f2ba4e..e327ece36e 100755 --- a/InternalPythonModules/android/contact.py +++ b/InternalPythonModules/android/contact.py @@ -46,7 +46,7 @@ from org.sleuthkit.datamodel import Account import traceback import general -deviceAccount = None +deviceAccountInstance = None """ Locates a variety of different contacts databases, parses them, and populates the blackboard. @@ -64,8 +64,8 @@ class ContactAnalyzer(general.AndroidComponentAnalyzer): ds = Case.getCurrentCase().getSleuthkitCase().getDataSource(datasourceObjId) deviceID = ds.getDeviceId() - global deviceAccount - deviceAccount = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().getOrCreateAccount(Account.Type.DEVICE, deviceID, general.MODULE_NAME, dataSource) + global deviceAccountInstance + deviceAccountInstance = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().createAccountInstance(Account.Type.DEVICE, deviceID, general.MODULE_NAME, dataSource) absFiles = fileManager.findFiles(dataSource, "contacts.db") absFiles.addAll(fileManager.findFiles(dataSource, "contacts2.db")) @@ -146,11 +146,11 @@ class ContactAnalyzer(general.AndroidComponentAnalyzer): artifact.addAttribute(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL, general.MODULE_NAME, data1)) acctType = Account.Type.EMAIL - # Create an account - contactAccount = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().getOrCreateAccount(acctType, data1, general.MODULE_NAME, abstractFile); + # Create an account instance + contactAccountInstance = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().createAccountInstance(acctType, data1, general.MODULE_NAME, abstractFile); # create relationship between accounts - Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().addRelationships(deviceAccount, [contactAccount], artifact); + Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().addRelationships(deviceAccountInstance, [contactAccountInstance], artifact); oldName = name diff --git a/InternalPythonModules/android/tangomessage.py b/InternalPythonModules/android/tangomessage.py index c9923e2d8f..846b3d159c 100755 --- a/InternalPythonModules/android/tangomessage.py +++ b/InternalPythonModules/android/tangomessage.py @@ -46,7 +46,7 @@ from org.sleuthkit.datamodel import Account import traceback import general -deviceAccount = None +deviceAccountInstance = None """ Locates database for the Tango app and adds info to blackboard. @@ -63,8 +63,8 @@ class TangoMessageAnalyzer(general.AndroidComponentAnalyzer): ds = Case.getCurrentCase().getSleuthkitCase().getDataSource(datasourceObjId) deviceID = ds.getDeviceId() - global deviceAccount - deviceAccount = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().getOrCreateAccount(Account.Type.DEVICE, deviceID, general.MODULE_NAME, dataSource) + global deviceAccountInstance + deviceAccountInstance = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().createAccountInstance(Account.Type.DEVICE, deviceID, general.MODULE_NAME, dataSource) absFiles = fileManager.findFiles(dataSource, "tc.db") for abstractFile in absFiles: diff --git a/InternalPythonModules/android/textmessage.py b/InternalPythonModules/android/textmessage.py index 38f0855a7c..cd2317a492 100755 --- a/InternalPythonModules/android/textmessage.py +++ b/InternalPythonModules/android/textmessage.py @@ -47,7 +47,7 @@ from org.sleuthkit.datamodel import Account import traceback import general -deviceAccount = None +deviceAccountInstance = None """ Finds database with SMS/MMS messages and adds them to blackboard. @@ -65,8 +65,8 @@ class TextMessageAnalyzer(general.AndroidComponentAnalyzer): ds = Case.getCurrentCase().getSleuthkitCase().getDataSource(datasourceObjId) deviceID = ds.getDeviceId() - global deviceAccount - deviceAccount = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().getOrCreateAccount(Account.Type.DEVICE, deviceID, general.MODULE_NAME, dataSource) + global deviceAccountInstance + deviceAccountInstance = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().createAccountInstance(Account.Type.DEVICE, deviceID, general.MODULE_NAME, dataSource) absFiles = fileManager.findFiles(dataSource, "mmssms.db") for abstractFile in absFiles: @@ -118,10 +118,10 @@ class TextMessageAnalyzer(general.AndroidComponentAnalyzer): artifact.addAttribute(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_MESSAGE_TYPE, general.MODULE_NAME, "SMS Message")) # Create an account - msgAccount = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().getOrCreateAccount(Account.Type.PHONE, address, general.MODULE_NAME, abstractFile); + msgAccountInstance = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().createAccountInstance(Account.Type.PHONE, address, general.MODULE_NAME, abstractFile); # create relationship between accounts - Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().addRelationships(deviceAccount, [msgAccount], artifact); + Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().addRelationships(deviceAccountInstance, [msgAccountInstance], artifact); bbartifacts.append(artifact) try: diff --git a/InternalPythonModules/android/wwfmessage.py b/InternalPythonModules/android/wwfmessage.py index 90554866c5..4d66e97af0 100755 --- a/InternalPythonModules/android/wwfmessage.py +++ b/InternalPythonModules/android/wwfmessage.py @@ -44,7 +44,7 @@ import traceback import general wwfAccountType = None -deviceAccount = None +deviceAccountInstance = None """ Analyzes messages from Words With Friends @@ -65,8 +65,8 @@ class WWFMessageAnalyzer(general.AndroidComponentAnalyzer): ds = Case.getCurrentCase().getSleuthkitCase().getDataSource(datasourceObjId) deviceID = ds.getDeviceId() - global deviceAccount - deviceAccount = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().getOrCreateAccount(Account.Type.DEVICE, deviceID, general.MODULE_NAME, dataSource) + global deviceAccountInstance + deviceAccountInstance = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().createAccountInstance(Account.Type.DEVICE, deviceID, general.MODULE_NAME, dataSource) absFiles = fileManager.findFiles(dataSource, "WordsFramework") for abstractFile in absFiles: @@ -112,10 +112,10 @@ class WWFMessageAnalyzer(general.AndroidComponentAnalyzer): artifact.addAttribute(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_MESSAGE_TYPE, general.MODULE_NAME, "Words With Friends Message")) # Create an account - wwfAccount = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().getOrCreateAccount(wwfAccountType, user_id, general.MODULE_NAME, abstractFile); + wwfAccountInstance = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().createAccountInstance(wwfAccountType, user_id, general.MODULE_NAME, abstractFile); # create relationship between accounts - Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().addRelationships(deviceAccount, [wwfAccount], artifact); + Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().addRelationships(deviceAccountInstance, [wwfAccountInstance], artifact); try: # index the artifact for keyword search diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentViewer.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentViewer.java index 680eb9e67e..315066cbbe 100755 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentViewer.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentViewer.java @@ -173,7 +173,14 @@ public class ExtractedContentViewer implements DataContentViewer { } } panel.updateControls(currentSource); - setPanel(content.getName(), sources); + + String contentName = ""; + if (content != null) { + contentName = content.getName(); + } + setPanel(contentName, sources); + + } static private IndexedText getRawArtifactText(Lookup nodeLookup) throws TskCoreException { diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/RegexQuery.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/RegexQuery.java index a4d3ca9153..6775ed366c 100755 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/RegexQuery.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/RegexQuery.java @@ -37,6 +37,7 @@ import org.apache.solr.common.SolrDocument; import org.apache.solr.common.SolrDocumentList; import org.apache.solr.common.params.CursorMarkParams; import org.openide.util.NbBundle; +import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil; import org.sleuthkit.autopsy.datamodel.CreditCards; @@ -46,6 +47,7 @@ import static org.sleuthkit.autopsy.keywordsearch.TermsComponentQuery.CREDIT_CAR import static org.sleuthkit.autopsy.keywordsearch.TermsComponentQuery.KEYWORD_SEARCH_DOCUMENT_ID; import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.Account; +import org.sleuthkit.datamodel.AccountInstance; import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardAttribute; import org.sleuthkit.datamodel.Content; @@ -404,7 +406,6 @@ final class RegexQuery implements KeywordSearchQuery { * Parse the credit card account attributes from the snippet for the * hit. */ - attributes.add(new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ACCOUNT_TYPE, MODULE_NAME, Account.Type.CREDIT_CARD.getTypeName())); Map parsedTrackAttributeMap = new HashMap<>(); Matcher matcher = TermsComponentQuery.CREDIT_CARD_TRACK1_PATTERN.matcher(hit.getSnippet()); if (matcher.find()) { @@ -467,7 +468,9 @@ final class RegexQuery implements KeywordSearchQuery { * Create an account artifact. */ try { - newArtifact = content.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_ACCOUNT); + //newArtifact = content.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_ACCOUNT); + AccountInstance ccAccountInstance = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().createAccountInstance(Account.Type.CREDIT_CARD, ccnAttribute.getValueString() , MODULE_NAME, content); + newArtifact = Case.getCurrentCase().getSleuthkitCase().getBlackboardArtifact(ccAccountInstance.getArtifactId()); } catch (TskCoreException ex) { LOGGER.log(Level.SEVERE, "Error adding artifact for account to blackboard", ex); //NON-NLS return null; diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TermsComponentQuery.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TermsComponentQuery.java index 3253e4d9ce..523385eb9f 100755 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TermsComponentQuery.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TermsComponentQuery.java @@ -33,11 +33,13 @@ import org.apache.commons.lang.StringUtils; import org.apache.commons.validator.routines.checkdigit.LuhnCheckDigit; import org.apache.solr.client.solrj.SolrQuery; import org.apache.solr.client.solrj.response.TermsResponse.Term; +import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.Version; import org.sleuthkit.autopsy.datamodel.CreditCards; import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.Account; +import org.sleuthkit.datamodel.AccountInstance; import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE; import org.sleuthkit.datamodel.BlackboardAttribute; @@ -346,7 +348,6 @@ final class TermsComponentQuery implements KeywordSearchQuery { * Parse the credit card account attributes from the snippet for the * hit. */ - attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_ACCOUNT_TYPE, MODULE_NAME, Account.Type.CREDIT_CARD.getTypeName())); Map parsedTrackAttributeMap = new HashMap<>(); Matcher matcher = CREDIT_CARD_TRACK1_PATTERN.matcher(hit.getSnippet()); if (matcher.find()) { @@ -409,7 +410,8 @@ final class TermsComponentQuery implements KeywordSearchQuery { * Create an account artifact. */ try { - newArtifact = content.newArtifact(ARTIFACT_TYPE.TSK_ACCOUNT); + AccountInstance ccAccountInstance = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().createAccountInstance(Account.Type.CREDIT_CARD, ccnAttribute.getValueString() , MODULE_NAME, content); + newArtifact = Case.getCurrentCase().getSleuthkitCase().getBlackboardArtifact(ccAccountInstance.getArtifactId()); } catch (TskCoreException ex) { LOGGER.log(Level.SEVERE, "Error adding artifact for account to blackboard", ex); //NON-NLS return null; diff --git a/thunderbirdparser/src/org/sleuthkit/autopsy/thunderbirdparser/ThunderbirdMboxFileIngestModule.java b/thunderbirdparser/src/org/sleuthkit/autopsy/thunderbirdparser/ThunderbirdMboxFileIngestModule.java index e9fa379ef2..60bc88a65b 100755 --- a/thunderbirdparser/src/org/sleuthkit/autopsy/thunderbirdparser/ThunderbirdMboxFileIngestModule.java +++ b/thunderbirdparser/src/org/sleuthkit/autopsy/thunderbirdparser/ThunderbirdMboxFileIngestModule.java @@ -46,6 +46,7 @@ import org.sleuthkit.autopsy.ingest.ModuleContentEvent; import org.sleuthkit.autopsy.ingest.ModuleDataEvent; import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.Account; +import org.sleuthkit.datamodel.AccountInstance; import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardAttribute; import org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE; @@ -404,11 +405,11 @@ public final class ThunderbirdMboxFileIngestModule implements FileIngestModule { String senderAddress; senderAddressList.addAll(findEmailAddresess(from)); - Account senderAccount = null; + AccountInstance senderAccountInstance = null; if (senderAddressList.size() == 1) { senderAddress = senderAddressList.get(0); try { - senderAccount = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().getOrCreateAccount(Account.Type.EMAIL, senderAddress, EmailParserModuleFactory.getModuleName(), abstractFile); + senderAccountInstance = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().createAccountInstance(Account.Type.EMAIL, senderAddress, EmailParserModuleFactory.getModuleName(), abstractFile); } catch(TskCoreException ex) { logger.log(Level.WARNING, "Failed to create account for email address " + senderAddress, ex); //NON-NLS @@ -423,13 +424,13 @@ public final class ThunderbirdMboxFileIngestModule implements FileIngestModule { recipientAddresses.addAll(findEmailAddresess(cc)); recipientAddresses.addAll(findEmailAddresess(bcc)); - List recipientAccounts = new ArrayList<>(); + List recipientAccountInstances = new ArrayList<>(); recipientAddresses.forEach((addr) -> { try { - Account recipientAccount = - Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().getOrCreateAccount(Account.Type.EMAIL, addr, + AccountInstance recipientAccountInstance = + Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().createAccountInstance(Account.Type.EMAIL, addr, EmailParserModuleFactory.getModuleName(), abstractFile); - recipientAccounts.add(recipientAccount); + recipientAccountInstances.add(recipientAccountInstance); } catch(TskCoreException ex) { logger.log(Level.WARNING, "Failed to create account for email address " + addr, ex); //NON-NLS @@ -463,7 +464,7 @@ public final class ThunderbirdMboxFileIngestModule implements FileIngestModule { bbart.addAttributes(bbattributes); // Add account relationships - Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().addRelationships(senderAccount, recipientAccounts, bbart); + Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().addRelationships(senderAccountInstance, recipientAccountInstances, bbart); try { // index the artifact for keyword search From 3cbc89157e76eaadb580bb4c20988f9052c9d4ef Mon Sep 17 00:00:00 2001 From: Raman Date: Mon, 2 Oct 2017 15:22:33 -0400 Subject: [PATCH 014/127] Removed commented code. --- .../src/org/sleuthkit/autopsy/keywordsearch/RegexQuery.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/RegexQuery.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/RegexQuery.java index 44e350e3a9..a456e6c029 100755 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/RegexQuery.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/RegexQuery.java @@ -493,10 +493,9 @@ final class RegexQuery implements KeywordSearchQuery { } /* - * Create an account artifact. + * Create an account instance. */ try { - //newArtifact = content.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_ACCOUNT); AccountInstance ccAccountInstance = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().createAccountInstance(Account.Type.CREDIT_CARD, ccnAttribute.getValueString() , MODULE_NAME, content); newArtifact = Case.getCurrentCase().getSleuthkitCase().getBlackboardArtifact(ccAccountInstance.getArtifactId()); } catch (TskCoreException ex) { From 2c7ce7ee39ec6964b3c47cfc25ba4a900d8b877e Mon Sep 17 00:00:00 2001 From: Raman Date: Tue, 3 Oct 2017 08:05:24 -0400 Subject: [PATCH 015/127] Fixed Codacy issue. --- InternalPythonModules/android/calllog.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/InternalPythonModules/android/calllog.py b/InternalPythonModules/android/calllog.py index c487b7576e..1cdab6b089 100755 --- a/InternalPythonModules/android/calllog.py +++ b/InternalPythonModules/android/calllog.py @@ -146,7 +146,7 @@ class CallLogAnalyzer(general.AndroidComponentAnalyzer): calllogAccountInstance = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().createAccountInstance(Account.Type.PHONE, number, general.MODULE_NAME, abstractFile); # create relationship between accounts - Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().addRelationships(deviceAccountInstance, [calllogAccount], artifact); + Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().addRelationships(deviceAccountInstance, [calllogAccountInstance], artifact); bbartifacts.append(artifact) From 786c8ffc319cbbaf6e90152e8e510c46ded6566d Mon Sep 17 00:00:00 2001 From: millmanorama Date: Mon, 23 Oct 2017 16:34:05 +0200 Subject: [PATCH 016/127] Add CVTTopComponent and accountsBrowser --- .../autopsy/communications/AccountNode.java | 23 +++ .../communications/AccountsBrowser.form | 40 ++++ .../communications/AccountsBrowser.java | 49 +++++ .../autopsy/communications/Bundle.properties | 9 + .../communications/CVTTopComponent.form | 167 ++++++++++++++++ .../communications/CVTTopComponent.java | 178 ++++++++++++++++++ .../autopsy/communications/OpenCVTAction.java | 78 ++++++++ .../communications/images/email_link.png | Bin 0 -> 821 bytes .../org/sleuthkit/autopsy/core/cvtWsmode.xml | 11 ++ Core/src/org/sleuthkit/autopsy/core/layer.xml | 1 + 10 files changed, 556 insertions(+) create mode 100644 Core/src/org/sleuthkit/autopsy/communications/AccountNode.java create mode 100644 Core/src/org/sleuthkit/autopsy/communications/AccountsBrowser.form create mode 100644 Core/src/org/sleuthkit/autopsy/communications/AccountsBrowser.java create mode 100644 Core/src/org/sleuthkit/autopsy/communications/Bundle.properties create mode 100644 Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.form create mode 100644 Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java create mode 100644 Core/src/org/sleuthkit/autopsy/communications/OpenCVTAction.java create mode 100644 Core/src/org/sleuthkit/autopsy/communications/images/email_link.png create mode 100644 Core/src/org/sleuthkit/autopsy/core/cvtWsmode.xml diff --git a/Core/src/org/sleuthkit/autopsy/communications/AccountNode.java b/Core/src/org/sleuthkit/autopsy/communications/AccountNode.java new file mode 100644 index 0000000000..0d6920e3c9 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/communications/AccountNode.java @@ -0,0 +1,23 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2011-2017 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.sleuthkit.autopsy.communications; + +public class AccountNode { + +} diff --git a/Core/src/org/sleuthkit/autopsy/communications/AccountsBrowser.form b/Core/src/org/sleuthkit/autopsy/communications/AccountsBrowser.form new file mode 100644 index 0000000000..83a3e75e9a --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/communications/AccountsBrowser.form @@ -0,0 +1,40 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/Core/src/org/sleuthkit/autopsy/communications/AccountsBrowser.java b/Core/src/org/sleuthkit/autopsy/communications/AccountsBrowser.java new file mode 100644 index 0000000000..cc9faa3ec5 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/communications/AccountsBrowser.java @@ -0,0 +1,49 @@ +package org.sleuthkit.autopsy.communications; + +import javax.swing.JPanel; + +public class AccountsBrowser extends JPanel { + + private static final long serialVersionUID = 1L; + + /** + * Creates new form AccountsBrowser + */ + public AccountsBrowser() { + initComponents(); + } + + /** + * This method is called from within the constructor to initialize the form. + * WARNING: Do NOT modify this code. The content of this method is always + * regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // //GEN-BEGIN:initComponents + private void initComponents() { + + outlineView = new org.openide.explorer.view.OutlineView(); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addGap(0, 0, 0) + .addComponent(outlineView, javax.swing.GroupLayout.DEFAULT_SIZE, 400, Short.MAX_VALUE) + .addGap(0, 0, 0)) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addGap(0, 0, 0) + .addComponent(outlineView, javax.swing.GroupLayout.DEFAULT_SIZE, 300, Short.MAX_VALUE) + .addGap(0, 0, 0)) + ); + }// //GEN-END:initComponents + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private org.openide.explorer.view.OutlineView outlineView; + // End of variables declaration//GEN-END:variables +} diff --git a/Core/src/org/sleuthkit/autopsy/communications/Bundle.properties b/Core/src/org/sleuthkit/autopsy/communications/Bundle.properties new file mode 100644 index 0000000000..bd82de278e --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/communications/Bundle.properties @@ -0,0 +1,9 @@ +# To change this license header, choose License Headers in Project Properties. +# To change this template file, choose Tools | Templates +# and open the template in the editor. + +CVTTopComponent.jPanel2.border.title=Filters +CVTTopComponent.jTextField1.text=place holder for messages ,thumbnail list, etc +CVTTopComponent.jTextField2.text=place holder for message viewer +CVTTopComponent.TabConstraints.tabTitle=Visualize +CVTTopComponent.accountsBrowser.TabConstraints.tabTitle=Browse diff --git a/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.form b/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.form new file mode 100644 index 0000000000..3dd339c0be --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.form @@ -0,0 +1,167 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java b/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java new file mode 100644 index 0000000000..23a752b78b --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java @@ -0,0 +1,178 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2011-2017 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.sleuthkit.autopsy.communications; + +import java.util.List; +import java.util.stream.Collectors; +import org.openide.explorer.ExplorerManager; +import org.openide.util.NbBundle; +import org.openide.windows.Mode; +import org.openide.windows.RetainLocation; +import org.openide.windows.TopComponent; +import org.openide.windows.WindowManager; +import org.sleuthkit.autopsy.coreutils.ThreadConfined; + +/** + * Top component which displays something. + */ +@TopComponent.Description( + preferredID = "CVTTopComponent", + //iconBase="SET/PATH/TO/ICON/HERE", //use this to put icon in window title area, + persistenceType = TopComponent.PERSISTENCE_NEVER) +@TopComponent.Registration(mode = "cvt", openAtStartup = false) +@RetainLocation("cvt") +@NbBundle.Messages("CVTTopComponent.name= Communications Visualization") +public final class CVTTopComponent extends TopComponent implements ExplorerManager.Provider { + + private static final long serialVersionUID = 1L; + + @ThreadConfined(type = ThreadConfined.ThreadType.AWT) + private final ExplorerManager em = new ExplorerManager(); + + public CVTTopComponent() { + initComponents(); + setName(Bundle.CVTTopComponent_name()); + } + + /** + * This method is called from within the constructor to initialize the form. + * WARNING: Do NOT modify this code. The content of this method is always + * regenerated by the Form Editor. + */ + // //GEN-BEGIN:initComponents + private void initComponents() { + + jPanel2 = new javax.swing.JPanel(); + jSplitPane1 = new javax.swing.JSplitPane(); + jTabbedPane1 = new javax.swing.JTabbedPane(); + accountsBrowser = new org.sleuthkit.autopsy.communications.AccountsBrowser(); + jPanel1 = new javax.swing.JPanel(); + jSplitPane2 = new javax.swing.JSplitPane(); + jTextField1 = new javax.swing.JTextField(); + jTextField2 = new javax.swing.JTextField(); + + jPanel2.setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(CVTTopComponent.class, "CVTTopComponent.jPanel2.border.title"))); // NOI18N + + javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2); + jPanel2.setLayout(jPanel2Layout); + jPanel2Layout.setHorizontalGroup( + jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 232, Short.MAX_VALUE) + ); + jPanel2Layout.setVerticalGroup( + jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 0, Short.MAX_VALUE) + ); + + jSplitPane1.setDividerLocation(600); + + jTabbedPane1.addTab(org.openide.util.NbBundle.getMessage(CVTTopComponent.class, "CVTTopComponent.accountsBrowser.TabConstraints.tabTitle"), accountsBrowser); // NOI18N + + jPanel1.setName(""); // NOI18N + + javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1); + jPanel1.setLayout(jPanel1Layout); + jPanel1Layout.setHorizontalGroup( + jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 594, Short.MAX_VALUE) + ); + jPanel1Layout.setVerticalGroup( + jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 716, Short.MAX_VALUE) + ); + + jTabbedPane1.addTab(org.openide.util.NbBundle.getMessage(CVTTopComponent.class, "CVTTopComponent.TabConstraints.tabTitle"), jPanel1); // NOI18N + + jSplitPane1.setLeftComponent(jTabbedPane1); + + jSplitPane2.setDividerLocation(200); + jSplitPane2.setOrientation(javax.swing.JSplitPane.VERTICAL_SPLIT); + + jTextField1.setText(org.openide.util.NbBundle.getMessage(CVTTopComponent.class, "CVTTopComponent.jTextField1.text")); // NOI18N + jTextField1.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jTextField1ActionPerformed(evt); + } + }); + jSplitPane2.setTopComponent(jTextField1); + + jTextField2.setText(org.openide.util.NbBundle.getMessage(CVTTopComponent.class, "CVTTopComponent.jTextField2.text")); // NOI18N + jSplitPane2.setRightComponent(jTextField2); + + jSplitPane1.setRightComponent(jSplitPane2); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addComponent(jPanel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(0, 0, 0) + .addComponent(jSplitPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 1334, Short.MAX_VALUE) + .addContainerGap()) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jSplitPane1) + .addComponent(jPanel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addContainerGap()) + ); + }// //GEN-END:initComponents + + private void jTextField1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jTextField1ActionPerformed + // TODO add your handling code here: + }//GEN-LAST:event_jTextField1ActionPerformed + + // Variables declaration - do not modify//GEN-BEGIN:variables + private org.sleuthkit.autopsy.communications.AccountsBrowser accountsBrowser; + private javax.swing.JPanel jPanel1; + private javax.swing.JPanel jPanel2; + private javax.swing.JSplitPane jSplitPane1; + private javax.swing.JSplitPane jSplitPane2; + private javax.swing.JTabbedPane jTabbedPane1; + private javax.swing.JTextField jTextField1; + private javax.swing.JTextField jTextField2; + // End of variables declaration//GEN-END:variables + + @Override + public void componentOpened() { + super.componentOpened(); + WindowManager.getDefault().setTopComponentFloating(this, true); + } + + @Override + public ExplorerManager getExplorerManager() { + return em; + } + + @Override + public List availableModes(List modes) { + /* + * This looks like the right thing to do, but online discussions seems + * to indicate this method is effectively deprecated. A break point + * placed here was never hit. + */ + return modes.stream().filter(mode -> mode.getName().equals("cvt")) + .collect(Collectors.toList()); + } +} diff --git a/Core/src/org/sleuthkit/autopsy/communications/OpenCVTAction.java b/Core/src/org/sleuthkit/autopsy/communications/OpenCVTAction.java new file mode 100644 index 0000000000..6606b563ec --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/communications/OpenCVTAction.java @@ -0,0 +1,78 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package org.sleuthkit.autopsy.communications; + +import java.awt.Component; +import javax.swing.ImageIcon; +import javax.swing.JButton; +import org.openide.awt.ActionID; +import org.openide.awt.ActionReference; +import org.openide.awt.ActionReferences; +import org.openide.awt.ActionRegistration; +import org.openide.util.HelpCtx; +import org.openide.util.NbBundle; +import org.openide.util.NbBundle.Messages; +import org.openide.util.actions.CallableSystemAction; +import org.openide.util.actions.Presenter; +import org.openide.windows.TopComponent; +import org.openide.windows.WindowManager; + +@ActionID(category = "Tools", + id = "org.sleuthkit.autopsy.communicationsVisualization.OpenCVTAction") +@ActionRegistration(displayName = "#CTL_OpenCVTAction", lazy = false) +@ActionReferences(value = { + @ActionReference(path = "Menu/Tools", position = 102) + , @ActionReference(path = "Toolbars/Case", position = 102)}) +@Messages("CTL_OpenCVTAction=Visualize Communications") +public final class OpenCVTAction extends CallableSystemAction implements Presenter.Toolbar { + + private static final long serialVersionUID = 1L; + + private final JButton toolbarButton = new JButton(getName(), + new ImageIcon(getClass().getResource("images/email_link.png"))); //NON-NLS + + public OpenCVTAction() { + toolbarButton.addActionListener(actionEvent -> performAction()); + } + + @Override + public void performAction() { + final TopComponent tc = WindowManager.getDefault().findTopComponent("CVTTopComponent"); + if (tc != null) { + if (tc.isOpened() == false) { + tc.open(); + } + tc.toFront(); + tc.requestActive(); + } + } + + @Override + @NbBundle.Messages("OpenCVTAction.displayName=Communications Visualizaton") + public String getName() { + return Bundle.OpenCVTAction_displayName(); + } + + /** + * Returns the toolbar component of this action + * + * @return component the toolbar button + */ + @Override + public Component getToolbarPresenter() { + return toolbarButton; + } + + @Override + public HelpCtx getHelpCtx() { + return HelpCtx.DEFAULT_HELP; + } + + @Override + public boolean asynchronous() { + return false; // run on edt + } +} diff --git a/Core/src/org/sleuthkit/autopsy/communications/images/email_link.png b/Core/src/org/sleuthkit/autopsy/communications/images/email_link.png new file mode 100644 index 0000000000000000000000000000000000000000..2c49f78a657c1ba1ec0ca6a28455721b20d4ec50 GIT binary patch literal 821 zcmV-51Iqk~P)@&xZvixulsk-;T#44a~v_p20ZGUos{+e ziqz?x2bDc`a!X|=H&x$AMYoNVcg>OOowMZH)34;Je1??Brir-Kni02|lNTF@eWxU< zNk%>3@}$y)izYH)GssfVp3xDiE3_bkWMX`Nts^t6W3>pK-9Ht?o9O^7?i6NLjsQv?P*iV0iU-X5Sd9M&!sd>k z-}n)V&Ti=SdNj)vcx!UOwiJe3ap)x zhTreU^71mwW;2vMYG|~5SX^`qp4Dm_$qtT$Tu~De0*V@+3QHb<@Jz?l?%DX)jK3n%GeMWMRG`GqGK;aY9f#^aZ zOePZ?4hJk23kC-Vah~@swT#Cppt+@$Wc};h+}xV#>gq5Bl$Mr`=jZ3Ai;9XMkw^s5 zntHTH0W_NhILR;mh%Tj488#RUA*0aU)W&v_?a!!auqSM92 z#VeJSmGRoz+9WTwtgP$?uL8c_qaN+i49)%pyygIR5QP`^00000NkvXXu0mjf)cSaJ literal 0 HcmV?d00001 diff --git a/Core/src/org/sleuthkit/autopsy/core/cvtWsmode.xml b/Core/src/org/sleuthkit/autopsy/core/cvtWsmode.xml new file mode 100644 index 0000000000..fc0f8a0200 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/core/cvtWsmode.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/Core/src/org/sleuthkit/autopsy/core/layer.xml b/Core/src/org/sleuthkit/autopsy/core/layer.xml index 95cfcd481e..09514caddf 100755 --- a/Core/src/org/sleuthkit/autopsy/core/layer.xml +++ b/Core/src/org/sleuthkit/autopsy/core/layer.xml @@ -443,6 +443,7 @@ + From e1a5b6109ef86b90847fbd6a719280feceac6dbb Mon Sep 17 00:00:00 2001 From: millmanorama Date: Mon, 23 Oct 2017 17:53:28 +0200 Subject: [PATCH 017/127] WIP connecting up CVTTopComponent and accountsBrowser --- .../autopsy/communications/AccountNode.java | 10 +++- .../communications/AccountRootNode.java | 42 ++++++++++++++++ .../communications/AccountsBrowser.java | 3 +- .../autopsy/communications/Bundle.properties | 1 + .../communications/CVTTopComponent.form | 29 ++++++++--- .../communications/CVTTopComponent.java | 49 ++++++++++++++----- .../autopsy/communications/OpenCVTAction.java | 19 +++++-- 7 files changed, 129 insertions(+), 24 deletions(-) create mode 100644 Core/src/org/sleuthkit/autopsy/communications/AccountRootNode.java diff --git a/Core/src/org/sleuthkit/autopsy/communications/AccountNode.java b/Core/src/org/sleuthkit/autopsy/communications/AccountNode.java index 0d6920e3c9..74dff9f8ce 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/AccountNode.java +++ b/Core/src/org/sleuthkit/autopsy/communications/AccountNode.java @@ -18,6 +18,14 @@ */ package org.sleuthkit.autopsy.communications; -public class AccountNode { +import org.openide.nodes.AbstractNode; +import org.openide.nodes.Children; +import org.openide.util.lookup.Lookups; +import org.sleuthkit.datamodel.Account; +public class AccountNode extends AbstractNode { + + public AccountNode(Account account) { + super(Children.LEAF, Lookups.fixed(account)); + } } diff --git a/Core/src/org/sleuthkit/autopsy/communications/AccountRootNode.java b/Core/src/org/sleuthkit/autopsy/communications/AccountRootNode.java new file mode 100644 index 0000000000..9348a22814 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/communications/AccountRootNode.java @@ -0,0 +1,42 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package org.sleuthkit.autopsy.communications; + +import java.util.List; +import org.openide.nodes.AbstractNode; +import org.openide.nodes.ChildFactory; +import org.openide.nodes.Children; +import org.openide.nodes.Node; +import org.sleuthkit.datamodel.Account; + +public class AccountRootNode extends AbstractNode { + + public AccountRootNode(List accounts) { + + super(Children.create(new AccountsNodeFactory(accounts), true)); + } + + private static class AccountsNodeFactory extends ChildFactory { + + private final List< Account> accounts; + + private AccountsNodeFactory(List accounts) { + this.accounts = accounts; + } + + @Override + protected boolean createKeys(List list) { + list.addAll(accounts); + return true; + } + + @Override + protected Node createNodeForKey(Account key) { + return new AccountNode(accounts); + } + + } +} diff --git a/Core/src/org/sleuthkit/autopsy/communications/AccountsBrowser.java b/Core/src/org/sleuthkit/autopsy/communications/AccountsBrowser.java index cc9faa3ec5..3692a8a39b 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/AccountsBrowser.java +++ b/Core/src/org/sleuthkit/autopsy/communications/AccountsBrowser.java @@ -2,7 +2,7 @@ package org.sleuthkit.autopsy.communications; import javax.swing.JPanel; -public class AccountsBrowser extends JPanel { +public class AccountsBrowser extends JPanel { private static final long serialVersionUID = 1L; @@ -11,6 +11,7 @@ public class AccountsBrowser extends JPanel { */ public AccountsBrowser() { initComponents(); + } /** diff --git a/Core/src/org/sleuthkit/autopsy/communications/Bundle.properties b/Core/src/org/sleuthkit/autopsy/communications/Bundle.properties index bd82de278e..aa0b453d77 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/communications/Bundle.properties @@ -7,3 +7,4 @@ CVTTopComponent.jTextField1.text=place holder for messages ,thumbnail list, etc CVTTopComponent.jTextField2.text=place holder for message viewer CVTTopComponent.TabConstraints.tabTitle=Visualize CVTTopComponent.accountsBrowser.TabConstraints.tabTitle=Browse +CVTTopComponent.jButton1.text=apply diff --git a/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.form b/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.form index 3dd339c0be..0131e3e127 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.form +++ b/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.form @@ -20,7 +20,7 @@ - + @@ -53,15 +53,35 @@ - + + + + + - + + + + + + + + + + + + + + + + + @@ -138,9 +158,6 @@ - - - diff --git a/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java b/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java index 23a752b78b..bef2a2f1c1 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java +++ b/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java @@ -21,12 +21,16 @@ package org.sleuthkit.autopsy.communications; import java.util.List; import java.util.stream.Collectors; import org.openide.explorer.ExplorerManager; +import org.openide.util.Exceptions; import org.openide.util.NbBundle; import org.openide.windows.Mode; import org.openide.windows.RetainLocation; import org.openide.windows.TopComponent; import org.openide.windows.WindowManager; +import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.coreutils.ThreadConfined; +import org.sleuthkit.datamodel.Account; +import org.sleuthkit.datamodel.TskCoreException; /** * Top component which displays something. @@ -59,6 +63,7 @@ public final class CVTTopComponent extends TopComponent implements ExplorerManag private void initComponents() { jPanel2 = new javax.swing.JPanel(); + jButton1 = new javax.swing.JButton(); jSplitPane1 = new javax.swing.JSplitPane(); jTabbedPane1 = new javax.swing.JTabbedPane(); accountsBrowser = new org.sleuthkit.autopsy.communications.AccountsBrowser(); @@ -69,15 +74,28 @@ public final class CVTTopComponent extends TopComponent implements ExplorerManag jPanel2.setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(CVTTopComponent.class, "CVTTopComponent.jPanel2.border.title"))); // NOI18N + org.openide.awt.Mnemonics.setLocalizedText(jButton1, org.openide.util.NbBundle.getMessage(CVTTopComponent.class, "CVTTopComponent.jButton1.text")); // NOI18N + jButton1.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jButton1ActionPerformed(evt); + } + }); + javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2); jPanel2.setLayout(jPanel2Layout); jPanel2Layout.setHorizontalGroup( jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGap(0, 232, Short.MAX_VALUE) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel2Layout.createSequentialGroup() + .addContainerGap(141, Short.MAX_VALUE) + .addComponent(jButton1) + .addContainerGap()) ); jPanel2Layout.setVerticalGroup( jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGap(0, 0, Short.MAX_VALUE) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel2Layout.createSequentialGroup() + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jButton1) + .addContainerGap()) ); jSplitPane1.setDividerLocation(600); @@ -105,11 +123,6 @@ public final class CVTTopComponent extends TopComponent implements ExplorerManag jSplitPane2.setOrientation(javax.swing.JSplitPane.VERTICAL_SPLIT); jTextField1.setText(org.openide.util.NbBundle.getMessage(CVTTopComponent.class, "CVTTopComponent.jTextField1.text")); // NOI18N - jTextField1.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - jTextField1ActionPerformed(evt); - } - }); jSplitPane2.setTopComponent(jTextField1); jTextField2.setText(org.openide.util.NbBundle.getMessage(CVTTopComponent.class, "CVTTopComponent.jTextField2.text")); // NOI18N @@ -125,7 +138,7 @@ public final class CVTTopComponent extends TopComponent implements ExplorerManag .addContainerGap() .addComponent(jPanel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addGap(0, 0, 0) - .addComponent(jSplitPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 1334, Short.MAX_VALUE) + .addComponent(jSplitPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 1350, Short.MAX_VALUE) .addContainerGap()) ); layout.setVerticalGroup( @@ -139,12 +152,22 @@ public final class CVTTopComponent extends TopComponent implements ExplorerManag ); }// //GEN-END:initComponents - private void jTextField1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jTextField1ActionPerformed - // TODO add your handling code here: - }//GEN-LAST:event_jTextField1ActionPerformed + private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed + + try { + List accounts; + accounts = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().getAccounts(Account.Type.EMAIL); + + em.setRootContext(new AccountRootNode(accounts)); + } catch (TskCoreException ex) { + Exceptions.printStackTrace(ex); + } + + }//GEN-LAST:event_jButton1ActionPerformed // Variables declaration - do not modify//GEN-BEGIN:variables private org.sleuthkit.autopsy.communications.AccountsBrowser accountsBrowser; + private javax.swing.JButton jButton1; private javax.swing.JPanel jPanel1; private javax.swing.JPanel jPanel2; private javax.swing.JSplitPane jSplitPane1; @@ -164,8 +187,8 @@ public final class CVTTopComponent extends TopComponent implements ExplorerManag public ExplorerManager getExplorerManager() { return em; } - - @Override + + @Override public List availableModes(List modes) { /* * This looks like the right thing to do, but online discussions seems diff --git a/Core/src/org/sleuthkit/autopsy/communications/OpenCVTAction.java b/Core/src/org/sleuthkit/autopsy/communications/OpenCVTAction.java index 6606b563ec..dde5936476 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/OpenCVTAction.java +++ b/Core/src/org/sleuthkit/autopsy/communications/OpenCVTAction.java @@ -1,7 +1,20 @@ /* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. + * Autopsy Forensic Browser + * + * Copyright 2011-2017 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package org.sleuthkit.autopsy.communications; From 417ad4788a7b7e3e176d2a6673ce36cd9e2f9cff Mon Sep 17 00:00:00 2001 From: millmanorama Date: Mon, 23 Oct 2017 20:43:04 +0200 Subject: [PATCH 018/127] add properties to AccountNode --- .../autopsy/communications/AccountNode.java | 45 +++++++++++++++++++ .../communications/AccountRootNode.java | 22 ++++++--- .../communications/AccountsBrowser.java | 15 ++++++- 3 files changed, 75 insertions(+), 7 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/communications/AccountNode.java b/Core/src/org/sleuthkit/autopsy/communications/AccountNode.java index 74dff9f8ce..692a3cd0f1 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/AccountNode.java +++ b/Core/src/org/sleuthkit/autopsy/communications/AccountNode.java @@ -20,12 +20,57 @@ package org.sleuthkit.autopsy.communications; import org.openide.nodes.AbstractNode; import org.openide.nodes.Children; +import org.openide.nodes.Sheet; +import org.openide.util.NbBundle; import org.openide.util.lookup.Lookups; +import org.sleuthkit.autopsy.datamodel.NodeProperty; import org.sleuthkit.datamodel.Account; public class AccountNode extends AbstractNode { + private final Account account; + public AccountNode(Account account) { super(Children.LEAF, Lookups.fixed(account)); + this.account = account; + } + + @Override + @NbBundle.Messages({ + "AccountNode.icon=Icon", + "AccountNode.device=Device", + "AccountNode.accountName=Account Name", + "AccountNode.accountType=Type", + "AccountNode.messageCount=Message Count"}) + protected Sheet createSheet() { + Sheet s = super.createSheet(); + Sheet.Set properties = s.get(Sheet.PROPERTIES); + if (properties == null) { + properties = Sheet.createPropertiesSet(); + s.put(properties); + } + + properties.put(new NodeProperty<>("icon", + Bundle.AccountNode_icon(), + "icon", + true)); // NON-NLS //gets overridden with icon + properties.put(new NodeProperty<>("name", + Bundle.AccountNode_accountName(), + "name", + account.getAccountUniqueID())); // NON-NLS + properties.put(new NodeProperty<>("type", + Bundle.AccountNode_accountType(), + "type", + account.getAccountType().getDisplayName())); // NON-NLS + properties.put(new NodeProperty<>("count", + Bundle.AccountNode_messageCount(), + "count", + 1)); // NON-NLS +// properties.put(new NodeProperty<>("device", +// Bundle.AccountNode_device(), +// "device", +// account.)); // NON-NLS + + return s; } } diff --git a/Core/src/org/sleuthkit/autopsy/communications/AccountRootNode.java b/Core/src/org/sleuthkit/autopsy/communications/AccountRootNode.java index 9348a22814..c54331f39a 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/AccountRootNode.java +++ b/Core/src/org/sleuthkit/autopsy/communications/AccountRootNode.java @@ -1,7 +1,20 @@ /* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. + * Sleuth Kit Data Model + * + * Copyright 2011-2017 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package org.sleuthkit.autopsy.communications; @@ -35,8 +48,7 @@ public class AccountRootNode extends AbstractNode { @Override protected Node createNodeForKey(Account key) { - return new AccountNode(accounts); + return new AccountNode(key); } - } } diff --git a/Core/src/org/sleuthkit/autopsy/communications/AccountsBrowser.java b/Core/src/org/sleuthkit/autopsy/communications/AccountsBrowser.java index 3692a8a39b..a07a8525cd 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/AccountsBrowser.java +++ b/Core/src/org/sleuthkit/autopsy/communications/AccountsBrowser.java @@ -1,8 +1,9 @@ package org.sleuthkit.autopsy.communications; import javax.swing.JPanel; +import javax.swing.ListSelectionModel; -public class AccountsBrowser extends JPanel { +public class AccountsBrowser extends JPanel { private static final long serialVersionUID = 1L; @@ -11,7 +12,17 @@ public class AccountsBrowser extends JPanel { */ public AccountsBrowser() { initComponents(); - + outlineView.getOutline().setRootVisible(false); + outlineView.setPropertyColumns( + "icon", Bundle.AccountNode_icon(), + "name", Bundle.AccountNode_accountName(), + "type", Bundle.AccountNode_accountType(), + "count", Bundle.AccountNode_messageCount(), + "known", Bundle.AccountNode_messageCount() + ); + + outlineView.getOutline().setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); + } /** From 48529cbdf6aed1251dce3823979e32e140466a7f Mon Sep 17 00:00:00 2001 From: millmanorama Date: Mon, 23 Oct 2017 22:13:35 +0200 Subject: [PATCH 019/127] add icons for Account.Type and disable/enable the OpenCVTAction based on case opening/closing --- .../sleuthkit/autopsy/casemodule/Case.java | 27 ++++------- .../autopsy/communications/AccountNode.java | 42 +++++++++++++----- .../communications/AccountsBrowser.java | 16 ++++--- .../autopsy/communications/OpenCVTAction.java | 22 ++++++--- .../communications/images/WhatsApp.png | Bin 0 -> 1715 bytes .../communications/images/creditcards.png | Bin 0 -> 693 bytes .../autopsy/communications/images/device.png | Bin 0 -> 578 bytes .../autopsy/communications/images/email.png | Bin 0 -> 641 bytes .../communications/images/facebook.png | Bin 0 -> 541 bytes .../communications/images/instagram.png | Bin 0 -> 804 bytes .../communications/images/messaging.png | Bin 0 -> 1124 bytes .../autopsy/communications/images/phone.png | Bin 0 -> 488 bytes .../autopsy/communications/images/twitter.png | Bin 0 -> 656 bytes .../autopsy/communications/images/world.png | Bin 0 -> 923 bytes 14 files changed, 66 insertions(+), 41 deletions(-) create mode 100644 Core/src/org/sleuthkit/autopsy/communications/images/WhatsApp.png create mode 100644 Core/src/org/sleuthkit/autopsy/communications/images/creditcards.png create mode 100644 Core/src/org/sleuthkit/autopsy/communications/images/device.png create mode 100644 Core/src/org/sleuthkit/autopsy/communications/images/email.png create mode 100644 Core/src/org/sleuthkit/autopsy/communications/images/facebook.png create mode 100644 Core/src/org/sleuthkit/autopsy/communications/images/instagram.png create mode 100644 Core/src/org/sleuthkit/autopsy/communications/images/messaging.png create mode 100644 Core/src/org/sleuthkit/autopsy/communications/images/phone.png create mode 100644 Core/src/org/sleuthkit/autopsy/communications/images/twitter.png create mode 100644 Core/src/org/sleuthkit/autopsy/communications/images/world.png diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/Case.java b/Core/src/org/sleuthkit/autopsy/casemodule/Case.java index afcf23ed57..cdad71a66f 100755 --- a/Core/src/org/sleuthkit/autopsy/casemodule/Case.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/Case.java @@ -76,6 +76,7 @@ import org.sleuthkit.autopsy.casemodule.events.ContentTagDeletedEvent; import org.sleuthkit.autopsy.casemodule.events.DataSourceAddedEvent; import org.sleuthkit.autopsy.casemodule.events.ReportAddedEvent; import org.sleuthkit.autopsy.casemodule.services.Services; +import org.sleuthkit.autopsy.communications.OpenCVTAction; import org.sleuthkit.autopsy.coordinationservice.CoordinationService; import org.sleuthkit.autopsy.coordinationservice.CoordinationService.CategoryNode; import org.sleuthkit.autopsy.coordinationservice.CoordinationService.CoordinationServiceException; @@ -1000,6 +1001,7 @@ public class Case { CallableSystemAction.get(CasePropertiesAction.class).setEnabled(true); CallableSystemAction.get(CaseDeleteAction.class).setEnabled(true); CallableSystemAction.get(OpenTimelineAction.class).setEnabled(true); + CallableSystemAction.get(OpenCVTAction.class).setEnabled(true); CallableSystemAction.get(OpenOutputFolderAction.class).setEnabled(false); /* @@ -1042,24 +1044,13 @@ public class Case { /* * Disable the case-specific menu items. */ - CallableSystemAction - .get(AddImageAction.class - ).setEnabled(false); - CallableSystemAction - .get(CaseCloseAction.class - ).setEnabled(false); - CallableSystemAction - .get(CasePropertiesAction.class - ).setEnabled(false); - CallableSystemAction - .get(CaseDeleteAction.class - ).setEnabled(false); - CallableSystemAction - .get(OpenTimelineAction.class - ).setEnabled(false); - CallableSystemAction - .get(OpenOutputFolderAction.class - ).setEnabled(false); + CallableSystemAction.get(AddImageAction.class).setEnabled(false); + CallableSystemAction.get(CaseCloseAction.class).setEnabled(false); + CallableSystemAction.get(CasePropertiesAction.class).setEnabled(false); + CallableSystemAction.get(CaseDeleteAction.class).setEnabled(false); + CallableSystemAction.get(OpenTimelineAction.class).setEnabled(false); + CallableSystemAction.get(OpenCVTAction.class).setEnabled(false); + CallableSystemAction.get(OpenOutputFolderAction.class).setEnabled(false); /* * Clear the notifications in the notfier component in the lower diff --git a/Core/src/org/sleuthkit/autopsy/communications/AccountNode.java b/Core/src/org/sleuthkit/autopsy/communications/AccountNode.java index 692a3cd0f1..bf622c556c 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/AccountNode.java +++ b/Core/src/org/sleuthkit/autopsy/communications/AccountNode.java @@ -26,18 +26,46 @@ import org.openide.util.lookup.Lookups; import org.sleuthkit.autopsy.datamodel.NodeProperty; import org.sleuthkit.datamodel.Account; -public class AccountNode extends AbstractNode { +class AccountNode extends AbstractNode { private final Account account; - public AccountNode(Account account) { + AccountNode(Account account) { super(Children.LEAF, Lookups.fixed(account)); this.account = account; + setName(account.getAccountUniqueID()); + setIconBaseWithExtension("org/sleuthkit/autopsy/communications/images/" + getIconFileName(account.getAccountType())); + } + + final String getIconFileName(Account.Type type) { + if (type == Account.Type.CREDIT_CARD) { + return "creditcards.png"; + } else if (type == Account.Type.DEVICE) { + return "device.png"; + } else if (type == Account.Type.EMAIL) { + return "email.png"; + } else if (type == Account.Type.FACEBOOK) { + return "facebook.png"; + } else if (type == Account.Type.INSTAGRAM) { + return "instagram.png"; + } else if (type == Account.Type.MESSAGING_APP) { + return "messaging.png"; + } else if (type == Account.Type.PHONE) { + return "phone.png"; + } else if (type == Account.Type.TWITTER) { + return "twitter.png"; + } else if (type == Account.Type.WEBSITE) { + return "world.png"; + } else if (type == Account.Type.WHATSAPP) { + return "WhatsApp.png"; + } else { + throw new IllegalArgumentException("Unknown Account.Type: " + type.getTypeName()); + } + } @Override @NbBundle.Messages({ - "AccountNode.icon=Icon", "AccountNode.device=Device", "AccountNode.accountName=Account Name", "AccountNode.accountType=Type", @@ -50,14 +78,6 @@ public class AccountNode extends AbstractNode { s.put(properties); } - properties.put(new NodeProperty<>("icon", - Bundle.AccountNode_icon(), - "icon", - true)); // NON-NLS //gets overridden with icon - properties.put(new NodeProperty<>("name", - Bundle.AccountNode_accountName(), - "name", - account.getAccountUniqueID())); // NON-NLS properties.put(new NodeProperty<>("type", Bundle.AccountNode_accountType(), "type", diff --git a/Core/src/org/sleuthkit/autopsy/communications/AccountsBrowser.java b/Core/src/org/sleuthkit/autopsy/communications/AccountsBrowser.java index a07a8525cd..e6f4527399 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/AccountsBrowser.java +++ b/Core/src/org/sleuthkit/autopsy/communications/AccountsBrowser.java @@ -2,6 +2,8 @@ package org.sleuthkit.autopsy.communications; import javax.swing.JPanel; import javax.swing.ListSelectionModel; +import org.netbeans.swing.outline.DefaultOutlineModel; +import org.netbeans.swing.outline.Outline; public class AccountsBrowser extends JPanel { @@ -12,16 +14,16 @@ public class AccountsBrowser extends JPanel { */ public AccountsBrowser() { initComponents(); - outlineView.getOutline().setRootVisible(false); + final Outline outline = outlineView.getOutline(); outlineView.setPropertyColumns( - "icon", Bundle.AccountNode_icon(), - "name", Bundle.AccountNode_accountName(), + "device", Bundle.AccountNode_device(), "type", Bundle.AccountNode_accountType(), - "count", Bundle.AccountNode_messageCount(), - "known", Bundle.AccountNode_messageCount() + "count", Bundle.AccountNode_messageCount() ); - - outlineView.getOutline().setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); + + outline.setRootVisible(false); + ((DefaultOutlineModel) outline.getOutlineModel()).setNodesColumnLabel(Bundle.AccountNode_accountName()); + outline.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); } diff --git a/Core/src/org/sleuthkit/autopsy/communications/OpenCVTAction.java b/Core/src/org/sleuthkit/autopsy/communications/OpenCVTAction.java index dde5936476..c62018e2b3 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/OpenCVTAction.java +++ b/Core/src/org/sleuthkit/autopsy/communications/OpenCVTAction.java @@ -41,16 +41,17 @@ import org.openide.windows.WindowManager; , @ActionReference(path = "Toolbars/Case", position = 102)}) @Messages("CTL_OpenCVTAction=Visualize Communications") public final class OpenCVTAction extends CallableSystemAction implements Presenter.Toolbar { - + private static final long serialVersionUID = 1L; - + private final JButton toolbarButton = new JButton(getName(), new ImageIcon(getClass().getResource("images/email_link.png"))); //NON-NLS public OpenCVTAction() { toolbarButton.addActionListener(actionEvent -> performAction()); + setEnabled(false); } - + @Override public void performAction() { final TopComponent tc = WindowManager.getDefault().findTopComponent("CVTTopComponent"); @@ -63,6 +64,17 @@ public final class OpenCVTAction extends CallableSystemAction implements Present } } + /** + * Set this action to be enabled/disabled + * + * @param value whether to enable this action or not + */ + @Override + public void setEnabled(boolean value) { + super.setEnabled(value); + toolbarButton.setEnabled(value); + } + @Override @NbBundle.Messages("OpenCVTAction.displayName=Communications Visualizaton") public String getName() { @@ -78,12 +90,12 @@ public final class OpenCVTAction extends CallableSystemAction implements Present public Component getToolbarPresenter() { return toolbarButton; } - + @Override public HelpCtx getHelpCtx() { return HelpCtx.DEFAULT_HELP; } - + @Override public boolean asynchronous() { return false; // run on edt diff --git a/Core/src/org/sleuthkit/autopsy/communications/images/WhatsApp.png b/Core/src/org/sleuthkit/autopsy/communications/images/WhatsApp.png new file mode 100644 index 0000000000000000000000000000000000000000..2e3b64bd11b0e002bcd37443685c2cd4cadf4a97 GIT binary patch literal 1715 zcmZ{k2Ut@{5P%o4_p_Yc!#leNDTF{Gh(Hh`h7tmbpc2AMQAjulC?bjlJ9_qVwx}qc z3KoihqDTZn6#|L~QbizyAPMOSxADC1JiqVed;4Z*_Me%3^Y+_A-kxsbM$a4#02oJh zCsCoEXc{BU;d`;=1Yf9zvYaSR06aWCMo%9GZL=tJi#03_@K zKnq<7od86m0q70}fOsB&X%UxleCz=ja?yJY%@qO~jYg-{>U27T!H}Mnsnu!+2M1GA z(*y#++_`fHlmpNYJy48;MkrtB2BTW7Ho?Y0ol&PTXy62zN|kcZFxab=b!jBfqf)61 zdPAS~bGKSz)Ek>ynw3f=OsLgs)he}4qw7$1Lc^dn7+`&^Ua!^b)H>)_DO8#Pbx*gX zS1J3X=#oigVzF4O(x?WMwY9a<9;rsHkq^k*+u9X!MZZe^_dG6shhjhhi+)!0_xJVp z%RbBGeeZf3-bm|v<+8rszPh({{Ahk_YwL#(AIi(hlarHAo;q3ex~jdoP4cN5J|A1! z#ns~5DJcyDO^>^?ue9I1+Cf2ts*snZ=VNtCb!-9 z6a{&gZ1gJGu%TjegS<)DBU)1&NEHQF_r1B*n!36uz@un=MrZDWkC`MP?OfwEwO+mF zO_Eaq)m7+E68gCaX|6&)=K|kr&37JmcbP87Yslf8j}awP8~!*ZHNd zW4@0=zSoVGyXDd9`<$IWC8MvEk;4x=Uy41rJ)EaLeKy zp88m2k%+lo%#xUA9YSGeNkOLw9?K5q&}~p{4!4$5hm-Ymq!jRX!3o8u0RQ4#I|Q2>mYWEy7GjXU)am_;Tz z(WZ;dCYs5NrhqYH$Bmyb@rOy1rwlP|&wT2S(>87jriU=5&zL!M802Tq2}PJJ7Mrtq z?oSrO!H9W3ZwU+M@_0OMSi~>$7l4I}ev6FaN5^c1vMqM;60mgH_P8DKJ9i~O*}Z4) zufTF&;{F5i2M--K$)O`w0ChAe>Dck#Pnt@Ef1I9?o|*L|J3c4(sjVF#5TE5ef038}vOxH%uxPnG za9B|+Dk&{1uMkzfu5w&C0ysHWi)(7%ynS2uuHJ>@IufjMb0@F%So6Mt;_2n>GYSBz zFU`+??Ye;Vfk7KazzgeLP1r8~$fn`24-5FN>-eE`K0;(fB2WP=8e?OLwzI_GXlNTE z#+Hb~FGHh=X!N6bJLmr=Ae9 t)6q7zI6NAUAuw=soLvZFO$cQ$tzd)|++Uo$e=V#4$gZBGROjG5e*tW;LRbI* literal 0 HcmV?d00001 diff --git a/Core/src/org/sleuthkit/autopsy/communications/images/creditcards.png b/Core/src/org/sleuthkit/autopsy/communications/images/creditcards.png new file mode 100644 index 0000000000000000000000000000000000000000..4eae583e15294a046d9ba4421f6b832361b7c516 GIT binary patch literal 693 zcmV;m0!safP)Q4qy{_r0XCiLueP)TcDHRjFwyR49fBE=0SrAQVAxqZ`35;M!d_>Nn7(Yg2F` z1vlcNi$EwyQ)xj+tCU)6UTm8-FYn%Q@nZgv>VaV{%$;-Qo;&K+v&9$F$=H(~+lm8- z0Adgk#0Z!mi!m4@6ib!2?_bW}qk+)1(fHHTL+1etq;Uer#c88T|dM4_%NSVb{RO;L$#*c>!gO`EEaw+pK$^dpxC_E1xZNEcKya6MW%d@1@X+oh8 zN-6#Y&+{UVGYe&`-3(IPmadC$(7kWaH|WA{ z3R3wV$A_qlPvEADBHf96+Ja>=N#^FKi;wyGDIy-Y+*~f_`o6Y8vQtBHKy#WBm z7+&Pi)|U`M{EFlF3oFa=kmq^c?RL>L4MGT42`w07NRkBBTI~1xpQ5U&yeJABk4Fp! z14L1DQ^0$V!{LD8aEPj^-U=du_a0J8^m@IUgFvdW5@6qXW;G9F2W#F9O zBs=HeoI?l!Lm&xn#ogb>cii^T!}FrUxQY9e|v5&*pJy~juU9WEb0N_n<(nxPx# literal 0 HcmV?d00001 diff --git a/Core/src/org/sleuthkit/autopsy/communications/images/email.png b/Core/src/org/sleuthkit/autopsy/communications/images/email.png new file mode 100644 index 0000000000000000000000000000000000000000..7348aed77fe6a64c2210a202f12c6eccae7fcf24 GIT binary patch literal 641 zcmV-{0)G98P)Az`{eoOom?Tf*9)f$7n8&|1&5M4#i^32;+&E? zC3Q;bRFQN#y*%%=_V)Mfa<$xe^kB0TO;vJPkN*k(2v-CI7)OaWj?&eKPos(H4wGh_ zIC;6#q1B5SMap5{(Hc0~XO7OfqZ=x{kupu8-H&9azl`L1pTuu^Znm3EA)kCoG=JuwsyNLEtY83i->Z~j3y~F)`RA1k>zTES07po!kBVS2y#L{jCt|CMY&v{ zxmqM|`OA#P2{R&)OcQd}v0kt6_Dh#`Z$i5_;q|93je3Q^PcfR{TmBHRmr;rWahz~G z2x-&;d_O~HkmKXt5Cd#Bs?-+qj3zOiUdU24KowBIUPg(gPNmxqX)Fiia~V*$y;5L( zrGNmU;81MA$F2k%oeUXQ@}N%bXz=qOij$4IYk4W=jfhDxfCz{PGXe-#ge#VfYTyoj zh4JvDePrW{lf(Oux2xG;VZmlSvDU+Qf@i=O!B`MLglhttCUHDIKkc7wwN{;4Af#Jp@WI=GB}9|NC!dC z#nqv7aBy&Iw+`?q09G%2XQKZ2^1r>3y(Iz3yd-tAm9ojzoVjeUHF5K^& z-}(4B&g{y!IVSSTU8%{m#XCF5|8^!OnqbgZp@3yUQ@#D5H zgXCj^750dYk4EcPEI2?4GhPNIFM~oh1?2$Cm2EUy8f<(J8y~_t)?mIgj@6}nr1zKq zW1zuo;ti(9!vE&ZIWDi;Ae8F9k$L@W7bL7>k0?r_x{DLmpcl_lcscRBr$K^L zL>IfbbeNwpt&+*dsX6~Si00000NkvXXu0mjfHKOoo literal 0 HcmV?d00001 diff --git a/Core/src/org/sleuthkit/autopsy/communications/images/instagram.png b/Core/src/org/sleuthkit/autopsy/communications/images/instagram.png new file mode 100644 index 0000000000000000000000000000000000000000..2688d3ab557751cd4e6f65b0f97c7b8dac870844 GIT binary patch literal 804 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6SkfJR9T^xl_H+M9WCijSl0AZa z85pWm85kOx85n;42huMY7)lKo7+xhXFj&oCU=Yur6o1qWsFo?o+ueoXe|!I#{XiaP zfk$L90|U1(2s1Lwnj--eWH0gbb!C6RB_(dAJ=yp04h9CsEuJopAsXj%C+^P{PLw#l z|9tWL*}o@pKl3|tQ$d6Avf5Qo5phRNzO~)X+=T^2uYxod{bn`4==l5}J9;-1yF7JK3mYAqS1{pef5{J~XZ8ESv3~_j(c6N5116T^5yEd!F2VI#Je{|LUtL zcFngLl=g?{UsaaZu-Q22!KSK(?5C{em$TiBtVzrNcDwd6LtS2F|3=S6_7@M#YM*q7 znV}&6(eU_1fVRjm-+1s#aM)WPWGF&F#UFdDZ00 ztAF=+V-A0}{d>vek`|*l#!_ z=l_eceDQ*>;KHO`wfdG!MQ0n5OQbE@wcngwS?XsI7@Pl2>pFvooTb}S`6ZT1FRw|v zx39~rKBV!{xxA>u;y$nXd2hDKem;@wyISD=f0@_HM_8ZUdpJ=xc;_TLWAn=9UnLo- z0t{2KH9arKJO_r3+$mA(Ylr_o<L7=A!*HZf2bc->9hmbgo( ztuxTJ)O{BU3SI-*r3^f&w^Tp(^ktwCH*OFW288x2p~@x>s(3fG2C}xufJ6Nmne(}& zX##6eC8!mz(mi;5qD1*d>^z*|WR5d&}z+ykQuepPyf>tgL*ow6yfOr_0CVci=Q~(5|JLDXK--vx?6lG6e5{Sp3Th6e7L{A{~qu)a34tJ7vUOB zg#iybfM@#q`+HpmbaQhvF*i4NJCn(L1SEhH;Gs5g!0>ILudgo}jYgjaNT<_(Ei5d2 zyuH2sF7PGxQ{h3gqVC48fv)lK@mB!Z+1a@_J3D(Pl}f#jUF*NlP)A1 zOEJ*J2%-6P-uFsN(314vc)81apZC3Y?}U^RyNqtPD}x|FyWJM~eFHm=EXyz)4*%_2 z`9-hS>nKH+LWpCvJW_K{ee2+Qy$;K=iUCm+-8LExR4SE?bDE}l5@MQWF@R2<=i#hh zg==L9Gagssz>e{B{#CAk4$LM@iPnXHWk?Xw`LOUEW#s_FFc8NvgbK8&R^1S*OrR37 zn*ts~sNlPI6{FG%N)TkF%_zHVFy=yhaAh z=X2P$4d3_SI1Uzzg$DC~VGUH@|Ab+(Q#4XH@4ktAj@60RTG$5=HcZZS5{SIqF_N{Nop=j*CvbS@%s zDX+dXkR--e5mc2sr*b^ITA~o7sOsi1tmjY>e6@nAV|pdw zVku;_|1kH?7PwprIhgV2%9(8|y(s^p9xG}E(@HR2iMZL7BX4{Lx(f_+7yjADa;(hM z)&WovjH;kcIocMmKk#;K|6?sdoi+_r@ZCm&*X1SN&enG|7^^fk`*9+eRtJlbV<8e! zV5c0j^@OKW3#c|B<7mW5$?l qZcwHthH$p~zmzTb=96h_AN&mgP8eQq{-WRj0000A9)b<7tX~vT z$e)FfZ+`X4_uKyq#wJHC;J3lH{lhQkUc~Wid;*pnjhM12xe-bPByd^xuQ9zgeM^Mm z*tc)|P}LtTnHXr@Gkmmbkg^O2bqyhO>LP|qjIwW2@Di+4EuKm~&tOO2!N3o{128Hl z9v%fgerM0C#)7P|PMvxr*!Gf?eGA8f{OT6fS`9l>LQCg)p=~c$Zr|AT_0+_?F*JJk zlapOT2Q(wWx-LMq(TxXxLn+U;!LV)MhNp~ommdh+fo8T*&g-yQbbG&ze&=>tC(Ar=&^1xlA;Jc(6 zcCi_xs8k}-S&#ONOHm%e@#nGC7F++8C~r29Or!_{(QGQEG)+O^J1BCPmgM4JAzC8I z`jS9bO>|}Jq_#$IRzp0d34>)&3L%7MN)eTv!0B!^nn}f4z2*vFE@jv3dn zG>H)u>FR7_d2JcsjvfZ$vkP~xik@T^(_N)nx=tqJV+tQjQ`owJ83bf`zX6Ear*=Mhzn5QUuXE|v zR33Qyi8G!0{H2r##d#6R6YmYbZz4NTssT;cXiGb6lxO+k@{ba@2D~*hKDY6N;Bkh> xhhCRLejsJkAIT{5sICHcfU`5>bKmUb{{y)0nR3PMMxX!y002ovPDHLkV1nl+t-}BS literal 0 HcmV?d00001 From 0b2b05f7aa09de117715a318513bfb78886c7a60 Mon Sep 17 00:00:00 2001 From: millmanorama Date: Mon, 23 Oct 2017 22:28:42 +0200 Subject: [PATCH 020/127] comments and small fixes --- .../autopsy/communications/AccountNode.java | 15 ++++++-- .../communications/AccountsBrowser.java | 26 ++++++++++++-- ...RootNode.java => AccountsNodeFactory.java} | 36 ++++++++----------- .../communications/CVTTopComponent.java | 15 +++++--- .../autopsy/communications/OpenCVTAction.java | 18 ++++++---- 5 files changed, 73 insertions(+), 37 deletions(-) rename Core/src/org/sleuthkit/autopsy/communications/{AccountRootNode.java => AccountsNodeFactory.java} (53%) diff --git a/Core/src/org/sleuthkit/autopsy/communications/AccountNode.java b/Core/src/org/sleuthkit/autopsy/communications/AccountNode.java index bf622c556c..cd4d4c3082 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/AccountNode.java +++ b/Core/src/org/sleuthkit/autopsy/communications/AccountNode.java @@ -26,6 +26,9 @@ import org.openide.util.lookup.Lookups; import org.sleuthkit.autopsy.datamodel.NodeProperty; import org.sleuthkit.datamodel.Account; +/** + * Node to represent an Account in the AccountsBrowser + */ class AccountNode extends AbstractNode { private final Account account; @@ -37,6 +40,12 @@ class AccountNode extends AbstractNode { setIconBaseWithExtension("org/sleuthkit/autopsy/communications/images/" + getIconFileName(account.getAccountType())); } + /** + * The file name of the icon for the given Account Type. Will not include + * the path but will include the extension. + * + * @return The file name of the icon for the given Account Type. + */ final String getIconFileName(Account.Type type) { if (type == Account.Type.CREDIT_CARD) { return "creditcards.png"; @@ -59,6 +68,7 @@ class AccountNode extends AbstractNode { } else if (type == Account.Type.WHATSAPP) { return "WhatsApp.png"; } else { + //there could be a default icon instead... throw new IllegalArgumentException("Unknown Account.Type: " + type.getTypeName()); } @@ -85,12 +95,13 @@ class AccountNode extends AbstractNode { properties.put(new NodeProperty<>("count", Bundle.AccountNode_messageCount(), "count", - 1)); // NON-NLS + 1)); // NON-NLS //dummy value + + //how do I get the device name // properties.put(new NodeProperty<>("device", // Bundle.AccountNode_device(), // "device", // account.)); // NON-NLS - return s; } } diff --git a/Core/src/org/sleuthkit/autopsy/communications/AccountsBrowser.java b/Core/src/org/sleuthkit/autopsy/communications/AccountsBrowser.java index e6f4527399..c61bb95fd7 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/AccountsBrowser.java +++ b/Core/src/org/sleuthkit/autopsy/communications/AccountsBrowser.java @@ -1,3 +1,21 @@ +/* + * Sleuth Kit Data Model + * + * Copyright 2011-2017 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package org.sleuthkit.autopsy.communications; import javax.swing.JPanel; @@ -5,14 +23,18 @@ import javax.swing.ListSelectionModel; import org.netbeans.swing.outline.DefaultOutlineModel; import org.netbeans.swing.outline.Outline; -public class AccountsBrowser extends JPanel { +/** + * A panel that goes in the Browse tab of the CVT. Has a OutlineView that shows + * information about Accounts. + */ +class AccountsBrowser extends JPanel { private static final long serialVersionUID = 1L; /** * Creates new form AccountsBrowser */ - public AccountsBrowser() { + AccountsBrowser() { initComponents(); final Outline outline = outlineView.getOutline(); outlineView.setPropertyColumns( diff --git a/Core/src/org/sleuthkit/autopsy/communications/AccountRootNode.java b/Core/src/org/sleuthkit/autopsy/communications/AccountsNodeFactory.java similarity index 53% rename from Core/src/org/sleuthkit/autopsy/communications/AccountRootNode.java rename to Core/src/org/sleuthkit/autopsy/communications/AccountsNodeFactory.java index c54331f39a..0abde7fd3a 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/AccountRootNode.java +++ b/Core/src/org/sleuthkit/autopsy/communications/AccountsNodeFactory.java @@ -19,36 +19,28 @@ package org.sleuthkit.autopsy.communications; import java.util.List; -import org.openide.nodes.AbstractNode; import org.openide.nodes.ChildFactory; -import org.openide.nodes.Children; import org.openide.nodes.Node; import org.sleuthkit.datamodel.Account; -public class AccountRootNode extends AbstractNode { - public AccountRootNode(List accounts) { - super(Children.create(new AccountsNodeFactory(accounts), true)); +class AccountsNodeFactory extends ChildFactory { + + private final List< Account> accounts; + + AccountsNodeFactory(List accounts) { + this.accounts = accounts; } - private static class AccountsNodeFactory extends ChildFactory { + @Override + protected boolean createKeys(List list) { + list.addAll(accounts); + return true; + } - private final List< Account> accounts; - - private AccountsNodeFactory(List accounts) { - this.accounts = accounts; - } - - @Override - protected boolean createKeys(List list) { - list.addAll(accounts); - return true; - } - - @Override - protected Node createNodeForKey(Account key) { - return new AccountNode(key); - } + @Override + protected Node createNodeForKey(Account key) { + return new AccountNode(key); } } diff --git a/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java b/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java index bef2a2f1c1..08e3971255 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java +++ b/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java @@ -21,6 +21,8 @@ package org.sleuthkit.autopsy.communications; import java.util.List; import java.util.stream.Collectors; import org.openide.explorer.ExplorerManager; +import org.openide.nodes.AbstractNode; +import org.openide.nodes.Children; import org.openide.util.Exceptions; import org.openide.util.NbBundle; import org.openide.windows.Mode; @@ -33,7 +35,7 @@ import org.sleuthkit.datamodel.Account; import org.sleuthkit.datamodel.TskCoreException; /** - * Top component which displays something. + * Top component which displays the Communications Visualization Tool. */ @TopComponent.Description( preferredID = "CVTTopComponent", @@ -153,12 +155,17 @@ public final class CVTTopComponent extends TopComponent implements ExplorerManag }// //GEN-END:initComponents private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed - + /* + * When the apply button is pressed, query for accounts using the + * selected filters, and send the results to the AccountsBrowser via the + * ExplorerManager + */ try { List accounts; - accounts = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().getAccounts(Account.Type.EMAIL); + accounts = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager() + .getAccounts(Account.Type.EMAIL); - em.setRootContext(new AccountRootNode(accounts)); + em.setRootContext(new AbstractNode(Children.create(new AccountsNodeFactory(accounts), true))); } catch (TskCoreException ex) { Exceptions.printStackTrace(ex); } diff --git a/Core/src/org/sleuthkit/autopsy/communications/OpenCVTAction.java b/Core/src/org/sleuthkit/autopsy/communications/OpenCVTAction.java index c62018e2b3..04065cc28c 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/OpenCVTAction.java +++ b/Core/src/org/sleuthkit/autopsy/communications/OpenCVTAction.java @@ -33,6 +33,10 @@ import org.openide.util.actions.Presenter; import org.openide.windows.TopComponent; import org.openide.windows.WindowManager; +/** + * Action that opens the CVT. Available through the Tools menu and the main + * toolbar. + */ @ActionID(category = "Tools", id = "org.sleuthkit.autopsy.communicationsVisualization.OpenCVTAction") @ActionRegistration(displayName = "#CTL_OpenCVTAction", lazy = false) @@ -41,17 +45,17 @@ import org.openide.windows.WindowManager; , @ActionReference(path = "Toolbars/Case", position = 102)}) @Messages("CTL_OpenCVTAction=Visualize Communications") public final class OpenCVTAction extends CallableSystemAction implements Presenter.Toolbar { - + private static final long serialVersionUID = 1L; - + private final JButton toolbarButton = new JButton(getName(), new ImageIcon(getClass().getResource("images/email_link.png"))); //NON-NLS public OpenCVTAction() { toolbarButton.addActionListener(actionEvent -> performAction()); - setEnabled(false); + setEnabled(false); //disabled by default. Will be enabled in Case.java when a case is opened. } - + @Override public void performAction() { final TopComponent tc = WindowManager.getDefault().findTopComponent("CVTTopComponent"); @@ -74,7 +78,7 @@ public final class OpenCVTAction extends CallableSystemAction implements Present super.setEnabled(value); toolbarButton.setEnabled(value); } - + @Override @NbBundle.Messages("OpenCVTAction.displayName=Communications Visualizaton") public String getName() { @@ -90,12 +94,12 @@ public final class OpenCVTAction extends CallableSystemAction implements Present public Component getToolbarPresenter() { return toolbarButton; } - + @Override public HelpCtx getHelpCtx() { return HelpCtx.DEFAULT_HELP; } - + @Override public boolean asynchronous() { return false; // run on edt From c237e3414608fa5bd4148368298e36ec872d1372 Mon Sep 17 00:00:00 2001 From: millmanorama Date: Mon, 23 Oct 2017 22:44:58 +0200 Subject: [PATCH 021/127] sort by counts, show device accounts (not sure we want this, more for testing --- .../communications/AccountsBrowser.java | 6 +++--- .../communications/AccountsNodeFactory.java | 4 ++-- .../autopsy/communications/Bundle.properties | 21 ++++++++++++++++--- .../communications/CVTTopComponent.java | 9 +++++--- 4 files changed, 29 insertions(+), 11 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/communications/AccountsBrowser.java b/Core/src/org/sleuthkit/autopsy/communications/AccountsBrowser.java index c61bb95fd7..29322196c4 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/AccountsBrowser.java +++ b/Core/src/org/sleuthkit/autopsy/communications/AccountsBrowser.java @@ -1,5 +1,5 @@ /* - * Sleuth Kit Data Model + * Autopsy Forensic Browser * * Copyright 2011-2017 Basis Technology Corp. * Contact: carrier sleuthkit org @@ -8,7 +8,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -46,7 +46,7 @@ class AccountsBrowser extends JPanel { outline.setRootVisible(false); ((DefaultOutlineModel) outline.getOutlineModel()).setNodesColumnLabel(Bundle.AccountNode_accountName()); outline.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); - + outline.setColumnSorted(3, false, 1); //it would be could if the column index wasn't hardcoded } /** diff --git a/Core/src/org/sleuthkit/autopsy/communications/AccountsNodeFactory.java b/Core/src/org/sleuthkit/autopsy/communications/AccountsNodeFactory.java index 0abde7fd3a..37cfccc4af 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/AccountsNodeFactory.java +++ b/Core/src/org/sleuthkit/autopsy/communications/AccountsNodeFactory.java @@ -1,5 +1,5 @@ /* - * Sleuth Kit Data Model + * Autopsy Forensic Browser * * Copyright 2011-2017 Basis Technology Corp. * Contact: carrier sleuthkit org @@ -8,7 +8,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/Core/src/org/sleuthkit/autopsy/communications/Bundle.properties b/Core/src/org/sleuthkit/autopsy/communications/Bundle.properties index aa0b453d77..ba1a2e7ea1 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/communications/Bundle.properties @@ -1,6 +1,21 @@ -# To change this license header, choose License Headers in Project Properties. -# To change this template file, choose Tools | Templates -# and open the template in the editor. +#/* +# * Autopsy Forensic Browser +# * +# * Copyright 2011-2017 Basis Technology Corp. +# * Contact: carrier sleuthkit org +# * +# * Licensed under the Apache License, Version 2.0 (the "License"); +# * you may not use this file except in compliance with the License. +# * You may obtain a copy of the License at +# * +# * http://www.apache.org/licenses/LICENSE-2.0 +# * +# * Unless required by applicable law or agreed to in writing, software +# * distributed under the License is distributed on an "AS IS" BASIS, +# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# * See the License for the specific language governing permissions and +# * limitations under the License. +# */ CVTTopComponent.jPanel2.border.title=Filters CVTTopComponent.jTextField1.text=place holder for messages ,thumbnail list, etc diff --git a/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java b/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java index 08e3971255..288380825e 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java +++ b/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java @@ -18,6 +18,7 @@ */ package org.sleuthkit.autopsy.communications; +import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; import org.openide.explorer.ExplorerManager; @@ -32,6 +33,7 @@ import org.openide.windows.WindowManager; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.coreutils.ThreadConfined; import org.sleuthkit.datamodel.Account; +import org.sleuthkit.datamodel.CommunicationsManager; import org.sleuthkit.datamodel.TskCoreException; /** @@ -161,9 +163,10 @@ public final class CVTTopComponent extends TopComponent implements ExplorerManag * ExplorerManager */ try { - List accounts; - accounts = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager() - .getAccounts(Account.Type.EMAIL); + List accounts = new ArrayList<>(); + final CommunicationsManager communicationsManager = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager(); + accounts.addAll(communicationsManager.getAccounts(Account.Type.EMAIL)); + accounts.addAll(communicationsManager.getAccounts(Account.Type.DEVICE)); em.setRootContext(new AbstractNode(Children.create(new AccountsNodeFactory(accounts), true))); } catch (TskCoreException ex) { From 14465efc0432d8f2f462da5c430ae630ef2e4b5d Mon Sep 17 00:00:00 2001 From: millmanorama Date: Tue, 24 Oct 2017 11:30:14 +0200 Subject: [PATCH 022/127] tweak account type icons --- .../autopsy/communications/AccountNode.java | 8 ++++---- .../autopsy/communications/images/calllog.png | Bin 0 -> 691 bytes .../communications/images/credit-card.png | Bin 0 -> 536 bytes .../communications/images/creditcards.png | Bin 693 -> 0 bytes .../autopsy/communications/images/device.png | Bin 578 -> 0 bytes .../autopsy/communications/images/email.png | Bin 641 -> 710 bytes .../communications/images/folder-icon-16.png | Bin 0 -> 483 bytes .../autopsy/communications/images/image.png | Bin 0 -> 1286 bytes .../communications/images/messaging.png | Bin 1124 -> 829 bytes .../autopsy/communications/images/web-file.png | Bin 0 -> 928 bytes .../autopsy/communications/images/world.png | Bin 923 -> 0 bytes 11 files changed, 4 insertions(+), 4 deletions(-) create mode 100755 Core/src/org/sleuthkit/autopsy/communications/images/calllog.png create mode 100755 Core/src/org/sleuthkit/autopsy/communications/images/credit-card.png delete mode 100644 Core/src/org/sleuthkit/autopsy/communications/images/creditcards.png delete mode 100644 Core/src/org/sleuthkit/autopsy/communications/images/device.png mode change 100644 => 100755 Core/src/org/sleuthkit/autopsy/communications/images/email.png create mode 100755 Core/src/org/sleuthkit/autopsy/communications/images/folder-icon-16.png create mode 100755 Core/src/org/sleuthkit/autopsy/communications/images/image.png mode change 100644 => 100755 Core/src/org/sleuthkit/autopsy/communications/images/messaging.png create mode 100755 Core/src/org/sleuthkit/autopsy/communications/images/web-file.png delete mode 100644 Core/src/org/sleuthkit/autopsy/communications/images/world.png diff --git a/Core/src/org/sleuthkit/autopsy/communications/AccountNode.java b/Core/src/org/sleuthkit/autopsy/communications/AccountNode.java index cd4d4c3082..f2571b5eb7 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/AccountNode.java +++ b/Core/src/org/sleuthkit/autopsy/communications/AccountNode.java @@ -48,9 +48,9 @@ class AccountNode extends AbstractNode { */ final String getIconFileName(Account.Type type) { if (type == Account.Type.CREDIT_CARD) { - return "creditcards.png"; + return "credit-card.png"; } else if (type == Account.Type.DEVICE) { - return "device.png"; + return "image.png"; } else if (type == Account.Type.EMAIL) { return "email.png"; } else if (type == Account.Type.FACEBOOK) { @@ -64,7 +64,7 @@ class AccountNode extends AbstractNode { } else if (type == Account.Type.TWITTER) { return "twitter.png"; } else if (type == Account.Type.WEBSITE) { - return "world.png"; + return "web-file.png"; } else if (type == Account.Type.WHATSAPP) { return "WhatsApp.png"; } else { @@ -77,7 +77,7 @@ class AccountNode extends AbstractNode { @Override @NbBundle.Messages({ "AccountNode.device=Device", - "AccountNode.accountName=Account Name", + "AccountNode.accountName=Account", "AccountNode.accountType=Type", "AccountNode.messageCount=Message Count"}) protected Sheet createSheet() { diff --git a/Core/src/org/sleuthkit/autopsy/communications/images/calllog.png b/Core/src/org/sleuthkit/autopsy/communications/images/calllog.png new file mode 100755 index 0000000000000000000000000000000000000000..83eb9c448d592e1cc125710cd5d02e9520543457 GIT binary patch literal 691 zcmV;k0!;mhP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!~g&e!~vBn4jTXf0!T?jK~y+TjgoCh zQ&AYl|9880cXtjqbbg5Z;Dkjb=7)k&R75l=C>PWh2lh6~K#EcdBFLZyWe~LwjrvrO z4#om2h_a|82}*QEnvNu#m=5!8tG(QLx7)dQw{5*F{BiF&-2XYx|D5|g4183s#&04;6A1%ExNOnSH)hvdz_xZXL8`KW-)$Lq2; z*u3@#qKPn4LJV`!2{?D$1E;6qKGX-db5Rb8#d$Jj(DmvI+BzcW9r`Zoxhgcd%b?S7 zs5EXs>;8xGVj-cgbJ%@u7z+svHm#=MyJVI1TosykcHvuO3L{h9NW@9a{$M#eatwSriSzes74>%x+l*+on=v>VRuqEt3x%AyT`M+RgXrqmt|)ng z)Vvr7`jxLN|Lnw5x6BB~$5CmppmpyvtT36;`_YTLua82*s9~*Y!ogkb^4_AYeA;8d zOni)7QGUQ_RM2ZHK&x5A_&Mxbe-k#Vv$%moyVs6^$wx5gbf8GOD2jqw#gJnuqi zli~jxNc04}@H};ZP5QYc-1MhL{N;xsM|AwM7lLDIN%<;ozE6b6F}n?P(y_qDgX zli8CH$OIL3;f1-Kxw$uQ=Ix#!BHU$3+;J(jd$G;?)-A9C)*dK!HrHP~SfSF@B=;lv zp#s5`B|;_GWaayJ0h*XE5Jf zrE$K1RnWy`=2>ljGB05=$E`b*r9~|wP(EZ4i+s+j?FE}P^YaElauATeJQ7ELERgn< zBAv(nsNOCC-AmwU!!khQaggG7B5^oq;t7M7->)G$ImEM%8(UU27CcUEuZC4#;&X6tS|-jrNQ4qy{_r0XCiLueP)TcDHRjFwyR49fBE=0SrAQVAxqZ`35;M!d_>Nn7(Yg2F` z1vlcNi$EwyQ)xj+tCU)6UTm8-FYn%Q@nZgv>VaV{%$;-Qo;&K+v&9$F$=H(~+lm8- z0Adgk#0Z!mi!m4@6ib!2?_bW}qk+)1(fHHTL+1etq;Uer#c88T|dM4_%NSVb{RO;L$#*c>!gO`EEaw+pK$^dpxC_E1xZNEcKya6MW%d@1@X+oh8 zN-6#Y&+{UVGYe&`-3(IPmadC$(7kWaH|WA{ z3R3wV$A_qlPvEADBHf96+Ja>=N#^FKi;wyGDIy-Y+*~f_`o6Y8vQtBHKy#WBm z7+&Pi)|U`M{EFlF3oFa=kmq^c?RL>L4MGT42`w07NRkBBTI~1xpQ5U&yeJABk4Fp! z14L1DQ^0$V!{LD8aEPj^-U=du_a0J8^m@IUgFvdW5@6qXW;G9F2W#F9O zBs=HeoI?l!Lm&xn#ogb>cii^T!}FrUxQY9e|v5&*pJy~juU9WEb0N_n<(nxPx# diff --git a/Core/src/org/sleuthkit/autopsy/communications/images/email.png b/Core/src/org/sleuthkit/autopsy/communications/images/email.png old mode 100644 new mode 100755 index 7348aed77fe6a64c2210a202f12c6eccae7fcf24..a919ae3e50664bd01a78732d9a07e223608b3aa4 GIT binary patch delta 687 zcmV;g0#N;d1;z!CBYy&oNkl>j+MtG` z`P5q!jWtZenr-1AX^&A+9=V3WVbEcy0@AdVgJ@<=Q2uPLp3F*11eZ z{OmLs3_5Yl$jF}lw#l;zWPXNo zv-VDzW9P4SA72A_@0xqg9#{qBN>CLJ&@)d!79JCTqyQFy`SDEZemQN9SsZHt(&uh? zW!mjOAvUP8Gk;(c6Hx9lgP9){mXLwGpc2cUJksFdS?jpP9;g%3<6eyjzFQ>0fH(;df`1bZK=fKm*?Qv6)clgDA#vlIDZy@-PqW0N(87tAP}jmtJCs4 zhmYe=F*|V&+bgP}P^!Um3>Iewkw`KqJ?O%|Ll($n1j6BPw5h4dC;@)IKVmYOw0|}< zy^=&c_7L+^k3fJ$e)&1<*WW;1zWVP;^!7$=Hd_|(`Fs(h(U=1`j>FvC90-01^hyGx zstjs%5r5=zc@F67>x()Zjx6BydLy;9wGzOxEK;cygbOGvHG4=r&m);!f>KFAp-@Qw z`uqE%PNy>qw6{Nq7z`)148usXQxx^jyG_%ygo?<(z(BOMwKWU4-R_7^r_+j^1VOC( zc*NCk9FL))!KlmSk^qI>ZVzfSn(B?b!m+WjktnXNu8XqO+qhK-)duo;A(n;s^&47c V_BvT^Cy4+6002ovPDHLkV1nXuPO<<1 delta 617 zcmV-v0+#*81%U;SBYyw{XF*Lt006JZHwB960000PbVXQnQ*UN;cVTj606}DLVr3vn zZDD6+Qe|Oed2z{QJOBU!6G=otR2Uhh!OKn)VHkkn_xtDX^gyQvIaDcySQFybYw!YG zdj)R20r#%mx-)ShI}=TaE-;aW8r`$N1Z<^J+5#O)JJXr}lYe5O?)yBVs?5VMC;R02 z=bc<3xYrA(3m22bI0c82I>o7ys^XlIIwf^V>Qs?*I=wvawf6S+?Q*r;c=TYi6irof zS&#n-{|HwE1QD1S1+a^sE}MX6*nhWf1%@4j_8yO>fd2^kN3Pw=haTd3rP{xD{1_n69! z5{s2ASHxUS5@wn=i>%d3Y=7-?8cta%8hi`B2j!eF2xGQ(yDTl1Xx58}a?Ok;DKplC z=4z4UYJpcDS`5ONa!v?xLO+ao@xDd5T%fsHByai4jDN-nGa`^o6LQwEUa#=>OP6+U zLc2HN^`|b4dWFDGF`D38{t&R2QHla_oNzn{Y19IIKSO7b`)E4uMCNZ5} z$Wk>x6;Q!mMv10QrP~i_EC=Ls8Bn;rQeb_hfB>T4P;9}+t^^#N3>jDQpib>*@be&w zla0G;d15K%jfhDxfCz{PGXe-#ge#VfYTyojh4JvDePrW{lf(Oux2xG;VZmlSvDU+Q zf@i=O!B`MLglhttCUHDIKkc7T!51h6p_`5m;7V|3DYOcL z2#T%*cQObrT)0pQQ+1lrNoJCJyfLA5v|UVv9td1+IKO*y&I#d}LH`X{c|RHReAeZX zi9qi@?Avv~=lQN~1_|)*q?+erbfib?9h+DKnseajr4&H+F}+$ExCgw|%t6UZ4p`{~oZ<;cX?juc-mj#PnPRIHZt82`Ti~3Uk?B!Ylp0*+7m{3+ootz+WN)WnQ(*-(AUCxn zQK2F?C$HG5!d3}vt`(3C64qBz04piUwpD^SD#ABF!8yMuRl!uxKsVXI%uvD1M9IxIyg#@@$ndN=gc>^!3Zj z%k|2Q_413-^$jg8E%gnI^o@*kfhu&1EAvVcD|GXUm0>2hq!uR^WfqiV=I1GZOiWD5 zFD$Tv3bSNU;+l1ennz|zM-B0$V)JVzP|XC=H|jx7ncO3BHWAB;NpiyW)Z+ZoqGVvir744~DzI`cN=+=uFAB-e&w+(vKt_H^esM;Afr4|esh**NZ(?$0 z9!LbN!`Ii!Gq1QLF)umQ)5TT^Xog;9W{Q=oo0FxHp|iP}o1>|rp{t>Vo2#X(rHh-R zqqBjFi;)vduSMv>2~2MaLazl*y`aR9TL84#CABECEH%ZgC_h&L>}jh^+-@<& zX&zK>3U0TU;nb@Sbc{YIYLTKECIn1BASOKF0y*%cpPC0u??u3b9iF@#n8O$=JY5_^ zDsCnH`TyUZS+!we7Tb&&GYptl<~y8mYq4uIPCr+}Vi+-j<>`^5syCjUo!uXvUR9-a zc(S^`N`ns%^A%RsR*7kPv3(0q-Z;T>?%9I}Oo5jiYJ~4Hh&nntvc<~U@-Wx^{l%L8 zxuCdNgHuBODl3x{kA3~WmLKkMY)2=!^UrU{^wZOu!=~}+!-qq;xA#`_cQJNxc?mFE ze2_T6TOxOYAyw3sEz&ZxZFl**W>tq80fvt^ZycPc(v`$u!WAlKTXllrkb9pTlXp>Z z){gdBN^78)|e))gy@^*jXeL_Wb?1WeKw+2l5{r9i+;lsJNCI0QJ zJ^eu}zopr08J6R{Qv*} literal 0 HcmV?d00001 diff --git a/Core/src/org/sleuthkit/autopsy/communications/images/messaging.png b/Core/src/org/sleuthkit/autopsy/communications/images/messaging.png old mode 100644 new mode 100755 index 62502c8fb64c9e1120b85ad5fc4aeb64823db9e8..6223516e3e122204aef38296213d0a4d2b382a36 GIT binary patch literal 829 zcmV-D1H$}?P)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!~g&e!~vBn4jTXf0@6uDK~y+Tb(7C) zR96(oKkvTxW-^mFGfeyyQxmkMDvB|J#pq5KUDUJ`#6>Bt6bjvyLKp3(+jb)&{uxFh zZd`~Wx+xmN_`3U^6oj``#s-tu9dBU4Oo`7zWaZe zcoUa@wbt2(Ne}P8;O6rluikTf?GBW=B7OUUjqHk0p_GL+CH=B!}T__NK8v+vk< zU>C}3zTsZ{u_Pq4BT39GmI8~&QY;7HOSxWbv6@)2SG0PXq0ue;I<=CQq3%9@OYNi0 zSgr^yC}O2>N{T>;3T2yi>c~>OTJ>2JSGz*&%X;cLIf3ISO?6PAEKQ$CHnkd)OR`^F ziTHjz zjKmlw39jj@I5K_nAzz+2gmNo&zN*aQm!Q7c$hU9?Y|icR7_FBGq7+~HsD&UDN5eRy z8^oMEzF#i%g-USgy9r8-Tj;XIppeifgHw`vql`<}8~icX)F}my$NeQ+7g3N>FO|!+e!P=UFA1_~JX6G=U=!lcj zoikq?&q?PN{${QfFi@%F1{$eKMl*^Nj*JY@U#Y$?fl#KXC<@kLew#OvL?QEwujz%- zA$bqW9Uo5@*}J2{r)GZs`x-a+Ht^xu2HGoaI)2E=@OJ(ImnmJUg7nZp00000NkvXX Hu0mjf^w*CM literal 1124 zcmV-q1e^PbP)!*HZf2bc->9hmbgo( ztuxTJ)O{BU3SI-*r3^f&w^Tp(^ktwCH*OFW288x2p~@x>s(3fG2C}xufJ6Nmne(}& zX##6eC8!mz(mi;5qD1*d>^z*|WR5d&}z+ykQuepPyf>tgL*ow6yfOr_0CVci=Q~(5|JLDXK--vx?6lG6e5{Sp3Th6e7L{A{~qu)a34tJ7vUOB zg#iybfM@#q`+HpmbaQhvF*i4NJCn(L1SEhH;Gs5g!0>ILudgo}jYgjaNT<_(Ei5d2 zyuH2sF7PGxQ{h3gqVC48fv)lK@mB!Z+1a@_J3D(Pl}f#jUF*NlMh53JODVWnpw>WFU8GbZ8({Xk{Qr zNlj3Y*^6%g00QhuL_t(I%dL}LXj^3*hoASH_nc#sG-;dWqm6CW(4s83b+X9Bt0|~3 z6mOI%-9=?M5O0K`ptn*G#rs`|6-PnD>5WW=H?uIcvzCo^E3WHYKeL=HA5C(SbCR6b z3)#f&*5~^FdoKR`eu4)${@&~<;4NLs{R%AQ`wgX7&~)wW+|1M$58jLW!S}zMGrL#P4P+<|J^kR=q!LjUR<=1mzj7BLp1miL0MTgZr{|x^iYGDyl!|!#OL6OV`f;PXlOge)!c#$#{SGXl@)s^XbSCXaYk@OhXc|B#CG* zL-81~z96~mqojuij=b@~*=YbR90{B}oE@c7E^@~W5Fg%$Qs65I} literal 0 HcmV?d00001 diff --git a/Core/src/org/sleuthkit/autopsy/communications/images/world.png b/Core/src/org/sleuthkit/autopsy/communications/images/world.png deleted file mode 100644 index 68f21d30116710e48a8bf462cb32441e51fad5f6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 923 zcmV;M17!S(P)A9)b<7tX~vT z$e)FfZ+`X4_uKyq#wJHC;J3lH{lhQkUc~Wid;*pnjhM12xe-bPByd^xuQ9zgeM^Mm z*tc)|P}LtTnHXr@Gkmmbkg^O2bqyhO>LP|qjIwW2@Di+4EuKm~&tOO2!N3o{128Hl z9v%fgerM0C#)7P|PMvxr*!Gf?eGA8f{OT6fS`9l>LQCg)p=~c$Zr|AT_0+_?F*JJk zlapOT2Q(wWx-LMq(TxXxLn+U;!LV)MhNp~ommdh+fo8T*&g-yQbbG&ze&=>tC(Ar=&^1xlA;Jc(6 zcCi_xs8k}-S&#ONOHm%e@#nGC7F++8C~r29Or!_{(QGQEG)+O^J1BCPmgM4JAzC8I z`jS9bO>|}Jq_#$IRzp0d34>)&3L%7MN)eTv!0B!^nn}f4z2*vFE@jv3dn zG>H)u>FR7_d2JcsjvfZ$vkP~xik@T^(_N)nx=tqJV+tQjQ`owJ83bf`zX6Ear*=Mhzn5QUuXE|v zR33Qyi8G!0{H2r##d#6R6YmYbZz4NTssT;cXiGb6lxO+k@{ba@2D~*hKDY6N;Bkh> xhhCRLejsJkAIT{5sICHcfU`5>bKmUb{{y)0nR3PMMxX!y002ovPDHLkV1nl+t-}BS From 3537f54e1bff869874c1897cfa169ee95ce3e72e Mon Sep 17 00:00:00 2001 From: millmanorama Date: Tue, 24 Oct 2017 12:25:41 +0200 Subject: [PATCH 023/127] begin build out of FiltersPanel --- .../communications/AccountsBrowser.java | 4 +- .../autopsy/communications/Bundle.properties | 25 +-- .../communications/CVTTopComponent.form | 82 +++------ .../communications/CVTTopComponent.java | 104 +++-------- .../autopsy/communications/FiltersPanel.form | 151 +++++++++++++++ .../autopsy/communications/FiltersPanel.java | 173 ++++++++++++++++++ .../autopsy/communications/images/funnel.png | Bin 0 -> 591 bytes 7 files changed, 382 insertions(+), 157 deletions(-) create mode 100644 Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.form create mode 100644 Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java create mode 100755 Core/src/org/sleuthkit/autopsy/communications/images/funnel.png diff --git a/Core/src/org/sleuthkit/autopsy/communications/AccountsBrowser.java b/Core/src/org/sleuthkit/autopsy/communications/AccountsBrowser.java index 29322196c4..2a0224a511 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/AccountsBrowser.java +++ b/Core/src/org/sleuthkit/autopsy/communications/AccountsBrowser.java @@ -27,14 +27,14 @@ import org.netbeans.swing.outline.Outline; * A panel that goes in the Browse tab of the CVT. Has a OutlineView that shows * information about Accounts. */ -class AccountsBrowser extends JPanel { +public class AccountsBrowser extends JPanel { private static final long serialVersionUID = 1L; /** * Creates new form AccountsBrowser */ - AccountsBrowser() { + public AccountsBrowser() { initComponents(); final Outline outline = outlineView.getOutline(); outlineView.setPropertyColumns( diff --git a/Core/src/org/sleuthkit/autopsy/communications/Bundle.properties b/Core/src/org/sleuthkit/autopsy/communications/Bundle.properties index ba1a2e7ea1..fa0ec34afe 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/communications/Bundle.properties @@ -1,25 +1,8 @@ -#/* -# * Autopsy Forensic Browser -# * -# * Copyright 2011-2017 Basis Technology Corp. -# * Contact: carrier sleuthkit org -# * -# * Licensed under the Apache License, Version 2.0 (the "License"); -# * you may not use this file except in compliance with the License. -# * You may obtain a copy of the License at -# * -# * http://www.apache.org/licenses/LICENSE-2.0 -# * -# * Unless required by applicable law or agreed to in writing, software -# * distributed under the License is distributed on an "AS IS" BASIS, -# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# * See the License for the specific language governing permissions and -# * limitations under the License. -# */ - -CVTTopComponent.jPanel2.border.title=Filters CVTTopComponent.jTextField1.text=place holder for messages ,thumbnail list, etc CVTTopComponent.jTextField2.text=place holder for message viewer CVTTopComponent.TabConstraints.tabTitle=Visualize CVTTopComponent.accountsBrowser.TabConstraints.tabTitle=Browse -CVTTopComponent.jButton1.text=apply +FiltersPanel.jPanel2.border.title=Account Types +FiltersPanel.jPanel1.border.title=Devices +FiltersPanel.jLabel1.text=Filters +FiltersPanel.applyFiltersButton.text=Apply Filters diff --git a/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.form b/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.form index 0131e3e127..fa9cad5ed6 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.form +++ b/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.form @@ -17,10 +17,10 @@ - - - - + + + + @@ -28,69 +28,30 @@ - + - - + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + + + + + + @@ -132,14 +93,14 @@ - + - + @@ -180,5 +141,14 @@ + + + + + + + + + diff --git a/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java b/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java index 288380825e..6c3d6af995 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java +++ b/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java @@ -18,23 +18,15 @@ */ package org.sleuthkit.autopsy.communications; -import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; import org.openide.explorer.ExplorerManager; -import org.openide.nodes.AbstractNode; -import org.openide.nodes.Children; -import org.openide.util.Exceptions; import org.openide.util.NbBundle; import org.openide.windows.Mode; import org.openide.windows.RetainLocation; import org.openide.windows.TopComponent; import org.openide.windows.WindowManager; -import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.coreutils.ThreadConfined; -import org.sleuthkit.datamodel.Account; -import org.sleuthkit.datamodel.CommunicationsManager; -import org.sleuthkit.datamodel.TskCoreException; /** * Top component which displays the Communications Visualization Tool. @@ -66,45 +58,19 @@ public final class CVTTopComponent extends TopComponent implements ExplorerManag // //GEN-BEGIN:initComponents private void initComponents() { - jPanel2 = new javax.swing.JPanel(); - jButton1 = new javax.swing.JButton(); - jSplitPane1 = new javax.swing.JSplitPane(); - jTabbedPane1 = new javax.swing.JTabbedPane(); + HSplitPane = new javax.swing.JSplitPane(); + BrowseVisualizeTabPane = new javax.swing.JTabbedPane(); accountsBrowser = new org.sleuthkit.autopsy.communications.AccountsBrowser(); jPanel1 = new javax.swing.JPanel(); - jSplitPane2 = new javax.swing.JSplitPane(); + VSplitPane = new javax.swing.JSplitPane(); jTextField1 = new javax.swing.JTextField(); jTextField2 = new javax.swing.JTextField(); + filtersPane = new org.sleuthkit.autopsy.communications.FiltersPanel(); - jPanel2.setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(CVTTopComponent.class, "CVTTopComponent.jPanel2.border.title"))); // NOI18N + HSplitPane.setDividerLocation(600); - org.openide.awt.Mnemonics.setLocalizedText(jButton1, org.openide.util.NbBundle.getMessage(CVTTopComponent.class, "CVTTopComponent.jButton1.text")); // NOI18N - jButton1.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - jButton1ActionPerformed(evt); - } - }); - - javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2); - jPanel2.setLayout(jPanel2Layout); - jPanel2Layout.setHorizontalGroup( - jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel2Layout.createSequentialGroup() - .addContainerGap(141, Short.MAX_VALUE) - .addComponent(jButton1) - .addContainerGap()) - ); - jPanel2Layout.setVerticalGroup( - jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel2Layout.createSequentialGroup() - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(jButton1) - .addContainerGap()) - ); - - jSplitPane1.setDividerLocation(600); - - jTabbedPane1.addTab(org.openide.util.NbBundle.getMessage(CVTTopComponent.class, "CVTTopComponent.accountsBrowser.TabConstraints.tabTitle"), accountsBrowser); // NOI18N + BrowseVisualizeTabPane.setFont(new java.awt.Font("Tahoma", 0, 18)); // NOI18N + BrowseVisualizeTabPane.addTab(org.openide.util.NbBundle.getMessage(CVTTopComponent.class, "CVTTopComponent.accountsBrowser.TabConstraints.tabTitle"), accountsBrowser); // NOI18N jPanel1.setName(""); // NOI18N @@ -116,23 +82,25 @@ public final class CVTTopComponent extends TopComponent implements ExplorerManag ); jPanel1Layout.setVerticalGroup( jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGap(0, 716, Short.MAX_VALUE) + .addGap(0, 710, Short.MAX_VALUE) ); - jTabbedPane1.addTab(org.openide.util.NbBundle.getMessage(CVTTopComponent.class, "CVTTopComponent.TabConstraints.tabTitle"), jPanel1); // NOI18N + BrowseVisualizeTabPane.addTab(org.openide.util.NbBundle.getMessage(CVTTopComponent.class, "CVTTopComponent.TabConstraints.tabTitle"), jPanel1); // NOI18N - jSplitPane1.setLeftComponent(jTabbedPane1); + HSplitPane.setLeftComponent(BrowseVisualizeTabPane); - jSplitPane2.setDividerLocation(200); - jSplitPane2.setOrientation(javax.swing.JSplitPane.VERTICAL_SPLIT); + VSplitPane.setDividerLocation(200); + VSplitPane.setOrientation(javax.swing.JSplitPane.VERTICAL_SPLIT); jTextField1.setText(org.openide.util.NbBundle.getMessage(CVTTopComponent.class, "CVTTopComponent.jTextField1.text")); // NOI18N - jSplitPane2.setTopComponent(jTextField1); + VSplitPane.setTopComponent(jTextField1); jTextField2.setText(org.openide.util.NbBundle.getMessage(CVTTopComponent.class, "CVTTopComponent.jTextField2.text")); // NOI18N - jSplitPane2.setRightComponent(jTextField2); + VSplitPane.setRightComponent(jTextField2); - jSplitPane1.setRightComponent(jSplitPane2); + HSplitPane.setRightComponent(VSplitPane); + + filtersPane.setBorder(javax.swing.BorderFactory.createEtchedBorder()); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); @@ -140,9 +108,9 @@ public final class CVTTopComponent extends TopComponent implements ExplorerManag layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addContainerGap() - .addComponent(jPanel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGap(0, 0, 0) - .addComponent(jSplitPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 1350, Short.MAX_VALUE) + .addComponent(filtersPane, javax.swing.GroupLayout.PREFERRED_SIZE, 360, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(HSplitPane, javax.swing.GroupLayout.DEFAULT_SIZE, 1211, Short.MAX_VALUE) .addContainerGap()) ); layout.setVerticalGroup( @@ -150,39 +118,19 @@ public final class CVTTopComponent extends TopComponent implements ExplorerManag .addGroup(layout.createSequentialGroup() .addContainerGap() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(jSplitPane1) - .addComponent(jPanel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addComponent(filtersPane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(HSplitPane)) .addContainerGap()) ); }// //GEN-END:initComponents - private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed - /* - * When the apply button is pressed, query for accounts using the - * selected filters, and send the results to the AccountsBrowser via the - * ExplorerManager - */ - try { - List accounts = new ArrayList<>(); - final CommunicationsManager communicationsManager = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager(); - accounts.addAll(communicationsManager.getAccounts(Account.Type.EMAIL)); - accounts.addAll(communicationsManager.getAccounts(Account.Type.DEVICE)); - - em.setRootContext(new AbstractNode(Children.create(new AccountsNodeFactory(accounts), true))); - } catch (TskCoreException ex) { - Exceptions.printStackTrace(ex); - } - - }//GEN-LAST:event_jButton1ActionPerformed - // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JTabbedPane BrowseVisualizeTabPane; + private javax.swing.JSplitPane HSplitPane; + private javax.swing.JSplitPane VSplitPane; private org.sleuthkit.autopsy.communications.AccountsBrowser accountsBrowser; - private javax.swing.JButton jButton1; + private org.sleuthkit.autopsy.communications.FiltersPanel filtersPane; private javax.swing.JPanel jPanel1; - private javax.swing.JPanel jPanel2; - private javax.swing.JSplitPane jSplitPane1; - private javax.swing.JSplitPane jSplitPane2; - private javax.swing.JTabbedPane jTabbedPane1; private javax.swing.JTextField jTextField1; private javax.swing.JTextField jTextField2; // End of variables declaration//GEN-END:variables diff --git a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.form b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.form new file mode 100644 index 0000000000..f03f3d3928 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.form @@ -0,0 +1,151 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java new file mode 100644 index 0000000000..981f3648ac --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java @@ -0,0 +1,173 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2011-2017 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.sleuthkit.autopsy.communications; + +import java.util.ArrayList; +import java.util.List; +import org.openide.explorer.ExplorerManager; +import org.openide.nodes.AbstractNode; +import org.openide.nodes.Children; +import org.openide.util.Exceptions; +import org.sleuthkit.autopsy.casemodule.Case; +import org.sleuthkit.datamodel.Account; +import org.sleuthkit.datamodel.CommunicationsManager; +import org.sleuthkit.datamodel.TskCoreException; + +/** + * + */ + public class FiltersPanel extends javax.swing.JPanel { + + private static final long serialVersionUID = 1L; + + private ExplorerManager em; + + /** + * Creates new form NewJPanel + */ + public FiltersPanel() { + initComponents(); + + } + + @Override + public void addNotify() { + super.addNotify(); + em = ExplorerManager.find(this); + } + + /** + * This method is called from within the constructor to initialize the form. + * WARNING: Do NOT modify this code. The content of this method is always + * regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // //GEN-BEGIN:initComponents + private void initComponents() { + + jScrollPane1 = new javax.swing.JScrollPane(); + jList1 = new javax.swing.JList<>(); + jPanel1 = new javax.swing.JPanel(); + jPanel2 = new javax.swing.JPanel(); + applyFiltersButton = new javax.swing.JButton(); + jLabel1 = new javax.swing.JLabel(); + + jList1.setModel(new javax.swing.AbstractListModel() { + String[] strings = { "Item 1", "Item 2", "Item 3", "Item 4", "Item 5" }; + public int getSize() { return strings.length; } + public String getElementAt(int i) { return strings[i]; } + }); + jScrollPane1.setViewportView(jList1); + + jPanel1.setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(FiltersPanel.class, "FiltersPanel.jPanel1.border.title"))); // NOI18N + + javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1); + jPanel1.setLayout(jPanel1Layout); + jPanel1Layout.setHorizontalGroup( + jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 0, Short.MAX_VALUE) + ); + jPanel1Layout.setVerticalGroup( + jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 189, Short.MAX_VALUE) + ); + + jPanel2.setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(FiltersPanel.class, "FiltersPanel.jPanel2.border.title"))); // NOI18N + + javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2); + jPanel2.setLayout(jPanel2Layout); + jPanel2Layout.setHorizontalGroup( + jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 0, Short.MAX_VALUE) + ); + jPanel2Layout.setVerticalGroup( + jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 57, Short.MAX_VALUE) + ); + + applyFiltersButton.setText(org.openide.util.NbBundle.getMessage(FiltersPanel.class, "FiltersPanel.applyFiltersButton.text")); // NOI18N + applyFiltersButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + applyFiltersButtonActionPerformed(evt); + } + }); + + jLabel1.setFont(new java.awt.Font("Tahoma", 0, 18)); // NOI18N + jLabel1.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/communications/images/funnel.png"))); // NOI18N + jLabel1.setText(org.openide.util.NbBundle.getMessage(FiltersPanel.class, "FiltersPanel.jLabel1.text")); // NOI18N + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup() + .addComponent(jLabel1) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 231, Short.MAX_VALUE) + .addComponent(applyFiltersButton)) + .addComponent(jPanel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addGap(12, 12, 12)) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel1) + .addComponent(applyFiltersButton)) + .addGap(18, 18, 18) + .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jPanel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap()) + ); + }// //GEN-END:initComponents + + private void applyFiltersButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_applyFiltersButtonActionPerformed + /* + * When the apply button is pressed, query for accounts using the + * selected filters, and send the results to the AccountsBrowser via the + * ExplorerManager + */ + try { + List accounts = new ArrayList<>(); + final CommunicationsManager communicationsManager = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager(); + accounts.addAll(communicationsManager.getAccounts(Account.Type.EMAIL)); + accounts.addAll(communicationsManager.getAccounts(Account.Type.DEVICE)); + + em.setRootContext(new AbstractNode(Children.create(new AccountsNodeFactory(accounts), true))); + } catch (TskCoreException ex) { + Exceptions.printStackTrace(ex); + } + + }//GEN-LAST:event_applyFiltersButtonActionPerformed + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton applyFiltersButton; + private javax.swing.JLabel jLabel1; + private javax.swing.JList jList1; + private javax.swing.JPanel jPanel1; + private javax.swing.JPanel jPanel2; + private javax.swing.JScrollPane jScrollPane1; + // End of variables declaration//GEN-END:variables +} diff --git a/Core/src/org/sleuthkit/autopsy/communications/images/funnel.png b/Core/src/org/sleuthkit/autopsy/communications/images/funnel.png new file mode 100755 index 0000000000000000000000000000000000000000..1f69604528f29ca95e3b124de2849067797d839f GIT binary patch literal 591 zcmV-V0cATV*9a|wo z*|KEKlz}ct89+ipctWkZ*HXK5WI(V{i9JH)C$JF2gjD4ZFri8nLW#r@7As+}6Fbcp z=f3!rv}stl((#M$yZ78rM_Viw^gm+o!}GkS-EMcM)9Fx>BueiJA?$oUPlZBZYTNeM zahx&E1n)mvt=6Y&0?1Cg-9DR6r;;F!V;T;}6a*vE^$Z9sf+Ja0ftb+upC8@GfThuB z_|0bXEDS?94=D^I8Vn*b3{yJ0u1m#YkxoxvogjmoB_Q&99EX)kh5G$I90!PMLlu!} z=BZRFQMp_u$0yTJ=#koJ`7O3=%>^1_oubS(KvF!NHRku=|qs z=`TSl9VV&OYJM)4lO(#nB-`HJqP@LGuW|nw_`W&?ace4)q+YKdF9|eB;CT<rcA zygf#7$7q@4e0TT3OV=&a{{G{)c>e%gY}|uhuSb)~gqx}KKUR%!_brMddCybgKCKb_ zOPHL&B(vE}Vr>uZ5VhlTrC`U=XtZ9!s%V;~eqKrM`8?+D1t+bJZzBO4r!~&gCA(5( zY;0mGI>0-+g=n0HX;~IW7D)YmY7+w?^Im7n5!19Y{80h-SPwi~R-}D}jq37m;1`gn dzkxpj3;^AW#{FvID!%{#002ovPDHLkV1h0A2_^sl literal 0 HcmV?d00001 From f00b1799b2c3f0c69d3b4b44e654072308c6b9ca Mon Sep 17 00:00:00 2001 From: millmanorama Date: Tue, 24 Oct 2017 12:44:42 +0200 Subject: [PATCH 024/127] tweak UI, add some more Icons --- .../autopsy/communications/Bundle.properties | 4 +- .../communications/CVTTopComponent.form | 6 ++ .../communications/CVTTopComponent.java | 4 +- .../autopsy/communications/FiltersPanel.form | 74 +++++++++++++----- .../autopsy/communications/FiltersPanel.java | 50 ++++++++---- .../communications/images/emblem-web.png | Bin 0 -> 887 bytes .../autopsy/communications/images/table.png | Bin 0 -> 566 bytes 7 files changed, 99 insertions(+), 39 deletions(-) create mode 100644 Core/src/org/sleuthkit/autopsy/communications/images/emblem-web.png create mode 100644 Core/src/org/sleuthkit/autopsy/communications/images/table.png diff --git a/Core/src/org/sleuthkit/autopsy/communications/Bundle.properties b/Core/src/org/sleuthkit/autopsy/communications/Bundle.properties index fa0ec34afe..d4c5d85892 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/communications/Bundle.properties @@ -2,7 +2,7 @@ CVTTopComponent.jTextField1.text=place holder for messages ,thumbnail list, etc CVTTopComponent.jTextField2.text=place holder for message viewer CVTTopComponent.TabConstraints.tabTitle=Visualize CVTTopComponent.accountsBrowser.TabConstraints.tabTitle=Browse -FiltersPanel.jPanel2.border.title=Account Types -FiltersPanel.jPanel1.border.title=Devices FiltersPanel.jLabel1.text=Filters FiltersPanel.applyFiltersButton.text=Apply Filters +FiltersPanel.jLabel2.text=Devices: +FiltersPanel.jLabel3.text=Account Types: diff --git a/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.form b/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.form index fa9cad5ed6..59d3925ee0 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.form +++ b/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.form @@ -67,6 +67,9 @@ + + + @@ -81,6 +84,9 @@ + + + diff --git a/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java b/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java index 6c3d6af995..d18930cf2e 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java +++ b/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java @@ -70,7 +70,7 @@ public final class CVTTopComponent extends TopComponent implements ExplorerManag HSplitPane.setDividerLocation(600); BrowseVisualizeTabPane.setFont(new java.awt.Font("Tahoma", 0, 18)); // NOI18N - BrowseVisualizeTabPane.addTab(org.openide.util.NbBundle.getMessage(CVTTopComponent.class, "CVTTopComponent.accountsBrowser.TabConstraints.tabTitle"), accountsBrowser); // NOI18N + BrowseVisualizeTabPane.addTab(org.openide.util.NbBundle.getMessage(CVTTopComponent.class, "CVTTopComponent.accountsBrowser.TabConstraints.tabTitle"), new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/communications/images/table.png")), accountsBrowser); // NOI18N jPanel1.setName(""); // NOI18N @@ -85,7 +85,7 @@ public final class CVTTopComponent extends TopComponent implements ExplorerManag .addGap(0, 710, Short.MAX_VALUE) ); - BrowseVisualizeTabPane.addTab(org.openide.util.NbBundle.getMessage(CVTTopComponent.class, "CVTTopComponent.TabConstraints.tabTitle"), jPanel1); // NOI18N + BrowseVisualizeTabPane.addTab(org.openide.util.NbBundle.getMessage(CVTTopComponent.class, "CVTTopComponent.TabConstraints.tabTitle"), new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/communications/images/emblem-web.png")), jPanel1); // NOI18N HSplitPane.setLeftComponent(BrowseVisualizeTabPane); diff --git a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.form b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.form index f03f3d3928..4853953d46 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.form +++ b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.form @@ -44,17 +44,29 @@ - - - - - - - + + + + + + + + + + + + + + + + + + + + + - - @@ -66,9 +78,13 @@ - + + + + + @@ -79,10 +95,8 @@ - - - - + + @@ -90,12 +104,12 @@ - + - + @@ -103,10 +117,8 @@ - - - - + + @@ -119,7 +131,7 @@ - + @@ -147,5 +159,25 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java index 981f3648ac..8769cf6c1e 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java +++ b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java @@ -67,6 +67,8 @@ import org.sleuthkit.datamodel.TskCoreException; jPanel2 = new javax.swing.JPanel(); applyFiltersButton = new javax.swing.JButton(); jLabel1 = new javax.swing.JLabel(); + jLabel2 = new javax.swing.JLabel(); + jLabel3 = new javax.swing.JLabel(); jList1.setModel(new javax.swing.AbstractListModel() { String[] strings = { "Item 1", "Item 2", "Item 3", "Item 4", "Item 5" }; @@ -75,20 +77,20 @@ import org.sleuthkit.datamodel.TskCoreException; }); jScrollPane1.setViewportView(jList1); - jPanel1.setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(FiltersPanel.class, "FiltersPanel.jPanel1.border.title"))); // NOI18N + jPanel1.setBorder(javax.swing.BorderFactory.createEtchedBorder()); javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1); jPanel1.setLayout(jPanel1Layout); jPanel1Layout.setHorizontalGroup( jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGap(0, 0, Short.MAX_VALUE) + .addGap(0, 400, Short.MAX_VALUE) ); jPanel1Layout.setVerticalGroup( jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGap(0, 189, Short.MAX_VALUE) + .addGap(0, 56, Short.MAX_VALUE) ); - jPanel2.setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(FiltersPanel.class, "FiltersPanel.jPanel2.border.title"))); // NOI18N + jPanel2.setBorder(javax.swing.BorderFactory.createEtchedBorder()); javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2); jPanel2.setLayout(jPanel2Layout); @@ -98,7 +100,7 @@ import org.sleuthkit.datamodel.TskCoreException; ); jPanel2Layout.setVerticalGroup( jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGap(0, 57, Short.MAX_VALUE) + .addGap(0, 77, Short.MAX_VALUE) ); applyFiltersButton.setText(org.openide.util.NbBundle.getMessage(FiltersPanel.class, "FiltersPanel.applyFiltersButton.text")); // NOI18N @@ -112,20 +114,34 @@ import org.sleuthkit.datamodel.TskCoreException; jLabel1.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/communications/images/funnel.png"))); // NOI18N jLabel1.setText(org.openide.util.NbBundle.getMessage(FiltersPanel.class, "FiltersPanel.jLabel1.text")); // NOI18N + jLabel2.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/communications/images/image.png"))); // NOI18N + jLabel2.setText(org.openide.util.NbBundle.getMessage(FiltersPanel.class, "FiltersPanel.jLabel2.text")); // NOI18N + + jLabel3.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/images/accounts.png"))); // NOI18N + jLabel3.setText(org.openide.util.NbBundle.getMessage(FiltersPanel.class, "FiltersPanel.jLabel3.text")); // NOI18N + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addContainerGap() - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) - .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup() - .addComponent(jLabel1) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 231, Short.MAX_VALUE) - .addComponent(applyFiltersButton)) - .addComponent(jPanel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - .addGap(12, 12, 12)) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup() + .addComponent(jLabel1) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 235, Short.MAX_VALUE) + .addComponent(applyFiltersButton)) + .addGroup(layout.createSequentialGroup() + .addComponent(jLabel3) + .addGap(0, 0, Short.MAX_VALUE)) + .addComponent(jPanel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addGap(12, 12, 12)) + .addGroup(layout.createSequentialGroup() + .addComponent(jLabel2) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) @@ -134,9 +150,13 @@ import org.sleuthkit.datamodel.TskCoreException; .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(jLabel1) .addComponent(applyFiltersButton)) - .addGap(18, 18, 18) + .addGap(28, 28, 28) + .addComponent(jLabel2) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jLabel3) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(jPanel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addContainerGap()) ); @@ -165,6 +185,8 @@ import org.sleuthkit.datamodel.TskCoreException; // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JButton applyFiltersButton; private javax.swing.JLabel jLabel1; + private javax.swing.JLabel jLabel2; + private javax.swing.JLabel jLabel3; private javax.swing.JList jList1; private javax.swing.JPanel jPanel1; private javax.swing.JPanel jPanel2; diff --git a/Core/src/org/sleuthkit/autopsy/communications/images/emblem-web.png b/Core/src/org/sleuthkit/autopsy/communications/images/emblem-web.png new file mode 100644 index 0000000000000000000000000000000000000000..54805fc1adadef07d5ac71b1ad9a0138104fd0a1 GIT binary patch literal 887 zcmV--1Bm>IP)SxAwW;~w%YgiOn2(EM% zS6BC*bEI>v55Btd_R%2u$gz389ythIFibV8RTs;GsVwLxn*Ww5_|5hFYi>L~`S`UL zpKbuM>P<_c|K!S@-aiY!;`4;4y-GR2&|TJ;D$ z!^>*{y+kug1+G$(!WcXoO19zhnuCyvhXX;Q;_+nF!x+Q6O`FiOImmo|X=jWxL!9Ke zv)K$|G_D1!;f%8j1&t_R>4`;>+|Y^z%OTVP0T`+!!-5Bc6NQ#J?(ifha0)J+3BWQy z!PoaD{P?hTD=9vIr%or8T>t)% zTIe!L1uGSw(6`a1Aju^CNro+@L`a2@isK}wFow=J2jDn)JnM~T{MwqZb(D}xO)fPL zj!uwLVk;r$2eMqU(@7A8$IpkFt-j{cnKJTU1es98i9lCo`@# z7xA5fTMv4)hbclzq!idnnVoFZo7H`E$h8<|!`J%P6JEMm>}= zJJ!;hH{Q}B`2?*l2EM~{s}*kl5&!Rf0ZN|3dVPW6iJ+INUB{2E{SCc#&yw8i&G7&L N002ovPDHLkV1h5Zma+f< literal 0 HcmV?d00001 diff --git a/Core/src/org/sleuthkit/autopsy/communications/images/table.png b/Core/src/org/sleuthkit/autopsy/communications/images/table.png new file mode 100644 index 0000000000000000000000000000000000000000..abcd93689a08ec9bdbf0984927e8da06c043c7cd GIT binary patch literal 566 zcmV-60?GY}P)>q?GuNnCdgP^*Bj5V_b?dAq2Ppn9^MBB^YUM zad0N-T{Ujg*A6d~mYV4na=hT4Nz+_}SGTgW|Iir!%$ z;@OGkWI6+j0H}~K4RYR%!7y|zM`O@*K>rL{*&}x3lR**HrMXC1->#slU>X|w!U1xQ zqc Date: Tue, 24 Oct 2017 13:33:04 +0200 Subject: [PATCH 025/127] populate Account Type filter list --- .../communications/CVTTopComponent.form | 8 +-- .../communications/CVTTopComponent.java | 6 +- .../autopsy/communications/FiltersPanel.form | 44 +++++++++++---- .../autopsy/communications/FiltersPanel.java | 55 +++++++++++++++---- 4 files changed, 85 insertions(+), 28 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.form b/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.form index 59d3925ee0..4054851796 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.form +++ b/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.form @@ -17,10 +17,10 @@ - - - - + + + + diff --git a/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java b/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java index d18930cf2e..6f51e65718 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java +++ b/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java @@ -108,9 +108,9 @@ public final class CVTTopComponent extends TopComponent implements ExplorerManag layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addContainerGap() - .addComponent(filtersPane, javax.swing.GroupLayout.PREFERRED_SIZE, 360, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(HSplitPane, javax.swing.GroupLayout.DEFAULT_SIZE, 1211, Short.MAX_VALUE) + .addComponent(filtersPane, javax.swing.GroupLayout.PREFERRED_SIZE, 276, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(HSplitPane, javax.swing.GroupLayout.DEFAULT_SIZE, 1290, Short.MAX_VALUE) .addContainerGap()) ); layout.setVerticalGroup( diff --git a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.form b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.form index 4853953d46..70b62fb19c 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.form +++ b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.form @@ -51,7 +51,7 @@ - + @@ -73,20 +73,20 @@ - + - + - + - + - + - + @@ -104,7 +104,7 @@ - + @@ -126,15 +126,39 @@ - + + + + + - + + + + + + + + + + + + + + + + + + + + + diff --git a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java index 8769cf6c1e..28a21a18de 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java +++ b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java @@ -18,8 +18,13 @@ */ package org.sleuthkit.autopsy.communications; +import java.awt.Component; import java.util.ArrayList; import java.util.List; +import javax.swing.DefaultListModel; +import javax.swing.JCheckBox; +import javax.swing.JList; +import javax.swing.ListCellRenderer; import org.openide.explorer.ExplorerManager; import org.openide.nodes.AbstractNode; import org.openide.nodes.Children; @@ -32,17 +37,32 @@ import org.sleuthkit.datamodel.TskCoreException; /** * */ - public class FiltersPanel extends javax.swing.JPanel { +public class FiltersPanel extends javax.swing.JPanel { private static final long serialVersionUID = 1L; private ExplorerManager em; + private final DefaultListModel accountTypesModel; - /** - * Creates new form NewJPanel - */ public FiltersPanel() { initComponents(); + accountTypesModel = new DefaultListModel<>(); + try { + final CommunicationsManager communicationsManager = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager(); + List accountTypesInUse = communicationsManager.getAccountTypesInUse(); + accountTypesInUse.forEach(accountTypesModel::addElement); + } catch (TskCoreException ex) { + Exceptions.printStackTrace(ex); + } + accountTypesList.setCellRenderer(new ListCellRenderer() { + @Override + public Component getListCellRendererComponent(JList list, Account.Type value, int index, boolean isSelected, boolean cellHasFocus) { + JCheckBox jCheckBox = new JCheckBox(value.getDisplayName()); + return jCheckBox; + } + }); + + accountTypesList.setModel(accountTypesModel); } @@ -65,6 +85,8 @@ import org.sleuthkit.datamodel.TskCoreException; jList1 = new javax.swing.JList<>(); jPanel1 = new javax.swing.JPanel(); jPanel2 = new javax.swing.JPanel(); + jScrollPane2 = new javax.swing.JScrollPane(); + accountTypesList = new javax.swing.JList<>(); applyFiltersButton = new javax.swing.JButton(); jLabel1 = new javax.swing.JLabel(); jLabel2 = new javax.swing.JLabel(); @@ -83,7 +105,7 @@ import org.sleuthkit.datamodel.TskCoreException; jPanel1.setLayout(jPanel1Layout); jPanel1Layout.setHorizontalGroup( jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGap(0, 400, Short.MAX_VALUE) + .addGap(0, 0, Short.MAX_VALUE) ); jPanel1Layout.setVerticalGroup( jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) @@ -92,15 +114,23 @@ import org.sleuthkit.datamodel.TskCoreException; jPanel2.setBorder(javax.swing.BorderFactory.createEtchedBorder()); + jScrollPane2.setViewportView(accountTypesList); + javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2); jPanel2.setLayout(jPanel2Layout); jPanel2Layout.setHorizontalGroup( jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGap(0, 0, Short.MAX_VALUE) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel2Layout.createSequentialGroup() + .addGap(0, 0, 0) + .addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE) + .addGap(0, 0, 0)) ); jPanel2Layout.setVerticalGroup( jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGap(0, 77, Short.MAX_VALUE) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel2Layout.createSequentialGroup() + .addGap(0, 0, 0) + .addComponent(jScrollPane2) + .addGap(0, 0, 0)) ); applyFiltersButton.setText(org.openide.util.NbBundle.getMessage(FiltersPanel.class, "FiltersPanel.applyFiltersButton.text")); // NOI18N @@ -132,7 +162,7 @@ import org.sleuthkit.datamodel.TskCoreException; .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup() .addComponent(jLabel1) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 235, Short.MAX_VALUE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(applyFiltersButton)) .addGroup(layout.createSequentialGroup() .addComponent(jLabel3) @@ -150,19 +180,20 @@ import org.sleuthkit.datamodel.TskCoreException; .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(jLabel1) .addComponent(applyFiltersButton)) - .addGap(28, 28, 28) + .addGap(18, 18, Short.MAX_VALUE) .addComponent(jLabel2) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(jLabel3) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jPanel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addContainerGap()) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); }// //GEN-END:initComponents private void applyFiltersButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_applyFiltersButtonActionPerformed + /* * When the apply button is pressed, query for accounts using the * selected filters, and send the results to the AccountsBrowser via the @@ -183,6 +214,7 @@ import org.sleuthkit.datamodel.TskCoreException; // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JList accountTypesList; private javax.swing.JButton applyFiltersButton; private javax.swing.JLabel jLabel1; private javax.swing.JLabel jLabel2; @@ -191,5 +223,6 @@ import org.sleuthkit.datamodel.TskCoreException; private javax.swing.JPanel jPanel1; private javax.swing.JPanel jPanel2; private javax.swing.JScrollPane jScrollPane1; + private javax.swing.JScrollPane jScrollPane2; // End of variables declaration//GEN-END:variables } From 18ce9c98171f534d430acf441337cb0390586e30 Mon Sep 17 00:00:00 2001 From: millmanorama Date: Tue, 24 Oct 2017 15:30:33 +0200 Subject: [PATCH 026/127] fix FiltersPanel accountType selection, and general polish --- .../autopsy/communications/AccountNode.java | 38 +-- .../autopsy/communications/AccountUtils.java | 48 +++ .../autopsy/communications/Bundle.properties | 10 +- .../communications/CVTTopComponent.form | 4 +- .../communications/CVTTopComponent.java | 4 +- .../autopsy/communications/FiltersPanel.form | 319 +++++++++++------- .../autopsy/communications/FiltersPanel.java | 296 ++++++++++------ .../communications/images/control-double.png | Bin 0 -> 499 bytes 8 files changed, 465 insertions(+), 254 deletions(-) create mode 100644 Core/src/org/sleuthkit/autopsy/communications/AccountUtils.java create mode 100644 Core/src/org/sleuthkit/autopsy/communications/images/control-double.png diff --git a/Core/src/org/sleuthkit/autopsy/communications/AccountNode.java b/Core/src/org/sleuthkit/autopsy/communications/AccountNode.java index f2571b5eb7..2d85bb92d1 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/AccountNode.java +++ b/Core/src/org/sleuthkit/autopsy/communications/AccountNode.java @@ -37,41 +37,7 @@ class AccountNode extends AbstractNode { super(Children.LEAF, Lookups.fixed(account)); this.account = account; setName(account.getAccountUniqueID()); - setIconBaseWithExtension("org/sleuthkit/autopsy/communications/images/" + getIconFileName(account.getAccountType())); - } - - /** - * The file name of the icon for the given Account Type. Will not include - * the path but will include the extension. - * - * @return The file name of the icon for the given Account Type. - */ - final String getIconFileName(Account.Type type) { - if (type == Account.Type.CREDIT_CARD) { - return "credit-card.png"; - } else if (type == Account.Type.DEVICE) { - return "image.png"; - } else if (type == Account.Type.EMAIL) { - return "email.png"; - } else if (type == Account.Type.FACEBOOK) { - return "facebook.png"; - } else if (type == Account.Type.INSTAGRAM) { - return "instagram.png"; - } else if (type == Account.Type.MESSAGING_APP) { - return "messaging.png"; - } else if (type == Account.Type.PHONE) { - return "phone.png"; - } else if (type == Account.Type.TWITTER) { - return "twitter.png"; - } else if (type == Account.Type.WEBSITE) { - return "web-file.png"; - } else if (type == Account.Type.WHATSAPP) { - return "WhatsApp.png"; - } else { - //there could be a default icon instead... - throw new IllegalArgumentException("Unknown Account.Type: " + type.getTypeName()); - } - + setIconBaseWithExtension("org/sleuthkit/autopsy/communications/images/" + AccountUtils.getIconFileName(account.getAccountType())); } @Override @@ -79,7 +45,7 @@ class AccountNode extends AbstractNode { "AccountNode.device=Device", "AccountNode.accountName=Account", "AccountNode.accountType=Type", - "AccountNode.messageCount=Message Count"}) + "AccountNode.messageCount=Msg Count"}) protected Sheet createSheet() { Sheet s = super.createSheet(); Sheet.Set properties = s.get(Sheet.PROPERTIES); diff --git a/Core/src/org/sleuthkit/autopsy/communications/AccountUtils.java b/Core/src/org/sleuthkit/autopsy/communications/AccountUtils.java new file mode 100644 index 0000000000..eca0595dd4 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/communications/AccountUtils.java @@ -0,0 +1,48 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package org.sleuthkit.autopsy.communications; + +import org.sleuthkit.datamodel.Account; + +/** + * + */ +public class AccountUtils { + + /** + * The file name of the icon for the given Account Type. Will not include + * the path but will include the extension. + * + * @return The file name of the icon for the given Account Type. + */ + static final String getIconFileName(Account.Type type) { + if (type == Account.Type.CREDIT_CARD) { + return "credit-card.png"; + } else if (type == Account.Type.DEVICE) { + return "image.png"; + } else if (type == Account.Type.EMAIL) { + return "email.png"; + } else if (type == Account.Type.FACEBOOK) { + return "facebook.png"; + } else if (type == Account.Type.INSTAGRAM) { + return "instagram.png"; + } else if (type == Account.Type.MESSAGING_APP) { + return "messaging.png"; + } else if (type == Account.Type.PHONE) { + return "phone.png"; + } else if (type == Account.Type.TWITTER) { + return "twitter.png"; + } else if (type == Account.Type.WEBSITE) { + return "web-file.png"; + } else if (type == Account.Type.WHATSAPP) { + return "WhatsApp.png"; + } else { + //there could be a default icon instead... + throw new IllegalArgumentException("Unknown Account.Type: " + type.getTypeName()); + } + } + +} diff --git a/Core/src/org/sleuthkit/autopsy/communications/Bundle.properties b/Core/src/org/sleuthkit/autopsy/communications/Bundle.properties index d4c5d85892..99621e3e12 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/communications/Bundle.properties @@ -2,7 +2,11 @@ CVTTopComponent.jTextField1.text=place holder for messages ,thumbnail list, etc CVTTopComponent.jTextField2.text=place holder for message viewer CVTTopComponent.TabConstraints.tabTitle=Visualize CVTTopComponent.accountsBrowser.TabConstraints.tabTitle=Browse -FiltersPanel.jLabel1.text=Filters FiltersPanel.applyFiltersButton.text=Apply Filters -FiltersPanel.jLabel2.text=Devices: -FiltersPanel.jLabel3.text=Account Types: +FiltersPanel.devicesLabel.text=Devices: +FiltersPanel.accountTypesLabel.text=Account Types: +FiltersPanel.filtersTitleLabel.text=Filters +FiltersPanel.unCheckAllAccountTypesButton.text=Uncheck All +FiltersPanel.checkAllAccountTypesButton.text=Check All +FiltersPanel.unCheckAllDevicesButton.text=Uncheck All +FiltersPanel.checkAllDevicesButton.text=Check All diff --git a/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.form b/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.form index 4054851796..e8b2877724 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.form +++ b/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.form @@ -18,9 +18,9 @@ - + - + diff --git a/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java b/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java index 6f51e65718..1d64eebc4b 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java +++ b/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java @@ -108,9 +108,9 @@ public final class CVTTopComponent extends TopComponent implements ExplorerManag layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addContainerGap() - .addComponent(filtersPane, javax.swing.GroupLayout.PREFERRED_SIZE, 276, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(filtersPane, javax.swing.GroupLayout.PREFERRED_SIZE, 244, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(HSplitPane, javax.swing.GroupLayout.DEFAULT_SIZE, 1290, Short.MAX_VALUE) + .addComponent(HSplitPane, javax.swing.GroupLayout.DEFAULT_SIZE, 1322, Short.MAX_VALUE) .addContainerGap()) ); layout.setVerticalGroup( diff --git a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.form b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.form index 70b62fb19c..8172098a59 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.form +++ b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.form @@ -47,25 +47,16 @@ - - - - - - - - - - - - - + + + - - - + + + + @@ -75,102 +66,34 @@ - + - - - - - - - - - + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + - + @@ -179,29 +102,193 @@ - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java index 28a21a18de..069e0d84ee 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java +++ b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java @@ -18,18 +18,18 @@ */ package org.sleuthkit.autopsy.communications; -import java.awt.Component; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; -import javax.swing.DefaultListModel; +import java.util.Map; +import java.util.Map.Entry; import javax.swing.JCheckBox; -import javax.swing.JList; -import javax.swing.ListCellRenderer; import org.openide.explorer.ExplorerManager; import org.openide.nodes.AbstractNode; import org.openide.nodes.Children; import org.openide.util.Exceptions; import org.sleuthkit.autopsy.casemodule.Case; +import org.sleuthkit.autopsy.coreutils.ThreadConfined; import org.sleuthkit.datamodel.Account; import org.sleuthkit.datamodel.CommunicationsManager; import org.sleuthkit.datamodel.TskCoreException; @@ -42,28 +42,35 @@ public class FiltersPanel extends javax.swing.JPanel { private static final long serialVersionUID = 1L; private ExplorerManager em; - private final DefaultListModel accountTypesModel; + + @ThreadConfined(type = ThreadConfined.ThreadType.AWT) + private final Map accountTypeMap = new HashMap<>(); public FiltersPanel() { initComponents(); - accountTypesModel = new DefaultListModel<>(); - try { - final CommunicationsManager communicationsManager = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager(); - List accountTypesInUse = communicationsManager.getAccountTypesInUse(); - accountTypesInUse.forEach(accountTypesModel::addElement); - } catch (TskCoreException ex) { - Exceptions.printStackTrace(ex); - } - accountTypesList.setCellRenderer(new ListCellRenderer() { - @Override - public Component getListCellRendererComponent(JList list, Account.Type value, int index, boolean isSelected, boolean cellHasFocus) { - JCheckBox jCheckBox = new JCheckBox(value.getDisplayName()); - return jCheckBox; - } + /* + * something like this commented code could be used to show only the + * account types that are found: + * + * final CommunicationsManager communicationsManager = + * Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager(); + * List accountTypesInUse = + * communicationsManager.getAccountTypesInUse(); + * accountTypesInUSe.forEach(....) + */ + Account.Type.PREDEFINED_ACCOUNT_TYPES.forEach(type -> { + final JCheckBox jCheckBox = new JCheckBox( + "
" + type.getDisplayName() + "
", + true + ); + accountTypePane.add(jCheckBox); + accountTypeMap.put(type, jCheckBox); }); - accountTypesList.setModel(accountTypesModel); - + invalidate(); } @Override @@ -83,14 +90,18 @@ public class FiltersPanel extends javax.swing.JPanel { jScrollPane1 = new javax.swing.JScrollPane(); jList1 = new javax.swing.JList<>(); - jPanel1 = new javax.swing.JPanel(); - jPanel2 = new javax.swing.JPanel(); - jScrollPane2 = new javax.swing.JScrollPane(); - accountTypesList = new javax.swing.JList<>(); applyFiltersButton = new javax.swing.JButton(); - jLabel1 = new javax.swing.JLabel(); - jLabel2 = new javax.swing.JLabel(); - jLabel3 = new javax.swing.JLabel(); + filtersTitleLabel = new javax.swing.JLabel(); + jPanel2 = new javax.swing.JPanel(); + accountTypePane = new javax.swing.JPanel(); + unCheckAllAccountTypesButton = new javax.swing.JButton(); + accountTypesLabel = new javax.swing.JLabel(); + checkAllAccountTypesButton = new javax.swing.JButton(); + jPanel3 = new javax.swing.JPanel(); + unCheckAllDevicesButton = new javax.swing.JButton(); + devicesLabel = new javax.swing.JLabel(); + checkAllDevicesButton = new javax.swing.JButton(); + jPanel1 = new javax.swing.JPanel(); jList1.setModel(new javax.swing.AbstractListModel() { String[] strings = { "Item 1", "Item 2", "Item 3", "Item 4", "Item 5" }; @@ -99,6 +110,89 @@ public class FiltersPanel extends javax.swing.JPanel { }); jScrollPane1.setViewportView(jList1); + applyFiltersButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/communications/images/control-double.png"))); // NOI18N + applyFiltersButton.setText(org.openide.util.NbBundle.getMessage(FiltersPanel.class, "FiltersPanel.applyFiltersButton.text")); // NOI18N + applyFiltersButton.setHorizontalTextPosition(javax.swing.SwingConstants.LEADING); + applyFiltersButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + applyFiltersButtonActionPerformed(evt); + } + }); + + filtersTitleLabel.setFont(new java.awt.Font("Tahoma", 0, 18)); // NOI18N + filtersTitleLabel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/communications/images/funnel.png"))); // NOI18N + filtersTitleLabel.setText(org.openide.util.NbBundle.getMessage(FiltersPanel.class, "FiltersPanel.filtersTitleLabel.text")); // NOI18N + + accountTypePane.setBorder(javax.swing.BorderFactory.createEtchedBorder()); + accountTypePane.setLayout(new javax.swing.BoxLayout(accountTypePane, javax.swing.BoxLayout.Y_AXIS)); + + unCheckAllAccountTypesButton.setText(org.openide.util.NbBundle.getMessage(FiltersPanel.class, "FiltersPanel.unCheckAllAccountTypesButton.text")); // NOI18N + unCheckAllAccountTypesButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + unCheckAllAccountTypesButtonActionPerformed(evt); + } + }); + + accountTypesLabel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/images/accounts.png"))); // NOI18N + accountTypesLabel.setText(org.openide.util.NbBundle.getMessage(FiltersPanel.class, "FiltersPanel.accountTypesLabel.text")); // NOI18N + + checkAllAccountTypesButton.setText(org.openide.util.NbBundle.getMessage(FiltersPanel.class, "FiltersPanel.checkAllAccountTypesButton.text")); // NOI18N + checkAllAccountTypesButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + checkAllAccountTypesButtonActionPerformed(evt); + } + }); + + javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2); + jPanel2.setLayout(jPanel2Layout); + jPanel2Layout.setHorizontalGroup( + jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel2Layout.createSequentialGroup() + .addGap(0, 0, 0) + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel2Layout.createSequentialGroup() + .addGap(0, 0, Short.MAX_VALUE) + .addComponent(unCheckAllAccountTypesButton) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(checkAllAccountTypesButton)) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel2Layout.createSequentialGroup() + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(accountTypePane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGroup(jPanel2Layout.createSequentialGroup() + .addComponent(accountTypesLabel) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 144, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addContainerGap()))) + ); + jPanel2Layout.setVerticalGroup( + jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel2Layout.createSequentialGroup() + .addComponent(accountTypesLabel) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(accountTypePane, javax.swing.GroupLayout.DEFAULT_SIZE, 118, Short.MAX_VALUE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(checkAllAccountTypesButton) + .addComponent(unCheckAllAccountTypesButton)) + .addContainerGap()) + ); + + unCheckAllDevicesButton.setText(org.openide.util.NbBundle.getMessage(FiltersPanel.class, "FiltersPanel.unCheckAllDevicesButton.text")); // NOI18N + unCheckAllDevicesButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + unCheckAllDevicesButtonActionPerformed(evt); + } + }); + + devicesLabel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/communications/images/image.png"))); // NOI18N + devicesLabel.setText(org.openide.util.NbBundle.getMessage(FiltersPanel.class, "FiltersPanel.devicesLabel.text")); // NOI18N + + checkAllDevicesButton.setText(org.openide.util.NbBundle.getMessage(FiltersPanel.class, "FiltersPanel.checkAllDevicesButton.text")); // NOI18N + checkAllDevicesButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + checkAllDevicesButtonActionPerformed(evt); + } + }); + jPanel1.setBorder(javax.swing.BorderFactory.createEtchedBorder()); javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1); @@ -109,47 +203,40 @@ public class FiltersPanel extends javax.swing.JPanel { ); jPanel1Layout.setVerticalGroup( jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGap(0, 56, Short.MAX_VALUE) + .addGap(0, 48, Short.MAX_VALUE) ); - jPanel2.setBorder(javax.swing.BorderFactory.createEtchedBorder()); - - jScrollPane2.setViewportView(accountTypesList); - - javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2); - jPanel2.setLayout(jPanel2Layout); - jPanel2Layout.setHorizontalGroup( - jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel2Layout.createSequentialGroup() - .addGap(0, 0, 0) - .addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE) - .addGap(0, 0, 0)) + javax.swing.GroupLayout jPanel3Layout = new javax.swing.GroupLayout(jPanel3); + jPanel3.setLayout(jPanel3Layout); + jPanel3Layout.setHorizontalGroup( + jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel3Layout.createSequentialGroup() + .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addContainerGap()) + .addGroup(jPanel3Layout.createSequentialGroup() + .addComponent(devicesLabel) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel3Layout.createSequentialGroup() + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(unCheckAllDevicesButton) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(checkAllDevicesButton) + .addContainerGap()) ); - jPanel2Layout.setVerticalGroup( - jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel2Layout.createSequentialGroup() - .addGap(0, 0, 0) - .addComponent(jScrollPane2) - .addGap(0, 0, 0)) + jPanel3Layout.setVerticalGroup( + jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel3Layout.createSequentialGroup() + .addContainerGap() + .addComponent(devicesLabel) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(checkAllDevicesButton) + .addComponent(unCheckAllDevicesButton)) + .addContainerGap()) ); - applyFiltersButton.setText(org.openide.util.NbBundle.getMessage(FiltersPanel.class, "FiltersPanel.applyFiltersButton.text")); // NOI18N - applyFiltersButton.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - applyFiltersButtonActionPerformed(evt); - } - }); - - jLabel1.setFont(new java.awt.Font("Tahoma", 0, 18)); // NOI18N - jLabel1.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/communications/images/funnel.png"))); // NOI18N - jLabel1.setText(org.openide.util.NbBundle.getMessage(FiltersPanel.class, "FiltersPanel.jLabel1.text")); // NOI18N - - jLabel2.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/communications/images/image.png"))); // NOI18N - jLabel2.setText(org.openide.util.NbBundle.getMessage(FiltersPanel.class, "FiltersPanel.jLabel2.text")); // NOI18N - - jLabel3.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/images/accounts.png"))); // NOI18N - jLabel3.setText(org.openide.util.NbBundle.getMessage(FiltersPanel.class, "FiltersPanel.jLabel3.text")); // NOI18N - javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); layout.setHorizontalGroup( @@ -158,37 +245,27 @@ public class FiltersPanel extends javax.swing.JPanel { .addContainerGap() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) - .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup() - .addComponent(jLabel1) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(applyFiltersButton)) - .addGroup(layout.createSequentialGroup() - .addComponent(jLabel3) - .addGap(0, 0, Short.MAX_VALUE)) - .addComponent(jPanel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addComponent(filtersTitleLabel) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(applyFiltersButton) .addGap(12, 12, 12)) - .addGroup(layout.createSequentialGroup() - .addComponent(jLabel2) - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addComponent(jPanel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addContainerGap()) + .addComponent(jPanel3, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addContainerGap() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(jLabel1) + .addComponent(filtersTitleLabel) .addComponent(applyFiltersButton)) - .addGap(18, 18, Short.MAX_VALUE) - .addComponent(jLabel2) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(18, 18, 18) + .addComponent(jPanel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(jLabel3) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(jPanel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addComponent(jPanel3, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addContainerGap()) ); }// //GEN-END:initComponents @@ -197,32 +274,61 @@ public class FiltersPanel extends javax.swing.JPanel { /* * When the apply button is pressed, query for accounts using the * selected filters, and send the results to the AccountsBrowser via the - * ExplorerManager + * ExplorerManager. + * + * This will need to be adapted to any changes in the Comunications + * Manager API */ try { - List accounts = new ArrayList<>(); final CommunicationsManager communicationsManager = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager(); - accounts.addAll(communicationsManager.getAccounts(Account.Type.EMAIL)); - accounts.addAll(communicationsManager.getAccounts(Account.Type.DEVICE)); + List accounts = new ArrayList<>(); + for (Entry entry : accountTypeMap.entrySet()) { + if (entry.getValue().isSelected()) { + accounts.addAll(communicationsManager.getAccounts(entry.getKey())); + } + } em.setRootContext(new AbstractNode(Children.create(new AccountsNodeFactory(accounts), true))); } catch (TskCoreException ex) { Exceptions.printStackTrace(ex); } }//GEN-LAST:event_applyFiltersButtonActionPerformed + @ThreadConfined(type = ThreadConfined.ThreadType.AWT) + private void setAllTypesSelected(boolean selected) { + accountTypeMap.values().forEach(box -> box.setSelected(selected)); + } + private void unCheckAllAccountTypesButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_unCheckAllAccountTypesButtonActionPerformed + setAllTypesSelected(false); + }//GEN-LAST:event_unCheckAllAccountTypesButtonActionPerformed + + private void checkAllAccountTypesButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_checkAllAccountTypesButtonActionPerformed + setAllTypesSelected(true); + }//GEN-LAST:event_checkAllAccountTypesButtonActionPerformed + + private void unCheckAllDevicesButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_unCheckAllDevicesButtonActionPerformed + // TODO add your handling code here: + }//GEN-LAST:event_unCheckAllDevicesButtonActionPerformed + + private void checkAllDevicesButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_checkAllDevicesButtonActionPerformed + // TODO add your handling code here: + }//GEN-LAST:event_checkAllDevicesButtonActionPerformed // Variables declaration - do not modify//GEN-BEGIN:variables - private javax.swing.JList accountTypesList; + private javax.swing.JPanel accountTypePane; + private javax.swing.JLabel accountTypesLabel; private javax.swing.JButton applyFiltersButton; - private javax.swing.JLabel jLabel1; - private javax.swing.JLabel jLabel2; - private javax.swing.JLabel jLabel3; + private javax.swing.JButton checkAllAccountTypesButton; + private javax.swing.JButton checkAllDevicesButton; + private javax.swing.JLabel devicesLabel; + private javax.swing.JLabel filtersTitleLabel; private javax.swing.JList jList1; private javax.swing.JPanel jPanel1; private javax.swing.JPanel jPanel2; + private javax.swing.JPanel jPanel3; private javax.swing.JScrollPane jScrollPane1; - private javax.swing.JScrollPane jScrollPane2; + private javax.swing.JButton unCheckAllAccountTypesButton; + private javax.swing.JButton unCheckAllDevicesButton; // End of variables declaration//GEN-END:variables } diff --git a/Core/src/org/sleuthkit/autopsy/communications/images/control-double.png b/Core/src/org/sleuthkit/autopsy/communications/images/control-double.png new file mode 100644 index 0000000000000000000000000000000000000000..4197fb468badbb0a39a578739a99ab817d3bb9e8 GIT binary patch literal 499 zcmVruu_RM-+6NM~L!H#5R{*9_it8`_tF@o7Ke>a|9r#Tb7Ty?FNx zL7ogCnY!n^YX+IBgkWeCr-vzxMv2h|@@YIugBTd|KbYB1f002ovPDHLkV1l?#;fnwO literal 0 HcmV?d00001 From e4c544e09dcdd24762427fa75408b404e6db1765 Mon Sep 17 00:00:00 2001 From: millmanorama Date: Tue, 24 Oct 2017 16:32:16 +0200 Subject: [PATCH 027/127] try to set the widths of the columns automatically --- .../communications/AccountsBrowser.java | 46 ++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/communications/AccountsBrowser.java b/Core/src/org/sleuthkit/autopsy/communications/AccountsBrowser.java index 2a0224a511..82864e7eb1 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/AccountsBrowser.java +++ b/Core/src/org/sleuthkit/autopsy/communications/AccountsBrowser.java @@ -18,10 +18,13 @@ */ package org.sleuthkit.autopsy.communications; +import java.awt.Component; import javax.swing.JPanel; import javax.swing.ListSelectionModel; +import javax.swing.table.TableCellRenderer; import org.netbeans.swing.outline.DefaultOutlineModel; import org.netbeans.swing.outline.Outline; +import org.openide.explorer.ExplorerManager; /** * A panel that goes in the Browse tab of the CVT. Has a OutlineView that shows @@ -31,12 +34,15 @@ public class AccountsBrowser extends JPanel { private static final long serialVersionUID = 1L; + private final Outline outline; + private ExplorerManager em; + /** * Creates new form AccountsBrowser */ public AccountsBrowser() { initComponents(); - final Outline outline = outlineView.getOutline(); + outline = outlineView.getOutline(); outlineView.setPropertyColumns( "device", Bundle.AccountNode_device(), "type", Bundle.AccountNode_accountType(), @@ -47,6 +53,44 @@ public class AccountsBrowser extends JPanel { ((DefaultOutlineModel) outline.getOutlineModel()).setNodesColumnLabel(Bundle.AccountNode_accountName()); outline.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); outline.setColumnSorted(3, false, 1); //it would be could if the column index wasn't hardcoded + +// setColumnWidths(); + } + + @Override + public void addNotify() { + super.addNotify(); + em = ExplorerManager.find(this); + em.addPropertyChangeListener(evt -> { + if (ExplorerManager.PROP_ROOT_CONTEXT.equals(evt.getPropertyName())) { + setColumnWidths(); + } else if (ExplorerManager.PROP_EXPLORED_CONTEXT.equals(evt.getPropertyName())) { + setColumnWidths(); + } + }); + } + + private void setColumnWidths() { + int margin = 4; + int padding = 8; + + for (int column = 0; column < outline.getModel().getColumnCount(); column++) { + int columnWidthLimit = 500; + int columnWidth = 0; + final int rows = Math.min(100, outline.getRowCount()); + + // find the maximum width needed to fit the values for the first 100 rows, at most + for (int row = 0; row < rows; row++) { + TableCellRenderer renderer = outline.getCellRenderer(row, column); + Component comp = outline.prepareRenderer(renderer, row, column); + columnWidth = Math.max(comp.getPreferredSize().width, columnWidth); + } + + columnWidth += 2 * margin + padding; // add margin and regular padding + columnWidth = Math.min(columnWidth, columnWidthLimit); + + outline.getColumnModel().getColumn(column).setPreferredWidth(columnWidth); + } } /** From 94366cc8eab74954971c0f4e697934e4b73ec020 Mon Sep 17 00:00:00 2001 From: Raman Date: Tue, 24 Oct 2017 10:48:11 -0400 Subject: [PATCH 028/127] 857: Reconcile Unique Accounts with Credit Card Review --- .../autopsy/datamodel/accounts/Accounts.java | 9 +- .../autopsy/keywordsearch/RegexQuery.java | 204 ++++++++++-------- .../keywordsearch/TermsComponentQuery.java | 204 ++++++++++-------- 3 files changed, 245 insertions(+), 172 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/accounts/Accounts.java b/Core/src/org/sleuthkit/autopsy/datamodel/accounts/Accounts.java index b27ffd9d38..e9ab484b3d 100755 --- a/Core/src/org/sleuthkit/autopsy/datamodel/accounts/Accounts.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/accounts/Accounts.java @@ -1429,7 +1429,14 @@ final public class Accounts implements AutopsyVisitableItem { artifacts.forEach(artifact -> { try { AccountInstance accountInstance = skCase.getCommunicationsManager().getAccountInstance(artifact); - accountInstance.setReviewStatus(newStatus); + + if (BlackboardArtifact.ReviewStatus.APPROVED == newStatus) { + accountInstance.approveAccount(); + } + else { + accountInstance.rejectAccount(); + } + } catch (TskCoreException ex) { LOGGER.log(Level.SEVERE, "Error changing artifact review status.", ex); //NON-NLS } diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/RegexQuery.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/RegexQuery.java index a456e6c029..1d4f32f18b 100755 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/RegexQuery.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/RegexQuery.java @@ -412,97 +412,30 @@ final class RegexQuery implements KeywordSearchQuery { return null; } + /* + * Credit Card number hits are handled differently + */ + if (originalKeyword.getArtifactAttributeType() == ATTRIBUTE_TYPE.TSK_CARD_NUMBER) { + createCCNAccount(content, foundKeyword, hit, snippet, listName); + return null; + } /* * Create either a "plain vanilla" keyword hit artifact with keyword and - * regex attributes, or a credit card account artifact with attributes - * parsed from from the snippet for the hit and looked up based on the - * parsed bank identifcation number. + * regex attributes */ BlackboardArtifact newArtifact; Collection attributes = new ArrayList<>(); - if (originalKeyword.getArtifactAttributeType() != ATTRIBUTE_TYPE.TSK_CARD_NUMBER) { - attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_KEYWORD, MODULE_NAME, foundKeyword.getSearchTerm())); - attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_KEYWORD_REGEXP, MODULE_NAME, getQueryString())); - try { - newArtifact = content.newArtifact(ARTIFACT_TYPE.TSK_KEYWORD_HIT); - } catch (TskCoreException ex) { - LOGGER.log(Level.SEVERE, "Error adding artifact for keyword hit to blackboard", ex); //NON-NLS - return null; - } - } else { - /* - * Parse the credit card account attributes from the snippet for the - * hit. - */ - Map parsedTrackAttributeMap = new HashMap<>(); - Matcher matcher = TermsComponentQuery.CREDIT_CARD_TRACK1_PATTERN.matcher(hit.getSnippet()); - if (matcher.find()) { - parseTrack1Data(parsedTrackAttributeMap, matcher); - } - matcher = CREDIT_CARD_TRACK2_PATTERN.matcher(hit.getSnippet()); - if (matcher.find()) { - parseTrack2Data(parsedTrackAttributeMap, matcher); - } - final BlackboardAttribute ccnAttribute = parsedTrackAttributeMap.get(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_CARD_NUMBER)); - if (ccnAttribute == null || StringUtils.isBlank(ccnAttribute.getValueString())) { - if (hit.isArtifactHit()) { - LOGGER.log(Level.SEVERE, String.format("Failed to parse credit card account number for artifact keyword hit: term = %s, snippet = '%s', artifact id = %d", foundKeyword.getSearchTerm(), hit.getSnippet(), hit.getArtifactID().get())); //NON-NLS - } else { - LOGGER.log(Level.SEVERE, String.format("Failed to parse credit card account number for content keyword hit: term = %s, snippet = '%s', object id = %d", foundKeyword.getSearchTerm(), hit.getSnippet(), hit.getContentID())); //NON-NLS - } - return null; - } - attributes.addAll(parsedTrackAttributeMap.values()); - - /* - * Look up the bank name, scheme, etc. attributes for the bank - * indentification number (BIN). - */ - final int bin = Integer.parseInt(ccnAttribute.getValueString().substring(0, 8)); - CreditCards.BankIdentificationNumber binInfo = CreditCards.getBINInfo(bin); - if (binInfo != null) { - binInfo.getScheme().ifPresent(scheme - -> attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_CARD_SCHEME, MODULE_NAME, scheme))); - binInfo.getCardType().ifPresent(cardType - -> attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_CARD_TYPE, MODULE_NAME, cardType))); - binInfo.getBrand().ifPresent(brand - -> attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_BRAND_NAME, MODULE_NAME, brand))); - binInfo.getBankName().ifPresent(bankName - -> attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_BANK_NAME, MODULE_NAME, bankName))); - binInfo.getBankPhoneNumber().ifPresent(phoneNumber - -> attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PHONE_NUMBER, MODULE_NAME, phoneNumber))); - binInfo.getBankURL().ifPresent(url - -> attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL, MODULE_NAME, url))); - binInfo.getCountry().ifPresent(country - -> attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_COUNTRY, MODULE_NAME, country))); - binInfo.getBankCity().ifPresent(city - -> attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_CITY, MODULE_NAME, city))); - } - - /* - * If the hit is from unused or unallocated space, record the Solr - * document id to support showing just the chunk that contained the - * hit. - */ - if (content instanceof AbstractFile) { - AbstractFile file = (AbstractFile) content; - if (file.getType() == TskData.TSK_DB_FILES_TYPE_ENUM.UNUSED_BLOCKS - || file.getType() == TskData.TSK_DB_FILES_TYPE_ENUM.UNALLOC_BLOCKS) { - attributes.add(new BlackboardAttribute(KEYWORD_SEARCH_DOCUMENT_ID, MODULE_NAME, hit.getSolrDocumentId())); - } - } - - /* - * Create an account instance. - */ - try { - AccountInstance ccAccountInstance = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().createAccountInstance(Account.Type.CREDIT_CARD, ccnAttribute.getValueString() , MODULE_NAME, content); - newArtifact = Case.getCurrentCase().getSleuthkitCase().getBlackboardArtifact(ccAccountInstance.getArtifactId()); - } catch (TskCoreException ex) { - LOGGER.log(Level.SEVERE, "Error adding artifact for account to blackboard", ex); //NON-NLS - return null; - } + + attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_KEYWORD, MODULE_NAME, foundKeyword.getSearchTerm())); + attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_KEYWORD_REGEXP, MODULE_NAME, getQueryString())); + + try { + newArtifact = content.newArtifact(ARTIFACT_TYPE.TSK_KEYWORD_HIT); + } catch (TskCoreException ex) { + LOGGER.log(Level.SEVERE, "Error adding artifact for keyword hit to blackboard", ex); //NON-NLS + return null; } + if (StringUtils.isNotBlank(listName)) { attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_SET_NAME, MODULE_NAME, listName)); @@ -526,6 +459,107 @@ final class RegexQuery implements KeywordSearchQuery { } } + private void createCCNAccount(Content content, Keyword foundKeyword, KeywordHit hit, String snippet, String listName) { + + final String MODULE_NAME = KeywordSearchModuleFactory.getModuleName(); + + if (originalKeyword.getArtifactAttributeType() != ATTRIBUTE_TYPE.TSK_CARD_NUMBER) { + LOGGER.log(Level.SEVERE, "Keyword hit is not a credit card number"); //NON-NLS + return; + } + /* + * Create a credit card account with attributes + * parsed from the snippet for the hit and looked up based on the + * parsed bank identifcation number. + */ + Collection attributes = new ArrayList<>(); + + Map parsedTrackAttributeMap = new HashMap<>(); + Matcher matcher = TermsComponentQuery.CREDIT_CARD_TRACK1_PATTERN.matcher(hit.getSnippet()); + if (matcher.find()) { + parseTrack1Data(parsedTrackAttributeMap, matcher); + } + matcher = CREDIT_CARD_TRACK2_PATTERN.matcher(hit.getSnippet()); + if (matcher.find()) { + parseTrack2Data(parsedTrackAttributeMap, matcher); + } + final BlackboardAttribute ccnAttribute = parsedTrackAttributeMap.get(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_CARD_NUMBER)); + if (ccnAttribute == null || StringUtils.isBlank(ccnAttribute.getValueString())) { + if (hit.isArtifactHit()) { + LOGGER.log(Level.SEVERE, String.format("Failed to parse credit card account number for artifact keyword hit: term = %s, snippet = '%s', artifact id = %d", foundKeyword.getSearchTerm(), hit.getSnippet(), hit.getArtifactID().get())); //NON-NLS + } else { + LOGGER.log(Level.SEVERE, String.format("Failed to parse credit card account number for content keyword hit: term = %s, snippet = '%s', object id = %d", foundKeyword.getSearchTerm(), hit.getSnippet(), hit.getContentID())); //NON-NLS + } + return; + } + attributes.addAll(parsedTrackAttributeMap.values()); + + /* + * Look up the bank name, scheme, etc. attributes for the bank + * indentification number (BIN). + */ + final int bin = Integer.parseInt(ccnAttribute.getValueString().substring(0, 8)); + CreditCards.BankIdentificationNumber binInfo = CreditCards.getBINInfo(bin); + if (binInfo != null) { + binInfo.getScheme().ifPresent(scheme + -> attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_CARD_SCHEME, MODULE_NAME, scheme))); + binInfo.getCardType().ifPresent(cardType + -> attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_CARD_TYPE, MODULE_NAME, cardType))); + binInfo.getBrand().ifPresent(brand + -> attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_BRAND_NAME, MODULE_NAME, brand))); + binInfo.getBankName().ifPresent(bankName + -> attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_BANK_NAME, MODULE_NAME, bankName))); + binInfo.getBankPhoneNumber().ifPresent(phoneNumber + -> attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PHONE_NUMBER, MODULE_NAME, phoneNumber))); + binInfo.getBankURL().ifPresent(url + -> attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL, MODULE_NAME, url))); + binInfo.getCountry().ifPresent(country + -> attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_COUNTRY, MODULE_NAME, country))); + binInfo.getBankCity().ifPresent(city + -> attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_CITY, MODULE_NAME, city))); + } + + /* + * If the hit is from unused or unallocated space, record the Solr + * document id to support showing just the chunk that contained the + * hit. + */ + if (content instanceof AbstractFile) { + AbstractFile file = (AbstractFile) content; + if (file.getType() == TskData.TSK_DB_FILES_TYPE_ENUM.UNUSED_BLOCKS + || file.getType() == TskData.TSK_DB_FILES_TYPE_ENUM.UNALLOC_BLOCKS) { + attributes.add(new BlackboardAttribute(KEYWORD_SEARCH_DOCUMENT_ID, MODULE_NAME, hit.getSolrDocumentId())); + } + } + + if (StringUtils.isNotBlank(listName)) { + attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_SET_NAME, MODULE_NAME, listName)); + } + if (snippet != null) { + attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_KEYWORD_PREVIEW, MODULE_NAME, snippet)); + } + + hit.getArtifactID().ifPresent(artifactID + -> attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT, MODULE_NAME, artifactID)) + ); + + attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_KEYWORD_SEARCH_TYPE, MODULE_NAME, KeywordSearch.QueryType.REGEX.ordinal())); + + + /* + * Create an account instance. + */ + try { + AccountInstance ccAccountInstance = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().createAccountInstance(Account.Type.CREDIT_CARD, ccnAttribute.getValueString() , MODULE_NAME, content); + + ccAccountInstance.addAttributes(attributes); + + } catch (TskCoreException ex) { + LOGGER.log(Level.SEVERE, "Error creating CCN account instance", ex); //NON-NLS + + } + + } /** * Parses the track 2 data from the snippet for a credit card account number * hit and turns them into artifact attributes. diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TermsComponentQuery.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TermsComponentQuery.java index c8ae73dc78..fb1bc3c3e4 100755 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TermsComponentQuery.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TermsComponentQuery.java @@ -329,99 +329,33 @@ final class TermsComponentQuery implements KeywordSearchQuery { @Override public BlackboardArtifact writeSingleFileHitsToBlackBoard(Content content, Keyword foundKeyword, KeywordHit hit, String snippet, String listName) { + /* - * Create either a "plain vanilla" keyword hit artifact with keyword and - * regex attributes, or a credit card account artifact with attributes - * parsed from from the snippet for the hit and looked up based on the - * parsed bank identifcation number. + * CCN hits are handled specially + */ + if (originalKeyword.getArtifactAttributeType() == ATTRIBUTE_TYPE.TSK_CARD_NUMBER) { + createCCNAccount(content, hit, snippet, listName); + return null; + } + + /* + * Create a "plain vanilla" keyword hit artifact with keyword and + * regex attributes, */ BlackboardArtifact newArtifact; Collection attributes = new ArrayList<>(); - if (originalKeyword.getArtifactAttributeType() != ATTRIBUTE_TYPE.TSK_CARD_NUMBER) { - attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_KEYWORD, MODULE_NAME, foundKeyword.getSearchTerm())); - attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_KEYWORD_REGEXP, MODULE_NAME, originalKeyword.getSearchTerm())); + + attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_KEYWORD, MODULE_NAME, foundKeyword.getSearchTerm())); + attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_KEYWORD_REGEXP, MODULE_NAME, originalKeyword.getSearchTerm())); - try { - newArtifact = content.newArtifact(ARTIFACT_TYPE.TSK_KEYWORD_HIT); + try { + newArtifact = content.newArtifact(ARTIFACT_TYPE.TSK_KEYWORD_HIT); - } catch (TskCoreException ex) { - LOGGER.log(Level.SEVERE, "Error adding artifact for keyword hit to blackboard", ex); //NON-NLS - return null; - } - } else { - /* - * Parse the credit card account attributes from the snippet for the - * hit. - */ - Map parsedTrackAttributeMap = new HashMap<>(); - Matcher matcher = CREDIT_CARD_TRACK1_PATTERN.matcher(hit.getSnippet()); - if (matcher.find()) { - parseTrack1Data(parsedTrackAttributeMap, matcher); - } - matcher = CREDIT_CARD_TRACK2_PATTERN.matcher(hit.getSnippet()); - if (matcher.find()) { - parseTrack2Data(parsedTrackAttributeMap, matcher); - } - final BlackboardAttribute ccnAttribute = parsedTrackAttributeMap.get(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_CARD_NUMBER)); - if (ccnAttribute == null || StringUtils.isBlank(ccnAttribute.getValueString())) { - if (hit.isArtifactHit()) { - LOGGER.log(Level.SEVERE, String.format("Failed to parse credit card account number for artifact keyword hit: term = %s, snippet = '%s', artifact id = %d", searchTerm, hit.getSnippet(), hit.getArtifactID().get())); //NON-NLS - } else { - LOGGER.log(Level.SEVERE, String.format("Failed to parse credit card account number for content keyword hit: term = %s, snippet = '%s', object id = %d", searchTerm, hit.getSnippet(), hit.getContentID())); //NON-NLS - } - return null; - } - attributes.addAll(parsedTrackAttributeMap.values()); - - /* - * Look up the bank name, scheme, etc. attributes for the bank - * indentification number (BIN). - */ - final int bin = Integer.parseInt(ccnAttribute.getValueString().substring(0, 8)); - CreditCards.BankIdentificationNumber binInfo = CreditCards.getBINInfo(bin); - if (binInfo != null) { - binInfo.getScheme().ifPresent(scheme - -> attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_CARD_SCHEME, MODULE_NAME, scheme))); - binInfo.getCardType().ifPresent(cardType - -> attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_CARD_TYPE, MODULE_NAME, cardType))); - binInfo.getBrand().ifPresent(brand - -> attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_BRAND_NAME, MODULE_NAME, brand))); - binInfo.getBankName().ifPresent(bankName - -> attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_BANK_NAME, MODULE_NAME, bankName))); - binInfo.getBankPhoneNumber().ifPresent(phoneNumber - -> attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PHONE_NUMBER, MODULE_NAME, phoneNumber))); - binInfo.getBankURL().ifPresent(url - -> attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL, MODULE_NAME, url))); - binInfo.getCountry().ifPresent(country - -> attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_COUNTRY, MODULE_NAME, country))); - binInfo.getBankCity().ifPresent(city - -> attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_CITY, MODULE_NAME, city))); - } - - /* - * If the hit is from unused or unallocated space, record the Solr - * document id to support showing just the chunk that contained the - * hit. - */ - if (content instanceof AbstractFile) { - AbstractFile file = (AbstractFile) content; - if (file.getType() == TskData.TSK_DB_FILES_TYPE_ENUM.UNUSED_BLOCKS - || file.getType() == TskData.TSK_DB_FILES_TYPE_ENUM.UNALLOC_BLOCKS) { - attributes.add(new BlackboardAttribute(KEYWORD_SEARCH_DOCUMENT_ID, MODULE_NAME, hit.getSolrDocumentId())); - } - } - - /* - * Create an account artifact. - */ - try { - AccountInstance ccAccountInstance = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().createAccountInstance(Account.Type.CREDIT_CARD, ccnAttribute.getValueString() , MODULE_NAME, content); - newArtifact = Case.getCurrentCase().getSleuthkitCase().getBlackboardArtifact(ccAccountInstance.getArtifactId()); - } catch (TskCoreException ex) { - LOGGER.log(Level.SEVERE, "Error adding artifact for account to blackboard", ex); //NON-NLS - return null; - } + } catch (TskCoreException ex) { + LOGGER.log(Level.SEVERE, "Error adding artifact for keyword hit to blackboard", ex); //NON-NLS + return null; } + if (StringUtils.isNotBlank(listName)) { attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_SET_NAME, MODULE_NAME, listName)); @@ -446,6 +380,104 @@ final class TermsComponentQuery implements KeywordSearchQuery { } } + private void createCCNAccount(Content content, KeywordHit hit, String snippet, String listName) { + + if (originalKeyword.getArtifactAttributeType() != ATTRIBUTE_TYPE.TSK_CARD_NUMBER) { + LOGGER.log(Level.SEVERE, "Keyword hit is not a credit card number"); //NON-NLS + return; + } + + /* + * Create a credit card account with attributes + * parsed from from the snippet for the hit and looked up based on the + * parsed bank identifcation number. + */ + Collection attributes = new ArrayList<>(); + + Map parsedTrackAttributeMap = new HashMap<>(); + Matcher matcher = CREDIT_CARD_TRACK1_PATTERN.matcher(hit.getSnippet()); + if (matcher.find()) { + parseTrack1Data(parsedTrackAttributeMap, matcher); + } + matcher = CREDIT_CARD_TRACK2_PATTERN.matcher(hit.getSnippet()); + if (matcher.find()) { + parseTrack2Data(parsedTrackAttributeMap, matcher); + } + final BlackboardAttribute ccnAttribute = parsedTrackAttributeMap.get(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_CARD_NUMBER)); + if (ccnAttribute == null || StringUtils.isBlank(ccnAttribute.getValueString())) { + if (hit.isArtifactHit()) { + LOGGER.log(Level.SEVERE, String.format("Failed to parse credit card account number for artifact keyword hit: term = %s, snippet = '%s', artifact id = %d", searchTerm, hit.getSnippet(), hit.getArtifactID().get())); //NON-NLS + } else { + LOGGER.log(Level.SEVERE, String.format("Failed to parse credit card account number for content keyword hit: term = %s, snippet = '%s', object id = %d", searchTerm, hit.getSnippet(), hit.getContentID())); //NON-NLS + } + return; + } + attributes.addAll(parsedTrackAttributeMap.values()); + + /* + * Look up the bank name, scheme, etc. attributes for the bank + * indentification number (BIN). + */ + final int bin = Integer.parseInt(ccnAttribute.getValueString().substring(0, 8)); + CreditCards.BankIdentificationNumber binInfo = CreditCards.getBINInfo(bin); + if (binInfo != null) { + binInfo.getScheme().ifPresent(scheme + -> attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_CARD_SCHEME, MODULE_NAME, scheme))); + binInfo.getCardType().ifPresent(cardType + -> attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_CARD_TYPE, MODULE_NAME, cardType))); + binInfo.getBrand().ifPresent(brand + -> attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_BRAND_NAME, MODULE_NAME, brand))); + binInfo.getBankName().ifPresent(bankName + -> attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_BANK_NAME, MODULE_NAME, bankName))); + binInfo.getBankPhoneNumber().ifPresent(phoneNumber + -> attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PHONE_NUMBER, MODULE_NAME, phoneNumber))); + binInfo.getBankURL().ifPresent(url + -> attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL, MODULE_NAME, url))); + binInfo.getCountry().ifPresent(country + -> attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_COUNTRY, MODULE_NAME, country))); + binInfo.getBankCity().ifPresent(city + -> attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_CITY, MODULE_NAME, city))); + } + + /* + * If the hit is from unused or unallocated space, record the Solr + * document id to support showing just the chunk that contained the + * hit. + */ + if (content instanceof AbstractFile) { + AbstractFile file = (AbstractFile) content; + if (file.getType() == TskData.TSK_DB_FILES_TYPE_ENUM.UNUSED_BLOCKS + || file.getType() == TskData.TSK_DB_FILES_TYPE_ENUM.UNALLOC_BLOCKS) { + attributes.add(new BlackboardAttribute(KEYWORD_SEARCH_DOCUMENT_ID, MODULE_NAME, hit.getSolrDocumentId())); + } + } + + if (StringUtils.isNotBlank(listName)) { + attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_SET_NAME, MODULE_NAME, listName)); + } + if (snippet != null) { + attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_KEYWORD_PREVIEW, MODULE_NAME, snippet)); + } + + hit.getArtifactID().ifPresent( + artifactID -> attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT, MODULE_NAME, artifactID)) + ); + + // TermsComponentQuery is now being used exclusively for substring searches. + attributes.add(new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD_SEARCH_TYPE, MODULE_NAME, KeywordSearch.QueryType.SUBSTRING.ordinal())); + + /* + * Create an account. + */ + try { + AccountInstance ccAccountInstance = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().createAccountInstance(Account.Type.CREDIT_CARD, ccnAttribute.getValueString() , MODULE_NAME, content); + ccAccountInstance.addAttributes(attributes); + //newArtifact = Case.getCurrentCase().getSleuthkitCase().getBlackboardArtifact(ccAccountInstance.getArtifactId()); + } catch (TskCoreException ex) { + LOGGER.log(Level.SEVERE, "Error creating CCN account instance", ex); //NON-NLS + } + + } /** * Parses the track 2 data from the snippet for a credit card account number * hit and turns them into artifact attributes. From d829203dc70457c5476ac4e9fefbf65dfaca921a Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Tue, 24 Oct 2017 13:36:52 -0400 Subject: [PATCH 029/127] Fix comment in RegexQuery class. --- .../src/org/sleuthkit/autopsy/keywordsearch/RegexQuery.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/RegexQuery.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/RegexQuery.java index 1d4f32f18b..4dea228f22 100755 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/RegexQuery.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/RegexQuery.java @@ -419,8 +419,9 @@ final class RegexQuery implements KeywordSearchQuery { createCCNAccount(content, foundKeyword, hit, snippet, listName); return null; } + /* - * Create either a "plain vanilla" keyword hit artifact with keyword and + * Create a "plain vanilla" keyword hit artifact with keyword and * regex attributes */ BlackboardArtifact newArtifact; From 4c67f987434a5de5d233a1347536512b682a22d5 Mon Sep 17 00:00:00 2001 From: millmanorama Date: Wed, 25 Oct 2017 13:51:13 +0200 Subject: [PATCH 030/127] rename OpenCommVisualizationToolAction to avoid abbreviation, ue Children.Keys instead of ChildFactory --- .../sleuthkit/autopsy/casemodule/Case.java | 6 +- .../communications/AccountsNodeChildren.java | 63 +++++++++++++++++++ .../communications/AccountsNodeFactory.java | 46 -------------- .../communications/CVTTopComponent.java | 3 +- ...a => OpenCommVisualizationToolAction.java} | 4 +- 5 files changed, 69 insertions(+), 53 deletions(-) create mode 100644 Core/src/org/sleuthkit/autopsy/communications/AccountsNodeChildren.java delete mode 100644 Core/src/org/sleuthkit/autopsy/communications/AccountsNodeFactory.java rename Core/src/org/sleuthkit/autopsy/communications/{OpenCVTAction.java => OpenCommVisualizationToolAction.java} (95%) diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/Case.java b/Core/src/org/sleuthkit/autopsy/casemodule/Case.java index cdad71a66f..ee45d53944 100755 --- a/Core/src/org/sleuthkit/autopsy/casemodule/Case.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/Case.java @@ -76,7 +76,7 @@ import org.sleuthkit.autopsy.casemodule.events.ContentTagDeletedEvent; import org.sleuthkit.autopsy.casemodule.events.DataSourceAddedEvent; import org.sleuthkit.autopsy.casemodule.events.ReportAddedEvent; import org.sleuthkit.autopsy.casemodule.services.Services; -import org.sleuthkit.autopsy.communications.OpenCVTAction; +import org.sleuthkit.autopsy.communications.OpenCommVisualizationToolAction; import org.sleuthkit.autopsy.coordinationservice.CoordinationService; import org.sleuthkit.autopsy.coordinationservice.CoordinationService.CategoryNode; import org.sleuthkit.autopsy.coordinationservice.CoordinationService.CoordinationServiceException; @@ -1001,7 +1001,7 @@ public class Case { CallableSystemAction.get(CasePropertiesAction.class).setEnabled(true); CallableSystemAction.get(CaseDeleteAction.class).setEnabled(true); CallableSystemAction.get(OpenTimelineAction.class).setEnabled(true); - CallableSystemAction.get(OpenCVTAction.class).setEnabled(true); + CallableSystemAction.get(OpenCommVisualizationToolAction.class).setEnabled(true); CallableSystemAction.get(OpenOutputFolderAction.class).setEnabled(false); /* @@ -1049,7 +1049,7 @@ public class Case { CallableSystemAction.get(CasePropertiesAction.class).setEnabled(false); CallableSystemAction.get(CaseDeleteAction.class).setEnabled(false); CallableSystemAction.get(OpenTimelineAction.class).setEnabled(false); - CallableSystemAction.get(OpenCVTAction.class).setEnabled(false); + CallableSystemAction.get(OpenCommVisualizationToolAction.class).setEnabled(false); CallableSystemAction.get(OpenOutputFolderAction.class).setEnabled(false); /* diff --git a/Core/src/org/sleuthkit/autopsy/communications/AccountsNodeChildren.java b/Core/src/org/sleuthkit/autopsy/communications/AccountsNodeChildren.java new file mode 100644 index 0000000000..e0b1209366 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/communications/AccountsNodeChildren.java @@ -0,0 +1,63 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2011-2017 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.sleuthkit.autopsy.communications; + +import java.util.Collections; +import java.util.List; +import org.openide.nodes.Children; +import org.openide.nodes.Node; +import org.sleuthkit.datamodel.Account; + +class AccountsNodeChildren extends Children.Keys { + + private final List accounts; + + AccountsNodeChildren(List accounts) { + super(true); + this.accounts = accounts; + } + + @Override + protected void removeNotify() { + super.removeNotify(); + setKeys(Collections.emptySet()); + } + + @Override + protected void addNotify() { + super.addNotify(); + setKeys(accounts); + } + + //These are the methods for ChildFactory. I am going to keep them around but commented until we make a final descision. + // @Override + // protected boolean createKeys(List list) { + // list.addAll(accounts); + // return true; + // } + // + // @Override + // protected Node createNodeForKey(Account key) { + // return new AccountNode(key); + // } + @Override + protected Node[] createNodes(Account key) { + return new Node[]{new AccountNode(key)}; + } +} diff --git a/Core/src/org/sleuthkit/autopsy/communications/AccountsNodeFactory.java b/Core/src/org/sleuthkit/autopsy/communications/AccountsNodeFactory.java deleted file mode 100644 index 37cfccc4af..0000000000 --- a/Core/src/org/sleuthkit/autopsy/communications/AccountsNodeFactory.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Autopsy Forensic Browser - * - * Copyright 2011-2017 Basis Technology Corp. - * Contact: carrier sleuthkit org - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.sleuthkit.autopsy.communications; - -import java.util.List; -import org.openide.nodes.ChildFactory; -import org.openide.nodes.Node; -import org.sleuthkit.datamodel.Account; - - - -class AccountsNodeFactory extends ChildFactory { - - private final List< Account> accounts; - - AccountsNodeFactory(List accounts) { - this.accounts = accounts; - } - - @Override - protected boolean createKeys(List list) { - list.addAll(accounts); - return true; - } - - @Override - protected Node createNodeForKey(Account key) { - return new AccountNode(key); - } -} diff --git a/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java b/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java index 288380825e..23703df6c1 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java +++ b/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java @@ -23,7 +23,6 @@ import java.util.List; import java.util.stream.Collectors; import org.openide.explorer.ExplorerManager; import org.openide.nodes.AbstractNode; -import org.openide.nodes.Children; import org.openide.util.Exceptions; import org.openide.util.NbBundle; import org.openide.windows.Mode; @@ -168,7 +167,7 @@ public final class CVTTopComponent extends TopComponent implements ExplorerManag accounts.addAll(communicationsManager.getAccounts(Account.Type.EMAIL)); accounts.addAll(communicationsManager.getAccounts(Account.Type.DEVICE)); - em.setRootContext(new AbstractNode(Children.create(new AccountsNodeFactory(accounts), true))); + em.setRootContext(new AbstractNode(new AccountsNodeChildren(accounts))); } catch (TskCoreException ex) { Exceptions.printStackTrace(ex); } diff --git a/Core/src/org/sleuthkit/autopsy/communications/OpenCVTAction.java b/Core/src/org/sleuthkit/autopsy/communications/OpenCommVisualizationToolAction.java similarity index 95% rename from Core/src/org/sleuthkit/autopsy/communications/OpenCVTAction.java rename to Core/src/org/sleuthkit/autopsy/communications/OpenCommVisualizationToolAction.java index 04065cc28c..80586d0aa9 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/OpenCVTAction.java +++ b/Core/src/org/sleuthkit/autopsy/communications/OpenCommVisualizationToolAction.java @@ -44,14 +44,14 @@ import org.openide.windows.WindowManager; @ActionReference(path = "Menu/Tools", position = 102) , @ActionReference(path = "Toolbars/Case", position = 102)}) @Messages("CTL_OpenCVTAction=Visualize Communications") -public final class OpenCVTAction extends CallableSystemAction implements Presenter.Toolbar { +public final class OpenCommVisualizationToolAction extends CallableSystemAction implements Presenter.Toolbar { private static final long serialVersionUID = 1L; private final JButton toolbarButton = new JButton(getName(), new ImageIcon(getClass().getResource("images/email_link.png"))); //NON-NLS - public OpenCVTAction() { + public OpenCommVisualizationToolAction() { toolbarButton.addActionListener(actionEvent -> performAction()); setEnabled(false); //disabled by default. Will be enabled in Case.java when a case is opened. } From b78438fffb0c8a6b8972cff386ce26f90127d6df Mon Sep 17 00:00:00 2001 From: millmanorama Date: Wed, 25 Oct 2017 14:07:50 +0200 Subject: [PATCH 031/127] fix merge error, add logger --- .../communications/CVTTopComponent.java | 2 +- .../autopsy/communications/FiltersPanel.form | 19 +++++++-------- .../autopsy/communications/FiltersPanel.java | 23 ++++++++++--------- 3 files changed, 23 insertions(+), 21 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java b/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java index 18fb085ee3..7ab0d82f28 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java +++ b/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java @@ -124,7 +124,7 @@ public final class CVTTopComponent extends TopComponent implements ExplorerManag ); }// //GEN-END:initComponents - em.setRootContext(new AbstractNode(new AccountsNodeChildren(accounts))); + // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JTabbedPane BrowseVisualizeTabPane; private javax.swing.JSplitPane HSplitPane; diff --git a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.form b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.form index 8172098a59..89e3a267eb 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.form +++ b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.form @@ -201,19 +201,20 @@ - - - - - - - - - + + + + + + + + + + diff --git a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java index 069e0d84ee..a823dea91b 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java +++ b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java @@ -23,12 +23,12 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; +import java.util.logging.Level; import javax.swing.JCheckBox; import org.openide.explorer.ExplorerManager; import org.openide.nodes.AbstractNode; -import org.openide.nodes.Children; -import org.openide.util.Exceptions; import org.sleuthkit.autopsy.casemodule.Case; +import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.ThreadConfined; import org.sleuthkit.datamodel.Account; import org.sleuthkit.datamodel.CommunicationsManager; @@ -38,14 +38,15 @@ import org.sleuthkit.datamodel.TskCoreException; * */ public class FiltersPanel extends javax.swing.JPanel { - + + private static final Logger logger = Logger.getLogger(FiltersPanel.class.getName()); private static final long serialVersionUID = 1L; - + private ExplorerManager em; - + @ThreadConfined(type = ThreadConfined.ThreadType.AWT) private final Map accountTypeMap = new HashMap<>(); - + public FiltersPanel() { initComponents(); /* @@ -69,10 +70,10 @@ public class FiltersPanel extends javax.swing.JPanel { accountTypePane.add(jCheckBox); accountTypeMap.put(type, jCheckBox); }); - + invalidate(); } - + @Override public void addNotify() { super.addNotify(); @@ -281,16 +282,16 @@ public class FiltersPanel extends javax.swing.JPanel { */ try { final CommunicationsManager communicationsManager = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager(); - + List accounts = new ArrayList<>(); for (Entry entry : accountTypeMap.entrySet()) { if (entry.getValue().isSelected()) { accounts.addAll(communicationsManager.getAccounts(entry.getKey())); } } - em.setRootContext(new AbstractNode(Children.create(new AccountsNodeFactory(accounts), true))); + em.setRootContext(new AbstractNode(new AccountsNodeChildren(accounts))); } catch (TskCoreException ex) { - Exceptions.printStackTrace(ex); + logger.log(Level.SEVERE, "There was a error loading the accounts.", ex); } }//GEN-LAST:event_applyFiltersButtonActionPerformed From 79604598763f3a1311ad4e9a4c3ec4c608a8b1fb Mon Sep 17 00:00:00 2001 From: millmanorama Date: Wed, 25 Oct 2017 15:17:15 +0200 Subject: [PATCH 032/127] tweak the FiltersPanel --- .../autopsy/communications/FiltersPanel.form | 25 ++-- .../autopsy/communications/FiltersPanel.java | 113 ++++++++++-------- 2 files changed, 74 insertions(+), 64 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.form b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.form index 89e3a267eb..6f3b8e8ef3 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.form +++ b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.form @@ -50,7 +50,7 @@ - + @@ -139,7 +139,7 @@ - + @@ -207,7 +207,7 @@ - + @@ -222,10 +222,10 @@ - + - + @@ -267,7 +267,7 @@ - + @@ -276,17 +276,8 @@ - - - - - - - - - - - + + diff --git a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java index a823dea91b..b61975d026 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java +++ b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java @@ -32,24 +32,30 @@ import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.ThreadConfined; import org.sleuthkit.datamodel.Account; import org.sleuthkit.datamodel.CommunicationsManager; +import org.sleuthkit.datamodel.DataSource; import org.sleuthkit.datamodel.TskCoreException; /** * */ public class FiltersPanel extends javax.swing.JPanel { - + private static final Logger logger = Logger.getLogger(FiltersPanel.class.getName()); private static final long serialVersionUID = 1L; - + private ExplorerManager em; - + @ThreadConfined(type = ThreadConfined.ThreadType.AWT) private final Map accountTypeMap = new HashMap<>(); - + @ThreadConfined(type = ThreadConfined.ThreadType.AWT) + private final Map devicesMap = new HashMap<>(); + public FiltersPanel() { initComponents(); + /* + * Populate the Account Types filter widgets + * * something like this commented code could be used to show only the * account types that are found: * @@ -59,21 +65,34 @@ public class FiltersPanel extends javax.swing.JPanel { * communicationsManager.getAccountTypesInUse(); * accountTypesInUSe.forEach(....) */ - Account.Type.PREDEFINED_ACCOUNT_TYPES.forEach(type -> { - final JCheckBox jCheckBox = new JCheckBox( - "
" + type.getDisplayName() + "
", - true - ); - accountTypePane.add(jCheckBox); - accountTypeMap.put(type, jCheckBox); - }); - - invalidate(); + Account.Type.PREDEFINED_ACCOUNT_TYPES.forEach( + type -> { + final JCheckBox jCheckBox = new JCheckBox( + "
" + type.getDisplayName() + "
", + true + ); + accountTypePane.add(jCheckBox); + accountTypeMap.put(type, jCheckBox); + }); + + /** + * Populate the devices filter widgets + */ + try { + Case.getCurrentCase().getSleuthkitCase().getDataSources().stream().forEach( + dataSource -> { + final JCheckBox jCheckBox = new JCheckBox(dataSource.getDeviceId(), true); + devicesPane.add(jCheckBox); + devicesMap.put(dataSource, jCheckBox); + }); + } catch (TskCoreException tskCoreException) { + logger.log(Level.SEVERE, "There was a error loading the datasources for the case.", tskCoreException); + } } - + @Override public void addNotify() { super.addNotify(); @@ -102,7 +121,7 @@ public class FiltersPanel extends javax.swing.JPanel { unCheckAllDevicesButton = new javax.swing.JButton(); devicesLabel = new javax.swing.JLabel(); checkAllDevicesButton = new javax.swing.JButton(); - jPanel1 = new javax.swing.JPanel(); + devicesPane = new javax.swing.JPanel(); jList1.setModel(new javax.swing.AbstractListModel() { String[] strings = { "Item 1", "Item 2", "Item 3", "Item 4", "Item 5" }; @@ -169,7 +188,7 @@ public class FiltersPanel extends javax.swing.JPanel { .addGroup(jPanel2Layout.createSequentialGroup() .addComponent(accountTypesLabel) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(accountTypePane, javax.swing.GroupLayout.DEFAULT_SIZE, 118, Short.MAX_VALUE) + .addComponent(accountTypePane, javax.swing.GroupLayout.DEFAULT_SIZE, 115, Short.MAX_VALUE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(checkAllAccountTypesButton) @@ -194,34 +213,24 @@ public class FiltersPanel extends javax.swing.JPanel { } }); - jPanel1.setBorder(javax.swing.BorderFactory.createEtchedBorder()); - - javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1); - jPanel1.setLayout(jPanel1Layout); - jPanel1Layout.setHorizontalGroup( - jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGap(0, 0, Short.MAX_VALUE) - ); - jPanel1Layout.setVerticalGroup( - jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGap(0, 48, Short.MAX_VALUE) - ); + devicesPane.setBorder(javax.swing.BorderFactory.createEtchedBorder()); + devicesPane.setLayout(new javax.swing.BoxLayout(devicesPane, javax.swing.BoxLayout.Y_AXIS)); javax.swing.GroupLayout jPanel3Layout = new javax.swing.GroupLayout(jPanel3); jPanel3.setLayout(jPanel3Layout); jPanel3Layout.setHorizontalGroup( jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(jPanel3Layout.createSequentialGroup() - .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addContainerGap()) .addGroup(jPanel3Layout.createSequentialGroup() .addComponent(devicesLabel) .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel3Layout.createSequentialGroup() - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(unCheckAllDevicesButton) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(checkAllDevicesButton) + .addGroup(jPanel3Layout.createSequentialGroup() + .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(devicesPane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel3Layout.createSequentialGroup() + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(unCheckAllDevicesButton) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(checkAllDevicesButton))) .addContainerGap()) ); jPanel3Layout.setVerticalGroup( @@ -230,7 +239,7 @@ public class FiltersPanel extends javax.swing.JPanel { .addContainerGap() .addComponent(devicesLabel) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(devicesPane, javax.swing.GroupLayout.DEFAULT_SIZE, 55, Short.MAX_VALUE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(checkAllDevicesButton) @@ -249,7 +258,7 @@ public class FiltersPanel extends javax.swing.JPanel { .addComponent(filtersTitleLabel) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(applyFiltersButton) - .addGap(12, 12, 12)) + .addContainerGap()) .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() .addComponent(jPanel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addContainerGap()) @@ -282,7 +291,7 @@ public class FiltersPanel extends javax.swing.JPanel { */ try { final CommunicationsManager communicationsManager = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager(); - + List accounts = new ArrayList<>(); for (Entry entry : accountTypeMap.entrySet()) { if (entry.getValue().isSelected()) { @@ -297,7 +306,17 @@ public class FiltersPanel extends javax.swing.JPanel { }//GEN-LAST:event_applyFiltersButtonActionPerformed @ThreadConfined(type = ThreadConfined.ThreadType.AWT) private void setAllTypesSelected(boolean selected) { - accountTypeMap.values().forEach(box -> box.setSelected(selected)); + setAllSelected(accountTypeMap, selected); + } + + @ThreadConfined(type = ThreadConfined.ThreadType.AWT) + private void setAllDevicesSelected(boolean selected) { + setAllSelected(devicesMap, selected); + } + + @ThreadConfined(type = ThreadConfined.ThreadType.AWT) + private void setAllSelected(Map map, boolean selected) { + map.values().forEach(box -> box.setSelected(selected)); } private void unCheckAllAccountTypesButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_unCheckAllAccountTypesButtonActionPerformed setAllTypesSelected(false); @@ -308,11 +327,11 @@ public class FiltersPanel extends javax.swing.JPanel { }//GEN-LAST:event_checkAllAccountTypesButtonActionPerformed private void unCheckAllDevicesButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_unCheckAllDevicesButtonActionPerformed - // TODO add your handling code here: + setAllDevicesSelected(false); }//GEN-LAST:event_unCheckAllDevicesButtonActionPerformed private void checkAllDevicesButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_checkAllDevicesButtonActionPerformed - // TODO add your handling code here: + setAllDevicesSelected(true); }//GEN-LAST:event_checkAllDevicesButtonActionPerformed @@ -323,9 +342,9 @@ public class FiltersPanel extends javax.swing.JPanel { private javax.swing.JButton checkAllAccountTypesButton; private javax.swing.JButton checkAllDevicesButton; private javax.swing.JLabel devicesLabel; + private javax.swing.JPanel devicesPane; private javax.swing.JLabel filtersTitleLabel; private javax.swing.JList jList1; - private javax.swing.JPanel jPanel1; private javax.swing.JPanel jPanel2; private javax.swing.JPanel jPanel3; private javax.swing.JScrollPane jScrollPane1; From 22a9dcd5fc18edcd922140be4915610865127c1f Mon Sep 17 00:00:00 2001 From: millmanorama Date: Wed, 25 Oct 2017 17:05:22 +0200 Subject: [PATCH 033/127] added TODOs for wiring up the ComunicationsManager to the UI using the real API --- .../autopsy/communications/AccountNode.java | 6 +- .../autopsy/communications/FiltersPanel.form | 59 ++++++++----------- .../autopsy/communications/FiltersPanel.java | 54 ++++++++--------- 3 files changed, 56 insertions(+), 63 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/communications/AccountNode.java b/Core/src/org/sleuthkit/autopsy/communications/AccountNode.java index 2d85bb92d1..304e6842a3 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/AccountNode.java +++ b/Core/src/org/sleuthkit/autopsy/communications/AccountNode.java @@ -28,6 +28,10 @@ import org.sleuthkit.datamodel.Account; /** * Node to represent an Account in the AccountsBrowser + * + * TODO: This will change to AccountDeviceInstanceNode and wrap a + * AccountDeviceInstance. This will let us populate the device field. What about + * the counts? Are we going to end up doing another query for each object? */ class AccountNode extends AbstractNode { @@ -63,7 +67,7 @@ class AccountNode extends AbstractNode { "count", 1)); // NON-NLS //dummy value - //how do I get the device name + //TODO: uncomment and correct this when this class changes to AccountDeviceInstanceNode // properties.put(new NodeProperty<>("device", // Bundle.AccountNode_device(), // "device", diff --git a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.form b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.form index 6f3b8e8ef3..8bf3f958de 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.form +++ b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.form @@ -52,11 +52,8 @@
- - - - +
@@ -70,10 +67,10 @@
- - - + + +
@@ -111,26 +108,20 @@ - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + @@ -138,14 +129,14 @@ - - - + + + - + @@ -208,7 +199,7 @@ - + @@ -225,13 +216,13 @@ - + - + diff --git a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java index b61975d026..f28be50b57 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java +++ b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java @@ -56,8 +56,9 @@ public class FiltersPanel extends javax.swing.JPanel { /* * Populate the Account Types filter widgets * - * something like this commented code could be used to show only the - * account types that are found: + * + * TODO: something like this commented code could be used to show only + * the account types that are found: * * final CommunicationsManager communicationsManager = * Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager(); @@ -168,27 +169,24 @@ public class FiltersPanel extends javax.swing.JPanel { jPanel2Layout.setHorizontalGroup( jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel2Layout.createSequentialGroup() - .addGap(0, 0, 0) - .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(jPanel2Layout.createSequentialGroup() - .addGap(0, 0, Short.MAX_VALUE) - .addComponent(unCheckAllAccountTypesButton) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(checkAllAccountTypesButton)) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel2Layout.createSequentialGroup() - .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(accountTypePane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addGroup(jPanel2Layout.createSequentialGroup() - .addComponent(accountTypesLabel) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 144, javax.swing.GroupLayout.PREFERRED_SIZE))) - .addContainerGap()))) + .addComponent(accountTypePane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addContainerGap()) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel2Layout.createSequentialGroup() + .addComponent(accountTypesLabel) + .addGap(144, 144, 144)) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel2Layout.createSequentialGroup() + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(unCheckAllAccountTypesButton) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(checkAllAccountTypesButton) + .addContainerGap()) ); jPanel2Layout.setVerticalGroup( jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel2Layout.createSequentialGroup() .addComponent(accountTypesLabel) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(accountTypePane, javax.swing.GroupLayout.DEFAULT_SIZE, 115, Short.MAX_VALUE) + .addComponent(accountTypePane, javax.swing.GroupLayout.DEFAULT_SIZE, 170, Short.MAX_VALUE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(checkAllAccountTypesButton) @@ -226,7 +224,7 @@ public class FiltersPanel extends javax.swing.JPanel { .addGroup(jPanel3Layout.createSequentialGroup() .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(devicesPane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel3Layout.createSequentialGroup() + .addGroup(jPanel3Layout.createSequentialGroup() .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(unCheckAllDevicesButton) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) @@ -239,7 +237,7 @@ public class FiltersPanel extends javax.swing.JPanel { .addContainerGap() .addComponent(devicesLabel) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(devicesPane, javax.swing.GroupLayout.DEFAULT_SIZE, 55, Short.MAX_VALUE) + .addComponent(devicesPane, javax.swing.GroupLayout.DEFAULT_SIZE, 67, Short.MAX_VALUE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(checkAllDevicesButton) @@ -259,10 +257,8 @@ public class FiltersPanel extends javax.swing.JPanel { .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(applyFiltersButton) .addContainerGap()) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() - .addComponent(jPanel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addContainerGap()) - .addComponent(jPanel3, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))) + .addComponent(jPanel3, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jPanel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) @@ -272,10 +268,10 @@ public class FiltersPanel extends javax.swing.JPanel { .addComponent(filtersTitleLabel) .addComponent(applyFiltersButton)) .addGap(18, 18, 18) - .addComponent(jPanel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(jPanel3, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addContainerGap()) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jPanel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); }// //GEN-END:initComponents @@ -286,8 +282,10 @@ public class FiltersPanel extends javax.swing.JPanel { * selected filters, and send the results to the AccountsBrowser via the * ExplorerManager. * - * This will need to be adapted to any changes in the Comunications - * Manager API + * TODO: This will need to be adapted to any changes in the + * Comunications Manager API, such as using Filter objcts built from the + * state of the checkboxes and the result types changing from Accounts + * to AccountDeviceInstances */ try { final CommunicationsManager communicationsManager = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager(); From 5cff9148e0cdb5a64a155f8e28915d054a1f6173 Mon Sep 17 00:00:00 2001 From: millmanorama Date: Wed, 25 Oct 2017 17:06:34 +0200 Subject: [PATCH 034/127] scheduling the calls to setColumnWidths to the EDT made the column sizing work. --- .../sleuthkit/autopsy/communications/AccountsBrowser.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/communications/AccountsBrowser.java b/Core/src/org/sleuthkit/autopsy/communications/AccountsBrowser.java index 82864e7eb1..d165ada2bd 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/AccountsBrowser.java +++ b/Core/src/org/sleuthkit/autopsy/communications/AccountsBrowser.java @@ -21,6 +21,7 @@ package org.sleuthkit.autopsy.communications; import java.awt.Component; import javax.swing.JPanel; import javax.swing.ListSelectionModel; +import javax.swing.SwingUtilities; import javax.swing.table.TableCellRenderer; import org.netbeans.swing.outline.DefaultOutlineModel; import org.netbeans.swing.outline.Outline; @@ -63,9 +64,9 @@ public class AccountsBrowser extends JPanel { em = ExplorerManager.find(this); em.addPropertyChangeListener(evt -> { if (ExplorerManager.PROP_ROOT_CONTEXT.equals(evt.getPropertyName())) { - setColumnWidths(); + SwingUtilities.invokeLater(this::setColumnWidths); } else if (ExplorerManager.PROP_EXPLORED_CONTEXT.equals(evt.getPropertyName())) { - setColumnWidths(); + SwingUtilities.invokeLater(this::setColumnWidths); } }); } @@ -74,10 +75,11 @@ public class AccountsBrowser extends JPanel { int margin = 4; int padding = 8; + final int rows = Math.min(100, outline.getRowCount()); + for (int column = 0; column < outline.getModel().getColumnCount(); column++) { int columnWidthLimit = 500; int columnWidth = 0; - final int rows = Math.min(100, outline.getRowCount()); // find the maximum width needed to fit the values for the first 100 rows, at most for (int row = 0; row < rows; row++) { From a8fce5caee4b013ee3de6b2ff65e34281681edee Mon Sep 17 00:00:00 2001 From: Raman Date: Wed, 25 Oct 2017 12:46:28 -0400 Subject: [PATCH 035/127] Removed error log - postKeywordHitToBlackboard() may legitimately return NULL, say for CreditCard hits --- .../src/org/sleuthkit/autopsy/keywordsearch/QueryResults.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/QueryResults.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/QueryResults.java index 7037f898be..585424b3ec 100755 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/QueryResults.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/QueryResults.java @@ -222,9 +222,6 @@ class QueryResults { * Post an artifact for the hit to the blackboard. */ BlackboardArtifact artifact = query.postKeywordHitToBlackboard(content, keyword, hit, snippet, query.getKeywordList().getName()); - if (null == artifact) { - logger.log(Level.SEVERE, "Error posting keyword hit artifact for keyword {0} in {1} to the blackboard", new Object[]{keyword.toString(), content}); //NON-NLS - } /* * Send an ingest inbox message for the hit. From 671ce19098295f9a8c665ab288fe6ddc45903071 Mon Sep 17 00:00:00 2001 From: Raman Date: Wed, 25 Oct 2017 15:54:14 -0400 Subject: [PATCH 036/127] 865: Milestone 1, basic UI with accounts table - Integrated the CommunicationsManager API to populate the Accounts device instance table. --- .../autopsy/communications/AccountNode.java | 65 ++++++++++++------- .../communications/AccountsNodeChildren.java | 14 ++-- .../communications/CVTTopComponent.java | 12 ++-- 3 files changed, 54 insertions(+), 37 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/communications/AccountNode.java b/Core/src/org/sleuthkit/autopsy/communications/AccountNode.java index f2571b5eb7..872536f9fc 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/AccountNode.java +++ b/Core/src/org/sleuthkit/autopsy/communications/AccountNode.java @@ -21,23 +21,28 @@ package org.sleuthkit.autopsy.communications; import org.openide.nodes.AbstractNode; import org.openide.nodes.Children; import org.openide.nodes.Sheet; +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.NodeProperty; import org.sleuthkit.datamodel.Account; +import org.sleuthkit.datamodel.AccountDeviceInstance; +import org.sleuthkit.datamodel.CommunicationsFilter; +import org.sleuthkit.datamodel.TskCoreException; /** * Node to represent an Account in the AccountsBrowser */ class AccountNode extends AbstractNode { - private final Account account; + private final AccountDeviceInstance accountDeviceInstance; - AccountNode(Account account) { - super(Children.LEAF, Lookups.fixed(account)); - this.account = account; - setName(account.getAccountUniqueID()); - setIconBaseWithExtension("org/sleuthkit/autopsy/communications/images/" + getIconFileName(account.getAccountType())); + AccountNode(AccountDeviceInstance accountDeviceInstance) { + super(Children.LEAF, Lookups.fixed(accountDeviceInstance)); + this.accountDeviceInstance = accountDeviceInstance; + setName(accountDeviceInstance.getAccount().getAccountUniqueID()); + setIconBaseWithExtension("org/sleuthkit/autopsy/communications/images/" + getIconFileName(accountDeviceInstance.getAccount().getAccountType())); } /** @@ -47,25 +52,25 @@ class AccountNode extends AbstractNode { * @return The file name of the icon for the given Account Type. */ final String getIconFileName(Account.Type type) { - if (type == Account.Type.CREDIT_CARD) { + if (type.equals(Account.Type.CREDIT_CARD)) { return "credit-card.png"; - } else if (type == Account.Type.DEVICE) { + } else if (type.equals(Account.Type.DEVICE)) { return "image.png"; - } else if (type == Account.Type.EMAIL) { + } else if (type.equals(Account.Type.EMAIL)) { return "email.png"; - } else if (type == Account.Type.FACEBOOK) { + } else if (type.equals(Account.Type.FACEBOOK)) { return "facebook.png"; - } else if (type == Account.Type.INSTAGRAM) { + } else if (type.equals(Account.Type.INSTAGRAM)) { return "instagram.png"; - } else if (type == Account.Type.MESSAGING_APP) { + } else if (type.equals(Account.Type.MESSAGING_APP)) { return "messaging.png"; - } else if (type == Account.Type.PHONE) { + } else if (type.equals(Account.Type.PHONE)) { return "phone.png"; - } else if (type == Account.Type.TWITTER) { + } else if (type.equals(Account.Type.TWITTER)) { return "twitter.png"; - } else if (type == Account.Type.WEBSITE) { + } else if (type.equals(Account.Type.WEBSITE)) { return "web-file.png"; - } else if (type == Account.Type.WHATSAPP) { + } else if (type.equals(Account.Type.WHATSAPP)) { return "WhatsApp.png"; } else { //there could be a default icon instead... @@ -88,20 +93,32 @@ class AccountNode extends AbstractNode { s.put(properties); } + // RAMAN TBD: need to figure out how to get the right filters here + // We talked about either creating a wrapper class around AccountDeviceInstance to push the selected filters + // Or some kind of static access to pull the selected filters + long msgCount = 0; + try { + CommunicationsFilter filter = null; + msgCount = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().getRelationshipsCount(filter, accountDeviceInstance); + } + catch (TskCoreException ex) { + Exceptions.printStackTrace(ex); + } + properties.put(new NodeProperty<>("type", Bundle.AccountNode_accountType(), "type", - account.getAccountType().getDisplayName())); // NON-NLS + accountDeviceInstance.getAccount().getAccountType().getDisplayName())); // NON-NLS + properties.put(new NodeProperty<>("count", Bundle.AccountNode_messageCount(), "count", - 1)); // NON-NLS //dummy value - - //how do I get the device name -// properties.put(new NodeProperty<>("device", -// Bundle.AccountNode_device(), -// "device", -// account.)); // NON-NLS + msgCount)); // NON-NLS + + properties.put(new NodeProperty<>("device", + Bundle.AccountNode_device(), + "device", + accountDeviceInstance.getDeviceId())); // NON-NLS return s; } } diff --git a/Core/src/org/sleuthkit/autopsy/communications/AccountsNodeChildren.java b/Core/src/org/sleuthkit/autopsy/communications/AccountsNodeChildren.java index e0b1209366..07e9335d5c 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/AccountsNodeChildren.java +++ b/Core/src/org/sleuthkit/autopsy/communications/AccountsNodeChildren.java @@ -22,15 +22,15 @@ import java.util.Collections; import java.util.List; import org.openide.nodes.Children; import org.openide.nodes.Node; -import org.sleuthkit.datamodel.Account; +import org.sleuthkit.datamodel.AccountDeviceInstance; -class AccountsNodeChildren extends Children.Keys { +class AccountsNodeChildren extends Children.Keys { - private final List accounts; + private final List accountDeviceInstances; - AccountsNodeChildren(List accounts) { + AccountsNodeChildren(List accountDeviceInstances) { super(true); - this.accounts = accounts; + this.accountDeviceInstances = accountDeviceInstances; } @Override @@ -42,7 +42,7 @@ class AccountsNodeChildren extends Children.Keys { @Override protected void addNotify() { super.addNotify(); - setKeys(accounts); + setKeys(accountDeviceInstances); } //These are the methods for ChildFactory. I am going to keep them around but commented until we make a final descision. @@ -57,7 +57,7 @@ class AccountsNodeChildren extends Children.Keys { // return new AccountNode(key); // } @Override - protected Node[] createNodes(Account key) { + protected Node[] createNodes(AccountDeviceInstance key) { return new Node[]{new AccountNode(key)}; } } diff --git a/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java b/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java index 23703df6c1..d9a8382052 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java +++ b/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java @@ -31,7 +31,7 @@ import org.openide.windows.TopComponent; import org.openide.windows.WindowManager; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.coreutils.ThreadConfined; -import org.sleuthkit.datamodel.Account; +import org.sleuthkit.datamodel.AccountDeviceInstance; import org.sleuthkit.datamodel.CommunicationsManager; import org.sleuthkit.datamodel.TskCoreException; @@ -162,12 +162,12 @@ public final class CVTTopComponent extends TopComponent implements ExplorerManag * ExplorerManager */ try { - List accounts = new ArrayList<>(); + List accountDeviceInstances = new ArrayList<>(); + final CommunicationsManager communicationsManager = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager(); - accounts.addAll(communicationsManager.getAccounts(Account.Type.EMAIL)); - accounts.addAll(communicationsManager.getAccounts(Account.Type.DEVICE)); - - em.setRootContext(new AbstractNode(new AccountsNodeChildren(accounts))); + accountDeviceInstances.addAll(communicationsManager.getAccountDeviceInstancesWithRelationships(null)); + + em.setRootContext(new AbstractNode(new AccountsNodeChildren(accountDeviceInstances))); } catch (TskCoreException ex) { Exceptions.printStackTrace(ex); } From 514d94aa1b2875fa751b5372d94214c230d42658 Mon Sep 17 00:00:00 2001 From: Raman Date: Wed, 25 Oct 2017 19:53:58 -0400 Subject: [PATCH 037/127] Adding logging of exceptions. --- .../org/sleuthkit/autopsy/communications/AccountNode.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/communications/AccountNode.java b/Core/src/org/sleuthkit/autopsy/communications/AccountNode.java index 872536f9fc..0b8d7af61c 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/AccountNode.java +++ b/Core/src/org/sleuthkit/autopsy/communications/AccountNode.java @@ -18,6 +18,8 @@ */ package org.sleuthkit.autopsy.communications; +import java.util.logging.Level; +import java.util.logging.Logger; import org.openide.nodes.AbstractNode; import org.openide.nodes.Children; import org.openide.nodes.Sheet; @@ -35,6 +37,8 @@ import org.sleuthkit.datamodel.TskCoreException; * Node to represent an Account in the AccountsBrowser */ class AccountNode extends AbstractNode { + + private static final Logger LOGGER = Logger.getLogger(AbstractNode.class.getName()); private final AccountDeviceInstance accountDeviceInstance; @@ -102,7 +106,7 @@ class AccountNode extends AbstractNode { msgCount = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().getRelationshipsCount(filter, accountDeviceInstance); } catch (TskCoreException ex) { - Exceptions.printStackTrace(ex); + LOGGER.log(Level.WARNING, "Failed to get message count for account", ex); //NON-NLS } properties.put(new NodeProperty<>("type", From a2c849b2d78a0ff9af9f052b18148b48564d4b6a Mon Sep 17 00:00:00 2001 From: millmanorama Date: Thu, 26 Oct 2017 13:24:34 +0200 Subject: [PATCH 038/127] tweak FiltersPanel --- .../autopsy/communications/FiltersPanel.form | 57 ++++++------ .../autopsy/communications/FiltersPanel.java | 87 ++++++++----------- 2 files changed, 67 insertions(+), 77 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.form b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.form index 8bf3f958de..a90676c49f 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.form +++ b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.form @@ -28,6 +28,11 @@ + + + + + @@ -37,24 +42,24 @@ - + - + - - + + + + - - - + @@ -108,20 +113,18 @@ - - - - - - - - - - - - - - + + + + + + + + + + + + @@ -130,13 +133,13 @@ - + - + @@ -206,23 +209,23 @@ - + - + - + - + diff --git a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java index fc46a7e0fa..3ed63bb53a 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java +++ b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java @@ -113,20 +113,7 @@ public class FiltersPanel extends javax.swing.JPanel { // //GEN-BEGIN:initComponents private void initComponents() { - jScrollPane1 = new javax.swing.JScrollPane(); jList1 = new javax.swing.JList<>(); - applyFiltersButton = new javax.swing.JButton(); - filtersTitleLabel = new javax.swing.JLabel(); - jPanel2 = new javax.swing.JPanel(); - accountTypePane = new javax.swing.JPanel(); - unCheckAllAccountTypesButton = new javax.swing.JButton(); - accountTypesLabel = new javax.swing.JLabel(); - checkAllAccountTypesButton = new javax.swing.JButton(); - jPanel3 = new javax.swing.JPanel(); - unCheckAllDevicesButton = new javax.swing.JButton(); - devicesLabel = new javax.swing.JLabel(); - checkAllDevicesButton = new javax.swing.JButton(); - devicesPane = new javax.swing.JPanel(); jList1.setModel(new javax.swing.AbstractListModel() { String[] strings = { "Item 1", "Item 2", "Item 3", "Item 4", "Item 5" }; @@ -135,6 +122,8 @@ public class FiltersPanel extends javax.swing.JPanel { }); jScrollPane1.setViewportView(jList1); + setPreferredSize(new java.awt.Dimension(256, 469)); + applyFiltersButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/communications/images/control-double.png"))); // NOI18N applyFiltersButton.setText(org.openide.util.NbBundle.getMessage(FiltersPanel.class, "FiltersPanel.applyFiltersButton.text")); // NOI18N applyFiltersButton.setHorizontalTextPosition(javax.swing.SwingConstants.LEADING); @@ -173,29 +162,27 @@ public class FiltersPanel extends javax.swing.JPanel { jPanel2Layout.setHorizontalGroup( jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel2Layout.createSequentialGroup() - .addComponent(accountTypePane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addContainerGap()) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel2Layout.createSequentialGroup() - .addComponent(accountTypesLabel) - .addGap(144, 144, 144)) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel2Layout.createSequentialGroup() - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(unCheckAllAccountTypesButton) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(checkAllAccountTypesButton) - .addContainerGap()) + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel2Layout.createSequentialGroup() + .addContainerGap(51, Short.MAX_VALUE) + .addComponent(unCheckAllAccountTypesButton) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(checkAllAccountTypesButton)) + .addComponent(accountTypesLabel) + .addComponent(accountTypePane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addGap(0, 0, 0)) ); jPanel2Layout.setVerticalGroup( jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel2Layout.createSequentialGroup() .addComponent(accountTypesLabel) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(accountTypePane, javax.swing.GroupLayout.DEFAULT_SIZE, 170, Short.MAX_VALUE) + .addComponent(accountTypePane, javax.swing.GroupLayout.DEFAULT_SIZE, 189, Short.MAX_VALUE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(checkAllAccountTypesButton) .addComponent(unCheckAllAccountTypesButton)) - .addContainerGap()) + .addGap(0, 0, 0)) ); unCheckAllDevicesButton.setText(org.openide.util.NbBundle.getMessage(FiltersPanel.class, "FiltersPanel.unCheckAllDevicesButton.text")); // NOI18N @@ -233,36 +220,36 @@ public class FiltersPanel extends javax.swing.JPanel { .addComponent(unCheckAllDevicesButton) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(checkAllDevicesButton))) - .addContainerGap()) + .addGap(0, 0, 0)) ); jPanel3Layout.setVerticalGroup( jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel3Layout.createSequentialGroup() - .addContainerGap() + .addGap(0, 0, 0) .addComponent(devicesLabel) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(devicesPane, javax.swing.GroupLayout.DEFAULT_SIZE, 67, Short.MAX_VALUE) + .addComponent(devicesPane, javax.swing.GroupLayout.DEFAULT_SIZE, 86, Short.MAX_VALUE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(checkAllDevicesButton) .addComponent(unCheckAllDevicesButton)) - .addContainerGap()) + .addGap(0, 0, 0)) ); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() .addContainerGap() - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(jPanel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jPanel3, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup() .addComponent(filtersTitleLabel) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(applyFiltersButton) - .addContainerGap()) - .addComponent(jPanel3, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(jPanel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))) + .addComponent(applyFiltersButton))) + .addContainerGap()) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) @@ -353,19 +340,19 @@ public class FiltersPanel extends javax.swing.JPanel { // Variables declaration - do not modify//GEN-BEGIN:variables - private javax.swing.JPanel accountTypePane; - private javax.swing.JLabel accountTypesLabel; - private javax.swing.JButton applyFiltersButton; - private javax.swing.JButton checkAllAccountTypesButton; - private javax.swing.JButton checkAllDevicesButton; - private javax.swing.JLabel devicesLabel; - private javax.swing.JPanel devicesPane; - private javax.swing.JLabel filtersTitleLabel; + private final javax.swing.JPanel accountTypePane = new javax.swing.JPanel(); + private final javax.swing.JLabel accountTypesLabel = new javax.swing.JLabel(); + private final javax.swing.JButton applyFiltersButton = new javax.swing.JButton(); + private final javax.swing.JButton checkAllAccountTypesButton = new javax.swing.JButton(); + private final javax.swing.JButton checkAllDevicesButton = new javax.swing.JButton(); + private final javax.swing.JLabel devicesLabel = new javax.swing.JLabel(); + private final javax.swing.JPanel devicesPane = new javax.swing.JPanel(); + private final javax.swing.JLabel filtersTitleLabel = new javax.swing.JLabel(); private javax.swing.JList jList1; - private javax.swing.JPanel jPanel2; - private javax.swing.JPanel jPanel3; - private javax.swing.JScrollPane jScrollPane1; - private javax.swing.JButton unCheckAllAccountTypesButton; - private javax.swing.JButton unCheckAllDevicesButton; + private final javax.swing.JPanel jPanel2 = new javax.swing.JPanel(); + private final javax.swing.JPanel jPanel3 = new javax.swing.JPanel(); + private final javax.swing.JScrollPane jScrollPane1 = new javax.swing.JScrollPane(); + private final javax.swing.JButton unCheckAllAccountTypesButton = new javax.swing.JButton(); + private final javax.swing.JButton unCheckAllDevicesButton = new javax.swing.JButton(); // End of variables declaration//GEN-END:variables } From a369fd8f432fffb26a3a0e8d71022502ddd3a06e Mon Sep 17 00:00:00 2001 From: millmanorama Date: Thu, 26 Oct 2017 14:14:31 +0200 Subject: [PATCH 039/127] change the way the filters are populated to prevent duplicates --- .../communications/CVTTopComponent.form | 3 + .../communications/CVTTopComponent.java | 1 + .../autopsy/communications/FiltersPanel.form | 15 ++--- .../autopsy/communications/FiltersPanel.java | 64 ++++++++++--------- 4 files changed, 44 insertions(+), 39 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.form b/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.form index e8b2877724..09ebfc73f0 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.form +++ b/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.form @@ -154,6 +154,9 @@ + + +
diff --git a/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java b/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java index 1d64eebc4b..616b6afd21 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java +++ b/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java @@ -101,6 +101,7 @@ public final class CVTTopComponent extends TopComponent implements ExplorerManag HSplitPane.setRightComponent(VSplitPane); filtersPane.setBorder(javax.swing.BorderFactory.createEtchedBorder()); + filtersPane.setMinimumSize(new java.awt.Dimension(256, 495)); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); diff --git a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.form b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.form index a90676c49f..e020c001a1 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.form +++ b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.form @@ -199,17 +199,12 @@ + - - - - - - - - - - + + + + diff --git a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java index 3ed63bb53a..8517db0a29 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java +++ b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java @@ -55,22 +55,28 @@ public class FiltersPanel extends javax.swing.JPanel { public FiltersPanel() { initComponents(); + populateAccountTypeFilter(); + populateDeviceFilter(); + } - /* - * Populate the Account Types filter widgets - * - * - * TODO: something like this commented code could be used to show only - * the account types that are found: - * - * final CommunicationsManager communicationsManager = - * Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager(); - * List accountTypesInUse = - * communicationsManager.getAccountTypesInUse(); - * accountTypesInUSe.forEach(....) - */ + @Override + public void addNotify() { + super.addNotify(); + em = ExplorerManager.find(this); + } + + /** + * Populate the Account Types filter widgets + */ + private void populateAccountTypeFilter() { + + //TODO: something like this commented code could be used to show only + //the account types that are found: + //final CommunicationsManager communicationsManager = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager(); + //List accountTypesInUse = communicationsManager.getAccountTypesInUse(); + //accountTypesInUSe.forEach(...) Account.Type.PREDEFINED_ACCOUNT_TYPES.forEach( - type -> { + type -> accountTypeMap.computeIfAbsent(type, t -> { final JCheckBox jCheckBox = new JCheckBox( "
{ + final List dataSources = Case.getCurrentCase().getSleuthkitCase().getDataSources(); + dataSources.forEach( + dataSource -> devicesMap.computeIfAbsent(dataSource, ds -> { final JCheckBox jCheckBox = new JCheckBox(dataSource.getDeviceId(), true); devicesPane.add(jCheckBox); - devicesMap.put(dataSource, jCheckBox); - }); + return jCheckBox; + }) + ); + } catch (IllegalStateException ex) { + logger.log(Level.WARNING, "Communications Visualization Tool opened with no open case.", ex); } catch (TskCoreException tskCoreException) { logger.log(Level.SEVERE, "There was a error loading the datasources for the case.", tskCoreException); } - } /** From d6a2f5b6ca5d841a4c4d22c1e4750d0944049ec3 Mon Sep 17 00:00:00 2001 From: Raman Date: Thu, 26 Oct 2017 08:15:04 -0400 Subject: [PATCH 040/127] Renamed AccountsNode/AccountsNodeChildren to AccountDeviceInstanceNode/AccountDevicesInstancesNodeChildren. --- .../{AccountNode.java => AccountDeviceInstanceNode.java} | 4 ++-- ...ldren.java => AccountDeviceInstancesNodeChildren.java} | 8 ++++---- .../sleuthkit/autopsy/communications/CVTTopComponent.java | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) rename Core/src/org/sleuthkit/autopsy/communications/{AccountNode.java => AccountDeviceInstanceNode.java} (97%) rename Core/src/org/sleuthkit/autopsy/communications/{AccountsNodeChildren.java => AccountDeviceInstancesNodeChildren.java} (85%) diff --git a/Core/src/org/sleuthkit/autopsy/communications/AccountNode.java b/Core/src/org/sleuthkit/autopsy/communications/AccountDeviceInstanceNode.java similarity index 97% rename from Core/src/org/sleuthkit/autopsy/communications/AccountNode.java rename to Core/src/org/sleuthkit/autopsy/communications/AccountDeviceInstanceNode.java index 0b8d7af61c..d149884200 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/AccountNode.java +++ b/Core/src/org/sleuthkit/autopsy/communications/AccountDeviceInstanceNode.java @@ -36,13 +36,13 @@ import org.sleuthkit.datamodel.TskCoreException; /** * Node to represent an Account in the AccountsBrowser */ -class AccountNode extends AbstractNode { +class AccountDeviceInstanceNode extends AbstractNode { private static final Logger LOGGER = Logger.getLogger(AbstractNode.class.getName()); private final AccountDeviceInstance accountDeviceInstance; - AccountNode(AccountDeviceInstance accountDeviceInstance) { + AccountDeviceInstanceNode(AccountDeviceInstance accountDeviceInstance) { super(Children.LEAF, Lookups.fixed(accountDeviceInstance)); this.accountDeviceInstance = accountDeviceInstance; setName(accountDeviceInstance.getAccount().getAccountUniqueID()); diff --git a/Core/src/org/sleuthkit/autopsy/communications/AccountsNodeChildren.java b/Core/src/org/sleuthkit/autopsy/communications/AccountDeviceInstancesNodeChildren.java similarity index 85% rename from Core/src/org/sleuthkit/autopsy/communications/AccountsNodeChildren.java rename to Core/src/org/sleuthkit/autopsy/communications/AccountDeviceInstancesNodeChildren.java index 07e9335d5c..03c28c4c13 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/AccountsNodeChildren.java +++ b/Core/src/org/sleuthkit/autopsy/communications/AccountDeviceInstancesNodeChildren.java @@ -24,11 +24,11 @@ import org.openide.nodes.Children; import org.openide.nodes.Node; import org.sleuthkit.datamodel.AccountDeviceInstance; -class AccountsNodeChildren extends Children.Keys { +class AccountDeviceInstancesNodeChildren extends Children.Keys { private final List accountDeviceInstances; - AccountsNodeChildren(List accountDeviceInstances) { + AccountDeviceInstancesNodeChildren(List accountDeviceInstances) { super(true); this.accountDeviceInstances = accountDeviceInstances; } @@ -54,10 +54,10 @@ class AccountsNodeChildren extends Children.Keys { // // @Override // protected Node createNodeForKey(Account key) { - // return new AccountNode(key); + // return new AccountDeviceInstanceNode(key); // } @Override protected Node[] createNodes(AccountDeviceInstance key) { - return new Node[]{new AccountNode(key)}; + return new Node[]{new AccountDeviceInstanceNode(key)}; } } diff --git a/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java b/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java index d9a8382052..41ce371bec 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java +++ b/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java @@ -167,7 +167,7 @@ public final class CVTTopComponent extends TopComponent implements ExplorerManag final CommunicationsManager communicationsManager = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager(); accountDeviceInstances.addAll(communicationsManager.getAccountDeviceInstancesWithRelationships(null)); - em.setRootContext(new AbstractNode(new AccountsNodeChildren(accountDeviceInstances))); + em.setRootContext(new AbstractNode(new AccountDeviceInstancesNodeChildren(accountDeviceInstances))); } catch (TskCoreException ex) { Exceptions.printStackTrace(ex); } From ffec373c06f24f8908bbb2a9c1bb18160b92e86f Mon Sep 17 00:00:00 2001 From: millmanorama Date: Thu, 26 Oct 2017 14:42:23 +0200 Subject: [PATCH 041/127] use deviceIDs rather DataSources as keys in the map since DataSources don't implement equals --- .../communications/CVTTopComponent.java | 6 ++++++ .../autopsy/communications/FiltersPanel.java | 21 ++++++++++++------- 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java b/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java index 616b6afd21..5c766b8d57 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java +++ b/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java @@ -147,6 +147,12 @@ public final class CVTTopComponent extends TopComponent implements ExplorerManag return em; } + @Override + public void open() { + super.open(); + filtersPane.updateFilters(); + } + @Override public List availableModes(List modes) { /* diff --git a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java index 8517db0a29..d2e95cdd5d 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java +++ b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java @@ -22,6 +22,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Map.Entry; import java.util.logging.Level; import java.util.stream.Collectors; import javax.swing.JCheckBox; @@ -41,7 +42,7 @@ import org.sleuthkit.datamodel.TskCoreException; /** * */ -public class FiltersPanel extends javax.swing.JPanel { +final public class FiltersPanel extends javax.swing.JPanel { private static final Logger logger = Logger.getLogger(FiltersPanel.class.getName()); private static final long serialVersionUID = 1L; @@ -51,12 +52,16 @@ public class FiltersPanel extends javax.swing.JPanel { @ThreadConfined(type = ThreadConfined.ThreadType.AWT) private final Map accountTypeMap = new HashMap<>(); @ThreadConfined(type = ThreadConfined.ThreadType.AWT) - private final Map devicesMap = new HashMap<>(); + private final Map devicesMap = new HashMap<>(); public FiltersPanel() { initComponents(); - populateAccountTypeFilter(); - populateDeviceFilter(); + updateFilters(); + } + + void updateFilters() { + updateAccountTypeFilter(); + updateDeviceFilter(); } @Override @@ -68,7 +73,7 @@ public class FiltersPanel extends javax.swing.JPanel { /** * Populate the Account Types filter widgets */ - private void populateAccountTypeFilter() { + private void updateAccountTypeFilter() { //TODO: something like this commented code could be used to show only //the account types that are found: @@ -93,11 +98,11 @@ public class FiltersPanel extends javax.swing.JPanel { /** * Populate the devices filter widgets */ - private void populateDeviceFilter() { + private void updateDeviceFilter() { try { final List dataSources = Case.getCurrentCase().getSleuthkitCase().getDataSources(); dataSources.forEach( - dataSource -> devicesMap.computeIfAbsent(dataSource, ds -> { + dataSource -> devicesMap.computeIfAbsent(dataSource.getDeviceId(), ds -> { final JCheckBox jCheckBox = new JCheckBox(dataSource.getDeviceId(), true); devicesPane.add(jCheckBox); return jCheckBox; @@ -303,7 +308,7 @@ public class FiltersPanel extends javax.swing.JPanel { private DeviceFilter getDevceFilter() { DeviceFilter deviceFilter = new DeviceFilter(devicesMap.entrySet().stream() .filter(entry -> entry.getValue().isSelected()) - .map(entry -> entry.getKey().getDeviceId()).collect(Collectors.toSet())); + .map(Entry::getKey).collect(Collectors.toSet())); return deviceFilter; } From e3591dbec96d4a4b5f9e6f2c6f4263c19657aa9e Mon Sep 17 00:00:00 2001 From: millmanorama Date: Thu, 26 Oct 2017 15:01:40 +0200 Subject: [PATCH 042/127] don't shown credit cards or device in the account type filter widget --- .../autopsy/communications/FiltersPanel.java | 30 ++++++++++++------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java index d2e95cdd5d..53a973eede 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java +++ b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java @@ -81,17 +81,25 @@ final public class FiltersPanel extends javax.swing.JPanel { //List accountTypesInUse = communicationsManager.getAccountTypesInUse(); //accountTypesInUSe.forEach(...) Account.Type.PREDEFINED_ACCOUNT_TYPES.forEach( - type -> accountTypeMap.computeIfAbsent(type, t -> { - final JCheckBox jCheckBox = new JCheckBox( - "
" + type.getDisplayName() + "
", - true - ); - accountTypePane.add(jCheckBox); - return jCheckBox; - }) + type -> { + if (type.equals(Account.Type.CREDIT_CARD)) { + //don't show a check box for credit cards + } else if (type.equals(Account.Type.DEVICE)) { + //don't show a check box fro device + } else { + accountTypeMap.computeIfAbsent(type, t -> { + final JCheckBox jCheckBox = new JCheckBox( + "
" + type.getDisplayName() + "
", + true + ); + accountTypePane.add(jCheckBox); + return jCheckBox; + }); + } + } ); } From d1412498ce00eecae47b13e4abf503827230f552 Mon Sep 17 00:00:00 2001 From: millmanorama Date: Thu, 26 Oct 2017 17:23:49 +0200 Subject: [PATCH 043/127] remove unused method --- .../communications/CVTTopComponent.java | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java b/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java index d7d4a118e7..c4b5721911 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java +++ b/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java @@ -125,24 +125,6 @@ public final class CVTTopComponent extends TopComponent implements ExplorerManag ); }// //GEN-END:initComponents - private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed - /* - * When the apply button is pressed, query for accounts using the - * selected filters, and send the results to the AccountsBrowser via the - * ExplorerManager - */ - try { - List accountDeviceInstances = new ArrayList<>(); - - final CommunicationsManager communicationsManager = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager(); - accountDeviceInstances.addAll(communicationsManager.getAccountDeviceInstancesWithRelationships(null)); - - em.setRootContext(new AbstractNode(new AccountDeviceInstancesNodeChildren(accountDeviceInstances))); - } catch (TskCoreException ex) { - Exceptions.printStackTrace(ex); - } - - }//GEN-LAST:event_jButton1ActionPerformed // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JTabbedPane BrowseVisualizeTabPane; From 924babd2ec677e701790e2d69f6c8a72fced3588 Mon Sep 17 00:00:00 2001 From: Raman Date: Thu, 26 Oct 2017 16:01:15 -0400 Subject: [PATCH 044/127] 866: Milestone 2 - Filter panel has device and account type filters --- .../autopsy/communications/FiltersPanel.java | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java index 53a973eede..4ed80b63e9 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java +++ b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java @@ -37,6 +37,7 @@ import org.sleuthkit.datamodel.CommunicationsFilter; import org.sleuthkit.datamodel.CommunicationsManager; import org.sleuthkit.datamodel.DataSource; import org.sleuthkit.datamodel.DeviceFilter; +import org.sleuthkit.datamodel.AccountTypeFilter; import org.sleuthkit.datamodel.TskCoreException; /** @@ -302,8 +303,7 @@ final public class FiltersPanel extends javax.swing.JPanel { CommunicationsFilter commsFilter = new CommunicationsFilter(); commsFilter.addAndFilter(getDevceFilter()); - //TODO: uncomment and correct this one AccountTypeFilter is in place - //commsFilter.addAndFilter(getAccountTypeFilter()); + commsFilter.addAndFilter(getAccountTypeFilter()); final CommunicationsManager communicationsManager = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager(); accountDeviceInstances.addAll(communicationsManager.getAccountDeviceInstancesWithRelationships(commsFilter)); @@ -320,13 +320,13 @@ final public class FiltersPanel extends javax.swing.JPanel { return deviceFilter; } - //TODO: uncomment and correct this one AccountTypeFilter is in place - //private AccountTypeFilter getAccountTypeFilter() { - // AccountTypeFilter accountTypeFilter = new AccountTypeFilter(accountTypeMap.entrySet().stream() - // .filter(entry -> entry.getValue().isSelected()) - // .map(entry -> entry.getKey()).collect(Collectors.toSet())); - // return accountTypeFilter; - //} + private AccountTypeFilter getAccountTypeFilter() { + AccountTypeFilter accountTypeFilter = new AccountTypeFilter(accountTypeMap.entrySet().stream() + .filter(entry -> entry.getValue().isSelected()) + .map(entry -> entry.getKey()).collect(Collectors.toSet())); + return accountTypeFilter; + } + @ThreadConfined(type = ThreadConfined.ThreadType.AWT) private void setAllTypesSelected(boolean selected) { setAllSelected(accountTypeMap, selected); From b6b9783a63497a1a6c1398a22fb4cdd3a90e00ac Mon Sep 17 00:00:00 2001 From: millmanorama Date: Fri, 27 Oct 2017 13:39:18 +0200 Subject: [PATCH 045/127] begin hookup of ResultPanel in CVT --- .../autopsy/communications/Bundle.properties | 2 - .../communications/CVTTopComponent.form | 45 +------------- .../communications/CVTTopComponent.java | 40 ++++++------- .../communications/MessageBrowser.form | 44 ++++++++++++++ .../communications/MessageBrowser.java | 58 +++++++++++++++++++ .../corecomponents/DataResultPanel.java | 23 ++------ .../corecomponents/DataResultViewerTable.java | 2 +- 7 files changed, 129 insertions(+), 85 deletions(-) create mode 100644 Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.form create mode 100644 Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.java diff --git a/Core/src/org/sleuthkit/autopsy/communications/Bundle.properties b/Core/src/org/sleuthkit/autopsy/communications/Bundle.properties index 99621e3e12..9e5cf923e1 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/communications/Bundle.properties @@ -1,5 +1,3 @@ -CVTTopComponent.jTextField1.text=place holder for messages ,thumbnail list, etc -CVTTopComponent.jTextField2.text=place holder for message viewer CVTTopComponent.TabConstraints.tabTitle=Visualize CVTTopComponent.accountsBrowser.TabConstraints.tabTitle=Browse FiltersPanel.applyFiltersButton.text=Apply Filters diff --git a/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.form b/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.form index 09ebfc73f0..82be39bf3d 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.form +++ b/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.form @@ -20,7 +20,7 @@ - + @@ -31,7 +31,7 @@ - + @@ -39,7 +39,7 @@ - + @@ -106,45 +106,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java b/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java index c4b5721911..5bc19cf2fe 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java +++ b/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java @@ -18,6 +18,7 @@ */ package org.sleuthkit.autopsy.communications; +import java.beans.PropertyChangeEvent; import java.util.List; import java.util.stream.Collectors; import org.openide.explorer.ExplorerManager; @@ -44,10 +45,20 @@ public final class CVTTopComponent extends TopComponent implements ExplorerManag @ThreadConfined(type = ThreadConfined.ThreadType.AWT) private final ExplorerManager em = new ExplorerManager(); + private final ExplorerManager messageExplorerManager; public CVTTopComponent() { initComponents(); setName(Bundle.CVTTopComponent_name()); + messageExplorerManager = new ExplorerManager(); + splitPane.setRightComponent(new MessageBrowser(messageExplorerManager)); + + em.addPropertyChangeListener((PropertyChangeEvent evt) -> { + if (evt.getPropertyName().equals(ExplorerManager.PROP_SELECTED_NODES)) { + + messageExplorerManager.setRootContext(em.getSelectedNodes()[0]); + } + }); } /** @@ -58,16 +69,13 @@ public final class CVTTopComponent extends TopComponent implements ExplorerManag // //GEN-BEGIN:initComponents private void initComponents() { - HSplitPane = new javax.swing.JSplitPane(); + splitPane = new javax.swing.JSplitPane(); BrowseVisualizeTabPane = new javax.swing.JTabbedPane(); accountsBrowser = new org.sleuthkit.autopsy.communications.AccountsBrowser(); jPanel1 = new javax.swing.JPanel(); - VSplitPane = new javax.swing.JSplitPane(); - jTextField1 = new javax.swing.JTextField(); - jTextField2 = new javax.swing.JTextField(); filtersPane = new org.sleuthkit.autopsy.communications.FiltersPanel(); - HSplitPane.setDividerLocation(600); + splitPane.setDividerLocation(600); BrowseVisualizeTabPane.setFont(new java.awt.Font("Tahoma", 0, 18)); // NOI18N BrowseVisualizeTabPane.addTab(org.openide.util.NbBundle.getMessage(CVTTopComponent.class, "CVTTopComponent.accountsBrowser.TabConstraints.tabTitle"), new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/communications/images/table.png")), accountsBrowser); // NOI18N @@ -87,18 +95,7 @@ public final class CVTTopComponent extends TopComponent implements ExplorerManag BrowseVisualizeTabPane.addTab(org.openide.util.NbBundle.getMessage(CVTTopComponent.class, "CVTTopComponent.TabConstraints.tabTitle"), new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/communications/images/emblem-web.png")), jPanel1); // NOI18N - HSplitPane.setLeftComponent(BrowseVisualizeTabPane); - - VSplitPane.setDividerLocation(200); - VSplitPane.setOrientation(javax.swing.JSplitPane.VERTICAL_SPLIT); - - jTextField1.setText(org.openide.util.NbBundle.getMessage(CVTTopComponent.class, "CVTTopComponent.jTextField1.text")); // NOI18N - VSplitPane.setTopComponent(jTextField1); - - jTextField2.setText(org.openide.util.NbBundle.getMessage(CVTTopComponent.class, "CVTTopComponent.jTextField2.text")); // NOI18N - VSplitPane.setRightComponent(jTextField2); - - HSplitPane.setRightComponent(VSplitPane); + splitPane.setLeftComponent(BrowseVisualizeTabPane); filtersPane.setBorder(javax.swing.BorderFactory.createEtchedBorder()); filtersPane.setMinimumSize(new java.awt.Dimension(256, 495)); @@ -111,7 +108,7 @@ public final class CVTTopComponent extends TopComponent implements ExplorerManag .addContainerGap() .addComponent(filtersPane, javax.swing.GroupLayout.PREFERRED_SIZE, 244, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(HSplitPane, javax.swing.GroupLayout.DEFAULT_SIZE, 1322, Short.MAX_VALUE) + .addComponent(splitPane, javax.swing.GroupLayout.DEFAULT_SIZE, 1322, Short.MAX_VALUE) .addContainerGap()) ); layout.setVerticalGroup( @@ -120,7 +117,7 @@ public final class CVTTopComponent extends TopComponent implements ExplorerManag .addContainerGap() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(filtersPane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(HSplitPane)) + .addComponent(splitPane)) .addContainerGap()) ); }// //GEN-END:initComponents @@ -128,13 +125,10 @@ public final class CVTTopComponent extends TopComponent implements ExplorerManag // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JTabbedPane BrowseVisualizeTabPane; - private javax.swing.JSplitPane HSplitPane; - private javax.swing.JSplitPane VSplitPane; private org.sleuthkit.autopsy.communications.AccountsBrowser accountsBrowser; private org.sleuthkit.autopsy.communications.FiltersPanel filtersPane; private javax.swing.JPanel jPanel1; - private javax.swing.JTextField jTextField1; - private javax.swing.JTextField jTextField2; + private javax.swing.JSplitPane splitPane; // End of variables declaration//GEN-END:variables @Override diff --git a/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.form b/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.form new file mode 100644 index 0000000000..148bd68314 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.form @@ -0,0 +1,44 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.java b/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.java new file mode 100644 index 0000000000..1f6abece25 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.java @@ -0,0 +1,58 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package org.sleuthkit.autopsy.communications; + +import org.openide.explorer.ExplorerManager; + +final class MessageBrowser extends javax.swing.JPanel implements ExplorerManager.Provider { + + private final ExplorerManager em; + + MessageBrowser(ExplorerManager em) { + this.em = em; + +splitPane } + + /** + * This method is called from within the constructor to initialize the form. + * WARNING: Do NOT modify this code. The content of this method is always + * regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // //GEN-BEGIN:initComponents + private void initComponents() { + + splitPane = new javax.swing.JSplitPane(); + + splitPane.setOrientation(javax.swing.JSplitPane.VERTICAL_SPLIT); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addGap(0, 0, 0) + .addComponent(splitPane, javax.swing.GroupLayout.DEFAULT_SIZE, 306, Short.MAX_VALUE)) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addGap(0, 0, 0) + .addComponent(splitPane, javax.swing.GroupLayout.DEFAULT_SIZE, 271, Short.MAX_VALUE) + .addGap(0, 0, 0)) + ); + }// //GEN-END:initComponents + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JSplitPane splitPane; + // End of variables declaration//GEN-END:variables + + @Override + public ExplorerManager getExplorerManager() { + return em; + } +} diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultPanel.java b/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultPanel.java index 34397cf960..e5252e035b 100755 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultPanel.java +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultPanel.java @@ -22,6 +22,7 @@ import java.awt.Cursor; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import javax.swing.JTabbedPane; import javax.swing.SwingUtilities; @@ -260,11 +261,7 @@ public class DataResultPanel extends javax.swing.JPanel implements DataResult, C */ @Override public List getViewers() { - List viewers = new ArrayList<>(); - resultViewers.forEach((viewer) -> { - viewers.add(viewer); - }); - return viewers; + return Collections.unmodifiableList(resultViewers); } /** @@ -397,9 +394,7 @@ public class DataResultPanel extends javax.swing.JPanel implements DataResult, C * @param selectedNodes The nodes to be selected. */ public void setSelectedNodes(Node[] selectedNodes) { - this.resultViewers.forEach((viewer) -> { - viewer.setSelectedNodes(selectedNodes); - }); + this.resultViewers.forEach((viewer) -> viewer.setSelectedNodes(selectedNodes)); } /** @@ -517,14 +512,10 @@ public class DataResultPanel extends javax.swing.JPanel implements DataResult, C explorerManager = null; } - this.resultViewers.forEach((viewer) -> { - viewer.setNode(null); - }); + this.resultViewers.forEach((viewer) -> viewer.setNode(null)); if (!this.isMain) { - this.resultViewers.forEach((viewer) -> { - viewer.clearComponent(); - }); + this.resultViewers.forEach(DataResultViewer::clearComponent); this.directoryTablePath.removeAll(); this.directoryTablePath = null; this.numberMatchLabel.removeAll(); @@ -563,9 +554,7 @@ public class DataResultPanel extends javax.swing.JPanel implements DataResult, C * Pass the selected nodes to all of the result viewers * sharing this explorer manager. */ - resultViewers.forEach((viewer) -> { - viewer.setSelectedNodes(selectedNodes); - }); + resultViewers.forEach((viewer) -> viewer.setSelectedNodes(selectedNodes)); /* * Passing null signals that either multiple nodes are diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerTable.java b/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerTable.java index e922e74c4f..c09ebc92f3 100755 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerTable.java +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerTable.java @@ -764,7 +764,7 @@ public class DataResultViewerTable extends AbstractDataResultViewer { Component component = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, col); // only override the color if a node is not selected - if (!isSelected) { + if (currentRoot != null && !isSelected) { Node node = currentRoot.getChildren().getNodeAt(table.convertRowIndexToModel(row)); boolean tagFound = false; if (node != null) { From 2656f47e3496b992e4321d4acb89e13ca2660a84 Mon Sep 17 00:00:00 2001 From: Raman Date: Fri, 27 Oct 2017 15:49:53 -0400 Subject: [PATCH 046/127] 866: Filter (panel) has device and account type filters - Apply filters to getting the relationships count. --- .../AccountDeviceInstanceKey.java | 46 +++++++++++++++++++ .../AccountDeviceInstanceNode.java | 11 ++--- .../AccountDeviceInstancesNodeChildren.java | 15 +++--- .../AccountsDeviceInstanceChildren.java | 15 +++--- .../autopsy/communications/FiltersPanel.java | 7 ++- 5 files changed, 71 insertions(+), 23 deletions(-) create mode 100644 Core/src/org/sleuthkit/autopsy/communications/AccountDeviceInstanceKey.java diff --git a/Core/src/org/sleuthkit/autopsy/communications/AccountDeviceInstanceKey.java b/Core/src/org/sleuthkit/autopsy/communications/AccountDeviceInstanceKey.java new file mode 100644 index 0000000000..435d738145 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/communications/AccountDeviceInstanceKey.java @@ -0,0 +1,46 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2011-2017 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.sleuthkit.autopsy.communications; + +import org.sleuthkit.datamodel.AccountDeviceInstance; +import org.sleuthkit.datamodel.CommunicationsFilter; + +/** + * Key for AccountDeviceInstance node. + * + * Encapsulates a AccountDeviceInstance, and CommunicationsFilter + */ +public class AccountDeviceInstanceKey { + + private final AccountDeviceInstance accountDeviceInstance; + private final CommunicationsFilter filter; + + AccountDeviceInstanceKey(AccountDeviceInstance accountDeviceInstance, CommunicationsFilter filter) { + this.accountDeviceInstance = accountDeviceInstance; + this.filter = filter; + } + + AccountDeviceInstance getAccountDeviceInstance() { + return accountDeviceInstance; + } + + CommunicationsFilter getCommunicationsFilter() { + return filter; + } +} diff --git a/Core/src/org/sleuthkit/autopsy/communications/AccountDeviceInstanceNode.java b/Core/src/org/sleuthkit/autopsy/communications/AccountDeviceInstanceNode.java index 721adcc300..e859765d55 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/AccountDeviceInstanceNode.java +++ b/Core/src/org/sleuthkit/autopsy/communications/AccountDeviceInstanceNode.java @@ -38,10 +38,13 @@ class AccountDeviceInstanceNode extends AbstractNode { private static final Logger LOGGER = Logger.getLogger(AccountDeviceInstanceNode.class.getName()); private final AccountDeviceInstance accountDeviceInstance; + private final CommunicationsFilter filter; - AccountDeviceInstanceNode(AccountDeviceInstance accountDeviceInstance) { + AccountDeviceInstanceNode(AccountDeviceInstance accountDeviceInstance, CommunicationsFilter filter) { super(Children.LEAF, Lookups.fixed(accountDeviceInstance)); this.accountDeviceInstance = accountDeviceInstance; + this.filter = filter; + setName(accountDeviceInstance.getAccount().getAccountUniqueID()); setIconBaseWithExtension("org/sleuthkit/autopsy/communications/images/" + AccountUtils.getIconFileName(accountDeviceInstance.getAccount().getAccountType())); @@ -61,13 +64,9 @@ class AccountDeviceInstanceNode extends AbstractNode { s.put(properties); } - // RAMAN TBD: need to figure out how to get the right filters here - // We talked about either creating a wrapper class around AccountDeviceInstance to push the selected filters - // Or some kind of static access to pull the selected filters long msgCount = 0; try { - CommunicationsFilter filter = null; - msgCount = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().getRelationshipsCount(filter, accountDeviceInstance); + msgCount = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().getRelationshipsCount(this.filter, accountDeviceInstance); } catch (TskCoreException ex) { LOGGER.log(Level.WARNING, "Failed to get message count for account", ex); //NON-NLS } diff --git a/Core/src/org/sleuthkit/autopsy/communications/AccountDeviceInstancesNodeChildren.java b/Core/src/org/sleuthkit/autopsy/communications/AccountDeviceInstancesNodeChildren.java index 03c28c4c13..916fc6d933 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/AccountDeviceInstancesNodeChildren.java +++ b/Core/src/org/sleuthkit/autopsy/communications/AccountDeviceInstancesNodeChildren.java @@ -22,15 +22,14 @@ import java.util.Collections; import java.util.List; import org.openide.nodes.Children; import org.openide.nodes.Node; -import org.sleuthkit.datamodel.AccountDeviceInstance; -class AccountDeviceInstancesNodeChildren extends Children.Keys { +class AccountDeviceInstancesNodeChildren extends Children.Keys { - private final List accountDeviceInstances; + private final List accountDeviceInstanceKeys; - AccountDeviceInstancesNodeChildren(List accountDeviceInstances) { + AccountDeviceInstancesNodeChildren(List accountDeviceInstanceKeys) { super(true); - this.accountDeviceInstances = accountDeviceInstances; + this.accountDeviceInstanceKeys = accountDeviceInstanceKeys; } @Override @@ -42,7 +41,7 @@ class AccountDeviceInstancesNodeChildren extends Children.Keys { +class AccountsDeviceInstanceChildren extends Children.Keys { - private final List accountDeviceInstances; + private final List accountDeviceInstanceKeys; - AccountsDeviceInstanceChildren(List accountDeviceInstances) { + AccountsDeviceInstanceChildren(List accountDeviceInstanceKeys) { super(true); - this.accountDeviceInstances = accountDeviceInstances; + this.accountDeviceInstanceKeys = accountDeviceInstanceKeys; } @Override @@ -42,7 +41,7 @@ class AccountsDeviceInstanceChildren extends Children.Keys accountDeviceInstanceKeys = new ArrayList<>(); + accountDeviceInstances.forEach((accountDevInstance) -> { + accountDeviceInstanceKeys.add(new AccountDeviceInstanceKey(accountDevInstance, commsFilter ) ); + }); + + em.setRootContext(new AbstractNode(new AccountsDeviceInstanceChildren(accountDeviceInstanceKeys))); } catch (TskCoreException ex) { logger.log(Level.SEVERE, "There was a error loading the accounts.", ex); } From 9a3d821c5cb4f40e6651552bc79a65714ba2ee9d Mon Sep 17 00:00:00 2001 From: Raman Date: Fri, 27 Oct 2017 15:53:56 -0400 Subject: [PATCH 047/127] Fixed Javadoc --- .../autopsy/communications/AccountDeviceInstanceKey.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/communications/AccountDeviceInstanceKey.java b/Core/src/org/sleuthkit/autopsy/communications/AccountDeviceInstanceKey.java index 435d738145..b2df68c542 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/AccountDeviceInstanceKey.java +++ b/Core/src/org/sleuthkit/autopsy/communications/AccountDeviceInstanceKey.java @@ -24,7 +24,7 @@ import org.sleuthkit.datamodel.CommunicationsFilter; /** * Key for AccountDeviceInstance node. * - * Encapsulates a AccountDeviceInstance, and CommunicationsFilter + * Encapsulates a AccountDeviceInstance, and CommunicationsFilter. */ public class AccountDeviceInstanceKey { From dd948ea878c5fe97d5fed8453d07a7ac10a5ce9e Mon Sep 17 00:00:00 2001 From: millmanorama Date: Mon, 30 Oct 2017 15:26:21 +0100 Subject: [PATCH 048/127] initial commit wiring up MessageBrowser --- .../communications/AccountDetailsNode.java | 84 ++++++++++++++++++ .../AccountDeviceInstanceNode.java | 10 ++- .../AccountDeviceInstancesNodeChildren.java | 63 -------------- .../AccountsDeviceInstanceChildren.java | 7 +- .../communications/CVTTopComponent.java | 13 +-- .../autopsy/communications/FiltersPanel.java | 4 +- .../communications/MessageBrowser.java | 85 +++++++++++++++++-- .../RelationShipFilterNode.java | 33 +++++++ 8 files changed, 209 insertions(+), 90 deletions(-) create mode 100644 Core/src/org/sleuthkit/autopsy/communications/AccountDetailsNode.java delete mode 100644 Core/src/org/sleuthkit/autopsy/communications/AccountDeviceInstancesNodeChildren.java create mode 100644 Core/src/org/sleuthkit/autopsy/communications/RelationShipFilterNode.java diff --git a/Core/src/org/sleuthkit/autopsy/communications/AccountDetailsNode.java b/Core/src/org/sleuthkit/autopsy/communications/AccountDetailsNode.java new file mode 100644 index 0000000000..8935864d0b --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/communications/AccountDetailsNode.java @@ -0,0 +1,84 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2011-2017 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.sleuthkit.autopsy.communications; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import org.openide.nodes.FilterNode; +import org.openide.nodes.Node; +import org.openide.util.Exceptions; +import org.sleuthkit.autopsy.datamodel.BlackboardArtifactNode; +import org.sleuthkit.datamodel.Account; +import org.sleuthkit.datamodel.AccountDeviceInstance; +import org.sleuthkit.datamodel.BlackboardArtifact; +import org.sleuthkit.datamodel.CommunicationsManager; +import org.sleuthkit.datamodel.TskCoreException; + +class AccountDetailsNode extends FilterNode { + + /** + * @param wrappedNode the value of selectedNode + */ + AccountDetailsNode(AccountDeviceInstanceNode wrappedNode) throws TskCoreException { + super(wrappedNode, new AccountRelationshipChildren(wrappedNode)); + } + + /** + * Children object for the relationships that the account is a member of. + */ + private static class AccountRelationshipChildren extends Children.Keys { + + private final AccountDeviceInstanceNode wrappedNode; + + private AccountRelationshipChildren(AccountDeviceInstanceNode wrappedNode) { + this.wrappedNode = wrappedNode; + } + + @Override + protected Node[] createNodes(BlackboardArtifact t) { + + final RelationShipFilterNode blackboardArtifactNode = new RelationShipFilterNode(new BlackboardArtifactNode(t)); + return new Node[]{blackboardArtifactNode}; + } + + @Override + protected void addNotify() { + try { + AccountDeviceInstance adi = wrappedNode.getLookup().lookup(AccountDeviceInstance.class); + CommunicationsManager communicationsManager = wrappedNode.getLookup().lookup(CommunicationsManager.class); + List accountsWithRelationship = communicationsManager.getAccountsWithRelationship(adi.getAccount()); + Set keys = new HashSet<>(); + + accountsWithRelationship.forEach(account -> { + try { + keys.addAll(communicationsManager.getRelationships(adi.getAccount(), account)); + } catch (TskCoreException ex) { + Exceptions.printStackTrace(ex); + } + }); + + setKeys(keys); + } catch (TskCoreException ex) { + //TODO: proper logging + Exceptions.printStackTrace(ex); + } + } + } +} diff --git a/Core/src/org/sleuthkit/autopsy/communications/AccountDeviceInstanceNode.java b/Core/src/org/sleuthkit/autopsy/communications/AccountDeviceInstanceNode.java index 721adcc300..4abd3b84d3 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/AccountDeviceInstanceNode.java +++ b/Core/src/org/sleuthkit/autopsy/communications/AccountDeviceInstanceNode.java @@ -25,10 +25,10 @@ import org.openide.nodes.Children; import org.openide.nodes.Sheet; import org.openide.util.NbBundle; import org.openide.util.lookup.Lookups; -import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.datamodel.NodeProperty; import org.sleuthkit.datamodel.AccountDeviceInstance; import org.sleuthkit.datamodel.CommunicationsFilter; +import org.sleuthkit.datamodel.CommunicationsManager; import org.sleuthkit.datamodel.TskCoreException; /** @@ -38,10 +38,12 @@ class AccountDeviceInstanceNode extends AbstractNode { private static final Logger LOGGER = Logger.getLogger(AccountDeviceInstanceNode.class.getName()); private final AccountDeviceInstance accountDeviceInstance; + private final CommunicationsManager commsManager; - AccountDeviceInstanceNode(AccountDeviceInstance accountDeviceInstance) { - super(Children.LEAF, Lookups.fixed(accountDeviceInstance)); + AccountDeviceInstanceNode(AccountDeviceInstance accountDeviceInstance, CommunicationsManager commsManager) { + super(Children.LEAF, Lookups.fixed(accountDeviceInstance, commsManager)); this.accountDeviceInstance = accountDeviceInstance; + this.commsManager = commsManager; setName(accountDeviceInstance.getAccount().getAccountUniqueID()); setIconBaseWithExtension("org/sleuthkit/autopsy/communications/images/" + AccountUtils.getIconFileName(accountDeviceInstance.getAccount().getAccountType())); @@ -67,7 +69,7 @@ class AccountDeviceInstanceNode extends AbstractNode { long msgCount = 0; try { CommunicationsFilter filter = null; - msgCount = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().getRelationshipsCount(filter, accountDeviceInstance); + msgCount = commsManager.getRelationshipsCount(filter, accountDeviceInstance); } catch (TskCoreException ex) { LOGGER.log(Level.WARNING, "Failed to get message count for account", ex); //NON-NLS } diff --git a/Core/src/org/sleuthkit/autopsy/communications/AccountDeviceInstancesNodeChildren.java b/Core/src/org/sleuthkit/autopsy/communications/AccountDeviceInstancesNodeChildren.java deleted file mode 100644 index 03c28c4c13..0000000000 --- a/Core/src/org/sleuthkit/autopsy/communications/AccountDeviceInstancesNodeChildren.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Autopsy Forensic Browser - * - * Copyright 2011-2017 Basis Technology Corp. - * Contact: carrier sleuthkit org - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.sleuthkit.autopsy.communications; - -import java.util.Collections; -import java.util.List; -import org.openide.nodes.Children; -import org.openide.nodes.Node; -import org.sleuthkit.datamodel.AccountDeviceInstance; - -class AccountDeviceInstancesNodeChildren extends Children.Keys { - - private final List accountDeviceInstances; - - AccountDeviceInstancesNodeChildren(List accountDeviceInstances) { - super(true); - this.accountDeviceInstances = accountDeviceInstances; - } - - @Override - protected void removeNotify() { - super.removeNotify(); - setKeys(Collections.emptySet()); - } - - @Override - protected void addNotify() { - super.addNotify(); - setKeys(accountDeviceInstances); - } - - //These are the methods for ChildFactory. I am going to keep them around but commented until we make a final descision. - // @Override - // protected boolean createKeys(List list) { - // list.addAll(accounts); - // return true; - // } - // - // @Override - // protected Node createNodeForKey(Account key) { - // return new AccountDeviceInstanceNode(key); - // } - @Override - protected Node[] createNodes(AccountDeviceInstance key) { - return new Node[]{new AccountDeviceInstanceNode(key)}; - } -} diff --git a/Core/src/org/sleuthkit/autopsy/communications/AccountsDeviceInstanceChildren.java b/Core/src/org/sleuthkit/autopsy/communications/AccountsDeviceInstanceChildren.java index 93856af02b..fe85f9d01d 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/AccountsDeviceInstanceChildren.java +++ b/Core/src/org/sleuthkit/autopsy/communications/AccountsDeviceInstanceChildren.java @@ -23,14 +23,17 @@ import java.util.List; import org.openide.nodes.Children; import org.openide.nodes.Node; import org.sleuthkit.datamodel.AccountDeviceInstance; +import org.sleuthkit.datamodel.CommunicationsManager; class AccountsDeviceInstanceChildren extends Children.Keys { private final List accountDeviceInstances; + private final CommunicationsManager commsManager; - AccountsDeviceInstanceChildren(List accountDeviceInstances) { + AccountsDeviceInstanceChildren(List accountDeviceInstances, CommunicationsManager commsManager) { super(true); this.accountDeviceInstances = accountDeviceInstances; + this.commsManager = commsManager; } @Override @@ -58,6 +61,6 @@ class AccountsDeviceInstanceChildren extends Children.Keys { - if (evt.getPropertyName().equals(ExplorerManager.PROP_SELECTED_NODES)) { - - messageExplorerManager.setRootContext(em.getSelectedNodes()[0]); - } - }); + splitPane.setRightComponent(new MessageBrowser()); } /** diff --git a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java index 4ed80b63e9..cd40ca445f 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java +++ b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java @@ -33,11 +33,11 @@ import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.ThreadConfined; import org.sleuthkit.datamodel.Account; import org.sleuthkit.datamodel.AccountDeviceInstance; +import org.sleuthkit.datamodel.AccountTypeFilter; import org.sleuthkit.datamodel.CommunicationsFilter; import org.sleuthkit.datamodel.CommunicationsManager; import org.sleuthkit.datamodel.DataSource; import org.sleuthkit.datamodel.DeviceFilter; -import org.sleuthkit.datamodel.AccountTypeFilter; import org.sleuthkit.datamodel.TskCoreException; /** @@ -307,7 +307,7 @@ final public class FiltersPanel extends javax.swing.JPanel { final CommunicationsManager communicationsManager = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager(); accountDeviceInstances.addAll(communicationsManager.getAccountDeviceInstancesWithRelationships(commsFilter)); - em.setRootContext(new AbstractNode(new AccountsDeviceInstanceChildren(accountDeviceInstances))); + em.setRootContext(new AbstractNode(new AccountsDeviceInstanceChildren(accountDeviceInstances, communicationsManager))); } catch (TskCoreException ex) { logger.log(Level.SEVERE, "There was a error loading the accounts.", ex); } diff --git a/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.java b/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.java index 1f6abece25..9da9dc04ec 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.java +++ b/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.java @@ -1,20 +1,89 @@ /* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. + * Autopsy Forensic Browser + * + * Copyright 2011-2017 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obt ain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package org.sleuthkit.autopsy.communications; +import java.beans.PropertyChangeEvent; import org.openide.explorer.ExplorerManager; +import org.openide.nodes.Node; +import org.openide.util.Exceptions; +import org.sleuthkit.autopsy.corecomponents.DataContentPanel; +import org.sleuthkit.autopsy.corecomponents.DataResultPanel; +import org.sleuthkit.autopsy.corecomponents.TableFilterNode; +import org.sleuthkit.datamodel.TskCoreException; +/** + * The right hand side of the CVT. Has a DataResultPanel to show messages and + * account details, and a Content viewer to show individual + */ final class MessageBrowser extends javax.swing.JPanel implements ExplorerManager.Provider { - private final ExplorerManager em; + private static final long serialVersionUID = 1L; - MessageBrowser(ExplorerManager em) { - this.em = em; + private ExplorerManager parentExplorereManager; + private final DataContentPanel customContentView; + private final DataResultPanel messagesResultPanel; + private ExplorerManager internalExplorerManager; -splitPane } + MessageBrowser() { + initComponents(); + customContentView = DataContentPanel.createInstance(); + messagesResultPanel = DataResultPanel.createInstanceUninitialized("Account", "", Node.EMPTY, 0, customContentView); + splitPane.setTopComponent(messagesResultPanel); + splitPane.setBottomComponent(customContentView); + + } + + @Override + public void addNotify() { + super.addNotify(); + this.parentExplorereManager = ExplorerManager.find(this); + + internalExplorerManager = new ExplorerManager(); + + parentExplorereManager.addPropertyChangeListener((PropertyChangeEvent evt) -> { + if (evt.getPropertyName().equals(ExplorerManager.PROP_SELECTED_NODES)) { + final Node[] selectedNodes = parentExplorereManager.getSelectedNodes(); + switch (selectedNodes.length) { + case 0: + messagesResultPanel.setNode(null); + break; + case 1: + final Node selectedNode = selectedNodes[0]; + if (selectedNode instanceof AccountDeviceInstanceNode) { + try { + final AccountDetailsNode accountDetailsNode = new AccountDetailsNode((AccountDeviceInstanceNode) selectedNode); + messagesResultPanel.setNode(new TableFilterNode(accountDetailsNode, true)); + } catch (TskCoreException ex) { + Exceptions.printStackTrace(ex); + } + } else { + internalExplorerManager.setRootContext(selectedNode); + } + break; + // TODO: fill in multiseelct support + default: + break; + } + } + }); + messagesResultPanel.open(); + } /** * This method is called from within the constructor to initialize the form. @@ -53,6 +122,6 @@ splitPane } @Override public ExplorerManager getExplorerManager() { - return em; + return internalExplorerManager; } } diff --git a/Core/src/org/sleuthkit/autopsy/communications/RelationShipFilterNode.java b/Core/src/org/sleuthkit/autopsy/communications/RelationShipFilterNode.java new file mode 100644 index 0000000000..8b0a7f53d5 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/communications/RelationShipFilterNode.java @@ -0,0 +1,33 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package org.sleuthkit.autopsy.communications; + +import org.openide.nodes.FilterNode; +import org.sleuthkit.autopsy.datamodel.BlackboardArtifactNode; + +/** + * + */ +public class RelationShipFilterNode extends FilterNode { + + private final BlackboardArtifactNode wrappedNode; + + public RelationShipFilterNode(BlackboardArtifactNode wrappedNode) { + super(wrappedNode, Children.LEAF); + this.wrappedNode = wrappedNode; + } + + @Override + public PropertySet[] getPropertySets() { + PropertySet[] propertySets = super.getPropertySets(); + for (PropertySet set : propertySets) { + for (Property p : set.getProperties()) { +// p.getName().equals(); + } + } + return propertySets; + } +} From 711a59db072d81fa7553177a8bc216abecb62c66 Mon Sep 17 00:00:00 2001 From: millmanorama Date: Mon, 30 Oct 2017 16:29:33 +0100 Subject: [PATCH 049/127] begin to suppress unneeded columns --- .../RelationShipFilterNode.java | 39 +++++++++++++++++-- 1 file changed, 36 insertions(+), 3 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/communications/RelationShipFilterNode.java b/Core/src/org/sleuthkit/autopsy/communications/RelationShipFilterNode.java index 8b0a7f53d5..b98eb431fd 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/RelationShipFilterNode.java +++ b/Core/src/org/sleuthkit/autopsy/communications/RelationShipFilterNode.java @@ -5,8 +5,13 @@ */ package org.sleuthkit.autopsy.communications; +import java.util.ArrayList; +import java.util.HashSet; import org.openide.nodes.FilterNode; +import org.openide.nodes.Sheet; import org.sleuthkit.autopsy.datamodel.BlackboardArtifactNode; +import org.sleuthkit.autopsy.datamodel.NodeProperty; +import org.sleuthkit.datamodel.BlackboardAttribute; /** * @@ -23,11 +28,39 @@ public class RelationShipFilterNode extends FilterNode { @Override public PropertySet[] getPropertySets() { PropertySet[] propertySets = super.getPropertySets(); + + HashSet suppressedPropertyNames = new HashSet<>(); + suppressedPropertyNames.add("Source File"); + suppressedPropertyNames.add("Data Source"); + suppressedPropertyNames.add("Path"); + suppressedPropertyNames.add("Message (Plaintext)"); + + ArrayList retPropSets = new ArrayList<>(); + boolean first = false; for (PropertySet set : propertySets) { - for (Property p : set.getProperties()) { -// p.getName().equals(); + Sheet.Set set1 = copySet(set); + if (first){ + first = false; + + String valueString = wrappedNode.getArtifact().getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_MESSAGE_TYPE)).getValueString(); + set1.put(new NodeProperty<>("Type", "Type", "Type", valueString)); } + + for (Property p : set.getProperties()) { + if (false == suppressedPropertyNames.contains(p.getName())) { + set1.put(p); + } + } + retPropSets.add(set1); } - return propertySets; + return retPropSets.toArray(new PropertySet[retPropSets.size()]); + } + + private Sheet.Set copySet(PropertySet set) { + Sheet.Set set1 = new Sheet.Set(); + set1.setName(set.getName()); + set1.setDisplayName(set.getDisplayName()); + set1.setShortDescription(set.getShortDescription()); + return set1; } } From 9df3f3229143aa7656286d244f92be9f1088ff63 Mon Sep 17 00:00:00 2001 From: millmanorama Date: Mon, 30 Oct 2017 16:45:17 +0100 Subject: [PATCH 050/127] suppress Message ID and tags, add relationship Type --- .../communications/RelationShipFilterNode.java | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/communications/RelationShipFilterNode.java b/Core/src/org/sleuthkit/autopsy/communications/RelationShipFilterNode.java index b98eb431fd..8d08c2e19a 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/RelationShipFilterNode.java +++ b/Core/src/org/sleuthkit/autopsy/communications/RelationShipFilterNode.java @@ -33,17 +33,19 @@ public class RelationShipFilterNode extends FilterNode { suppressedPropertyNames.add("Source File"); suppressedPropertyNames.add("Data Source"); suppressedPropertyNames.add("Path"); + suppressedPropertyNames.add("Message ID"); + suppressedPropertyNames.add("Tags"); suppressedPropertyNames.add("Message (Plaintext)"); ArrayList retPropSets = new ArrayList<>(); - boolean first = false; + boolean first = true; for (PropertySet set : propertySets) { Sheet.Set set1 = copySet(set); - if (first){ + if (first) { first = false; - - String valueString = wrappedNode.getArtifact().getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_MESSAGE_TYPE)).getValueString(); - set1.put(new NodeProperty<>("Type", "Type", "Type", valueString)); + + final String artifactTypeName = wrappedNode.getArtifact().getArtifactTypeName(); + set1.put(new NodeProperty<>("Type", "Type", "Type", artifactTypeName)); } for (Property p : set.getProperties()) { @@ -55,6 +57,7 @@ public class RelationShipFilterNode extends FilterNode { } return retPropSets.toArray(new PropertySet[retPropSets.size()]); } + private static final BlackboardAttribute.Type MSG_TYPE = new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_MESSAGE_TYPE); private Sheet.Set copySet(PropertySet set) { Sheet.Set set1 = new Sheet.Set(); From 3eae38f53b50b6d27a55a2941c7ec6bc7078ee91 Mon Sep 17 00:00:00 2001 From: millmanorama Date: Tue, 31 Oct 2017 15:21:17 +0100 Subject: [PATCH 051/127] suppress more columns --- .../RelationShipFilterNode.java | 28 ++++++++++--------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/communications/RelationShipFilterNode.java b/Core/src/org/sleuthkit/autopsy/communications/RelationShipFilterNode.java index 8d08c2e19a..42e7db75b9 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/RelationShipFilterNode.java +++ b/Core/src/org/sleuthkit/autopsy/communications/RelationShipFilterNode.java @@ -7,6 +7,7 @@ package org.sleuthkit.autopsy.communications; import java.util.ArrayList; import java.util.HashSet; +import org.apache.commons.lang3.StringUtils; import org.openide.nodes.FilterNode; import org.openide.nodes.Sheet; import org.sleuthkit.autopsy.datamodel.BlackboardArtifactNode; @@ -18,24 +19,27 @@ import org.sleuthkit.datamodel.BlackboardAttribute; */ public class RelationShipFilterNode extends FilterNode { - private final BlackboardArtifactNode wrappedNode; public RelationShipFilterNode(BlackboardArtifactNode wrappedNode) { super(wrappedNode, Children.LEAF); - this.wrappedNode = wrappedNode; + setDisplayName( StringUtils.stripEnd(wrappedNode.getArtifact().getDisplayName(),"s")); } @Override public PropertySet[] getPropertySets() { PropertySet[] propertySets = super.getPropertySets(); - HashSet suppressedPropertyNames = new HashSet<>(); - suppressedPropertyNames.add("Source File"); - suppressedPropertyNames.add("Data Source"); - suppressedPropertyNames.add("Path"); - suppressedPropertyNames.add("Message ID"); - suppressedPropertyNames.add("Tags"); - suppressedPropertyNames.add("Message (Plaintext)"); + HashSet propertyNames = new HashSet<>(); + propertyNames.add("Source File"); + propertyNames.add("Data Source"); + propertyNames.add("Path"); + propertyNames.add("Message ID"); + propertyNames.add("Tags"); + propertyNames.add("Text"); + propertyNames.add("Read"); + propertyNames.add("Directon"); + propertyNames.add("Name"); + propertyNames.add("Message (Plaintext)"); ArrayList retPropSets = new ArrayList<>(); boolean first = true; @@ -43,13 +47,11 @@ public class RelationShipFilterNode extends FilterNode { Sheet.Set set1 = copySet(set); if (first) { first = false; - - final String artifactTypeName = wrappedNode.getArtifact().getArtifactTypeName(); - set1.put(new NodeProperty<>("Type", "Type", "Type", artifactTypeName)); + set1.put(new NodeProperty<>("Type", "Type", "Type", getDisplayName())); } for (Property p : set.getProperties()) { - if (false == suppressedPropertyNames.contains(p.getName())) { + if (false == propertyNames.contains(p.getName())) { set1.put(p); } } From 35588f5b134a29ac2438bd76713e838015ebc821 Mon Sep 17 00:00:00 2001 From: millmanorama Date: Tue, 31 Oct 2017 20:48:21 +0100 Subject: [PATCH 052/127] continue wiring up Message Results and Viewer --- .../communications/AccountDetailsNode.java | 62 +++--- .../AccountDeviceInstanceNode.java | 12 ++ .../communications/MessageBrowser.form | 15 +- .../communications/MessageBrowser.java | 64 +++--- .../communications/MessageDataContent.java | 25 +++ .../RelationShipFilterNode.java | 3 +- .../contentviewers/MessageContentViewer.java | 185 ++++++++---------- .../corecomponentinterfaces/DataContent.java | 2 - 8 files changed, 206 insertions(+), 162 deletions(-) create mode 100644 Core/src/org/sleuthkit/autopsy/communications/MessageDataContent.java diff --git a/Core/src/org/sleuthkit/autopsy/communications/AccountDetailsNode.java b/Core/src/org/sleuthkit/autopsy/communications/AccountDetailsNode.java index 8935864d0b..6452931d2b 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/AccountDetailsNode.java +++ b/Core/src/org/sleuthkit/autopsy/communications/AccountDetailsNode.java @@ -18,26 +18,30 @@ */ package org.sleuthkit.autopsy.communications; +import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; -import org.openide.nodes.FilterNode; +import java.util.logging.Level; +import org.openide.nodes.AbstractNode; +import org.openide.nodes.Children; import org.openide.nodes.Node; -import org.openide.util.Exceptions; +import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.datamodel.BlackboardArtifactNode; import org.sleuthkit.datamodel.Account; -import org.sleuthkit.datamodel.AccountDeviceInstance; import org.sleuthkit.datamodel.BlackboardArtifact; +import org.sleuthkit.datamodel.CommunicationsFilter; import org.sleuthkit.datamodel.CommunicationsManager; import org.sleuthkit.datamodel.TskCoreException; -class AccountDetailsNode extends FilterNode { +class AccountDetailsNode extends AbstractNode { - /** - * @param wrappedNode the value of selectedNode - */ - AccountDetailsNode(AccountDeviceInstanceNode wrappedNode) throws TskCoreException { - super(wrappedNode, new AccountRelationshipChildren(wrappedNode)); + private final static Logger logger = Logger.getLogger(AccountDetailsNode.class.getName()); + private final CommunicationsFilter filter; //TODO: Use this + + AccountDetailsNode(Set accounts,CommunicationsFilter filter, CommunicationsManager commsManager) { + super(new AccountRelationshipChildren(accounts, commsManager)); + this.filter = filter; } /** @@ -45,40 +49,40 @@ class AccountDetailsNode extends FilterNode { */ private static class AccountRelationshipChildren extends Children.Keys { - private final AccountDeviceInstanceNode wrappedNode; + private final Set accounts; + private final CommunicationsManager commsManager; - private AccountRelationshipChildren(AccountDeviceInstanceNode wrappedNode) { - this.wrappedNode = wrappedNode; + private AccountRelationshipChildren(Set accounts, CommunicationsManager commsManager) { + this.accounts = accounts; + this.commsManager = commsManager; } @Override - protected Node[] createNodes(BlackboardArtifact t) { - - final RelationShipFilterNode blackboardArtifactNode = new RelationShipFilterNode(new BlackboardArtifactNode(t)); - return new Node[]{blackboardArtifactNode}; + protected Node[] createNodes(BlackboardArtifact key) { + return new Node[]{new RelationShipFilterNode(new BlackboardArtifactNode(key))}; } @Override protected void addNotify() { - try { - AccountDeviceInstance adi = wrappedNode.getLookup().lookup(AccountDeviceInstance.class); - CommunicationsManager communicationsManager = wrappedNode.getLookup().lookup(CommunicationsManager.class); - List accountsWithRelationship = communicationsManager.getAccountsWithRelationship(adi.getAccount()); - Set keys = new HashSet<>(); + Set keys = new HashSet<>(); + for (Account account : accounts) { + List accountsWithRelationship = new ArrayList<>(); + try { + accountsWithRelationship.addAll(commsManager.getAccountsWithRelationship(account)); //TODO: Use filter + } catch (TskCoreException ex) { + logger.log(Level.WARNING, "Error loading with relationships to " + account, ex); + } - accountsWithRelationship.forEach(account -> { + accountsWithRelationship.forEach(otherAcount -> { try { - keys.addAll(communicationsManager.getRelationships(adi.getAccount(), account)); + keys.addAll(commsManager.getRelationships(account, otherAcount)); //TODO:Use filter } catch (TskCoreException ex) { - Exceptions.printStackTrace(ex); + logger.log(Level.WARNING, "Error loading relationships between " + account + " and " + otherAcount, ex); } }); - - setKeys(keys); - } catch (TskCoreException ex) { - //TODO: proper logging - Exceptions.printStackTrace(ex); } + setKeys(keys); } } + } diff --git a/Core/src/org/sleuthkit/autopsy/communications/AccountDeviceInstanceNode.java b/Core/src/org/sleuthkit/autopsy/communications/AccountDeviceInstanceNode.java index 1627312e34..4c45f647f3 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/AccountDeviceInstanceNode.java +++ b/Core/src/org/sleuthkit/autopsy/communications/AccountDeviceInstanceNode.java @@ -52,6 +52,18 @@ class AccountDeviceInstanceNode extends AbstractNode { + AccountUtils.getIconFileName(accountDeviceInstance.getAccount().getAccountType())); } + public AccountDeviceInstance getAccountDeviceInstance() { + return accountDeviceInstance; + } + + public CommunicationsManager getCommsManager() { + return commsManager; + } + + public CommunicationsFilter getFilter() { + return filter; + } + @Override @NbBundle.Messages({ "AccountNode.device=Device", diff --git a/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.form b/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.form index 148bd68314..ee473957ee 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.form +++ b/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.form @@ -18,7 +18,7 @@ - + @@ -26,7 +26,7 @@ - + @@ -35,10 +35,21 @@ + + + + + + + + + + + diff --git a/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.java b/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.java index 9da9dc04ec..75964a6558 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.java +++ b/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.java @@ -18,14 +18,15 @@ */ package org.sleuthkit.autopsy.communications; -import java.beans.PropertyChangeEvent; +import java.util.HashSet; +import java.util.Set; import org.openide.explorer.ExplorerManager; import org.openide.nodes.Node; -import org.openide.util.Exceptions; -import org.sleuthkit.autopsy.corecomponents.DataContentPanel; import org.sleuthkit.autopsy.corecomponents.DataResultPanel; import org.sleuthkit.autopsy.corecomponents.TableFilterNode; -import org.sleuthkit.datamodel.TskCoreException; +import org.sleuthkit.datamodel.Account; +import org.sleuthkit.datamodel.CommunicationsFilter; +import org.sleuthkit.datamodel.CommunicationsManager; /** * The right hand side of the CVT. Has a DataResultPanel to show messages and @@ -36,16 +37,14 @@ final class MessageBrowser extends javax.swing.JPanel implements ExplorerManager private static final long serialVersionUID = 1L; private ExplorerManager parentExplorereManager; - private final DataContentPanel customContentView; private final DataResultPanel messagesResultPanel; private ExplorerManager internalExplorerManager; MessageBrowser() { initComponents(); - customContentView = DataContentPanel.createInstance(); - messagesResultPanel = DataResultPanel.createInstanceUninitialized("Account", "", Node.EMPTY, 0, customContentView); + messagesResultPanel = DataResultPanel.createInstanceUninitialized("Account", "", Node.EMPTY, 0, messageDataContent); splitPane.setTopComponent(messagesResultPanel); - splitPane.setBottomComponent(customContentView); + splitPane.setBottomComponent(messageDataContent); } @@ -56,28 +55,34 @@ final class MessageBrowser extends javax.swing.JPanel implements ExplorerManager internalExplorerManager = new ExplorerManager(); - parentExplorereManager.addPropertyChangeListener((PropertyChangeEvent evt) -> { - if (evt.getPropertyName().equals(ExplorerManager.PROP_SELECTED_NODES)) { + parentExplorereManager.addPropertyChangeListener(pce -> { + if (pce.getPropertyName().equals(ExplorerManager.PROP_SELECTED_NODES)) { final Node[] selectedNodes = parentExplorereManager.getSelectedNodes(); switch (selectedNodes.length) { case 0: - messagesResultPanel.setNode(null); + messagesResultPanel.setNode(null); break; - case 1: - final Node selectedNode = selectedNodes[0]; - if (selectedNode instanceof AccountDeviceInstanceNode) { - try { - final AccountDetailsNode accountDetailsNode = new AccountDetailsNode((AccountDeviceInstanceNode) selectedNode); - messagesResultPanel.setNode(new TableFilterNode(accountDetailsNode, true)); - } catch (TskCoreException ex) { - Exceptions.printStackTrace(ex); - } - } else { - internalExplorerManager.setRootContext(selectedNode); - } - break; - // TODO: fill in multiseelct support default: + Set accounts = new HashSet<>(); + CommunicationsFilter filter = null; + CommunicationsManager commsManager = null; + for (Node n : selectedNodes) { + if (n instanceof AccountDeviceInstanceNode) { + final AccountDeviceInstanceNode adiNode = (AccountDeviceInstanceNode) n; + accounts.add(adiNode.getAccountDeviceInstance().getAccount()); + if (commsManager == null) { + commsManager = adiNode.getCommsManager(); + } + if (filter == null) { + filter = adiNode.getFilter(); + } else if (filter != adiNode.getFilter()) { + //different filters ..... exception? + } + } else { + ///this should never happen... + } + } + messagesResultPanel.setNode(new TableFilterNode(new AccountDetailsNode(accounts, filter, commsManager), true)); break; } } @@ -95,8 +100,12 @@ final class MessageBrowser extends javax.swing.JPanel implements ExplorerManager private void initComponents() { splitPane = new javax.swing.JSplitPane(); + messageDataContent = new org.sleuthkit.autopsy.communications.MessageDataContent(); + splitPane.setDividerLocation(400); splitPane.setOrientation(javax.swing.JSplitPane.VERTICAL_SPLIT); + splitPane.setResizeWeight(0.5); + splitPane.setBottomComponent(messageDataContent); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); @@ -104,19 +113,20 @@ final class MessageBrowser extends javax.swing.JPanel implements ExplorerManager layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() .addGap(0, 0, 0) - .addComponent(splitPane, javax.swing.GroupLayout.DEFAULT_SIZE, 306, Short.MAX_VALUE)) + .addComponent(splitPane, javax.swing.GroupLayout.DEFAULT_SIZE, 652, Short.MAX_VALUE)) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addGap(0, 0, 0) - .addComponent(splitPane, javax.swing.GroupLayout.DEFAULT_SIZE, 271, Short.MAX_VALUE) + .addComponent(splitPane, javax.swing.GroupLayout.DEFAULT_SIZE, 578, Short.MAX_VALUE) .addGap(0, 0, 0)) ); }// //GEN-END:initComponents // Variables declaration - do not modify//GEN-BEGIN:variables + private org.sleuthkit.autopsy.communications.MessageDataContent messageDataContent; private javax.swing.JSplitPane splitPane; // End of variables declaration//GEN-END:variables diff --git a/Core/src/org/sleuthkit/autopsy/communications/MessageDataContent.java b/Core/src/org/sleuthkit/autopsy/communications/MessageDataContent.java new file mode 100644 index 0000000000..4f432f0b94 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/communications/MessageDataContent.java @@ -0,0 +1,25 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package org.sleuthkit.autopsy.communications; + +import java.beans.PropertyChangeEvent; +import org.sleuthkit.autopsy.contentviewers.MessageContentViewer; +import org.sleuthkit.autopsy.corecomponentinterfaces.DataContent; + +/** + * Extend MessageContentViewer so that it implements DataContent and can be set + * as the only ContentViewer for a DataResultPanel + */ +public class MessageDataContent extends MessageContentViewer implements DataContent { + + private static final long serialVersionUID = 1L; + + @Override + public void propertyChange(PropertyChangeEvent evt) { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + +} diff --git a/Core/src/org/sleuthkit/autopsy/communications/RelationShipFilterNode.java b/Core/src/org/sleuthkit/autopsy/communications/RelationShipFilterNode.java index 42e7db75b9..3420f531c0 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/RelationShipFilterNode.java +++ b/Core/src/org/sleuthkit/autopsy/communications/RelationShipFilterNode.java @@ -37,9 +37,10 @@ public class RelationShipFilterNode extends FilterNode { propertyNames.add("Tags"); propertyNames.add("Text"); propertyNames.add("Read"); - propertyNames.add("Directon"); + propertyNames.add("Direction"); propertyNames.add("Name"); propertyNames.add("Message (Plaintext)"); + propertyNames.add("Message Type"); ArrayList retPropSets = new ArrayList<>(); boolean first = true; diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java b/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java index bdd07871fc..17ad5ba3d6 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java @@ -20,6 +20,8 @@ package org.sleuthkit.autopsy.contentviewers; import java.awt.Component; import java.util.logging.Level; +import org.jsoup.Jsoup; +import org.jsoup.nodes.Document; import org.openide.nodes.Node; import org.openide.util.NbBundle; import org.openide.util.lookup.ServiceProvider; @@ -28,8 +30,6 @@ import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardAttribute; import org.sleuthkit.datamodel.TskCoreException; -import org.jsoup.Jsoup; -import org.jsoup.nodes.Document; /** * Shows SMS/MMS/EMail messages @@ -37,16 +37,15 @@ import org.jsoup.nodes.Document; @ServiceProvider(service = DataContentViewer.class, position = 4) public class MessageContentViewer extends javax.swing.JPanel implements DataContentViewer { - private static final Logger LOGGER = Logger.getLogger(MessageContentViewer.class.getName()); - + private static final int HDR_TAB_INDEX = 0; private static final int TEXT_TAB_INDEX = 1; private static final int HTML_TAB_INDEX = 2; private static final int RTF_TAB_INDEX = 3; - + private BlackboardArtifact artifact; // Artifact currently being displayed - + /** * Creates new form MessageContentViewer */ @@ -252,19 +251,18 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont }// //GEN-END:initComponents private void showImagesToggleButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_showImagesToggleButtonActionPerformed - + try { BlackboardAttribute attr = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_CONTENT_HTML)); if (attr != null && !attr.getValueString().isEmpty()) { - + if (showImagesToggleButton.isSelected()) { showImagesToggleButton.setText(org.openide.util.NbBundle.getMessage(MessageContentViewer.class, "MessageContentViewer.showImagesToggleButton.hide.text")); - + this.htmlbodyTextPane.setText("" + attr.getValueString() + ""); - } - else { + } else { showImagesToggleButton.setText(org.openide.util.NbBundle.getMessage(MessageContentViewer.class, "MessageContentViewer.showImagesToggleButton.text")); - + this.htmlbodyTextPane.setText("" + cleanseHTML(attr.getValueString()) + ""); } } @@ -302,27 +300,30 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont private void customizeComponents() { // do any customizations here - Utilities.configureTextPaneAsHtml(htmlbodyTextPane); - Utilities.configureTextPaneAsRtf(rtfbodyTextPane); - + Utilities.configureTextPaneAsHtml(htmlbodyTextPane); + Utilities.configureTextPaneAsRtf(rtfbodyTextPane); + } - + @Override public void setNode(Node node) { - - artifact = node.getLookup().lookup(BlackboardArtifact.class); - - if (artifact == null) { + + if (node == null) { return; } + artifact = node.getLookup().lookup(BlackboardArtifact.class); + + if (artifact == null) { + return; + } + if (artifact.getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_MESSAGE.getTypeID()) { displayMsg(); - } - else if (artifact.getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_EMAIL_MSG.getTypeID()) { + } else if (artifact.getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_EMAIL_MSG.getTypeID()) { displayEmailMsg(); } - + } @Override @@ -352,211 +353,193 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont @Override public boolean isSupported(Node node) { - BlackboardArtifact artifact = node.getLookup().lookup(BlackboardArtifact.class); - return ( (artifact != null) + BlackboardArtifact artifact = node.getLookup().lookup(BlackboardArtifact.class); + return ((artifact != null) && ((artifact.getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_EMAIL_MSG.getTypeID()) || (artifact.getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_MESSAGE.getTypeID()))); } @Override public int isPreferred(Node node) { - - if ( isSupported(node)){ + + if (isSupported(node)) { return 6; } return 0; } - - - private void displayEmailMsg() - { + + private void displayEmailMsg() { directionText.setVisible(false); - + showImagesToggleButton.setVisible(false); showImagesToggleButton.setText("Show Images"); showImagesToggleButton.setSelected(false); - + try { BlackboardAttribute attr = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_FROM)); this.fromText.setText(attr.getValueString()); - + attr = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_TO)); if (attr != null) { - this.toText.setText(attr.getValueString()); + this.toText.setText(attr.getValueString()); } - - + attr = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_CC)); if (attr != null && !attr.getValueString().isEmpty()) { this.ccText.setVisible(true); this.ccText.setText(attr.getValueString()); - } - else { + } else { this.ccText.setVisible(false); } - + attr = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SUBJECT)); if (attr != null && !attr.getValueString().isEmpty()) { this.subjectText.setVisible(true); this.subjectText.setText(attr.getValueString()); - } - else { + } else { this.subjectText.setVisible(false); } - + attr = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_RCVD)); if (attr != null && !attr.getDisplayString().isEmpty()) { this.datetimeText.setVisible(true); this.datetimeText.setText(attr.getDisplayString()); - } - else { + } else { this.datetimeText.setVisible(false); } - + int selectedTabIndex = -1; attr = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_CONTENT_PLAIN)); if (attr != null && !attr.getValueString().isEmpty()) { this.textbodyTextArea.setVisible(true); this.textbodyTextArea.setText(attr.getValueString()); - + msgbodyTabbedPane.setEnabledAt(TEXT_TAB_INDEX, true); selectedTabIndex = TEXT_TAB_INDEX; - } - else { + } else { msgbodyTabbedPane.setEnabledAt(TEXT_TAB_INDEX, false); } - + attr = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_CONTENT_HTML)); if (attr != null && !attr.getValueString().isEmpty()) { - + this.showImagesToggleButton.setVisible(true); - - + this.htmlbodyTextPane.setVisible(true); this.htmlbodyTextPane.setText("" + cleanseHTML(attr.getValueString()) + ""); //this.htmlbodyTextPane.setText(cleanseHTML(attr.getValueString())); - + msgbodyTabbedPane.setEnabledAt(HTML_TAB_INDEX, true); selectedTabIndex = HTML_TAB_INDEX; - } - else { + } else { msgbodyTabbedPane.setEnabledAt(HTML_TAB_INDEX, false); this.htmlbodyTextPane.setVisible(false); } - + attr = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_CONTENT_RTF)); if (attr != null && !attr.getValueString().isEmpty()) { - + this.rtfbodyTextPane.setVisible(true); this.rtfbodyTextPane.setText(attr.getValueString()); - + msgbodyTabbedPane.setEnabledAt(RTF_TAB_INDEX, true); selectedTabIndex = RTF_TAB_INDEX; - } - else { + } else { msgbodyTabbedPane.setEnabledAt(RTF_TAB_INDEX, false); } - + attr = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_HEADERS)); if (attr != null && !attr.getValueString().isEmpty()) { this.headersTextArea.setVisible(true); this.headersTextArea.setText(attr.getValueString()); if (selectedTabIndex < 0) { - selectedTabIndex = HDR_TAB_INDEX; + selectedTabIndex = HDR_TAB_INDEX; } - } - else { + } else { msgbodyTabbedPane.setEnabledAt(HDR_TAB_INDEX, false); } - + msgbodyTabbedPane.setSelectedIndex(selectedTabIndex); - } - catch (TskCoreException ex) { + } catch (TskCoreException ex) { LOGGER.log(Level.WARNING, "Failed to get attributes for email message.", ex); //NON-NLS } } - + private void displayMsg() { - + this.ccText.setVisible(false); this.showImagesToggleButton.setVisible(false); msgbodyTabbedPane.setEnabledAt(HTML_TAB_INDEX, false); msgbodyTabbedPane.setEnabledAt(RTF_TAB_INDEX, false); msgbodyTabbedPane.setEnabledAt(HDR_TAB_INDEX, false); - + try { - + BlackboardAttribute attr = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_FROM)); if (attr != null) { this.fromText.setText(attr.getValueString()); - }else { - this.fromText.setVisible(false); + } else { + this.fromText.setVisible(false); } - + attr = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_TO)); if (attr != null) { - this.toText.setText(attr.getValueString()); - }else { - this.toText.setVisible(false); + this.toText.setText(attr.getValueString()); + } else { + this.toText.setVisible(false); } - + attr = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DIRECTION)); if (attr != null) { - this.directionText.setText(attr.getValueString()); - }else { - this.directionText.setVisible(false); + this.directionText.setText(attr.getValueString()); + } else { + this.directionText.setVisible(false); } - + attr = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SUBJECT)); if (attr != null && !attr.getValueString().isEmpty()) { this.subjectText.setVisible(true); this.subjectText.setText(attr.getValueString()); - } - else { + } else { this.subjectText.setVisible(false); } - + attr = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME)); if (attr != null && !attr.getDisplayString().isEmpty()) { this.datetimeText.setVisible(true); this.datetimeText.setText(attr.getDisplayString()); - } - else { + } else { this.datetimeText.setVisible(false); } - - + attr = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_TEXT)); if (attr != null && !attr.getValueString().isEmpty()) { this.textbodyTextArea.setVisible(true); this.textbodyTextArea.setText(attr.getValueString()); - + msgbodyTabbedPane.setEnabledAt(TEXT_TAB_INDEX, true); - } - else { + } else { msgbodyTabbedPane.setEnabledAt(TEXT_TAB_INDEX, false); } msgbodyTabbedPane.setSelectedIndex(TEXT_TAB_INDEX); - } - catch (TskCoreException ex) { + } catch (TskCoreException ex) { LOGGER.log(Level.WARNING, "Failed to get attributes for message.", ex); //NON-NLS } - + } - + /** * Cleans out input HTML string */ - private String cleanseHTML(String htmlInString) { - + private String cleanseHTML(String htmlInString) { + Document doc = Jsoup.parse(htmlInString); - + // fix all img tags doc.select("img[src]").forEach((img) -> { img.attr("src", ""); }); return doc.html(); - } } diff --git a/Core/src/org/sleuthkit/autopsy/corecomponentinterfaces/DataContent.java b/Core/src/org/sleuthkit/autopsy/corecomponentinterfaces/DataContent.java index 92d0e39547..f51f558f74 100755 --- a/Core/src/org/sleuthkit/autopsy/corecomponentinterfaces/DataContent.java +++ b/Core/src/org/sleuthkit/autopsy/corecomponentinterfaces/DataContent.java @@ -20,12 +20,10 @@ package org.sleuthkit.autopsy.corecomponentinterfaces; import java.beans.PropertyChangeListener; import org.openide.nodes.Node; -import org.openide.windows.TopComponent; /** * The interface for the "bottom right component" window. * - * @author jantonius */ public interface DataContent extends PropertyChangeListener { From 56870ab605316b33117dfeedaa0e13fdf5d35295 Mon Sep 17 00:00:00 2001 From: millmanorama Date: Tue, 31 Oct 2017 21:06:36 +0100 Subject: [PATCH 053/127] tweak UI layout --- .../autopsy/communications/Bundle.properties | 4 ++-- .../communications/CVTTopComponent.form | 14 +++++++++++--- .../communications/CVTTopComponent.java | 8 ++++++-- .../autopsy/communications/FiltersPanel.form | 2 +- .../autopsy/communications/FiltersPanel.java | 19 +++++++------------ .../communications/MessageBrowser.form | 2 +- .../communications/MessageBrowser.java | 2 +- 7 files changed, 29 insertions(+), 22 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/communications/Bundle.properties b/Core/src/org/sleuthkit/autopsy/communications/Bundle.properties index 9e5cf923e1..c95f1af5c8 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/communications/Bundle.properties @@ -1,9 +1,9 @@ CVTTopComponent.TabConstraints.tabTitle=Visualize CVTTopComponent.accountsBrowser.TabConstraints.tabTitle=Browse -FiltersPanel.applyFiltersButton.text=Apply Filters +FiltersPanel.applyFiltersButton.text=Apply FiltersPanel.devicesLabel.text=Devices: FiltersPanel.accountTypesLabel.text=Account Types: -FiltersPanel.filtersTitleLabel.text=Filters +FiltersPanel.filtersTitleLabel.text=Account Filters FiltersPanel.unCheckAllAccountTypesButton.text=Uncheck All FiltersPanel.checkAllAccountTypesButton.text=Check All FiltersPanel.unCheckAllDevicesButton.text=Uncheck All diff --git a/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.form b/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.form index 82be39bf3d..f2ba98c5b9 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.form +++ b/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.form @@ -17,9 +17,9 @@ - - - + + + @@ -42,6 +42,7 @@ + @@ -106,6 +107,13 @@ + + + + + + + diff --git a/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java b/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java index fa789271a2..aa09e14560 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java +++ b/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java @@ -49,7 +49,7 @@ public final class CVTTopComponent extends TopComponent implements ExplorerManag initComponents(); setName(Bundle.CVTTopComponent_name()); - splitPane.setRightComponent(new MessageBrowser()); +// splitPane.setRightComponent(new MessageBrowser()); } /** @@ -64,9 +64,11 @@ public final class CVTTopComponent extends TopComponent implements ExplorerManag BrowseVisualizeTabPane = new javax.swing.JTabbedPane(); accountsBrowser = new org.sleuthkit.autopsy.communications.AccountsBrowser(); jPanel1 = new javax.swing.JPanel(); + messageBrowser1 = new org.sleuthkit.autopsy.communications.MessageBrowser(); filtersPane = new org.sleuthkit.autopsy.communications.FiltersPanel(); splitPane.setDividerLocation(600); + splitPane.setResizeWeight(0.3); BrowseVisualizeTabPane.setFont(new java.awt.Font("Tahoma", 0, 18)); // NOI18N BrowseVisualizeTabPane.addTab(org.openide.util.NbBundle.getMessage(CVTTopComponent.class, "CVTTopComponent.accountsBrowser.TabConstraints.tabTitle"), new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/communications/images/table.png")), accountsBrowser); // NOI18N @@ -87,6 +89,7 @@ public final class CVTTopComponent extends TopComponent implements ExplorerManag BrowseVisualizeTabPane.addTab(org.openide.util.NbBundle.getMessage(CVTTopComponent.class, "CVTTopComponent.TabConstraints.tabTitle"), new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/communications/images/emblem-web.png")), jPanel1); // NOI18N splitPane.setLeftComponent(BrowseVisualizeTabPane); + splitPane.setRightComponent(messageBrowser1); filtersPane.setBorder(javax.swing.BorderFactory.createEtchedBorder()); filtersPane.setMinimumSize(new java.awt.Dimension(256, 495)); @@ -97,7 +100,7 @@ public final class CVTTopComponent extends TopComponent implements ExplorerManag layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addContainerGap() - .addComponent(filtersPane, javax.swing.GroupLayout.PREFERRED_SIZE, 244, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(filtersPane, javax.swing.GroupLayout.PREFERRED_SIZE, 244, Short.MAX_VALUE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(splitPane, javax.swing.GroupLayout.DEFAULT_SIZE, 1322, Short.MAX_VALUE) .addContainerGap()) @@ -119,6 +122,7 @@ public final class CVTTopComponent extends TopComponent implements ExplorerManag private org.sleuthkit.autopsy.communications.AccountsBrowser accountsBrowser; private org.sleuthkit.autopsy.communications.FiltersPanel filtersPane; private javax.swing.JPanel jPanel1; + private org.sleuthkit.autopsy.communications.MessageBrowser messageBrowser1; private javax.swing.JSplitPane splitPane; // End of variables declaration//GEN-END:variables diff --git a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.form b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.form index e020c001a1..907dcace44 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.form +++ b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.form @@ -116,7 +116,7 @@ - + diff --git a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java index a8bf3d1e4a..5d840df9eb 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java +++ b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java @@ -134,8 +134,6 @@ final public class FiltersPanel extends javax.swing.JPanel { // //GEN-BEGIN:initComponents private void initComponents() { - jList1 = new javax.swing.JList<>(); - jList1.setModel(new javax.swing.AbstractListModel() { String[] strings = { "Item 1", "Item 2", "Item 3", "Item 4", "Item 5" }; public int getSize() { return strings.length; } @@ -185,7 +183,7 @@ final public class FiltersPanel extends javax.swing.JPanel { .addGroup(jPanel2Layout.createSequentialGroup() .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel2Layout.createSequentialGroup() - .addContainerGap(51, Short.MAX_VALUE) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(unCheckAllAccountTypesButton) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(checkAllAccountTypesButton)) @@ -233,15 +231,12 @@ final public class FiltersPanel extends javax.swing.JPanel { .addGroup(jPanel3Layout.createSequentialGroup() .addComponent(devicesLabel) .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addComponent(devicesPane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addGroup(jPanel3Layout.createSequentialGroup() - .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(devicesPane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addGroup(jPanel3Layout.createSequentialGroup() - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(unCheckAllDevicesButton) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(checkAllDevicesButton))) - .addGap(0, 0, 0)) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(unCheckAllDevicesButton) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(checkAllDevicesButton)) ); jPanel3Layout.setVerticalGroup( jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) @@ -372,7 +367,7 @@ final public class FiltersPanel extends javax.swing.JPanel { private final javax.swing.JLabel devicesLabel = new javax.swing.JLabel(); private final javax.swing.JPanel devicesPane = new javax.swing.JPanel(); private final javax.swing.JLabel filtersTitleLabel = new javax.swing.JLabel(); - private javax.swing.JList jList1; + private final javax.swing.JList jList1 = new javax.swing.JList<>(); private final javax.swing.JPanel jPanel2 = new javax.swing.JPanel(); private final javax.swing.JPanel jPanel3 = new javax.swing.JPanel(); private final javax.swing.JScrollPane jScrollPane1 = new javax.swing.JScrollPane(); diff --git a/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.form b/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.form index ee473957ee..25399629ca 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.form +++ b/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.form @@ -37,7 +37,7 @@ - + diff --git a/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.java b/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.java index 75964a6558..0bdc2514ed 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.java +++ b/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.java @@ -104,7 +104,7 @@ final class MessageBrowser extends javax.swing.JPanel implements ExplorerManager splitPane.setDividerLocation(400); splitPane.setOrientation(javax.swing.JSplitPane.VERTICAL_SPLIT); - splitPane.setResizeWeight(0.5); + splitPane.setResizeWeight(0.4); splitPane.setBottomComponent(messageDataContent); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); From 825a614b07c79f3906745eb372a466e0a3dea937 Mon Sep 17 00:00:00 2001 From: millmanorama Date: Wed, 1 Nov 2017 12:20:09 +0100 Subject: [PATCH 054/127] override createSheet instead of using the implementation in BlackboardArtifactNode and suppressing some columns. --- .../communications/AccountDetailsNode.java | 3 +- .../AccountDeviceInstanceNode.java | 104 ------------ .../AccountsDeviceInstanceChildren.java | 65 -------- .../communications/AccountsRootChildren.java | 128 ++++++++++++++ .../communications/CVTTopComponent.form | 7 - .../communications/CVTTopComponent.java | 5 +- .../autopsy/communications/FiltersPanel.form | 14 +- .../autopsy/communications/FiltersPanel.java | 13 +- .../communications/MessageBrowser.form | 8 +- .../communications/MessageBrowser.java | 6 +- .../communications/MessageDataContent.java | 19 ++- .../RelationShipFilterNode.java | 156 ++++++++++++------ 12 files changed, 274 insertions(+), 254 deletions(-) delete mode 100644 Core/src/org/sleuthkit/autopsy/communications/AccountDeviceInstanceNode.java delete mode 100644 Core/src/org/sleuthkit/autopsy/communications/AccountsDeviceInstanceChildren.java create mode 100644 Core/src/org/sleuthkit/autopsy/communications/AccountsRootChildren.java diff --git a/Core/src/org/sleuthkit/autopsy/communications/AccountDetailsNode.java b/Core/src/org/sleuthkit/autopsy/communications/AccountDetailsNode.java index 6452931d2b..c428cbb3fd 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/AccountDetailsNode.java +++ b/Core/src/org/sleuthkit/autopsy/communications/AccountDetailsNode.java @@ -27,7 +27,6 @@ import org.openide.nodes.AbstractNode; import org.openide.nodes.Children; import org.openide.nodes.Node; import org.sleuthkit.autopsy.coreutils.Logger; -import org.sleuthkit.autopsy.datamodel.BlackboardArtifactNode; import org.sleuthkit.datamodel.Account; import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.CommunicationsFilter; @@ -59,7 +58,7 @@ class AccountDetailsNode extends AbstractNode { @Override protected Node[] createNodes(BlackboardArtifact key) { - return new Node[]{new RelationShipFilterNode(new BlackboardArtifactNode(key))}; + return new Node[]{new RelationShipFilterNode(key)}; } @Override diff --git a/Core/src/org/sleuthkit/autopsy/communications/AccountDeviceInstanceNode.java b/Core/src/org/sleuthkit/autopsy/communications/AccountDeviceInstanceNode.java deleted file mode 100644 index 4c45f647f3..0000000000 --- a/Core/src/org/sleuthkit/autopsy/communications/AccountDeviceInstanceNode.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Autopsy Forensic Browser - * - * Copyright 2011-2017 Basis Technology Corp. - * Contact: carrier sleuthkit org - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.sleuthkit.autopsy.communications; - -import java.util.logging.Level; -import java.util.logging.Logger; -import org.openide.nodes.AbstractNode; -import org.openide.nodes.Children; -import org.openide.nodes.Sheet; -import org.openide.util.NbBundle; -import org.openide.util.lookup.Lookups; -import org.sleuthkit.autopsy.datamodel.NodeProperty; -import org.sleuthkit.datamodel.AccountDeviceInstance; -import org.sleuthkit.datamodel.CommunicationsFilter; -import org.sleuthkit.datamodel.CommunicationsManager; -import org.sleuthkit.datamodel.TskCoreException; - -/** - * Node to represent an Account in the AccountsBrowser - */ -class AccountDeviceInstanceNode extends AbstractNode { - - private static final Logger LOGGER = Logger.getLogger(AccountDeviceInstanceNode.class.getName()); - private final AccountDeviceInstance accountDeviceInstance; - private final CommunicationsManager commsManager; - private final CommunicationsFilter filter; - - AccountDeviceInstanceNode(AccountDeviceInstanceKey accountDeviceInstanceKey, CommunicationsManager commsManager) { - super(Children.LEAF, Lookups.fixed(accountDeviceInstanceKey, commsManager)); - this.accountDeviceInstance = accountDeviceInstanceKey.getAccountDeviceInstance(); - this.commsManager = commsManager; - this.filter = accountDeviceInstanceKey.getCommunicationsFilter(); - - setName(accountDeviceInstance.getAccount().getAccountUniqueID()); - setIconBaseWithExtension("org/sleuthkit/autopsy/communications/images/" - + AccountUtils.getIconFileName(accountDeviceInstance.getAccount().getAccountType())); - } - - public AccountDeviceInstance getAccountDeviceInstance() { - return accountDeviceInstance; - } - - public CommunicationsManager getCommsManager() { - return commsManager; - } - - public CommunicationsFilter getFilter() { - return filter; - } - - @Override - @NbBundle.Messages({ - "AccountNode.device=Device", - "AccountNode.accountName=Account", - "AccountNode.accountType=Type", - "AccountNode.messageCount=Msg Count"}) - protected Sheet createSheet() { - Sheet s = super.createSheet(); - Sheet.Set properties = s.get(Sheet.PROPERTIES); - if (properties == null) { - properties = Sheet.createPropertiesSet(); - s.put(properties); - } - - long msgCount = 0; - try { - msgCount = commsManager.getRelationshipsCount(filter, accountDeviceInstance); - } catch (TskCoreException ex) { - LOGGER.log(Level.WARNING, "Failed to get message count for account", ex); //NON-NLS - } - - properties.put(new NodeProperty<>("type", - Bundle.AccountNode_accountType(), - "type", - accountDeviceInstance.getAccount().getAccountType().getDisplayName())); // NON-NLS - - properties.put(new NodeProperty<>("count", - Bundle.AccountNode_messageCount(), - "count", - msgCount)); // NON-NLS - - properties.put(new NodeProperty<>("device", - Bundle.AccountNode_device(), - "device", - accountDeviceInstance.getDeviceId())); // NON-NLS - return s; - } -} diff --git a/Core/src/org/sleuthkit/autopsy/communications/AccountsDeviceInstanceChildren.java b/Core/src/org/sleuthkit/autopsy/communications/AccountsDeviceInstanceChildren.java deleted file mode 100644 index 51db6d0e4f..0000000000 --- a/Core/src/org/sleuthkit/autopsy/communications/AccountsDeviceInstanceChildren.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Autopsy Forensic Browser - * - * Copyright 2011-2017 Basis Technology Corp. - * Contact: carrier sleuthkit org - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.sleuthkit.autopsy.communications; - -import java.util.Collections; -import java.util.List; -import org.openide.nodes.Children; -import org.openide.nodes.Node; -import org.sleuthkit.datamodel.CommunicationsManager; - -class AccountsDeviceInstanceChildren extends Children.Keys { - - private final List accountDeviceInstanceKeys; - private final CommunicationsManager commsManager; - - AccountsDeviceInstanceChildren(List accountDeviceInstanceKeys, CommunicationsManager commsManager) { - super(true); - this.accountDeviceInstanceKeys = accountDeviceInstanceKeys; - this.commsManager = commsManager; - } - - @Override - protected void removeNotify() { - super.removeNotify(); - setKeys(Collections.emptySet()); - } - - @Override - protected void addNotify() { - super.addNotify(); - setKeys(accountDeviceInstanceKeys); - } - - //These are the methods for ChildFactory. I am going to keep them around but commented until we make a final descision. - // @Override - // protected boolean createKeys(List list) { - // list.addAll(accounts); - // return true; - // } - // - // @Override - // protected Node createNodeForKey(Account key) { - // return new AccountDeviceInstanceNode(key); - // } - @Override - protected Node[] createNodes(AccountDeviceInstanceKey key) { - return new Node[]{new AccountDeviceInstanceNode(key, commsManager)}; - } -} diff --git a/Core/src/org/sleuthkit/autopsy/communications/AccountsRootChildren.java b/Core/src/org/sleuthkit/autopsy/communications/AccountsRootChildren.java new file mode 100644 index 0000000000..3da39f6776 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/communications/AccountsRootChildren.java @@ -0,0 +1,128 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2011-2017 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.sleuthkit.autopsy.communications; + +import java.util.Collections; +import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; +import org.openide.nodes.AbstractNode; +import org.openide.nodes.Children; +import org.openide.nodes.Node; +import org.openide.nodes.Sheet; +import org.openide.util.NbBundle; +import org.openide.util.lookup.Lookups; +import org.sleuthkit.autopsy.datamodel.NodeProperty; +import org.sleuthkit.datamodel.AccountDeviceInstance; +import org.sleuthkit.datamodel.CommunicationsFilter; +import org.sleuthkit.datamodel.CommunicationsManager; +import org.sleuthkit.datamodel.TskCoreException; + +class AccountsRootChildren extends Children.Keys { + + private final List accountDeviceInstanceKeys; + private final CommunicationsManager commsManager; + + AccountsRootChildren(List accountDeviceInstanceKeys, CommunicationsManager commsManager) { + super(true); + this.accountDeviceInstanceKeys = accountDeviceInstanceKeys; + this.commsManager = commsManager; + } + + @Override + protected void removeNotify() { + super.removeNotify(); + setKeys(Collections.emptySet()); + } + + @Override + protected void addNotify() { + super.addNotify(); + setKeys(accountDeviceInstanceKeys); + } + + //These are the methods for ChildFactory. I am going to keep them around but commented until we make a final descision. + // @Override + // protected boolean createKeys(List list) { + // list.addAll(accounts); + // return true; + // } + // + // @Override + // protected Node createNodeForKey(Account key) { + // return new AccountDeviceInstanceNode(key); + // } + @Override + protected Node[] createNodes(AccountDeviceInstanceKey key) { + return new Node[]{new AccountDeviceInstanceNode(key, commsManager)}; + } + + /** + * Node to represent an Account in the AccountsBrowser + */ + static class AccountDeviceInstanceNode extends AbstractNode { + + private static final Logger LOGGER = Logger.getLogger(AccountDeviceInstanceNode.class.getName()); + private final AccountDeviceInstance accountDeviceInstance; + private final CommunicationsManager commsManager; + private final CommunicationsFilter filter; + + private AccountDeviceInstanceNode(AccountDeviceInstanceKey accountDeviceInstanceKey, CommunicationsManager commsManager) { + super(Children.LEAF, Lookups.fixed(accountDeviceInstanceKey, commsManager)); + this.accountDeviceInstance = accountDeviceInstanceKey.getAccountDeviceInstance(); + this.commsManager = commsManager; + this.filter = accountDeviceInstanceKey.getCommunicationsFilter(); + setName(accountDeviceInstance.getAccount().getAccountUniqueID()); + setIconBaseWithExtension("org/sleuthkit/autopsy/communications/images/" + AccountUtils.getIconFileName(accountDeviceInstance.getAccount().getAccountType())); + } + + public AccountDeviceInstance getAccountDeviceInstance() { + return accountDeviceInstance; + } + + public CommunicationsManager getCommsManager() { + return commsManager; + } + + public CommunicationsFilter getFilter() { + return filter; + } + + @Override + @NbBundle.Messages(value = {"AccountNode.device=Device", "AccountNode.accountName=Account", "AccountNode.accountType=Type", "AccountNode.messageCount=Msg Count"}) + protected Sheet createSheet() { + Sheet s = super.createSheet(); + Sheet.Set properties = s.get(Sheet.PROPERTIES); + if (properties == null) { + properties = Sheet.createPropertiesSet(); + s.put(properties); + } + long msgCount = 0; + try { + msgCount = commsManager.getRelationshipsCount(filter, accountDeviceInstance); + } catch (TskCoreException ex) { + LOGGER.log(Level.WARNING, "Failed to get message count for account", ex); //NON-NLS + } + properties.put(new NodeProperty<>("type", Bundle.AccountNode_accountType(), "type", accountDeviceInstance.getAccount().getAccountType().getDisplayName())); // NON-NLS + properties.put(new NodeProperty<>("count", Bundle.AccountNode_messageCount(), "count", msgCount)); // NON-NLS + properties.put(new NodeProperty<>("device", Bundle.AccountNode_device(), "device", accountDeviceInstance.getDeviceId())); // NON-NLS + return s; + } + } +} diff --git a/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.form b/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.form index f2ba98c5b9..524529e9bd 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.form +++ b/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.form @@ -107,13 +107,6 @@ - - - - - - - diff --git a/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java b/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java index aa09e14560..9a108d3271 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java +++ b/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java @@ -49,7 +49,7 @@ public final class CVTTopComponent extends TopComponent implements ExplorerManag initComponents(); setName(Bundle.CVTTopComponent_name()); -// splitPane.setRightComponent(new MessageBrowser()); + splitPane.setRightComponent(new MessageBrowser()); } /** @@ -64,7 +64,6 @@ public final class CVTTopComponent extends TopComponent implements ExplorerManag BrowseVisualizeTabPane = new javax.swing.JTabbedPane(); accountsBrowser = new org.sleuthkit.autopsy.communications.AccountsBrowser(); jPanel1 = new javax.swing.JPanel(); - messageBrowser1 = new org.sleuthkit.autopsy.communications.MessageBrowser(); filtersPane = new org.sleuthkit.autopsy.communications.FiltersPanel(); splitPane.setDividerLocation(600); @@ -89,7 +88,6 @@ public final class CVTTopComponent extends TopComponent implements ExplorerManag BrowseVisualizeTabPane.addTab(org.openide.util.NbBundle.getMessage(CVTTopComponent.class, "CVTTopComponent.TabConstraints.tabTitle"), new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/communications/images/emblem-web.png")), jPanel1); // NOI18N splitPane.setLeftComponent(BrowseVisualizeTabPane); - splitPane.setRightComponent(messageBrowser1); filtersPane.setBorder(javax.swing.BorderFactory.createEtchedBorder()); filtersPane.setMinimumSize(new java.awt.Dimension(256, 495)); @@ -122,7 +120,6 @@ public final class CVTTopComponent extends TopComponent implements ExplorerManag private org.sleuthkit.autopsy.communications.AccountsBrowser accountsBrowser; private org.sleuthkit.autopsy.communications.FiltersPanel filtersPane; private javax.swing.JPanel jPanel1; - private org.sleuthkit.autopsy.communications.MessageBrowser messageBrowser1; private javax.swing.JSplitPane splitPane; // End of variables declaration//GEN-END:variables diff --git a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.form b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.form index 907dcace44..ef451b0751 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.form +++ b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.form @@ -28,11 +28,6 @@ - - - - - @@ -56,7 +51,7 @@ - + @@ -90,6 +85,9 @@ + + + @@ -98,7 +96,7 @@ - + @@ -116,7 +114,7 @@ - + diff --git a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java index 5d840df9eb..90cee25853 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java +++ b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java @@ -141,18 +141,17 @@ final public class FiltersPanel extends javax.swing.JPanel { }); jScrollPane1.setViewportView(jList1); - setPreferredSize(new java.awt.Dimension(256, 469)); - applyFiltersButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/communications/images/control-double.png"))); // NOI18N applyFiltersButton.setText(org.openide.util.NbBundle.getMessage(FiltersPanel.class, "FiltersPanel.applyFiltersButton.text")); // NOI18N applyFiltersButton.setHorizontalTextPosition(javax.swing.SwingConstants.LEADING); + applyFiltersButton.setPreferredSize(null); applyFiltersButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { applyFiltersButtonActionPerformed(evt); } }); - filtersTitleLabel.setFont(new java.awt.Font("Tahoma", 0, 18)); // NOI18N + filtersTitleLabel.setFont(new java.awt.Font("Tahoma", 0, 16)); // NOI18N filtersTitleLabel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/communications/images/funnel.png"))); // NOI18N filtersTitleLabel.setText(org.openide.util.NbBundle.getMessage(FiltersPanel.class, "FiltersPanel.filtersTitleLabel.text")); // NOI18N @@ -183,7 +182,7 @@ final public class FiltersPanel extends javax.swing.JPanel { .addGroup(jPanel2Layout.createSequentialGroup() .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel2Layout.createSequentialGroup() - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addContainerGap(43, Short.MAX_VALUE) .addComponent(unCheckAllAccountTypesButton) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(checkAllAccountTypesButton)) @@ -264,7 +263,7 @@ final public class FiltersPanel extends javax.swing.JPanel { .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup() .addComponent(filtersTitleLabel) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(applyFiltersButton))) + .addComponent(applyFiltersButton, javax.swing.GroupLayout.PREFERRED_SIZE, 83, javax.swing.GroupLayout.PREFERRED_SIZE))) .addContainerGap()) ); layout.setVerticalGroup( @@ -273,7 +272,7 @@ final public class FiltersPanel extends javax.swing.JPanel { .addContainerGap() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(filtersTitleLabel) - .addComponent(applyFiltersButton)) + .addComponent(applyFiltersButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addGap(18, 18, 18) .addComponent(jPanel3, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) @@ -307,7 +306,7 @@ final public class FiltersPanel extends javax.swing.JPanel { accountDeviceInstances.forEach(accountDeviceInstance -> accountDeviceInstanceKeys.add(new AccountDeviceInstanceKey(accountDeviceInstance, commsFilter))); - em.setRootContext(new AbstractNode(new AccountsDeviceInstanceChildren(accountDeviceInstanceKeys, commsManager))); + em.setRootContext(new AbstractNode(new AccountsRootChildren(accountDeviceInstanceKeys, commsManager))); } catch (TskCoreException ex) { logger.log(Level.SEVERE, "There was a error loading the accounts.", ex); } diff --git a/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.form b/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.form index 25399629ca..606d60c7df 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.form +++ b/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.form @@ -26,7 +26,7 @@ - + @@ -36,6 +36,7 @@ + @@ -43,6 +44,11 @@ + + + + + diff --git a/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.java b/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.java index 0bdc2514ed..20a4388dae 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.java +++ b/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.java @@ -22,6 +22,7 @@ import java.util.HashSet; import java.util.Set; import org.openide.explorer.ExplorerManager; import org.openide.nodes.Node; +import org.sleuthkit.autopsy.communications.AccountsRootChildren.AccountDeviceInstanceNode; import org.sleuthkit.autopsy.corecomponents.DataResultPanel; import org.sleuthkit.autopsy.corecomponents.TableFilterNode; import org.sleuthkit.datamodel.Account; @@ -103,8 +104,11 @@ final class MessageBrowser extends javax.swing.JPanel implements ExplorerManager messageDataContent = new org.sleuthkit.autopsy.communications.MessageDataContent(); splitPane.setDividerLocation(400); + splitPane.setDividerSize(10); splitPane.setOrientation(javax.swing.JSplitPane.VERTICAL_SPLIT); splitPane.setResizeWeight(0.4); + + messageDataContent.setMinimumSize(null); splitPane.setBottomComponent(messageDataContent); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); @@ -119,7 +123,7 @@ final class MessageBrowser extends javax.swing.JPanel implements ExplorerManager layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addGap(0, 0, 0) - .addComponent(splitPane, javax.swing.GroupLayout.DEFAULT_SIZE, 578, Short.MAX_VALUE) + .addComponent(splitPane, javax.swing.GroupLayout.DEFAULT_SIZE, 1083, Short.MAX_VALUE) .addGap(0, 0, 0)) ); }// //GEN-END:initComponents diff --git a/Core/src/org/sleuthkit/autopsy/communications/MessageDataContent.java b/Core/src/org/sleuthkit/autopsy/communications/MessageDataContent.java index 4f432f0b94..1b7b5dc3c0 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/MessageDataContent.java +++ b/Core/src/org/sleuthkit/autopsy/communications/MessageDataContent.java @@ -1,7 +1,20 @@ /* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. + * Autopsy Forensic Browser + * + * Copyright 2011-2017 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package org.sleuthkit.autopsy.communications; diff --git a/Core/src/org/sleuthkit/autopsy/communications/RelationShipFilterNode.java b/Core/src/org/sleuthkit/autopsy/communications/RelationShipFilterNode.java index 3420f531c0..71508f807a 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/RelationShipFilterNode.java +++ b/Core/src/org/sleuthkit/autopsy/communications/RelationShipFilterNode.java @@ -1,72 +1,124 @@ /* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. + * Autopsy Forensic Browser + * + * Copyright 2011-2017 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package org.sleuthkit.autopsy.communications; -import java.util.ArrayList; -import java.util.HashSet; +import java.util.logging.Level; import org.apache.commons.lang3.StringUtils; -import org.openide.nodes.FilterNode; import org.openide.nodes.Sheet; +import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.datamodel.BlackboardArtifactNode; import org.sleuthkit.autopsy.datamodel.NodeProperty; +import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardAttribute; +import org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE; +import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME; +import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_SENT; +import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_START; +import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_FROM; +import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_TO; +import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_FROM; +import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_TO; +import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SUBJECT; +import org.sleuthkit.datamodel.TskCoreException; /** * */ -public class RelationShipFilterNode extends FilterNode { - - - public RelationShipFilterNode(BlackboardArtifactNode wrappedNode) { - super(wrappedNode, Children.LEAF); - setDisplayName( StringUtils.stripEnd(wrappedNode.getArtifact().getDisplayName(),"s")); +public class RelationShipFilterNode extends BlackboardArtifactNode { + + private static final Logger logger = Logger.getLogger(RelationShipFilterNode.class.getName()); + + public RelationShipFilterNode(BlackboardArtifact artifact) { + super(artifact); + final String stripEnd = StringUtils.stripEnd(artifact.getDisplayName(), "s"); + String removeEndIgnoreCase = StringUtils.removeEndIgnoreCase(stripEnd, "message"); + setDisplayName(removeEndIgnoreCase.isEmpty() ? stripEnd : removeEndIgnoreCase); } - + @Override - public PropertySet[] getPropertySets() { - PropertySet[] propertySets = super.getPropertySets(); - - HashSet propertyNames = new HashSet<>(); - propertyNames.add("Source File"); - propertyNames.add("Data Source"); - propertyNames.add("Path"); - propertyNames.add("Message ID"); - propertyNames.add("Tags"); - propertyNames.add("Text"); - propertyNames.add("Read"); - propertyNames.add("Direction"); - propertyNames.add("Name"); - propertyNames.add("Message (Plaintext)"); - propertyNames.add("Message Type"); - - ArrayList retPropSets = new ArrayList<>(); - boolean first = true; - for (PropertySet set : propertySets) { - Sheet.Set set1 = copySet(set); - if (first) { - first = false; - set1.put(new NodeProperty<>("Type", "Type", "Type", getDisplayName())); - } - - for (Property p : set.getProperties()) { - if (false == propertyNames.contains(p.getName())) { - set1.put(p); - } - } - retPropSets.add(set1); + protected Sheet createSheet() { + + Sheet s = new Sheet(); + Sheet.Set ss = s.get(Sheet.PROPERTIES); + if (ss == null) { + ss = Sheet.createPropertiesSet(); + s.put(ss); } - return retPropSets.toArray(new PropertySet[retPropSets.size()]); + + ss.put(new NodeProperty<>("Type", "Type", "Type", getDisplayName())); + final BlackboardArtifact artifact = getArtifact(); + BlackboardArtifact.ARTIFACT_TYPE fromID = BlackboardArtifact.ARTIFACT_TYPE.fromID(getArtifact().getArtifactTypeID()); + if (null != fromID) { + switch (fromID) { + case TSK_EMAIL_MSG: + ss.put(new NodeProperty<>("From", "From", "From", + getAttributeDisplayString(artifact, TSK_EMAIL_FROM))); + ss.put(new NodeProperty<>("To", "To", "To", + getAttributeDisplayString(artifact, TSK_EMAIL_TO))); + ss.put(new NodeProperty<>("Date", "Date", "Date", + getAttributeDisplayString(artifact, TSK_DATETIME_SENT))); + ss.put(new NodeProperty<>("Subject", "Subject", "Subject", + getAttributeDisplayString(artifact, TSK_SUBJECT))); + break; + case TSK_MESSAGE: + ss.put(new NodeProperty<>("From", "From", "From", + getAttributeDisplayString(artifact, TSK_PHONE_NUMBER_FROM))); + ss.put(new NodeProperty<>("To", "To", "To", + getAttributeDisplayString(artifact, TSK_PHONE_NUMBER_TO))); + ss.put(new NodeProperty<>("Date", "Date", "Date", + getAttributeDisplayString(artifact, TSK_DATETIME))); + ss.put(new NodeProperty<>("Subject", "Subject", "Subject", + getAttributeDisplayString(artifact, TSK_SUBJECT))); + break; + case TSK_CALLLOG: + ss.put(new NodeProperty<>("From", "From", "From", + getAttributeDisplayString(artifact, TSK_PHONE_NUMBER_FROM))); + ss.put(new NodeProperty<>("To", "To", "To", + getAttributeDisplayString(artifact, TSK_PHONE_NUMBER_TO))); + ss.put(new NodeProperty<>("Date", "Date", "Date", + getAttributeDisplayString(artifact, TSK_DATETIME_START))); + break; + default: + break; + } + } + return s; } - private static final BlackboardAttribute.Type MSG_TYPE = new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_MESSAGE_TYPE); - private Sheet.Set copySet(PropertySet set) { - Sheet.Set set1 = new Sheet.Set(); - set1.setName(set.getName()); - set1.setDisplayName(set.getDisplayName()); - set1.setShortDescription(set.getShortDescription()); - return set1; + /** + * + * @param artifact the value of artifact + * @param attributeType the value of TSK_SUBJECT1 + * + * @throws TskCoreException + */ + private static String getAttributeDisplayString(final BlackboardArtifact artifact, final ATTRIBUTE_TYPE attributeType) { + try { + BlackboardAttribute attribute = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.fromID(attributeType.getTypeID()))); + if (attribute == null) { + return ""; + } else { + return attribute.getDisplayString(); + } + } catch (TskCoreException tskCoreException) { + logger.log(Level.WARNING, "Error getting attribute value.", tskCoreException); + return ""; + } } } From ca36a50b16d11ffe8666bed26f5a732798a6bba3 Mon Sep 17 00:00:00 2001 From: millmanorama Date: Wed, 1 Nov 2017 12:34:44 +0100 Subject: [PATCH 055/127] tweak MessageContentViewer for better resizing. eliminate nested scrollpanes --- .../autopsy/contentviewers/Bundle.properties | 2 +- .../contentviewers/MessageContentViewer.form | 172 ++++++++---------- .../contentviewers/MessageContentViewer.java | 115 ++++++------ 3 files changed, 131 insertions(+), 158 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/Bundle.properties b/Core/src/org/sleuthkit/autopsy/contentviewers/Bundle.properties index ed52040276..09048ca131 100755 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/Bundle.properties @@ -37,4 +37,4 @@ MessageContentViewer.directionText.text=direction MessageContentViewer.ccLabel.text=CC: MessageContentViewer.showImagesToggleButton.text=Show Images MessageContentViewer.showImagesToggleButton.hide.text=Hide Images -MessageContentViewer.htmlbodyScrollPane.TabConstraints.tabTitle=HTML +MessageContentViewer.htmlPane.TabConstraints.tabTitle=HTML diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.form b/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.form index a83f08d765..7c089d54a7 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.form +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.form @@ -3,7 +3,7 @@
- + @@ -21,22 +21,24 @@ - - - - + + + + + + + - + + - - - - + + @@ -53,53 +55,46 @@ - + - - - - - + - - - - + - + + + + + + - - - - - - - - - - - - - + + + + + + + + - + - + @@ -116,12 +111,12 @@ - + - + @@ -136,6 +131,7 @@ + @@ -192,6 +188,7 @@ + @@ -247,81 +244,64 @@ - + - + - + + + + + + + + + + + + + + + + + + + + + + - + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - + - - - + - - - + + + + + + + + + + diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java b/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java index 17ad5ba3d6..fc1df57e6d 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java @@ -43,6 +43,7 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont private static final int TEXT_TAB_INDEX = 1; private static final int HTML_TAB_INDEX = 2; private static final int RTF_TAB_INDEX = 3; + private static final long serialVersionUID = 1L; private BlackboardArtifact artifact; // Artifact currently being displayed @@ -79,20 +80,20 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont headersTextArea = new javax.swing.JTextArea(); textbodyScrollPane = new javax.swing.JScrollPane(); textbodyTextArea = new javax.swing.JTextArea(); - htmlbodyScrollPane = new javax.swing.JScrollPane(); - jPanel2 = new javax.swing.JPanel(); + htmlPane = new javax.swing.JPanel(); jScrollPane2 = new javax.swing.JScrollPane(); htmlbodyTextPane = new javax.swing.JTextPane(); showImagesToggleButton = new javax.swing.JToggleButton(); rtfbodyScrollPane = new javax.swing.JScrollPane(); rtfbodyTextPane = new javax.swing.JTextPane(); - setMinimumSize(new java.awt.Dimension(650, 546)); + setMinimumSize(null); envelopePanel.setBackground(new java.awt.Color(204, 204, 204)); org.openide.awt.Mnemonics.setLocalizedText(fromLabel, org.openide.util.NbBundle.getMessage(MessageContentViewer.class, "MessageContentViewer.fromLabel.text")); // NOI18N + datetimeText.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT); org.openide.awt.Mnemonics.setLocalizedText(datetimeText, org.openide.util.NbBundle.getMessage(MessageContentViewer.class, "MessageContentViewer.datetimeText.text")); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(fromText, org.openide.util.NbBundle.getMessage(MessageContentViewer.class, "MessageContentViewer.fromText.text")); // NOI18N @@ -109,6 +110,7 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont org.openide.awt.Mnemonics.setLocalizedText(subjectText, org.openide.util.NbBundle.getMessage(MessageContentViewer.class, "MessageContentViewer.subjectText.text")); // NOI18N + directionText.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT); org.openide.awt.Mnemonics.setLocalizedText(directionText, org.openide.util.NbBundle.getMessage(MessageContentViewer.class, "MessageContentViewer.directionText.text")); // NOI18N javax.swing.GroupLayout envelopePanelLayout = new javax.swing.GroupLayout(envelopePanel); @@ -116,40 +118,36 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont envelopePanelLayout.setHorizontalGroup( envelopePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(envelopePanelLayout.createSequentialGroup() - .addContainerGap() + .addGap(5, 5, 5) .addGroup(envelopePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(envelopePanelLayout.createSequentialGroup() .addGroup(envelopePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(fromLabel) .addComponent(toLabel)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addGroup(envelopePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(fromText, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(toText, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addGroup(envelopePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(envelopePanelLayout.createSequentialGroup() - .addGap(8, 8, 8) - .addComponent(datetimeText)) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, envelopePanelLayout.createSequentialGroup() + .addComponent(toText, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(directionText)))) + .addComponent(directionText, javax.swing.GroupLayout.PREFERRED_SIZE, 66, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(envelopePanelLayout.createSequentialGroup() + .addComponent(fromText, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(datetimeText, javax.swing.GroupLayout.PREFERRED_SIZE, 140, javax.swing.GroupLayout.PREFERRED_SIZE)))) .addGroup(envelopePanelLayout.createSequentialGroup() - .addGroup(envelopePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(envelopePanelLayout.createSequentialGroup() - .addComponent(ccLabel) - .addGap(18, 18, 18) - .addComponent(ccText)) - .addGroup(envelopePanelLayout.createSequentialGroup() - .addComponent(subjectLabel) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(subjectText, javax.swing.GroupLayout.PREFERRED_SIZE, 400, javax.swing.GroupLayout.PREFERRED_SIZE))) - .addGap(0, 0, Short.MAX_VALUE))) - .addContainerGap()) + .addComponent(ccLabel) + .addGap(26, 26, 26) + .addComponent(ccText, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addGroup(envelopePanelLayout.createSequentialGroup() + .addComponent(subjectLabel) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(subjectText, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))) + .addGap(5, 5, 5)) ); envelopePanelLayout.setVerticalGroup( envelopePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(envelopePanelLayout.createSequentialGroup() - .addContainerGap() + .addGap(5, 5, 5) .addGroup(envelopePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(fromLabel) .addComponent(datetimeText) @@ -163,11 +161,11 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont .addGroup(envelopePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(ccLabel) .addComponent(ccText)) - .addGap(18, 18, 18) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addGroup(envelopePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(subjectLabel) .addComponent(subjectText)) - .addContainerGap(24, Short.MAX_VALUE)) + .addGap(5, 5, 5)) ); headersTextArea.setEditable(false); @@ -194,35 +192,26 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont } }); - javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2); - jPanel2.setLayout(jPanel2Layout); - jPanel2Layout.setHorizontalGroup( - jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel2Layout.createSequentialGroup() - .addContainerGap(536, Short.MAX_VALUE) + javax.swing.GroupLayout htmlPaneLayout = new javax.swing.GroupLayout(htmlPane); + htmlPane.setLayout(htmlPaneLayout); + htmlPaneLayout.setHorizontalGroup( + htmlPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jScrollPane2) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, htmlPaneLayout.createSequentialGroup() + .addContainerGap(533, Short.MAX_VALUE) .addComponent(showImagesToggleButton) - .addContainerGap()) - .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(jPanel2Layout.createSequentialGroup() - .addContainerGap() - .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 623, Short.MAX_VALUE) - .addContainerGap())) + .addGap(3, 3, 3)) ); - jPanel2Layout.setVerticalGroup( - jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(jPanel2Layout.createSequentialGroup() - .addContainerGap() + htmlPaneLayout.setVerticalGroup( + htmlPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(htmlPaneLayout.createSequentialGroup() .addComponent(showImagesToggleButton) - .addContainerGap(333, Short.MAX_VALUE)) - .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel2Layout.createSequentialGroup() - .addGap(0, 34, Short.MAX_VALUE) - .addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 333, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jScrollPane2) + .addGap(0, 0, 0)) ); - htmlbodyScrollPane.setViewportView(jPanel2); - - msgbodyTabbedPane.addTab(org.openide.util.NbBundle.getMessage(MessageContentViewer.class, "MessageContentViewer.htmlbodyScrollPane.TabConstraints.tabTitle"), htmlbodyScrollPane); // NOI18N + msgbodyTabbedPane.addTab(org.openide.util.NbBundle.getMessage(MessageContentViewer.class, "MessageContentViewer.htmlPane.TabConstraints.tabTitle"), htmlPane); // NOI18N rtfbodyTextPane.setEditable(false); rtfbodyScrollPane.setViewportView(rtfbodyTextPane); @@ -233,20 +222,21 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont this.setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() - .addContainerGap() - .addComponent(envelopePanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addContainerGap()) - .addComponent(msgbodyTabbedPane) + .addGroup(layout.createSequentialGroup() + .addGap(5, 5, 5) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(msgbodyTabbedPane) + .addComponent(envelopePanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addGap(5, 5, 5)) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() - .addContainerGap() - .addComponent(envelopePanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGap(5, 5, 5) + .addComponent(envelopePanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(msgbodyTabbedPane, javax.swing.GroupLayout.PREFERRED_SIZE, 397, javax.swing.GroupLayout.PREFERRED_SIZE) - .addContainerGap()) + .addComponent(msgbodyTabbedPane, javax.swing.GroupLayout.DEFAULT_SIZE, 471, Short.MAX_VALUE) + .addGap(0, 0, 0)) ); }// //GEN-END:initComponents @@ -282,9 +272,8 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont private javax.swing.JLabel fromText; private javax.swing.JScrollPane headersScrollPane; private javax.swing.JTextArea headersTextArea; - private javax.swing.JScrollPane htmlbodyScrollPane; + private javax.swing.JPanel htmlPane; private javax.swing.JTextPane htmlbodyTextPane; - private javax.swing.JPanel jPanel2; private javax.swing.JScrollPane jScrollPane2; private javax.swing.JTabbedPane msgbodyTabbedPane; private javax.swing.JScrollPane rtfbodyScrollPane; @@ -311,7 +300,7 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont if (node == null) { return; } - + artifact = node.getLookup().lookup(BlackboardArtifact.class); if (artifact == null) { @@ -530,6 +519,10 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont /** * Cleans out input HTML string + * + * @param htmlInString The HTML string to cleanse + * + * @return The cleansed HTML String */ private String cleanseHTML(String htmlInString) { From 974bf77fc82a79a72776f17ac4f4558244fc0e97 Mon Sep 17 00:00:00 2001 From: millmanorama Date: Wed, 1 Nov 2017 12:45:55 +0100 Subject: [PATCH 056/127] refactor and cleanup slightly --- .../communications/AccountDetailsNode.java | 11 ++-- .../communications/MessageBrowser.java | 58 +++++++++++-------- 2 files changed, 40 insertions(+), 29 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/communications/AccountDetailsNode.java b/Core/src/org/sleuthkit/autopsy/communications/AccountDetailsNode.java index c428cbb3fd..34245f1a6d 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/AccountDetailsNode.java +++ b/Core/src/org/sleuthkit/autopsy/communications/AccountDetailsNode.java @@ -39,7 +39,7 @@ class AccountDetailsNode extends AbstractNode { private final CommunicationsFilter filter; //TODO: Use this AccountDetailsNode(Set accounts,CommunicationsFilter filter, CommunicationsManager commsManager) { - super(new AccountRelationshipChildren(accounts, commsManager)); + super(new AccountRelationshipChildren(accounts, commsManager, filter)); this.filter = filter; } @@ -50,10 +50,12 @@ class AccountDetailsNode extends AbstractNode { private final Set accounts; private final CommunicationsManager commsManager; + private final CommunicationsFilter filter;//TODO: Use this - private AccountRelationshipChildren(Set accounts, CommunicationsManager commsManager) { + private AccountRelationshipChildren(Set accounts, CommunicationsManager commsManager, CommunicationsFilter filter) { this.accounts = accounts; this.commsManager = commsManager; + this.filter = filter; } @Override @@ -67,14 +69,14 @@ class AccountDetailsNode extends AbstractNode { for (Account account : accounts) { List accountsWithRelationship = new ArrayList<>(); try { - accountsWithRelationship.addAll(commsManager.getAccountsWithRelationship(account)); //TODO: Use filter + accountsWithRelationship.addAll(commsManager.getAccountsWithRelationship(account)); //TODO: Use filter here } catch (TskCoreException ex) { logger.log(Level.WARNING, "Error loading with relationships to " + account, ex); } accountsWithRelationship.forEach(otherAcount -> { try { - keys.addAll(commsManager.getRelationships(account, otherAcount)); //TODO:Use filter + keys.addAll(commsManager.getRelationships(account, otherAcount)); //TODO:Use filter here } catch (TskCoreException ex) { logger.log(Level.WARNING, "Error loading relationships between " + account + " and " + otherAcount, ex); } @@ -83,5 +85,4 @@ class AccountDetailsNode extends AbstractNode { setKeys(keys); } } - } diff --git a/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.java b/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.java index 20a4388dae..e5c6704f10 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.java +++ b/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.java @@ -18,13 +18,16 @@ */ package org.sleuthkit.autopsy.communications; +import com.google.common.collect.Iterables; import java.util.HashSet; import java.util.Set; +import java.util.logging.Level; import org.openide.explorer.ExplorerManager; import org.openide.nodes.Node; import org.sleuthkit.autopsy.communications.AccountsRootChildren.AccountDeviceInstanceNode; import org.sleuthkit.autopsy.corecomponents.DataResultPanel; import org.sleuthkit.autopsy.corecomponents.TableFilterNode; +import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.datamodel.Account; import org.sleuthkit.datamodel.CommunicationsFilter; import org.sleuthkit.datamodel.CommunicationsManager; @@ -35,6 +38,8 @@ import org.sleuthkit.datamodel.CommunicationsManager; */ final class MessageBrowser extends javax.swing.JPanel implements ExplorerManager.Provider { + private static final Logger logger = Logger.getLogger(MessageBrowser.class.getName()); + private static final long serialVersionUID = 1L; private ExplorerManager parentExplorereManager; @@ -59,32 +64,37 @@ final class MessageBrowser extends javax.swing.JPanel implements ExplorerManager parentExplorereManager.addPropertyChangeListener(pce -> { if (pce.getPropertyName().equals(ExplorerManager.PROP_SELECTED_NODES)) { final Node[] selectedNodes = parentExplorereManager.getSelectedNodes(); - switch (selectedNodes.length) { - case 0: - messagesResultPanel.setNode(null); - break; - default: - Set accounts = new HashSet<>(); - CommunicationsFilter filter = null; - CommunicationsManager commsManager = null; - for (Node n : selectedNodes) { - if (n instanceof AccountDeviceInstanceNode) { - final AccountDeviceInstanceNode adiNode = (AccountDeviceInstanceNode) n; - accounts.add(adiNode.getAccountDeviceInstance().getAccount()); - if (commsManager == null) { - commsManager = adiNode.getCommsManager(); - } - if (filter == null) { - filter = adiNode.getFilter(); - } else if (filter != adiNode.getFilter()) { - //different filters ..... exception? - } - } else { - ///this should never happen... + if (selectedNodes.length == 0) { + messagesResultPanel.setNode(null); + messagesResultPanel.setPath(""); + } else { + Set accounts = new HashSet<>(); + CommunicationsFilter filter = null; + CommunicationsManager commsManager = null; + for (Node n : selectedNodes) { + if (n instanceof AccountDeviceInstanceNode) { + final AccountDeviceInstanceNode adiNode = (AccountDeviceInstanceNode) n; + accounts.add(adiNode.getAccountDeviceInstance().getAccount()); + if (commsManager == null) { + commsManager = adiNode.getCommsManager(); } + if (filter == null) { + filter = adiNode.getFilter(); + } else if (filter != adiNode.getFilter()) { + ///this should never happen... + logger.log(Level.WARNING, "Not all AccountDeviceInstanceNodes have the same filter. Using the first."); + } + } else { + ///this should never happen... + logger.log(Level.WARNING, "Unexpected Node encountered: " + n.toString()); } - messagesResultPanel.setNode(new TableFilterNode(new AccountDetailsNode(accounts, filter, commsManager), true)); - break; + } + messagesResultPanel.setNode(new TableFilterNode(new AccountDetailsNode(accounts, filter, commsManager), true)); + if (accounts.size() == 1) { + messagesResultPanel.setPath(Iterables.getOnlyElement(accounts).getAccountUniqueID()); + } else { + messagesResultPanel.setPath(accounts.size() + " accounts"); + } } } }); From ec89718520dce1f6b63faa09f956e6cd5f79a560 Mon Sep 17 00:00:00 2001 From: millmanorama Date: Thu, 2 Nov 2017 11:44:48 +0100 Subject: [PATCH 057/127] update and apply the filters when the CVT window is (re)opened --- .../communications/CVTTopComponent.java | 7 +- .../autopsy/communications/FiltersPanel.java | 88 +++++++++++++------ 2 files changed, 65 insertions(+), 30 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java b/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java index 9a108d3271..0618cb7fc4 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java +++ b/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java @@ -46,7 +46,6 @@ public final class CVTTopComponent extends TopComponent implements ExplorerManag private final ExplorerManager em = new ExplorerManager(); public CVTTopComponent() { - initComponents(); setName(Bundle.CVTTopComponent_name()); splitPane.setRightComponent(new MessageBrowser()); @@ -137,7 +136,11 @@ public final class CVTTopComponent extends TopComponent implements ExplorerManag @Override public void open() { super.open(); - filtersPane.updateFilters(); + /* + * when the window is (re)opened make sure the filters and accounts are + * in a up to date and consistent state. + */ + filtersPane.updateAndApplyFilters(); } @Override diff --git a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java index 90cee25853..0a6b74524d 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java +++ b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java @@ -18,7 +18,6 @@ */ package org.sleuthkit.autopsy.communications; -import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -32,7 +31,6 @@ import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.ThreadConfined; import org.sleuthkit.datamodel.Account; -import org.sleuthkit.datamodel.AccountDeviceInstance; import org.sleuthkit.datamodel.AccountTypeFilter; import org.sleuthkit.datamodel.CommunicationsFilter; import org.sleuthkit.datamodel.CommunicationsManager; @@ -42,7 +40,7 @@ import org.sleuthkit.datamodel.TskCoreException; /** * Panel that holds the Filter control widgets and translates user filtering - * changes into queries against the CommunicationsManager + * changes into queries against the CommunicationsManager. */ final public class FiltersPanel extends javax.swing.JPanel { @@ -58,17 +56,27 @@ final public class FiltersPanel extends javax.swing.JPanel { public FiltersPanel() { initComponents(); - updateFilters(); + updateAndApplyFilters(); } - void updateFilters() { + /** + * Update the filter widgets, and apply them. + */ + void updateAndApplyFilters() { updateAccountTypeFilter(); updateDeviceFilter(); + if (em != null) { + applyFilters(); + } } @Override public void addNotify() { super.addNotify(); + /* + * Since we get the exploreremanager from the parent JComponenet, wait + * till this FiltersPanel is actaully added to a parent. + */ em = ExplorerManager.find(this); } @@ -282,36 +290,38 @@ final public class FiltersPanel extends javax.swing.JPanel { }// //GEN-END:initComponents private void applyFiltersButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_applyFiltersButtonActionPerformed + applyFilters(); + }//GEN-LAST:event_applyFiltersButtonActionPerformed + + /** + * Query for accounts using the selected filters, and send the results to + * the AccountsBrowser via the ExplorerManager. + */ + private void applyFilters() { + CommunicationsFilter commsFilter = new CommunicationsFilter(); + commsFilter.addAndFilter(getDevceFilter()); + commsFilter.addAndFilter(getAccountTypeFilter()); - /* - * When the apply button is pressed, query for accounts using the - * selected filters, and send the results to the AccountsBrowser via the - * ExplorerManager. - * - * TODO: This will need to be adapted to any changes in the - * Comunications Manager API, such as using Filter objcts built from the - * state of the checkboxes and the result types changing from Accounts - * to AccountDeviceInstances - */ try { - List accountDeviceInstances = new ArrayList<>(); - CommunicationsFilter commsFilter = new CommunicationsFilter(); - commsFilter.addAndFilter(getDevceFilter()); - - commsFilter.addAndFilter(getAccountTypeFilter()); final CommunicationsManager commsManager = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager(); - accountDeviceInstances.addAll(commsManager.getAccountDeviceInstancesWithRelationships(commsFilter)); - List accountDeviceInstanceKeys = new ArrayList<>(); - accountDeviceInstances.forEach(accountDeviceInstance - -> accountDeviceInstanceKeys.add(new AccountDeviceInstanceKey(accountDeviceInstance, commsFilter))); + List accountDeviceInstanceKeys = + commsManager.getAccountDeviceInstancesWithRelationships(commsFilter) + .stream() + .map(adi -> new AccountDeviceInstanceKey(adi, commsFilter)) + .collect(Collectors.toList()); em.setRootContext(new AbstractNode(new AccountsRootChildren(accountDeviceInstanceKeys, commsManager))); } catch (TskCoreException ex) { logger.log(Level.SEVERE, "There was a error loading the accounts.", ex); } - }//GEN-LAST:event_applyFiltersButtonActionPerformed + } + /** + * Get a DeviceFilter that matches the state of the UI widgets. + * + * @return a DeviceFilter + */ private DeviceFilter getDevceFilter() { DeviceFilter deviceFilter = new DeviceFilter(devicesMap.entrySet().stream() .filter(entry -> entry.getValue().isSelected()) @@ -319,6 +329,11 @@ final public class FiltersPanel extends javax.swing.JPanel { return deviceFilter; } + /** + * Get an AccountTypeFilter that matches the state of the UI widgets + * + * @return an AccountTypeFilter + */ private AccountTypeFilter getAccountTypeFilter() { AccountTypeFilter accountTypeFilter = new AccountTypeFilter(accountTypeMap.entrySet().stream() .filter(entry -> entry.getValue().isSelected()) @@ -326,26 +341,43 @@ final public class FiltersPanel extends javax.swing.JPanel { return accountTypeFilter; } + /** + * Set the selection state of all the account type check boxes + * + * @param selected The selection state to set the check boxes to. + */ @ThreadConfined(type = ThreadConfined.ThreadType.AWT) - private void setAllTypesSelected(boolean selected) { + private void setAllAccountTypesSelected(boolean selected) { setAllSelected(accountTypeMap, selected); } + /** + * Set the selection state of all the device check boxes + * + * @param selected The selection state to set the check boxes to. + */ @ThreadConfined(type = ThreadConfined.ThreadType.AWT) private void setAllDevicesSelected(boolean selected) { setAllSelected(devicesMap, selected); } + /** + * Helper method that sets all the checkboxes in the given map to the given + * selection state. + * + * @param map A map from anything to JCheckBoxes. + * @param selected The selection state to set all the checkboxes to. + */ @ThreadConfined(type = ThreadConfined.ThreadType.AWT) private void setAllSelected(Map map, boolean selected) { map.values().forEach(box -> box.setSelected(selected)); } private void unCheckAllAccountTypesButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_unCheckAllAccountTypesButtonActionPerformed - setAllTypesSelected(false); + setAllAccountTypesSelected(false); }//GEN-LAST:event_unCheckAllAccountTypesButtonActionPerformed private void checkAllAccountTypesButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_checkAllAccountTypesButtonActionPerformed - setAllTypesSelected(true); + setAllAccountTypesSelected(true); }//GEN-LAST:event_checkAllAccountTypesButtonActionPerformed private void unCheckAllDevicesButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_unCheckAllDevicesButtonActionPerformed From 2a1cb8d78b9ddb54900209546e6ca72b88842d42 Mon Sep 17 00:00:00 2001 From: millmanorama Date: Thu, 2 Nov 2017 13:57:59 +0100 Subject: [PATCH 058/127] allow custom DataResultViewerTable titles --- .../communications/MessageBrowser.java | 3 +++ .../corecomponents/DataResultPanel.java | 2 +- .../corecomponents/DataResultViewerTable.java | 20 ++++++++++++++++--- 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.java b/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.java index e5c6704f10..b58fa590ff 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.java +++ b/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.java @@ -26,6 +26,7 @@ import org.openide.explorer.ExplorerManager; import org.openide.nodes.Node; import org.sleuthkit.autopsy.communications.AccountsRootChildren.AccountDeviceInstanceNode; import org.sleuthkit.autopsy.corecomponents.DataResultPanel; +import org.sleuthkit.autopsy.corecomponents.DataResultViewerTable; import org.sleuthkit.autopsy.corecomponents.TableFilterNode; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.datamodel.Account; @@ -49,6 +50,8 @@ final class MessageBrowser extends javax.swing.JPanel implements ExplorerManager MessageBrowser() { initComponents(); messagesResultPanel = DataResultPanel.createInstanceUninitialized("Account", "", Node.EMPTY, 0, messageDataContent); + messagesResultPanel.addResultViewer(new DataResultViewerTable("Messages")); + splitPane.setTopComponent(messagesResultPanel); splitPane.setBottomComponent(messageDataContent); diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultPanel.java b/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultPanel.java index e5252e035b..09b292dd29 100755 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultPanel.java +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultPanel.java @@ -246,7 +246,7 @@ public class DataResultPanel extends javax.swing.JPanel implements DataResult, C * * @param resultViewer The result viewer. */ - private void addResultViewer(DataResultViewer resultViewer) { + public void addResultViewer(DataResultViewer resultViewer) { if (null != contentView) { resultViewer.setContentViewer(contentView); } diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerTable.java b/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerTable.java index c09ebc92f3..66a1d33ad5 100755 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerTable.java +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerTable.java @@ -80,6 +80,8 @@ public class DataResultViewerTable extends AbstractDataResultViewer { @NbBundle.Messages("DataResultViewerTable.firstColLbl=Name") static private final String FIRST_COLUMN_LABEL = Bundle.DataResultViewerTable_firstColLbl(); private static final Color TAGGED_COLOR = new Color(255, 255, 195); + + private final String title; /** * The properties map: * @@ -118,14 +120,26 @@ public class DataResultViewerTable extends AbstractDataResultViewer { */ public DataResultViewerTable(ExplorerManager explorerManager) { super(explorerManager); + title = Bundle.DataResultViewerTable_title(); initialize(); } /** * Creates a DataResultViewerTable object that is NOT compatible with node - * multiple selection actions. + * multiple selection actions, and with the default title. */ public DataResultViewerTable() { + this(Bundle.DataResultViewerTable_title()); + } + + /** + * Creates a DataResultViewerTable object that is NOT compatible with node + * multiple selection actions, and with a custom title. + * + * @param title The title for this DataResultViewer. + */ + public DataResultViewerTable(String title) { + this.title = title; initialize(); } @@ -579,7 +593,7 @@ public class DataResultViewerTable extends AbstractDataResultViewer { @Override @NbBundle.Messages("DataResultViewerTable.title=Table") public String getTitle() { - return Bundle.DataResultViewerTable_title(); + return title; } @Override @@ -764,7 +778,7 @@ public class DataResultViewerTable extends AbstractDataResultViewer { Component component = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, col); // only override the color if a node is not selected - if (currentRoot != null && !isSelected) { + if (currentRoot != null && !isSelected) { Node node = currentRoot.getChildren().getNodeAt(table.convertRowIndexToModel(row)); boolean tagFound = false; if (node != null) { From 8219599fc4f652ca77365b799700ef528f0da6a4 Mon Sep 17 00:00:00 2001 From: millmanorama Date: Thu, 2 Nov 2017 14:21:34 +0100 Subject: [PATCH 059/127] use correct ExplorerManager in DataResultViewerTable constructor, reorganize constructors for better code reuse. --- .../communications/MessageBrowser.java | 5 ++- .../AbstractDataResultViewer.java | 13 ++---- .../corecomponents/DataResultViewerTable.java | 45 +++++++++---------- 3 files changed, 28 insertions(+), 35 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.java b/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.java index b58fa590ff..8570074269 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.java +++ b/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.java @@ -50,8 +50,7 @@ final class MessageBrowser extends javax.swing.JPanel implements ExplorerManager MessageBrowser() { initComponents(); messagesResultPanel = DataResultPanel.createInstanceUninitialized("Account", "", Node.EMPTY, 0, messageDataContent); - messagesResultPanel.addResultViewer(new DataResultViewerTable("Messages")); - + splitPane.setTopComponent(messagesResultPanel); splitPane.setBottomComponent(messageDataContent); @@ -101,6 +100,8 @@ final class MessageBrowser extends javax.swing.JPanel implements ExplorerManager } } }); + messagesResultPanel.addResultViewer(new DataResultViewerTable(internalExplorerManager,"Messages")); + messagesResultPanel.open(); } diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/AbstractDataResultViewer.java b/Core/src/org/sleuthkit/autopsy/corecomponents/AbstractDataResultViewer.java index 13fda58c20..fcbb1233e9 100755 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/AbstractDataResultViewer.java +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/AbstractDataResultViewer.java @@ -56,7 +56,9 @@ abstract class AbstractDataResultViewer extends JPanel implements DataResultView */ public AbstractDataResultViewer(ExplorerManager explorerManager) { this.em = explorerManager; - initialize(); + //DataContent is designed to return only the default viewer from lookup + //use the default one unless set otherwise + contentViewer = Lookup.getDefault().lookup(DataContent.class); } /** @@ -65,14 +67,7 @@ abstract class AbstractDataResultViewer extends JPanel implements DataResultView * context lookup. */ public AbstractDataResultViewer() { - em = new ExplorerManager(); - initialize(); - } - - private void initialize() { - //DataContent is designed to return only the default viewer from lookup - //use the default one unless set otherwise - contentViewer = Lookup.getDefault().lookup(DataContent.class); + this(new ExplorerManager()); } @Override diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerTable.java b/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerTable.java index 66a1d33ad5..fe21a4ca55 100755 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerTable.java +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerTable.java @@ -82,6 +82,7 @@ public class DataResultViewerTable extends AbstractDataResultViewer { private static final Color TAGGED_COLOR = new Color(255, 255, 195); private final String title; + /** * The properties map: * @@ -110,50 +111,37 @@ public class DataResultViewerTable extends AbstractDataResultViewer { /** * Listener for table model event and mouse clicks. */ - private TableListener tableListener; + private final TableListener tableListener; /** * Creates a DataResultViewerTable object that is compatible with node - * multiple selection actions. + * multiple selection actions, and the default title. * * @param explorerManager allow for explorer manager sharing */ public DataResultViewerTable(ExplorerManager explorerManager) { - super(explorerManager); - title = Bundle.DataResultViewerTable_title(); - initialize(); + this(explorerManager, Bundle.DataResultViewerTable_title()); } /** - * Creates a DataResultViewerTable object that is NOT compatible with node - * multiple selection actions, and with the default title. - */ - public DataResultViewerTable() { - this(Bundle.DataResultViewerTable_title()); - } - - /** - * Creates a DataResultViewerTable object that is NOT compatible with node - * multiple selection actions, and with a custom title. + * Creates a DataResultViewerTable object that is compatible with node + * multiple selection actions, and a custom title. * - * @param title The title for this DataResultViewer. + * @param explorerManager allow for explorer manager sharing + * @param title The custom title. */ - public DataResultViewerTable(String title) { + public DataResultViewerTable(ExplorerManager explorerManager, String title) { + super(explorerManager); this.title = title; - initialize(); - } - - private void initialize() { + initComponents(); - + outlineView.setAllowedDragActions(DnDConstants.ACTION_NONE); - outline = outlineView.getOutline(); outline.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); outline.setRootVisible(false); // don't show the root node outline.setDragEnabled(false); outline.setDefaultRenderer(Object.class, new ColorTagCustomRenderer()); - // add a listener so that when columns are moved, the new order is stored tableListener = new TableListener(); outline.getColumnModel().addColumnModelListener(tableListener); @@ -161,6 +149,15 @@ public class DataResultViewerTable extends AbstractDataResultViewer { outline.getTableHeader().addMouseListener(tableListener); } + /** + * Creates a DataResultViewerTable object that is NOT compatible with node + * multiple selection actions. + */ + public DataResultViewerTable() { + this(new ExplorerManager(),Bundle.DataResultViewerTable_title()); + } + + /** * Expand node * From ff8bc0f44672ce7f209e9eb23c2462efac2279d6 Mon Sep 17 00:00:00 2001 From: Raman Date: Thu, 2 Nov 2017 09:25:53 -0400 Subject: [PATCH 060/127] Fix typo. --- .../org/sleuthkit/autopsy/communications/FiltersPanel.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java index dea43916a7..5058dce36a 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java +++ b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java @@ -301,7 +301,7 @@ final public class FiltersPanel extends javax.swing.JPanel { try { List accountDeviceInstances = new ArrayList<>(); CommunicationsFilter commsFilter = new CommunicationsFilter(); - commsFilter.addAndFilter(getDevceFilter()); + commsFilter.addAndFilter(getDeviceFilter()); commsFilter.addAndFilter(getAccountTypeFilter()); final CommunicationsManager communicationsManager = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager(); @@ -318,7 +318,7 @@ final public class FiltersPanel extends javax.swing.JPanel { } }//GEN-LAST:event_applyFiltersButtonActionPerformed - private DeviceFilter getDevceFilter() { + private DeviceFilter getDeviceFilter() { DeviceFilter deviceFilter = new DeviceFilter(devicesMap.entrySet().stream() .filter(entry -> entry.getValue().isSelected()) .map(Entry::getKey).collect(Collectors.toSet())); From 670ade9b0e9c9f9fb8647a302fc98461197ebce8 Mon Sep 17 00:00:00 2001 From: Raman Date: Thu, 2 Nov 2017 13:01:38 -0400 Subject: [PATCH 061/127] Updated the getRelationshipsCount() method call to match the new API definition. --- .../sleuthkit/autopsy/communications/AccountsRootChildren.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/communications/AccountsRootChildren.java b/Core/src/org/sleuthkit/autopsy/communications/AccountsRootChildren.java index 3da39f6776..12fa9f0567 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/AccountsRootChildren.java +++ b/Core/src/org/sleuthkit/autopsy/communications/AccountsRootChildren.java @@ -115,7 +115,7 @@ class AccountsRootChildren extends Children.Keys { } long msgCount = 0; try { - msgCount = commsManager.getRelationshipsCount(filter, accountDeviceInstance); + msgCount = commsManager.getRelationshipsCount(accountDeviceInstance.getAccount(), filter ); } catch (TskCoreException ex) { LOGGER.log(Level.WARNING, "Failed to get message count for account", ex); //NON-NLS } From 7a48fe66054c38d13ea376c8c2e9296e1bf69f9e Mon Sep 17 00:00:00 2001 From: millmanorama Date: Sun, 5 Nov 2017 15:20:03 +0100 Subject: [PATCH 062/127] cleanup MessageContentViewer, reset when an unsupported node is selected. --- .../autopsy/contentviewers/Bundle.properties | 13 +- .../contentviewers/MessageContentViewer.form | 9 +- .../contentviewers/MessageContentViewer.java | 237 +++++++----------- 3 files changed, 97 insertions(+), 162 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/Bundle.properties b/Core/src/org/sleuthkit/autopsy/contentviewers/Bundle.properties index 09048ca131..e0a5e749d2 100755 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/Bundle.properties @@ -17,24 +17,17 @@ Metadata.toolTip=Displays metadata about the file. Metadata.nodeText.nonFilePassedIn=Non-file passed in Metadata.nodeText.text=From The Sleuth Kit istat Tool\: Metadata.nodeText.exceptionNotice.text=Error getting file metadata\: -MessageContentViewer.title=Message -MessageContentViewer.toolTip=Displays messages. -MessageContentViewer.jPanel2.TabConstraints.tabTitle=tab1 -MessageContentViewer.jPanel3.TabConstraints.tabTitle=tab2 -MessageContentViewer.jPanel4.TabConstraints.tabTitle=tab3 MessageContentViewer.rtfbodyScrollPane.TabConstraints.tabTitle=RTF MessageContentViewer.headersScrollPane.TabConstraints.tabTitle=Headers MessageContentViewer.textbodyScrollPane.TabConstraints.tabTitle=Text +MessageContentViewer.htmlPane.TabConstraints.tabTitle=HTML MessageContentViewer.fromText.text=from address goes here MessageContentViewer.fromLabel.text=From: -MessageContentViewer.datetimeText.text=Right Anchored +MessageContentViewer.datetimeText.text=date goes here MessageContentViewer.toText.text=to list goes here MessageContentViewer.toLabel.text=To: MessageContentViewer.ccText.text=cc list goes here MessageContentViewer.subjectLabel.text=Subject: -MessageContentViewer.subjectText.text=jLabel6 +MessageContentViewer.subjectText.text=subject goes here MessageContentViewer.directionText.text=direction MessageContentViewer.ccLabel.text=CC: -MessageContentViewer.showImagesToggleButton.text=Show Images -MessageContentViewer.showImagesToggleButton.hide.text=Hide Images -MessageContentViewer.htmlPane.TabConstraints.tabTitle=HTML diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.form b/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.form index 7c089d54a7..73d96ff6b5 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.form +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.form @@ -1,11 +1,6 @@ - - - - - @@ -66,12 +61,12 @@ - + - + diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java b/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java index fc1df57e6d..4b89603aff 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java @@ -19,6 +19,7 @@ package org.sleuthkit.autopsy.contentviewers; import java.awt.Component; +import java.util.Optional; import java.util.logging.Level; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; @@ -29,6 +30,20 @@ import org.sleuthkit.autopsy.corecomponentinterfaces.DataContentViewer; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardAttribute; +import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME; +import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_RCVD; +import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DIRECTION; +import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_CC; +import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_CONTENT_HTML; +import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_CONTENT_PLAIN; +import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_CONTENT_RTF; +import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_FROM; +import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_TO; +import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_HEADERS; +import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_FROM; +import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_TO; +import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SUBJECT; +import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_TEXT; import org.sleuthkit.datamodel.TskCoreException; /** @@ -52,7 +67,9 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont */ public MessageContentViewer() { initComponents(); - customizeComponents(); + Utilities.configureTextPaneAsHtml(htmlbodyTextPane); + Utilities.configureTextPaneAsRtf(rtfbodyTextPane); + resetComponent(); } /** @@ -87,8 +104,6 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont rtfbodyScrollPane = new javax.swing.JScrollPane(); rtfbodyTextPane = new javax.swing.JTextPane(); - setMinimumSize(null); - envelopePanel.setBackground(new java.awt.Color(204, 204, 204)); org.openide.awt.Mnemonics.setLocalizedText(fromLabel, org.openide.util.NbBundle.getMessage(MessageContentViewer.class, "MessageContentViewer.fromLabel.text")); // NOI18N @@ -128,11 +143,11 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont .addGroup(envelopePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(envelopePanelLayout.createSequentialGroup() .addComponent(toText, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(directionText, javax.swing.GroupLayout.PREFERRED_SIZE, 66, javax.swing.GroupLayout.PREFERRED_SIZE)) .addGroup(envelopePanelLayout.createSequentialGroup() .addComponent(fromText, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(datetimeText, javax.swing.GroupLayout.PREFERRED_SIZE, 140, javax.swing.GroupLayout.PREFERRED_SIZE)))) .addGroup(envelopePanelLayout.createSequentialGroup() .addComponent(ccLabel) @@ -240,20 +255,18 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont ); }// //GEN-END:initComponents + @NbBundle.Messages({"MessageContentViewer.showImagesToggleButton.hide.text=Hide Images", + "MessageContentViewer.showImagesToggleButton.text=Show Images"}) private void showImagesToggleButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_showImagesToggleButtonActionPerformed - try { - BlackboardAttribute attr = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_CONTENT_HTML)); - if (attr != null && !attr.getValueString().isEmpty()) { - + String htmlText = getAttributeValueSafe(artifact, TSK_EMAIL_CONTENT_HTML); + if (!htmlText.isEmpty()) { if (showImagesToggleButton.isSelected()) { - showImagesToggleButton.setText(org.openide.util.NbBundle.getMessage(MessageContentViewer.class, "MessageContentViewer.showImagesToggleButton.hide.text")); - - this.htmlbodyTextPane.setText("" + attr.getValueString() + ""); + showImagesToggleButton.setText(Bundle.MessageContentViewer_showImagesToggleButton_hide_text()); + this.htmlbodyTextPane.setText(wrapInHtmlBody(htmlText)); } else { - showImagesToggleButton.setText(org.openide.util.NbBundle.getMessage(MessageContentViewer.class, "MessageContentViewer.showImagesToggleButton.text")); - - this.htmlbodyTextPane.setText("" + cleanseHTML(attr.getValueString()) + ""); + showImagesToggleButton.setText(Bundle.MessageContentViewer_showImagesToggleButton_text()); + this.htmlbodyTextPane.setText(wrapInHtmlBody(cleanseHTML(htmlText))); } } } catch (TskCoreException ex) { @@ -287,23 +300,17 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont private javax.swing.JLabel toText; // End of variables declaration//GEN-END:variables - private void customizeComponents() { - // do any customizations here - Utilities.configureTextPaneAsHtml(htmlbodyTextPane); - Utilities.configureTextPaneAsRtf(rtfbodyTextPane); - - } - @Override public void setNode(Node node) { if (node == null) { + resetComponent(); return; } artifact = node.getLookup().lookup(BlackboardArtifact.class); - if (artifact == null) { + resetComponent(); return; } @@ -311,18 +318,22 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont displayMsg(); } else if (artifact.getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_EMAIL_MSG.getTypeID()) { displayEmailMsg(); + } else { + resetComponent(); } } @Override + @NbBundle.Messages("MessageContentViewer.title=Message") public String getTitle() { - return NbBundle.getMessage(this.getClass(), "MessageContentViewer.title"); + return Bundle.MessageContentViewer_title(); } @Override + @NbBundle.Messages("MessageContentViewer.toolTip=Displays messages.") public String getToolTip() { - return NbBundle.getMessage(this.getClass(), "MessageContentViewer.toolTip"); + return Bundle.MessageContentViewer_toolTip(); } @Override @@ -336,8 +347,15 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont } @Override - public void resetComponent() { + final public void resetComponent() { // reset all fields + fromText.setText(""); + toText.setText(""); + ccText.setText(""); + subjectText.setText(""); + datetimeText.setText(""); + directionText.setText(""); + setEnabled(false); } @Override @@ -358,163 +376,94 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont } private void displayEmailMsg() { - directionText.setVisible(false); - + setEnabled(true); + directionText.setText(""); showImagesToggleButton.setVisible(false); showImagesToggleButton.setText("Show Images"); showImagesToggleButton.setSelected(false); try { - BlackboardAttribute attr = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_FROM)); - this.fromText.setText(attr.getValueString()); + this.fromText.setText(getAttributeValueSafe(artifact, TSK_EMAIL_FROM)); + this.toText.setText(getAttributeValueSafe(artifact, TSK_EMAIL_TO)); + this.ccText.setText(getAttributeValueSafe(artifact, TSK_EMAIL_CC)); + this.subjectText.setText(getAttributeValueSafe(artifact, TSK_SUBJECT)); + this.datetimeText.setText(getAttributeValueSafe(artifact, TSK_DATETIME_RCVD)); - attr = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_TO)); - if (attr != null) { - this.toText.setText(attr.getValueString()); - } - - attr = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_CC)); - if (attr != null && !attr.getValueString().isEmpty()) { - this.ccText.setVisible(true); - this.ccText.setText(attr.getValueString()); + String headersText = getAttributeValueSafe(artifact, TSK_HEADERS); + if (!headersText.isEmpty()) { + this.headersTextArea.setText(headersText); + msgbodyTabbedPane.setEnabledAt(HDR_TAB_INDEX, true); + msgbodyTabbedPane.setSelectedIndex(HDR_TAB_INDEX); } else { - this.ccText.setVisible(false); + msgbodyTabbedPane.setEnabledAt(HDR_TAB_INDEX, false); } - attr = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SUBJECT)); - if (attr != null && !attr.getValueString().isEmpty()) { - this.subjectText.setVisible(true); - this.subjectText.setText(attr.getValueString()); - } else { - this.subjectText.setVisible(false); - } - - attr = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_RCVD)); - if (attr != null && !attr.getDisplayString().isEmpty()) { - this.datetimeText.setVisible(true); - this.datetimeText.setText(attr.getDisplayString()); - } else { - this.datetimeText.setVisible(false); - } - - int selectedTabIndex = -1; - attr = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_CONTENT_PLAIN)); - if (attr != null && !attr.getValueString().isEmpty()) { - this.textbodyTextArea.setVisible(true); - this.textbodyTextArea.setText(attr.getValueString()); - + String plainText = getAttributeValueSafe(artifact, TSK_EMAIL_CONTENT_PLAIN); + if (!plainText.isEmpty()) { + this.textbodyTextArea.setText(plainText); msgbodyTabbedPane.setEnabledAt(TEXT_TAB_INDEX, true); - selectedTabIndex = TEXT_TAB_INDEX; + msgbodyTabbedPane.setSelectedIndex(TEXT_TAB_INDEX); } else { msgbodyTabbedPane.setEnabledAt(TEXT_TAB_INDEX, false); } - - attr = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_CONTENT_HTML)); - if (attr != null && !attr.getValueString().isEmpty()) { - + String htmlText = getAttributeValueSafe(artifact, TSK_EMAIL_CONTENT_HTML); + if (!htmlText.isEmpty()) { this.showImagesToggleButton.setVisible(true); - - this.htmlbodyTextPane.setVisible(true); - this.htmlbodyTextPane.setText("" + cleanseHTML(attr.getValueString()) + ""); - //this.htmlbodyTextPane.setText(cleanseHTML(attr.getValueString())); - + this.htmlbodyTextPane.setText(wrapInHtmlBody(cleanseHTML(htmlText))); msgbodyTabbedPane.setEnabledAt(HTML_TAB_INDEX, true); - selectedTabIndex = HTML_TAB_INDEX; + msgbodyTabbedPane.setSelectedIndex(HTML_TAB_INDEX); } else { msgbodyTabbedPane.setEnabledAt(HTML_TAB_INDEX, false); this.htmlbodyTextPane.setVisible(false); } - attr = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_CONTENT_RTF)); - if (attr != null && !attr.getValueString().isEmpty()) { - - this.rtfbodyTextPane.setVisible(true); - this.rtfbodyTextPane.setText(attr.getValueString()); - + String rtfText = getAttributeValueSafe(artifact, TSK_EMAIL_CONTENT_RTF); + if (!rtfText.isEmpty()) { + this.rtfbodyTextPane.setText(rtfText); msgbodyTabbedPane.setEnabledAt(RTF_TAB_INDEX, true); - selectedTabIndex = RTF_TAB_INDEX; + msgbodyTabbedPane.setSelectedIndex(RTF_TAB_INDEX); } else { msgbodyTabbedPane.setEnabledAt(RTF_TAB_INDEX, false); } - attr = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_HEADERS)); - if (attr != null && !attr.getValueString().isEmpty()) { - this.headersTextArea.setVisible(true); - this.headersTextArea.setText(attr.getValueString()); - if (selectedTabIndex < 0) { - selectedTabIndex = HDR_TAB_INDEX; - } - } else { - msgbodyTabbedPane.setEnabledAt(HDR_TAB_INDEX, false); - } - - msgbodyTabbedPane.setSelectedIndex(selectedTabIndex); } catch (TskCoreException ex) { LOGGER.log(Level.WARNING, "Failed to get attributes for email message.", ex); //NON-NLS } } - private void displayMsg() { + private static String wrapInHtmlBody(String htmlText) { + return "" + cleanseHTML(htmlText) + ""; + } - this.ccText.setVisible(false); + private void displayMsg() { + setEnabled(true); + this.ccText.setText(""); this.showImagesToggleButton.setVisible(false); msgbodyTabbedPane.setEnabledAt(HTML_TAB_INDEX, false); msgbodyTabbedPane.setEnabledAt(RTF_TAB_INDEX, false); msgbodyTabbedPane.setEnabledAt(HDR_TAB_INDEX, false); try { + this.fromText.setText(getAttributeValueSafe(artifact, TSK_PHONE_NUMBER_FROM)); + this.toText.setText(getAttributeValueSafe(artifact, TSK_PHONE_NUMBER_TO)); + this.directionText.setText(getAttributeValueSafe(artifact, TSK_DIRECTION)); + this.subjectText.setText(getAttributeValueSafe(artifact, TSK_SUBJECT)); + this.datetimeText.setText(getAttributeValueSafe(artifact, TSK_DATETIME)); + this.datetimeText.setText(getAttributeValueSafe(artifact, TSK_DATETIME)); - BlackboardAttribute attr = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_FROM)); - if (attr != null) { - this.fromText.setText(attr.getValueString()); - } else { - this.fromText.setVisible(false); - } - - attr = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_TO)); - if (attr != null) { - this.toText.setText(attr.getValueString()); - } else { - this.toText.setVisible(false); - } - - attr = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DIRECTION)); - if (attr != null) { - this.directionText.setText(attr.getValueString()); - } else { - this.directionText.setVisible(false); - } - - attr = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SUBJECT)); - if (attr != null && !attr.getValueString().isEmpty()) { - this.subjectText.setVisible(true); - this.subjectText.setText(attr.getValueString()); - } else { - this.subjectText.setVisible(false); - } - - attr = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME)); - if (attr != null && !attr.getDisplayString().isEmpty()) { - this.datetimeText.setVisible(true); - this.datetimeText.setText(attr.getDisplayString()); - } else { - this.datetimeText.setVisible(false); - } - - attr = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_TEXT)); - if (attr != null && !attr.getValueString().isEmpty()) { - this.textbodyTextArea.setVisible(true); - this.textbodyTextArea.setText(attr.getValueString()); - - msgbodyTabbedPane.setEnabledAt(TEXT_TAB_INDEX, true); - } else { - msgbodyTabbedPane.setEnabledAt(TEXT_TAB_INDEX, false); - } + String text = getAttributeValueSafe(artifact, TSK_TEXT); + this.textbodyTextArea.setText(text); + msgbodyTabbedPane.setEnabledAt(TEXT_TAB_INDEX, text.isEmpty() == false); msgbodyTabbedPane.setSelectedIndex(TEXT_TAB_INDEX); } catch (TskCoreException ex) { LOGGER.log(Level.WARNING, "Failed to get attributes for message.", ex); //NON-NLS } + } + String getAttributeValueSafe(BlackboardArtifact artifact, BlackboardAttribute.ATTRIBUTE_TYPE type) throws TskCoreException { + return Optional.ofNullable(artifact.getAttribute(new BlackboardAttribute.Type(type))) + .map(BlackboardAttribute::getDisplayString) + .orElse(""); } /** @@ -524,14 +473,12 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont * * @return The cleansed HTML String */ - private String cleanseHTML(String htmlInString) { + static private String cleanseHTML(String htmlInString) { Document doc = Jsoup.parse(htmlInString); - // fix all img tags - doc.select("img[src]").forEach((img) -> { - img.attr("src", ""); - }); + //fix all img tags + doc.select("img[src]").forEach(img -> img.attr("src", "")); return doc.html(); } From 6e5851e98f0a60f1751172b569b31327ad357038 Mon Sep 17 00:00:00 2001 From: millmanorama Date: Sun, 5 Nov 2017 16:35:16 +0100 Subject: [PATCH 063/127] refactor to get rid of a lot of duplicate code --- .../contentviewers/MessageContentViewer.form | 10 +- .../contentviewers/MessageContentViewer.java | 106 ++++++++---------- 2 files changed, 54 insertions(+), 62 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.form b/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.form index 73d96ff6b5..98f27a6351 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.form +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.form @@ -19,7 +19,7 @@ - + @@ -29,11 +29,11 @@ - + - - - + + + diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java b/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java index 4b89603aff..acbcb9ead1 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2013-2014 Basis Technology Corp. + * Copyright 2011-2017 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -19,8 +19,11 @@ package org.sleuthkit.autopsy.contentviewers; import java.awt.Component; +import java.util.Arrays; +import java.util.List; import java.util.Optional; import java.util.logging.Level; +import javax.swing.text.JTextComponent; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.openide.nodes.Node; @@ -29,6 +32,8 @@ import org.openide.util.lookup.ServiceProvider; import org.sleuthkit.autopsy.corecomponentinterfaces.DataContentViewer; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.datamodel.BlackboardArtifact; +import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_EMAIL_MSG; +import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_MESSAGE; import org.sleuthkit.datamodel.BlackboardAttribute; import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME; import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_RCVD; @@ -52,21 +57,28 @@ import org.sleuthkit.datamodel.TskCoreException; @ServiceProvider(service = DataContentViewer.class, position = 4) public class MessageContentViewer extends javax.swing.JPanel implements DataContentViewer { + private static final long serialVersionUID = 1L; private static final Logger LOGGER = Logger.getLogger(MessageContentViewer.class.getName()); private static final int HDR_TAB_INDEX = 0; private static final int TEXT_TAB_INDEX = 1; private static final int HTML_TAB_INDEX = 2; private static final int RTF_TAB_INDEX = 3; - private static final long serialVersionUID = 1L; - - private BlackboardArtifact artifact; // Artifact currently being displayed + private final List textAreas; /** - * Creates new form MessageContentViewer + * Artifact currently being displayed + */ + private BlackboardArtifact artifact; + + /** + * Creates new MessageContentViewer */ public MessageContentViewer() { initComponents(); + + textAreas = Arrays.asList(headersTextArea, textbodyTextArea, htmlbodyTextPane, rtfbodyTextPane); + Utilities.configureTextPaneAsHtml(htmlbodyTextPane); Utilities.configureTextPaneAsRtf(rtfbodyTextPane); resetComponent(); @@ -240,22 +252,23 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont .addGroup(layout.createSequentialGroup() .addGap(5, 5, 5) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(msgbodyTabbedPane) + .addComponent(msgbodyTabbedPane, javax.swing.GroupLayout.DEFAULT_SIZE, 652, Short.MAX_VALUE) .addComponent(envelopePanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addGap(5, 5, 5)) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() - .addGap(5, 5, 5) + .addContainerGap() .addComponent(envelopePanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(msgbodyTabbedPane, javax.swing.GroupLayout.DEFAULT_SIZE, 471, Short.MAX_VALUE) - .addGap(0, 0, 0)) + .addComponent(msgbodyTabbedPane) + .addContainerGap()) ); }// //GEN-END:initComponents - @NbBundle.Messages({"MessageContentViewer.showImagesToggleButton.hide.text=Hide Images", + @NbBundle.Messages({ + "MessageContentViewer.showImagesToggleButton.hide.text=Hide Images", "MessageContentViewer.showImagesToggleButton.text=Show Images"}) private void showImagesToggleButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_showImagesToggleButtonActionPerformed try { @@ -302,7 +315,6 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont @Override public void setNode(Node node) { - if (node == null) { resetComponent(); return; @@ -314,9 +326,9 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont return; } - if (artifact.getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_MESSAGE.getTypeID()) { + if (artifact.getArtifactTypeID() == TSK_MESSAGE.getTypeID()) { displayMsg(); - } else if (artifact.getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_EMAIL_MSG.getTypeID()) { + } else if (artifact.getArtifactTypeID() == TSK_EMAIL_MSG.getTypeID()) { displayEmailMsg(); } else { resetComponent(); @@ -355,6 +367,10 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont subjectText.setText(""); datetimeText.setText(""); directionText.setText(""); + headersTextArea.setText(""); + rtfbodyTextPane.setText(""); + htmlbodyTextPane.setText(""); + textbodyTextArea.setText(""); setEnabled(false); } @@ -375,10 +391,23 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont return 0; } + void configureTextArea(BlackboardAttribute.ATTRIBUTE_TYPE type, int index) throws TskCoreException { + String attributeText = getAttributeValueSafe(artifact, type); + if (!attributeText.isEmpty()) { + attributeText = (index == HTML_TAB_INDEX) + ? wrapInHtmlBody(cleanseHTML(attributeText)) + : attributeText; + textAreas.get(index).setText(attributeText); + msgbodyTabbedPane.setEnabledAt(index, true); + msgbodyTabbedPane.setSelectedIndex(index); + } else { + msgbodyTabbedPane.setEnabledAt(index, false); + } + } + private void displayEmailMsg() { setEnabled(true); directionText.setText(""); - showImagesToggleButton.setVisible(false); showImagesToggleButton.setText("Show Images"); showImagesToggleButton.setSelected(false); @@ -389,42 +418,10 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont this.subjectText.setText(getAttributeValueSafe(artifact, TSK_SUBJECT)); this.datetimeText.setText(getAttributeValueSafe(artifact, TSK_DATETIME_RCVD)); - String headersText = getAttributeValueSafe(artifact, TSK_HEADERS); - if (!headersText.isEmpty()) { - this.headersTextArea.setText(headersText); - msgbodyTabbedPane.setEnabledAt(HDR_TAB_INDEX, true); - msgbodyTabbedPane.setSelectedIndex(HDR_TAB_INDEX); - } else { - msgbodyTabbedPane.setEnabledAt(HDR_TAB_INDEX, false); - } - - String plainText = getAttributeValueSafe(artifact, TSK_EMAIL_CONTENT_PLAIN); - if (!plainText.isEmpty()) { - this.textbodyTextArea.setText(plainText); - msgbodyTabbedPane.setEnabledAt(TEXT_TAB_INDEX, true); - msgbodyTabbedPane.setSelectedIndex(TEXT_TAB_INDEX); - } else { - msgbodyTabbedPane.setEnabledAt(TEXT_TAB_INDEX, false); - } - String htmlText = getAttributeValueSafe(artifact, TSK_EMAIL_CONTENT_HTML); - if (!htmlText.isEmpty()) { - this.showImagesToggleButton.setVisible(true); - this.htmlbodyTextPane.setText(wrapInHtmlBody(cleanseHTML(htmlText))); - msgbodyTabbedPane.setEnabledAt(HTML_TAB_INDEX, true); - msgbodyTabbedPane.setSelectedIndex(HTML_TAB_INDEX); - } else { - msgbodyTabbedPane.setEnabledAt(HTML_TAB_INDEX, false); - this.htmlbodyTextPane.setVisible(false); - } - - String rtfText = getAttributeValueSafe(artifact, TSK_EMAIL_CONTENT_RTF); - if (!rtfText.isEmpty()) { - this.rtfbodyTextPane.setText(rtfText); - msgbodyTabbedPane.setEnabledAt(RTF_TAB_INDEX, true); - msgbodyTabbedPane.setSelectedIndex(RTF_TAB_INDEX); - } else { - msgbodyTabbedPane.setEnabledAt(RTF_TAB_INDEX, false); - } + configureTextArea(TSK_HEADERS, HDR_TAB_INDEX); + configureTextArea(TSK_EMAIL_CONTENT_PLAIN, TEXT_TAB_INDEX); + configureTextArea(TSK_EMAIL_CONTENT_HTML, HTML_TAB_INDEX); + configureTextArea(TSK_EMAIL_CONTENT_RTF, RTF_TAB_INDEX); } catch (TskCoreException ex) { LOGGER.log(Level.WARNING, "Failed to get attributes for email message.", ex); //NON-NLS @@ -432,13 +429,12 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont } private static String wrapInHtmlBody(String htmlText) { - return "" + cleanseHTML(htmlText) + ""; + return "" + htmlText + ""; } private void displayMsg() { setEnabled(true); this.ccText.setText(""); - this.showImagesToggleButton.setVisible(false); msgbodyTabbedPane.setEnabledAt(HTML_TAB_INDEX, false); msgbodyTabbedPane.setEnabledAt(RTF_TAB_INDEX, false); msgbodyTabbedPane.setEnabledAt(HDR_TAB_INDEX, false); @@ -449,12 +445,8 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont this.directionText.setText(getAttributeValueSafe(artifact, TSK_DIRECTION)); this.subjectText.setText(getAttributeValueSafe(artifact, TSK_SUBJECT)); this.datetimeText.setText(getAttributeValueSafe(artifact, TSK_DATETIME)); - this.datetimeText.setText(getAttributeValueSafe(artifact, TSK_DATETIME)); - String text = getAttributeValueSafe(artifact, TSK_TEXT); - this.textbodyTextArea.setText(text); - msgbodyTabbedPane.setEnabledAt(TEXT_TAB_INDEX, text.isEmpty() == false); - msgbodyTabbedPane.setSelectedIndex(TEXT_TAB_INDEX); + configureTextArea(TSK_TEXT, TEXT_TAB_INDEX); } catch (TskCoreException ex) { LOGGER.log(Level.WARNING, "Failed to get attributes for message.", ex); //NON-NLS } From e22296f2cc5635568f74f8742401807f050691e8 Mon Sep 17 00:00:00 2001 From: millmanorama Date: Mon, 6 Nov 2017 11:25:10 +0100 Subject: [PATCH 064/127] try to fix scrolling --- .../communications/MessageBrowser.form | 9 +-- .../communications/MessageBrowser.java | 6 +- .../contentviewers/MessageContentViewer.form | 31 ++++++-- .../contentviewers/MessageContentViewer.java | 75 +++++++++++++------ 4 files changed, 82 insertions(+), 39 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.form b/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.form index 606d60c7df..58e19523f1 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.form +++ b/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.form @@ -18,7 +18,7 @@ - + @@ -38,17 +38,12 @@ - + - - - - - diff --git a/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.java b/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.java index e5c6704f10..815a3580fb 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.java +++ b/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.java @@ -116,9 +116,7 @@ final class MessageBrowser extends javax.swing.JPanel implements ExplorerManager splitPane.setDividerLocation(400); splitPane.setDividerSize(10); splitPane.setOrientation(javax.swing.JSplitPane.VERTICAL_SPLIT); - splitPane.setResizeWeight(0.4); - - messageDataContent.setMinimumSize(null); + splitPane.setResizeWeight(0.5); splitPane.setBottomComponent(messageDataContent); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); @@ -127,7 +125,7 @@ final class MessageBrowser extends javax.swing.JPanel implements ExplorerManager layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() .addGap(0, 0, 0) - .addComponent(splitPane, javax.swing.GroupLayout.DEFAULT_SIZE, 652, Short.MAX_VALUE)) + .addComponent(splitPane)) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.form b/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.form index 98f27a6351..856adf99a8 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.form +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.form @@ -19,7 +19,7 @@ - + @@ -196,6 +196,10 @@ + + + + @@ -212,12 +216,18 @@ + + + + + + @@ -233,8 +243,9 @@ - + + @@ -253,9 +264,9 @@ - + - + @@ -266,14 +277,17 @@ - - + + - + + + + @@ -300,6 +314,9 @@ + + + diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java b/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java index acbcb9ead1..aa75370afb 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java @@ -76,7 +76,6 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont */ public MessageContentViewer() { initComponents(); - textAreas = Arrays.asList(headersTextArea, textbodyTextArea, htmlbodyTextPane, rtfbodyTextPane); Utilities.configureTextPaneAsHtml(htmlbodyTextPane); @@ -110,7 +109,7 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont textbodyScrollPane = new javax.swing.JScrollPane(); textbodyTextArea = new javax.swing.JTextArea(); htmlPane = new javax.swing.JPanel(); - jScrollPane2 = new javax.swing.JScrollPane(); + htmlScrollPane = new javax.swing.JScrollPane(); htmlbodyTextPane = new javax.swing.JTextPane(); showImagesToggleButton = new javax.swing.JToggleButton(); rtfbodyScrollPane = new javax.swing.JScrollPane(); @@ -195,22 +194,33 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont .addGap(5, 5, 5)) ); + headersScrollPane.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); + headersScrollPane.setVerticalScrollBarPolicy(javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS); + headersTextArea.setEditable(false); headersTextArea.setColumns(20); + headersTextArea.setLineWrap(true); headersTextArea.setRows(5); + headersTextArea.setWrapStyleWord(true); headersScrollPane.setViewportView(headersTextArea); msgbodyTabbedPane.addTab(org.openide.util.NbBundle.getMessage(MessageContentViewer.class, "MessageContentViewer.headersScrollPane.TabConstraints.tabTitle"), headersScrollPane); // NOI18N + textbodyScrollPane.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); + textbodyScrollPane.setVerticalScrollBarPolicy(javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS); + textbodyTextArea.setEditable(false); - textbodyTextArea.setColumns(20); + textbodyTextArea.setLineWrap(true); textbodyTextArea.setRows(5); + textbodyTextArea.setWrapStyleWord(true); textbodyScrollPane.setViewportView(textbodyTextArea); msgbodyTabbedPane.addTab(org.openide.util.NbBundle.getMessage(MessageContentViewer.class, "MessageContentViewer.textbodyScrollPane.TabConstraints.tabTitle"), textbodyScrollPane); // NOI18N + htmlScrollPane.setVerticalScrollBarPolicy(javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS); + htmlbodyTextPane.setEditable(false); - jScrollPane2.setViewportView(htmlbodyTextPane); + htmlScrollPane.setViewportView(htmlbodyTextPane); org.openide.awt.Mnemonics.setLocalizedText(showImagesToggleButton, org.openide.util.NbBundle.getMessage(MessageContentViewer.class, "MessageContentViewer.showImagesToggleButton.text")); // NOI18N showImagesToggleButton.addActionListener(new java.awt.event.ActionListener() { @@ -223,9 +233,9 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont htmlPane.setLayout(htmlPaneLayout); htmlPaneLayout.setHorizontalGroup( htmlPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(jScrollPane2) + .addComponent(htmlScrollPane) .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, htmlPaneLayout.createSequentialGroup() - .addContainerGap(533, Short.MAX_VALUE) + .addContainerGap(283, Short.MAX_VALUE) .addComponent(showImagesToggleButton) .addGap(3, 3, 3)) ); @@ -234,12 +244,14 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont .addGroup(htmlPaneLayout.createSequentialGroup() .addComponent(showImagesToggleButton) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(jScrollPane2) + .addComponent(htmlScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 327, Short.MAX_VALUE) .addGap(0, 0, 0)) ); msgbodyTabbedPane.addTab(org.openide.util.NbBundle.getMessage(MessageContentViewer.class, "MessageContentViewer.htmlPane.TabConstraints.tabTitle"), htmlPane); // NOI18N + rtfbodyScrollPane.setVerticalScrollBarPolicy(javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS); + rtfbodyTextPane.setEditable(false); rtfbodyScrollPane.setViewportView(rtfbodyTextPane); @@ -252,7 +264,7 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont .addGroup(layout.createSequentialGroup() .addGap(5, 5, 5) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(msgbodyTabbedPane, javax.swing.GroupLayout.DEFAULT_SIZE, 652, Short.MAX_VALUE) + .addComponent(msgbodyTabbedPane) .addComponent(envelopePanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addGap(5, 5, 5)) ); @@ -299,8 +311,8 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont private javax.swing.JScrollPane headersScrollPane; private javax.swing.JTextArea headersTextArea; private javax.swing.JPanel htmlPane; + private javax.swing.JScrollPane htmlScrollPane; private javax.swing.JTextPane htmlbodyTextPane; - private javax.swing.JScrollPane jScrollPane2; private javax.swing.JTabbedPane msgbodyTabbedPane; private javax.swing.JScrollPane rtfbodyScrollPane; private javax.swing.JTextPane rtfbodyTextPane; @@ -333,7 +345,6 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont } else { resetComponent(); } - } @Override @@ -362,16 +373,23 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont final public void resetComponent() { // reset all fields fromText.setText(""); + fromLabel.setEnabled(false); toText.setText(""); + toLabel.setEnabled(false); ccText.setText(""); + ccLabel.setEnabled(false); subjectText.setText(""); + subjectLabel.setEnabled(false); datetimeText.setText(""); + datetimeText.setEnabled(false); directionText.setText(""); + directionText.setEnabled(false); + headersTextArea.setText(""); rtfbodyTextPane.setText(""); htmlbodyTextPane.setText(""); textbodyTextArea.setText(""); - setEnabled(false); + msgbodyTabbedPane.setEnabled(false); } @Override @@ -384,7 +402,6 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont @Override public int isPreferred(Node node) { - if (isSupported(node)) { return 6; } @@ -397,7 +414,9 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont attributeText = (index == HTML_TAB_INDEX) ? wrapInHtmlBody(cleanseHTML(attributeText)) : attributeText; - textAreas.get(index).setText(attributeText); + final JTextComponent textComponent = textAreas.get(index); + textComponent.setText(attributeText); + textComponent.setCaretPosition(0); msgbodyTabbedPane.setEnabledAt(index, true); msgbodyTabbedPane.setSelectedIndex(index); } else { @@ -406,14 +425,22 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont } private void displayEmailMsg() { - setEnabled(true); - directionText.setText(""); + msgbodyTabbedPane.setEnabled(true); + fromLabel.setEnabled(true); + toLabel.setEnabled(true); + ccLabel.setEnabled(true); + subjectLabel.setEnabled(true); + datetimeText.setEnabled(true); + + directionText.setEnabled(false); + showImagesToggleButton.setText("Show Images"); showImagesToggleButton.setSelected(false); try { this.fromText.setText(getAttributeValueSafe(artifact, TSK_EMAIL_FROM)); this.toText.setText(getAttributeValueSafe(artifact, TSK_EMAIL_TO)); + this.directionText.setText(""); this.ccText.setText(getAttributeValueSafe(artifact, TSK_EMAIL_CC)); this.subjectText.setText(getAttributeValueSafe(artifact, TSK_SUBJECT)); this.datetimeText.setText(getAttributeValueSafe(artifact, TSK_DATETIME_RCVD)); @@ -422,7 +449,6 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont configureTextArea(TSK_EMAIL_CONTENT_PLAIN, TEXT_TAB_INDEX); configureTextArea(TSK_EMAIL_CONTENT_HTML, HTML_TAB_INDEX); configureTextArea(TSK_EMAIL_CONTENT_RTF, RTF_TAB_INDEX); - } catch (TskCoreException ex) { LOGGER.log(Level.WARNING, "Failed to get attributes for email message.", ex); //NON-NLS } @@ -433,19 +459,26 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont } private void displayMsg() { - setEnabled(true); - this.ccText.setText(""); - msgbodyTabbedPane.setEnabledAt(HTML_TAB_INDEX, false); - msgbodyTabbedPane.setEnabledAt(RTF_TAB_INDEX, false); - msgbodyTabbedPane.setEnabledAt(HDR_TAB_INDEX, false); + msgbodyTabbedPane.setEnabled(true); + fromLabel.setEnabled(true); + toLabel.setEnabled(true); + subjectLabel.setEnabled(true); + directionText.setEnabled(true); + datetimeText.setEnabled(true); + + ccLabel.setEnabled(false); try { this.fromText.setText(getAttributeValueSafe(artifact, TSK_PHONE_NUMBER_FROM)); this.toText.setText(getAttributeValueSafe(artifact, TSK_PHONE_NUMBER_TO)); this.directionText.setText(getAttributeValueSafe(artifact, TSK_DIRECTION)); + this.ccText.setText(""); this.subjectText.setText(getAttributeValueSafe(artifact, TSK_SUBJECT)); this.datetimeText.setText(getAttributeValueSafe(artifact, TSK_DATETIME)); + msgbodyTabbedPane.setEnabledAt(HTML_TAB_INDEX, false); + msgbodyTabbedPane.setEnabledAt(RTF_TAB_INDEX, false); + msgbodyTabbedPane.setEnabledAt(HDR_TAB_INDEX, false); configureTextArea(TSK_TEXT, TEXT_TAB_INDEX); } catch (TskCoreException ex) { LOGGER.log(Level.WARNING, "Failed to get attributes for message.", ex); //NON-NLS From 9ec6b02565d25c0f6b5f1949c3e52ebfd9bfc774 Mon Sep 17 00:00:00 2001 From: millmanorama Date: Mon, 6 Nov 2017 13:50:02 +0100 Subject: [PATCH 065/127] add actions to MessageBrowser --- .../org/sleuthkit/autopsy/communications/MessageBrowser.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.java b/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.java index e5c6704f10..c06779e104 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.java +++ b/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.java @@ -28,6 +28,7 @@ import org.sleuthkit.autopsy.communications.AccountsRootChildren.AccountDeviceIn import org.sleuthkit.autopsy.corecomponents.DataResultPanel; import org.sleuthkit.autopsy.corecomponents.TableFilterNode; import org.sleuthkit.autopsy.coreutils.Logger; +import org.sleuthkit.autopsy.directorytree.DataResultFilterNode; import org.sleuthkit.datamodel.Account; import org.sleuthkit.datamodel.CommunicationsFilter; import org.sleuthkit.datamodel.CommunicationsManager; @@ -89,7 +90,7 @@ final class MessageBrowser extends javax.swing.JPanel implements ExplorerManager logger.log(Level.WARNING, "Unexpected Node encountered: " + n.toString()); } } - messagesResultPanel.setNode(new TableFilterNode(new AccountDetailsNode(accounts, filter, commsManager), true)); + messagesResultPanel.setNode(new TableFilterNode(new DataResultFilterNode(new AccountDetailsNode(accounts, filter, commsManager),internalExplorerManager), true)); if (accounts.size() == 1) { messagesResultPanel.setPath(Iterables.getOnlyElement(accounts).getAccountUniqueID()); } else { From 6e0ccf4e01832c781198d8a2a90577b6c12cdf9f Mon Sep 17 00:00:00 2001 From: Raman Date: Tue, 7 Nov 2017 13:35:03 -0500 Subject: [PATCH 066/127] Updated the CommunicationsManager API usage for getCommunicationsCount() and getCommunications() --- .../communications/AccountDetailsNode.java | 36 ++++++++----------- .../communications/AccountsRootChildren.java | 2 +- .../autopsy/communications/FiltersPanel.java | 2 +- .../communications/MessageBrowser.java | 13 +++---- 4 files changed, 24 insertions(+), 29 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/communications/AccountDetailsNode.java b/Core/src/org/sleuthkit/autopsy/communications/AccountDetailsNode.java index 34245f1a6d..eb0a28206d 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/AccountDetailsNode.java +++ b/Core/src/org/sleuthkit/autopsy/communications/AccountDetailsNode.java @@ -28,6 +28,7 @@ import org.openide.nodes.Children; import org.openide.nodes.Node; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.datamodel.Account; +import org.sleuthkit.datamodel.AccountDeviceInstance; import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.CommunicationsFilter; import org.sleuthkit.datamodel.CommunicationsManager; @@ -38,8 +39,8 @@ class AccountDetailsNode extends AbstractNode { private final static Logger logger = Logger.getLogger(AccountDetailsNode.class.getName()); private final CommunicationsFilter filter; //TODO: Use this - AccountDetailsNode(Set accounts,CommunicationsFilter filter, CommunicationsManager commsManager) { - super(new AccountRelationshipChildren(accounts, commsManager, filter)); + AccountDetailsNode(Set accountDeviceInstances, CommunicationsFilter filter, CommunicationsManager commsManager) { + super(new AccountRelationshipChildren(accountDeviceInstances, commsManager, filter)); this.filter = filter; } @@ -48,12 +49,12 @@ class AccountDetailsNode extends AbstractNode { */ private static class AccountRelationshipChildren extends Children.Keys { - private final Set accounts; + private final Set accountDeviceInstances; private final CommunicationsManager commsManager; - private final CommunicationsFilter filter;//TODO: Use this + private final CommunicationsFilter filter; - private AccountRelationshipChildren(Set accounts, CommunicationsManager commsManager, CommunicationsFilter filter) { - this.accounts = accounts; + private AccountRelationshipChildren(Set accountDeviceInstances, CommunicationsManager commsManager, CommunicationsFilter filter) { + this.accountDeviceInstances = accountDeviceInstances; this.commsManager = commsManager; this.filter = filter; } @@ -66,22 +67,15 @@ class AccountDetailsNode extends AbstractNode { @Override protected void addNotify() { Set keys = new HashSet<>(); - for (Account account : accounts) { - List accountsWithRelationship = new ArrayList<>(); - try { - accountsWithRelationship.addAll(commsManager.getAccountsWithRelationship(account)); //TODO: Use filter here - } catch (TskCoreException ex) { - logger.log(Level.WARNING, "Error loading with relationships to " + account, ex); - } - - accountsWithRelationship.forEach(otherAcount -> { - try { - keys.addAll(commsManager.getRelationships(account, otherAcount)); //TODO:Use filter here - } catch (TskCoreException ex) { - logger.log(Level.WARNING, "Error loading relationships between " + account + " and " + otherAcount, ex); - } - }); + + try { + Set communications = commsManager.getCommunications(accountDeviceInstances, filter); + keys = new HashSet<>(communications); } + catch (TskCoreException ex) { + logger.log(Level.WARNING, "Error loading communications for accounts. ", ex); + } + setKeys(keys); } } diff --git a/Core/src/org/sleuthkit/autopsy/communications/AccountsRootChildren.java b/Core/src/org/sleuthkit/autopsy/communications/AccountsRootChildren.java index 12fa9f0567..53cb4e06c3 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/AccountsRootChildren.java +++ b/Core/src/org/sleuthkit/autopsy/communications/AccountsRootChildren.java @@ -115,7 +115,7 @@ class AccountsRootChildren extends Children.Keys { } long msgCount = 0; try { - msgCount = commsManager.getRelationshipsCount(accountDeviceInstance.getAccount(), filter ); + msgCount = commsManager.getCommunicationsCount(accountDeviceInstance, filter ); } catch (TskCoreException ex) { LOGGER.log(Level.WARNING, "Failed to get message count for account", ex); //NON-NLS } diff --git a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java index 0169ce32ab..26b216b182 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java +++ b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java @@ -306,7 +306,7 @@ final public class FiltersPanel extends javax.swing.JPanel { final CommunicationsManager commsManager = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager(); List accountDeviceInstanceKeys = - commsManager.getAccountDeviceInstancesWithRelationships(commsFilter) + commsManager.getAccountDeviceInstancesWithCommunications(commsFilter) .stream() .map(adi -> new AccountDeviceInstanceKey(adi, commsFilter)) .collect(Collectors.toList()); diff --git a/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.java b/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.java index 7eaecf85a0..6ab5289133 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.java +++ b/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.java @@ -31,6 +31,7 @@ import org.sleuthkit.autopsy.corecomponents.TableFilterNode; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.directorytree.DataResultFilterNode; import org.sleuthkit.datamodel.Account; +import org.sleuthkit.datamodel.AccountDeviceInstance; import org.sleuthkit.datamodel.CommunicationsFilter; import org.sleuthkit.datamodel.CommunicationsManager; @@ -71,13 +72,13 @@ final class MessageBrowser extends javax.swing.JPanel implements ExplorerManager messagesResultPanel.setNode(null); messagesResultPanel.setPath(""); } else { - Set accounts = new HashSet<>(); + Set accountDeviceInstances = new HashSet<>(); CommunicationsFilter filter = null; CommunicationsManager commsManager = null; for (Node n : selectedNodes) { if (n instanceof AccountDeviceInstanceNode) { final AccountDeviceInstanceNode adiNode = (AccountDeviceInstanceNode) n; - accounts.add(adiNode.getAccountDeviceInstance().getAccount()); + accountDeviceInstances.add(adiNode.getAccountDeviceInstance()); if (commsManager == null) { commsManager = adiNode.getCommsManager(); } @@ -92,11 +93,11 @@ final class MessageBrowser extends javax.swing.JPanel implements ExplorerManager logger.log(Level.WARNING, "Unexpected Node encountered: " + n.toString()); } } - messagesResultPanel.setNode(new TableFilterNode(new DataResultFilterNode(new AccountDetailsNode(accounts, filter, commsManager),internalExplorerManager), true)); - if (accounts.size() == 1) { - messagesResultPanel.setPath(Iterables.getOnlyElement(accounts).getAccountUniqueID()); + messagesResultPanel.setNode(new TableFilterNode(new AccountDetailsNode(accountDeviceInstances, filter, commsManager), true)); + if (accountDeviceInstances.size() == 1) { + messagesResultPanel.setPath(Iterables.getOnlyElement(accountDeviceInstances).getAccount().getAccountUniqueID()); } else { - messagesResultPanel.setPath(accounts.size() + " accounts"); + messagesResultPanel.setPath(accountDeviceInstances.size() + " accounts"); } } } From dfd8043fff26aa5d2bd9e4a94c85cc5458731e97 Mon Sep 17 00:00:00 2001 From: Raman Date: Wed, 8 Nov 2017 12:31:08 -0500 Subject: [PATCH 067/127] Fixed a typo in previous commit. --- Core/src/org/sleuthkit/autopsy/report/TableReportGenerator.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/report/TableReportGenerator.java b/Core/src/org/sleuthkit/autopsy/report/TableReportGenerator.java index 2a8235ee08..d30839afaa 100755 --- a/Core/src/org/sleuthkit/autopsy/report/TableReportGenerator.java +++ b/Core/src/org/sleuthkit/autopsy/report/TableReportGenerator.java @@ -184,7 +184,7 @@ class TableReportGenerator { } } catch (TskCoreException ex) { - logger.log(Level.SEVERE, "Unable to get dusplay name for account type.", ex); + logger.log(Level.SEVERE, "Unable to get display name for account type.", ex); } } From ae8d9c4860a53010bd653caff9e5e4dc15b5d0c7 Mon Sep 17 00:00:00 2001 From: Raman Date: Wed, 8 Nov 2017 12:56:48 -0500 Subject: [PATCH 068/127] Added more info to log statement. --- Core/src/org/sleuthkit/autopsy/report/TableReportGenerator.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/report/TableReportGenerator.java b/Core/src/org/sleuthkit/autopsy/report/TableReportGenerator.java index d30839afaa..6de7e62f86 100755 --- a/Core/src/org/sleuthkit/autopsy/report/TableReportGenerator.java +++ b/Core/src/org/sleuthkit/autopsy/report/TableReportGenerator.java @@ -184,7 +184,7 @@ class TableReportGenerator { } } catch (TskCoreException ex) { - logger.log(Level.SEVERE, "Unable to get display name for account type.", ex); + logger.log(Level.SEVERE, "Unable to get display name for account type " + accountTypeStr, ex); } } From 894c3f6d1eb729b5c0e0242b86b3f2803d189195 Mon Sep 17 00:00:00 2001 From: millmanorama Date: Tue, 7 Nov 2017 12:21:49 +0100 Subject: [PATCH 069/127] fix a compiler error, and use the correct API so that counts in the tables match. some comments and minor cleanup --- .../communications/AccountDetailsNode.java | 25 +++++++------------ ...pFilterNode.java => RelationShipNode.java} | 24 ++++++++++-------- 2 files changed, 23 insertions(+), 26 deletions(-) rename Core/src/org/sleuthkit/autopsy/communications/{RelationShipFilterNode.java => RelationShipNode.java} (92%) diff --git a/Core/src/org/sleuthkit/autopsy/communications/AccountDetailsNode.java b/Core/src/org/sleuthkit/autopsy/communications/AccountDetailsNode.java index eb0a28206d..ac93209b8b 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/AccountDetailsNode.java +++ b/Core/src/org/sleuthkit/autopsy/communications/AccountDetailsNode.java @@ -18,34 +18,33 @@ */ package org.sleuthkit.autopsy.communications; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; import java.util.Set; import java.util.logging.Level; import org.openide.nodes.AbstractNode; import org.openide.nodes.Children; import org.openide.nodes.Node; import org.sleuthkit.autopsy.coreutils.Logger; -import org.sleuthkit.datamodel.Account; import org.sleuthkit.datamodel.AccountDeviceInstance; import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.CommunicationsFilter; import org.sleuthkit.datamodel.CommunicationsManager; import org.sleuthkit.datamodel.TskCoreException; +/** + * 'Root' Node for the Account/Messages area. Has children which are all the + * relationships of all the accounts in this node. + * + */ class AccountDetailsNode extends AbstractNode { private final static Logger logger = Logger.getLogger(AccountDetailsNode.class.getName()); - private final CommunicationsFilter filter; //TODO: Use this AccountDetailsNode(Set accountDeviceInstances, CommunicationsFilter filter, CommunicationsManager commsManager) { super(new AccountRelationshipChildren(accountDeviceInstances, commsManager, filter)); - this.filter = filter; } /** - * Children object for the relationships that the account is a member of. + * Children object for the relationships that the accounts are part of. */ private static class AccountRelationshipChildren extends Children.Keys { @@ -61,22 +60,16 @@ class AccountDetailsNode extends AbstractNode { @Override protected Node[] createNodes(BlackboardArtifact key) { - return new Node[]{new RelationShipFilterNode(key)}; + return new Node[]{new RelationShipNode(key)}; } @Override protected void addNotify() { - Set keys = new HashSet<>(); - try { - Set communications = commsManager.getCommunications(accountDeviceInstances, filter); - keys = new HashSet<>(communications); - } - catch (TskCoreException ex) { + setKeys(commsManager.getCommunications(accountDeviceInstances, filter)); + } catch (TskCoreException ex) { logger.log(Level.WARNING, "Error loading communications for accounts. ", ex); } - - setKeys(keys); } } } diff --git a/Core/src/org/sleuthkit/autopsy/communications/RelationShipFilterNode.java b/Core/src/org/sleuthkit/autopsy/communications/RelationShipNode.java similarity index 92% rename from Core/src/org/sleuthkit/autopsy/communications/RelationShipFilterNode.java rename to Core/src/org/sleuthkit/autopsy/communications/RelationShipNode.java index 71508f807a..b46aa90ff3 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/RelationShipFilterNode.java +++ b/Core/src/org/sleuthkit/autopsy/communications/RelationShipNode.java @@ -38,29 +38,29 @@ import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SUB import org.sleuthkit.datamodel.TskCoreException; /** - * + * Node for a relationship, as represented by a BlackboardArtifact. */ -public class RelationShipFilterNode extends BlackboardArtifactNode { - - private static final Logger logger = Logger.getLogger(RelationShipFilterNode.class.getName()); - - public RelationShipFilterNode(BlackboardArtifact artifact) { +public class RelationShipNode extends BlackboardArtifactNode { + + private static final Logger logger = Logger.getLogger(RelationShipNode.class.getName()); + + public RelationShipNode(BlackboardArtifact artifact) { super(artifact); final String stripEnd = StringUtils.stripEnd(artifact.getDisplayName(), "s"); String removeEndIgnoreCase = StringUtils.removeEndIgnoreCase(stripEnd, "message"); setDisplayName(removeEndIgnoreCase.isEmpty() ? stripEnd : removeEndIgnoreCase); } - + @Override protected Sheet createSheet() { - + Sheet s = new Sheet(); Sheet.Set ss = s.get(Sheet.PROPERTIES); if (ss == null) { ss = Sheet.createPropertiesSet(); s.put(ss); } - + ss.put(new NodeProperty<>("Type", "Type", "Type", getDisplayName())); final BlackboardArtifact artifact = getArtifact(); BlackboardArtifact.ARTIFACT_TYPE fromID = BlackboardArtifact.ARTIFACT_TYPE.fromID(getArtifact().getArtifactTypeID()); @@ -102,11 +102,15 @@ public class RelationShipFilterNode extends BlackboardArtifactNode { } /** + * + * Get the display string for the attribute of the given type from the given + * artifact. * * @param artifact the value of artifact * @param attributeType the value of TSK_SUBJECT1 * - * @throws TskCoreException + * @return The display string, or an empty string if there is no such + * attribute or an an error. */ private static String getAttributeDisplayString(final BlackboardArtifact artifact, final ATTRIBUTE_TYPE attributeType) { try { From 00e52e50c0005b5394102628229ade6642a3ec0f Mon Sep 17 00:00:00 2001 From: Raman Date: Fri, 10 Nov 2017 12:57:49 -0500 Subject: [PATCH 070/127] 879: Add date range filter to API - Added dateTime to addRelationships() api --- InternalPythonModules/android/calllog.py | 2 +- InternalPythonModules/android/contact.py | 2 +- InternalPythonModules/android/textmessage.py | 2 +- InternalPythonModules/android/wwfmessage.py | 2 +- .../core/core.jar/org/netbeans/core/startup/Bundle.properties | 2 +- .../thunderbirdparser/ThunderbirdMboxFileIngestModule.java | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/InternalPythonModules/android/calllog.py b/InternalPythonModules/android/calllog.py index 1cdab6b089..be877997ff 100755 --- a/InternalPythonModules/android/calllog.py +++ b/InternalPythonModules/android/calllog.py @@ -146,7 +146,7 @@ class CallLogAnalyzer(general.AndroidComponentAnalyzer): calllogAccountInstance = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().createAccountInstance(Account.Type.PHONE, number, general.MODULE_NAME, abstractFile); # create relationship between accounts - Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().addRelationships(deviceAccountInstance, [calllogAccountInstance], artifact); + Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().addRelationships(deviceAccountInstance, [calllogAccountInstance], artifact, date); bbartifacts.append(artifact) diff --git a/InternalPythonModules/android/contact.py b/InternalPythonModules/android/contact.py index e327ece36e..0b0baf1e46 100755 --- a/InternalPythonModules/android/contact.py +++ b/InternalPythonModules/android/contact.py @@ -150,7 +150,7 @@ class ContactAnalyzer(general.AndroidComponentAnalyzer): contactAccountInstance = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().createAccountInstance(acctType, data1, general.MODULE_NAME, abstractFile); # create relationship between accounts - Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().addRelationships(deviceAccountInstance, [contactAccountInstance], artifact); + Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().addRelationships(deviceAccountInstance, [contactAccountInstance], artifact, 0); oldName = name diff --git a/InternalPythonModules/android/textmessage.py b/InternalPythonModules/android/textmessage.py index cd2317a492..535d43b07f 100755 --- a/InternalPythonModules/android/textmessage.py +++ b/InternalPythonModules/android/textmessage.py @@ -121,7 +121,7 @@ class TextMessageAnalyzer(general.AndroidComponentAnalyzer): msgAccountInstance = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().createAccountInstance(Account.Type.PHONE, address, general.MODULE_NAME, abstractFile); # create relationship between accounts - Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().addRelationships(deviceAccountInstance, [msgAccountInstance], artifact); + Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().addRelationships(deviceAccountInstance, [msgAccountInstance], artifact, date); bbartifacts.append(artifact) try: diff --git a/InternalPythonModules/android/wwfmessage.py b/InternalPythonModules/android/wwfmessage.py index 4d66e97af0..21860d53b4 100755 --- a/InternalPythonModules/android/wwfmessage.py +++ b/InternalPythonModules/android/wwfmessage.py @@ -115,7 +115,7 @@ class WWFMessageAnalyzer(general.AndroidComponentAnalyzer): wwfAccountInstance = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().createAccountInstance(wwfAccountType, user_id, general.MODULE_NAME, abstractFile); # create relationship between accounts - Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().addRelationships(deviceAccountInstance, [wwfAccountInstance], artifact); + Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().addRelationships(deviceAccountInstance, [wwfAccountInstance], artifact, created_at); try: # index the artifact for keyword search diff --git a/branding/core/core.jar/org/netbeans/core/startup/Bundle.properties b/branding/core/core.jar/org/netbeans/core/startup/Bundle.properties index f487637e9c..f4eae0ead3 100644 --- a/branding/core/core.jar/org/netbeans/core/startup/Bundle.properties +++ b/branding/core/core.jar/org/netbeans/core/startup/Bundle.properties @@ -1,5 +1,5 @@ #Updated by build script -#Wed, 08 Nov 2017 10:44:01 -0500 +#Thu, 09 Nov 2017 11:15:59 -0500 LBL_splash_window_title=Starting Autopsy SPLASH_HEIGHT=314 SPLASH_WIDTH=538 diff --git a/thunderbirdparser/src/org/sleuthkit/autopsy/thunderbirdparser/ThunderbirdMboxFileIngestModule.java b/thunderbirdparser/src/org/sleuthkit/autopsy/thunderbirdparser/ThunderbirdMboxFileIngestModule.java index 32e739dda6..e852d37b00 100755 --- a/thunderbirdparser/src/org/sleuthkit/autopsy/thunderbirdparser/ThunderbirdMboxFileIngestModule.java +++ b/thunderbirdparser/src/org/sleuthkit/autopsy/thunderbirdparser/ThunderbirdMboxFileIngestModule.java @@ -465,7 +465,7 @@ public final class ThunderbirdMboxFileIngestModule implements FileIngestModule { bbart.addAttributes(bbattributes); // Add account relationships - Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().addRelationships(senderAccountInstance, recipientAccountInstances, bbart); + Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().addRelationships(senderAccountInstance, recipientAccountInstances, bbart, dateL); try { // index the artifact for keyword search From f04e26621296318eb7079dfb010ab5bdbecd2d53 Mon Sep 17 00:00:00 2001 From: millmanorama Date: Fri, 10 Nov 2017 21:06:10 +0100 Subject: [PATCH 071/127] remove etched border from FiltersPanel --- .../sleuthkit/autopsy/communications/CVTTopComponent.form | 5 ----- .../sleuthkit/autopsy/communications/CVTTopComponent.java | 1 - 2 files changed, 6 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.form b/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.form index 524529e9bd..0463a92715 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.form +++ b/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.form @@ -111,11 +111,6 @@ - - - - - diff --git a/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java b/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java index 0618cb7fc4..b5c26bb1a2 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java +++ b/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java @@ -88,7 +88,6 @@ public final class CVTTopComponent extends TopComponent implements ExplorerManag splitPane.setLeftComponent(BrowseVisualizeTabPane); - filtersPane.setBorder(javax.swing.BorderFactory.createEtchedBorder()); filtersPane.setMinimumSize(new java.awt.Dimension(256, 495)); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); From 8dc4ce4408e52c971d8f6a6fc9869b8f74d79bba Mon Sep 17 00:00:00 2001 From: millmanorama Date: Fri, 10 Nov 2017 21:06:56 +0100 Subject: [PATCH 072/127] add date filter widgets to FiltersPanel --- .../autopsy/communications/Bundle.properties | 7 + .../autopsy/communications/FiltersPanel.form | 186 +++++++++++-- .../autopsy/communications/FiltersPanel.java | 245 ++++++++++++++++-- 3 files changed, 391 insertions(+), 47 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/communications/Bundle.properties b/Core/src/org/sleuthkit/autopsy/communications/Bundle.properties index c95f1af5c8..11ae095dbc 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/communications/Bundle.properties @@ -8,3 +8,10 @@ FiltersPanel.unCheckAllAccountTypesButton.text=Uncheck All FiltersPanel.checkAllAccountTypesButton.text=Check All FiltersPanel.unCheckAllDevicesButton.text=Uncheck All FiltersPanel.checkAllDevicesButton.text=Check All +FiltersPanel.dateRangeLabel.text=Date Range: +FiltersPanel.startCheckBox.text=start: +FiltersPanel.endCheckBox.text=end: +FiltersPanel.endDateTextField.text= +FiltersPanel.startDateTextField.text= +FiltersPanel.startCalendarButton.text= +FiltersPanel.endCalendarButton.text= diff --git a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.form b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.form index ef451b0751..02c5a82a1e 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.form +++ b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.form @@ -43,16 +43,17 @@ - - - - + + + + + @@ -68,9 +69,11 @@ - + - + + + @@ -111,16 +114,24 @@ - - - - - - - + + + + + + + + + + + + + + + + + - - @@ -131,7 +142,7 @@ - + @@ -197,12 +208,17 @@ - - - - - + + + + + + + + + + @@ -212,7 +228,7 @@ - + @@ -269,5 +285,131 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java index 26b216b182..43ba0b4a4c 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java +++ b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java @@ -18,6 +18,13 @@ */ package org.sleuthkit.autopsy.communications; +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.time.Instant; +import java.time.LocalDate; +import java.time.ZoneId; +import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -25,6 +32,7 @@ import java.util.Map.Entry; import java.util.logging.Level; import java.util.stream.Collectors; import javax.swing.JCheckBox; +import javax.swing.JFormattedTextField; import org.openide.explorer.ExplorerManager; import org.openide.nodes.AbstractNode; import org.sleuthkit.autopsy.casemodule.Case; @@ -47,6 +55,8 @@ final public class FiltersPanel extends javax.swing.JPanel { private static final Logger logger = Logger.getLogger(FiltersPanel.class.getName()); private static final long serialVersionUID = 1L; + private static final DateFormat DATE_FORMAT = new SimpleDateFormat("MM/dd/yyyy"); + private ExplorerManager em; @ThreadConfined(type = ThreadConfined.ThreadType.AWT) @@ -56,6 +66,9 @@ final public class FiltersPanel extends javax.swing.JPanel { public FiltersPanel() { initComponents(); + startCalendarButton.addPropertyChangeListener(this::startPopupChanged); + endCalendarButton.addPropertyChangeListener(this::endPopupChanged); + updateAndApplyFilters(); } @@ -80,6 +93,42 @@ final public class FiltersPanel extends javax.swing.JPanel { em = ExplorerManager.find(this); } + private void startPopupChanged(java.beans.PropertyChangeEvent evt) { + if (evt.getNewValue() instanceof Date) { + setStartDate((Date) evt.getNewValue()); + } + } + + /** + * + * @param newStartDate the value of newStartDate + */ + private void setStartDate(final Date newStartDate) { + startDateTextField.setValue(newStartDate); + startCalendarButton.setTargetDate(newStartDate); + } + + private void endPopupChanged(java.beans.PropertyChangeEvent evt) { + if (evt.getNewValue() instanceof Date) { + setEndDate((Date) evt.getNewValue()); + } + } + + /** + * + * @param newEndDate the value of newEndDate + */ + private void setEndDate(final Date newEndDate) { + endDateTextField.setValue(newEndDate); + endCalendarButton.setTargetDate(newEndDate); + } + + /** + * Validate and set the datetime field on the screen given a datetime + * string. + * + * @param date The date object + */ /** * Populate the Account Types filter widgets */ @@ -187,15 +236,20 @@ final public class FiltersPanel extends javax.swing.JPanel { jPanel2.setLayout(jPanel2Layout); jPanel2Layout.setHorizontalGroup( jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(jPanel2Layout.createSequentialGroup() - .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel2Layout.createSequentialGroup() - .addContainerGap(43, Short.MAX_VALUE) - .addComponent(unCheckAllAccountTypesButton) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(checkAllAccountTypesButton)) - .addComponent(accountTypesLabel) - .addComponent(accountTypePane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel2Layout.createSequentialGroup() + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addGroup(javax.swing.GroupLayout.Alignment.LEADING, jPanel2Layout.createSequentialGroup() + .addComponent(accountTypesLabel) + .addGap(0, 0, Short.MAX_VALUE)) + .addGroup(jPanel2Layout.createSequentialGroup() + .addGap(8, 8, 8) + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(accountTypePane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGroup(jPanel2Layout.createSequentialGroup() + .addGap(0, 32, Short.MAX_VALUE) + .addComponent(unCheckAllAccountTypesButton) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(checkAllAccountTypesButton))))) .addGap(0, 0, 0)) ); jPanel2Layout.setVerticalGroup( @@ -203,7 +257,7 @@ final public class FiltersPanel extends javax.swing.JPanel { .addGroup(jPanel2Layout.createSequentialGroup() .addComponent(accountTypesLabel) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(accountTypePane, javax.swing.GroupLayout.DEFAULT_SIZE, 189, Short.MAX_VALUE) + .addComponent(accountTypePane, javax.swing.GroupLayout.DEFAULT_SIZE, 174, Short.MAX_VALUE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(checkAllAccountTypesButton) @@ -238,12 +292,15 @@ final public class FiltersPanel extends javax.swing.JPanel { .addGroup(jPanel3Layout.createSequentialGroup() .addComponent(devicesLabel) .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - .addComponent(devicesPane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addGroup(jPanel3Layout.createSequentialGroup() - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(unCheckAllDevicesButton) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(checkAllDevicesButton)) + .addGap(8, 8, 8) + .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel3Layout.createSequentialGroup() + .addGap(0, 32, Short.MAX_VALUE) + .addComponent(unCheckAllDevicesButton) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(checkAllDevicesButton)) + .addComponent(devicesPane, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))) ); jPanel3Layout.setVerticalGroup( jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) @@ -251,7 +308,7 @@ final public class FiltersPanel extends javax.swing.JPanel { .addGap(0, 0, 0) .addComponent(devicesLabel) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(devicesPane, javax.swing.GroupLayout.DEFAULT_SIZE, 86, Short.MAX_VALUE) + .addComponent(devicesPane, javax.swing.GroupLayout.DEFAULT_SIZE, 59, Short.MAX_VALUE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(checkAllDevicesButton) @@ -259,19 +316,97 @@ final public class FiltersPanel extends javax.swing.JPanel { .addGap(0, 0, 0)) ); + dateRangeLabel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/images/calendar.png"))); // NOI18N + dateRangeLabel.setText(org.openide.util.NbBundle.getMessage(FiltersPanel.class, "FiltersPanel.dateRangeLabel.text")); // NOI18N + + startCheckBox.setText(org.openide.util.NbBundle.getMessage(FiltersPanel.class, "FiltersPanel.startCheckBox.text")); // NOI18N + startCheckBox.addChangeListener(new javax.swing.event.ChangeListener() { + public void stateChanged(javax.swing.event.ChangeEvent evt) { + startCheckBoxStateChanged(evt); + } + }); + + endCheckBox.setText(org.openide.util.NbBundle.getMessage(FiltersPanel.class, "FiltersPanel.endCheckBox.text")); // NOI18N + endCheckBox.addChangeListener(new javax.swing.event.ChangeListener() { + public void stateChanged(javax.swing.event.ChangeEvent evt) { + endCheckBoxStateChanged(evt); + } + }); + + startCalendarButton.setText(org.openide.util.NbBundle.getMessage(FiltersPanel.class, "FiltersPanel.startCalendarButton.text")); // NOI18N + startCalendarButton.setEnabled(false); + + endCalendarButton.setText(org.openide.util.NbBundle.getMessage(FiltersPanel.class, "FiltersPanel.endCalendarButton.text")); // NOI18N + endCalendarButton.setEnabled(false); + + endDateTextField.setText(org.openide.util.NbBundle.getMessage(FiltersPanel.class, "FiltersPanel.endDateTextField.text")); // NOI18N + endDateTextField.setEnabled(false); + endDateTextField.addFocusListener(new java.awt.event.FocusAdapter() { + public void focusLost(java.awt.event.FocusEvent evt) { + endDateTextFieldFocusLost(evt); + } + }); + + startDateTextField.setText(org.openide.util.NbBundle.getMessage(FiltersPanel.class, "FiltersPanel.startDateTextField.text")); // NOI18N + startDateTextField.setEnabled(false); + startDateTextField.addFocusListener(new java.awt.event.FocusAdapter() { + public void focusLost(java.awt.event.FocusEvent evt) { + startDateTextFieldFocusLost(evt); + } + }); + + javax.swing.GroupLayout jPanel4Layout = new javax.swing.GroupLayout(jPanel4); + jPanel4.setLayout(jPanel4Layout); + jPanel4Layout.setHorizontalGroup( + jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel4Layout.createSequentialGroup() + .addComponent(dateRangeLabel) + .addContainerGap()) + .addGroup(jPanel4Layout.createSequentialGroup() + .addGap(0, 0, 0) + .addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(endCheckBox) + .addComponent(startCheckBox)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(endDateTextField) + .addComponent(startDateTextField)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addComponent(startCalendarButton, javax.swing.GroupLayout.DEFAULT_SIZE, 27, Short.MAX_VALUE) + .addComponent(endCalendarButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))) + ); + jPanel4Layout.setVerticalGroup( + jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel4Layout.createSequentialGroup() + .addComponent(dateRangeLabel) + .addGap(5, 5, 5) + .addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(startCheckBox) + .addComponent(startCalendarButton, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(startDateTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(endCheckBox) + .addComponent(endCalendarButton, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(endDateTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGap(0, 0, 0)) + ); + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() - .addContainerGap() - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) - .addComponent(jPanel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(jPanel3, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup() + .addGroup(layout.createSequentialGroup() + .addGap(8, 8, 8) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jPanel2, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jPanel3, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGroup(layout.createSequentialGroup() .addComponent(filtersTitleLabel) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(applyFiltersButton, javax.swing.GroupLayout.PREFERRED_SIZE, 83, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addComponent(applyFiltersButton, javax.swing.GroupLayout.PREFERRED_SIZE, 83, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(jPanel4, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addContainerGap()) ); layout.setVerticalGroup( @@ -283,9 +418,11 @@ final public class FiltersPanel extends javax.swing.JPanel { .addComponent(applyFiltersButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addGap(18, 18, 18) .addComponent(jPanel3, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGap(18, 18, 18) .addComponent(jPanel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addGap(18, 18, 18) + .addComponent(jPanel4, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addContainerGap()) ); }// //GEN-END:initComponents @@ -388,6 +525,56 @@ final public class FiltersPanel extends javax.swing.JPanel { setAllDevicesSelected(true); }//GEN-LAST:event_checkAllDevicesButtonActionPerformed + private void endDateTextFieldFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_endDateTextFieldFocusLost + String endDateString = this.endDateTextField.getText(); + if (endDateString.isEmpty() == false) { + try { + Date fromDate = DATE_FORMAT.parse(endDateString); + endCalendarButton.setTargetDate(fromDate); + } catch (ParseException ex) { + // for now, no need to show the error message to the user here + } + } else { + endCheckBox.setSelected(false); + } + }//GEN-LAST:event_endDateTextFieldFocusLost + + private void startDateTextFieldFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_startDateTextFieldFocusLost + String startDateString = this.startDateTextField.getText(); + if (startDateString.isEmpty() == false) { + try { + Date fromDate = DATE_FORMAT.parse(startDateString); + startCalendarButton.setTargetDate(fromDate); + } catch (ParseException ex) { + // for now, no need to show the error message to the user here + } + } else { + startCheckBox.setSelected(false); + } + }//GEN-LAST:event_startDateTextFieldFocusLost + + private void startCheckBoxStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_startCheckBoxStateChanged + boolean selected = startCheckBox.isSelected(); + startCalendarButton.setEnabled(selected); + startDateTextField.setEnabled(selected); + + if (selected && startDateTextField.getText().isEmpty()) { + final Instant threeWeeksAgoInstant = + LocalDate.now().minusWeeks(3).atStartOfDay(ZoneId.systemDefault()).toInstant(); + setStartDate(Date.from(threeWeeksAgoInstant)); + } + }//GEN-LAST:event_startCheckBoxStateChanged + + private void endCheckBoxStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_endCheckBoxStateChanged + boolean selected = endCheckBox.isSelected(); + endCalendarButton.setEnabled(selected); + endDateTextField.setEnabled(selected); + + if (selected && endDateTextField.getText().isEmpty()) { + setEndDate(new Date()); + } + }//GEN-LAST:event_endCheckBoxStateChanged + // Variables declaration - do not modify//GEN-BEGIN:variables private final javax.swing.JPanel accountTypePane = new javax.swing.JPanel(); @@ -395,13 +582,21 @@ final public class FiltersPanel extends javax.swing.JPanel { private final javax.swing.JButton applyFiltersButton = new javax.swing.JButton(); private final javax.swing.JButton checkAllAccountTypesButton = new javax.swing.JButton(); private final javax.swing.JButton checkAllDevicesButton = new javax.swing.JButton(); + private final javax.swing.JLabel dateRangeLabel = new javax.swing.JLabel(); private final javax.swing.JLabel devicesLabel = new javax.swing.JLabel(); private final javax.swing.JPanel devicesPane = new javax.swing.JPanel(); + private final org.jbundle.thin.base.screen.jcalendarbutton.JCalendarButton endCalendarButton = new org.jbundle.thin.base.screen.jcalendarbutton.JCalendarButton(); + private final javax.swing.JCheckBox endCheckBox = new javax.swing.JCheckBox(); + private final javax.swing.JFormattedTextField endDateTextField = new JFormattedTextField(this.DATE_FORMAT); private final javax.swing.JLabel filtersTitleLabel = new javax.swing.JLabel(); private final javax.swing.JList jList1 = new javax.swing.JList<>(); private final javax.swing.JPanel jPanel2 = new javax.swing.JPanel(); private final javax.swing.JPanel jPanel3 = new javax.swing.JPanel(); + private final javax.swing.JPanel jPanel4 = new javax.swing.JPanel(); private final javax.swing.JScrollPane jScrollPane1 = new javax.swing.JScrollPane(); + private final org.jbundle.thin.base.screen.jcalendarbutton.JCalendarButton startCalendarButton = new org.jbundle.thin.base.screen.jcalendarbutton.JCalendarButton(); + private final javax.swing.JCheckBox startCheckBox = new javax.swing.JCheckBox(); + private final javax.swing.JFormattedTextField startDateTextField = new JFormattedTextField(this.DATE_FORMAT); private final javax.swing.JButton unCheckAllAccountTypesButton = new javax.swing.JButton(); private final javax.swing.JButton unCheckAllDevicesButton = new javax.swing.JButton(); // End of variables declaration//GEN-END:variables From 1b296156936baf9b22a0b503710bb9d2ab5689e2 Mon Sep 17 00:00:00 2001 From: millmanorama Date: Fri, 10 Nov 2017 21:18:48 +0100 Subject: [PATCH 073/127] just set the default value initialy, don't wait for fields to be eneabled --- .../autopsy/communications/FiltersPanel.java | 47 +++++++------------ 1 file changed, 16 insertions(+), 31 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java index 43ba0b4a4c..f397627f65 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java +++ b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java @@ -68,7 +68,10 @@ final public class FiltersPanel extends javax.swing.JPanel { initComponents(); startCalendarButton.addPropertyChangeListener(this::startPopupChanged); endCalendarButton.addPropertyChangeListener(this::endPopupChanged); - + final Instant threeWeeksAgoInstant = + LocalDate.now().minusWeeks(3).atStartOfDay(ZoneId.systemDefault()).toInstant(); + setStartDate(Date.from(threeWeeksAgoInstant)); + setEndDate(new Date()); updateAndApplyFilters(); } @@ -527,52 +530,34 @@ final public class FiltersPanel extends javax.swing.JPanel { private void endDateTextFieldFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_endDateTextFieldFocusLost String endDateString = this.endDateTextField.getText(); - if (endDateString.isEmpty() == false) { - try { - Date fromDate = DATE_FORMAT.parse(endDateString); - endCalendarButton.setTargetDate(fromDate); - } catch (ParseException ex) { - // for now, no need to show the error message to the user here - } - } else { - endCheckBox.setSelected(false); + try { + Date fromDate = DATE_FORMAT.parse(endDateString); + endCalendarButton.setTargetDate(fromDate); + } catch (ParseException ex) { + // for now, no need to show the error message to the user here } }//GEN-LAST:event_endDateTextFieldFocusLost private void startDateTextFieldFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_startDateTextFieldFocusLost String startDateString = this.startDateTextField.getText(); - if (startDateString.isEmpty() == false) { - try { - Date fromDate = DATE_FORMAT.parse(startDateString); - startCalendarButton.setTargetDate(fromDate); - } catch (ParseException ex) { - // for now, no need to show the error message to the user here - } - } else { - startCheckBox.setSelected(false); + try { + Date fromDate = DATE_FORMAT.parse(startDateString); + startCalendarButton.setTargetDate(fromDate); + } catch (ParseException ex) { + // for now, no need to show the error message to the user here } }//GEN-LAST:event_startDateTextFieldFocusLost private void startCheckBoxStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_startCheckBoxStateChanged - boolean selected = startCheckBox.isSelected(); + boolean selected = startCheckBox.isSelected(); startCalendarButton.setEnabled(selected); startDateTextField.setEnabled(selected); - - if (selected && startDateTextField.getText().isEmpty()) { - final Instant threeWeeksAgoInstant = - LocalDate.now().minusWeeks(3).atStartOfDay(ZoneId.systemDefault()).toInstant(); - setStartDate(Date.from(threeWeeksAgoInstant)); - } }//GEN-LAST:event_startCheckBoxStateChanged private void endCheckBoxStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_endCheckBoxStateChanged - boolean selected = endCheckBox.isSelected(); + boolean selected = endCheckBox.isSelected(); endCalendarButton.setEnabled(selected); endDateTextField.setEnabled(selected); - - if (selected && endDateTextField.getText().isEmpty()) { - setEndDate(new Date()); - } }//GEN-LAST:event_endCheckBoxStateChanged From 3c341e3fe7e28d0dec909c272ad21f8a82785024 Mon Sep 17 00:00:00 2001 From: millmanorama Date: Wed, 8 Nov 2017 09:41:46 +0100 Subject: [PATCH 074/127] add DataResultPanel for attachments to MessageContentViewer --- .../communications/RelationShipNode.java | 9 +++ .../contentviewers/MessageContentViewer.java | 55 +++++++++++++++++++ .../AbstractDataResultViewer.java | 15 +++-- .../corecomponents/DataResultPanel.java | 21 +++---- 4 files changed, 78 insertions(+), 22 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/communications/RelationShipNode.java b/Core/src/org/sleuthkit/autopsy/communications/RelationShipNode.java index b46aa90ff3..84bfc94327 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/RelationShipNode.java +++ b/Core/src/org/sleuthkit/autopsy/communications/RelationShipNode.java @@ -21,6 +21,7 @@ package org.sleuthkit.autopsy.communications; import java.util.logging.Level; import org.apache.commons.lang3.StringUtils; import org.openide.nodes.Sheet; +import org.openide.util.Exceptions; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.datamodel.BlackboardArtifactNode; import org.sleuthkit.autopsy.datamodel.NodeProperty; @@ -75,6 +76,14 @@ public class RelationShipNode extends BlackboardArtifactNode { getAttributeDisplayString(artifact, TSK_DATETIME_SENT))); ss.put(new NodeProperty<>("Subject", "Subject", "Subject", getAttributeDisplayString(artifact, TSK_SUBJECT))); + { + try { + ss.put(new NodeProperty<>("at", "at", "at", + artifact.getChildrenCount() > 0)); + } catch (TskCoreException ex) { + Exceptions.printStackTrace(ex); + } + } break; case TSK_MESSAGE: ss.put(new NodeProperty<>("From", "From", "From", diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java b/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java index aa75370afb..ce9c89f252 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java @@ -19,18 +19,29 @@ package org.sleuthkit.autopsy.contentviewers; import java.awt.Component; +import java.beans.PropertyChangeEvent; import java.util.Arrays; import java.util.List; import java.util.Optional; +import java.util.Set; import java.util.logging.Level; +import java.util.stream.Collectors; import javax.swing.text.JTextComponent; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; +import org.openide.nodes.AbstractNode; +import org.openide.nodes.Children; import org.openide.nodes.Node; import org.openide.util.NbBundle; import org.openide.util.lookup.ServiceProvider; +import org.sleuthkit.autopsy.corecomponentinterfaces.DataContent; import org.sleuthkit.autopsy.corecomponentinterfaces.DataContentViewer; +import org.sleuthkit.autopsy.corecomponents.DataResultPanel; +import org.sleuthkit.autopsy.corecomponents.TableFilterNode; import org.sleuthkit.autopsy.coreutils.Logger; +import org.sleuthkit.autopsy.datamodel.FileNode; +import org.sleuthkit.autopsy.directorytree.DataResultFilterNode; +import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.BlackboardArtifact; import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_EMAIL_MSG; import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_MESSAGE; @@ -70,17 +81,36 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont * Artifact currently being displayed */ private BlackboardArtifact artifact; + private DataResultPanel drp; /** * Creates new MessageContentViewer */ public MessageContentViewer() { initComponents(); + + drp = DataResultPanel.createInstanceUninitialized("Attachments", "", Node.EMPTY, 0, new DataContent() { + @Override + public void setNode(Node selectedNode) { +// throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public void propertyChange(PropertyChangeEvent evt) { +// throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + } + ); + msgbodyTabbedPane.addTab("Attachments", drp); + msgbodyTabbedPane.setEnabledAt(4, true); + textAreas = Arrays.asList(headersTextArea, textbodyTextArea, htmlbodyTextPane, rtfbodyTextPane); Utilities.configureTextPaneAsHtml(htmlbodyTextPane); Utilities.configureTextPaneAsRtf(rtfbodyTextPane); resetComponent(); + + drp.open(); } /** @@ -339,6 +369,7 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont } if (artifact.getArtifactTypeID() == TSK_MESSAGE.getTypeID()) { + displayMsg(); } else if (artifact.getArtifactTypeID() == TSK_EMAIL_MSG.getTypeID()) { displayEmailMsg(); @@ -480,6 +511,10 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont msgbodyTabbedPane.setEnabledAt(RTF_TAB_INDEX, false); msgbodyTabbedPane.setEnabledAt(HDR_TAB_INDEX, false); configureTextArea(TSK_TEXT, TEXT_TAB_INDEX); + drp.setNode(new DataResultFilterNode(new TableFilterNode(new AbstractNode(new AttachmentsChildren(artifact.getChildren().stream() + .filter(AbstractFile.class::isInstance) + .map(AbstractFile.class::cast) + .collect(Collectors.toSet()))), true), null)); } catch (TskCoreException ex) { LOGGER.log(Level.WARNING, "Failed to get attributes for message.", ex); //NON-NLS } @@ -507,4 +542,24 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont return doc.html(); } + + private static class AttachmentsChildren extends Children.Keys { + + private final Set files; + + AttachmentsChildren(Set collect) { + this.files = collect; + } + + @Override + protected Node[] createNodes(AbstractFile t) { + return new Node[]{new FileNode(t)}; + } + + @Override + protected void addNotify() { + super.addNotify(); + setKeys(files); + } + } } diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/AbstractDataResultViewer.java b/Core/src/org/sleuthkit/autopsy/corecomponents/AbstractDataResultViewer.java index fcbb1233e9..00385bb3fb 100755 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/AbstractDataResultViewer.java +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/AbstractDataResultViewer.java @@ -25,7 +25,6 @@ import javax.swing.JPanel; import org.openide.explorer.ExplorerManager; import org.openide.explorer.ExplorerManager.Provider; import org.openide.nodes.Node; -import org.openide.util.Lookup; import org.sleuthkit.autopsy.corecomponentinterfaces.DataContent; import org.sleuthkit.autopsy.corecomponentinterfaces.DataResultViewer; import org.sleuthkit.autopsy.coreutils.Logger; @@ -40,11 +39,11 @@ abstract class AbstractDataResultViewer extends JPanel implements DataResultView private static final Logger logger = Logger.getLogger(AbstractDataResultViewer.class.getName()); protected transient ExplorerManager em; - /** - * Content viewer to respond to selection events Either the main one, or - * custom one if set - */ - protected DataContent contentViewer; +// /** +// * Content viewer to respond to selection events Either the main one, or +// * custom one if set +// */ +// protected DataContent contentViewer; /** * This constructor is intended to allow an AbstractDataResultViewer to use @@ -58,7 +57,7 @@ abstract class AbstractDataResultViewer extends JPanel implements DataResultView this.em = explorerManager; //DataContent is designed to return only the default viewer from lookup //use the default one unless set otherwise - contentViewer = Lookup.getDefault().lookup(DataContent.class); +// contentViewer = Lookup.getDefault().lookup(DataContent.class); } /** @@ -112,6 +111,6 @@ abstract class AbstractDataResultViewer extends JPanel implements DataResultView @Override public void setContentViewer(DataContent contentViewer) { - this.contentViewer = contentViewer; +// this.contentViewer = contentViewer; } } diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultPanel.java b/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultPanel.java index 09b292dd29..879f67351a 100755 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultPanel.java +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultPanel.java @@ -159,16 +159,6 @@ public class DataResultPanel extends javax.swing.JPanel implements DataResult, C resultViewPanel.setPath(pathText); } - /** - * Constructs a Swing JPanel with a JTabbedPane child component that - * contains result viewers (implementations of the DataResultViewer - * interface). - */ - private DataResultPanel() { - this.isMain = true; - initComponents(); - } - /** * Constructs a Swing JPanel with a JTabbedPane child component that * contains result viewers (implementations of the DataResultViewer @@ -179,9 +169,13 @@ public class DataResultPanel extends javax.swing.JPanel implements DataResult, C * DataResultPanel. */ DataResultPanel(String title, boolean isMain) { - this(); + this(isMain, Lookup.getDefault().lookup(DataContent.class)); + } + + private DataResultPanel(boolean isMain, DataContent contentView) { this.isMain = isMain; - this.contentView = Lookup.getDefault().lookup(DataContent.class); + this.contentView = contentView; + initComponents(); } /** @@ -194,8 +188,7 @@ public class DataResultPanel extends javax.swing.JPanel implements DataResult, C * content view. */ DataResultPanel(String title, DataContent customContentView) { - this(title, false); - this.contentView = customContentView; + this(false, customContentView); } /** From cc448531f8ab8ab2dbb1ba7e869c028e9e91a215 Mon Sep 17 00:00:00 2001 From: millmanorama Date: Thu, 9 Nov 2017 12:36:33 +0100 Subject: [PATCH 075/127] put some garbage data in the attachments table to test it. --- .../contentviewers/MessageContentViewer.java | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java b/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java index ce9c89f252..0d43bd6849 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java @@ -81,7 +81,7 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont * Artifact currently being displayed */ private BlackboardArtifact artifact; - private DataResultPanel drp; + private DataResultPanel drp; /** * Creates new MessageContentViewer @@ -480,6 +480,15 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont configureTextArea(TSK_EMAIL_CONTENT_PLAIN, TEXT_TAB_INDEX); configureTextArea(TSK_EMAIL_CONTENT_HTML, HTML_TAB_INDEX); configureTextArea(TSK_EMAIL_CONTENT_RTF, RTF_TAB_INDEX); + + final Set attachments = artifact.getDataSource().getChildren().stream() + .filter(AbstractFile.class::isInstance) + .map(AbstractFile.class::cast) + .collect(Collectors.toSet()); + + drp.setNode(new TableFilterNode(new DataResultFilterNode(new AbstractNode( + new AttachmentsChildren(attachments)), null), true)); + } catch (TskCoreException ex) { LOGGER.log(Level.WARNING, "Failed to get attributes for email message.", ex); //NON-NLS } @@ -511,10 +520,6 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont msgbodyTabbedPane.setEnabledAt(RTF_TAB_INDEX, false); msgbodyTabbedPane.setEnabledAt(HDR_TAB_INDEX, false); configureTextArea(TSK_TEXT, TEXT_TAB_INDEX); - drp.setNode(new DataResultFilterNode(new TableFilterNode(new AbstractNode(new AttachmentsChildren(artifact.getChildren().stream() - .filter(AbstractFile.class::isInstance) - .map(AbstractFile.class::cast) - .collect(Collectors.toSet()))), true), null)); } catch (TskCoreException ex) { LOGGER.log(Level.WARNING, "Failed to get attributes for message.", ex); //NON-NLS } From 3ab2dca596c4990b69ff4635d17cf33654cc4059 Mon Sep 17 00:00:00 2001 From: millmanorama Date: Thu, 9 Nov 2017 14:28:03 +0100 Subject: [PATCH 076/127] add View in New Window button to attachments tab of MessageContentViewer --- .../autopsy/contentviewers/Bundle.properties | 2 + .../contentviewers/MessageContentViewer.form | 58 +++++++++++++++++ .../contentviewers/MessageContentViewer.java | 65 ++++++++++++++++++- .../corecomponents/DataResultPanel.java | 7 +- 4 files changed, 128 insertions(+), 4 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/Bundle.properties b/Core/src/org/sleuthkit/autopsy/contentviewers/Bundle.properties index e0a5e749d2..29697568fe 100755 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/Bundle.properties @@ -31,3 +31,5 @@ MessageContentViewer.subjectLabel.text=Subject: MessageContentViewer.subjectText.text=subject goes here MessageContentViewer.directionText.text=direction MessageContentViewer.ccLabel.text=CC: +MessageContentViewer.attachmentsPanel.TabConstraints.tabTitle=Attachments +MessageContentViewer.viewInNewWindowButton.text=View in new Window diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.form b/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.form index 856adf99a8..9fdcddfe02 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.form +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.form @@ -336,6 +336,64 @@
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java b/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java index 0d43bd6849..2836b69b50 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java @@ -29,6 +29,7 @@ import java.util.stream.Collectors; import javax.swing.text.JTextComponent; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; +import org.openide.explorer.ExplorerManager; import org.openide.nodes.AbstractNode; import org.openide.nodes.Children; import org.openide.nodes.Node; @@ -41,6 +42,7 @@ import org.sleuthkit.autopsy.corecomponents.TableFilterNode; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.datamodel.FileNode; import org.sleuthkit.autopsy.directorytree.DataResultFilterNode; +import org.sleuthkit.autopsy.directorytree.NewWindowViewAction; import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.BlackboardArtifact; import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_EMAIL_MSG; @@ -75,6 +77,7 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont private static final int TEXT_TAB_INDEX = 1; private static final int HTML_TAB_INDEX = 2; private static final int RTF_TAB_INDEX = 3; + private static final int ATTM_TAB_INDEX = 4; private final List textAreas; /** @@ -82,13 +85,13 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont */ private BlackboardArtifact artifact; private DataResultPanel drp; + private final ExplorerManager drpExplorerManager; /** * Creates new MessageContentViewer */ public MessageContentViewer() { initComponents(); - drp = DataResultPanel.createInstanceUninitialized("Attachments", "", Node.EMPTY, 0, new DataContent() { @Override public void setNode(Node selectedNode) { @@ -101,7 +104,8 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont } } ); - msgbodyTabbedPane.addTab("Attachments", drp); + + attachmentsScrollPane.setViewportView(drp); msgbodyTabbedPane.setEnabledAt(4, true); textAreas = Arrays.asList(headersTextArea, textbodyTextArea, htmlbodyTextPane, rtfbodyTextPane); @@ -111,6 +115,10 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont resetComponent(); drp.open(); + drpExplorerManager = drp.getExplorerManager(); + drpExplorerManager.addPropertyChangeListener(evt + -> viewInNewWindowButton.setEnabled(drpExplorerManager.getSelectedNodes().length == 1)); + } /** @@ -144,6 +152,9 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont showImagesToggleButton = new javax.swing.JToggleButton(); rtfbodyScrollPane = new javax.swing.JScrollPane(); rtfbodyTextPane = new javax.swing.JTextPane(); + attachmentsPanel = new javax.swing.JPanel(); + viewInNewWindowButton = new javax.swing.JButton(); + attachmentsScrollPane = new javax.swing.JScrollPane(); envelopePanel.setBackground(new java.awt.Color(204, 204, 204)); @@ -287,6 +298,39 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont msgbodyTabbedPane.addTab(org.openide.util.NbBundle.getMessage(MessageContentViewer.class, "MessageContentViewer.rtfbodyScrollPane.TabConstraints.tabTitle"), rtfbodyScrollPane); // NOI18N + org.openide.awt.Mnemonics.setLocalizedText(viewInNewWindowButton, org.openide.util.NbBundle.getMessage(MessageContentViewer.class, "MessageContentViewer.viewInNewWindowButton.text")); // NOI18N + viewInNewWindowButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + viewInNewWindowButtonActionPerformed(evt); + } + }); + + javax.swing.GroupLayout attachmentsPanelLayout = new javax.swing.GroupLayout(attachmentsPanel); + attachmentsPanel.setLayout(attachmentsPanelLayout); + attachmentsPanelLayout.setHorizontalGroup( + attachmentsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(attachmentsPanelLayout.createSequentialGroup() + .addGap(0, 0, 0) + .addGroup(attachmentsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, attachmentsPanelLayout.createSequentialGroup() + .addComponent(viewInNewWindowButton) + .addGap(3, 3, 3)) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, attachmentsPanelLayout.createSequentialGroup() + .addComponent(attachmentsScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 647, Short.MAX_VALUE) + .addGap(0, 0, 0)))) + ); + attachmentsPanelLayout.setVerticalGroup( + attachmentsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(attachmentsPanelLayout.createSequentialGroup() + .addGap(0, 0, 0) + .addComponent(viewInNewWindowButton) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(attachmentsScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 327, Short.MAX_VALUE) + .addGap(0, 0, 0)) + ); + + msgbodyTabbedPane.addTab(org.openide.util.NbBundle.getMessage(MessageContentViewer.class, "MessageContentViewer.attachmentsPanel.TabConstraints.tabTitle"), attachmentsPanel); // NOI18N + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); layout.setHorizontalGroup( @@ -329,8 +373,15 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont } }//GEN-LAST:event_showImagesToggleButtonActionPerformed + private void viewInNewWindowButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_viewInNewWindowButtonActionPerformed + + new NewWindowViewAction("View in new window", drpExplorerManager.getSelectedNodes()[0]).actionPerformed(evt); + }//GEN-LAST:event_viewInNewWindowButtonActionPerformed + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JPanel attachmentsPanel; + private javax.swing.JScrollPane attachmentsScrollPane; private javax.swing.JLabel ccLabel; private javax.swing.JLabel ccText; private javax.swing.JLabel datetimeText; @@ -353,6 +404,7 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont private javax.swing.JTextArea textbodyTextArea; private javax.swing.JLabel toLabel; private javax.swing.JLabel toText; + private javax.swing.JButton viewInNewWindowButton; // End of variables declaration//GEN-END:variables @Override @@ -480,12 +532,16 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont configureTextArea(TSK_EMAIL_CONTENT_PLAIN, TEXT_TAB_INDEX); configureTextArea(TSK_EMAIL_CONTENT_HTML, HTML_TAB_INDEX); configureTextArea(TSK_EMAIL_CONTENT_RTF, RTF_TAB_INDEX); - + + //TODO: Replace this with code to get the actual attachements! final Set attachments = artifact.getDataSource().getChildren().stream() .filter(AbstractFile.class::isInstance) .map(AbstractFile.class::cast) .collect(Collectors.toSet()); + final int numberOfAttachments = attachments.size(); + msgbodyTabbedPane.setEnabledAt(4, numberOfAttachments > 0); + msgbodyTabbedPane.setTitleAt(4, "Attachments (" + numberOfAttachments + ")"); drp.setNode(new TableFilterNode(new DataResultFilterNode(new AbstractNode( new AttachmentsChildren(attachments)), null), true)); @@ -519,7 +575,10 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont msgbodyTabbedPane.setEnabledAt(HTML_TAB_INDEX, false); msgbodyTabbedPane.setEnabledAt(RTF_TAB_INDEX, false); msgbodyTabbedPane.setEnabledAt(HDR_TAB_INDEX, false); + msgbodyTabbedPane.setEnabledAt(HDR_TAB_INDEX, false); configureTextArea(TSK_TEXT, TEXT_TAB_INDEX); + msgbodyTabbedPane.setEnabledAt(ATTM_TAB_INDEX, false); + msgbodyTabbedPane.setTitleAt(ATTM_TAB_INDEX, "Attachments"); } catch (TskCoreException ex) { LOGGER.log(Level.WARNING, "Failed to get attributes for message.", ex); //NON-NLS } diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultPanel.java b/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultPanel.java index 879f67351a..12e78e2d68 100755 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultPanel.java +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultPanel.java @@ -65,7 +65,7 @@ import org.sleuthkit.autopsy.datamodel.NodeSelectionInfo; * normally docked into the lower right hand side of the main window, underneath * the results view. A custom content view may be specified instead. */ -public class DataResultPanel extends javax.swing.JPanel implements DataResult, ChangeListener { +public class DataResultPanel extends javax.swing.JPanel implements DataResult, ChangeListener, ExplorerManager.Provider { private static final long serialVersionUID = 1L; private static final int NO_TAB_SELECTED = -1; @@ -521,6 +521,11 @@ public class DataResultPanel extends javax.swing.JPanel implements DataResult, C } } + @Override + public ExplorerManager getExplorerManager() { + return explorerManager; + } + /** * Responds to node selection change events from the explorer manager. */ From 76268d787093983ac7e2b47a917d90491c77b6bb Mon Sep 17 00:00:00 2001 From: millmanorama Date: Thu, 9 Nov 2017 14:33:59 +0100 Subject: [PATCH 077/127] tweak layout --- .../autopsy/contentviewers/Bundle.properties | 3 ++- .../contentviewers/MessageContentViewer.form | 12 ++++++------ .../contentviewers/MessageContentViewer.java | 17 ++++++++--------- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/Bundle.properties b/Core/src/org/sleuthkit/autopsy/contentviewers/Bundle.properties index 29697568fe..521ff6318d 100755 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/Bundle.properties @@ -32,4 +32,5 @@ MessageContentViewer.subjectText.text=subject goes here MessageContentViewer.directionText.text=direction MessageContentViewer.ccLabel.text=CC: MessageContentViewer.attachmentsPanel.TabConstraints.tabTitle=Attachments -MessageContentViewer.viewInNewWindowButton.text=View in new Window +MessageContentViewer.viewInNewWindowButton.text=View in New Window +MessageContentViewer.showImagesToggleButton.text=Show Images diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.form b/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.form index 9fdcddfe02..3a07d09210 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.form +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.form @@ -29,11 +29,11 @@ - + - + @@ -106,7 +106,7 @@
- + @@ -266,7 +266,7 @@ - + @@ -277,7 +277,7 @@ - + @@ -371,7 +371,7 @@ - +
diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java b/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java index 2836b69b50..797f4ead1a 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java @@ -228,7 +228,7 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont .addGroup(envelopePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(ccLabel) .addComponent(ccText)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(envelopePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(subjectLabel) .addComponent(subjectText)) @@ -276,7 +276,7 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont htmlPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(htmlScrollPane) .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, htmlPaneLayout.createSequentialGroup() - .addContainerGap(283, Short.MAX_VALUE) + .addContainerGap(533, Short.MAX_VALUE) .addComponent(showImagesToggleButton) .addGap(3, 3, 3)) ); @@ -285,7 +285,7 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont .addGroup(htmlPaneLayout.createSequentialGroup() .addComponent(showImagesToggleButton) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(htmlScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 327, Short.MAX_VALUE) + .addComponent(htmlScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 333, Short.MAX_VALUE) .addGap(0, 0, 0)) ); @@ -325,7 +325,7 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont .addGap(0, 0, 0) .addComponent(viewInNewWindowButton) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(attachmentsScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 327, Short.MAX_VALUE) + .addComponent(attachmentsScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 333, Short.MAX_VALUE) .addGap(0, 0, 0)) ); @@ -345,17 +345,16 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() - .addContainerGap() + .addGap(5, 5, 5) .addComponent(envelopePanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(msgbodyTabbedPane) - .addContainerGap()) + .addGap(5, 5, 5)) ); }// //GEN-END:initComponents @NbBundle.Messages({ - "MessageContentViewer.showImagesToggleButton.hide.text=Hide Images", - "MessageContentViewer.showImagesToggleButton.text=Show Images"}) + "MessageContentViewer.showImagesToggleButton.hide.text=Hide Images"}) private void showImagesToggleButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_showImagesToggleButtonActionPerformed try { String htmlText = getAttributeValueSafe(artifact, TSK_EMAIL_CONTENT_HTML); @@ -374,7 +373,7 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont }//GEN-LAST:event_showImagesToggleButtonActionPerformed private void viewInNewWindowButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_viewInNewWindowButtonActionPerformed - + new NewWindowViewAction("View in new window", drpExplorerManager.getSelectedNodes()[0]).actionPerformed(evt); }//GEN-LAST:event_viewInNewWindowButtonActionPerformed From be9efad3cedf8f733d29392cc2d4eed7f389bc35 Mon Sep 17 00:00:00 2001 From: millmanorama Date: Thu, 9 Nov 2017 14:40:40 +0100 Subject: [PATCH 078/127] remove no-op implementation --- .../contentviewers/MessageContentViewer.java | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java b/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java index 797f4ead1a..deec64f5b2 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java @@ -19,7 +19,6 @@ package org.sleuthkit.autopsy.contentviewers; import java.awt.Component; -import java.beans.PropertyChangeEvent; import java.util.Arrays; import java.util.List; import java.util.Optional; @@ -35,7 +34,6 @@ import org.openide.nodes.Children; import org.openide.nodes.Node; import org.openide.util.NbBundle; import org.openide.util.lookup.ServiceProvider; -import org.sleuthkit.autopsy.corecomponentinterfaces.DataContent; import org.sleuthkit.autopsy.corecomponentinterfaces.DataContentViewer; import org.sleuthkit.autopsy.corecomponents.DataResultPanel; import org.sleuthkit.autopsy.corecomponents.TableFilterNode; @@ -92,18 +90,7 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont */ public MessageContentViewer() { initComponents(); - drp = DataResultPanel.createInstanceUninitialized("Attachments", "", Node.EMPTY, 0, new DataContent() { - @Override - public void setNode(Node selectedNode) { -// throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public void propertyChange(PropertyChangeEvent evt) { -// throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - } - ); + drp = DataResultPanel.createInstanceUninitialized("Attachments", "", Node.EMPTY, 0, null); attachmentsScrollPane.setViewportView(drp); msgbodyTabbedPane.setEnabledAt(4, true); From f0c2e3c79650856b1b8011c1bb872f501b3f558f Mon Sep 17 00:00:00 2001 From: millmanorama Date: Thu, 9 Nov 2017 15:15:15 +0100 Subject: [PATCH 079/127] add MessageContentViewer.AttachmentNode to limit the number of properties shown for attachments --- .../communications/RelationShipNode.java | 1 - .../contentviewers/MessageContentViewer.java | 31 ++++++++++++++++++- .../datamodel/AbstractFsContentNode.java | 3 +- .../autopsy/datamodel/Bundle.properties | 1 - 4 files changed, 32 insertions(+), 4 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/communications/RelationShipNode.java b/Core/src/org/sleuthkit/autopsy/communications/RelationShipNode.java index 84bfc94327..de9c3c0dc0 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/RelationShipNode.java +++ b/Core/src/org/sleuthkit/autopsy/communications/RelationShipNode.java @@ -54,7 +54,6 @@ public class RelationShipNode extends BlackboardArtifactNode { @Override protected Sheet createSheet() { - Sheet s = new Sheet(); Sheet.Set ss = s.get(Sheet.PROPERTIES); if (ss == null) { diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java b/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java index deec64f5b2..6a06e2d1da 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java @@ -32,6 +32,7 @@ import org.openide.explorer.ExplorerManager; import org.openide.nodes.AbstractNode; import org.openide.nodes.Children; import org.openide.nodes.Node; +import org.openide.nodes.Sheet; import org.openide.util.NbBundle; import org.openide.util.lookup.ServiceProvider; import org.sleuthkit.autopsy.corecomponentinterfaces.DataContentViewer; @@ -39,6 +40,7 @@ import org.sleuthkit.autopsy.corecomponents.DataResultPanel; import org.sleuthkit.autopsy.corecomponents.TableFilterNode; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.datamodel.FileNode; +import org.sleuthkit.autopsy.datamodel.NodeProperty; import org.sleuthkit.autopsy.directorytree.DataResultFilterNode; import org.sleuthkit.autopsy.directorytree.NewWindowViewAction; import org.sleuthkit.datamodel.AbstractFile; @@ -603,7 +605,7 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont @Override protected Node[] createNodes(AbstractFile t) { - return new Node[]{new FileNode(t)}; + return new Node[]{new AttachmentNode(t)}; } @Override @@ -612,4 +614,31 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont setKeys(files); } } + + private static class AttachmentNode extends FileNode { + + private final AbstractFile file; + + AttachmentNode(AbstractFile file) { + super(file, true); + this.file = file; + } + + @Override + protected Sheet createSheet() { + Sheet s = new Sheet(); + Sheet.Set ss = s.get(Sheet.PROPERTIES); + if (ss == null) { + ss = Sheet.createPropertiesSet(); + s.put(ss); + } + + ss.put(new NodeProperty<>("Name", "Name", "Name", file.getName())); + ss.put(new NodeProperty<>("Size", "Size", "Size", file.getSize())); + ss.put(new NodeProperty<>("Mime Type", "Mime Type", "Mime Type", file.getMIMEType())); + ss.put(new NodeProperty<>("Known", "Known", "Known", file.getKnown().getName())); + return s; + } + + } } diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractFsContentNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractFsContentNode.java index b8a6807c24..372ae3e6ea 100755 --- a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractFsContentNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractFsContentNode.java @@ -61,6 +61,7 @@ public abstract class AbstractFsContentNode extends Abst } @Override + @NbBundle.Messages("AbstractFsContentNode.noDesc.text=no description") protected Sheet createSheet() { Sheet s = super.createSheet(); Sheet.Set ss = s.get(Sheet.PROPERTIES); @@ -72,7 +73,7 @@ public abstract class AbstractFsContentNode extends Abst Map map = new LinkedHashMap<>(); fillPropertyMap(map, getContent()); - final String NO_DESCR = NbBundle.getMessage(this.getClass(), "AbstractFsContentNode.noDesc.text"); + final String NO_DESCR = Bundle.AbstractFsContentNode_noDesc_text(); for (AbstractFilePropertyType propType : AbstractFilePropertyType.values()) { final String propString = propType.toString(); ss.put(new NodeProperty<>(propString, propString, NO_DESCR, map.get(propString))); diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/Bundle.properties b/Core/src/org/sleuthkit/autopsy/datamodel/Bundle.properties index dd8a8cb5ff..7063656562 100755 --- a/Core/src/org/sleuthkit/autopsy/datamodel/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/datamodel/Bundle.properties @@ -2,7 +2,6 @@ OpenIDE-Module-Name=DataModel AbstractContentChildren.CreateTSKNodeVisitor.exception.noNodeMsg=No Node defined for the given SleuthkitItem AbstractContentChildren.createAutopsyNodeVisitor.exception.noNodeMsg=No Node defined for the given DisplayableItem AbstractContentNode.exception.cannotChangeSysName.msg=Cannot change the system name. -AbstractFsContentNode.noDesc.text=no description ArtifactStringContent.getStr.srcFilePath.text=Source File Path ArtifactStringContent.getStr.err=Error getting content ArtifactTypeNode.createSheet.artType.name=Artifact Type From 0f6acfe53be4794e3b77fb841ff177e0b4e3651f Mon Sep 17 00:00:00 2001 From: millmanorama Date: Thu, 9 Nov 2017 15:55:56 +0100 Subject: [PATCH 080/127] messages could have attachments too --- .../contentviewers/MessageContentViewer.java | 32 +++++++++++-------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java b/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java index 6a06e2d1da..ea19ffe1ad 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java @@ -521,23 +521,28 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont configureTextArea(TSK_EMAIL_CONTENT_HTML, HTML_TAB_INDEX); configureTextArea(TSK_EMAIL_CONTENT_RTF, RTF_TAB_INDEX); - //TODO: Replace this with code to get the actual attachements! - final Set attachments = artifact.getDataSource().getChildren().stream() - .filter(AbstractFile.class::isInstance) - .map(AbstractFile.class::cast) - .collect(Collectors.toSet()); - final int numberOfAttachments = attachments.size(); - - msgbodyTabbedPane.setEnabledAt(4, numberOfAttachments > 0); - msgbodyTabbedPane.setTitleAt(4, "Attachments (" + numberOfAttachments + ")"); - drp.setNode(new TableFilterNode(new DataResultFilterNode(new AbstractNode( - new AttachmentsChildren(attachments)), null), true)); + + configureAttachments(); } catch (TskCoreException ex) { LOGGER.log(Level.WARNING, "Failed to get attributes for email message.", ex); //NON-NLS } } + private void configureAttachments() throws TskCoreException { + //TODO: Replace this with code to get the actual attachements! + final Set attachments = artifact.getChildren().stream() + .filter(AbstractFile.class::isInstance) + .map(AbstractFile.class::cast) + .collect(Collectors.toSet()); + final int numberOfAttachments = attachments.size(); + + msgbodyTabbedPane.setEnabledAt(4, numberOfAttachments > 0); + msgbodyTabbedPane.setTitleAt(4, "Attachments (" + numberOfAttachments + ")"); + drp.setNode(new TableFilterNode(new DataResultFilterNode(new AbstractNode( + new AttachmentsChildren(attachments)), null), true)); + } + private static String wrapInHtmlBody(String htmlText) { return "" + htmlText + ""; } @@ -565,8 +570,7 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont msgbodyTabbedPane.setEnabledAt(HDR_TAB_INDEX, false); msgbodyTabbedPane.setEnabledAt(HDR_TAB_INDEX, false); configureTextArea(TSK_TEXT, TEXT_TAB_INDEX); - msgbodyTabbedPane.setEnabledAt(ATTM_TAB_INDEX, false); - msgbodyTabbedPane.setTitleAt(ATTM_TAB_INDEX, "Attachments"); + configureAttachments(); } catch (TskCoreException ex) { LOGGER.log(Level.WARNING, "Failed to get attributes for message.", ex); //NON-NLS } @@ -637,6 +641,8 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont ss.put(new NodeProperty<>("Size", "Size", "Size", file.getSize())); ss.put(new NodeProperty<>("Mime Type", "Mime Type", "Mime Type", file.getMIMEType())); ss.put(new NodeProperty<>("Known", "Known", "Known", file.getKnown().getName())); + + addTagProperty(ss); return s; } From 5506f232d50216224d6d17929d63d896e8ead39e Mon Sep 17 00:00:00 2001 From: millmanorama Date: Sat, 11 Nov 2017 14:54:23 +0100 Subject: [PATCH 081/127] fix bundle property issue --- .../sleuthkit/autopsy/contentviewers/Bundle.properties | 1 - .../autopsy/contentviewers/MessageContentViewer.form | 9 ++------- .../autopsy/contentviewers/MessageContentViewer.java | 9 ++++----- 3 files changed, 6 insertions(+), 13 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/Bundle.properties b/Core/src/org/sleuthkit/autopsy/contentviewers/Bundle.properties index 521ff6318d..45916b87b3 100755 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/Bundle.properties @@ -33,4 +33,3 @@ MessageContentViewer.directionText.text=direction MessageContentViewer.ccLabel.text=CC: MessageContentViewer.attachmentsPanel.TabConstraints.tabTitle=Attachments MessageContentViewer.viewInNewWindowButton.text=View in New Window -MessageContentViewer.showImagesToggleButton.text=Show Images diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.form b/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.form index 3a07d09210..76cf355856 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.form +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.form @@ -303,9 +303,7 @@ - - - + @@ -357,10 +355,7 @@
- - - - +
diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java b/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java index ea19ffe1ad..ad9f8cc531 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java @@ -252,7 +252,7 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont htmlbodyTextPane.setEditable(false); htmlScrollPane.setViewportView(htmlbodyTextPane); - org.openide.awt.Mnemonics.setLocalizedText(showImagesToggleButton, org.openide.util.NbBundle.getMessage(MessageContentViewer.class, "MessageContentViewer.showImagesToggleButton.text")); // NOI18N + org.openide.awt.Mnemonics.setLocalizedText(showImagesToggleButton, "Show Images"); showImagesToggleButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { showImagesToggleButtonActionPerformed(evt); @@ -304,9 +304,7 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, attachmentsPanelLayout.createSequentialGroup() .addComponent(viewInNewWindowButton) .addGap(3, 3, 3)) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, attachmentsPanelLayout.createSequentialGroup() - .addComponent(attachmentsScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 647, Short.MAX_VALUE) - .addGap(0, 0, 0)))) + .addComponent(attachmentsScrollPane, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 647, Short.MAX_VALUE))) ); attachmentsPanelLayout.setVerticalGroup( attachmentsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) @@ -343,7 +341,8 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont }// //GEN-END:initComponents @NbBundle.Messages({ - "MessageContentViewer.showImagesToggleButton.hide.text=Hide Images"}) + "MessageContentViewer.showImagesToggleButton.hide.text=Hide Images", + "MessageContentViewer.showImagesToggleButton.text=Show Images"}) private void showImagesToggleButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_showImagesToggleButtonActionPerformed try { String htmlText = getAttributeValueSafe(artifact, TSK_EMAIL_CONTENT_HTML); From 237e43ef89362ce0b12304a4e084745ef1d25f50 Mon Sep 17 00:00:00 2001 From: millmanorama Date: Sat, 11 Nov 2017 15:04:54 +0100 Subject: [PATCH 082/127] replace harcoded number --- .../autopsy/contentviewers/MessageContentViewer.java | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java b/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java index ad9f8cc531..bf6a01fc1a 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java @@ -84,7 +84,7 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont * Artifact currently being displayed */ private BlackboardArtifact artifact; - private DataResultPanel drp; + private final DataResultPanel drp; private final ExplorerManager drpExplorerManager; /** @@ -95,7 +95,7 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont drp = DataResultPanel.createInstanceUninitialized("Attachments", "", Node.EMPTY, 0, null); attachmentsScrollPane.setViewportView(drp); - msgbodyTabbedPane.setEnabledAt(4, true); + msgbodyTabbedPane.setEnabledAt(ATTM_TAB_INDEX, true); textAreas = Arrays.asList(headersTextArea, textbodyTextArea, htmlbodyTextPane, rtfbodyTextPane); @@ -107,7 +107,6 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont drpExplorerManager = drp.getExplorerManager(); drpExplorerManager.addPropertyChangeListener(evt -> viewInNewWindowButton.setEnabled(drpExplorerManager.getSelectedNodes().length == 1)); - } /** @@ -361,7 +360,6 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont }//GEN-LAST:event_showImagesToggleButtonActionPerformed private void viewInNewWindowButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_viewInNewWindowButtonActionPerformed - new NewWindowViewAction("View in new window", drpExplorerManager.getSelectedNodes()[0]).actionPerformed(evt); }//GEN-LAST:event_viewInNewWindowButtonActionPerformed @@ -408,7 +406,6 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont } if (artifact.getArtifactTypeID() == TSK_MESSAGE.getTypeID()) { - displayMsg(); } else if (artifact.getArtifactTypeID() == TSK_EMAIL_MSG.getTypeID()) { displayEmailMsg(); @@ -536,8 +533,8 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont .collect(Collectors.toSet()); final int numberOfAttachments = attachments.size(); - msgbodyTabbedPane.setEnabledAt(4, numberOfAttachments > 0); - msgbodyTabbedPane.setTitleAt(4, "Attachments (" + numberOfAttachments + ")"); + msgbodyTabbedPane.setEnabledAt(ATTM_TAB_INDEX, numberOfAttachments > 0); + msgbodyTabbedPane.setTitleAt(ATTM_TAB_INDEX, "Attachments (" + numberOfAttachments + ")"); drp.setNode(new TableFilterNode(new DataResultFilterNode(new AbstractNode( new AttachmentsChildren(attachments)), null), true)); } From ba0d5938ea985746aaf900cc44f592d220610f8d Mon Sep 17 00:00:00 2001 From: millmanorama Date: Sat, 11 Nov 2017 15:35:24 +0100 Subject: [PATCH 083/127] guard against null mimetype --- .../autopsy/contentviewers/MessageContentViewer.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java b/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java index bf6a01fc1a..d0ae158aac 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java @@ -26,6 +26,7 @@ import java.util.Set; import java.util.logging.Level; import java.util.stream.Collectors; import javax.swing.text.JTextComponent; +import org.apache.commons.lang3.StringUtils; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.openide.explorer.ExplorerManager; @@ -517,7 +518,6 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont configureTextArea(TSK_EMAIL_CONTENT_HTML, HTML_TAB_INDEX); configureTextArea(TSK_EMAIL_CONTENT_RTF, RTF_TAB_INDEX); - configureAttachments(); } catch (TskCoreException ex) { @@ -532,7 +532,7 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont .map(AbstractFile.class::cast) .collect(Collectors.toSet()); final int numberOfAttachments = attachments.size(); - + msgbodyTabbedPane.setEnabledAt(ATTM_TAB_INDEX, numberOfAttachments > 0); msgbodyTabbedPane.setTitleAt(ATTM_TAB_INDEX, "Attachments (" + numberOfAttachments + ")"); drp.setNode(new TableFilterNode(new DataResultFilterNode(new AbstractNode( @@ -635,9 +635,9 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont ss.put(new NodeProperty<>("Name", "Name", "Name", file.getName())); ss.put(new NodeProperty<>("Size", "Size", "Size", file.getSize())); - ss.put(new NodeProperty<>("Mime Type", "Mime Type", "Mime Type", file.getMIMEType())); + ss.put(new NodeProperty<>("Mime Type", "Mime Type", "Mime Type", StringUtils.defaultString(file.getMIMEType()))); ss.put(new NodeProperty<>("Known", "Known", "Known", file.getKnown().getName())); - + addTagProperty(ss); return s; } From 3892cfb5fb9cadb56f548a8d70b217a79957b2f2 Mon Sep 17 00:00:00 2001 From: millmanorama Date: Sat, 11 Nov 2017 16:02:50 +0100 Subject: [PATCH 084/127] add attachments column to message, log error --- .../communications/RelationShipNode.java | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/communications/RelationShipNode.java b/Core/src/org/sleuthkit/autopsy/communications/RelationShipNode.java index de9c3c0dc0..622c637ed2 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/RelationShipNode.java +++ b/Core/src/org/sleuthkit/autopsy/communications/RelationShipNode.java @@ -21,7 +21,6 @@ package org.sleuthkit.autopsy.communications; import java.util.logging.Level; import org.apache.commons.lang3.StringUtils; import org.openide.nodes.Sheet; -import org.openide.util.Exceptions; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.datamodel.BlackboardArtifactNode; import org.sleuthkit.autopsy.datamodel.NodeProperty; @@ -62,9 +61,11 @@ public class RelationShipNode extends BlackboardArtifactNode { } ss.put(new NodeProperty<>("Type", "Type", "Type", getDisplayName())); + final BlackboardArtifact artifact = getArtifact(); BlackboardArtifact.ARTIFACT_TYPE fromID = BlackboardArtifact.ARTIFACT_TYPE.fromID(getArtifact().getArtifactTypeID()); if (null != fromID) { + //Consider refactoring this to reduce boilerplate switch (fromID) { case TSK_EMAIL_MSG: ss.put(new NodeProperty<>("From", "From", "From", @@ -75,14 +76,12 @@ public class RelationShipNode extends BlackboardArtifactNode { getAttributeDisplayString(artifact, TSK_DATETIME_SENT))); ss.put(new NodeProperty<>("Subject", "Subject", "Subject", getAttributeDisplayString(artifact, TSK_SUBJECT))); - { - try { - ss.put(new NodeProperty<>("at", "at", "at", - artifact.getChildrenCount() > 0)); - } catch (TskCoreException ex) { - Exceptions.printStackTrace(ex); - } + try { + ss.put(new NodeProperty<>("Attms", "Attms", "Attms", artifact.getChildrenCount() > 0)); + } catch (TskCoreException ex) { + logger.log(Level.WARNING, "Error loading attachment count for " + artifact, ex); } + break; case TSK_MESSAGE: ss.put(new NodeProperty<>("From", "From", "From", @@ -93,6 +92,11 @@ public class RelationShipNode extends BlackboardArtifactNode { getAttributeDisplayString(artifact, TSK_DATETIME))); ss.put(new NodeProperty<>("Subject", "Subject", "Subject", getAttributeDisplayString(artifact, TSK_SUBJECT))); + try { + ss.put(new NodeProperty<>("Attms", "Attms", "Attms", artifact.getChildrenCount() > 0)); + } catch (TskCoreException ex) { + logger.log(Level.WARNING, "Error loading attachment count for " + artifact, ex); + } break; case TSK_CALLLOG: ss.put(new NodeProperty<>("From", "From", "From", From 6dcc20a80e0d86d4512844049b664dc4f12b4ec6 Mon Sep 17 00:00:00 2001 From: millmanorama Date: Sat, 11 Nov 2017 16:20:59 +0100 Subject: [PATCH 085/127] someclean up in MessageContentViewer --- .../contentviewers/MessageContentViewer.java | 129 ++++++++++-------- 1 file changed, 70 insertions(+), 59 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java b/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java index d0ae158aac..bf63b1088f 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java @@ -94,7 +94,6 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont public MessageContentViewer() { initComponents(); drp = DataResultPanel.createInstanceUninitialized("Attachments", "", Node.EMPTY, 0, null); - attachmentsScrollPane.setViewportView(drp); msgbodyTabbedPane.setEnabledAt(ATTM_TAB_INDEX, true); @@ -346,7 +345,7 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont private void showImagesToggleButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_showImagesToggleButtonActionPerformed try { String htmlText = getAttributeValueSafe(artifact, TSK_EMAIL_CONTENT_HTML); - if (!htmlText.isEmpty()) { + if (false == htmlText.isEmpty()) { if (showImagesToggleButton.isSelected()) { showImagesToggleButton.setText(Bundle.MessageContentViewer_showImagesToggleButton_hide_text()); this.htmlbodyTextPane.setText(wrapInHtmlBody(htmlText)); @@ -457,6 +456,7 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont rtfbodyTextPane.setText(""); htmlbodyTextPane.setText(""); textbodyTextArea.setText(""); + drp.setNode(null); msgbodyTabbedPane.setEnabled(false); } @@ -464,8 +464,8 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont public boolean isSupported(Node node) { BlackboardArtifact artifact = node.getLookup().lookup(BlackboardArtifact.class); return ((artifact != null) - && ((artifact.getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_EMAIL_MSG.getTypeID()) - || (artifact.getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_MESSAGE.getTypeID()))); + && ((artifact.getArtifactTypeID() == TSK_EMAIL_MSG.getTypeID()) + || (artifact.getArtifactTypeID() == TSK_MESSAGE.getTypeID()))); } @Override @@ -476,53 +476,39 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont return 0; } - void configureTextArea(BlackboardAttribute.ATTRIBUTE_TYPE type, int index) throws TskCoreException { + /** + * Configure the text area at the given index to show the content of the + * given type. + * + * @param type The ATTRIBUT_TYPE to show in the indexed tab. + * @param index The index of the text area to configure. + * + * @throws TskCoreException + */ + private void configureTextArea(BlackboardAttribute.ATTRIBUTE_TYPE type, int index) throws TskCoreException { String attributeText = getAttributeValueSafe(artifact, type); - if (!attributeText.isEmpty()) { - attributeText = (index == HTML_TAB_INDEX) - ? wrapInHtmlBody(cleanseHTML(attributeText)) - : attributeText; - final JTextComponent textComponent = textAreas.get(index); - textComponent.setText(attributeText); - textComponent.setCaretPosition(0); - msgbodyTabbedPane.setEnabledAt(index, true); - msgbodyTabbedPane.setSelectedIndex(index); - } else { - msgbodyTabbedPane.setEnabledAt(index, false); + + if (index == HTML_TAB_INDEX) { + //special case for HTML, we need to 'cleanse' it + attributeText = wrapInHtmlBody(cleanseHTML(attributeText)); } + JTextComponent textComponent = textAreas.get(index); + textComponent.setText(attributeText); + final boolean hasText = attributeText.length() > 0; + + if (hasText) { + textComponent.setCaretPosition(0); //make sure we start at the top + msgbodyTabbedPane.setSelectedIndex(index); + } + msgbodyTabbedPane.setEnabledAt(index, hasText); } - private void displayEmailMsg() { + private void enableCommonFields() { msgbodyTabbedPane.setEnabled(true); fromLabel.setEnabled(true); toLabel.setEnabled(true); - ccLabel.setEnabled(true); subjectLabel.setEnabled(true); datetimeText.setEnabled(true); - - directionText.setEnabled(false); - - showImagesToggleButton.setText("Show Images"); - showImagesToggleButton.setSelected(false); - - try { - this.fromText.setText(getAttributeValueSafe(artifact, TSK_EMAIL_FROM)); - this.toText.setText(getAttributeValueSafe(artifact, TSK_EMAIL_TO)); - this.directionText.setText(""); - this.ccText.setText(getAttributeValueSafe(artifact, TSK_EMAIL_CC)); - this.subjectText.setText(getAttributeValueSafe(artifact, TSK_SUBJECT)); - this.datetimeText.setText(getAttributeValueSafe(artifact, TSK_DATETIME_RCVD)); - - configureTextArea(TSK_HEADERS, HDR_TAB_INDEX); - configureTextArea(TSK_EMAIL_CONTENT_PLAIN, TEXT_TAB_INDEX); - configureTextArea(TSK_EMAIL_CONTENT_HTML, HTML_TAB_INDEX); - configureTextArea(TSK_EMAIL_CONTENT_RTF, RTF_TAB_INDEX); - - configureAttachments(); - - } catch (TskCoreException ex) { - LOGGER.log(Level.WARNING, "Failed to get attributes for email message.", ex); //NON-NLS - } } private void configureAttachments() throws TskCoreException { @@ -543,14 +529,37 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont return "" + htmlText + ""; } - private void displayMsg() { - msgbodyTabbedPane.setEnabled(true); - fromLabel.setEnabled(true); - toLabel.setEnabled(true); - subjectLabel.setEnabled(true); - directionText.setEnabled(true); - datetimeText.setEnabled(true); + private void displayEmailMsg() { + enableCommonFields(); + directionText.setEnabled(false); + ccLabel.setEnabled(true); + + showImagesToggleButton.setText("Show Images"); + showImagesToggleButton.setSelected(false); + + try { + this.fromText.setText(getAttributeValueSafe(artifact, TSK_EMAIL_FROM)); + this.toText.setText(getAttributeValueSafe(artifact, TSK_EMAIL_TO)); + this.directionText.setText(""); + this.ccText.setText(getAttributeValueSafe(artifact, TSK_EMAIL_CC)); + this.subjectText.setText(getAttributeValueSafe(artifact, TSK_SUBJECT)); + this.datetimeText.setText(getAttributeValueSafe(artifact, TSK_DATETIME_RCVD)); + + configureTextArea(TSK_HEADERS, HDR_TAB_INDEX); + configureTextArea(TSK_EMAIL_CONTENT_PLAIN, TEXT_TAB_INDEX); + configureTextArea(TSK_EMAIL_CONTENT_HTML, HTML_TAB_INDEX); + configureTextArea(TSK_EMAIL_CONTENT_RTF, RTF_TAB_INDEX); + configureAttachments(); + } catch (TskCoreException ex) { + LOGGER.log(Level.WARNING, "Failed to get attributes for email message.", ex); //NON-NLS + } + } + + private void displayMsg() { + enableCommonFields(); + + directionText.setEnabled(true); ccLabel.setEnabled(false); try { @@ -572,7 +581,7 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont } } - String getAttributeValueSafe(BlackboardArtifact artifact, BlackboardAttribute.ATTRIBUTE_TYPE type) throws TskCoreException { + private static String getAttributeValueSafe(BlackboardArtifact artifact, BlackboardAttribute.ATTRIBUTE_TYPE type) throws TskCoreException { return Optional.ofNullable(artifact.getAttribute(new BlackboardAttribute.Type(type))) .map(BlackboardAttribute::getDisplayString) .orElse(""); @@ -597,10 +606,10 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont private static class AttachmentsChildren extends Children.Keys { - private final Set files; + private final Set attachments; - AttachmentsChildren(Set collect) { - this.files = collect; + AttachmentsChildren(Set attachments) { + this.attachments = attachments; } @Override @@ -611,17 +620,20 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont @Override protected void addNotify() { super.addNotify(); - setKeys(files); + setKeys(attachments); } } + /** + * Extension of FileNode customized for viewing attachments in the + * MessageContentViewer. It overrides createSheet() to customize what + * properties are shown in the table, and could also override getActions(), + * getPreferedAction(), etc. + */ private static class AttachmentNode extends FileNode { - private final AbstractFile file; - AttachmentNode(AbstractFile file) { super(file, true); - this.file = file; } @Override @@ -632,7 +644,7 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont ss = Sheet.createPropertiesSet(); s.put(ss); } - + AbstractFile file = getContent(); ss.put(new NodeProperty<>("Name", "Name", "Name", file.getName())); ss.put(new NodeProperty<>("Size", "Size", "Size", file.getSize())); ss.put(new NodeProperty<>("Mime Type", "Mime Type", "Mime Type", StringUtils.defaultString(file.getMIMEType()))); @@ -641,6 +653,5 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont addTagProperty(ss); return s; } - } } From a06c374a5ac0d98c2ea75949045e8c5578292d28 Mon Sep 17 00:00:00 2001 From: millmanorama Date: Sat, 11 Nov 2017 16:27:01 +0100 Subject: [PATCH 086/127] deprecate useless setContentViewer --- .../DataResultViewer.java | 1 + .../corecomponents/AbstractDataResultViewer.java | 16 +++++----------- .../autopsy/corecomponents/DataResultPanel.java | 3 --- 3 files changed, 6 insertions(+), 14 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/corecomponentinterfaces/DataResultViewer.java b/Core/src/org/sleuthkit/autopsy/corecomponentinterfaces/DataResultViewer.java index f838e693d5..e6596b53c8 100755 --- a/Core/src/org/sleuthkit/autopsy/corecomponentinterfaces/DataResultViewer.java +++ b/Core/src/org/sleuthkit/autopsy/corecomponentinterfaces/DataResultViewer.java @@ -90,5 +90,6 @@ public interface DataResultViewer { * @param contentViewer content viewer to respond to selection events from * this viewer */ + @Deprecated public void setContentViewer(DataContent contentViewer); } diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/AbstractDataResultViewer.java b/Core/src/org/sleuthkit/autopsy/corecomponents/AbstractDataResultViewer.java index 00385bb3fb..26d58d6eff 100755 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/AbstractDataResultViewer.java +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/AbstractDataResultViewer.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2013 Basis Technology Corp. + * Copyright 2011-17 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -39,11 +39,6 @@ abstract class AbstractDataResultViewer extends JPanel implements DataResultView private static final Logger logger = Logger.getLogger(AbstractDataResultViewer.class.getName()); protected transient ExplorerManager em; -// /** -// * Content viewer to respond to selection events Either the main one, or -// * custom one if set -// */ -// protected DataContent contentViewer; /** * This constructor is intended to allow an AbstractDataResultViewer to use @@ -52,12 +47,11 @@ abstract class AbstractDataResultViewer extends JPanel implements DataResultView * TopComponent has focus. The ExplorerManager must be present when the * object is constructed so that its child components can discover it using * the ExplorerManager.find() method. + * + * @param explorerManager */ - public AbstractDataResultViewer(ExplorerManager explorerManager) { + AbstractDataResultViewer(ExplorerManager explorerManager) { this.em = explorerManager; - //DataContent is designed to return only the default viewer from lookup - //use the default one unless set otherwise -// contentViewer = Lookup.getDefault().lookup(DataContent.class); } /** @@ -109,8 +103,8 @@ abstract class AbstractDataResultViewer extends JPanel implements DataResultView } } + @Deprecated @Override public void setContentViewer(DataContent contentViewer) { -// this.contentViewer = contentViewer; } } diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultPanel.java b/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultPanel.java index 12e78e2d68..883c94ef56 100755 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultPanel.java +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultPanel.java @@ -240,9 +240,6 @@ public class DataResultPanel extends javax.swing.JPanel implements DataResult, C * @param resultViewer The result viewer. */ public void addResultViewer(DataResultViewer resultViewer) { - if (null != contentView) { - resultViewer.setContentViewer(contentView); - } resultViewers.add(resultViewer); dataResultTabbedPanel.addTab(resultViewer.getTitle(), resultViewer.getComponent()); } From 30455d5c65b61a3e09ef9a648ff5d4c2e8f56aa3 Mon Sep 17 00:00:00 2001 From: millmanorama Date: Mon, 13 Nov 2017 15:08:42 +0100 Subject: [PATCH 087/127] replace JCalendarButton with LGoodDatePicker, tweak layout --- .../autopsy/communications/Bundle.properties | 4 - .../communications/CVTTopComponent.form | 20 +- .../communications/CVTTopComponent.java | 18 +- .../autopsy/communications/FiltersPanel.form | 110 ++++------ .../autopsy/communications/FiltersPanel.java | 192 +++++------------- CoreLibs/ivy.xml | 1 + CoreLibs/nbproject/project.properties | 3 + CoreLibs/nbproject/project.xml | 7 + 8 files changed, 123 insertions(+), 232 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/communications/Bundle.properties b/Core/src/org/sleuthkit/autopsy/communications/Bundle.properties index 11ae095dbc..5b2de59bea 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/communications/Bundle.properties @@ -11,7 +11,3 @@ FiltersPanel.checkAllDevicesButton.text=Check All FiltersPanel.dateRangeLabel.text=Date Range: FiltersPanel.startCheckBox.text=start: FiltersPanel.endCheckBox.text=end: -FiltersPanel.endDateTextField.text= -FiltersPanel.startDateTextField.text= -FiltersPanel.startCalendarButton.text= -FiltersPanel.endCalendarButton.text= diff --git a/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.form b/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.form index 0463a92715..3f36c1afd3 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.form +++ b/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.form @@ -17,23 +17,23 @@ - - - - - + + + + + - + + - - + @@ -95,12 +95,12 @@ - + - + diff --git a/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java b/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java index b5c26bb1a2..f7b5daa0c2 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java +++ b/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java @@ -77,11 +77,11 @@ public final class CVTTopComponent extends TopComponent implements ExplorerManag jPanel1.setLayout(jPanel1Layout); jPanel1Layout.setHorizontalGroup( jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGap(0, 594, Short.MAX_VALUE) + .addGap(0, 597, Short.MAX_VALUE) ); jPanel1Layout.setVerticalGroup( jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGap(0, 710, Short.MAX_VALUE) + .addGap(0, 718, Short.MAX_VALUE) ); BrowseVisualizeTabPane.addTab(org.openide.util.NbBundle.getMessage(CVTTopComponent.class, "CVTTopComponent.TabConstraints.tabTitle"), new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/communications/images/emblem-web.png")), jPanel1); // NOI18N @@ -95,20 +95,20 @@ public final class CVTTopComponent extends TopComponent implements ExplorerManag layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() - .addContainerGap() - .addComponent(filtersPane, javax.swing.GroupLayout.PREFERRED_SIZE, 244, Short.MAX_VALUE) + .addGap(0, 0, 0) + .addComponent(filtersPane, javax.swing.GroupLayout.PREFERRED_SIZE, 246, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(splitPane, javax.swing.GroupLayout.DEFAULT_SIZE, 1322, Short.MAX_VALUE) - .addContainerGap()) + .addComponent(splitPane, javax.swing.GroupLayout.DEFAULT_SIZE, 1344, Short.MAX_VALUE) + .addGap(0, 0, 0)) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addContainerGap() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(filtersPane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(splitPane)) - .addContainerGap()) + .addComponent(splitPane, javax.swing.GroupLayout.DEFAULT_SIZE, 756, Short.MAX_VALUE) + .addComponent(filtersPane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addGap(5, 5, 5)) ); }// //GEN-END:initComponents diff --git a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.form b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.form index 02c5a82a1e..cfcdf28784 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.form +++ b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.form @@ -53,7 +53,10 @@ - + + + + @@ -62,7 +65,7 @@ - + @@ -125,7 +128,7 @@ - + @@ -142,7 +145,7 @@ - + @@ -212,7 +215,7 @@ - + @@ -228,7 +231,7 @@ - + @@ -277,6 +280,9 @@ + + + @@ -291,25 +297,20 @@ - - - - - - - - - - - - - - - - - + + + + + + + + + + + + @@ -318,23 +319,25 @@ - - - - + + + - - - - - + + + + - + + + + + @@ -365,50 +368,11 @@ - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java index f397627f65..b25100ab08 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java +++ b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java @@ -18,13 +18,9 @@ */ package org.sleuthkit.autopsy.communications; -import java.text.DateFormat; -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.time.Instant; import java.time.LocalDate; import java.time.ZoneId; -import java.util.Date; +import java.time.ZoneOffset; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -32,10 +28,10 @@ import java.util.Map.Entry; import java.util.logging.Level; import java.util.stream.Collectors; import javax.swing.JCheckBox; -import javax.swing.JFormattedTextField; import org.openide.explorer.ExplorerManager; import org.openide.nodes.AbstractNode; import org.sleuthkit.autopsy.casemodule.Case; +import org.sleuthkit.autopsy.core.UserPreferences; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.ThreadConfined; import org.sleuthkit.datamodel.Account; @@ -43,6 +39,7 @@ import org.sleuthkit.datamodel.AccountTypeFilter; import org.sleuthkit.datamodel.CommunicationsFilter; import org.sleuthkit.datamodel.CommunicationsManager; import org.sleuthkit.datamodel.DataSource; +import org.sleuthkit.datamodel.DateRangeFilter; import org.sleuthkit.datamodel.DeviceFilter; import org.sleuthkit.datamodel.TskCoreException; @@ -51,27 +48,22 @@ import org.sleuthkit.datamodel.TskCoreException; * changes into queries against the CommunicationsManager. */ final public class FiltersPanel extends javax.swing.JPanel { - + private static final Logger logger = Logger.getLogger(FiltersPanel.class.getName()); private static final long serialVersionUID = 1L; - private static final DateFormat DATE_FORMAT = new SimpleDateFormat("MM/dd/yyyy"); - +// private static final DateFormat DATE_FORMAT = new SimpleDateFormat("MM/dd/yyyy"); private ExplorerManager em; - + @ThreadConfined(type = ThreadConfined.ThreadType.AWT) private final Map accountTypeMap = new HashMap<>(); @ThreadConfined(type = ThreadConfined.ThreadType.AWT) private final Map devicesMap = new HashMap<>(); - + public FiltersPanel() { initComponents(); - startCalendarButton.addPropertyChangeListener(this::startPopupChanged); - endCalendarButton.addPropertyChangeListener(this::endPopupChanged); - final Instant threeWeeksAgoInstant = - LocalDate.now().minusWeeks(3).atStartOfDay(ZoneId.systemDefault()).toInstant(); - setStartDate(Date.from(threeWeeksAgoInstant)); - setEndDate(new Date()); + startDatePicker.setDate(LocalDate.now().minusWeeks(3)); + endDatePicker.setDateToToday(); updateAndApplyFilters(); } @@ -84,8 +76,10 @@ final public class FiltersPanel extends javax.swing.JPanel { if (em != null) { applyFilters(); } + + dateRangeLabel.setText("Date Range ( " + (UserPreferences.displayTimesInLocalTime() ? ZoneId.systemDefault().getId() : ZoneOffset.UTC.getId()) + "):"); } - + @Override public void addNotify() { super.addNotify(); @@ -96,42 +90,6 @@ final public class FiltersPanel extends javax.swing.JPanel { em = ExplorerManager.find(this); } - private void startPopupChanged(java.beans.PropertyChangeEvent evt) { - if (evt.getNewValue() instanceof Date) { - setStartDate((Date) evt.getNewValue()); - } - } - - /** - * - * @param newStartDate the value of newStartDate - */ - private void setStartDate(final Date newStartDate) { - startDateTextField.setValue(newStartDate); - startCalendarButton.setTargetDate(newStartDate); - } - - private void endPopupChanged(java.beans.PropertyChangeEvent evt) { - if (evt.getNewValue() instanceof Date) { - setEndDate((Date) evt.getNewValue()); - } - } - - /** - * - * @param newEndDate the value of newEndDate - */ - private void setEndDate(final Date newEndDate) { - endDateTextField.setValue(newEndDate); - endCalendarButton.setTargetDate(newEndDate); - } - - /** - * Validate and set the datetime field on the screen given a datetime - * string. - * - * @param date The date object - */ /** * Populate the Account Types filter widgets */ @@ -249,7 +207,7 @@ final public class FiltersPanel extends javax.swing.JPanel { .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) .addComponent(accountTypePane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addGroup(jPanel2Layout.createSequentialGroup() - .addGap(0, 32, Short.MAX_VALUE) + .addGap(0, 0, Short.MAX_VALUE) .addComponent(unCheckAllAccountTypesButton) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(checkAllAccountTypesButton))))) @@ -260,7 +218,7 @@ final public class FiltersPanel extends javax.swing.JPanel { .addGroup(jPanel2Layout.createSequentialGroup() .addComponent(accountTypesLabel) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(accountTypePane, javax.swing.GroupLayout.DEFAULT_SIZE, 174, Short.MAX_VALUE) + .addComponent(accountTypePane, javax.swing.GroupLayout.DEFAULT_SIZE, 220, Short.MAX_VALUE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(checkAllAccountTypesButton) @@ -286,6 +244,7 @@ final public class FiltersPanel extends javax.swing.JPanel { }); devicesPane.setBorder(javax.swing.BorderFactory.createEtchedBorder()); + devicesPane.setMinimumSize(new java.awt.Dimension(4, 100)); devicesPane.setLayout(new javax.swing.BoxLayout(devicesPane, javax.swing.BoxLayout.Y_AXIS)); javax.swing.GroupLayout jPanel3Layout = new javax.swing.GroupLayout(jPanel3); @@ -299,7 +258,7 @@ final public class FiltersPanel extends javax.swing.JPanel { .addGap(8, 8, 8) .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel3Layout.createSequentialGroup() - .addGap(0, 32, Short.MAX_VALUE) + .addGap(0, 0, Short.MAX_VALUE) .addComponent(unCheckAllDevicesButton) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(checkAllDevicesButton)) @@ -311,7 +270,7 @@ final public class FiltersPanel extends javax.swing.JPanel { .addGap(0, 0, 0) .addComponent(devicesLabel) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(devicesPane, javax.swing.GroupLayout.DEFAULT_SIZE, 59, Short.MAX_VALUE) + .addComponent(devicesPane, javax.swing.GroupLayout.DEFAULT_SIZE, 107, Short.MAX_VALUE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(checkAllDevicesButton) @@ -319,6 +278,8 @@ final public class FiltersPanel extends javax.swing.JPanel { .addGap(0, 0, 0)) ); + startDatePicker.setEnabled(false); + dateRangeLabel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/images/calendar.png"))); // NOI18N dateRangeLabel.setText(org.openide.util.NbBundle.getMessage(FiltersPanel.class, "FiltersPanel.dateRangeLabel.text")); // NOI18N @@ -336,64 +297,37 @@ final public class FiltersPanel extends javax.swing.JPanel { } }); - startCalendarButton.setText(org.openide.util.NbBundle.getMessage(FiltersPanel.class, "FiltersPanel.startCalendarButton.text")); // NOI18N - startCalendarButton.setEnabled(false); - - endCalendarButton.setText(org.openide.util.NbBundle.getMessage(FiltersPanel.class, "FiltersPanel.endCalendarButton.text")); // NOI18N - endCalendarButton.setEnabled(false); - - endDateTextField.setText(org.openide.util.NbBundle.getMessage(FiltersPanel.class, "FiltersPanel.endDateTextField.text")); // NOI18N - endDateTextField.setEnabled(false); - endDateTextField.addFocusListener(new java.awt.event.FocusAdapter() { - public void focusLost(java.awt.event.FocusEvent evt) { - endDateTextFieldFocusLost(evt); - } - }); - - startDateTextField.setText(org.openide.util.NbBundle.getMessage(FiltersPanel.class, "FiltersPanel.startDateTextField.text")); // NOI18N - startDateTextField.setEnabled(false); - startDateTextField.addFocusListener(new java.awt.event.FocusAdapter() { - public void focusLost(java.awt.event.FocusEvent evt) { - startDateTextFieldFocusLost(evt); - } - }); + endDatePicker.setEnabled(false); javax.swing.GroupLayout jPanel4Layout = new javax.swing.GroupLayout(jPanel4); jPanel4.setLayout(jPanel4Layout); jPanel4Layout.setHorizontalGroup( jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel4Layout.createSequentialGroup() - .addComponent(dateRangeLabel) - .addContainerGap()) - .addGroup(jPanel4Layout.createSequentialGroup() - .addGap(0, 0, 0) .addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(endCheckBox) - .addComponent(startCheckBox)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(endDateTextField) - .addComponent(startDateTextField)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) - .addComponent(startCalendarButton, javax.swing.GroupLayout.DEFAULT_SIZE, 27, Short.MAX_VALUE) - .addComponent(endCalendarButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))) + .addComponent(dateRangeLabel) + .addGroup(jPanel4Layout.createSequentialGroup() + .addComponent(startCheckBox) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(startDatePicker, javax.swing.GroupLayout.PREFERRED_SIZE, 162, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(jPanel4Layout.createSequentialGroup() + .addComponent(endCheckBox) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(endDatePicker, javax.swing.GroupLayout.PREFERRED_SIZE, 161, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addGap(0, 0, 0)) ); jPanel4Layout.setVerticalGroup( jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel4Layout.createSequentialGroup() .addComponent(dateRangeLabel) .addGap(5, 5, 5) - .addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) .addComponent(startCheckBox) - .addComponent(startCalendarButton, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(startDateTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(startDatePicker, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGap(7, 7, 7) + .addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) .addComponent(endCheckBox) - .addComponent(endCalendarButton, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(endDateTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addGap(0, 0, 0)) + .addComponent(endDatePicker, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) ); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); @@ -409,13 +343,15 @@ final public class FiltersPanel extends javax.swing.JPanel { .addComponent(filtersTitleLabel) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(applyFiltersButton, javax.swing.GroupLayout.PREFERRED_SIZE, 83, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addComponent(jPanel4, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addGroup(layout.createSequentialGroup() + .addComponent(jPanel4, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGap(0, 0, 0))) .addContainerGap()) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() - .addContainerGap() + .addGap(0, 0, 0) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(filtersTitleLabel) .addComponent(applyFiltersButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) @@ -441,16 +377,17 @@ final public class FiltersPanel extends javax.swing.JPanel { CommunicationsFilter commsFilter = new CommunicationsFilter(); commsFilter.addAndFilter(getDeviceFilter()); commsFilter.addAndFilter(getAccountTypeFilter()); - + commsFilter.addAndFilter(getDateRangeFilter()); + try { final CommunicationsManager commsManager = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager(); - + List accountDeviceInstanceKeys = commsManager.getAccountDeviceInstancesWithCommunications(commsFilter) .stream() .map(adi -> new AccountDeviceInstanceKey(adi, commsFilter)) .collect(Collectors.toList()); - + em.setRootContext(new AbstractNode(new AccountsRootChildren(accountDeviceInstanceKeys, commsManager))); } catch (TskCoreException ex) { logger.log(Level.SEVERE, "There was a error loading the accounts.", ex); @@ -480,6 +417,15 @@ final public class FiltersPanel extends javax.swing.JPanel { .map(entry -> entry.getKey()).collect(Collectors.toSet())); return accountTypeFilter; } + + private DateRangeFilter getDateRangeFilter() { + ZoneId zone = UserPreferences.displayTimesInLocalTime() ? ZoneId.systemDefault() : ZoneOffset.UTC; + long start = startDatePicker.isEnabled() ? startDatePicker.getDate().atStartOfDay(zone).toEpochSecond() : 0; + + //need to go to next day since atStartOfDay() is going to shift back to midnight + long end = endDatePicker.isEnabled() ? endDatePicker.getDate().plusDays(1).atStartOfDay(zone).toEpochSecond() : 0; + return new DateRangeFilter(start, end); + } /** * Set the selection state of all the account type check boxes @@ -528,36 +474,12 @@ final public class FiltersPanel extends javax.swing.JPanel { setAllDevicesSelected(true); }//GEN-LAST:event_checkAllDevicesButtonActionPerformed - private void endDateTextFieldFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_endDateTextFieldFocusLost - String endDateString = this.endDateTextField.getText(); - try { - Date fromDate = DATE_FORMAT.parse(endDateString); - endCalendarButton.setTargetDate(fromDate); - } catch (ParseException ex) { - // for now, no need to show the error message to the user here - } - }//GEN-LAST:event_endDateTextFieldFocusLost - - private void startDateTextFieldFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_startDateTextFieldFocusLost - String startDateString = this.startDateTextField.getText(); - try { - Date fromDate = DATE_FORMAT.parse(startDateString); - startCalendarButton.setTargetDate(fromDate); - } catch (ParseException ex) { - // for now, no need to show the error message to the user here - } - }//GEN-LAST:event_startDateTextFieldFocusLost - private void startCheckBoxStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_startCheckBoxStateChanged - boolean selected = startCheckBox.isSelected(); - startCalendarButton.setEnabled(selected); - startDateTextField.setEnabled(selected); + startDatePicker.setEnabled(startCheckBox.isSelected()); }//GEN-LAST:event_startCheckBoxStateChanged private void endCheckBoxStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_endCheckBoxStateChanged - boolean selected = endCheckBox.isSelected(); - endCalendarButton.setEnabled(selected); - endDateTextField.setEnabled(selected); + endDatePicker.setEnabled(endCheckBox.isSelected()); }//GEN-LAST:event_endCheckBoxStateChanged @@ -570,18 +492,16 @@ final public class FiltersPanel extends javax.swing.JPanel { private final javax.swing.JLabel dateRangeLabel = new javax.swing.JLabel(); private final javax.swing.JLabel devicesLabel = new javax.swing.JLabel(); private final javax.swing.JPanel devicesPane = new javax.swing.JPanel(); - private final org.jbundle.thin.base.screen.jcalendarbutton.JCalendarButton endCalendarButton = new org.jbundle.thin.base.screen.jcalendarbutton.JCalendarButton(); private final javax.swing.JCheckBox endCheckBox = new javax.swing.JCheckBox(); - private final javax.swing.JFormattedTextField endDateTextField = new JFormattedTextField(this.DATE_FORMAT); + private final com.github.lgooddatepicker.datepicker.DatePicker endDatePicker = new com.github.lgooddatepicker.datepicker.DatePicker(); private final javax.swing.JLabel filtersTitleLabel = new javax.swing.JLabel(); private final javax.swing.JList jList1 = new javax.swing.JList<>(); private final javax.swing.JPanel jPanel2 = new javax.swing.JPanel(); private final javax.swing.JPanel jPanel3 = new javax.swing.JPanel(); private final javax.swing.JPanel jPanel4 = new javax.swing.JPanel(); private final javax.swing.JScrollPane jScrollPane1 = new javax.swing.JScrollPane(); - private final org.jbundle.thin.base.screen.jcalendarbutton.JCalendarButton startCalendarButton = new org.jbundle.thin.base.screen.jcalendarbutton.JCalendarButton(); private final javax.swing.JCheckBox startCheckBox = new javax.swing.JCheckBox(); - private final javax.swing.JFormattedTextField startDateTextField = new JFormattedTextField(this.DATE_FORMAT); + private final com.github.lgooddatepicker.datepicker.DatePicker startDatePicker = new com.github.lgooddatepicker.datepicker.DatePicker(); private final javax.swing.JButton unCheckAllAccountTypesButton = new javax.swing.JButton(); private final javax.swing.JButton unCheckAllDevicesButton = new javax.swing.JButton(); // End of variables declaration//GEN-END:variables diff --git a/CoreLibs/ivy.xml b/CoreLibs/ivy.xml index bfd9112f9e..406847acac 100755 --- a/CoreLibs/ivy.xml +++ b/CoreLibs/ivy.xml @@ -14,6 +14,7 @@ + diff --git a/CoreLibs/nbproject/project.properties b/CoreLibs/nbproject/project.properties index 13a62b62ee..057a3d3568 100755 --- a/CoreLibs/nbproject/project.properties +++ b/CoreLibs/nbproject/project.properties @@ -53,6 +53,7 @@ file.reference.joda-time-2.4-javadoc.jar=release/modules/ext/joda-time-2.4-javad file.reference.joda-time-2.4-sources.jar=release/modules/ext/joda-time-2.4-sources.jar file.reference.joda-time-2.4.jar=release/modules/ext/joda-time-2.4.jar file.reference.jsr305-1.3.9.jar=release/modules/ext/jsr305-1.3.9.jar +file.reference.LGoodDatePicker-4.3.1.jar=release/modules/ext/LGoodDatePicker-4.3.1.jar file.reference.log4j-1.2.17.jar=release/modules/ext/log4j-1.2.17.jar file.reference.logkit-1.0.1.jar=release/modules/ext/logkit-1.0.1.jar file.reference.mail-1.4.3.jar=release/modules/ext/mail-1.4.3.jar @@ -82,6 +83,7 @@ javadoc.reference.guava-19.0.jar=release/modules/ext/guava-19.0-javadoc.jar javadoc.reference.jfxtras-common-8.0-r4.jar=release/modules/ext/jfxtras-common-8.0-r4-javadoc.jar javadoc.reference.jfxtras-controls-8.0-r4.jar=release/modules/ext/jfxtras-controls-8.0-r4-javadoc.jar javadoc.reference.jfxtras-fxml-8.0-r4.jar=release/modules/ext/jfxtras-fxml-8.0-r4-javadoc.jar +javadoc.reference.LGoodDatePicker-4.3.1.jar=release/modules/ext/LGoodDatePicker-4.3.1-javadoc.jar nbm.needs.restart=true source.reference.commons-csv-1.4.jar=release/modules/ext/commons-csv-1.4-sources.jar source.reference.commons-io-2.5.jar=release/modules/ext/commons-io-2.5-sources.jar @@ -91,3 +93,4 @@ source.reference.guava-19.0.jar=release/modules/ext/guava-19.0-sources.jar source.reference.jfxtras-common-8.0-r4.jar=release/modules/ext/jfxtras-common-8.0-r4-sources.jar source.reference.jfxtras-controls-8.0-r4.jar=release/modules/ext/jfxtras-controls-8.0-r4-sources.jar source.reference.jfxtras-fxml-8.0-r4.jar=release/modules/ext/jfxtras-fxml-8.0-r4-sources.jar +source.reference.LGoodDatePicker-4.3.1.jar=release/modules/ext/LGoodDatePicker-4.3.1-sources.jar diff --git a/CoreLibs/nbproject/project.xml b/CoreLibs/nbproject/project.xml index 6fcef46ccd..bd62edb402 100755 --- a/CoreLibs/nbproject/project.xml +++ b/CoreLibs/nbproject/project.xml @@ -37,6 +37,9 @@ com.apple.eawt com.apple.eawt.event com.apple.eio + com.github.lgooddatepicker.datepicker + com.github.lgooddatepicker.datetimepicker + com.github.lgooddatepicker.timepicker com.github.mustachejava com.github.mustachejava.codes com.github.mustachejava.functions @@ -723,6 +726,10 @@ ext/imgscalr-lib-4.2.jar release/modules/ext/imgscalr-lib-4.2.jar + + ext/LGoodDatePicker-4.3.1.jar + release/modules/ext/LGoodDatePicker-4.3.1.jar + ext/xmlbeans-2.6.0.jar release/modules/ext/xmlbeans-2.6.0.jar From e0d768d139fe92c8f434bb385377b90976a46786 Mon Sep 17 00:00:00 2001 From: millmanorama Date: Mon, 13 Nov 2017 15:52:30 +0100 Subject: [PATCH 088/127] don't do extra day, it is handled in filter --- .../autopsy/communications/FiltersPanel.java | 22 +++++++++---------- 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java index b25100ab08..858567f8e0 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java +++ b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java @@ -48,18 +48,18 @@ import org.sleuthkit.datamodel.TskCoreException; * changes into queries against the CommunicationsManager. */ final public class FiltersPanel extends javax.swing.JPanel { - + private static final Logger logger = Logger.getLogger(FiltersPanel.class.getName()); private static final long serialVersionUID = 1L; // private static final DateFormat DATE_FORMAT = new SimpleDateFormat("MM/dd/yyyy"); private ExplorerManager em; - + @ThreadConfined(type = ThreadConfined.ThreadType.AWT) private final Map accountTypeMap = new HashMap<>(); @ThreadConfined(type = ThreadConfined.ThreadType.AWT) private final Map devicesMap = new HashMap<>(); - + public FiltersPanel() { initComponents(); startDatePicker.setDate(LocalDate.now().minusWeeks(3)); @@ -76,10 +76,10 @@ final public class FiltersPanel extends javax.swing.JPanel { if (em != null) { applyFilters(); } - + dateRangeLabel.setText("Date Range ( " + (UserPreferences.displayTimesInLocalTime() ? ZoneId.systemDefault().getId() : ZoneOffset.UTC.getId()) + "):"); } - + @Override public void addNotify() { super.addNotify(); @@ -378,16 +378,16 @@ final public class FiltersPanel extends javax.swing.JPanel { commsFilter.addAndFilter(getDeviceFilter()); commsFilter.addAndFilter(getAccountTypeFilter()); commsFilter.addAndFilter(getDateRangeFilter()); - + try { final CommunicationsManager commsManager = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager(); - + List accountDeviceInstanceKeys = commsManager.getAccountDeviceInstancesWithCommunications(commsFilter) .stream() .map(adi -> new AccountDeviceInstanceKey(adi, commsFilter)) .collect(Collectors.toList()); - + em.setRootContext(new AbstractNode(new AccountsRootChildren(accountDeviceInstanceKeys, commsManager))); } catch (TskCoreException ex) { logger.log(Level.SEVERE, "There was a error loading the accounts.", ex); @@ -417,13 +417,11 @@ final public class FiltersPanel extends javax.swing.JPanel { .map(entry -> entry.getKey()).collect(Collectors.toSet())); return accountTypeFilter; } - + private DateRangeFilter getDateRangeFilter() { ZoneId zone = UserPreferences.displayTimesInLocalTime() ? ZoneId.systemDefault() : ZoneOffset.UTC; long start = startDatePicker.isEnabled() ? startDatePicker.getDate().atStartOfDay(zone).toEpochSecond() : 0; - - //need to go to next day since atStartOfDay() is going to shift back to midnight - long end = endDatePicker.isEnabled() ? endDatePicker.getDate().plusDays(1).atStartOfDay(zone).toEpochSecond() : 0; + long end = endDatePicker.isEnabled() ? endDatePicker.getDate().atStartOfDay(zone).toEpochSecond() : 0; return new DateRangeFilter(start, end); } From c0c5383b115fa31257f2c5caa4dbcfc556a3e0f3 Mon Sep 17 00:00:00 2001 From: millmanorama Date: Tue, 14 Nov 2017 11:56:23 +0100 Subject: [PATCH 089/127] only add one "messages tab"; some refactoring --- .../communications/MessageBrowser.java | 85 +++++++++---------- .../communications/MessageDataContent.java | 3 +- .../communications/RelationShipNode.java | 4 +- 3 files changed, 41 insertions(+), 51 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.java b/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.java index 6ab5289133..7c6704b6f2 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.java +++ b/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.java @@ -18,10 +18,10 @@ */ package org.sleuthkit.autopsy.communications; -import com.google.common.collect.Iterables; -import java.util.HashSet; +import java.util.Collections; import java.util.Set; -import java.util.logging.Level; +import java.util.stream.Collectors; +import java.util.stream.Stream; import org.openide.explorer.ExplorerManager; import org.openide.nodes.Node; import org.sleuthkit.autopsy.communications.AccountsRootChildren.AccountDeviceInstanceNode; @@ -29,84 +29,79 @@ import org.sleuthkit.autopsy.corecomponents.DataResultPanel; import org.sleuthkit.autopsy.corecomponents.DataResultViewerTable; import org.sleuthkit.autopsy.corecomponents.TableFilterNode; import org.sleuthkit.autopsy.coreutils.Logger; -import org.sleuthkit.autopsy.directorytree.DataResultFilterNode; -import org.sleuthkit.datamodel.Account; import org.sleuthkit.datamodel.AccountDeviceInstance; import org.sleuthkit.datamodel.CommunicationsFilter; import org.sleuthkit.datamodel.CommunicationsManager; /** * The right hand side of the CVT. Has a DataResultPanel to show messages and - * account details, and a Content viewer to show individual + * other account details, and a ContentViewer to show individual */ final class MessageBrowser extends javax.swing.JPanel implements ExplorerManager.Provider { + private static final long serialVersionUID = 1L; private static final Logger logger = Logger.getLogger(MessageBrowser.class.getName()); - private static final long serialVersionUID = 1L; - - private ExplorerManager parentExplorereManager; private final DataResultPanel messagesResultPanel; - private ExplorerManager internalExplorerManager; + private final ExplorerManager explorerManager = new ExplorerManager(); + private final DataResultViewerTable dataResultViewerTable = new DataResultViewerTable(explorerManager, "Messages"); + + ; MessageBrowser() { initComponents(); messagesResultPanel = DataResultPanel.createInstanceUninitialized("Account", "", Node.EMPTY, 0, messageDataContent); - + splitPane.setTopComponent(messagesResultPanel); splitPane.setBottomComponent(messageDataContent); - } @Override public void addNotify() { super.addNotify(); - this.parentExplorereManager = ExplorerManager.find(this); - - internalExplorerManager = new ExplorerManager(); - + ExplorerManager parentExplorereManager = ExplorerManager.find(this); parentExplorereManager.addPropertyChangeListener(pce -> { if (pce.getPropertyName().equals(ExplorerManager.PROP_SELECTED_NODES)) { final Node[] selectedNodes = parentExplorereManager.getSelectedNodes(); if (selectedNodes.length == 0) { + //reset panel when there is no selection messagesResultPanel.setNode(null); messagesResultPanel.setPath(""); + messagesResultPanel.setNumMatches(0); } else { - Set accountDeviceInstances = new HashSet<>(); - CommunicationsFilter filter = null; - CommunicationsManager commsManager = null; - for (Node n : selectedNodes) { - if (n instanceof AccountDeviceInstanceNode) { - final AccountDeviceInstanceNode adiNode = (AccountDeviceInstanceNode) n; - accountDeviceInstances.add(adiNode.getAccountDeviceInstance()); - if (commsManager == null) { - commsManager = adiNode.getCommsManager(); - } - if (filter == null) { - filter = adiNode.getFilter(); - } else if (filter != adiNode.getFilter()) { - ///this should never happen... - logger.log(Level.WARNING, "Not all AccountDeviceInstanceNodes have the same filter. Using the first."); - } - } else { - ///this should never happen... - logger.log(Level.WARNING, "Unexpected Node encountered: " + n.toString()); - } - } - messagesResultPanel.setNode(new TableFilterNode(new AccountDetailsNode(accountDeviceInstances, filter, commsManager), true)); - if (accountDeviceInstances.size() == 1) { - messagesResultPanel.setPath(Iterables.getOnlyElement(accountDeviceInstances).getAccount().getAccountUniqueID()); + AccountDeviceInstanceNode adiNode = (AccountDeviceInstanceNode) selectedNodes[0]; + CommunicationsFilter filter = adiNode.getFilter(); + CommunicationsManager commsManager = adiNode.getCommsManager(); + final Set collect; + + if (selectedNodes.length == 1) { + final AccountDeviceInstance accountDeviceInstance = adiNode.getAccountDeviceInstance(); + collect = Collections.singleton(accountDeviceInstance); + messagesResultPanel.setPath(accountDeviceInstance.getAccount().getAccountUniqueID()); } else { - messagesResultPanel.setPath(accountDeviceInstances.size() + " accounts"); + collect = Stream.of(selectedNodes) + .map(node -> (AccountDeviceInstanceNode) node) + .map(AccountDeviceInstanceNode::getAccountDeviceInstance) + .collect(Collectors.toSet()); + messagesResultPanel.setPath(selectedNodes.length + " accounts"); } + messagesResultPanel.setNode(new TableFilterNode( + new AccountDetailsNode(collect, filter, commsManager), true)); } } }); - messagesResultPanel.addResultViewer(new DataResultViewerTable(internalExplorerManager,"Messages")); - + + if (messagesResultPanel.getViewers().contains(dataResultViewerTable) == false) { + messagesResultPanel.addResultViewer(dataResultViewerTable); + } messagesResultPanel.open(); } + @Override + public ExplorerManager getExplorerManager() { + return explorerManager; + } + /** * This method is called from within the constructor to initialize the form. * WARNING: Do NOT modify this code. The content of this method is always @@ -148,8 +143,4 @@ final class MessageBrowser extends javax.swing.JPanel implements ExplorerManager private javax.swing.JSplitPane splitPane; // End of variables declaration//GEN-END:variables - @Override - public ExplorerManager getExplorerManager() { - return internalExplorerManager; - } } diff --git a/Core/src/org/sleuthkit/autopsy/communications/MessageDataContent.java b/Core/src/org/sleuthkit/autopsy/communications/MessageDataContent.java index 1b7b5dc3c0..4181103b38 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/MessageDataContent.java +++ b/Core/src/org/sleuthkit/autopsy/communications/MessageDataContent.java @@ -23,7 +23,7 @@ import org.sleuthkit.autopsy.contentviewers.MessageContentViewer; import org.sleuthkit.autopsy.corecomponentinterfaces.DataContent; /** - * Extend MessageContentViewer so that it implements DataContent and can be set + * Extends MessageContentViewer so that it implements DataContent and can be set * as the only ContentViewer for a DataResultPanel */ public class MessageDataContent extends MessageContentViewer implements DataContent { @@ -34,5 +34,4 @@ public class MessageDataContent extends MessageContentViewer implements DataCont public void propertyChange(PropertyChangeEvent evt) { throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. } - } diff --git a/Core/src/org/sleuthkit/autopsy/communications/RelationShipNode.java b/Core/src/org/sleuthkit/autopsy/communications/RelationShipNode.java index 622c637ed2..3bd1b5dd27 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/RelationShipNode.java +++ b/Core/src/org/sleuthkit/autopsy/communications/RelationShipNode.java @@ -77,7 +77,7 @@ public class RelationShipNode extends BlackboardArtifactNode { ss.put(new NodeProperty<>("Subject", "Subject", "Subject", getAttributeDisplayString(artifact, TSK_SUBJECT))); try { - ss.put(new NodeProperty<>("Attms", "Attms", "Attms", artifact.getChildrenCount() > 0)); + ss.put(new NodeProperty<>("Attms", "Attms", "Attms", artifact.getChildrenCount())); } catch (TskCoreException ex) { logger.log(Level.WARNING, "Error loading attachment count for " + artifact, ex); } @@ -93,7 +93,7 @@ public class RelationShipNode extends BlackboardArtifactNode { ss.put(new NodeProperty<>("Subject", "Subject", "Subject", getAttributeDisplayString(artifact, TSK_SUBJECT))); try { - ss.put(new NodeProperty<>("Attms", "Attms", "Attms", artifact.getChildrenCount() > 0)); + ss.put(new NodeProperty<>("Attms", "Attms", "Attms", artifact.getChildrenCount())); } catch (TskCoreException ex) { logger.log(Level.WARNING, "Error loading attachment count for " + artifact, ex); } From d4ca8b1a734f325f889673a326e7ade8fce014ca Mon Sep 17 00:00:00 2001 From: millmanorama Date: Tue, 14 Nov 2017 11:57:30 +0100 Subject: [PATCH 090/127] fix disabling of HTML tab when there is no content --- .../autopsy/contentviewers/MessageContentViewer.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java b/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java index bf63b1088f..439d9f2ca4 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java @@ -488,19 +488,19 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont private void configureTextArea(BlackboardAttribute.ATTRIBUTE_TYPE type, int index) throws TskCoreException { String attributeText = getAttributeValueSafe(artifact, type); - if (index == HTML_TAB_INDEX) { + if (index == HTML_TAB_INDEX && StringUtils.isNotBlank(attributeText)) { //special case for HTML, we need to 'cleanse' it attributeText = wrapInHtmlBody(cleanseHTML(attributeText)); } JTextComponent textComponent = textAreas.get(index); textComponent.setText(attributeText); + textComponent.setCaretPosition(0); //make sure we start at the top final boolean hasText = attributeText.length() > 0; + msgbodyTabbedPane.setEnabledAt(index, hasText); if (hasText) { - textComponent.setCaretPosition(0); //make sure we start at the top msgbodyTabbedPane.setSelectedIndex(index); } - msgbodyTabbedPane.setEnabledAt(index, hasText); } private void enableCommonFields() { From 0a8bdd9918ac30e32cdfab83925e4eb9b510fc43 Mon Sep 17 00:00:00 2001 From: millmanorama Date: Tue, 14 Nov 2017 12:30:28 +0100 Subject: [PATCH 091/127] update javadoc to include deprecation --- .../autopsy/corecomponentinterfaces/DataResultViewer.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/corecomponentinterfaces/DataResultViewer.java b/Core/src/org/sleuthkit/autopsy/corecomponentinterfaces/DataResultViewer.java index e6596b53c8..db0316993a 100755 --- a/Core/src/org/sleuthkit/autopsy/corecomponentinterfaces/DataResultViewer.java +++ b/Core/src/org/sleuthkit/autopsy/corecomponentinterfaces/DataResultViewer.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2013 Basis Technology Corp. + * Copyright 2011-17 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -89,7 +89,9 @@ public interface DataResultViewer { * * @param contentViewer content viewer to respond to selection events from * this viewer + * + * @deprecated All implementations of this method are now no-ops. */ - @Deprecated + @Deprecated public void setContentViewer(DataContent contentViewer); } From 85ea748c3686d7945fcf2a3467a769ce400f3fd5 Mon Sep 17 00:00:00 2001 From: millmanorama Date: Tue, 14 Nov 2017 12:35:04 +0100 Subject: [PATCH 092/127] fix comment --- .../autopsy/corecomponentinterfaces/DataResultViewer.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/corecomponentinterfaces/DataResultViewer.java b/Core/src/org/sleuthkit/autopsy/corecomponentinterfaces/DataResultViewer.java index db0316993a..d88c979844 100755 --- a/Core/src/org/sleuthkit/autopsy/corecomponentinterfaces/DataResultViewer.java +++ b/Core/src/org/sleuthkit/autopsy/corecomponentinterfaces/DataResultViewer.java @@ -85,12 +85,12 @@ public interface DataResultViewer { /** * Set a custom content viewer to respond to selection events from this - * result viewer. If not set, the default content viewer is user + * result viewer. If not set, the default content viewer is used * * @param contentViewer content viewer to respond to selection events from * this viewer * - * @deprecated All implementations of this method are now no-ops. + * @deprecated All implementations of this in the standard DataResultViewers are now no-ops. */ @Deprecated public void setContentViewer(DataContent contentViewer); From 30abacc9fb14243b90b774bd2b484c7f1a4d517c Mon Sep 17 00:00:00 2001 From: millmanorama Date: Tue, 14 Nov 2017 12:46:22 +0100 Subject: [PATCH 093/127] update Javadoc --- .../communications/MessageBrowser.java | 2 ++ .../corecomponents/DataResultPanel.java | 23 ++++++++----------- 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.java b/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.java index 7c6704b6f2..ab6580ab70 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.java +++ b/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.java @@ -50,6 +50,7 @@ final class MessageBrowser extends javax.swing.JPanel implements ExplorerManager MessageBrowser() { initComponents(); + //create an uninitialized DataResultPanel so we can control the ResultViewers that get added. messagesResultPanel = DataResultPanel.createInstanceUninitialized("Account", "", Node.EMPTY, 0, messageDataContent); splitPane.setTopComponent(messagesResultPanel); @@ -91,6 +92,7 @@ final class MessageBrowser extends javax.swing.JPanel implements ExplorerManager } }); + //add the required result viewers and THEN open the panel if (messagesResultPanel.getViewers().contains(dataResultViewerTable) == false) { messagesResultPanel.addResultViewer(dataResultViewerTable); } diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultPanel.java b/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultPanel.java index 883c94ef56..e89d677ad8 100755 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultPanel.java +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultPanel.java @@ -80,8 +80,8 @@ public class DataResultPanel extends javax.swing.JPanel implements DataResult, C private DataContent contentView; /** - * Constructs and opens a Swing JPanel with a JTabbedPane child component. - * The tabbed pane contains result viewers. + * Constructs and opens a DataResultPanel with the given initial data, and + * the default DataContent. * * @param title The title for the panel. * @param pathText Descriptive text about the source of the nodes @@ -99,8 +99,8 @@ public class DataResultPanel extends javax.swing.JPanel implements DataResult, C } /** - * Constructs and opens a Swing JPanel with a JTabbedPane child component. - * The tabbed pane contains result viewers. + * Constructs and opens a DataResultPanel with the given initial data, and a + * custom DataContent. * * @param title The title for the panel. * @param pathText Descriptive text about the source of the nodes @@ -120,9 +120,9 @@ public class DataResultPanel extends javax.swing.JPanel implements DataResult, C } /** - * Constructs a Swing JPanel with a JTabbedPane child component. The tabbed - * pane contains result viewers. The panel is NOT opened; the client of this - * method must call open on the panel that is returned. + * Constructs a DataResultPanel with the given initial data, and a custom + * DataContent. The panel is NOT opened; the client of this method must call + * open on the panel that is returned. * * @param title The title for the panel. * @param pathText Descriptive text about the source of the nodes @@ -160,9 +160,7 @@ public class DataResultPanel extends javax.swing.JPanel implements DataResult, C } /** - * Constructs a Swing JPanel with a JTabbedPane child component that - * contains result viewers (implementations of the DataResultViewer - * interface). + * Constructs a DataResultPanel with the default DataContent * * @param title The title for the panel. * @param isMain True if the DataResultPanel being constructed is the "main" @@ -170,6 +168,7 @@ public class DataResultPanel extends javax.swing.JPanel implements DataResult, C */ DataResultPanel(String title, boolean isMain) { this(isMain, Lookup.getDefault().lookup(DataContent.class)); + setTitle(title); } private DataResultPanel(boolean isMain, DataContent contentView) { @@ -179,9 +178,7 @@ public class DataResultPanel extends javax.swing.JPanel implements DataResult, C } /** - * Constructs a Swing JPanel with a JTabbedPane child component that - * contains result viewers (implementations of the DataResultViewer - * interface). + * Constructs a DataResultPanel with the a custom DataContent. * * @param title The title for the panel. * @param customContentView A content view to use in place of the default From e77be5d7043b1a312b6385000e6d354b00b7d245 Mon Sep 17 00:00:00 2001 From: millmanorama Date: Tue, 14 Nov 2017 13:07:10 +0100 Subject: [PATCH 094/127] removed unused logger --- .../org/sleuthkit/autopsy/communications/MessageBrowser.java | 2 -- .../sleuthkit/autopsy/contentviewers/MessageContentViewer.java | 1 + 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.java b/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.java index ab6580ab70..c4c6e91fe8 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.java +++ b/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.java @@ -28,7 +28,6 @@ import org.sleuthkit.autopsy.communications.AccountsRootChildren.AccountDeviceIn import org.sleuthkit.autopsy.corecomponents.DataResultPanel; import org.sleuthkit.autopsy.corecomponents.DataResultViewerTable; import org.sleuthkit.autopsy.corecomponents.TableFilterNode; -import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.datamodel.AccountDeviceInstance; import org.sleuthkit.datamodel.CommunicationsFilter; import org.sleuthkit.datamodel.CommunicationsManager; @@ -40,7 +39,6 @@ import org.sleuthkit.datamodel.CommunicationsManager; final class MessageBrowser extends javax.swing.JPanel implements ExplorerManager.Provider { private static final long serialVersionUID = 1L; - private static final Logger logger = Logger.getLogger(MessageBrowser.class.getName()); private final DataResultPanel messagesResultPanel; private final ExplorerManager explorerManager = new ExplorerManager(); diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java b/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java index 439d9f2ca4..ec49948b78 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java @@ -79,6 +79,7 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont private static final int HTML_TAB_INDEX = 2; private static final int RTF_TAB_INDEX = 3; private static final int ATTM_TAB_INDEX = 4; + private final List textAreas; /** From 29237dd8825286425961cc3c80bcaf7beb2c181e Mon Sep 17 00:00:00 2001 From: millmanorama Date: Tue, 14 Nov 2017 16:35:44 +0100 Subject: [PATCH 095/127] fix project.xml for LGoodDatePicker --- CoreLibs/nbproject/project.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/CoreLibs/nbproject/project.xml b/CoreLibs/nbproject/project.xml index bd62edb402..f95b75754b 100755 --- a/CoreLibs/nbproject/project.xml +++ b/CoreLibs/nbproject/project.xml @@ -40,6 +40,7 @@ com.github.lgooddatepicker.datepicker com.github.lgooddatepicker.datetimepicker com.github.lgooddatepicker.timepicker + com.github.lgooddatepicker.zinternaltools com.github.mustachejava com.github.mustachejava.codes com.github.mustachejava.functions From f1c4792fa278df6beaf57a5b74b77521e1a3222b Mon Sep 17 00:00:00 2001 From: millmanorama Date: Tue, 14 Nov 2017 16:57:00 +0100 Subject: [PATCH 096/127] show the relationship date/time in the table according to user preferences --- .../sleuthkit/autopsy/communications/MessageBrowser.java | 8 +++----- .../autopsy/communications/RelationShipNode.java | 8 ++++++++ 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.java b/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.java index 6ab5289133..c7c1e6c83b 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.java +++ b/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.java @@ -29,8 +29,6 @@ import org.sleuthkit.autopsy.corecomponents.DataResultPanel; import org.sleuthkit.autopsy.corecomponents.DataResultViewerTable; import org.sleuthkit.autopsy.corecomponents.TableFilterNode; import org.sleuthkit.autopsy.coreutils.Logger; -import org.sleuthkit.autopsy.directorytree.DataResultFilterNode; -import org.sleuthkit.datamodel.Account; import org.sleuthkit.datamodel.AccountDeviceInstance; import org.sleuthkit.datamodel.CommunicationsFilter; import org.sleuthkit.datamodel.CommunicationsManager; @@ -52,7 +50,7 @@ final class MessageBrowser extends javax.swing.JPanel implements ExplorerManager MessageBrowser() { initComponents(); messagesResultPanel = DataResultPanel.createInstanceUninitialized("Account", "", Node.EMPTY, 0, messageDataContent); - + splitPane.setTopComponent(messagesResultPanel); splitPane.setBottomComponent(messageDataContent); @@ -102,8 +100,8 @@ final class MessageBrowser extends javax.swing.JPanel implements ExplorerManager } } }); - messagesResultPanel.addResultViewer(new DataResultViewerTable(internalExplorerManager,"Messages")); - + messagesResultPanel.addResultViewer(new DataResultViewerTable(internalExplorerManager, "Messages")); + messagesResultPanel.open(); } diff --git a/Core/src/org/sleuthkit/autopsy/communications/RelationShipNode.java b/Core/src/org/sleuthkit/autopsy/communications/RelationShipNode.java index b46aa90ff3..19002a0771 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/RelationShipNode.java +++ b/Core/src/org/sleuthkit/autopsy/communications/RelationShipNode.java @@ -18,9 +18,13 @@ */ package org.sleuthkit.autopsy.communications; +import java.time.ZoneId; +import java.time.ZoneOffset; +import java.util.TimeZone; import java.util.logging.Level; import org.apache.commons.lang3.StringUtils; import org.openide.nodes.Sheet; +import org.sleuthkit.autopsy.core.UserPreferences; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.datamodel.BlackboardArtifactNode; import org.sleuthkit.autopsy.datamodel.NodeProperty; @@ -35,6 +39,7 @@ import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMA import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_FROM; import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_TO; import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SUBJECT; +import org.sleuthkit.datamodel.TimeUtilities; import org.sleuthkit.datamodel.TskCoreException; /** @@ -117,6 +122,9 @@ public class RelationShipNode extends BlackboardArtifactNode { BlackboardAttribute attribute = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.fromID(attributeType.getTypeID()))); if (attribute == null) { return ""; + } else if (attributeType.getValueType() == BlackboardAttribute.TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.DATETIME) { + ZoneId zone = UserPreferences.displayTimesInLocalTime() ? ZoneOffset.systemDefault() : ZoneOffset.UTC; + return TimeUtilities.epochToTime(attribute.getValueLong(), TimeZone.getTimeZone(zone)); } else { return attribute.getDisplayString(); } From 5fdf18d7486b7f9d3edd08aa665eeee873376afe Mon Sep 17 00:00:00 2001 From: millmanorama Date: Tue, 14 Nov 2017 17:06:16 +0100 Subject: [PATCH 097/127] rename AccountUtils to Utils, add Utils.getUserPreferredZoneId() method --- .../autopsy/communications/AccountsRootChildren.java | 2 +- .../autopsy/communications/FiltersPanel.java | 8 +++----- .../autopsy/communications/RelationShipNode.java | 11 +++++------ .../communications/{AccountUtils.java => Utils.java} | 12 ++++++++++-- 4 files changed, 19 insertions(+), 14 deletions(-) rename Core/src/org/sleuthkit/autopsy/communications/{AccountUtils.java => Utils.java} (87%) diff --git a/Core/src/org/sleuthkit/autopsy/communications/AccountsRootChildren.java b/Core/src/org/sleuthkit/autopsy/communications/AccountsRootChildren.java index 53cb4e06c3..4f7ad9a039 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/AccountsRootChildren.java +++ b/Core/src/org/sleuthkit/autopsy/communications/AccountsRootChildren.java @@ -89,7 +89,7 @@ class AccountsRootChildren extends Children.Keys { this.commsManager = commsManager; this.filter = accountDeviceInstanceKey.getCommunicationsFilter(); setName(accountDeviceInstance.getAccount().getAccountUniqueID()); - setIconBaseWithExtension("org/sleuthkit/autopsy/communications/images/" + AccountUtils.getIconFileName(accountDeviceInstance.getAccount().getAccountType())); + setIconBaseWithExtension("org/sleuthkit/autopsy/communications/images/" + Utils.getIconFileName(accountDeviceInstance.getAccount().getAccountType())); } public AccountDeviceInstance getAccountDeviceInstance() { diff --git a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java index 858567f8e0..df5b3132fe 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java +++ b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java @@ -20,7 +20,6 @@ package org.sleuthkit.autopsy.communications; import java.time.LocalDate; import java.time.ZoneId; -import java.time.ZoneOffset; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -31,7 +30,6 @@ import javax.swing.JCheckBox; import org.openide.explorer.ExplorerManager; import org.openide.nodes.AbstractNode; import org.sleuthkit.autopsy.casemodule.Case; -import org.sleuthkit.autopsy.core.UserPreferences; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.ThreadConfined; import org.sleuthkit.datamodel.Account; @@ -77,7 +75,7 @@ final public class FiltersPanel extends javax.swing.JPanel { applyFilters(); } - dateRangeLabel.setText("Date Range ( " + (UserPreferences.displayTimesInLocalTime() ? ZoneId.systemDefault().getId() : ZoneOffset.UTC.getId()) + "):"); + dateRangeLabel.setText("Date Range ( " + (Utils.getUserPreferredZoneId().getId() + "):"); } @Override @@ -111,7 +109,7 @@ final public class FiltersPanel extends javax.swing.JPanel { final JCheckBox jCheckBox = new JCheckBox( "
" + type.getDisplayName() + "
", true ); @@ -419,7 +417,7 @@ final public class FiltersPanel extends javax.swing.JPanel { } private DateRangeFilter getDateRangeFilter() { - ZoneId zone = UserPreferences.displayTimesInLocalTime() ? ZoneId.systemDefault() : ZoneOffset.UTC; + ZoneId zone = Utils.getUserPreferredZoneId(); long start = startDatePicker.isEnabled() ? startDatePicker.getDate().atStartOfDay(zone).toEpochSecond() : 0; long end = endDatePicker.isEnabled() ? endDatePicker.getDate().atStartOfDay(zone).toEpochSecond() : 0; return new DateRangeFilter(start, end); diff --git a/Core/src/org/sleuthkit/autopsy/communications/RelationShipNode.java b/Core/src/org/sleuthkit/autopsy/communications/RelationShipNode.java index 19002a0771..f92b89ee71 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/RelationShipNode.java +++ b/Core/src/org/sleuthkit/autopsy/communications/RelationShipNode.java @@ -18,13 +18,10 @@ */ package org.sleuthkit.autopsy.communications; -import java.time.ZoneId; -import java.time.ZoneOffset; import java.util.TimeZone; import java.util.logging.Level; import org.apache.commons.lang3.StringUtils; import org.openide.nodes.Sheet; -import org.sleuthkit.autopsy.core.UserPreferences; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.datamodel.BlackboardArtifactNode; import org.sleuthkit.autopsy.datamodel.NodeProperty; @@ -39,6 +36,7 @@ import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMA import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_FROM; import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_TO; import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SUBJECT; +import static org.sleuthkit.datamodel.BlackboardAttribute.TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.DATETIME; import org.sleuthkit.datamodel.TimeUtilities; import org.sleuthkit.datamodel.TskCoreException; @@ -122,9 +120,9 @@ public class RelationShipNode extends BlackboardArtifactNode { BlackboardAttribute attribute = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.fromID(attributeType.getTypeID()))); if (attribute == null) { return ""; - } else if (attributeType.getValueType() == BlackboardAttribute.TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.DATETIME) { - ZoneId zone = UserPreferences.displayTimesInLocalTime() ? ZoneOffset.systemDefault() : ZoneOffset.UTC; - return TimeUtilities.epochToTime(attribute.getValueLong(), TimeZone.getTimeZone(zone)); + } else if (attributeType.getValueType() == DATETIME) { + return TimeUtilities.epochToTime(attribute.getValueLong(), + TimeZone.getTimeZone(Utils.getUserPreferredZoneId())); } else { return attribute.getDisplayString(); } @@ -133,4 +131,5 @@ public class RelationShipNode extends BlackboardArtifactNode { return ""; } } + } diff --git a/Core/src/org/sleuthkit/autopsy/communications/AccountUtils.java b/Core/src/org/sleuthkit/autopsy/communications/Utils.java similarity index 87% rename from Core/src/org/sleuthkit/autopsy/communications/AccountUtils.java rename to Core/src/org/sleuthkit/autopsy/communications/Utils.java index 3c936ecc70..af8cd3f8b4 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/AccountUtils.java +++ b/Core/src/org/sleuthkit/autopsy/communications/Utils.java @@ -18,14 +18,22 @@ */ package org.sleuthkit.autopsy.communications; +import java.time.ZoneId; +import java.time.ZoneOffset; +import org.sleuthkit.autopsy.core.UserPreferences; import org.sleuthkit.datamodel.Account; /** * Utility class with helpers for dealing with accounts. */ -class AccountUtils { +class Utils { - private AccountUtils() { + static ZoneId getUserPreferredZoneId() { + ZoneId zone = UserPreferences.displayTimesInLocalTime() ? ZoneOffset.systemDefault() : ZoneOffset.UTC; + return zone; + } + + private Utils() { } /** From 5b18937ec3a1d5bc6b809e0b5026996d1a1a5482 Mon Sep 17 00:00:00 2001 From: Raman Date: Tue, 14 Nov 2017 15:09:10 -0500 Subject: [PATCH 098/127] Address review comments. --- .../autopsy/datamodel/accounts/Accounts.java | 4 ++-- .../sleuthkit/autopsy/keywordsearch/RegexQuery.java | 4 ++-- .../autopsy/keywordsearch/TermsComponentQuery.java | 4 ++-- .../ThunderbirdMboxFileIngestModule.java | 12 ++++++------ 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/accounts/Accounts.java b/Core/src/org/sleuthkit/autopsy/datamodel/accounts/Accounts.java index e9ab484b3d..531598ad65 100755 --- a/Core/src/org/sleuthkit/autopsy/datamodel/accounts/Accounts.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/accounts/Accounts.java @@ -71,7 +71,7 @@ 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.AccountInstance; +import org.sleuthkit.datamodel.AccountFileInstance; import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE; import org.sleuthkit.datamodel.BlackboardAttribute; @@ -1428,7 +1428,7 @@ final public class Accounts implements AutopsyVisitableItem { final Collection artifacts = Utilities.actionsGlobalContext().lookupAll(BlackboardArtifact.class); artifacts.forEach(artifact -> { try { - AccountInstance accountInstance = skCase.getCommunicationsManager().getAccountInstance(artifact); + AccountFileInstance accountInstance = skCase.getCommunicationsManager().getAccountFileInstance(artifact); if (BlackboardArtifact.ReviewStatus.APPROVED == newStatus) { accountInstance.approveAccount(); diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/RegexQuery.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/RegexQuery.java index ac5ea43acf..582a9d3199 100755 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/RegexQuery.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/RegexQuery.java @@ -47,7 +47,7 @@ import static org.sleuthkit.autopsy.keywordsearch.TermsComponentQuery.CREDIT_CAR import static org.sleuthkit.autopsy.keywordsearch.TermsComponentQuery.KEYWORD_SEARCH_DOCUMENT_ID; import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.Account; -import org.sleuthkit.datamodel.AccountInstance; +import org.sleuthkit.datamodel.AccountFileInstance; import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE; import org.sleuthkit.datamodel.BlackboardAttribute; @@ -567,7 +567,7 @@ final class RegexQuery implements KeywordSearchQuery { * Create an account instance. */ try { - AccountInstance ccAccountInstance = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().createAccountInstance(Account.Type.CREDIT_CARD, ccnAttribute.getValueString() , MODULE_NAME, content); + AccountFileInstance ccAccountInstance = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().createAccountFileInstance(Account.Type.CREDIT_CARD, ccnAttribute.getValueString() , MODULE_NAME, content); ccAccountInstance.addAttributes(attributes); diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TermsComponentQuery.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TermsComponentQuery.java index 2be10ebe67..11e833e09d 100755 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TermsComponentQuery.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TermsComponentQuery.java @@ -38,7 +38,7 @@ import org.sleuthkit.autopsy.coreutils.Version; import org.sleuthkit.autopsy.datamodel.CreditCards; import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.Account; -import org.sleuthkit.datamodel.AccountInstance; +import org.sleuthkit.datamodel.AccountFileInstance; import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE; import org.sleuthkit.datamodel.BlackboardAttribute; @@ -485,7 +485,7 @@ final class TermsComponentQuery implements KeywordSearchQuery { * Create an account. */ try { - AccountInstance ccAccountInstance = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().createAccountInstance(Account.Type.CREDIT_CARD, ccnAttribute.getValueString() , MODULE_NAME, content); + AccountFileInstance ccAccountInstance = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().createAccountFileInstance(Account.Type.CREDIT_CARD, ccnAttribute.getValueString() , MODULE_NAME, content); ccAccountInstance.addAttributes(attributes); //newArtifact = Case.getCurrentCase().getSleuthkitCase().getBlackboardArtifact(ccAccountInstance.getArtifactId()); } catch (TskCoreException ex) { diff --git a/thunderbirdparser/src/org/sleuthkit/autopsy/thunderbirdparser/ThunderbirdMboxFileIngestModule.java b/thunderbirdparser/src/org/sleuthkit/autopsy/thunderbirdparser/ThunderbirdMboxFileIngestModule.java index e852d37b00..f4aa12c9dc 100755 --- a/thunderbirdparser/src/org/sleuthkit/autopsy/thunderbirdparser/ThunderbirdMboxFileIngestModule.java +++ b/thunderbirdparser/src/org/sleuthkit/autopsy/thunderbirdparser/ThunderbirdMboxFileIngestModule.java @@ -46,7 +46,7 @@ import org.sleuthkit.autopsy.ingest.ModuleContentEvent; import org.sleuthkit.autopsy.ingest.ModuleDataEvent; import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.Account; -import org.sleuthkit.datamodel.AccountInstance; +import org.sleuthkit.datamodel.AccountFileInstance; import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardAttribute; import org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE; @@ -406,11 +406,11 @@ public final class ThunderbirdMboxFileIngestModule implements FileIngestModule { String senderAddress; senderAddressList.addAll(findEmailAddresess(from)); - AccountInstance senderAccountInstance = null; + AccountFileInstance senderAccountInstance = null; if (senderAddressList.size() == 1) { senderAddress = senderAddressList.get(0); try { - senderAccountInstance = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().createAccountInstance(Account.Type.EMAIL, senderAddress, EmailParserModuleFactory.getModuleName(), abstractFile); + senderAccountInstance = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().createAccountFileInstance(Account.Type.EMAIL, senderAddress, EmailParserModuleFactory.getModuleName(), abstractFile); } catch(TskCoreException ex) { logger.log(Level.WARNING, "Failed to create account for email address " + senderAddress, ex); //NON-NLS @@ -425,11 +425,11 @@ public final class ThunderbirdMboxFileIngestModule implements FileIngestModule { recipientAddresses.addAll(findEmailAddresess(cc)); recipientAddresses.addAll(findEmailAddresess(bcc)); - List recipientAccountInstances = new ArrayList<>(); + List recipientAccountInstances = new ArrayList<>(); recipientAddresses.forEach((addr) -> { try { - AccountInstance recipientAccountInstance = - Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().createAccountInstance(Account.Type.EMAIL, addr, + AccountFileInstance recipientAccountInstance = + Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().createAccountFileInstance(Account.Type.EMAIL, addr, EmailParserModuleFactory.getModuleName(), abstractFile); recipientAccountInstances.add(recipientAccountInstance); } From 5b35cfca970f4abbd80b61c7705be77f1e0e7621 Mon Sep 17 00:00:00 2001 From: millmanorama Date: Wed, 15 Nov 2017 20:38:23 +0100 Subject: [PATCH 099/127] change "Msg Count" to Msgs, remove trailing semicolon from email addresses --- .../autopsy/communications/AccountsRootChildren.java | 5 ++++- .../sleuthkit/autopsy/communications/CVTTopComponent.form | 6 +++--- .../sleuthkit/autopsy/communications/CVTTopComponent.java | 6 +++--- .../sleuthkit/autopsy/communications/RelationShipNode.java | 4 ++-- 4 files changed, 12 insertions(+), 9 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/communications/AccountsRootChildren.java b/Core/src/org/sleuthkit/autopsy/communications/AccountsRootChildren.java index 4f7ad9a039..d0a43b3c84 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/AccountsRootChildren.java +++ b/Core/src/org/sleuthkit/autopsy/communications/AccountsRootChildren.java @@ -105,7 +105,10 @@ class AccountsRootChildren extends Children.Keys { } @Override - @NbBundle.Messages(value = {"AccountNode.device=Device", "AccountNode.accountName=Account", "AccountNode.accountType=Type", "AccountNode.messageCount=Msg Count"}) + @NbBundle.Messages(value = {"AccountNode.device=Device", + "AccountNode.accountName=Account", + "AccountNode.accountType=Type", + "AccountNode.messageCount=Msgs"}) protected Sheet createSheet() { Sheet s = super.createSheet(); Sheet.Set properties = s.get(Sheet.PROPERTIES); diff --git a/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.form b/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.form index 3f36c1afd3..a5a1daf073 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.form +++ b/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.form @@ -30,7 +30,7 @@ - + @@ -41,7 +41,7 @@ - + @@ -95,7 +95,7 @@ - + diff --git a/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java b/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java index f7b5daa0c2..03ae968f12 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java +++ b/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java @@ -65,7 +65,7 @@ public final class CVTTopComponent extends TopComponent implements ExplorerManag jPanel1 = new javax.swing.JPanel(); filtersPane = new org.sleuthkit.autopsy.communications.FiltersPanel(); - splitPane.setDividerLocation(600); + splitPane.setDividerLocation(400); splitPane.setResizeWeight(0.3); BrowseVisualizeTabPane.setFont(new java.awt.Font("Tahoma", 0, 18)); // NOI18N @@ -77,7 +77,7 @@ public final class CVTTopComponent extends TopComponent implements ExplorerManag jPanel1.setLayout(jPanel1Layout); jPanel1Layout.setHorizontalGroup( jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGap(0, 597, Short.MAX_VALUE) + .addGap(0, 394, Short.MAX_VALUE) ); jPanel1Layout.setVerticalGroup( jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) @@ -106,7 +106,7 @@ public final class CVTTopComponent extends TopComponent implements ExplorerManag .addGroup(layout.createSequentialGroup() .addContainerGap() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(splitPane, javax.swing.GroupLayout.DEFAULT_SIZE, 756, Short.MAX_VALUE) + .addComponent(splitPane) .addComponent(filtersPane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addGap(5, 5, 5)) ); diff --git a/Core/src/org/sleuthkit/autopsy/communications/RelationShipNode.java b/Core/src/org/sleuthkit/autopsy/communications/RelationShipNode.java index 33fb926f7b..b122cb2ebd 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/RelationShipNode.java +++ b/Core/src/org/sleuthkit/autopsy/communications/RelationShipNode.java @@ -72,9 +72,9 @@ public class RelationShipNode extends BlackboardArtifactNode { switch (fromID) { case TSK_EMAIL_MSG: ss.put(new NodeProperty<>("From", "From", "From", - getAttributeDisplayString(artifact, TSK_EMAIL_FROM))); + StringUtils.strip(getAttributeDisplayString(artifact, TSK_EMAIL_FROM), " \t\n;"))); ss.put(new NodeProperty<>("To", "To", "To", - getAttributeDisplayString(artifact, TSK_EMAIL_TO))); + StringUtils.strip(getAttributeDisplayString(artifact, TSK_EMAIL_TO), " \t\n;"))); ss.put(new NodeProperty<>("Date", "Date", "Date", getAttributeDisplayString(artifact, TSK_DATETIME_SENT))); ss.put(new NodeProperty<>("Subject", "Subject", "Subject", From deaa9199711af5d8ea0e2044143bfc471eb4378d Mon Sep 17 00:00:00 2001 From: millmanorama Date: Thu, 16 Nov 2017 10:06:26 +0100 Subject: [PATCH 100/127] put check lists in scroll panes, some other UI tweeks --- .../autopsy/communications/Bundle.properties | 6 +- .../communications/CVTTopComponent.form | 20 +-- .../communications/CVTTopComponent.java | 17 +-- .../autopsy/communications/FiltersPanel.form | 124 +++++++++--------- .../autopsy/communications/FiltersPanel.java | 65 ++++----- 5 files changed, 118 insertions(+), 114 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/communications/Bundle.properties b/Core/src/org/sleuthkit/autopsy/communications/Bundle.properties index 5b2de59bea..13d3eda321 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/communications/Bundle.properties @@ -3,11 +3,11 @@ CVTTopComponent.accountsBrowser.TabConstraints.tabTitle=Browse FiltersPanel.applyFiltersButton.text=Apply FiltersPanel.devicesLabel.text=Devices: FiltersPanel.accountTypesLabel.text=Account Types: -FiltersPanel.filtersTitleLabel.text=Account Filters +FiltersPanel.filtersTitleLabel.text=Filters FiltersPanel.unCheckAllAccountTypesButton.text=Uncheck All FiltersPanel.checkAllAccountTypesButton.text=Check All FiltersPanel.unCheckAllDevicesButton.text=Uncheck All FiltersPanel.checkAllDevicesButton.text=Check All FiltersPanel.dateRangeLabel.text=Date Range: -FiltersPanel.startCheckBox.text=start: -FiltersPanel.endCheckBox.text=end: +FiltersPanel.startCheckBox.text=Start: +FiltersPanel.endCheckBox.text=End: diff --git a/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.form b/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.form index 3f36c1afd3..b9e1bee9bc 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.form +++ b/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.form @@ -17,20 +17,22 @@ - - - - - + + + + + - - + + + + @@ -42,7 +44,7 @@ - + @@ -95,7 +97,7 @@ - + diff --git a/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java b/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java index f7b5daa0c2..aa55b24d2a 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java +++ b/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java @@ -66,7 +66,7 @@ public final class CVTTopComponent extends TopComponent implements ExplorerManag filtersPane = new org.sleuthkit.autopsy.communications.FiltersPanel(); splitPane.setDividerLocation(600); - splitPane.setResizeWeight(0.3); + splitPane.setResizeWeight(0.7); BrowseVisualizeTabPane.setFont(new java.awt.Font("Tahoma", 0, 18)); // NOI18N BrowseVisualizeTabPane.addTab(org.openide.util.NbBundle.getMessage(CVTTopComponent.class, "CVTTopComponent.accountsBrowser.TabConstraints.tabTitle"), new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/communications/images/table.png")), accountsBrowser); // NOI18N @@ -77,7 +77,7 @@ public final class CVTTopComponent extends TopComponent implements ExplorerManag jPanel1.setLayout(jPanel1Layout); jPanel1Layout.setHorizontalGroup( jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGap(0, 597, Short.MAX_VALUE) + .addGap(0, 594, Short.MAX_VALUE) ); jPanel1Layout.setVerticalGroup( jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) @@ -95,18 +95,19 @@ public final class CVTTopComponent extends TopComponent implements ExplorerManag layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() - .addGap(0, 0, 0) - .addComponent(filtersPane, javax.swing.GroupLayout.PREFERRED_SIZE, 246, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(splitPane, javax.swing.GroupLayout.DEFAULT_SIZE, 1344, Short.MAX_VALUE) + .addContainerGap() + .addComponent(filtersPane, javax.swing.GroupLayout.PREFERRED_SIZE, 251, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(splitPane, javax.swing.GroupLayout.DEFAULT_SIZE, 1332, Short.MAX_VALUE) .addGap(0, 0, 0)) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() - .addContainerGap() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(splitPane, javax.swing.GroupLayout.DEFAULT_SIZE, 756, Short.MAX_VALUE) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addComponent(splitPane)) .addComponent(filtersPane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addGap(5, 5, 5)) ); diff --git a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.form b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.form index cfcdf28784..fcc06c122e 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.form +++ b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.form @@ -43,20 +43,17 @@ - + + - - - - - + @@ -65,18 +62,18 @@ - + - + - + - - - + + + @@ -124,10 +121,10 @@ - + - - + + @@ -145,31 +142,17 @@ - + - - - - - - - - - - - - - - @@ -200,6 +183,18 @@ + + + + + + + + + + + + @@ -207,20 +202,20 @@ - + - + - + - + - + @@ -228,16 +223,16 @@ - + - + - + @@ -273,21 +268,28 @@
- + - - - - - + - + - - - + + + + + + + + + + + + + + @@ -296,21 +298,19 @@ - - - - - - - - - - - - - + + + + + + - + + + + + + diff --git a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java index 9794769a34..45d46b69c0 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java +++ b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java @@ -171,9 +171,6 @@ final public class FiltersPanel extends javax.swing.JPanel { filtersTitleLabel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/communications/images/funnel.png"))); // NOI18N filtersTitleLabel.setText(org.openide.util.NbBundle.getMessage(FiltersPanel.class, "FiltersPanel.filtersTitleLabel.text")); // NOI18N - accountTypePane.setBorder(javax.swing.BorderFactory.createEtchedBorder()); - accountTypePane.setLayout(new javax.swing.BoxLayout(accountTypePane, javax.swing.BoxLayout.Y_AXIS)); - unCheckAllAccountTypesButton.setText(org.openide.util.NbBundle.getMessage(FiltersPanel.class, "FiltersPanel.unCheckAllAccountTypesButton.text")); // NOI18N unCheckAllAccountTypesButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { @@ -191,6 +188,9 @@ final public class FiltersPanel extends javax.swing.JPanel { } }); + accountTypePane.setLayout(new javax.swing.BoxLayout(accountTypePane, javax.swing.BoxLayout.Y_AXIS)); + jScrollPane3.setViewportView(accountTypePane); + javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2); jPanel2.setLayout(jPanel2Layout); jPanel2Layout.setHorizontalGroup( @@ -201,9 +201,9 @@ final public class FiltersPanel extends javax.swing.JPanel { .addComponent(accountTypesLabel) .addGap(0, 0, Short.MAX_VALUE)) .addGroup(jPanel2Layout.createSequentialGroup() - .addGap(8, 8, 8) + .addGap(6, 6, 6) .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) - .addComponent(accountTypePane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jScrollPane3) .addGroup(jPanel2Layout.createSequentialGroup() .addGap(0, 0, Short.MAX_VALUE) .addComponent(unCheckAllAccountTypesButton) @@ -216,12 +216,11 @@ final public class FiltersPanel extends javax.swing.JPanel { .addGroup(jPanel2Layout.createSequentialGroup() .addComponent(accountTypesLabel) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(accountTypePane, javax.swing.GroupLayout.DEFAULT_SIZE, 220, Short.MAX_VALUE) + .addComponent(jScrollPane3, javax.swing.GroupLayout.DEFAULT_SIZE, 242, Short.MAX_VALUE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(checkAllAccountTypesButton) - .addComponent(unCheckAllAccountTypesButton)) - .addGap(0, 0, 0)) + .addComponent(unCheckAllAccountTypesButton))) ); unCheckAllDevicesButton.setText(org.openide.util.NbBundle.getMessage(FiltersPanel.class, "FiltersPanel.unCheckAllDevicesButton.text")); // NOI18N @@ -241,9 +240,12 @@ final public class FiltersPanel extends javax.swing.JPanel { } }); - devicesPane.setBorder(javax.swing.BorderFactory.createEtchedBorder()); + jScrollPane2.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); + jScrollPane2.setMinimumSize(new java.awt.Dimension(27, 75)); + devicesPane.setMinimumSize(new java.awt.Dimension(4, 100)); devicesPane.setLayout(new javax.swing.BoxLayout(devicesPane, javax.swing.BoxLayout.Y_AXIS)); + jScrollPane2.setViewportView(devicesPane); javax.swing.GroupLayout jPanel3Layout = new javax.swing.GroupLayout(jPanel3); jPanel3.setLayout(jPanel3Layout); @@ -253,14 +255,14 @@ final public class FiltersPanel extends javax.swing.JPanel { .addComponent(devicesLabel) .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addGroup(jPanel3Layout.createSequentialGroup() - .addGap(8, 8, 8) + .addGap(6, 6, 6) .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel3Layout.createSequentialGroup() - .addGap(0, 0, Short.MAX_VALUE) + .addGap(0, 101, Short.MAX_VALUE) .addComponent(unCheckAllDevicesButton) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(checkAllDevicesButton)) - .addComponent(devicesPane, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))) + .addComponent(jScrollPane2, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))) ); jPanel3Layout.setVerticalGroup( jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) @@ -268,12 +270,12 @@ final public class FiltersPanel extends javax.swing.JPanel { .addGap(0, 0, 0) .addComponent(devicesLabel) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(devicesPane, javax.swing.GroupLayout.DEFAULT_SIZE, 107, Short.MAX_VALUE) + .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 92, Short.MAX_VALUE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(checkAllDevicesButton) .addComponent(unCheckAllDevicesButton)) - .addGap(0, 0, 0)) + .addGap(5, 5, 5)) ); startDatePicker.setEnabled(false); @@ -301,18 +303,17 @@ final public class FiltersPanel extends javax.swing.JPanel { jPanel4.setLayout(jPanel4Layout); jPanel4Layout.setHorizontalGroup( jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel4Layout.createSequentialGroup() + .addComponent(endCheckBox) + .addGap(18, 18, Short.MAX_VALUE) + .addComponent(endDatePicker, javax.swing.GroupLayout.PREFERRED_SIZE, 163, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(0, 0, 0)) + .addComponent(dateRangeLabel)) .addGroup(jPanel4Layout.createSequentialGroup() - .addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(dateRangeLabel) - .addGroup(jPanel4Layout.createSequentialGroup() - .addComponent(startCheckBox) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(startDatePicker, javax.swing.GroupLayout.PREFERRED_SIZE, 162, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addGroup(jPanel4Layout.createSequentialGroup() - .addComponent(endCheckBox) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(endDatePicker, javax.swing.GroupLayout.PREFERRED_SIZE, 161, javax.swing.GroupLayout.PREFERRED_SIZE))) - .addGap(0, 0, 0)) + .addComponent(startCheckBox) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(startDatePicker, javax.swing.GroupLayout.PREFERRED_SIZE, 162, javax.swing.GroupLayout.PREFERRED_SIZE)) ); jPanel4Layout.setVerticalGroup( jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) @@ -335,21 +336,19 @@ final public class FiltersPanel extends javax.swing.JPanel { .addGroup(layout.createSequentialGroup() .addGap(8, 8, 8) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(jPanel2, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(jPanel3, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jPanel2, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addGroup(layout.createSequentialGroup() .addComponent(filtersTitleLabel) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(applyFiltersButton, javax.swing.GroupLayout.PREFERRED_SIZE, 83, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addGroup(layout.createSequentialGroup() - .addComponent(jPanel4, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addGap(0, 0, 0))) + .addComponent(jPanel4, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addContainerGap()) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() - .addGap(0, 0, 0) + .addContainerGap() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(filtersTitleLabel) .addComponent(applyFiltersButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) @@ -358,8 +357,8 @@ final public class FiltersPanel extends javax.swing.JPanel { .addGap(18, 18, 18) .addComponent(jPanel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addGap(18, 18, 18) - .addComponent(jPanel4, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addContainerGap()) + .addComponent(jPanel4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap(16, Short.MAX_VALUE)) ); }// //GEN-END:initComponents @@ -496,6 +495,8 @@ final public class FiltersPanel extends javax.swing.JPanel { private final javax.swing.JPanel jPanel3 = new javax.swing.JPanel(); private final javax.swing.JPanel jPanel4 = new javax.swing.JPanel(); private final javax.swing.JScrollPane jScrollPane1 = new javax.swing.JScrollPane(); + private final javax.swing.JScrollPane jScrollPane2 = new javax.swing.JScrollPane(); + private final javax.swing.JScrollPane jScrollPane3 = new javax.swing.JScrollPane(); private final javax.swing.JCheckBox startCheckBox = new javax.swing.JCheckBox(); private final com.github.lgooddatepicker.datepicker.DatePicker startDatePicker = new com.github.lgooddatepicker.datepicker.DatePicker(); private final javax.swing.JButton unCheckAllAccountTypesButton = new javax.swing.JButton(); From 7dc7c523802495795e81c447ebfac8326190a696 Mon Sep 17 00:00:00 2001 From: Raman Date: Thu, 16 Nov 2017 11:20:36 -0500 Subject: [PATCH 101/127] Fixed API name mismatch after renaming createAccountInstance() to createAccountFileInstance() --- InternalPythonModules/android/calllog.py | 4 ++-- InternalPythonModules/android/contact.py | 4 ++-- InternalPythonModules/android/tangomessage.py | 2 +- InternalPythonModules/android/textmessage.py | 4 ++-- InternalPythonModules/android/wwfmessage.py | 4 ++-- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/InternalPythonModules/android/calllog.py b/InternalPythonModules/android/calllog.py index be877997ff..233e111871 100755 --- a/InternalPythonModules/android/calllog.py +++ b/InternalPythonModules/android/calllog.py @@ -91,7 +91,7 @@ class CallLogAnalyzer(general.AndroidComponentAnalyzer): deviceID = ds.getDeviceId() global deviceAccountInstance - deviceAccountInstance = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().createAccountInstance(Account.Type.DEVICE, deviceID, general.MODULE_NAME, dataSource) + deviceAccountInstance = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().createAccountFileInstance(Account.Type.DEVICE, deviceID, general.MODULE_NAME, dataSource) absFiles = fileManager.findFiles(dataSource, "logs.db") absFiles.addAll(fileManager.findFiles(dataSource, "contacts.db")) @@ -143,7 +143,7 @@ class CallLogAnalyzer(general.AndroidComponentAnalyzer): artifact.addAttribute(BlackboardAttribute(ATTRIBUTE_TYPE.TSK_NAME, general.MODULE_NAME, name)) # Create an account - calllogAccountInstance = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().createAccountInstance(Account.Type.PHONE, number, general.MODULE_NAME, abstractFile); + calllogAccountInstance = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().createAccountFileInstance(Account.Type.PHONE, number, general.MODULE_NAME, abstractFile); # create relationship between accounts Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().addRelationships(deviceAccountInstance, [calllogAccountInstance], artifact, date); diff --git a/InternalPythonModules/android/contact.py b/InternalPythonModules/android/contact.py index 0b0baf1e46..c820a39e3f 100755 --- a/InternalPythonModules/android/contact.py +++ b/InternalPythonModules/android/contact.py @@ -65,7 +65,7 @@ class ContactAnalyzer(general.AndroidComponentAnalyzer): deviceID = ds.getDeviceId() global deviceAccountInstance - deviceAccountInstance = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().createAccountInstance(Account.Type.DEVICE, deviceID, general.MODULE_NAME, dataSource) + deviceAccountInstance = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().createAccountFileInstance (Account.Type.DEVICE, deviceID, general.MODULE_NAME, dataSource) absFiles = fileManager.findFiles(dataSource, "contacts.db") absFiles.addAll(fileManager.findFiles(dataSource, "contacts2.db")) @@ -147,7 +147,7 @@ class ContactAnalyzer(general.AndroidComponentAnalyzer): acctType = Account.Type.EMAIL # Create an account instance - contactAccountInstance = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().createAccountInstance(acctType, data1, general.MODULE_NAME, abstractFile); + contactAccountInstance = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().createAccountFileInstance (acctType, data1, general.MODULE_NAME, abstractFile); # create relationship between accounts Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().addRelationships(deviceAccountInstance, [contactAccountInstance], artifact, 0); diff --git a/InternalPythonModules/android/tangomessage.py b/InternalPythonModules/android/tangomessage.py index 846b3d159c..0d23e0ea3a 100755 --- a/InternalPythonModules/android/tangomessage.py +++ b/InternalPythonModules/android/tangomessage.py @@ -64,7 +64,7 @@ class TangoMessageAnalyzer(general.AndroidComponentAnalyzer): deviceID = ds.getDeviceId() global deviceAccountInstance - deviceAccountInstance = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().createAccountInstance(Account.Type.DEVICE, deviceID, general.MODULE_NAME, dataSource) + deviceAccountInstance = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().createAccountFileInstance(Account.Type.DEVICE, deviceID, general.MODULE_NAME, dataSource) absFiles = fileManager.findFiles(dataSource, "tc.db") for abstractFile in absFiles: diff --git a/InternalPythonModules/android/textmessage.py b/InternalPythonModules/android/textmessage.py index 535d43b07f..fea5bd4218 100755 --- a/InternalPythonModules/android/textmessage.py +++ b/InternalPythonModules/android/textmessage.py @@ -66,7 +66,7 @@ class TextMessageAnalyzer(general.AndroidComponentAnalyzer): deviceID = ds.getDeviceId() global deviceAccountInstance - deviceAccountInstance = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().createAccountInstance(Account.Type.DEVICE, deviceID, general.MODULE_NAME, dataSource) + deviceAccountInstance = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().createAccountFileInstance(Account.Type.DEVICE, deviceID, general.MODULE_NAME, dataSource) absFiles = fileManager.findFiles(dataSource, "mmssms.db") for abstractFile in absFiles: @@ -118,7 +118,7 @@ class TextMessageAnalyzer(general.AndroidComponentAnalyzer): artifact.addAttribute(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_MESSAGE_TYPE, general.MODULE_NAME, "SMS Message")) # Create an account - msgAccountInstance = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().createAccountInstance(Account.Type.PHONE, address, general.MODULE_NAME, abstractFile); + msgAccountInstance = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().createAccountFileInstance(Account.Type.PHONE, address, general.MODULE_NAME, abstractFile); # create relationship between accounts Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().addRelationships(deviceAccountInstance, [msgAccountInstance], artifact, date); diff --git a/InternalPythonModules/android/wwfmessage.py b/InternalPythonModules/android/wwfmessage.py index 21860d53b4..54f35aff5b 100755 --- a/InternalPythonModules/android/wwfmessage.py +++ b/InternalPythonModules/android/wwfmessage.py @@ -66,7 +66,7 @@ class WWFMessageAnalyzer(general.AndroidComponentAnalyzer): deviceID = ds.getDeviceId() global deviceAccountInstance - deviceAccountInstance = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().createAccountInstance(Account.Type.DEVICE, deviceID, general.MODULE_NAME, dataSource) + deviceAccountInstance = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().createAccountFileInstance(Account.Type.DEVICE, deviceID, general.MODULE_NAME, dataSource) absFiles = fileManager.findFiles(dataSource, "WordsFramework") for abstractFile in absFiles: @@ -112,7 +112,7 @@ class WWFMessageAnalyzer(general.AndroidComponentAnalyzer): artifact.addAttribute(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_MESSAGE_TYPE, general.MODULE_NAME, "Words With Friends Message")) # Create an account - wwfAccountInstance = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().createAccountInstance(wwfAccountType, user_id, general.MODULE_NAME, abstractFile); + wwfAccountInstance = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().createAccountFileInstance(wwfAccountType, user_id, general.MODULE_NAME, abstractFile); # create relationship between accounts Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().addRelationships(deviceAccountInstance, [wwfAccountInstance], artifact, created_at); From e2de84c227b16cb542e1f96053b8449ff64450f4 Mon Sep 17 00:00:00 2001 From: millmanorama Date: Thu, 16 Nov 2017 20:25:45 +0100 Subject: [PATCH 102/127] first pass at refresh --- .../communications/CVTTopComponent.form | 12 +-- .../communications/CVTTopComponent.java | 13 ++- .../autopsy/communications/FiltersPanel.form | 27 +++--- .../autopsy/communications/FiltersPanel.java | 86 +++++++++++++----- .../autopsy/communications/images/reload.png | Bin 0 -> 1282 bytes 5 files changed, 88 insertions(+), 50 deletions(-) create mode 100644 Core/src/org/sleuthkit/autopsy/communications/images/reload.png diff --git a/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.form b/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.form index b9e1bee9bc..ef764c80e1 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.form +++ b/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.form @@ -17,10 +17,10 @@ - + - + @@ -28,12 +28,10 @@ + - - - - + @@ -97,7 +95,7 @@ - + diff --git a/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java b/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java index aa55b24d2a..b5ec0888a2 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java +++ b/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java @@ -77,7 +77,7 @@ public final class CVTTopComponent extends TopComponent implements ExplorerManag jPanel1.setLayout(jPanel1Layout); jPanel1Layout.setHorizontalGroup( jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGap(0, 594, Short.MAX_VALUE) + .addGap(0, 602, Short.MAX_VALUE) ); jPanel1Layout.setVerticalGroup( jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) @@ -95,20 +95,19 @@ public final class CVTTopComponent extends TopComponent implements ExplorerManag layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() - .addContainerGap() + .addGap(0, 0, 0) .addComponent(filtersPane, javax.swing.GroupLayout.PREFERRED_SIZE, 251, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(splitPane, javax.swing.GroupLayout.DEFAULT_SIZE, 1332, Short.MAX_VALUE) + .addComponent(splitPane, javax.swing.GroupLayout.DEFAULT_SIZE, 1344, Short.MAX_VALUE) .addGap(0, 0, 0)) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() + .addContainerGap() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addContainerGap() - .addComponent(splitPane)) - .addComponent(filtersPane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addComponent(filtersPane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(splitPane)) .addGap(5, 5, 5)) ); }// //GEN-END:initComponents diff --git a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.form b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.form index fcc06c122e..2960e5e259 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.form +++ b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.form @@ -44,7 +44,7 @@ - + @@ -55,14 +55,14 @@ - + - + @@ -73,7 +73,7 @@ - + @@ -142,7 +142,7 @@ - + @@ -210,7 +210,7 @@ - + @@ -226,7 +226,7 @@ - + @@ -298,15 +298,12 @@ - - - - - - - - + + + + + diff --git a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java index 45d46b69c0..ce4712f983 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java +++ b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java @@ -18,20 +18,30 @@ */ package org.sleuthkit.autopsy.communications; +import java.beans.PropertyChangeListener; import java.time.LocalDate; import java.time.ZoneId; +import java.time.format.TextStyle; import java.util.HashMap; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.Map.Entry; import java.util.logging.Level; import java.util.stream.Collectors; +import javax.swing.ImageIcon; import javax.swing.JCheckBox; import org.openide.explorer.ExplorerManager; import org.openide.nodes.AbstractNode; import org.sleuthkit.autopsy.casemodule.Case; +import static org.sleuthkit.autopsy.casemodule.Case.Events.CURRENT_CASE; +import org.sleuthkit.autopsy.core.UserPreferences; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.ThreadConfined; +import org.sleuthkit.autopsy.ingest.IngestManager; +import static org.sleuthkit.autopsy.ingest.IngestManager.IngestJobEvent.CANCELLED; +import static org.sleuthkit.autopsy.ingest.IngestManager.IngestJobEvent.COMPLETED; +import static org.sleuthkit.autopsy.ingest.IngestManager.IngestModuleEvent.DATA_ADDED; import org.sleuthkit.datamodel.Account; import org.sleuthkit.datamodel.AccountTypeFilter; import org.sleuthkit.datamodel.CommunicationsFilter; @@ -50,32 +60,61 @@ final public class FiltersPanel extends javax.swing.JPanel { private static final Logger logger = Logger.getLogger(FiltersPanel.class.getName()); private static final long serialVersionUID = 1L; -// private static final DateFormat DATE_FORMAT = new SimpleDateFormat("MM/dd/yyyy"); private ExplorerManager em; @ThreadConfined(type = ThreadConfined.ThreadType.AWT) private final Map accountTypeMap = new HashMap<>(); @ThreadConfined(type = ThreadConfined.ThreadType.AWT) private final Map devicesMap = new HashMap<>(); + private final PropertyChangeListener ingestListener; public FiltersPanel() { initComponents(); startDatePicker.setDate(LocalDate.now().minusWeeks(3)); endDatePicker.setDateToToday(); - updateAndApplyFilters(); + setPreferredTimeZone(); + + updateFilters(); + setAllAccountTypesSelected(true); + setAllDevicesSelected(true); + UserPreferences.addChangeListener(preferenceChangeEvent -> { + if (preferenceChangeEvent.getKey().equals(UserPreferences.DISPLAY_TIMES_IN_LOCAL_TIME)) { + setPreferredTimeZone(); + } + }); + + this.ingestListener = pce -> { + String eventType = pce.getPropertyName(); + if (eventType.equals(DATA_ADDED.toString())) { + updateFilters(); + applyFiltersButton.setText("Refresh"); + applyFiltersButton.setIcon(new ImageIcon("org/sleuthkit/autopsy/communications/images/reload.png")); + } else if (eventType.equals(COMPLETED.toString())) { + } else if (eventType.equals(CANCELLED.toString())) { + + } else if (eventType.equals(CURRENT_CASE.toString())) { + } + }; + } /** * Update the filter widgets, and apply them. */ void updateAndApplyFilters() { - updateAccountTypeFilter(); - updateDeviceFilter(); + updateFilters(); if (em != null) { applyFilters(); } +} - dateRangeLabel.setText("Date Range ( " + Utils.getUserPreferredZoneId().getId() + "):"); + private void setPreferredTimeZone() { + dateRangeLabel.setText("Date Range ( " + Utils.getUserPreferredZoneId().getDisplayName(TextStyle.NARROW, Locale.getDefault()) + "):"); + } + + void updateFilters() { + updateAccountTypeFilter(); + updateDeviceFilter(); } @Override @@ -86,6 +125,8 @@ final public class FiltersPanel extends javax.swing.JPanel { * till this FiltersPanel is actaully added to a parent. */ em = ExplorerManager.find(this); + IngestManager.getInstance().removeIngestModuleEventListener(ingestListener); + } /** @@ -111,7 +152,7 @@ final public class FiltersPanel extends javax.swing.JPanel { + FiltersPanel.class.getResource("/org/sleuthkit/autopsy/communications/images/" + Utils.getIconFileName(type)) + "\"/>
" + type.getDisplayName() + "
", - true + false ); accountTypePane.add(jCheckBox); return jCheckBox; @@ -129,7 +170,7 @@ final public class FiltersPanel extends javax.swing.JPanel { final List dataSources = Case.getCurrentCase().getSleuthkitCase().getDataSources(); dataSources.forEach( dataSource -> devicesMap.computeIfAbsent(dataSource.getDeviceId(), ds -> { - final JCheckBox jCheckBox = new JCheckBox(dataSource.getDeviceId(), true); + final JCheckBox jCheckBox = new JCheckBox(dataSource.getDeviceId(), false); devicesPane.add(jCheckBox); return jCheckBox; }) @@ -216,7 +257,7 @@ final public class FiltersPanel extends javax.swing.JPanel { .addGroup(jPanel2Layout.createSequentialGroup() .addComponent(accountTypesLabel) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(jScrollPane3, javax.swing.GroupLayout.DEFAULT_SIZE, 242, Short.MAX_VALUE) + .addComponent(jScrollPane3, javax.swing.GroupLayout.DEFAULT_SIZE, 246, Short.MAX_VALUE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(checkAllAccountTypesButton) @@ -258,7 +299,7 @@ final public class FiltersPanel extends javax.swing.JPanel { .addGap(6, 6, 6) .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel3Layout.createSequentialGroup() - .addGap(0, 101, Short.MAX_VALUE) + .addGap(0, 121, Short.MAX_VALUE) .addComponent(unCheckAllDevicesButton) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(checkAllDevicesButton)) @@ -270,7 +311,7 @@ final public class FiltersPanel extends javax.swing.JPanel { .addGap(0, 0, 0) .addComponent(devicesLabel) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 92, Short.MAX_VALUE) + .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 96, Short.MAX_VALUE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(checkAllDevicesButton) @@ -303,13 +344,11 @@ final public class FiltersPanel extends javax.swing.JPanel { jPanel4.setLayout(jPanel4Layout); jPanel4Layout.setHorizontalGroup( jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel4Layout.createSequentialGroup() - .addComponent(endCheckBox) - .addGap(18, 18, Short.MAX_VALUE) - .addComponent(endDatePicker, javax.swing.GroupLayout.PREFERRED_SIZE, 163, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGap(0, 0, 0)) - .addComponent(dateRangeLabel)) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel4Layout.createSequentialGroup() + .addComponent(endCheckBox) + .addGap(18, 18, Short.MAX_VALUE) + .addComponent(endDatePicker, javax.swing.GroupLayout.PREFERRED_SIZE, 163, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(dateRangeLabel) .addGroup(jPanel4Layout.createSequentialGroup() .addComponent(startCheckBox) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) @@ -334,7 +373,7 @@ final public class FiltersPanel extends javax.swing.JPanel { layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() - .addGap(8, 8, 8) + .addGap(0, 0, 0) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(jPanel3, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(jPanel2, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) @@ -343,12 +382,12 @@ final public class FiltersPanel extends javax.swing.JPanel { .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(applyFiltersButton, javax.swing.GroupLayout.PREFERRED_SIZE, 83, javax.swing.GroupLayout.PREFERRED_SIZE)) .addComponent(jPanel4, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - .addContainerGap()) + .addGap(0, 0, 0)) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() - .addContainerGap() + .addGap(0, 0, 0) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(filtersTitleLabel) .addComponent(applyFiltersButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) @@ -358,7 +397,7 @@ final public class FiltersPanel extends javax.swing.JPanel { .addComponent(jPanel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addGap(18, 18, 18) .addComponent(jPanel4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addContainerGap(16, Short.MAX_VALUE)) + .addContainerGap(21, Short.MAX_VALUE)) ); }// //GEN-END:initComponents @@ -389,6 +428,11 @@ final public class FiltersPanel extends javax.swing.JPanel { } catch (TskCoreException ex) { logger.log(Level.SEVERE, "There was a error loading the accounts.", ex); } + + + applyFiltersButton.setText("Apply"); + applyFiltersButton.setIcon(new ImageIcon("org/sleuthkit/autopsy/communications/images/control-double.png")); + } /** diff --git a/Core/src/org/sleuthkit/autopsy/communications/images/reload.png b/Core/src/org/sleuthkit/autopsy/communications/images/reload.png new file mode 100644 index 0000000000000000000000000000000000000000..7cd97a7f9a514331f8b1c0f327bd11697a18ac95 GIT binary patch literal 1282 zcmV+d1^xPoP)Ocsg0qbhttrBd&R7yDjLMeq1 z!Vi2VrR)a6tL(s}>$<-IzbmCmx)4GDty0QwT-R*_R{KoC6|Gqz#Eb+qpsn((6{>og zth{JgL-8sa0AxL@)rJHFAYIpeoB2Z5b*;j&VpOywAgU?%CIs^I>C?OS?Ah~CI2>+j zZEanjPN$2Llasl4JU)Bm$dM6XC94tDA0My}_@Um6&d$!ZlP6E^i$O%*>1xi^Udi-n^Mf zrBaUH@7Du?fY#jHyuPQWCptVlJUcx-onMA>9Qd=k1788(ds*tbt_=(feAm&@vB7m+ zu3o)5d*;lUhuLg44LE==7!0=b_V(`FzkmM+Qc4WN$aHme{et&#{0!W#?m!3diI)S1 z4jtOv+1c6Qx-QqQU3=Es+dEh)l~RC7rL>kxrNx1PfvIpfylKmpElr_Nr~y!S@7|sD zpnU{PRMT*|AQaoSZTrx&EavCuo#V%k4+8~Wub2wRpE`AFB%My%rfITu>((~BQ(aK= zaVZC?RnotG`}UA++r;DX`BJI0Sg~J{cwu27H9kJRXxldJ?d{DKj=B!KMz&+ej`02a z_kS`B<3M9$qu;VD_U_%=Y8b|W!NI{FgTY|XgV>pxn#x<2MN3Od1K$6xvR3%D9Y`b+ zGbc`*Fy`jwuq+G9vM3Y^B$G*X`0(M;Y&M(qT3I9#dC#&eCMG8S#ybdK?10z#+t;sO z9~~MR%GkC|_37*Dn|$!#!DBDtNF>s{dGqG?Y}>{#j77>p>IG3R2n%P=o*hZ0QnqDT z7>4ou!i5VXK*_^i9y@mIYaxVgnkIMd-1*DPQC^7wuRu}BWODk_rAtOWpI7J3of|bx zbABnqXf(Rv%9ShMwzs!$vMh^OESBl-?|+1Mf1$z409h^#?Hf04jAk+!du(j%k5^VC z4jw$Xv%99p3N4(H`(UO(B z^EFZzFSY*{O{oHkQp)0*iI%mBfYK?~>c@`bd>IG?)(IhWT`ymlG))syN;FLqwd0y^ z0>E`$ Date: Fri, 17 Nov 2017 09:42:04 +0100 Subject: [PATCH 103/127] cleanup filtersPane, clear devices on case change. Devices unselected by default to simplify adding new ones and maintaining results --- .../communications/CVTTopComponent.form | 14 ++--- .../communications/CVTTopComponent.java | 14 ++--- .../autopsy/communications/FiltersPanel.form | 27 ---------- .../autopsy/communications/FiltersPanel.java | 51 +++++++++---------- 4 files changed, 39 insertions(+), 67 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.form b/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.form index ef764c80e1..6db797c284 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.form +++ b/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.form @@ -17,10 +17,10 @@ - - - - + + + + @@ -28,7 +28,7 @@ - + @@ -95,12 +95,12 @@ - + - + diff --git a/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java b/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java index b5ec0888a2..582453859b 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java +++ b/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java @@ -77,11 +77,11 @@ public final class CVTTopComponent extends TopComponent implements ExplorerManag jPanel1.setLayout(jPanel1Layout); jPanel1Layout.setHorizontalGroup( jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGap(0, 602, Short.MAX_VALUE) + .addGap(0, 591, Short.MAX_VALUE) ); jPanel1Layout.setVerticalGroup( jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGap(0, 718, Short.MAX_VALUE) + .addGap(0, 725, Short.MAX_VALUE) ); BrowseVisualizeTabPane.addTab(org.openide.util.NbBundle.getMessage(CVTTopComponent.class, "CVTTopComponent.TabConstraints.tabTitle"), new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/communications/images/emblem-web.png")), jPanel1); // NOI18N @@ -95,16 +95,16 @@ public final class CVTTopComponent extends TopComponent implements ExplorerManag layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() - .addGap(0, 0, 0) - .addComponent(filtersPane, javax.swing.GroupLayout.PREFERRED_SIZE, 251, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(splitPane, javax.swing.GroupLayout.DEFAULT_SIZE, 1344, Short.MAX_VALUE) + .addGap(6, 6, 6) + .addComponent(filtersPane, javax.swing.GroupLayout.PREFERRED_SIZE, 250, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(splitPane, javax.swing.GroupLayout.DEFAULT_SIZE, 1334, Short.MAX_VALUE) .addGap(0, 0, 0)) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() - .addContainerGap() + .addGap(6, 6, 6) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(filtersPane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(splitPane)) diff --git a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.form b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.form index 2960e5e259..72a13e519e 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.form +++ b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.form @@ -1,33 +1,6 @@
- - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java index ce4712f983..7f50087f2c 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java +++ b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java @@ -22,6 +22,7 @@ import java.beans.PropertyChangeListener; import java.time.LocalDate; import java.time.ZoneId; import java.time.format.TextStyle; +import java.util.EnumSet; import java.util.HashMap; import java.util.List; import java.util.Locale; @@ -75,8 +76,6 @@ final public class FiltersPanel extends javax.swing.JPanel { setPreferredTimeZone(); updateFilters(); - setAllAccountTypesSelected(true); - setAllDevicesSelected(true); UserPreferences.addChangeListener(preferenceChangeEvent -> { if (preferenceChangeEvent.getKey().equals(UserPreferences.DISPLAY_TIMES_IN_LOCAL_TIME)) { setPreferredTimeZone(); @@ -91,7 +90,6 @@ final public class FiltersPanel extends javax.swing.JPanel { applyFiltersButton.setIcon(new ImageIcon("org/sleuthkit/autopsy/communications/images/reload.png")); } else if (eventType.equals(COMPLETED.toString())) { } else if (eventType.equals(CANCELLED.toString())) { - } else if (eventType.equals(CURRENT_CASE.toString())) { } }; @@ -106,7 +104,7 @@ final public class FiltersPanel extends javax.swing.JPanel { if (em != null) { applyFilters(); } -} + } private void setPreferredTimeZone() { dateRangeLabel.setText("Date Range ( " + Utils.getUserPreferredZoneId().getDisplayName(TextStyle.NARROW, Locale.getDefault()) + "):"); @@ -125,8 +123,17 @@ final public class FiltersPanel extends javax.swing.JPanel { * till this FiltersPanel is actaully added to a parent. */ em = ExplorerManager.find(this); - IngestManager.getInstance().removeIngestModuleEventListener(ingestListener); + IngestManager.getInstance().addIngestModuleEventListener(ingestListener); + Case.addEventTypeSubscriber(EnumSet.of(CURRENT_CASE), evt -> { + devicesMap.clear(); + devicesPane.removeAll(); + }); + } + @Override + public void removeNotify() { + super.removeNotify(); + IngestManager.getInstance().removeIngestModuleEventListener(ingestListener); } /** @@ -152,7 +159,7 @@ final public class FiltersPanel extends javax.swing.JPanel { + FiltersPanel.class.getResource("/org/sleuthkit/autopsy/communications/images/" + Utils.getIconFileName(type)) + "\"/>" + type.getDisplayName() + "", - false + true ); accountTypePane.add(jCheckBox); return jCheckBox; @@ -167,14 +174,16 @@ final public class FiltersPanel extends javax.swing.JPanel { */ private void updateDeviceFilter() { try { - final List dataSources = Case.getCurrentCase().getSleuthkitCase().getDataSources(); - dataSources.forEach( - dataSource -> devicesMap.computeIfAbsent(dataSource.getDeviceId(), ds -> { - final JCheckBox jCheckBox = new JCheckBox(dataSource.getDeviceId(), false); - devicesPane.add(jCheckBox); - return jCheckBox; - }) - ); + Case.getCurrentCase() + .getSleuthkitCase() + .getDataSources().stream().map(DataSource::getDeviceId) + .forEach( + deviceID -> devicesMap.computeIfAbsent(deviceID, ds -> { + final JCheckBox jCheckBox = new JCheckBox(deviceID, false); + devicesPane.add(jCheckBox); + return jCheckBox; + })); + } catch (IllegalStateException ex) { logger.log(Level.WARNING, "Communications Visualization Tool opened with no open case.", ex); } catch (TskCoreException tskCoreException) { @@ -191,13 +200,6 @@ final public class FiltersPanel extends javax.swing.JPanel { // //GEN-BEGIN:initComponents private void initComponents() { - jList1.setModel(new javax.swing.AbstractListModel() { - String[] strings = { "Item 1", "Item 2", "Item 3", "Item 4", "Item 5" }; - public int getSize() { return strings.length; } - public String getElementAt(int i) { return strings[i]; } - }); - jScrollPane1.setViewportView(jList1); - applyFiltersButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/communications/images/control-double.png"))); // NOI18N applyFiltersButton.setText(org.openide.util.NbBundle.getMessage(FiltersPanel.class, "FiltersPanel.applyFiltersButton.text")); // NOI18N applyFiltersButton.setHorizontalTextPosition(javax.swing.SwingConstants.LEADING); @@ -428,11 +430,10 @@ final public class FiltersPanel extends javax.swing.JPanel { } catch (TskCoreException ex) { logger.log(Level.SEVERE, "There was a error loading the accounts.", ex); } - - + applyFiltersButton.setText("Apply"); applyFiltersButton.setIcon(new ImageIcon("org/sleuthkit/autopsy/communications/images/control-double.png")); - + } /** @@ -534,11 +535,9 @@ final public class FiltersPanel extends javax.swing.JPanel { private final javax.swing.JCheckBox endCheckBox = new javax.swing.JCheckBox(); private final com.github.lgooddatepicker.datepicker.DatePicker endDatePicker = new com.github.lgooddatepicker.datepicker.DatePicker(); private final javax.swing.JLabel filtersTitleLabel = new javax.swing.JLabel(); - private final javax.swing.JList jList1 = new javax.swing.JList<>(); private final javax.swing.JPanel jPanel2 = new javax.swing.JPanel(); private final javax.swing.JPanel jPanel3 = new javax.swing.JPanel(); private final javax.swing.JPanel jPanel4 = new javax.swing.JPanel(); - private final javax.swing.JScrollPane jScrollPane1 = new javax.swing.JScrollPane(); private final javax.swing.JScrollPane jScrollPane2 = new javax.swing.JScrollPane(); private final javax.swing.JScrollPane jScrollPane3 = new javax.swing.JScrollPane(); private final javax.swing.JCheckBox startCheckBox = new javax.swing.JCheckBox(); From 6be534c52b52b514636bc39454dcb805e56ec9ec Mon Sep 17 00:00:00 2001 From: millmanorama Date: Fri, 17 Nov 2017 10:22:58 +0100 Subject: [PATCH 104/127] cleanup refresh label and icon --- .../autopsy/communications/FiltersPanel.form | 3 +- .../autopsy/communications/FiltersPanel.java | 31 ++++++++++-------- .../images/arrow-circle-double-135.png | Bin 0 -> 864 bytes .../autopsy/communications/images/reload.png | Bin 1282 -> 0 bytes .../autopsy/communications/images/tick.png | Bin 0 -> 582 bytes 5 files changed, 18 insertions(+), 16 deletions(-) create mode 100755 Core/src/org/sleuthkit/autopsy/communications/images/arrow-circle-double-135.png delete mode 100644 Core/src/org/sleuthkit/autopsy/communications/images/reload.png create mode 100755 Core/src/org/sleuthkit/autopsy/communications/images/tick.png diff --git a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.form b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.form index 72a13e519e..8eff896e5f 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.form +++ b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.form @@ -55,12 +55,11 @@ - + - diff --git a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java index 7f50087f2c..fc90dd9d25 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java +++ b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java @@ -21,11 +21,9 @@ package org.sleuthkit.autopsy.communications; import java.beans.PropertyChangeListener; import java.time.LocalDate; import java.time.ZoneId; -import java.time.format.TextStyle; import java.util.EnumSet; import java.util.HashMap; import java.util.List; -import java.util.Locale; import java.util.Map; import java.util.Map.Entry; import java.util.logging.Level; @@ -34,6 +32,7 @@ import javax.swing.ImageIcon; import javax.swing.JCheckBox; import org.openide.explorer.ExplorerManager; import org.openide.nodes.AbstractNode; +import org.openide.util.NbBundle; import org.sleuthkit.autopsy.casemodule.Case; import static org.sleuthkit.autopsy.casemodule.Case.Events.CURRENT_CASE; import org.sleuthkit.autopsy.core.UserPreferences; @@ -61,6 +60,9 @@ final public class FiltersPanel extends javax.swing.JPanel { private static final Logger logger = Logger.getLogger(FiltersPanel.class.getName()); private static final long serialVersionUID = 1L; + private static final ImageIcon APPLY_ICON = new ImageIcon(FiltersPanel.class.getResource("images/tick.png")); + private static final ImageIcon REFRESH_ICON = new ImageIcon(FiltersPanel.class.getResource("images/arrow-circle-double-135.png")); + private ExplorerManager em; @ThreadConfined(type = ThreadConfined.ThreadType.AWT) @@ -69,25 +71,26 @@ final public class FiltersPanel extends javax.swing.JPanel { private final Map devicesMap = new HashMap<>(); private final PropertyChangeListener ingestListener; + @NbBundle.Messages({"refreshText=Refresh Results", + "applyText=Apply"}) public FiltersPanel() { initComponents(); startDatePicker.setDate(LocalDate.now().minusWeeks(3)); endDatePicker.setDateToToday(); - setPreferredTimeZone(); + updateTimeZone(); updateFilters(); UserPreferences.addChangeListener(preferenceChangeEvent -> { if (preferenceChangeEvent.getKey().equals(UserPreferences.DISPLAY_TIMES_IN_LOCAL_TIME)) { - setPreferredTimeZone(); + updateTimeZone(); } }); - this.ingestListener = pce -> { String eventType = pce.getPropertyName(); if (eventType.equals(DATA_ADDED.toString())) { updateFilters(); - applyFiltersButton.setText("Refresh"); - applyFiltersButton.setIcon(new ImageIcon("org/sleuthkit/autopsy/communications/images/reload.png")); + applyFiltersButton.setText(Bundle.refreshText()); + applyFiltersButton.setIcon(REFRESH_ICON); } else if (eventType.equals(COMPLETED.toString())) { } else if (eventType.equals(CANCELLED.toString())) { } else if (eventType.equals(CURRENT_CASE.toString())) { @@ -106,8 +109,8 @@ final public class FiltersPanel extends javax.swing.JPanel { } } - private void setPreferredTimeZone() { - dateRangeLabel.setText("Date Range ( " + Utils.getUserPreferredZoneId().getDisplayName(TextStyle.NARROW, Locale.getDefault()) + "):"); + private void updateTimeZone() { + dateRangeLabel.setText("Date Range ( " + Utils.getUserPreferredZoneId().toString() + "):"); } void updateFilters() { @@ -200,9 +203,8 @@ final public class FiltersPanel extends javax.swing.JPanel { // //GEN-BEGIN:initComponents private void initComponents() { - applyFiltersButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/communications/images/control-double.png"))); // NOI18N + applyFiltersButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/communications/images/tick.png"))); // NOI18N applyFiltersButton.setText(org.openide.util.NbBundle.getMessage(FiltersPanel.class, "FiltersPanel.applyFiltersButton.text")); // NOI18N - applyFiltersButton.setHorizontalTextPosition(javax.swing.SwingConstants.LEADING); applyFiltersButton.setPreferredSize(null); applyFiltersButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { @@ -421,7 +423,8 @@ final public class FiltersPanel extends javax.swing.JPanel { final CommunicationsManager commsManager = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager(); List accountDeviceInstanceKeys = - commsManager.getAccountDeviceInstancesWithCommunications(commsFilter) + commsManager + .getAccountDeviceInstancesWithCommunications(commsFilter) .stream() .map(adi -> new AccountDeviceInstanceKey(adi, commsFilter)) .collect(Collectors.toList()); @@ -431,8 +434,8 @@ final public class FiltersPanel extends javax.swing.JPanel { logger.log(Level.SEVERE, "There was a error loading the accounts.", ex); } - applyFiltersButton.setText("Apply"); - applyFiltersButton.setIcon(new ImageIcon("org/sleuthkit/autopsy/communications/images/control-double.png")); + applyFiltersButton.setText(Bundle.applyText()); + applyFiltersButton.setIcon(APPLY_ICON); } diff --git a/Core/src/org/sleuthkit/autopsy/communications/images/arrow-circle-double-135.png b/Core/src/org/sleuthkit/autopsy/communications/images/arrow-circle-double-135.png new file mode 100755 index 0000000000000000000000000000000000000000..4f40ba52062c62295a89856c8459052c0b78eadb GIT binary patch literal 864 zcmV-m1E2hfP)RAm^3ulMxKna&KIw$o|t$6$e0ZEG|phiWCMQ9(+YsAv#fxHYh-3}{$6em-`;9HZz2|fwY>x$fOC!yjt+&+xw*ON{ObqusX{`jv^6o- z!~{wu4-TZV^RM;~2ENQ9GW53!))*Q!&B@uP!kq_gGMNO|O4Zek?N$wFK0TP$6QkYn zZVQed&S$^9v^gblToDoD130bG+E6KLasz43U05vwS48AEV=a zYexDKnbJnP54h_A7_C8sMBve=?Q-haXlS&aFwXa6 zdET;!gzuf22`f7qfOMzN`R}einbB(faC56_DkN0j*#04F%xMvsZ#SFlwpt5T>nn?2 zFBNSv$!bH`)(WdNR_n(AV=C*VJI&6X3|oFi#@?El>K@5|A#uFqti9GfoIml*yGO&H zcc7=gi<%c;wB|2~aTFP6%+2EB`NH@|Z?oA-dR{nP7Nzwc4_)Yt=t~DcusSF9UM` z(T`sp_8&{_h|4RvxV+LC^&Y%*@7D1$`N{kEoedyEWY?&cZphk&WhvjRdEqA&lG&Hy q`zwXL1RjtA(m>)rd~pOg!2St{?uz8+#hTgx0000Ocsg0qbhttrBd&R7yDjLMeq1 z!Vi2VrR)a6tL(s}>$<-IzbmCmx)4GDty0QwT-R*_R{KoC6|Gqz#Eb+qpsn((6{>og zth{JgL-8sa0AxL@)rJHFAYIpeoB2Z5b*;j&VpOywAgU?%CIs^I>C?OS?Ah~CI2>+j zZEanjPN$2Llasl4JU)Bm$dM6XC94tDA0My}_@Um6&d$!ZlP6E^i$O%*>1xi^Udi-n^Mf zrBaUH@7Du?fY#jHyuPQWCptVlJUcx-onMA>9Qd=k1788(ds*tbt_=(feAm&@vB7m+ zu3o)5d*;lUhuLg44LE==7!0=b_V(`FzkmM+Qc4WN$aHme{et&#{0!W#?m!3diI)S1 z4jtOv+1c6Qx-QqQU3=Es+dEh)l~RC7rL>kxrNx1PfvIpfylKmpElr_Nr~y!S@7|sD zpnU{PRMT*|AQaoSZTrx&EavCuo#V%k4+8~Wub2wRpE`AFB%My%rfITu>((~BQ(aK= zaVZC?RnotG`}UA++r;DX`BJI0Sg~J{cwu27H9kJRXxldJ?d{DKj=B!KMz&+ej`02a z_kS`B<3M9$qu;VD_U_%=Y8b|W!NI{FgTY|XgV>pxn#x<2MN3Od1K$6xvR3%D9Y`b+ zGbc`*Fy`jwuq+G9vM3Y^B$G*X`0(M;Y&M(qT3I9#dC#&eCMG8S#ybdK?10z#+t;sO z9~~MR%GkC|_37*Dn|$!#!DBDtNF>s{dGqG?Y}>{#j77>p>IG3R2n%P=o*hZ0QnqDT z7>4ou!i5VXK*_^i9y@mIYaxVgnkIMd-1*DPQC^7wuRu}BWODk_rAtOWpI7J3of|bx zbABnqXf(Rv%9ShMwzs!$vMh^OESBl-?|+1Mf1$z409h^#?Hf04jAk+!du(j%k5^VC z4jw$Xv%99p3N4(H`(UO(B z^EFZzFSY*{O{oHkQp)0*iI%mBfYK?~>c@`bd>IG?)(IhWT`ymlG))syN;FLqwd0y^ z0>E`$tYd4K$mX5uyr2F@fdffp{&DSHtl4|Bn9=ukpCx`#%PTUr-D(@b7;C zhJXJjrnw{;1KBM=6&|E`fsNrGL!Y6%zUh}QUl`(@V)PmQFtotEKmafTHP0uP}7&%m4pcKQ#X)BiAJ2y+PrtBI>9eEIt2-_c7)?*Lsf z5vX5*Af@m-wBJRV%#Fiz=BdPr0!2^az8K(fJ0K@xl?-_o)`1bna-SH57SeZUButL)d$cI_) zkpl5Q!w#U+YtHUCagF&eebP3jhEB literal 0 HcmV?d00001 From 1e100eea1a2b50103640a70ff054f87c914941e4 Mon Sep 17 00:00:00 2001 From: millmanorama Date: Fri, 17 Nov 2017 11:36:10 +0100 Subject: [PATCH 105/127] update LGoodDatePicker to 10.3.1 to fix bug that allowed popup calendar to be offscreen --- .../sleuthkit/autopsy/communications/FiltersPanel.form | 4 ++-- .../sleuthkit/autopsy/communications/FiltersPanel.java | 5 +++-- CoreLibs/ivy.xml | 2 +- CoreLibs/nbproject/project.properties | 6 +++--- CoreLibs/nbproject/project.xml | 9 ++++----- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.form b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.form index cfcdf28784..b8a5b5ae23 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.form +++ b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.form @@ -333,7 +333,7 @@ - + @@ -368,7 +368,7 @@ - + diff --git a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java index 9794769a34..90eb6c298c 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java +++ b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java @@ -62,6 +62,7 @@ final public class FiltersPanel extends javax.swing.JPanel { initComponents(); startDatePicker.setDate(LocalDate.now().minusWeeks(3)); endDatePicker.setDateToToday(); + updateAndApplyFilters(); } @@ -489,7 +490,7 @@ final public class FiltersPanel extends javax.swing.JPanel { private final javax.swing.JLabel devicesLabel = new javax.swing.JLabel(); private final javax.swing.JPanel devicesPane = new javax.swing.JPanel(); private final javax.swing.JCheckBox endCheckBox = new javax.swing.JCheckBox(); - private final com.github.lgooddatepicker.datepicker.DatePicker endDatePicker = new com.github.lgooddatepicker.datepicker.DatePicker(); + private final com.github.lgooddatepicker.components.DatePicker endDatePicker = new com.github.lgooddatepicker.components.DatePicker(); private final javax.swing.JLabel filtersTitleLabel = new javax.swing.JLabel(); private final javax.swing.JList jList1 = new javax.swing.JList<>(); private final javax.swing.JPanel jPanel2 = new javax.swing.JPanel(); @@ -497,7 +498,7 @@ final public class FiltersPanel extends javax.swing.JPanel { private final javax.swing.JPanel jPanel4 = new javax.swing.JPanel(); private final javax.swing.JScrollPane jScrollPane1 = new javax.swing.JScrollPane(); private final javax.swing.JCheckBox startCheckBox = new javax.swing.JCheckBox(); - private final com.github.lgooddatepicker.datepicker.DatePicker startDatePicker = new com.github.lgooddatepicker.datepicker.DatePicker(); + private final com.github.lgooddatepicker.components.DatePicker startDatePicker = new com.github.lgooddatepicker.components.DatePicker(); private final javax.swing.JButton unCheckAllAccountTypesButton = new javax.swing.JButton(); private final javax.swing.JButton unCheckAllDevicesButton = new javax.swing.JButton(); // End of variables declaration//GEN-END:variables diff --git a/CoreLibs/ivy.xml b/CoreLibs/ivy.xml index 406847acac..32c7186ae5 100755 --- a/CoreLibs/ivy.xml +++ b/CoreLibs/ivy.xml @@ -14,7 +14,7 @@ - + diff --git a/CoreLibs/nbproject/project.properties b/CoreLibs/nbproject/project.properties index 057a3d3568..4b3f88b1bc 100755 --- a/CoreLibs/nbproject/project.properties +++ b/CoreLibs/nbproject/project.properties @@ -53,7 +53,7 @@ file.reference.joda-time-2.4-javadoc.jar=release/modules/ext/joda-time-2.4-javad file.reference.joda-time-2.4-sources.jar=release/modules/ext/joda-time-2.4-sources.jar file.reference.joda-time-2.4.jar=release/modules/ext/joda-time-2.4.jar file.reference.jsr305-1.3.9.jar=release/modules/ext/jsr305-1.3.9.jar -file.reference.LGoodDatePicker-4.3.1.jar=release/modules/ext/LGoodDatePicker-4.3.1.jar +file.reference.LGoodDatePicker-4.3.1.jar=release/modules/ext/LGoodDatePicker-10.3.1.jar file.reference.log4j-1.2.17.jar=release/modules/ext/log4j-1.2.17.jar file.reference.logkit-1.0.1.jar=release/modules/ext/logkit-1.0.1.jar file.reference.mail-1.4.3.jar=release/modules/ext/mail-1.4.3.jar @@ -83,7 +83,7 @@ javadoc.reference.guava-19.0.jar=release/modules/ext/guava-19.0-javadoc.jar javadoc.reference.jfxtras-common-8.0-r4.jar=release/modules/ext/jfxtras-common-8.0-r4-javadoc.jar javadoc.reference.jfxtras-controls-8.0-r4.jar=release/modules/ext/jfxtras-controls-8.0-r4-javadoc.jar javadoc.reference.jfxtras-fxml-8.0-r4.jar=release/modules/ext/jfxtras-fxml-8.0-r4-javadoc.jar -javadoc.reference.LGoodDatePicker-4.3.1.jar=release/modules/ext/LGoodDatePicker-4.3.1-javadoc.jar +javadoc.reference.LGoodDatePicker-4.3.1.jar=release/modules/ext/LGoodDatePicker-10.3.1-javadoc.jar nbm.needs.restart=true source.reference.commons-csv-1.4.jar=release/modules/ext/commons-csv-1.4-sources.jar source.reference.commons-io-2.5.jar=release/modules/ext/commons-io-2.5-sources.jar @@ -93,4 +93,4 @@ source.reference.guava-19.0.jar=release/modules/ext/guava-19.0-sources.jar source.reference.jfxtras-common-8.0-r4.jar=release/modules/ext/jfxtras-common-8.0-r4-sources.jar source.reference.jfxtras-controls-8.0-r4.jar=release/modules/ext/jfxtras-controls-8.0-r4-sources.jar source.reference.jfxtras-fxml-8.0-r4.jar=release/modules/ext/jfxtras-fxml-8.0-r4-sources.jar -source.reference.LGoodDatePicker-4.3.1.jar=release/modules/ext/LGoodDatePicker-4.3.1-sources.jar +source.reference.LGoodDatePicker-4.3.1.jar=release/modules/ext/LGoodDatePicker-10.3.1-sources.jar diff --git a/CoreLibs/nbproject/project.xml b/CoreLibs/nbproject/project.xml index f95b75754b..e0d87f25ea 100755 --- a/CoreLibs/nbproject/project.xml +++ b/CoreLibs/nbproject/project.xml @@ -37,9 +37,8 @@ com.apple.eawt com.apple.eawt.event com.apple.eio - com.github.lgooddatepicker.datepicker - com.github.lgooddatepicker.datetimepicker - com.github.lgooddatepicker.timepicker + com.github.lgooddatepicker.components + com.github.lgooddatepicker.optionalusertools com.github.lgooddatepicker.zinternaltools com.github.mustachejava com.github.mustachejava.codes @@ -728,8 +727,8 @@ release/modules/ext/imgscalr-lib-4.2.jar - ext/LGoodDatePicker-4.3.1.jar - release/modules/ext/LGoodDatePicker-4.3.1.jar + ext/LGoodDatePicker-10.3.1.jar + release/modules/ext/LGoodDatePicker-10.3.1.jar ext/xmlbeans-2.6.0.jar From 98d5c7790e0857c7e9278355ac1e58704bbab72b Mon Sep 17 00:00:00 2001 From: millmanorama Date: Fri, 17 Nov 2017 11:47:20 +0100 Subject: [PATCH 106/127] disallow invalid date selections --- .../autopsy/communications/FiltersPanel.java | 49 +++++++++++-------- 1 file changed, 29 insertions(+), 20 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java index 90eb6c298c..0b0a7d17e4 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java +++ b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java @@ -62,6 +62,16 @@ final public class FiltersPanel extends javax.swing.JPanel { initComponents(); startDatePicker.setDate(LocalDate.now().minusWeeks(3)); endDatePicker.setDateToToday(); + startDatePicker.getSettings().setVetoPolicy( + //no end date, or start is before end + startDate -> endCheckBox.isSelected() == false + || startDate.compareTo(endDatePicker.getDate()) <= 0 + ); + endDatePicker.getSettings().setVetoPolicy( + //no start date, or end is after start + endDate -> startCheckBox.isSelected() == false + || endDate.compareTo(startDatePicker.getDate()) >= 0 + ); updateAndApplyFilters(); } @@ -99,26 +109,25 @@ final public class FiltersPanel extends javax.swing.JPanel { //final CommunicationsManager communicationsManager = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager(); //List accountTypesInUse = communicationsManager.getAccountTypesInUse(); //accountTypesInUSe.forEach(...) - Account.Type.PREDEFINED_ACCOUNT_TYPES.forEach( - type -> { - if (type.equals(Account.Type.CREDIT_CARD)) { - //don't show a check box for credit cards - } else if (type.equals(Account.Type.DEVICE)) { - //don't show a check box fro device - } else { - accountTypeMap.computeIfAbsent(type, t -> { - final JCheckBox jCheckBox = new JCheckBox( - "
" + type.getDisplayName() + "
", - true - ); - accountTypePane.add(jCheckBox); - return jCheckBox; - }); - } - } + Account.Type.PREDEFINED_ACCOUNT_TYPES.forEach(type -> { + if (type.equals(Account.Type.CREDIT_CARD)) { + //don't show a check box for credit cards + } else if (type.equals(Account.Type.DEVICE)) { + //don't show a check box fro device + } else { + accountTypeMap.computeIfAbsent(type, t -> { + final JCheckBox jCheckBox = new JCheckBox( + "
" + type.getDisplayName() + "
", + true + ); + accountTypePane.add(jCheckBox); + return jCheckBox; + }); + } + } ); } From 10e6bbaa8585860e09938175d805682a791a1541 Mon Sep 17 00:00:00 2001 From: millmanorama Date: Fri, 17 Nov 2017 12:21:54 +0100 Subject: [PATCH 107/127] reuse visualiationion tab in action button --- .../OpenCommVisualizationToolAction.java | 2 +- .../communications/images/emblem-web24.png | Bin 0 -> 1389 bytes 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 Core/src/org/sleuthkit/autopsy/communications/images/emblem-web24.png diff --git a/Core/src/org/sleuthkit/autopsy/communications/OpenCommVisualizationToolAction.java b/Core/src/org/sleuthkit/autopsy/communications/OpenCommVisualizationToolAction.java index 80586d0aa9..fe2b5afcbd 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/OpenCommVisualizationToolAction.java +++ b/Core/src/org/sleuthkit/autopsy/communications/OpenCommVisualizationToolAction.java @@ -49,7 +49,7 @@ public final class OpenCommVisualizationToolAction extends CallableSystemAction private static final long serialVersionUID = 1L; private final JButton toolbarButton = new JButton(getName(), - new ImageIcon(getClass().getResource("images/email_link.png"))); //NON-NLS + new ImageIcon(getClass().getResource("images/emblem-web24.png"))); //NON-NLS public OpenCommVisualizationToolAction() { toolbarButton.addActionListener(actionEvent -> performAction()); diff --git a/Core/src/org/sleuthkit/autopsy/communications/images/emblem-web24.png b/Core/src/org/sleuthkit/autopsy/communications/images/emblem-web24.png new file mode 100644 index 0000000000000000000000000000000000000000..9b105460320af9c74a8662565c288e10ad21ca8b GIT binary patch literal 1389 zcmV-z1(N!SP)quy0r)0yh-8KpO*T6pfy?0Gjj*gq~QozSlv=9vTFLN6rH5E35c*MW0R zJLf?J1UA|M&cmfM0nJG9{y|1wc>r3mCeVs+Y#6@36CfyNw$ANw!FX9wSYe|bP*s%< zL`0R=A>vV@iL_@UPC2(J+zFu@H`(e%Tw0F_jbf2I8YE~|h)h{xy+^#@yDGItZ#alN|**(mkv{#@NKl#ppe=mf?X~uZr7*0z30X5WR^E}9}^hxB6tzp=jTaQaX2k_=kAQXy*(d{Mk9ag!6{kc7)>+grzK}QA?vM( zj}A|H<>fUr!nA402Kf#Eh+%4gFt~2VVPOR z2$`)>3*aaLXWdhCXSyutHw@On!89i?pUe@Z0hN{(>m1HGtant_v3Hcvt{J9f#BX<( zEDQMB`4&!Ay=uK@kyljKQ#r>xDLB(Kq$_h30JHOG{ZftdsvRuAIetjfmj9!f3@a?U3E! zoV`bXFO*g&t;dOfV(iPw!Ex9-zizFg&))YICsjm0qt`Z^VXvE9ByO zosY*0I*ov}W=Ovk&}#;?>jBN0#uymQa!df12Q7{kIr;3tbn@=+{!ks?dtHeLN~!08 v9|Bha4PcB>&bcqzZeJ!3+y&kekz1bu){Dj6w`vW~00000NkvXXu0mjfXJ?d$ literal 0 HcmV?d00001 From 24acb7814d13ad00969f6d6f96966ef257571034 Mon Sep 17 00:00:00 2001 From: millmanorama Date: Fri, 17 Nov 2017 13:10:24 +0100 Subject: [PATCH 108/127] Capitalize date range labels --- .../org/sleuthkit/autopsy/communications/Bundle.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/communications/Bundle.properties b/Core/src/org/sleuthkit/autopsy/communications/Bundle.properties index 5b2de59bea..09ca7ce486 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/communications/Bundle.properties @@ -9,5 +9,5 @@ FiltersPanel.checkAllAccountTypesButton.text=Check All FiltersPanel.unCheckAllDevicesButton.text=Uncheck All FiltersPanel.checkAllDevicesButton.text=Check All FiltersPanel.dateRangeLabel.text=Date Range: -FiltersPanel.startCheckBox.text=start: -FiltersPanel.endCheckBox.text=end: +FiltersPanel.startCheckBox.text=Start: +FiltersPanel.endCheckBox.text=End: From faa169d20d4985154cb977911ade609e904e8ff9 Mon Sep 17 00:00:00 2001 From: millmanorama Date: Fri, 17 Nov 2017 13:13:04 +0100 Subject: [PATCH 109/127] removed unused jlist; query for account device instances in swing worker; show wait cursor --- .../communications/CVTTopComponent.form | 2 +- .../communications/CVTTopComponent.java | 4 +- .../autopsy/communications/FiltersPanel.form | 35 +------ .../autopsy/communications/FiltersPanel.java | 98 +++++++++---------- 4 files changed, 54 insertions(+), 85 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.form b/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.form index 3f36c1afd3..44f734e9d3 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.form +++ b/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.form @@ -30,7 +30,7 @@ - + diff --git a/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java b/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java index f7b5daa0c2..7010f22e33 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java +++ b/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java @@ -137,7 +137,9 @@ public final class CVTTopComponent extends TopComponent implements ExplorerManag super.open(); /* * when the window is (re)opened make sure the filters and accounts are - * in a up to date and consistent state. + * in an up to date and consistent state. + * + * Re-applying the filters means we will lose the selection... */ filtersPane.updateAndApplyFilters(); } diff --git a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.form b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.form index cfcdf28784..7d51693298 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.form +++ b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.form @@ -1,33 +1,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -53,10 +26,7 @@ - - - - + @@ -95,9 +65,6 @@
- - -
diff --git a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java index 9794769a34..294c0359f5 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java +++ b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java @@ -18,15 +18,18 @@ */ package org.sleuthkit.autopsy.communications; +import java.awt.Cursor; import java.time.LocalDate; import java.time.ZoneId; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; +import java.util.concurrent.ExecutionException; import java.util.logging.Level; import java.util.stream.Collectors; import javax.swing.JCheckBox; +import javax.swing.SwingWorker; import org.openide.explorer.ExplorerManager; import org.openide.nodes.AbstractNode; import org.sleuthkit.autopsy.casemodule.Case; @@ -62,7 +65,8 @@ final public class FiltersPanel extends javax.swing.JPanel { initComponents(); startDatePicker.setDate(LocalDate.now().minusWeeks(3)); endDatePicker.setDateToToday(); - updateAndApplyFilters(); + + applyFiltersButton.addActionListener(actionEvent -> applyFilters()); } /** @@ -86,6 +90,7 @@ final public class FiltersPanel extends javax.swing.JPanel { * till this FiltersPanel is actaully added to a parent. */ em = ExplorerManager.find(this); + updateAndApplyFilters(); } /** @@ -98,26 +103,25 @@ final public class FiltersPanel extends javax.swing.JPanel { //final CommunicationsManager communicationsManager = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager(); //List accountTypesInUse = communicationsManager.getAccountTypesInUse(); //accountTypesInUSe.forEach(...) - Account.Type.PREDEFINED_ACCOUNT_TYPES.forEach( - type -> { - if (type.equals(Account.Type.CREDIT_CARD)) { - //don't show a check box for credit cards - } else if (type.equals(Account.Type.DEVICE)) { - //don't show a check box fro device - } else { - accountTypeMap.computeIfAbsent(type, t -> { - final JCheckBox jCheckBox = new JCheckBox( - "
" + type.getDisplayName() + "
", - true - ); - accountTypePane.add(jCheckBox); - return jCheckBox; - }); - } - } + Account.Type.PREDEFINED_ACCOUNT_TYPES.forEach(type -> { + if (type.equals(Account.Type.CREDIT_CARD)) { + //don't show a check box for credit cards + } else if (type.equals(Account.Type.DEVICE)) { + //don't show a check box fro device + } else { + accountTypeMap.computeIfAbsent(type, t -> { + final JCheckBox jCheckBox = new JCheckBox( + "
" + type.getDisplayName() + "
", + true + ); + accountTypePane.add(jCheckBox); + return jCheckBox; + }); + } + } ); } @@ -150,22 +154,10 @@ final public class FiltersPanel extends javax.swing.JPanel { // //GEN-BEGIN:initComponents private void initComponents() { - jList1.setModel(new javax.swing.AbstractListModel() { - String[] strings = { "Item 1", "Item 2", "Item 3", "Item 4", "Item 5" }; - public int getSize() { return strings.length; } - public String getElementAt(int i) { return strings[i]; } - }); - jScrollPane1.setViewportView(jList1); - applyFiltersButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/communications/images/control-double.png"))); // NOI18N applyFiltersButton.setText(org.openide.util.NbBundle.getMessage(FiltersPanel.class, "FiltersPanel.applyFiltersButton.text")); // NOI18N applyFiltersButton.setHorizontalTextPosition(javax.swing.SwingConstants.LEADING); applyFiltersButton.setPreferredSize(null); - applyFiltersButton.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - applyFiltersButtonActionPerformed(evt); - } - }); filtersTitleLabel.setFont(new java.awt.Font("Tahoma", 0, 16)); // NOI18N filtersTitleLabel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/communications/images/funnel.png"))); // NOI18N @@ -341,9 +333,7 @@ final public class FiltersPanel extends javax.swing.JPanel { .addComponent(filtersTitleLabel) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(applyFiltersButton, javax.swing.GroupLayout.PREFERRED_SIZE, 83, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addGroup(layout.createSequentialGroup() - .addComponent(jPanel4, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addGap(0, 0, 0))) + .addComponent(jPanel4, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addContainerGap()) ); layout.setVerticalGroup( @@ -363,10 +353,6 @@ final public class FiltersPanel extends javax.swing.JPanel { ); }// //GEN-END:initComponents - private void applyFiltersButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_applyFiltersButtonActionPerformed - applyFilters(); - }//GEN-LAST:event_applyFiltersButtonActionPerformed - /** * Query for accounts using the selected filters, and send the results to * the AccountsBrowser via the ExplorerManager. @@ -379,16 +365,32 @@ final public class FiltersPanel extends javax.swing.JPanel { try { final CommunicationsManager commsManager = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager(); + setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); + new SwingWorker() { + @Override + protected AbstractNode doInBackground() throws Exception { + List accountDeviceInstanceKeys = + commsManager.getAccountDeviceInstancesWithCommunications(commsFilter) + .stream() + .map(adi -> new AccountDeviceInstanceKey(adi, commsFilter)) + .collect(Collectors.toList()); + return new AbstractNode(new AccountsRootChildren(accountDeviceInstanceKeys, commsManager)); + } - List accountDeviceInstanceKeys = - commsManager.getAccountDeviceInstancesWithCommunications(commsFilter) - .stream() - .map(adi -> new AccountDeviceInstanceKey(adi, commsFilter)) - .collect(Collectors.toList()); + @Override + protected void done() { + super.done(); //To change body of generated methods, choose Tools | Templates. - em.setRootContext(new AbstractNode(new AccountsRootChildren(accountDeviceInstanceKeys, commsManager))); + setCursor(Cursor.getDefaultCursor()); + try { + em.setRootContext(get()); + } catch (InterruptedException | ExecutionException ex) { + logger.log(Level.SEVERE, "Error getting account device instances for filter: " + commsFilter, ex); + } + } + }.execute(); } catch (TskCoreException ex) { - logger.log(Level.SEVERE, "There was a error loading the accounts.", ex); + logger.log(Level.SEVERE, "There was an error getting the CommunicationsManager for the current case.", ex); } } @@ -491,11 +493,9 @@ final public class FiltersPanel extends javax.swing.JPanel { private final javax.swing.JCheckBox endCheckBox = new javax.swing.JCheckBox(); private final com.github.lgooddatepicker.datepicker.DatePicker endDatePicker = new com.github.lgooddatepicker.datepicker.DatePicker(); private final javax.swing.JLabel filtersTitleLabel = new javax.swing.JLabel(); - private final javax.swing.JList jList1 = new javax.swing.JList<>(); private final javax.swing.JPanel jPanel2 = new javax.swing.JPanel(); private final javax.swing.JPanel jPanel3 = new javax.swing.JPanel(); private final javax.swing.JPanel jPanel4 = new javax.swing.JPanel(); - private final javax.swing.JScrollPane jScrollPane1 = new javax.swing.JScrollPane(); private final javax.swing.JCheckBox startCheckBox = new javax.swing.JCheckBox(); private final com.github.lgooddatepicker.datepicker.DatePicker startDatePicker = new com.github.lgooddatepicker.datepicker.DatePicker(); private final javax.swing.JButton unCheckAllAccountTypesButton = new javax.swing.JButton(); From 146a41743812ecd643de503e0a8a6d18b7d1b117 Mon Sep 17 00:00:00 2001 From: millmanorama Date: Mon, 20 Nov 2017 12:48:09 +0100 Subject: [PATCH 110/127] split apply/refresh into to buttons --- .../autopsy/communications/Bundle.properties | 1 + .../communications/CVTTopComponent.form | 6 +-- .../communications/CVTTopComponent.java | 6 +-- .../autopsy/communications/FiltersPanel.form | 22 ++++++--- .../autopsy/communications/FiltersPanel.java | 47 +++++++------------ 5 files changed, 40 insertions(+), 42 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/communications/Bundle.properties b/Core/src/org/sleuthkit/autopsy/communications/Bundle.properties index 13d3eda321..af6d79d8ab 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/communications/Bundle.properties @@ -11,3 +11,4 @@ FiltersPanel.checkAllDevicesButton.text=Check All FiltersPanel.dateRangeLabel.text=Date Range: FiltersPanel.startCheckBox.text=Start: FiltersPanel.endCheckBox.text=End: +FiltersPanel.refreshButton.text=Refresh diff --git a/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.form b/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.form index 36f882c2b6..7b23c12636 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.form +++ b/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.form @@ -19,8 +19,8 @@ - - + + @@ -95,7 +95,7 @@ - + diff --git a/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java b/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java index 2f81943211..3fb54e878f 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java +++ b/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java @@ -77,7 +77,7 @@ public final class CVTTopComponent extends TopComponent implements ExplorerManag jPanel1.setLayout(jPanel1Layout); jPanel1Layout.setHorizontalGroup( jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGap(0, 394, Short.MAX_VALUE) + .addGap(0, 397, Short.MAX_VALUE) ); jPanel1Layout.setVerticalGroup( jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) @@ -97,8 +97,8 @@ public final class CVTTopComponent extends TopComponent implements ExplorerManag .addGroup(layout.createSequentialGroup() .addGap(6, 6, 6) .addComponent(filtersPane, javax.swing.GroupLayout.PREFERRED_SIZE, 250, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(splitPane, javax.swing.GroupLayout.DEFAULT_SIZE, 1334, Short.MAX_VALUE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(splitPane, javax.swing.GroupLayout.DEFAULT_SIZE, 1339, Short.MAX_VALUE) .addGap(0, 0, 0)) ); layout.setVerticalGroup( diff --git a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.form b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.form index b69d1bba17..7073afec35 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.form +++ b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.form @@ -25,6 +25,8 @@ + + @@ -39,6 +41,7 @@ + @@ -64,21 +67,18 @@
- - -
- - - + + + @@ -344,5 +344,15 @@ + + + + + + + + + + diff --git a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java index df6260fea5..57399187dc 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java +++ b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java @@ -28,7 +28,6 @@ import java.util.Map; import java.util.Map.Entry; import java.util.logging.Level; import java.util.stream.Collectors; -import javax.swing.ImageIcon; import javax.swing.JCheckBox; import org.openide.explorer.ExplorerManager; import org.openide.nodes.AbstractNode; @@ -39,8 +38,6 @@ import org.sleuthkit.autopsy.core.UserPreferences; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.ThreadConfined; import org.sleuthkit.autopsy.ingest.IngestManager; -import static org.sleuthkit.autopsy.ingest.IngestManager.IngestJobEvent.CANCELLED; -import static org.sleuthkit.autopsy.ingest.IngestManager.IngestJobEvent.COMPLETED; import static org.sleuthkit.autopsy.ingest.IngestManager.IngestModuleEvent.DATA_ADDED; import org.sleuthkit.datamodel.Account; import org.sleuthkit.datamodel.AccountTypeFilter; @@ -60,15 +57,14 @@ final public class FiltersPanel extends javax.swing.JPanel { private static final Logger logger = Logger.getLogger(FiltersPanel.class.getName()); private static final long serialVersionUID = 1L; - private static final ImageIcon APPLY_ICON = new ImageIcon(FiltersPanel.class.getResource("images/tick.png")); - private static final ImageIcon REFRESH_ICON = new ImageIcon(FiltersPanel.class.getResource("images/arrow-circle-double-135.png")); - private ExplorerManager em; @ThreadConfined(type = ThreadConfined.ThreadType.AWT) private final Map accountTypeMap = new HashMap<>(); @ThreadConfined(type = ThreadConfined.ThreadType.AWT) private final Map devicesMap = new HashMap<>(); + + private final PropertyChangeListener ingestListener; @NbBundle.Messages({"refreshText=Refresh Results", @@ -77,7 +73,7 @@ final public class FiltersPanel extends javax.swing.JPanel { initComponents(); startDatePicker.setDate(LocalDate.now().minusWeeks(3)); endDatePicker.setDateToToday(); - startDatePicker.getSettings().setVetoPolicy( + startDatePicker.getSettings().setVetoPolicy( //no end date, or start is before end startDate -> endCheckBox.isSelected() == false || startDate.compareTo(endDatePicker.getDate()) <= 0 @@ -88,29 +84,24 @@ final public class FiltersPanel extends javax.swing.JPanel { || endDate.compareTo(startDatePicker.getDate()) >= 0 ); - - updateTimeZone(); - updateFilters(); UserPreferences.addChangeListener(preferenceChangeEvent -> { if (preferenceChangeEvent.getKey().equals(UserPreferences.DISPLAY_TIMES_IN_LOCAL_TIME)) { updateTimeZone(); } }); + this.ingestListener = pce -> { String eventType = pce.getPropertyName(); if (eventType.equals(DATA_ADDED.toString())) { - updateFilters(); - applyFiltersButton.setText(Bundle.refreshText()); - applyFiltersButton.setIcon(REFRESH_ICON); - } else if (eventType.equals(COMPLETED.toString())) { - } else if (eventType.equals(CANCELLED.toString())) { - } else if (eventType.equals(CURRENT_CASE.toString())) { + refreshButton.setEnabled(true); } }; + applyFiltersButton.addActionListener(e -> applyFilters()); + refreshButton.addActionListener(e -> applyFilters()); } /** @@ -219,11 +210,6 @@ final public class FiltersPanel extends javax.swing.JPanel { applyFiltersButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/communications/images/tick.png"))); // NOI18N applyFiltersButton.setText(org.openide.util.NbBundle.getMessage(FiltersPanel.class, "FiltersPanel.applyFiltersButton.text")); // NOI18N applyFiltersButton.setPreferredSize(null); - applyFiltersButton.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - applyFiltersButtonActionPerformed(evt); - } - }); filtersTitleLabel.setFont(new java.awt.Font("Tahoma", 0, 16)); // NOI18N filtersTitleLabel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/communications/images/funnel.png"))); // NOI18N @@ -385,6 +371,9 @@ final public class FiltersPanel extends javax.swing.JPanel { .addComponent(endDatePicker, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) ); + refreshButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/communications/images/arrow-circle-double-135.png"))); // NOI18N + refreshButton.setText(org.openide.util.NbBundle.getMessage(FiltersPanel.class, "FiltersPanel.refreshButton.text")); // NOI18N + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); layout.setHorizontalGroup( @@ -397,7 +386,9 @@ final public class FiltersPanel extends javax.swing.JPanel { .addGroup(layout.createSequentialGroup() .addComponent(filtersTitleLabel) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(applyFiltersButton, javax.swing.GroupLayout.PREFERRED_SIZE, 83, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(applyFiltersButton, javax.swing.GroupLayout.PREFERRED_SIZE, 83, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(refreshButton)) .addComponent(jPanel4, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addGap(0, 0, 0)) ); @@ -407,7 +398,8 @@ final public class FiltersPanel extends javax.swing.JPanel { .addGap(0, 0, 0) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(filtersTitleLabel) - .addComponent(applyFiltersButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(applyFiltersButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(refreshButton)) .addGap(18, 18, 18) .addComponent(jPanel3, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addGap(18, 18, 18) @@ -418,10 +410,6 @@ final public class FiltersPanel extends javax.swing.JPanel { ); }//
//GEN-END:initComponents - private void applyFiltersButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_applyFiltersButtonActionPerformed - applyFilters(); - }//GEN-LAST:event_applyFiltersButtonActionPerformed - /** * Query for accounts using the selected filters, and send the results to * the AccountsBrowser via the ExplorerManager. @@ -447,9 +435,7 @@ final public class FiltersPanel extends javax.swing.JPanel { logger.log(Level.SEVERE, "There was a error loading the accounts.", ex); } - applyFiltersButton.setText(Bundle.applyText()); - applyFiltersButton.setIcon(APPLY_ICON); - + refreshButton.setEnabled(false); } /** @@ -556,6 +542,7 @@ final public class FiltersPanel extends javax.swing.JPanel { private final javax.swing.JPanel jPanel4 = new javax.swing.JPanel(); private final javax.swing.JScrollPane jScrollPane2 = new javax.swing.JScrollPane(); private final javax.swing.JScrollPane jScrollPane3 = new javax.swing.JScrollPane(); + private final javax.swing.JButton refreshButton = new javax.swing.JButton(); private final javax.swing.JCheckBox startCheckBox = new javax.swing.JCheckBox(); private final com.github.lgooddatepicker.components.DatePicker startDatePicker = new com.github.lgooddatepicker.components.DatePicker(); private final javax.swing.JButton unCheckAllAccountTypesButton = new javax.swing.JButton(); From 876bdc0cb8872a44abde4a246b4c5a81185e4b08 Mon Sep 17 00:00:00 2001 From: millmanorama Date: Mon, 20 Nov 2017 12:52:54 +0100 Subject: [PATCH 111/127] remove duplicate library reference --- CoreLibs/nbproject/project.properties | 3 --- 1 file changed, 3 deletions(-) diff --git a/CoreLibs/nbproject/project.properties b/CoreLibs/nbproject/project.properties index b7db1fe07c..4218ccab88 100755 --- a/CoreLibs/nbproject/project.properties +++ b/CoreLibs/nbproject/project.properties @@ -54,7 +54,6 @@ file.reference.joda-time-2.4-sources.jar=release/modules/ext/joda-time-2.4-sourc file.reference.joda-time-2.4.jar=release/modules/ext/joda-time-2.4.jar file.reference.jsr305-1.3.9.jar=release/modules/ext/jsr305-1.3.9.jar file.reference.LGoodDatePicker-10.3.1.jar=release/modules/ext/LGoodDatePicker-10.3.1.jar -file.reference.LGoodDatePicker-4.3.1.jar=release/modules/ext/LGoodDatePicker-10.3.1.jar file.reference.log4j-1.2.17.jar=release/modules/ext/log4j-1.2.17.jar file.reference.logkit-1.0.1.jar=release/modules/ext/logkit-1.0.1.jar file.reference.mail-1.4.3.jar=release/modules/ext/mail-1.4.3.jar @@ -85,7 +84,6 @@ javadoc.reference.jfxtras-common-8.0-r4.jar=release/modules/ext/jfxtras-common-8 javadoc.reference.jfxtras-controls-8.0-r4.jar=release/modules/ext/jfxtras-controls-8.0-r4-javadoc.jar javadoc.reference.jfxtras-fxml-8.0-r4.jar=release/modules/ext/jfxtras-fxml-8.0-r4-javadoc.jar javadoc.reference.LGoodDatePicker-10.3.1.jar=release/modules/ext/LGoodDatePicker-10.3.1-javadoc.jar -javadoc.reference.LGoodDatePicker-4.3.1.jar=release/modules/ext/LGoodDatePicker-10.3.1-javadoc.jar nbm.needs.restart=true source.reference.commons-csv-1.4.jar=release/modules/ext/commons-csv-1.4-sources.jar source.reference.commons-io-2.5.jar=release/modules/ext/commons-io-2.5-sources.jar @@ -96,4 +94,3 @@ source.reference.jfxtras-common-8.0-r4.jar=release/modules/ext/jfxtras-common-8. source.reference.jfxtras-controls-8.0-r4.jar=release/modules/ext/jfxtras-controls-8.0-r4-sources.jar source.reference.jfxtras-fxml-8.0-r4.jar=release/modules/ext/jfxtras-fxml-8.0-r4-sources.jar source.reference.LGoodDatePicker-10.3.1.jar=release/modules/ext/LGoodDatePicker-10.3.1-sources.jar -source.reference.LGoodDatePicker-4.3.1.jar=release/modules/ext/LGoodDatePicker-10.3.1-sources.jar From f47edb131e76c61e63fdb5a3aa38c705c8d1cb4a Mon Sep 17 00:00:00 2001 From: millmanorama Date: Mon, 20 Nov 2017 14:57:44 +0100 Subject: [PATCH 112/127] change to ChildFactory, do CommunicationsManager calls off the EDT --- .../communications/AccountDetailsNode.java | 37 ++++---- .../AccountDeviceInstanceKey.java | 14 ++- .../communications/AccountsRootChildren.java | 92 +++++++++---------- .../autopsy/communications/FiltersPanel.form | 12 +-- .../autopsy/communications/FiltersPanel.java | 35 ++++--- .../communications/MessageBrowser.java | 33 ++++++- 6 files changed, 135 insertions(+), 88 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/communications/AccountDetailsNode.java b/Core/src/org/sleuthkit/autopsy/communications/AccountDetailsNode.java index ac93209b8b..5136ed2843 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/AccountDetailsNode.java +++ b/Core/src/org/sleuthkit/autopsy/communications/AccountDetailsNode.java @@ -18,17 +18,16 @@ */ package org.sleuthkit.autopsy.communications; +import java.util.List; import java.util.Set; -import java.util.logging.Level; import org.openide.nodes.AbstractNode; +import org.openide.nodes.ChildFactory; import org.openide.nodes.Children; import org.openide.nodes.Node; import org.sleuthkit.autopsy.coreutils.Logger; -import org.sleuthkit.datamodel.AccountDeviceInstance; import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.CommunicationsFilter; import org.sleuthkit.datamodel.CommunicationsManager; -import org.sleuthkit.datamodel.TskCoreException; /** * 'Root' Node for the Account/Messages area. Has children which are all the @@ -39,37 +38,43 @@ class AccountDetailsNode extends AbstractNode { private final static Logger logger = Logger.getLogger(AccountDetailsNode.class.getName()); - AccountDetailsNode(Set accountDeviceInstances, CommunicationsFilter filter, CommunicationsManager commsManager) { - super(new AccountRelationshipChildren(accountDeviceInstances, commsManager, filter)); + AccountDetailsNode(Set accountDeviceInstances, CommunicationsFilter filter, CommunicationsManager commsManager) { + super(Children.create(new AccountRelationshipChildren(accountDeviceInstances, commsManager, filter), true)); } /** * Children object for the relationships that the accounts are part of. */ - private static class AccountRelationshipChildren extends Children.Keys { + private static class AccountRelationshipChildren extends ChildFactory { - private final Set accountDeviceInstances; + private final Set accountDeviceInstances; private final CommunicationsManager commsManager; private final CommunicationsFilter filter; - private AccountRelationshipChildren(Set accountDeviceInstances, CommunicationsManager commsManager, CommunicationsFilter filter) { + private AccountRelationshipChildren(Set accountDeviceInstances, CommunicationsManager commsManager, CommunicationsFilter filter) { this.accountDeviceInstances = accountDeviceInstances; this.commsManager = commsManager; this.filter = filter; } @Override - protected Node[] createNodes(BlackboardArtifact key) { - return new Node[]{new RelationShipNode(key)}; + protected boolean createKeys(List list) { + list.addAll(accountDeviceInstances); + return true; } @Override - protected void addNotify() { - try { - setKeys(commsManager.getCommunications(accountDeviceInstances, filter)); - } catch (TskCoreException ex) { - logger.log(Level.WARNING, "Error loading communications for accounts. ", ex); - } + protected Node createNodeForKey(BlackboardArtifact t) { + return new RelationShipNode(t); //To change body of generated methods, choose Tools | Templates. } + +// @Override +// protected Node[] createNodes(BlackboardArtifact key) { +// return new Node[]{new RelationShipNode(key)}; +// } +// @Override +// protected void addNotify() { +// setKeys(accountDeviceInstances); +// } } } diff --git a/Core/src/org/sleuthkit/autopsy/communications/AccountDeviceInstanceKey.java b/Core/src/org/sleuthkit/autopsy/communications/AccountDeviceInstanceKey.java index b2df68c542..9078d7c0b6 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/AccountDeviceInstanceKey.java +++ b/Core/src/org/sleuthkit/autopsy/communications/AccountDeviceInstanceKey.java @@ -23,17 +23,21 @@ import org.sleuthkit.datamodel.CommunicationsFilter; /** * Key for AccountDeviceInstance node. - * + * * Encapsulates a AccountDeviceInstance, and CommunicationsFilter. */ -public class AccountDeviceInstanceKey { +class AccountDeviceInstanceKey { private final AccountDeviceInstance accountDeviceInstance; private final CommunicationsFilter filter; + private final long messageCount; - AccountDeviceInstanceKey(AccountDeviceInstance accountDeviceInstance, CommunicationsFilter filter) { + + + AccountDeviceInstanceKey(AccountDeviceInstance accountDeviceInstance, CommunicationsFilter filter, long msgCount) { this.accountDeviceInstance = accountDeviceInstance; this.filter = filter; + this.messageCount = msgCount; } AccountDeviceInstance getAccountDeviceInstance() { @@ -43,4 +47,8 @@ public class AccountDeviceInstanceKey { CommunicationsFilter getCommunicationsFilter() { return filter; } + + long getMessageCount() { + return messageCount; + } } diff --git a/Core/src/org/sleuthkit/autopsy/communications/AccountsRootChildren.java b/Core/src/org/sleuthkit/autopsy/communications/AccountsRootChildren.java index d0a43b3c84..a6938008d6 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/AccountsRootChildren.java +++ b/Core/src/org/sleuthkit/autopsy/communications/AccountsRootChildren.java @@ -18,59 +18,59 @@ */ package org.sleuthkit.autopsy.communications; -import java.util.Collections; import java.util.List; -import java.util.logging.Level; import java.util.logging.Logger; import org.openide.nodes.AbstractNode; +import org.openide.nodes.ChildFactory; import org.openide.nodes.Children; import org.openide.nodes.Node; import org.openide.nodes.Sheet; import org.openide.util.NbBundle; import org.openide.util.lookup.Lookups; import org.sleuthkit.autopsy.datamodel.NodeProperty; +import org.sleuthkit.datamodel.Account; import org.sleuthkit.datamodel.AccountDeviceInstance; import org.sleuthkit.datamodel.CommunicationsFilter; import org.sleuthkit.datamodel.CommunicationsManager; -import org.sleuthkit.datamodel.TskCoreException; -class AccountsRootChildren extends Children.Keys { +class AccountsRootChildren extends ChildFactory { private final List accountDeviceInstanceKeys; private final CommunicationsManager commsManager; AccountsRootChildren(List accountDeviceInstanceKeys, CommunicationsManager commsManager) { - super(true); + super(); this.accountDeviceInstanceKeys = accountDeviceInstanceKeys; this.commsManager = commsManager; } - - @Override - protected void removeNotify() { - super.removeNotify(); - setKeys(Collections.emptySet()); - } - - @Override - protected void addNotify() { - super.addNotify(); - setKeys(accountDeviceInstanceKeys); - } - +//these are the methods for Children.Keys +// @Override +// protected void removeNotify() { +// super.removeNotify(); +// setKeys(Collections.emptySet()); +// } +// +// @Override +// protected void addNotify() { +// super.addNotify(); +// setKeys(accountDeviceInstanceKeys); +// } + // @Override +// protected Node[] createNodes(AccountDeviceInstanceKey key) { +// return new Node[]{new AccountDeviceInstanceNode(key, commsManager)}; +// } + + //These are the methods for ChildFactory. I am going to keep them around but commented until we make a final descision. - // @Override - // protected boolean createKeys(List list) { - // list.addAll(accounts); - // return true; - // } - // - // @Override - // protected Node createNodeForKey(Account key) { - // return new AccountDeviceInstanceNode(key); - // } @Override - protected Node[] createNodes(AccountDeviceInstanceKey key) { - return new Node[]{new AccountDeviceInstanceNode(key, commsManager)}; + protected boolean createKeys(List list) { + list.addAll(accountDeviceInstanceKeys); + return true; + } + + @Override + protected Node createNodeForKey(AccountDeviceInstanceKey key) { + return new AccountDeviceInstanceNode(key, commsManager); } /** @@ -79,21 +79,21 @@ class AccountsRootChildren extends Children.Keys { static class AccountDeviceInstanceNode extends AbstractNode { private static final Logger LOGGER = Logger.getLogger(AccountDeviceInstanceNode.class.getName()); - private final AccountDeviceInstance accountDeviceInstance; + private final AccountDeviceInstanceKey accountDeviceInstanceKey; private final CommunicationsManager commsManager; - private final CommunicationsFilter filter; + private final Account account; private AccountDeviceInstanceNode(AccountDeviceInstanceKey accountDeviceInstanceKey, CommunicationsManager commsManager) { super(Children.LEAF, Lookups.fixed(accountDeviceInstanceKey, commsManager)); - this.accountDeviceInstance = accountDeviceInstanceKey.getAccountDeviceInstance(); + this.accountDeviceInstanceKey = accountDeviceInstanceKey; this.commsManager = commsManager; - this.filter = accountDeviceInstanceKey.getCommunicationsFilter(); - setName(accountDeviceInstance.getAccount().getAccountUniqueID()); - setIconBaseWithExtension("org/sleuthkit/autopsy/communications/images/" + Utils.getIconFileName(accountDeviceInstance.getAccount().getAccountType())); + this.account = accountDeviceInstanceKey.getAccountDeviceInstance().getAccount(); + setName(account.getAccountUniqueID()); + setIconBaseWithExtension("org/sleuthkit/autopsy/communications/images/" + Utils.getIconFileName(account.getAccountType())); } public AccountDeviceInstance getAccountDeviceInstance() { - return accountDeviceInstance; + return accountDeviceInstanceKey.getAccountDeviceInstance(); } public CommunicationsManager getCommsManager() { @@ -101,7 +101,7 @@ class AccountsRootChildren extends Children.Keys { } public CommunicationsFilter getFilter() { - return filter; + return accountDeviceInstanceKey.getCommunicationsFilter(); } @Override @@ -116,15 +116,13 @@ class AccountsRootChildren extends Children.Keys { properties = Sheet.createPropertiesSet(); s.put(properties); } - long msgCount = 0; - try { - msgCount = commsManager.getCommunicationsCount(accountDeviceInstance, filter ); - } catch (TskCoreException ex) { - LOGGER.log(Level.WARNING, "Failed to get message count for account", ex); //NON-NLS - } - properties.put(new NodeProperty<>("type", Bundle.AccountNode_accountType(), "type", accountDeviceInstance.getAccount().getAccountType().getDisplayName())); // NON-NLS - properties.put(new NodeProperty<>("count", Bundle.AccountNode_messageCount(), "count", msgCount)); // NON-NLS - properties.put(new NodeProperty<>("device", Bundle.AccountNode_device(), "device", accountDeviceInstance.getDeviceId())); // NON-NLS + + properties.put(new NodeProperty<>("type", Bundle.AccountNode_accountType(), "type", + account.getAccountType().getDisplayName())); // NON-NLS + properties.put(new NodeProperty<>("count", Bundle.AccountNode_messageCount(), "count", + accountDeviceInstanceKey.getMessageCount())); // NON-NLS + properties.put(new NodeProperty<>("device", Bundle.AccountNode_device(), "device", + accountDeviceInstanceKey.getAccountDeviceInstance().getDeviceId())); // NON-NLS return s; } } diff --git a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.form b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.form index 023193d488..911ca2eca4 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.form +++ b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.form @@ -68,15 +68,15 @@
- - - + + + @@ -271,13 +271,13 @@
- + - + - +
diff --git a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java index e7d17ecf71..93dc713468 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java +++ b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java @@ -21,6 +21,7 @@ package org.sleuthkit.autopsy.communications; import java.awt.Cursor; import java.time.LocalDate; import java.time.ZoneId; +import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -32,10 +33,12 @@ import javax.swing.JCheckBox; import javax.swing.SwingWorker; import org.openide.explorer.ExplorerManager; import org.openide.nodes.AbstractNode; +import org.openide.nodes.Children; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.ThreadConfined; import org.sleuthkit.datamodel.Account; +import org.sleuthkit.datamodel.AccountDeviceInstance; import org.sleuthkit.datamodel.AccountTypeFilter; import org.sleuthkit.datamodel.CommunicationsFilter; import org.sleuthkit.datamodel.CommunicationsManager; @@ -53,7 +56,6 @@ final public class FiltersPanel extends javax.swing.JPanel { private static final Logger logger = Logger.getLogger(FiltersPanel.class.getName()); private static final long serialVersionUID = 1L; -// private static final DateFormat DATE_FORMAT = new SimpleDateFormat("MM/dd/yyyy"); private ExplorerManager em; @ThreadConfined(type = ThreadConfined.ThreadType.AWT) @@ -67,8 +69,6 @@ final public class FiltersPanel extends javax.swing.JPanel { endDatePicker.setDateToToday(); startDatePicker.getSettings().setVetoPolicy( //no end date, or start is before end - - startDate -> endCheckBox.isSelected() == false || startDate.compareTo(endDatePicker.getDate()) <= 0 ); @@ -77,16 +77,15 @@ final public class FiltersPanel extends javax.swing.JPanel { endDate -> startCheckBox.isSelected() == false || endDate.compareTo(startDatePicker.getDate()) >= 0 ); - applyFiltersButton.addActionListener(actionEvent -> applyFilters()); + applyFiltersButton.addActionListener(actionEvent -> applyFilters()); } /** * Update the filter widgets, and apply them. */ void updateAndApplyFilters() { - updateAccountTypeFilter(); - updateDeviceFilter(); + updateFilters(); if (em != null) { applyFilters(); } @@ -94,6 +93,11 @@ final public class FiltersPanel extends javax.swing.JPanel { dateRangeLabel.setText("Date Range ( " + Utils.getUserPreferredZoneId().getId() + "):"); } + private void updateFilters() { + updateAccountTypeFilter(); + updateDeviceFilter(); + } + @Override public void addNotify() { super.addNotify(); @@ -312,10 +316,10 @@ final public class FiltersPanel extends javax.swing.JPanel { .addComponent(startCheckBox) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(startDatePicker, javax.swing.GroupLayout.PREFERRED_SIZE, 162, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addGroup(jPanel4Layout.createSequentialGroup() + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel4Layout.createSequentialGroup() .addComponent(endCheckBox) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(endDatePicker, javax.swing.GroupLayout.PREFERRED_SIZE, 161, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addComponent(endDatePicker, javax.swing.GroupLayout.PREFERRED_SIZE, 163, javax.swing.GroupLayout.PREFERRED_SIZE))) .addGap(0, 0, 0)) ); jPanel4Layout.setVerticalGroup( @@ -377,16 +381,18 @@ final public class FiltersPanel extends javax.swing.JPanel { try { final CommunicationsManager commsManager = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager(); + + getRootPane().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); new SwingWorker() { @Override protected AbstractNode doInBackground() throws Exception { - List accountDeviceInstanceKeys = - commsManager.getAccountDeviceInstancesWithCommunications(commsFilter) - .stream() - .map(adi -> new AccountDeviceInstanceKey(adi, commsFilter)) - .collect(Collectors.toList()); - return new AbstractNode(new AccountsRootChildren(accountDeviceInstanceKeys, commsManager)); + List accountDeviceInstanceKeys = new ArrayList<>(); + for (AccountDeviceInstance adi : commsManager.getAccountDeviceInstancesWithCommunications(commsFilter)) { + long communicationsCount = commsManager.getCommunicationsCount(adi, commsFilter); + accountDeviceInstanceKeys.add(new AccountDeviceInstanceKey(adi, commsFilter, communicationsCount)); + }; + return new AbstractNode(Children.create(new AccountsRootChildren(accountDeviceInstanceKeys, commsManager), true)); } @Override @@ -394,6 +400,7 @@ final public class FiltersPanel extends javax.swing.JPanel { super.done(); //To change body of generated methods, choose Tools | Templates. setCursor(Cursor.getDefaultCursor()); + getRootPane().setCursor(Cursor.getDefaultCursor()); try { em.setRootContext(get()); } catch (InterruptedException | ExecutionException ex) { diff --git a/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.java b/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.java index c4c6e91fe8..73962e9214 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.java +++ b/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.java @@ -18,17 +18,23 @@ */ package org.sleuthkit.autopsy.communications; +import java.awt.Cursor; import java.util.Collections; import java.util.Set; +import java.util.concurrent.ExecutionException; +import java.util.logging.Level; import java.util.stream.Collectors; import java.util.stream.Stream; +import javax.swing.SwingWorker; import org.openide.explorer.ExplorerManager; import org.openide.nodes.Node; import org.sleuthkit.autopsy.communications.AccountsRootChildren.AccountDeviceInstanceNode; import org.sleuthkit.autopsy.corecomponents.DataResultPanel; import org.sleuthkit.autopsy.corecomponents.DataResultViewerTable; import org.sleuthkit.autopsy.corecomponents.TableFilterNode; +import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.datamodel.AccountDeviceInstance; +import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.CommunicationsFilter; import org.sleuthkit.datamodel.CommunicationsManager; @@ -40,6 +46,8 @@ final class MessageBrowser extends javax.swing.JPanel implements ExplorerManager private static final long serialVersionUID = 1L; + private static final Logger logger = Logger.getLogger(MessageBrowser.class.getName()); + private final DataResultPanel messagesResultPanel; private final ExplorerManager explorerManager = new ExplorerManager(); private final DataResultViewerTable dataResultViewerTable = new DataResultViewerTable(explorerManager, "Messages"); @@ -84,8 +92,29 @@ final class MessageBrowser extends javax.swing.JPanel implements ExplorerManager .collect(Collectors.toSet()); messagesResultPanel.setPath(selectedNodes.length + " accounts"); } - messagesResultPanel.setNode(new TableFilterNode( - new AccountDetailsNode(collect, filter, commsManager), true)); + messagesResultPanel.setNumMatches(0); + messagesResultPanel.setNode(null); + getRootPane().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); + new SwingWorker, Void>() { + @Override + protected Set doInBackground() throws Exception { + return commsManager.getCommunications(collect, filter); + } + + @Override + protected void done() { + super.done(); //To change body of generated methods, choose Tools | Templates. + try { + messagesResultPanel.setNode(new TableFilterNode( + new AccountDetailsNode(get(), filter, commsManager), true)); + } catch (InterruptedException | ExecutionException ex) { + logger.log(Level.SEVERE, "Error getting relationships", ex); + } + getRootPane().setCursor(Cursor.getDefaultCursor()); + + } + }.execute(); + } } }); From 3cb5583e4f613450b9ea5809be56ff441417e689 Mon Sep 17 00:00:00 2001 From: millmanorama Date: Mon, 20 Nov 2017 15:25:42 +0100 Subject: [PATCH 113/127] wrap nodes in DataResiltFilterNodes to get more actions automatically --- .../org/sleuthkit/autopsy/communications/MessageBrowser.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.java b/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.java index c4c6e91fe8..ad48e11103 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.java +++ b/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.java @@ -28,6 +28,7 @@ import org.sleuthkit.autopsy.communications.AccountsRootChildren.AccountDeviceIn import org.sleuthkit.autopsy.corecomponents.DataResultPanel; import org.sleuthkit.autopsy.corecomponents.DataResultViewerTable; import org.sleuthkit.autopsy.corecomponents.TableFilterNode; +import org.sleuthkit.autopsy.directorytree.DataResultFilterNode; import org.sleuthkit.datamodel.AccountDeviceInstance; import org.sleuthkit.datamodel.CommunicationsFilter; import org.sleuthkit.datamodel.CommunicationsManager; @@ -84,8 +85,8 @@ final class MessageBrowser extends javax.swing.JPanel implements ExplorerManager .collect(Collectors.toSet()); messagesResultPanel.setPath(selectedNodes.length + " accounts"); } - messagesResultPanel.setNode(new TableFilterNode( - new AccountDetailsNode(collect, filter, commsManager), true)); + messagesResultPanel.setNode(new TableFilterNode(new DataResultFilterNode( + new AccountDetailsNode(collect, filter, commsManager), parentExplorereManager), true)); } } }); From 65b947bafacfca5383452a89a08d6bc241603700 Mon Sep 17 00:00:00 2001 From: millmanorama Date: Mon, 20 Nov 2017 21:10:00 +0100 Subject: [PATCH 114/127] restore wrapping in DataResultFilterNode --- .../org/sleuthkit/autopsy/communications/MessageBrowser.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.java b/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.java index c13520015b..eeeaa6cc81 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.java +++ b/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.java @@ -33,6 +33,7 @@ import org.sleuthkit.autopsy.corecomponents.DataResultPanel; import org.sleuthkit.autopsy.corecomponents.DataResultViewerTable; import org.sleuthkit.autopsy.corecomponents.TableFilterNode; import org.sleuthkit.autopsy.coreutils.Logger; +import org.sleuthkit.autopsy.directorytree.DataResultFilterNode; import org.sleuthkit.datamodel.AccountDeviceInstance; import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.CommunicationsFilter; @@ -105,8 +106,8 @@ final class MessageBrowser extends javax.swing.JPanel implements ExplorerManager protected void done() { super.done(); //To change body of generated methods, choose Tools | Templates. try { - messagesResultPanel.setNode(new TableFilterNode( - new AccountDetailsNode(get(), filter, commsManager), true)); + messagesResultPanel.setNode(new TableFilterNode(new DataResultFilterNode( + new AccountDetailsNode(get(), filter, commsManager), parentExplorereManager), true)); } catch (InterruptedException | ExecutionException ex) { logger.log(Level.SEVERE, "Error getting relationships", ex); } From 54a77d25a470ee92bbc19caec97f3a44f70a2e56 Mon Sep 17 00:00:00 2001 From: Brian Carrier Date: Mon, 20 Nov 2017 15:12:04 -0500 Subject: [PATCH 115/127] revert to old way of rejecting --- .../sleuthkit/autopsy/datamodel/accounts/Accounts.java | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/accounts/Accounts.java b/Core/src/org/sleuthkit/autopsy/datamodel/accounts/Accounts.java index 531598ad65..3e60b9b5d7 100755 --- a/Core/src/org/sleuthkit/autopsy/datamodel/accounts/Accounts.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/accounts/Accounts.java @@ -1428,15 +1428,7 @@ final public class Accounts implements AutopsyVisitableItem { final Collection artifacts = Utilities.actionsGlobalContext().lookupAll(BlackboardArtifact.class); artifacts.forEach(artifact -> { try { - AccountFileInstance accountInstance = skCase.getCommunicationsManager().getAccountFileInstance(artifact); - - if (BlackboardArtifact.ReviewStatus.APPROVED == newStatus) { - accountInstance.approveAccount(); - } - else { - accountInstance.rejectAccount(); - } - + skCase.setReviewStatus(artifact, newStatus); } catch (TskCoreException ex) { LOGGER.log(Level.SEVERE, "Error changing artifact review status.", ex); //NON-NLS } From 2640ab926c547b602332ac5173884aed51434501 Mon Sep 17 00:00:00 2001 From: millmanorama Date: Mon, 20 Nov 2017 22:30:14 +0100 Subject: [PATCH 116/127] simplify nodes by relying n asynchronous children instead of the SwingWorkers. --- .../communications/AccountDetailsNode.java | 26 +++++----- .../communications/AccountsRootChildren.java | 44 ++++++++--------- .../autopsy/communications/FiltersPanel.java | 38 +-------------- .../communications/MessageBrowser.java | 48 ++++++------------- .../autopsy/communications/Utils.java | 7 +-- 5 files changed, 52 insertions(+), 111 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/communications/AccountDetailsNode.java b/Core/src/org/sleuthkit/autopsy/communications/AccountDetailsNode.java index 5136ed2843..25a87924d8 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/AccountDetailsNode.java +++ b/Core/src/org/sleuthkit/autopsy/communications/AccountDetailsNode.java @@ -20,14 +20,17 @@ package org.sleuthkit.autopsy.communications; import java.util.List; import java.util.Set; +import java.util.logging.Level; import org.openide.nodes.AbstractNode; import org.openide.nodes.ChildFactory; import org.openide.nodes.Children; import org.openide.nodes.Node; import org.sleuthkit.autopsy.coreutils.Logger; +import org.sleuthkit.datamodel.AccountDeviceInstance; import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.CommunicationsFilter; import org.sleuthkit.datamodel.CommunicationsManager; +import org.sleuthkit.datamodel.TskCoreException; /** * 'Root' Node for the Account/Messages area. Has children which are all the @@ -38,7 +41,7 @@ class AccountDetailsNode extends AbstractNode { private final static Logger logger = Logger.getLogger(AccountDetailsNode.class.getName()); - AccountDetailsNode(Set accountDeviceInstances, CommunicationsFilter filter, CommunicationsManager commsManager) { + AccountDetailsNode(Set accountDeviceInstances, CommunicationsFilter filter, CommunicationsManager commsManager) { super(Children.create(new AccountRelationshipChildren(accountDeviceInstances, commsManager, filter), true)); } @@ -47,11 +50,11 @@ class AccountDetailsNode extends AbstractNode { */ private static class AccountRelationshipChildren extends ChildFactory { - private final Set accountDeviceInstances; + private final Set accountDeviceInstances; private final CommunicationsManager commsManager; private final CommunicationsFilter filter; - private AccountRelationshipChildren(Set accountDeviceInstances, CommunicationsManager commsManager, CommunicationsFilter filter) { + private AccountRelationshipChildren(Set accountDeviceInstances, CommunicationsManager commsManager, CommunicationsFilter filter) { this.accountDeviceInstances = accountDeviceInstances; this.commsManager = commsManager; this.filter = filter; @@ -59,22 +62,17 @@ class AccountDetailsNode extends AbstractNode { @Override protected boolean createKeys(List list) { - list.addAll(accountDeviceInstances); + try { + list.addAll(commsManager.getCommunications(accountDeviceInstances, filter)); + } catch (TskCoreException ex) { + logger.log(Level.SEVERE, "Error getting communications", ex); + } return true; } @Override protected Node createNodeForKey(BlackboardArtifact t) { - return new RelationShipNode(t); //To change body of generated methods, choose Tools | Templates. + return new RelationShipNode(t); } - -// @Override -// protected Node[] createNodes(BlackboardArtifact key) { -// return new Node[]{new RelationShipNode(key)}; -// } -// @Override -// protected void addNotify() { -// setKeys(accountDeviceInstances); -// } } } diff --git a/Core/src/org/sleuthkit/autopsy/communications/AccountsRootChildren.java b/Core/src/org/sleuthkit/autopsy/communications/AccountsRootChildren.java index a6938008d6..7fe3413e2d 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/AccountsRootChildren.java +++ b/Core/src/org/sleuthkit/autopsy/communications/AccountsRootChildren.java @@ -18,7 +18,9 @@ */ package org.sleuthkit.autopsy.communications; +import java.util.ArrayList; import java.util.List; +import java.util.logging.Level; import java.util.logging.Logger; import org.openide.nodes.AbstractNode; import org.openide.nodes.ChildFactory; @@ -32,39 +34,34 @@ import org.sleuthkit.datamodel.Account; import org.sleuthkit.datamodel.AccountDeviceInstance; import org.sleuthkit.datamodel.CommunicationsFilter; import org.sleuthkit.datamodel.CommunicationsManager; +import org.sleuthkit.datamodel.TskCoreException; class AccountsRootChildren extends ChildFactory { - private final List accountDeviceInstanceKeys; - private final CommunicationsManager commsManager; + private static final Logger logger = Logger.getLogger(AccountsRootChildren.class.getName()); - AccountsRootChildren(List accountDeviceInstanceKeys, CommunicationsManager commsManager) { + private final CommunicationsManager commsManager; + private final CommunicationsFilter commsFilter; + + AccountsRootChildren(CommunicationsManager commsManager, CommunicationsFilter commsFilter) { super(); - this.accountDeviceInstanceKeys = accountDeviceInstanceKeys; this.commsManager = commsManager; + this.commsFilter = commsFilter; } -//these are the methods for Children.Keys -// @Override -// protected void removeNotify() { -// super.removeNotify(); -// setKeys(Collections.emptySet()); -// } -// -// @Override -// protected void addNotify() { -// super.addNotify(); -// setKeys(accountDeviceInstanceKeys); -// } - // @Override -// protected Node[] createNodes(AccountDeviceInstanceKey key) { -// return new Node[]{new AccountDeviceInstanceNode(key, commsManager)}; -// } - - - //These are the methods for ChildFactory. I am going to keep them around but commented until we make a final descision. + @Override protected boolean createKeys(List list) { + List accountDeviceInstanceKeys = new ArrayList<>(); + try { + for (AccountDeviceInstance adi : commsManager.getAccountDeviceInstancesWithCommunications(commsFilter)) { + long communicationsCount = commsManager.getCommunicationsCount(adi, commsFilter); + accountDeviceInstanceKeys.add(new AccountDeviceInstanceKey(adi, commsFilter, communicationsCount)); + }; + } catch (TskCoreException tskCoreException) { + logger.log(Level.SEVERE, "Error getting filtered account device instances", tskCoreException); + } list.addAll(accountDeviceInstanceKeys); + return true; } @@ -78,7 +75,6 @@ class AccountsRootChildren extends ChildFactory { */ static class AccountDeviceInstanceNode extends AbstractNode { - private static final Logger LOGGER = Logger.getLogger(AccountDeviceInstanceNode.class.getName()); private final AccountDeviceInstanceKey accountDeviceInstanceKey; private final CommunicationsManager commsManager; private final Account account; diff --git a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java index f0b451a586..754bc14b3b 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java +++ b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java @@ -18,21 +18,16 @@ */ package org.sleuthkit.autopsy.communications; -import java.awt.Cursor; import java.beans.PropertyChangeListener; import java.time.LocalDate; import java.time.ZoneId; -import java.util.ArrayList; import java.util.EnumSet; import java.util.HashMap; -import java.util.List; import java.util.Map; import java.util.Map.Entry; -import java.util.concurrent.ExecutionException; import java.util.logging.Level; import java.util.stream.Collectors; import javax.swing.JCheckBox; -import javax.swing.SwingWorker; import org.openide.explorer.ExplorerManager; import org.openide.nodes.AbstractNode; import org.openide.nodes.Children; @@ -45,7 +40,6 @@ import org.sleuthkit.autopsy.coreutils.ThreadConfined; import org.sleuthkit.autopsy.ingest.IngestManager; import static org.sleuthkit.autopsy.ingest.IngestManager.IngestModuleEvent.DATA_ADDED; import org.sleuthkit.datamodel.Account; -import org.sleuthkit.datamodel.AccountDeviceInstance; import org.sleuthkit.datamodel.AccountTypeFilter; import org.sleuthkit.datamodel.CommunicationsFilter; import org.sleuthkit.datamodel.CommunicationsManager; @@ -69,8 +63,7 @@ final public class FiltersPanel extends javax.swing.JPanel { private final Map accountTypeMap = new HashMap<>(); @ThreadConfined(type = ThreadConfined.ThreadType.AWT) private final Map devicesMap = new HashMap<>(); - - + private final PropertyChangeListener ingestListener; @NbBundle.Messages({"refreshText=Refresh Results", @@ -124,7 +117,6 @@ final public class FiltersPanel extends javax.swing.JPanel { dateRangeLabel.setText("Date Range ( " + Utils.getUserPreferredZoneId().toString() + "):"); } - private void updateFilters() { updateAccountTypeFilter(); updateDeviceFilter(); @@ -433,33 +425,7 @@ final public class FiltersPanel extends javax.swing.JPanel { try { final CommunicationsManager commsManager = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager(); - - getRootPane().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); - setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); - new SwingWorker() { - @Override - protected AbstractNode doInBackground() throws Exception { - List accountDeviceInstanceKeys = new ArrayList<>(); - for (AccountDeviceInstance adi : commsManager.getAccountDeviceInstancesWithCommunications(commsFilter)) { - long communicationsCount = commsManager.getCommunicationsCount(adi, commsFilter); - accountDeviceInstanceKeys.add(new AccountDeviceInstanceKey(adi, commsFilter, communicationsCount)); - }; - return new AbstractNode(Children.create(new AccountsRootChildren(accountDeviceInstanceKeys, commsManager), true)); - } - - @Override - protected void done() { - super.done(); //To change body of generated methods, choose Tools | Templates. - - setCursor(Cursor.getDefaultCursor()); - getRootPane().setCursor(Cursor.getDefaultCursor()); - try { - em.setRootContext(get()); - } catch (InterruptedException | ExecutionException ex) { - logger.log(Level.SEVERE, "Error getting account device instances for filter: " + commsFilter, ex); - } - } - }.execute(); + em.setRootContext(new AbstractNode(Children.create(new AccountsRootChildren(commsManager, commsFilter), true))); } catch (TskCoreException ex) { logger.log(Level.SEVERE, "There was an error getting the CommunicationsManager for the current case.", ex); } diff --git a/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.java b/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.java index eeeaa6cc81..a06d5547f0 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.java +++ b/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.java @@ -18,24 +18,18 @@ */ package org.sleuthkit.autopsy.communications; -import java.awt.Cursor; import java.util.Collections; import java.util.Set; -import java.util.concurrent.ExecutionException; -import java.util.logging.Level; import java.util.stream.Collectors; import java.util.stream.Stream; -import javax.swing.SwingWorker; import org.openide.explorer.ExplorerManager; import org.openide.nodes.Node; import org.sleuthkit.autopsy.communications.AccountsRootChildren.AccountDeviceInstanceNode; import org.sleuthkit.autopsy.corecomponents.DataResultPanel; import org.sleuthkit.autopsy.corecomponents.DataResultViewerTable; import org.sleuthkit.autopsy.corecomponents.TableFilterNode; -import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.directorytree.DataResultFilterNode; import org.sleuthkit.datamodel.AccountDeviceInstance; -import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.CommunicationsFilter; import org.sleuthkit.datamodel.CommunicationsManager; @@ -47,7 +41,6 @@ final class MessageBrowser extends javax.swing.JPanel implements ExplorerManager private static final long serialVersionUID = 1L; - private static final Logger logger = Logger.getLogger(MessageBrowser.class.getName()); private final DataResultPanel messagesResultPanel; private final ExplorerManager explorerManager = new ExplorerManager(); @@ -71,50 +64,35 @@ final class MessageBrowser extends javax.swing.JPanel implements ExplorerManager parentExplorereManager.addPropertyChangeListener(pce -> { if (pce.getPropertyName().equals(ExplorerManager.PROP_SELECTED_NODES)) { final Node[] selectedNodes = parentExplorereManager.getSelectedNodes(); + + messagesResultPanel.setNumMatches(0); + messagesResultPanel.setNode(null); + if (selectedNodes.length == 0) { //reset panel when there is no selection - messagesResultPanel.setNode(null); messagesResultPanel.setPath(""); - messagesResultPanel.setNumMatches(0); } else { AccountDeviceInstanceNode adiNode = (AccountDeviceInstanceNode) selectedNodes[0]; CommunicationsFilter filter = adiNode.getFilter(); CommunicationsManager commsManager = adiNode.getCommsManager(); - final Set collect; + final Set accountDeviceInstances; if (selectedNodes.length == 1) { final AccountDeviceInstance accountDeviceInstance = adiNode.getAccountDeviceInstance(); - collect = Collections.singleton(accountDeviceInstance); + accountDeviceInstances = Collections.singleton(accountDeviceInstance); messagesResultPanel.setPath(accountDeviceInstance.getAccount().getAccountUniqueID()); } else { - collect = Stream.of(selectedNodes) + accountDeviceInstances = Stream.of(selectedNodes) .map(node -> (AccountDeviceInstanceNode) node) .map(AccountDeviceInstanceNode::getAccountDeviceInstance) .collect(Collectors.toSet()); messagesResultPanel.setPath(selectedNodes.length + " accounts"); } - messagesResultPanel.setNumMatches(0); - messagesResultPanel.setNode(null); - getRootPane().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); - new SwingWorker, Void>() { - @Override - protected Set doInBackground() throws Exception { - return commsManager.getCommunications(collect, filter); - } - - @Override - protected void done() { - super.done(); //To change body of generated methods, choose Tools | Templates. - try { - messagesResultPanel.setNode(new TableFilterNode(new DataResultFilterNode( - new AccountDetailsNode(get(), filter, commsManager), parentExplorereManager), true)); - } catch (InterruptedException | ExecutionException ex) { - logger.log(Level.SEVERE, "Error getting relationships", ex); - } - getRootPane().setCursor(Cursor.getDefaultCursor()); - - } - }.execute(); + AccountDetailsNode accountDetailsNode = + new AccountDetailsNode(accountDeviceInstances, filter, commsManager); + TableFilterNode wrappedNode = + new TableFilterNode(new DataResultFilterNode(accountDetailsNode, parentExplorereManager), true); + messagesResultPanel.setNode(wrappedNode); } } }); @@ -126,6 +104,8 @@ final class MessageBrowser extends javax.swing.JPanel implements ExplorerManager messagesResultPanel.open(); } + + @Override public ExplorerManager getExplorerManager() { return explorerManager; diff --git a/Core/src/org/sleuthkit/autopsy/communications/Utils.java b/Core/src/org/sleuthkit/autopsy/communications/Utils.java index af8cd3f8b4..91dabf5678 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/Utils.java +++ b/Core/src/org/sleuthkit/autopsy/communications/Utils.java @@ -28,14 +28,14 @@ import org.sleuthkit.datamodel.Account; */ class Utils { + private Utils() { + } + static ZoneId getUserPreferredZoneId() { ZoneId zone = UserPreferences.displayTimesInLocalTime() ? ZoneOffset.systemDefault() : ZoneOffset.UTC; return zone; } - private Utils() { - } - /** * The file name of the icon for the given Account Type. Will not include * the path but will include the extension. @@ -68,4 +68,5 @@ class Utils { throw new IllegalArgumentException("Unknown Account.Type: " + type.getTypeName()); } } + } From 4269e6bc7c4e3814468c6b79dd2ee8952474461e Mon Sep 17 00:00:00 2001 From: millmanorama Date: Mon, 27 Nov 2017 12:32:41 +0100 Subject: [PATCH 117/127] correct import statements --- .../org/sleuthkit/autopsy/communications/FiltersPanel.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java index 754bc14b3b..4a1d232a1e 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java +++ b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java @@ -40,12 +40,12 @@ import org.sleuthkit.autopsy.coreutils.ThreadConfined; import org.sleuthkit.autopsy.ingest.IngestManager; import static org.sleuthkit.autopsy.ingest.IngestManager.IngestModuleEvent.DATA_ADDED; import org.sleuthkit.datamodel.Account; -import org.sleuthkit.datamodel.AccountTypeFilter; import org.sleuthkit.datamodel.CommunicationsFilter; +import org.sleuthkit.datamodel.CommunicationsFilter.AccountTypeFilter; +import org.sleuthkit.datamodel.CommunicationsFilter.DateRangeFilter; +import org.sleuthkit.datamodel.CommunicationsFilter.DeviceFilter; import org.sleuthkit.datamodel.CommunicationsManager; import org.sleuthkit.datamodel.DataSource; -import org.sleuthkit.datamodel.DateRangeFilter; -import org.sleuthkit.datamodel.DeviceFilter; import org.sleuthkit.datamodel.TskCoreException; /** From 22c53dd4f980d8c254f9958bfbfe04f10c1916d0 Mon Sep 17 00:00:00 2001 From: millmanorama Date: Wed, 29 Nov 2017 12:33:40 +0100 Subject: [PATCH 118/127] update to getTypeSpecificID --- .../autopsy/communications/AccountsRootChildren.java | 4 ++-- .../org/sleuthkit/autopsy/communications/MessageBrowser.java | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/communications/AccountsRootChildren.java b/Core/src/org/sleuthkit/autopsy/communications/AccountsRootChildren.java index 7fe3413e2d..34762c056c 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/AccountsRootChildren.java +++ b/Core/src/org/sleuthkit/autopsy/communications/AccountsRootChildren.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2011-2017 Basis Technology Corp. + * Copyright 2017 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -84,7 +84,7 @@ class AccountsRootChildren extends ChildFactory { this.accountDeviceInstanceKey = accountDeviceInstanceKey; this.commsManager = commsManager; this.account = accountDeviceInstanceKey.getAccountDeviceInstance().getAccount(); - setName(account.getAccountUniqueID()); + setName(account.getTypeSpecificID()); setIconBaseWithExtension("org/sleuthkit/autopsy/communications/images/" + Utils.getIconFileName(account.getAccountType())); } diff --git a/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.java b/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.java index a06d5547f0..af53f7c030 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.java +++ b/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2011-2017 Basis Technology Corp. + * Copyright 2017 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -80,7 +80,7 @@ final class MessageBrowser extends javax.swing.JPanel implements ExplorerManager if (selectedNodes.length == 1) { final AccountDeviceInstance accountDeviceInstance = adiNode.getAccountDeviceInstance(); accountDeviceInstances = Collections.singleton(accountDeviceInstance); - messagesResultPanel.setPath(accountDeviceInstance.getAccount().getAccountUniqueID()); + messagesResultPanel.setPath(accountDeviceInstance.getAccount().getTypeSpecificID()); } else { accountDeviceInstances = Stream.of(selectedNodes) .map(node -> (AccountDeviceInstanceNode) node) From fb21914e586b8678dd8b7ffd6644d48e4fe751db Mon Sep 17 00:00:00 2001 From: millmanorama Date: Wed, 29 Nov 2017 12:35:21 +0100 Subject: [PATCH 119/127] update copyright headers --- .../sleuthkit/autopsy/communications/AccountDetailsNode.java | 2 +- .../autopsy/communications/AccountDeviceInstanceKey.java | 2 +- .../org/sleuthkit/autopsy/communications/AccountsBrowser.java | 2 +- .../org/sleuthkit/autopsy/communications/CVTTopComponent.java | 2 +- Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java | 2 +- .../sleuthkit/autopsy/communications/MessageDataContent.java | 2 +- .../autopsy/communications/OpenCommVisualizationToolAction.java | 2 +- .../org/sleuthkit/autopsy/communications/RelationShipNode.java | 2 +- Core/src/org/sleuthkit/autopsy/communications/Utils.java | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/communications/AccountDetailsNode.java b/Core/src/org/sleuthkit/autopsy/communications/AccountDetailsNode.java index 25a87924d8..9b7a76e69f 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/AccountDetailsNode.java +++ b/Core/src/org/sleuthkit/autopsy/communications/AccountDetailsNode.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2011-2017 Basis Technology Corp. + * Copyright 2017 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/Core/src/org/sleuthkit/autopsy/communications/AccountDeviceInstanceKey.java b/Core/src/org/sleuthkit/autopsy/communications/AccountDeviceInstanceKey.java index 9078d7c0b6..92b6938ac0 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/AccountDeviceInstanceKey.java +++ b/Core/src/org/sleuthkit/autopsy/communications/AccountDeviceInstanceKey.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2011-2017 Basis Technology Corp. + * Copyright 2017 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/Core/src/org/sleuthkit/autopsy/communications/AccountsBrowser.java b/Core/src/org/sleuthkit/autopsy/communications/AccountsBrowser.java index b7162150f8..8e418d65fb 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/AccountsBrowser.java +++ b/Core/src/org/sleuthkit/autopsy/communications/AccountsBrowser.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2011-2017 Basis Technology Corp. + * Copyright 2017 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java b/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java index 9833903f9a..67e77b0f00 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java +++ b/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2011-2017 Basis Technology Corp. + * Copyright 2017 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java index 4a1d232a1e..13ecc22304 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java +++ b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2011-2017 Basis Technology Corp. + * Copyright 2017 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/Core/src/org/sleuthkit/autopsy/communications/MessageDataContent.java b/Core/src/org/sleuthkit/autopsy/communications/MessageDataContent.java index 4181103b38..1c4ea0f7b4 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/MessageDataContent.java +++ b/Core/src/org/sleuthkit/autopsy/communications/MessageDataContent.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2011-2017 Basis Technology Corp. + * Copyright 2017 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/Core/src/org/sleuthkit/autopsy/communications/OpenCommVisualizationToolAction.java b/Core/src/org/sleuthkit/autopsy/communications/OpenCommVisualizationToolAction.java index fe2b5afcbd..832926bc15 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/OpenCommVisualizationToolAction.java +++ b/Core/src/org/sleuthkit/autopsy/communications/OpenCommVisualizationToolAction.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2011-2017 Basis Technology Corp. + * Copyright 2017 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/Core/src/org/sleuthkit/autopsy/communications/RelationShipNode.java b/Core/src/org/sleuthkit/autopsy/communications/RelationShipNode.java index b122cb2ebd..5c060a262e 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/RelationShipNode.java +++ b/Core/src/org/sleuthkit/autopsy/communications/RelationShipNode.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2011-2017 Basis Technology Corp. + * Copyright 2017 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/Core/src/org/sleuthkit/autopsy/communications/Utils.java b/Core/src/org/sleuthkit/autopsy/communications/Utils.java index 91dabf5678..91ee1e9fdf 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/Utils.java +++ b/Core/src/org/sleuthkit/autopsy/communications/Utils.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2011-2017 Basis Technology Corp. + * Copyright 2017 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); From 802b73163f7937fb7355764e5c0bd82bbb5c1fc0 Mon Sep 17 00:00:00 2001 From: millmanorama Date: Thu, 30 Nov 2017 23:28:56 +0100 Subject: [PATCH 120/127] update to use RelationshipTypeFilter to exclude contacts --- .../sleuthkit/autopsy/communications/AccountDetailsNode.java | 2 +- .../autopsy/communications/AccountsRootChildren.java | 4 ++-- .../org/sleuthkit/autopsy/communications/FiltersPanel.java | 5 +++++ 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/communications/AccountDetailsNode.java b/Core/src/org/sleuthkit/autopsy/communications/AccountDetailsNode.java index 9b7a76e69f..69761aa12f 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/AccountDetailsNode.java +++ b/Core/src/org/sleuthkit/autopsy/communications/AccountDetailsNode.java @@ -63,7 +63,7 @@ class AccountDetailsNode extends AbstractNode { @Override protected boolean createKeys(List list) { try { - list.addAll(commsManager.getCommunications(accountDeviceInstances, filter)); + list.addAll(commsManager.getRelationshipSources(accountDeviceInstances, filter)); } catch (TskCoreException ex) { logger.log(Level.SEVERE, "Error getting communications", ex); } diff --git a/Core/src/org/sleuthkit/autopsy/communications/AccountsRootChildren.java b/Core/src/org/sleuthkit/autopsy/communications/AccountsRootChildren.java index 34762c056c..99f71275c7 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/AccountsRootChildren.java +++ b/Core/src/org/sleuthkit/autopsy/communications/AccountsRootChildren.java @@ -53,8 +53,8 @@ class AccountsRootChildren extends ChildFactory { protected boolean createKeys(List list) { List accountDeviceInstanceKeys = new ArrayList<>(); try { - for (AccountDeviceInstance adi : commsManager.getAccountDeviceInstancesWithCommunications(commsFilter)) { - long communicationsCount = commsManager.getCommunicationsCount(adi, commsFilter); + for (AccountDeviceInstance adi : commsManager.getAccountDeviceInstancesWithRelationships(commsFilter)) { + long communicationsCount = commsManager.getRelationshipSourcesCount(adi, commsFilter); accountDeviceInstanceKeys.add(new AccountDeviceInstanceKey(adi, commsFilter, communicationsCount)); }; } catch (TskCoreException tskCoreException) { diff --git a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java index 13ecc22304..1543149fd8 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java +++ b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java @@ -18,6 +18,7 @@ */ package org.sleuthkit.autopsy.communications; +import com.google.common.collect.ImmutableSet; import java.beans.PropertyChangeListener; import java.time.LocalDate; import java.time.ZoneId; @@ -46,6 +47,8 @@ import org.sleuthkit.datamodel.CommunicationsFilter.DateRangeFilter; import org.sleuthkit.datamodel.CommunicationsFilter.DeviceFilter; import org.sleuthkit.datamodel.CommunicationsManager; import org.sleuthkit.datamodel.DataSource; +import static org.sleuthkit.datamodel.Relationship.Type.CALL_LOG; +import static org.sleuthkit.datamodel.Relationship.Type.MESSAGE; import org.sleuthkit.datamodel.TskCoreException; /** @@ -422,6 +425,8 @@ final public class FiltersPanel extends javax.swing.JPanel { commsFilter.addAndFilter(getDeviceFilter()); commsFilter.addAndFilter(getAccountTypeFilter()); commsFilter.addAndFilter(getDateRangeFilter()); + commsFilter.addAndFilter(new CommunicationsFilter.RelationshipTypeFilter( + ImmutableSet.of(CALL_LOG, MESSAGE))); try { final CommunicationsManager commsManager = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager(); From e319cb1cdaa282808b1b7acc92db2658e651a70c Mon Sep 17 00:00:00 2001 From: millmanorama Date: Fri, 1 Dec 2017 11:19:00 +0100 Subject: [PATCH 121/127] update usages of addRelationships --- InternalPythonModules/android/calllog.py | 5 +++-- InternalPythonModules/android/contact.py | 5 +++-- InternalPythonModules/android/textmessage.py | 5 +++-- InternalPythonModules/android/wwfmessage.py | 5 +++-- .../ThunderbirdMboxFileIngestModule.java | 8 +++++--- 5 files changed, 17 insertions(+), 11 deletions(-) diff --git a/InternalPythonModules/android/calllog.py b/InternalPythonModules/android/calllog.py index 233e111871..6fa413884c 100755 --- a/InternalPythonModules/android/calllog.py +++ b/InternalPythonModules/android/calllog.py @@ -1,7 +1,7 @@ """ Autopsy Forensic Browser -Copyright 2016 Basis Technology Corp. +Copyright 2016-17 Basis Technology Corp. Contact: carrier sleuthkit org Licensed under the Apache License, Version 2.0 (the "License"); @@ -44,6 +44,7 @@ from org.sleuthkit.datamodel.BlackboardAttribute import ATTRIBUTE_TYPE from org.sleuthkit.datamodel import Content from org.sleuthkit.datamodel import TskCoreException from org.sleuthkit.datamodel import Account +from org.sleuthkit.datamodel import Relationship import traceback import general @@ -146,7 +147,7 @@ class CallLogAnalyzer(general.AndroidComponentAnalyzer): calllogAccountInstance = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().createAccountFileInstance(Account.Type.PHONE, number, general.MODULE_NAME, abstractFile); # create relationship between accounts - Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().addRelationships(deviceAccountInstance, [calllogAccountInstance], artifact, date); + Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().addRelationships(deviceAccountInstance, [calllogAccountInstance], artifact, Relationship.TYPE.CALL_LOG, date); bbartifacts.append(artifact) diff --git a/InternalPythonModules/android/contact.py b/InternalPythonModules/android/contact.py index c820a39e3f..8816412113 100755 --- a/InternalPythonModules/android/contact.py +++ b/InternalPythonModules/android/contact.py @@ -1,7 +1,7 @@ """ Autopsy Forensic Browser -Copyright 2016 Basis Technology Corp. +Copyright 2016-17 Basis Technology Corp. Contact: carrier sleuthkit org Licensed under the Apache License, Version 2.0 (the "License"); @@ -42,6 +42,7 @@ from org.sleuthkit.datamodel import BlackboardAttribute from org.sleuthkit.datamodel import Content from org.sleuthkit.datamodel import TskCoreException from org.sleuthkit.datamodel import Account +from org.sleuthkit.datamodel import Relationship import traceback import general @@ -150,7 +151,7 @@ class ContactAnalyzer(general.AndroidComponentAnalyzer): contactAccountInstance = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().createAccountFileInstance (acctType, data1, general.MODULE_NAME, abstractFile); # create relationship between accounts - Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().addRelationships(deviceAccountInstance, [contactAccountInstance], artifact, 0); + Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().addRelationships(deviceAccountInstance, [contactAccountInstance], artifact,Relationship.TYPE.CONTACT, 0); oldName = name diff --git a/InternalPythonModules/android/textmessage.py b/InternalPythonModules/android/textmessage.py index fea5bd4218..07009084de 100755 --- a/InternalPythonModules/android/textmessage.py +++ b/InternalPythonModules/android/textmessage.py @@ -1,7 +1,7 @@ """ Autopsy Forensic Browser -Copyright 2016 Basis Technology Corp. +Copyright 2016-17 Basis Technology Corp. Contact: carrier sleuthkit org Licensed under the Apache License, Version 2.0 (the "License"); @@ -43,6 +43,7 @@ from org.sleuthkit.datamodel import BlackboardAttribute from org.sleuthkit.datamodel import Content from org.sleuthkit.datamodel import TskCoreException from org.sleuthkit.datamodel import Account +from org.sleuthkit.datamodel import Relationship import traceback import general @@ -121,7 +122,7 @@ class TextMessageAnalyzer(general.AndroidComponentAnalyzer): msgAccountInstance = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().createAccountFileInstance(Account.Type.PHONE, address, general.MODULE_NAME, abstractFile); # create relationship between accounts - Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().addRelationships(deviceAccountInstance, [msgAccountInstance], artifact, date); + Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().addRelationships(deviceAccountInstance, [msgAccountInstance], artifact,Relationship.TYPE.MESSAGE, date); bbartifacts.append(artifact) try: diff --git a/InternalPythonModules/android/wwfmessage.py b/InternalPythonModules/android/wwfmessage.py index 54f35aff5b..0ca51bcd44 100755 --- a/InternalPythonModules/android/wwfmessage.py +++ b/InternalPythonModules/android/wwfmessage.py @@ -1,7 +1,7 @@ """ Autopsy Forensic Browser -Copyright 2016 Basis Technology Corp. +Copyright 2016-17 Basis Technology Corp. Contact: carrier sleuthkit org Licensed under the Apache License, Version 2.0 (the "License"); @@ -39,6 +39,7 @@ from org.sleuthkit.datamodel import BlackboardAttribute from org.sleuthkit.datamodel import Content from org.sleuthkit.datamodel import TskCoreException from org.sleuthkit.datamodel import Account +from org.sleuthkit.datamodel import Relationship import traceback import general @@ -115,7 +116,7 @@ class WWFMessageAnalyzer(general.AndroidComponentAnalyzer): wwfAccountInstance = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().createAccountFileInstance(wwfAccountType, user_id, general.MODULE_NAME, abstractFile); # create relationship between accounts - Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().addRelationships(deviceAccountInstance, [wwfAccountInstance], artifact, created_at); + Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().addRelationships(deviceAccountInstance, [wwfAccountInstance], artifact,Relationship.TYPE.MESSAGE, created_at); try: # index the artifact for keyword search diff --git a/thunderbirdparser/src/org/sleuthkit/autopsy/thunderbirdparser/ThunderbirdMboxFileIngestModule.java b/thunderbirdparser/src/org/sleuthkit/autopsy/thunderbirdparser/ThunderbirdMboxFileIngestModule.java index f4aa12c9dc..91c4c2ff5c 100755 --- a/thunderbirdparser/src/org/sleuthkit/autopsy/thunderbirdparser/ThunderbirdMboxFileIngestModule.java +++ b/thunderbirdparser/src/org/sleuthkit/autopsy/thunderbirdparser/ThunderbirdMboxFileIngestModule.java @@ -26,8 +26,8 @@ import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.logging.Level; -import java.util.regex.Pattern; import java.util.regex.Matcher; +import java.util.regex.Pattern; import org.openide.util.NbBundle; import org.openide.util.NbBundle.Messages; import org.sleuthkit.autopsy.casemodule.Case; @@ -51,8 +51,10 @@ import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardAttribute; import org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE; import org.sleuthkit.datamodel.DerivedFile; +import org.sleuthkit.datamodel.Relationship; import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.datamodel.TskData; +import org.sleuthkit.datamodel.TskDataException; import org.sleuthkit.datamodel.TskException; /** @@ -465,7 +467,7 @@ public final class ThunderbirdMboxFileIngestModule implements FileIngestModule { bbart.addAttributes(bbattributes); // Add account relationships - Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().addRelationships(senderAccountInstance, recipientAccountInstances, bbart, dateL); + Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().addRelationships(senderAccountInstance, recipientAccountInstances, bbart,Relationship.Type.MESSAGE, dateL); try { // index the artifact for keyword search @@ -474,7 +476,7 @@ public final class ThunderbirdMboxFileIngestModule implements FileIngestModule { logger.log(Level.SEVERE, "Unable to index blackboard artifact " + bbart.getArtifactID(), ex); //NON-NLS MessageNotifyUtil.Notify.error(Bundle.ThunderbirdMboxFileIngestModule_addArtifact_indexError_message(), bbart.getDisplayName()); } - } catch (TskCoreException ex) { + } catch (TskCoreException | TskDataException ex) { logger.log(Level.WARNING, null, ex); } From 2f468dd1a1b7fd207a45527be22787a01d76425f Mon Sep 17 00:00:00 2001 From: millmanorama Date: Sat, 2 Dec 2017 13:12:03 +0100 Subject: [PATCH 122/127] fix python android modules --- InternalPythonModules/android/calllog.py | 2 +- InternalPythonModules/android/contact.py | 2 +- InternalPythonModules/android/textmessage.py | 2 +- InternalPythonModules/android/wwfmessage.py | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/InternalPythonModules/android/calllog.py b/InternalPythonModules/android/calllog.py index 6fa413884c..504cd4d4a7 100755 --- a/InternalPythonModules/android/calllog.py +++ b/InternalPythonModules/android/calllog.py @@ -147,7 +147,7 @@ class CallLogAnalyzer(general.AndroidComponentAnalyzer): calllogAccountInstance = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().createAccountFileInstance(Account.Type.PHONE, number, general.MODULE_NAME, abstractFile); # create relationship between accounts - Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().addRelationships(deviceAccountInstance, [calllogAccountInstance], artifact, Relationship.TYPE.CALL_LOG, date); + Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().addRelationships(deviceAccountInstance, [calllogAccountInstance], artifact, Relationship.Type.CALL_LOG, date); bbartifacts.append(artifact) diff --git a/InternalPythonModules/android/contact.py b/InternalPythonModules/android/contact.py index 8816412113..eaff7871f5 100755 --- a/InternalPythonModules/android/contact.py +++ b/InternalPythonModules/android/contact.py @@ -151,7 +151,7 @@ class ContactAnalyzer(general.AndroidComponentAnalyzer): contactAccountInstance = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().createAccountFileInstance (acctType, data1, general.MODULE_NAME, abstractFile); # create relationship between accounts - Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().addRelationships(deviceAccountInstance, [contactAccountInstance], artifact,Relationship.TYPE.CONTACT, 0); + Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().addRelationships(deviceAccountInstance, [contactAccountInstance], artifact,Relationship.Type.CONTACT, 0); oldName = name diff --git a/InternalPythonModules/android/textmessage.py b/InternalPythonModules/android/textmessage.py index 07009084de..61e1ec627f 100755 --- a/InternalPythonModules/android/textmessage.py +++ b/InternalPythonModules/android/textmessage.py @@ -122,7 +122,7 @@ class TextMessageAnalyzer(general.AndroidComponentAnalyzer): msgAccountInstance = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().createAccountFileInstance(Account.Type.PHONE, address, general.MODULE_NAME, abstractFile); # create relationship between accounts - Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().addRelationships(deviceAccountInstance, [msgAccountInstance], artifact,Relationship.TYPE.MESSAGE, date); + Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().addRelationships(deviceAccountInstance, [msgAccountInstance], artifact,Relationship.Type.MESSAGE, date); bbartifacts.append(artifact) try: diff --git a/InternalPythonModules/android/wwfmessage.py b/InternalPythonModules/android/wwfmessage.py index 0ca51bcd44..3754daa5c7 100755 --- a/InternalPythonModules/android/wwfmessage.py +++ b/InternalPythonModules/android/wwfmessage.py @@ -116,7 +116,7 @@ class WWFMessageAnalyzer(general.AndroidComponentAnalyzer): wwfAccountInstance = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().createAccountFileInstance(wwfAccountType, user_id, general.MODULE_NAME, abstractFile); # create relationship between accounts - Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().addRelationships(deviceAccountInstance, [wwfAccountInstance], artifact,Relationship.TYPE.MESSAGE, created_at); + Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().addRelationships(deviceAccountInstance, [wwfAccountInstance], artifact,Relationship.Type.MESSAGE, created_at); try: # index the artifact for keyword search From d27d13ba68fd05fe0420c5e159811d9d8b3163d9 Mon Sep 17 00:00:00 2001 From: millmanorama Date: Fri, 1 Dec 2017 22:22:17 +0100 Subject: [PATCH 123/127] WIP Merge branch 'accounts_relationships' into 883_user-friendly-device-ids --- .../communications/AccountsRootChildren.java | 21 +++++++++++- .../autopsy/communications/FiltersPanel.java | 34 +++++++++++++------ 2 files changed, 44 insertions(+), 11 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/communications/AccountsRootChildren.java b/Core/src/org/sleuthkit/autopsy/communications/AccountsRootChildren.java index 99f71275c7..1f53d6f8e8 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/AccountsRootChildren.java +++ b/Core/src/org/sleuthkit/autopsy/communications/AccountsRootChildren.java @@ -29,11 +29,14 @@ import org.openide.nodes.Node; import org.openide.nodes.Sheet; import org.openide.util.NbBundle; import org.openide.util.lookup.Lookups; +import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.datamodel.NodeProperty; import org.sleuthkit.datamodel.Account; import org.sleuthkit.datamodel.AccountDeviceInstance; import org.sleuthkit.datamodel.CommunicationsFilter; import org.sleuthkit.datamodel.CommunicationsManager; +import org.sleuthkit.datamodel.DataSource; +import org.sleuthkit.datamodel.SleuthkitCase; import org.sleuthkit.datamodel.TskCoreException; class AccountsRootChildren extends ChildFactory { @@ -118,8 +121,24 @@ class AccountsRootChildren extends ChildFactory { properties.put(new NodeProperty<>("count", Bundle.AccountNode_messageCount(), "count", accountDeviceInstanceKey.getMessageCount())); // NON-NLS properties.put(new NodeProperty<>("device", Bundle.AccountNode_device(), "device", - accountDeviceInstanceKey.getAccountDeviceInstance().getDeviceId())); // NON-NLS + getDataSourceName())); // NON-NLS return s; } + + private String getDataSourceName() { + try { + final SleuthkitCase sleuthkitCase = Case.getCurrentCase() + .getSleuthkitCase(); + List dataSources = sleuthkitCase.getDataSources(); + for (DataSource dataSource : dataSources) { + if (dataSource.getDeviceId().equals(getAccountDeviceInstance().getDeviceId())) { + return sleuthkitCase.getContentById(dataSource.getId()).getName(); + } + } + } catch (TskCoreException ex) { + logger.log(Level.SEVERE, "Error getting datasource name, falling back on device ID.", ex); + } + return getAccountDeviceInstance().getDeviceId(); + } } } diff --git a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java index 1543149fd8..dea371e3bf 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java +++ b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java @@ -48,7 +48,9 @@ import org.sleuthkit.datamodel.CommunicationsFilter.DeviceFilter; import org.sleuthkit.datamodel.CommunicationsManager; import org.sleuthkit.datamodel.DataSource; import static org.sleuthkit.datamodel.Relationship.Type.CALL_LOG; +import org.sleuthkit.datamodel.SleuthkitCase; import static org.sleuthkit.datamodel.Relationship.Type.MESSAGE; +import org.sleuthkit.datamodel.SleuthkitCase; import org.sleuthkit.datamodel.TskCoreException; /** @@ -183,15 +185,18 @@ final public class FiltersPanel extends javax.swing.JPanel { */ private void updateDeviceFilter() { try { - Case.getCurrentCase() - .getSleuthkitCase() - .getDataSources().stream().map(DataSource::getDeviceId) - .forEach( - deviceID -> devicesMap.computeIfAbsent(deviceID, ds -> { - final JCheckBox jCheckBox = new JCheckBox(deviceID, false); - devicesPane.add(jCheckBox); - return jCheckBox; - })); + final SleuthkitCase sleuthkitCase = Case.getCurrentCase().getSleuthkitCase(); + + for (DataSource dataSource : sleuthkitCase.getDataSources()) { + String dsName = getDataSourceName(sleuthkitCase, dataSource); + + //store the device id in the map, but display the datasource name in the UI. + devicesMap.computeIfAbsent(dataSource.getDeviceId(), ds -> { + final JCheckBox jCheckBox = new JCheckBox(dsName, false); + devicesPane.add(jCheckBox); + return jCheckBox; + }); + }; } catch (IllegalStateException ex) { logger.log(Level.WARNING, "Communications Visualization Tool opened with no open case.", ex); @@ -200,6 +205,15 @@ final public class FiltersPanel extends javax.swing.JPanel { } } + private String getDataSourceName(SleuthkitCase sleuthkitCase, DataSource dataSource) { + try { + return sleuthkitCase.getContentById(dataSource.getId()).getName(); + } catch (TskCoreException ex) { + logger.log(Level.SEVERE, "Error getting datasource name, falling back on device ID.", ex); + } + return dataSource.getDeviceId(); + } + /** * This method is called from within the constructor to initialize the form. * WARNING: Do NOT modify this code. The content of this method is always @@ -427,7 +441,7 @@ final public class FiltersPanel extends javax.swing.JPanel { commsFilter.addAndFilter(getDateRangeFilter()); commsFilter.addAndFilter(new CommunicationsFilter.RelationshipTypeFilter( ImmutableSet.of(CALL_LOG, MESSAGE))); - + try { final CommunicationsManager commsManager = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager(); em.setRootContext(new AbstractNode(Children.create(new AccountsRootChildren(commsManager, commsFilter), true))); From 63174e0dfca024989919949ea74362d2ebc165bf Mon Sep 17 00:00:00 2001 From: millmanorama Date: Sat, 2 Dec 2017 16:17:35 +0100 Subject: [PATCH 124/127] inline method --- .../communications/AccountsRootChildren.java | 10 +++---- .../autopsy/communications/FiltersPanel.form | 11 ++++--- .../autopsy/communications/FiltersPanel.java | 29 +++++++------------ 3 files changed, 19 insertions(+), 31 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/communications/AccountsRootChildren.java b/Core/src/org/sleuthkit/autopsy/communications/AccountsRootChildren.java index 1f53d6f8e8..9b0b5081d2 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/AccountsRootChildren.java +++ b/Core/src/org/sleuthkit/autopsy/communications/AccountsRootChildren.java @@ -127,17 +127,15 @@ class AccountsRootChildren extends ChildFactory { private String getDataSourceName() { try { - final SleuthkitCase sleuthkitCase = Case.getCurrentCase() - .getSleuthkitCase(); - List dataSources = sleuthkitCase.getDataSources(); - for (DataSource dataSource : dataSources) { + final SleuthkitCase sleuthkitCase = Case.getCurrentCase().getSleuthkitCase(); + for (DataSource dataSource : sleuthkitCase.getDataSources()) { if (dataSource.getDeviceId().equals(getAccountDeviceInstance().getDeviceId())) { return sleuthkitCase.getContentById(dataSource.getId()).getName(); } } } catch (TskCoreException ex) { - logger.log(Level.SEVERE, "Error getting datasource name, falling back on device ID.", ex); - } + logger.log(Level.SEVERE, "Error getting datasource name, falling back on device ID.", ex); + } return getAccountDeviceInstance().getDeviceId(); } } diff --git a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.form b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.form index dd37f45b9c..da402cb4e6 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.form +++ b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.form @@ -30,7 +30,6 @@ -
@@ -70,15 +69,15 @@
- - - + + + @@ -97,7 +96,7 @@ - + @@ -182,7 +181,7 @@ - + diff --git a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java index dea371e3bf..93e3230576 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java +++ b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java @@ -48,7 +48,6 @@ import org.sleuthkit.datamodel.CommunicationsFilter.DeviceFilter; import org.sleuthkit.datamodel.CommunicationsManager; import org.sleuthkit.datamodel.DataSource; import static org.sleuthkit.datamodel.Relationship.Type.CALL_LOG; -import org.sleuthkit.datamodel.SleuthkitCase; import static org.sleuthkit.datamodel.Relationship.Type.MESSAGE; import org.sleuthkit.datamodel.SleuthkitCase; import org.sleuthkit.datamodel.TskCoreException; @@ -188,9 +187,8 @@ final public class FiltersPanel extends javax.swing.JPanel { final SleuthkitCase sleuthkitCase = Case.getCurrentCase().getSleuthkitCase(); for (DataSource dataSource : sleuthkitCase.getDataSources()) { - String dsName = getDataSourceName(sleuthkitCase, dataSource); - - //store the device id in the map, but display the datasource name in the UI. + String dsName = sleuthkitCase.getContentById(dataSource.getId()).getName(); + //store the device id in the map, but display a datasource name in the UI. devicesMap.computeIfAbsent(dataSource.getDeviceId(), ds -> { final JCheckBox jCheckBox = new JCheckBox(dsName, false); devicesPane.add(jCheckBox); @@ -205,14 +203,6 @@ final public class FiltersPanel extends javax.swing.JPanel { } } - private String getDataSourceName(SleuthkitCase sleuthkitCase, DataSource dataSource) { - try { - return sleuthkitCase.getContentById(dataSource.getId()).getName(); - } catch (TskCoreException ex) { - logger.log(Level.SEVERE, "Error getting datasource name, falling back on device ID.", ex); - } - return dataSource.getDeviceId(); - } /** * This method is called from within the constructor to initialize the form. @@ -227,9 +217,9 @@ final public class FiltersPanel extends javax.swing.JPanel { applyFiltersButton.setText(org.openide.util.NbBundle.getMessage(FiltersPanel.class, "FiltersPanel.applyFiltersButton.text")); // NOI18N applyFiltersButton.setPreferredSize(null); + filtersTitleLabel.setFont(new java.awt.Font("Tahoma", 0, 16)); // NOI18N filtersTitleLabel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/communications/images/funnel.png"))); // NOI18N filtersTitleLabel.setText(org.openide.util.NbBundle.getMessage(FiltersPanel.class, "FiltersPanel.filtersTitleLabel.text")); // NOI18N - filtersTitleLabel.setFont(new java.awt.Font("Tahoma", 0, 16)); // NOI18N unCheckAllAccountTypesButton.setText(org.openide.util.NbBundle.getMessage(FiltersPanel.class, "FiltersPanel.unCheckAllAccountTypesButton.text")); // NOI18N unCheckAllAccountTypesButton.addActionListener(new java.awt.event.ActionListener() { @@ -265,7 +255,7 @@ final public class FiltersPanel extends javax.swing.JPanel { .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) .addComponent(jScrollPane3) .addGroup(jPanel2Layout.createSequentialGroup() - .addGap(0, 115, Short.MAX_VALUE) + .addGap(0, 0, Short.MAX_VALUE) .addComponent(unCheckAllAccountTypesButton) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(checkAllAccountTypesButton))))) @@ -318,7 +308,7 @@ final public class FiltersPanel extends javax.swing.JPanel { .addContainerGap() .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel3Layout.createSequentialGroup() - .addGap(0, 115, Short.MAX_VALUE) + .addGap(0, 0, Short.MAX_VALUE) .addComponent(unCheckAllDevicesButton) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(checkAllDevicesButton)) @@ -409,8 +399,7 @@ final public class FiltersPanel extends javax.swing.JPanel { .addComponent(applyFiltersButton, javax.swing.GroupLayout.PREFERRED_SIZE, 83, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(refreshButton)) - .addComponent(jPanel4, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - .addGap(0, 0, 0)) + .addComponent(jPanel4, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) @@ -458,9 +447,11 @@ final public class FiltersPanel extends javax.swing.JPanel { * @return a DeviceFilter */ private DeviceFilter getDeviceFilter() { - DeviceFilter deviceFilter = new DeviceFilter(devicesMap.entrySet().stream() + DeviceFilter deviceFilter = new DeviceFilter( + devicesMap.entrySet().stream() .filter(entry -> entry.getValue().isSelected()) - .map(Entry::getKey).collect(Collectors.toSet())); + .map(Entry::getKey) + .collect(Collectors.toSet())); return deviceFilter; } From 85e9f375ca179463e83e48a33a59b4802614f908 Mon Sep 17 00:00:00 2001 From: millmanorama Date: Tue, 5 Dec 2017 14:01:46 +0100 Subject: [PATCH 125/127] disable Visualize tab. --- .../autopsy/communications/CVTTopComponent.form | 2 +- .../autopsy/communications/CVTTopComponent.java | 13 +++++++------ 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.form b/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.form index 7b23c12636..e8d83b24f1 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.form +++ b/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.form @@ -47,7 +47,7 @@ - + diff --git a/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java b/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java index 67e77b0f00..4099af0bfa 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java +++ b/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java @@ -47,6 +47,7 @@ public final class CVTTopComponent extends TopComponent implements ExplorerManag public CVTTopComponent() { initComponents(); + browseVisualizeTabPane.setEnabledAt(1, false); setName(Bundle.CVTTopComponent_name()); splitPane.setRightComponent(new MessageBrowser()); } @@ -60,7 +61,7 @@ public final class CVTTopComponent extends TopComponent implements ExplorerManag private void initComponents() { splitPane = new javax.swing.JSplitPane(); - BrowseVisualizeTabPane = new javax.swing.JTabbedPane(); + browseVisualizeTabPane = new javax.swing.JTabbedPane(); accountsBrowser = new org.sleuthkit.autopsy.communications.AccountsBrowser(); jPanel1 = new javax.swing.JPanel(); filtersPane = new org.sleuthkit.autopsy.communications.FiltersPanel(); @@ -68,8 +69,8 @@ public final class CVTTopComponent extends TopComponent implements ExplorerManag splitPane.setDividerLocation(400); splitPane.setResizeWeight(0.7); - BrowseVisualizeTabPane.setFont(new java.awt.Font("Tahoma", 0, 18)); // NOI18N - BrowseVisualizeTabPane.addTab(org.openide.util.NbBundle.getMessage(CVTTopComponent.class, "CVTTopComponent.accountsBrowser.TabConstraints.tabTitle"), new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/communications/images/table.png")), accountsBrowser); // NOI18N + browseVisualizeTabPane.setFont(new java.awt.Font("Tahoma", 0, 18)); // NOI18N + browseVisualizeTabPane.addTab(org.openide.util.NbBundle.getMessage(CVTTopComponent.class, "CVTTopComponent.accountsBrowser.TabConstraints.tabTitle"), new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/communications/images/table.png")), accountsBrowser); // NOI18N jPanel1.setName(""); // NOI18N @@ -84,9 +85,9 @@ public final class CVTTopComponent extends TopComponent implements ExplorerManag .addGap(0, 725, Short.MAX_VALUE) ); - BrowseVisualizeTabPane.addTab(org.openide.util.NbBundle.getMessage(CVTTopComponent.class, "CVTTopComponent.TabConstraints.tabTitle"), new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/communications/images/emblem-web.png")), jPanel1); // NOI18N + browseVisualizeTabPane.addTab(org.openide.util.NbBundle.getMessage(CVTTopComponent.class, "CVTTopComponent.TabConstraints.tabTitle"), new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/communications/images/emblem-web.png")), jPanel1); // NOI18N - splitPane.setLeftComponent(BrowseVisualizeTabPane); + splitPane.setLeftComponent(browseVisualizeTabPane); filtersPane.setMinimumSize(new java.awt.Dimension(256, 495)); @@ -114,8 +115,8 @@ public final class CVTTopComponent extends TopComponent implements ExplorerManag // Variables declaration - do not modify//GEN-BEGIN:variables - private javax.swing.JTabbedPane BrowseVisualizeTabPane; private org.sleuthkit.autopsy.communications.AccountsBrowser accountsBrowser; + private javax.swing.JTabbedPane browseVisualizeTabPane; private org.sleuthkit.autopsy.communications.FiltersPanel filtersPane; private javax.swing.JPanel jPanel1; private javax.swing.JSplitPane splitPane; From 1db2c9b04317bd5db438c43d8fee820e6a7c9be3 Mon Sep 17 00:00:00 2001 From: Raman Date: Tue, 5 Dec 2017 12:31:40 -0500 Subject: [PATCH 126/127] Handle build error after merging develop to accounts_relationships branch --- .../org/sleuthkit/autopsy/keywordsearch/RegexQuery.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/RegexQuery.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/RegexQuery.java index 17c4094e2f..d121289bb9 100755 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/RegexQuery.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/RegexQuery.java @@ -36,6 +36,7 @@ import org.apache.solr.client.solrj.response.QueryResponse; import org.apache.solr.common.SolrDocument; import org.apache.solr.common.SolrDocumentList; import org.apache.solr.common.params.CursorMarkParams; +import org.openide.util.Exceptions; import org.openide.util.NbBundle; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.coreutils.Logger; @@ -518,10 +519,15 @@ final class RegexQuery implements KeywordSearchQuery { } final BlackboardAttribute ccnAttribute = parsedTrackAttributeMap.get(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_CARD_NUMBER)); if (ccnAttribute == null || StringUtils.isBlank(ccnAttribute.getValueString())) { + if (hit.isArtifactHit()) { LOGGER.log(Level.SEVERE, String.format("Failed to parse credit card account number for artifact keyword hit: term = %s, snippet = '%s', artifact id = %d", foundKeyword.getSearchTerm(), hit.getSnippet(), hit.getArtifactID().get())); //NON-NLS } else { - LOGGER.log(Level.SEVERE, String.format("Failed to parse credit card account number for content keyword hit: term = %s, snippet = '%s', object id = %d", foundKeyword.getSearchTerm(), hit.getSnippet(), hit.getContentID())); //NON-NLS + try { + LOGGER.log(Level.SEVERE, String.format("Failed to parse credit card account number for content keyword hit: term = %s, snippet = '%s', object id = %d", foundKeyword.getSearchTerm(), hit.getSnippet(), hit.getContentID())); //NON-NLS + } catch (TskCoreException ex) { + LOGGER.log(Level.SEVERE, "There was a error getting contentID for keyword hit.", ex); //NON-NLS + } } return; } From 9364640b5e27cff05d5beefad981599003df9e43 Mon Sep 17 00:00:00 2001 From: Raman Date: Wed, 6 Dec 2017 10:25:27 -0500 Subject: [PATCH 127/127] Fixed lost log message in case there's an exception while logging it. --- .../src/org/sleuthkit/autopsy/keywordsearch/RegexQuery.java | 1 + 1 file changed, 1 insertion(+) diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/RegexQuery.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/RegexQuery.java index d121289bb9..306502603c 100755 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/RegexQuery.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/RegexQuery.java @@ -526,6 +526,7 @@ final class RegexQuery implements KeywordSearchQuery { try { LOGGER.log(Level.SEVERE, String.format("Failed to parse credit card account number for content keyword hit: term = %s, snippet = '%s', object id = %d", foundKeyword.getSearchTerm(), hit.getSnippet(), hit.getContentID())); //NON-NLS } catch (TskCoreException ex) { + LOGGER.log(Level.SEVERE, String.format("Failed to parse credit card account number for content keyword hit: term = %s, snippet = '%s' ", foundKeyword.getSearchTerm(), hit.getSnippet())); //NON-NLS LOGGER.log(Level.SEVERE, "There was a error getting contentID for keyword hit.", ex); //NON-NLS } }