From 70e62f28c0026b3d5f5ff01ef9bad896e7f6d580 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Mon, 24 Feb 2020 15:57:32 -0500 Subject: [PATCH 001/100] beginning to integrate postgres with multiuser settings to be used with central repository --- .../optionspanel/GlobalSettingsPanel.java | 73 ++++++++++++++++--- .../MultiUserSettingsPanel.java | 3 + 2 files changed, 65 insertions(+), 11 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java index ab0ea0401f..61a89befed 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java @@ -18,6 +18,7 @@ */ package org.sleuthkit.autopsy.centralrepository.optionspanel; +import java.awt.Component; import java.awt.Cursor; import java.awt.EventQueue; import org.sleuthkit.autopsy.coreutils.Logger; @@ -78,26 +79,77 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i ingestStateUpdated(Case.isCaseOpen()); } - @Messages({"GlobalSettingsPanel.updateFailed.title=Central repository disabled"}) private void updateDatabase() { - + updateDatabase(this); + } + + private static boolean invokeCbChoice(Component parent) { + EamDbSettingsDialog dialog = new EamDbSettingsDialog(); + if (dialog.wasConfigurationChanged()) { + updateDatabase(parent); + return true; + } + + return false; + } + + + @NbBundle.Messages({ + "GlobalSettingsPanel.onMultiUserChange.enable.title=Enable Central Repository?", + "GlobalSettingsPanel.onMultiUserChange.enable.description=Do you want to enable Central Repository using these settings?", + "GlobalSettingsPanel.onMultiUserChange.disabledMu.title=Central Repository Change Necessary", + "GlobalSettingsPanel.onMultiUserChange.disabledMu.description=Since mult-user cases have been disabled, 'PostgreSQL using multi-user settings' is no longer a valid option for Central Repository." + }) + public static void onMultiUserChange(Component parent, boolean muPreviouslySelected, boolean muCurrentlySelected, boolean muChange) { + if (!muPreviouslySelected && muCurrentlySelected) { + if (JOptionPane.YES_OPTION == JOptionPane.showConfirmDialog(parent, + NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.onMultiUserChange.enable.description"), + NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.onMultiUserChange.enable.title"), + JOptionPane.YES_NO_OPTION)) { + + // TODO: test and/or setup database for CR + } + } + // moving from selected to not selected && 'PostgreSQL using multi-user settings' is selected + else if (muPreviouslySelected && !muCurrentlySelected && crMultiUser) { + if (JOptionPane.YES_OPTION == JOptionPane.showConfirmDialog(parent, + NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.onMultiUserChange.disabledMu.description"), + NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.onMultiUserChange.disabledMu.title"), + JOptionPane.YES_NO_OPTION)) { + + invokeCbChoice(parent); + // TODO: test and/or setup database for CR + } + else { + // TODO: disable central repository + } + } + // changing multi-user settings connection && 'PostgreSQL using multi-user settings' is selected + else if (muChange && crMultiUser) { + // todo test and/or setup database for CR + } + + } + + @Messages({"GlobalSettingsPanel.updateFailed.title=Central repository disabled"}) + private static void updateDatabase(Component parent) { if (CentralRepoPlatforms.getSelectedPlatform().equals(DISABLED)) { return; } - setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); + parent.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); try { CentralRepoDbManager.upgradeDatabase(); - setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); + parent.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); } catch (CentralRepoException ex) { - setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); - JOptionPane.showMessageDialog(this, + parent.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); + JOptionPane.showMessageDialog(parent, ex.getUserMessage(), - NbBundle.getMessage(this.getClass(), + NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.updateFailed.title"), JOptionPane.WARNING_MESSAGE); } finally { - setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); + parent.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); } } @@ -425,9 +477,8 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i private void bnDbConfigureActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnDbConfigureActionPerformed store(); - EamDbSettingsDialog dialog = new EamDbSettingsDialog(); - if (dialog.wasConfigurationChanged()) { - updateDatabase(); + boolean changed = invokeCbChoice(this); + if (changed) { load(); // reload db settings content and update buttons firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); } diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/MultiUserSettingsPanel.java b/Core/src/org/sleuthkit/autopsy/corecomponents/MultiUserSettingsPanel.java index 8747d49795..e5c6bef2a3 100644 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/MultiUserSettingsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/MultiUserSettingsPanel.java @@ -33,6 +33,7 @@ import org.sleuthkit.autopsy.coreutils.Logger; import java.awt.Cursor; import java.util.logging.Level; import javax.swing.ImageIcon; +import javax.swing.JOptionPane; import org.openide.util.ImageUtilities; import org.openide.util.Lookup; import org.sleuthkit.autopsy.core.UserPreferencesException; @@ -683,6 +684,8 @@ public final class MultiUserSettingsPanel extends javax.swing.JPanel { boolean isPwSet = (tbMsgPassword.getPassword().length != 0); return (isUserSet == isPwSet); } + + void store() { From c0a0af5e61a178d6369f35bbb1fe6e4942466735 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Tue, 25 Feb 2020 09:33:25 -0500 Subject: [PATCH 002/100] changes in multi user settings are redirected to central repository --- .../datamodel/CentralRepoDbManager.java | 4 +- .../datamodel/CentralRepoDbSettings.java | 3 +- .../datamodel/CentralRepoPlatforms.java | 7 +++- .../optionspanel/GlobalSettingsPanel.java | 35 ++++++++++++------ .../MultiUserSettingsPanel.java | 37 +++++++++++++++++++ 5 files changed, 70 insertions(+), 16 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java index e4f9eea857..e1f2c2686a 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java @@ -142,7 +142,7 @@ public class CentralRepoDbManager { } catch (CentralRepoException ex2) { logger.log(Level.SEVERE, "Error shutting down central repo connection pool", ex2); } - CentralRepoPlatforms.setSelectedPlatform(CentralRepoPlatforms.DISABLED.name()); + CentralRepoPlatforms.setSelectedPlatform(CentralRepoPlatforms.DISABLED); CentralRepoPlatforms.saveSelectedPlatform(); if (innerException == null) { throw new CentralRepoException(message, desc); @@ -281,7 +281,7 @@ public class CentralRepoDbManager { // Even if we fail to close the existing connections, make sure that we // save the new connection settings, so an Autopsy restart will correctly // start with the new settings. - CentralRepoPlatforms.setSelectedPlatform(selectedPlatform.name()); + CentralRepoPlatforms.setSelectedPlatform(selectedPlatform); CentralRepoPlatforms.saveSelectedPlatform(); CentralRepoDbSettings selectedDbSettings = getSelectedSettings(); diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbSettings.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbSettings.java index 01d8ed1d6f..2d340117aa 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbSettings.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbSettings.java @@ -19,8 +19,7 @@ package org.sleuthkit.autopsy.centralrepository.datamodel; /** - * - * @author gregd + * common interface for db connectivity */ public interface CentralRepoDbSettings { diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoPlatforms.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoPlatforms.java index bcdf009ca3..69162975ff 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoPlatforms.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoPlatforms.java @@ -26,7 +26,8 @@ import org.sleuthkit.autopsy.coreutils.ModuleSettings; public enum CentralRepoPlatforms { DISABLED("Disabled", true), SQLITE("SQLite", false), - POSTGRESQL("PostgreSQL", false); + POSTGRESQL_MULTIUSER("PostgreSQL using multi-user settings", false), + POSTGRESQL("Custom PostgreSQL", false); private final String platformName; private Boolean selected; @@ -102,6 +103,10 @@ public enum CentralRepoPlatforms { } } + public static void setSelectedPlatform(CentralRepoPlatforms platform) { + setSelectedPlatform(platform.toString()); + } + /** * Get the selected platform. * diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java index 61a89befed..4133284fe5 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java @@ -18,7 +18,6 @@ */ package org.sleuthkit.autopsy.centralrepository.optionspanel; -import java.awt.Component; import java.awt.Cursor; import java.awt.EventQueue; import org.sleuthkit.autopsy.coreutils.Logger; @@ -83,7 +82,7 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i updateDatabase(this); } - private static boolean invokeCbChoice(Component parent) { + private static boolean invokeCrChoice(Component parent) { EamDbSettingsDialog dialog = new EamDbSettingsDialog(); if (dialog.wasConfigurationChanged()) { updateDatabase(parent); @@ -94,20 +93,33 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i } + /** + * when multi user settings are updated, this function triggers pertinent updates for central repository + * NOTE: if multi user settings were previously enabled and multi user settings are currently selected, this function assumes + * there is a change in the postgres connectivity + * + * @param parent the swing component that serves as a parent for dialogs that may arise + * @param muPreviouslySelected if multi user settings were previously enabled + * @param muCurrentlySelected if multi user settings are currently enabled as of most recent change + */ @NbBundle.Messages({ "GlobalSettingsPanel.onMultiUserChange.enable.title=Enable Central Repository?", "GlobalSettingsPanel.onMultiUserChange.enable.description=Do you want to enable Central Repository using these settings?", "GlobalSettingsPanel.onMultiUserChange.disabledMu.title=Central Repository Change Necessary", "GlobalSettingsPanel.onMultiUserChange.disabledMu.description=Since mult-user cases have been disabled, 'PostgreSQL using multi-user settings' is no longer a valid option for Central Repository." }) - public static void onMultiUserChange(Component parent, boolean muPreviouslySelected, boolean muCurrentlySelected, boolean muChange) { + public static void onMultiUserChange(Component parent, boolean muPreviouslySelected, boolean muCurrentlySelected) { + boolean crMultiUser = CentralRepoPlatforms.getSelectedPlatform() == CentralRepoPlatforms.POSTGRESQL_MULTIUSER; + if (!muPreviouslySelected && muCurrentlySelected) { if (JOptionPane.YES_OPTION == JOptionPane.showConfirmDialog(parent, NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.onMultiUserChange.enable.description"), NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.onMultiUserChange.enable.title"), JOptionPane.YES_NO_OPTION)) { - // TODO: test and/or setup database for CR + // setup database for CR + CentralRepoPlatforms.setSelectedPlatform(CentralRepoPlatforms.POSTGRESQL_MULTIUSER); + updateDatabase(parent); } } // moving from selected to not selected && 'PostgreSQL using multi-user settings' is selected @@ -117,18 +129,19 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.onMultiUserChange.disabledMu.title"), JOptionPane.YES_NO_OPTION)) { - invokeCbChoice(parent); - // TODO: test and/or setup database for CR + // present user with central repository choice + invokeCrChoice(parent); } else { - // TODO: disable central repository + // disable central repository + CentralRepoPlatforms.setSelectedPlatform(CentralRepoPlatforms.DISABLED); } } // changing multi-user settings connection && 'PostgreSQL using multi-user settings' is selected - else if (muChange && crMultiUser) { - // todo test and/or setup database for CR + else if (muPreviouslySelected && muCurrentlySelected && crMultiUser) { + // test databse for CR change + updateDatabase(parent); } - } @Messages({"GlobalSettingsPanel.updateFailed.title=Central repository disabled"}) @@ -477,7 +490,7 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i private void bnDbConfigureActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnDbConfigureActionPerformed store(); - boolean changed = invokeCbChoice(this); + boolean changed = invokeCrChoice(this); if (changed) { load(); // reload db settings content and update buttons firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/MultiUserSettingsPanel.java b/Core/src/org/sleuthkit/autopsy/corecomponents/MultiUserSettingsPanel.java index e5c6bef2a3..ddae80a82f 100644 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/MultiUserSettingsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/MultiUserSettingsPanel.java @@ -27,6 +27,7 @@ import javax.swing.event.DocumentListener; import org.openide.util.NbBundle; import org.sleuthkit.datamodel.CaseDbConnectionInfo; import org.sleuthkit.datamodel.TskData.DbType; +import org.sleuthkit.autopsy.centralrepository.optionspanel.GlobalSettingsPanel; import org.sleuthkit.autopsy.core.UserPreferences; import org.sleuthkit.autopsy.events.MessageServiceConnectionInfo; import org.sleuthkit.autopsy.coreutils.Logger; @@ -688,6 +689,8 @@ public final class MultiUserSettingsPanel extends javax.swing.JPanel { void store() { + boolean prevSelected = UserPreferences.getIsMultiUserModeEnabled(); + CaseDbConnectionInfo prevConn = UserPreferences.getDatabaseConnectionInfo(); boolean multiUserCasesEnabled = cbEnableMultiUser.isSelected(); UserPreferences.setIsMultiUserModeEnabled(multiUserCasesEnabled); @@ -734,8 +737,42 @@ public final class MultiUserSettingsPanel extends javax.swing.JPanel { UserPreferences.setIndexingServerHost(tbSolrHostname.getText().trim()); UserPreferences.setIndexingServerPort(Integer.parseInt(tbSolrPort.getText().trim())); + boolean curSelected = UserPreferences.getIsMultiUserModeEnabled(); + CaseDbConnectionInfo curConn = UserPreferences.getDatabaseConnectionInfo(); + + if (prevSelected != curSelected || !areCaseDbConnectionEqual(prevConn, curConn)) + GlobalSettingsPanel.onMultiUserChange(this, prevSelected, curSelected); } + private static boolean arePropsEqual(Object a, Object b) { + if (a == null || b == null) { + if (a == null && b == null) + return true; + else + return false; + } + else { + return a.equals(b); + } + } + + private static boolean areCaseDbConnectionEqual(CaseDbConnectionInfo a, CaseDbConnectionInfo b) { + if (a == null || b == null) { + if (a == null && b == null) + return true; + else + return false; + } + + return + arePropsEqual(a.getDbType(), b.getDbType()) && + arePropsEqual(a.getHost(), b.getHost()) && + arePropsEqual(a.getPassword(), b.getPassword()) && + arePropsEqual(a.getPort(), b.getPort()) && + arePropsEqual(a.getUserName(), b.getUserName()); + } + + /** * Validates that the form is filled out correctly for our usage. * From 5ea3751c35fbb3ac9969f5ef96b5f025f05f4655 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Tue, 25 Feb 2020 11:30:54 -0500 Subject: [PATCH 003/100] small bug fix --- .../optionspanel/GlobalSettingsPanel.java | 1 + .../corecomponents/MultiUserSettingsPanel.java | 12 +++++++++--- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java index 4133284fe5..b3499250c9 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java @@ -42,6 +42,7 @@ import static org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoPlatf import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoDbUtil; import org.sleuthkit.autopsy.centralrepository.datamodel.PostgresCentralRepoSettings; import org.sleuthkit.autopsy.centralrepository.datamodel.SqliteCentralRepoSettings; +import java.awt.Component; /** * Main settings panel for the Central Repository diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/MultiUserSettingsPanel.java b/Core/src/org/sleuthkit/autopsy/corecomponents/MultiUserSettingsPanel.java index ddae80a82f..49373330c7 100644 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/MultiUserSettingsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/MultiUserSettingsPanel.java @@ -690,7 +690,12 @@ public final class MultiUserSettingsPanel extends javax.swing.JPanel { void store() { boolean prevSelected = UserPreferences.getIsMultiUserModeEnabled(); - CaseDbConnectionInfo prevConn = UserPreferences.getDatabaseConnectionInfo(); + CaseDbConnectionInfo prevConn = null; + try { + prevConn = UserPreferences.getDatabaseConnectionInfo(); + } catch (UserPreferencesException ex) { + logger.log(Level.SEVERE, "There was an error while fetching previous connection settings while trying to save", ex); //NON-NLS + } boolean multiUserCasesEnabled = cbEnableMultiUser.isSelected(); UserPreferences.setIsMultiUserModeEnabled(multiUserCasesEnabled); @@ -737,8 +742,9 @@ public final class MultiUserSettingsPanel extends javax.swing.JPanel { UserPreferences.setIndexingServerHost(tbSolrHostname.getText().trim()); UserPreferences.setIndexingServerPort(Integer.parseInt(tbSolrPort.getText().trim())); - boolean curSelected = UserPreferences.getIsMultiUserModeEnabled(); - CaseDbConnectionInfo curConn = UserPreferences.getDatabaseConnectionInfo(); + + boolean curSelected = multiUserCasesEnabled; + CaseDbConnectionInfo curConn = info; if (prevSelected != curSelected || !areCaseDbConnectionEqual(prevConn, curConn)) GlobalSettingsPanel.onMultiUserChange(this, prevSelected, curSelected); From b13b621b2a628a9b096514590ccde4d62490c241 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Tue, 25 Feb 2020 15:09:42 -0500 Subject: [PATCH 004/100] beginning to create settings choice vs. db choice --- .../centralrepository/datamodel/CentralRepoPlatforms.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoPlatforms.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoPlatforms.java index 69162975ff..23a1ea925e 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoPlatforms.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoPlatforms.java @@ -26,8 +26,7 @@ import org.sleuthkit.autopsy.coreutils.ModuleSettings; public enum CentralRepoPlatforms { DISABLED("Disabled", true), SQLITE("SQLite", false), - POSTGRESQL_MULTIUSER("PostgreSQL using multi-user settings", false), - POSTGRESQL("Custom PostgreSQL", false); + POSTGRESQL("PostgreSQL", false); private final String platformName; private Boolean selected; From 8d0948a824031313b049a804743000573bae5e75 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Tue, 25 Feb 2020 15:11:08 -0500 Subject: [PATCH 005/100] adding new enum --- .../datamodel/CentralRepoDbChoice.java | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbChoice.java diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbChoice.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbChoice.java new file mode 100644 index 0000000000..f3261f14af --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbChoice.java @@ -0,0 +1,51 @@ +/* + * Central Repository + * + * Copyright 2015-2020 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.centralrepository.datamodel; + +/** + * + */ +public enum CentralRepoDbChoice { + DISABLED("Disabled"), + SQLITE("SQLite"), + POSTGRESQL_MULTIUSER("PostgreSQL_Multiuser", "PostgreSQL using multi-user settings"), + POSTGRESQL("PostgreSQL", "Custom PostgreSQL"); + + private final String key; + private final String title; + + CentralRepoDbChoice(String key, String title) { + this.key = key; + this.title = title; + } + + CentralRepoDbChoice(String key) { + this(key, key); + } + + public String getKey() { + return key; + } + + public String getTitle() { + return title; + } + + +} From 0fd078a8072f09ff39dae9fbba8a77033560ef37 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Wed, 26 Feb 2020 15:42:38 -0500 Subject: [PATCH 006/100] refactoring to create CentralRepoDbChoice --- .../datamodel/CentralRepoDbChoice.java | 46 +++++--- .../datamodel/CentralRepoDbManager.java | 87 ++++++++++----- .../datamodel/CentralRepoPlatforms.java | 101 +----------------- .../datamodel/CentralRepository.java | 2 +- .../datamodel/RdbmsCentralRepo.java | 2 +- .../ingestmodule/CentralRepoIngestModule.java | 3 +- .../optionspanel/EamDbSettingsDialog.form | 8 +- .../optionspanel/EamDbSettingsDialog.java | 40 ++++--- .../optionspanel/GlobalSettingsPanel.java | 45 ++++---- 9 files changed, 151 insertions(+), 183 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbChoice.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbChoice.java index f3261f14af..f0d1080f10 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbChoice.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbChoice.java @@ -21,31 +21,49 @@ package org.sleuthkit.autopsy.centralrepository.datamodel; /** * */ -public enum CentralRepoDbChoice { - DISABLED("Disabled"), - SQLITE("SQLite"), - POSTGRESQL_MULTIUSER("PostgreSQL_Multiuser", "PostgreSQL using multi-user settings"), - POSTGRESQL("PostgreSQL", "Custom PostgreSQL"); +public class CentralRepoDbChoice { + public static final CentralRepoDbChoice DISABLED = new CentralRepoDbChoice("Disabled", null); - private final String key; + public static final CentralRepoDbChoice SQLITE = new CentralRepoDbChoice("Sqlite", CentralRepoPlatforms.SQLITE); + + public static final CentralRepoDbChoice POSTGRESQL_MULTIUSER = + new CentralRepoDbChoice("PostgreSQL_Multiuser", "PostgreSQL using multi-user settings", CentralRepoPlatforms.POSTGRESQL); + + public static final CentralRepoDbChoice POSTGRESQL_CUSTOM = + new CentralRepoDbChoice("PostgreSQL", "Custom PostgreSQL", CentralRepoPlatforms.POSTGRESQL); + + public static final CentralRepoDbChoice[] CHOICES = new CentralRepoDbChoice[]{ + DISABLED, SQLITE, POSTGRESQL_MULTIUSER, POSTGRESQL_CUSTOM + }; + + public static final CentralRepoDbChoice[] DB_CHOICES = new CentralRepoDbChoice[]{ + SQLITE, POSTGRESQL_MULTIUSER, POSTGRESQL_CUSTOM + }; + + + private final String settingKey; private final String title; + private final CentralRepoPlatforms platform; - CentralRepoDbChoice(String key, String title) { - this.key = key; + CentralRepoDbChoice(String key, String title, CentralRepoPlatforms platform) { + this.settingKey = key; this.title = title; + this.platform = platform; } - CentralRepoDbChoice(String key) { - this(key, key); + CentralRepoDbChoice(String key, CentralRepoPlatforms platform) { + this(key, key, platform); } - public String getKey() { - return key; + public String getSettingKey() { + return settingKey; } public String getTitle() { return title; } - - + + public CentralRepoPlatforms getDbPlatform() { + return platform; + } } diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java index 905fb577cd..6af0072de7 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java @@ -34,6 +34,45 @@ public class CentralRepoDbManager { private static final String CENTRAL_REPO_DB_NAME = "central_repository"; + + + private static CentralRepoDbChoice SAVED_CHOICE = null; + + /** + * Save the selected platform to the config file. + */ + public static CentralRepoDbChoice saveDbChoice(CentralRepoDbChoice choice) { + choice = (choice == null) ? CentralRepoDbChoice.DISABLED : choice; + SAVED_CHOICE = choice; + ModuleSettings.setConfigSetting("CentralRepository", "db.selectedPlatform", choice.getSettingKey()); + return choice; + } + + /** + * Load the selectedPlatform boolean from the config file, if it is set. + */ + public static CentralRepoDbChoice getSavedDbChoice() { + if (SAVED_CHOICE == null) { + String selectedPlatformString = ModuleSettings.getConfigSetting("CentralRepository", "db.selectedPlatform"); // NON-NLS + SAVED_CHOICE = fromKey(selectedPlatformString); + } + + return SAVED_CHOICE; + } + + + private static CentralRepoDbChoice fromKey(String keyName) { + for (CentralRepoDbChoice dbChoice : CentralRepoDbChoice.CHOICES) { + if (dbChoice.getSettingKey().equalsIgnoreCase(keyName)) { + return dbChoice; + } + } + + return CentralRepoDbChoice.DISABLED; + } + + + /** * obtains the database connectivity for central repository * @@ -142,8 +181,7 @@ public class CentralRepoDbManager { } catch (CentralRepoException ex2) { logger.log(Level.SEVERE, "Error shutting down central repo connection pool", ex2); } - CentralRepoPlatforms.setSelectedPlatform(CentralRepoPlatforms.DISABLED); - CentralRepoPlatforms.saveSelectedPlatform(); + saveDbChoice(CentralRepoDbChoice.DISABLED); if (innerException == null) { throw new CentralRepoException(message, desc); } else { @@ -152,7 +190,7 @@ public class CentralRepoDbManager { } private DatabaseTestResult testingStatus; - private CentralRepoPlatforms selectedPlatform; + private CentralRepoDbChoice selectedDbChoice; private final PostgresCentralRepoSettings dbSettingsPostgres; private final SqliteCentralRepoSettings dbSettingsSqlite; @@ -162,13 +200,7 @@ public class CentralRepoDbManager { public CentralRepoDbManager() { dbSettingsPostgres = new PostgresCentralRepoSettings(); dbSettingsSqlite = new SqliteCentralRepoSettings(); - selectedPlatform = CentralRepoPlatforms.getSelectedPlatform(); - - // set the default selected platform for displaying in the ui of EamDbSettingsDialog - // if selected option is not applicable - if (selectedPlatform == null || selectedPlatform.equals(CentralRepoPlatforms.DISABLED)) { - selectedPlatform = CentralRepoPlatforms.POSTGRESQL; - } + selectedDbChoice = getSavedDbChoice(); } public PostgresCentralRepoSettings getDbSettingsPostgres() { @@ -185,7 +217,7 @@ public class CentralRepoDbManager { */ public void setupDefaultSqliteDb() throws CentralRepoException { // change in-memory settings to default sqlite - selectedPlatform = CentralRepoPlatforms.SQLITE; + selectedDbChoice = CentralRepoDbChoice.SQLITE; dbSettingsSqlite.setupDefaultSettings(); // if db is not present, attempt to create it @@ -217,7 +249,7 @@ public class CentralRepoDbManager { } private CentralRepoDbSettings getSelectedSettings() throws CentralRepoException { - switch (selectedPlatform) { + switch (selectedDbChoice) { case POSTGRESQL: return dbSettingsPostgres; case SQLITE: @@ -225,20 +257,20 @@ public class CentralRepoDbManager { case DISABLED: return null; default: - throw new CentralRepoException("Unknown database type: " + selectedPlatform); + throw new CentralRepoException("Unknown database type: " + selectedDbChoice); } } private RdbmsCentralRepoFactory getDbFactory() throws CentralRepoException { - switch (selectedPlatform) { + switch (selectedDbChoice) { case POSTGRESQL: - return new RdbmsCentralRepoFactory(selectedPlatform, dbSettingsPostgres); + return new RdbmsCentralRepoFactory(selectedDbChoice, dbSettingsPostgres); case SQLITE: - return new RdbmsCentralRepoFactory(selectedPlatform, dbSettingsSqlite); + return new RdbmsCentralRepoFactory(selectedDbChoice, dbSettingsSqlite); case DISABLED: return null; default: - throw new CentralRepoException("Unknown database type: " + selectedPlatform); + throw new CentralRepoException("Unknown database type: " + selectedDbChoice); } } @@ -305,8 +337,7 @@ public class CentralRepoDbManager { // Even if we fail to close the existing connections, make sure that we // save the new connection settings, so an Autopsy restart will correctly // start with the new settings. - CentralRepoPlatforms.setSelectedPlatform(selectedPlatform); - CentralRepoPlatforms.saveSelectedPlatform(); + saveDbChoice(selectedDbChoice); CentralRepoDbSettings selectedDbSettings = getSelectedSettings(); @@ -314,7 +345,7 @@ public class CentralRepoDbManager { selectedDbSettings.saveSettings(); // Load those newly saved settings into the postgres db manager instance // in case we are still using the same instance. - if (selectedPlatform == CentralRepoPlatforms.POSTGRESQL || selectedPlatform == CentralRepoPlatforms.SQLITE) { + if (selectedDbChoice != null && selectedDbSettings != CentralRepoDbChoice.DISABLED) { try { logger.info("Creating central repo db with settings: " + selectedDbSettings); CentralRepository.getInstance().updateSettings(); @@ -330,16 +361,16 @@ public class CentralRepoDbManager { return testingStatus; } - public CentralRepoPlatforms getSelectedPlatform() { - return selectedPlatform; + public CentralRepoDbChoice getSelectedDbChoice() { + return selectedDbChoice; } public void clearStatus() { testingStatus = DatabaseTestResult.UNTESTED; } - public void setSelectedPlatform(CentralRepoPlatforms newSelected) { - selectedPlatform = newSelected; + public void setSelctedDbChoice(CentralRepoDbChoice newSelected) { + selectedDbChoice = newSelected; testingStatus = DatabaseTestResult.UNTESTED; } @@ -351,7 +382,7 @@ public class CentralRepoDbManager { public boolean testDatabaseSettingsAreValid( String tbDbHostname, String tbDbPort, String tbDbUsername, String tfDatabasePath, String jpDbPassword) throws CentralRepoException, NumberFormatException { - switch (selectedPlatform) { + switch (selectedDbChoice) { case POSTGRESQL: dbSettingsPostgres.setHost(tbDbHostname); dbSettingsPostgres.setPort(Integer.parseInt(tbDbPort)); @@ -365,14 +396,14 @@ public class CentralRepoDbManager { dbSettingsSqlite.setDbDirectory(databasePath.getPath()); break; default: - throw new IllegalStateException("Central Repo has an unknown selected platform: " + selectedPlatform); + throw new IllegalStateException("Central Repo has an unknown selected platform: " + selectedDbChoice); } return true; } public DatabaseTestResult testStatus() { - if (selectedPlatform == CentralRepoPlatforms.POSTGRESQL) { + if (selectedDbChoice == CentralRepoPlatforms.POSTGRESQL) { if (dbSettingsPostgres.verifyConnection()) { if (dbSettingsPostgres.verifyDatabaseExists()) { if (dbSettingsPostgres.verifyDatabaseSchema()) { @@ -386,7 +417,7 @@ public class CentralRepoDbManager { } else { testingStatus = DatabaseTestResult.CONNECTION_FAILED; } - } else if (selectedPlatform == CentralRepoPlatforms.SQLITE) { + } else if (selectedDbChoice == CentralRepoPlatforms.SQLITE) { if (dbSettingsSqlite.dbFileExists()) { if (dbSettingsSqlite.verifyConnection()) { if (dbSettingsSqlite.verifyDatabaseSchema()) { diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoPlatforms.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoPlatforms.java index 23a1ea925e..b9c1a7b4e7 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoPlatforms.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoPlatforms.java @@ -18,106 +18,11 @@ */ package org.sleuthkit.autopsy.centralrepository.datamodel; -import org.sleuthkit.autopsy.coreutils.ModuleSettings; - /** * */ public enum CentralRepoPlatforms { - DISABLED("Disabled", true), - SQLITE("SQLite", false), - POSTGRESQL("PostgreSQL", false); - - private final String platformName; - private Boolean selected; - - CentralRepoPlatforms(String name, Boolean selected) { - this.platformName = name; - this.selected = selected; - loadSettings(); - } - - /** - * Load the selectedPlatform boolean from the config file, if it is set. - */ - private void loadSettings() { - String selectedPlatformString = ModuleSettings.getConfigSetting("CentralRepository", "db.selectedPlatform"); // NON-NLS - - if (null != selectedPlatformString) { - selected = this.toString().equalsIgnoreCase(selectedPlatformString); - } else if (this == DISABLED) { - selected = true; - } - } - - @Override - public String toString() { - return platformName; - } - - private void setSelected(Boolean selected) { - this.selected = selected; - } - - public Boolean isSelected() { - return selected; - } - - public static CentralRepoPlatforms fromString(String pName) { - if (null == pName) { - return DISABLED; - } - - for (CentralRepoPlatforms p : CentralRepoPlatforms.values()) { - if (p.toString().equalsIgnoreCase(pName)) { - return p; - } - } - return DISABLED; - } - - /** - * Save the selected platform to the config file. - */ - public static void saveSelectedPlatform() { - CentralRepoPlatforms selectedPlatform = DISABLED; - for (CentralRepoPlatforms p : CentralRepoPlatforms.values()) { - if (p.isSelected()) { - selectedPlatform = p; - } - } - ModuleSettings.setConfigSetting("CentralRepository", "db.selectedPlatform", selectedPlatform.name()); // NON-NLS - } - - /** - * Set the selected db platform. Other platforms will be set as not - * selected. - * - * @param platformString The name of the selected platform. - */ - public static void setSelectedPlatform(String platformString) { - CentralRepoPlatforms pSelected = CentralRepoPlatforms.fromString(platformString); - for (CentralRepoPlatforms p : CentralRepoPlatforms.values()) { - p.setSelected(p == pSelected); - } - } - - public static void setSelectedPlatform(CentralRepoPlatforms platform) { - setSelectedPlatform(platform.toString()); - } - - /** - * Get the selected platform. - * - * @return The selected platform, or if not platform is selected, default to - * DISABLED. - */ - public static CentralRepoPlatforms getSelectedPlatform() { - for (CentralRepoPlatforms p : CentralRepoPlatforms.values()) { - if (p.isSelected()) { - return p; - } - } - return DISABLED; - } + DISABLED, + SQLITE, + POSTGRESQL } diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepository.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepository.java index 3e7ac158a9..3311c8d957 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepository.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepository.java @@ -41,7 +41,7 @@ public interface CentralRepository { CentralRepoPlatforms selectedPlatform = CentralRepoPlatforms.DISABLED; if (CentralRepoDbUtil.allowUseOfCentralRepository()) { - selectedPlatform = CentralRepoPlatforms.getSelectedPlatform(); + selectedPlatform = CentralRepoDbManager.getSavedDbChoice().getDbPlatform(); } switch (selectedPlatform) { case POSTGRESQL: diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/RdbmsCentralRepo.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/RdbmsCentralRepo.java index 513fd3f944..fa10ee7e11 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/RdbmsCentralRepo.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/RdbmsCentralRepo.java @@ -3332,7 +3332,7 @@ abstract class RdbmsCentralRepo implements CentralRepository { conn = connect(false); conn.setAutoCommit(false); statement = conn.createStatement(); - selectedPlatform = CentralRepoPlatforms.getSelectedPlatform(); + selectedPlatform = CentralRepoDbManager.getSavedDbChoice().getDbPlatform(); int minorVersion = 0; String minorVersionStr = null; resultSet = statement.executeQuery("SELECT value FROM db_info WHERE name='" + RdbmsCentralRepo.SCHEMA_MINOR_VERSION_KEY + "'"); diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/CentralRepoIngestModule.java b/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/CentralRepoIngestModule.java index e561aeeff6..a3fba73778 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/CentralRepoIngestModule.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/CentralRepoIngestModule.java @@ -33,6 +33,7 @@ import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationDataSource; import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeUtil; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoException; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoPlatforms; +import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoDbChoice; import org.sleuthkit.autopsy.centralrepository.eventlisteners.IngestEventsListener; import org.sleuthkit.autopsy.core.RuntimeProperties; import org.sleuthkit.autopsy.coreutils.Logger; @@ -274,7 +275,7 @@ final class CentralRepoIngestModule implements FileIngestModule { // Don't allow sqlite central repo databases to be used for multi user cases if ((autopsyCase.getCaseType() == Case.CaseType.MULTI_USER_CASE) - && (CentralRepoPlatforms.getSelectedPlatform() == CentralRepoPlatforms.SQLITE)) { + && (CentralRepoDbManager.getSavedDbChoice().getDbPlatform() == CentralRepoPlatforms.SQLITE)) { logger.log(Level.SEVERE, "Cannot run correlation engine on a multi-user case with a SQLite central repository."); throw new IngestModuleException("Cannot run on a multi-user case with a SQLite central repository."); // NON-NLS } diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.form b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.form index 27eae7629c..2e9b63530e 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.form +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.form @@ -138,7 +138,7 @@ - + @@ -146,7 +146,7 @@ - + @@ -320,7 +320,7 @@ - + @@ -330,7 +330,7 @@ - + diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java index 25289da2af..b041912565 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java @@ -38,11 +38,11 @@ import org.netbeans.spi.options.OptionsPanelController; import org.openide.util.NbBundle; import org.openide.util.NbBundle.Messages; import org.openide.windows.WindowManager; +import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoDbChoice; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoDbManager; import org.sleuthkit.autopsy.corecomponents.TextPrompt; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoException; -import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoPlatforms; import org.sleuthkit.autopsy.centralrepository.datamodel.DatabaseTestResult; import org.sleuthkit.autopsy.centralrepository.datamodel.SqliteCentralRepoSettings; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository; @@ -95,11 +95,20 @@ public class EamDbSettingsDialog extends JDialog { return "Directories and Central Repository databases"; } }); - cbDatabaseType.setSelectedItem(manager.getSelectedPlatform()); + + setSelectedChoice(manager); customizeComponents(); valid(); display(); + } + private void setSelectedChoice(CentralRepoDbManager manager) { + CentralRepoDbChoice toSelect = + (Arrays.asList(CentralRepoDbChoice.DB_CHOICES).contains(manager.getSelectedDbChoice())) ? + manager.getSelectedDbChoice() : + CentralRepoDbChoice.DB_CHOICES[0]; + + cbDatabaseType.setSelectedItem(toSelect); } @@ -281,7 +290,7 @@ public class EamDbSettingsDialog extends JDialog { jpDbPassword.setPreferredSize(new java.awt.Dimension(509, 20)); - cbDatabaseType.setModel(new javax.swing.DefaultComboBoxModel<>(new CentralRepoPlatforms[]{CentralRepoPlatforms.POSTGRESQL, CentralRepoPlatforms.SQLITE})); + cbDatabaseType.setModel(new javax.swing.DefaultComboBoxModel<>(org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoDbChoice.DB_CHOICES)); cbDatabaseType.setPreferredSize(new java.awt.Dimension(120, 20)); cbDatabaseType.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { @@ -323,17 +332,17 @@ public class EamDbSettingsDialog extends JDialog { .addComponent(lbUserName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(lbPort, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addGroup(pnSQLiteSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false) - .addComponent(lbDatabaseDesc, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(lbDatabaseDesc, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 94, Short.MAX_VALUE) .addComponent(lbUserPassword, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))) .addGap(10, 10, 10) - .addGroup(pnSQLiteSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(pnSQLiteSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) .addGroup(pnSQLiteSettingsLayout.createSequentialGroup() .addComponent(tfDatabasePath, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(bnDatabasePathFileOpen)) .addGroup(pnSQLiteSettingsLayout.createSequentialGroup() .addComponent(cbDatabaseType, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(lbSingleUserSqLite, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addComponent(jpDbPassword, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(tbDbUsername, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) @@ -414,15 +423,20 @@ public class EamDbSettingsDialog extends JDialog { setTextPrompts(); setTextBoxListeners(); manager.clearStatus(); - if (manager.getSelectedPlatform() == CentralRepoPlatforms.SQLITE) { + if (manager.getSelectedDbChoice() == CentralRepoDbChoice.SQLITE) { updatePostgresFields(false); updateSqliteFields(true); } - else { + else if (manager.getSelectedDbChoice() == CentralRepoDbChoice.POSTGRESQL_CUSTOM) { updatePostgresFields(true); updateSqliteFields(false); } - displayDatabaseSettings(CentralRepoPlatforms.POSTGRESQL.equals(manager.getSelectedPlatform())); + else { + updatePostgresFields(false); + updateSqliteFields(false); + } + + displayDatabaseSettings(CentralRepoDbChoice.POSTGRESQL_CUSTOM.equals(manager.getSelectedDbChoice())); } private void display() { @@ -497,7 +511,7 @@ public class EamDbSettingsDialog extends JDialog { private void cbDatabaseTypeActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cbDatabaseTypeActionPerformed - manager.setSelectedPlatform((CentralRepoPlatforms) cbDatabaseType.getSelectedItem()); + manager.setSelctedDbChoice((CentralRepoDbChoice) cbDatabaseType.getSelectedItem()); customizeComponents(); }//GEN-LAST:event_cbDatabaseTypeActionPerformed @@ -610,14 +624,14 @@ public class EamDbSettingsDialog extends JDialog { @Messages({"EamDbSettingsDialog.validation.incompleteFields=Fill in all values for the selected database."}) private boolean databaseFieldsArePopulated() { boolean result = true; - if (manager.getSelectedPlatform() == CentralRepoPlatforms.POSTGRESQL) { + if (manager.getSelectedDbChoice() == CentralRepoDbChoice.POSTGRESQL_CUSTOM) { result = !tbDbHostname.getText().trim().isEmpty() && !tbDbPort.getText().trim().isEmpty() // && !tbDbName.getText().trim().isEmpty() && !tbDbUsername.getText().trim().isEmpty() && 0 < jpDbPassword.getPassword().length; } - else if (manager.getSelectedPlatform() == CentralRepoPlatforms.SQLITE) { + else if (manager.getSelectedDbChoice() == CentralRepoDbChoice.SQLITE) { result = !tfDatabasePath.getText().trim().isEmpty(); } @@ -722,7 +736,7 @@ public class EamDbSettingsDialog extends JDialog { private javax.swing.JButton bnDatabasePathFileOpen; private javax.swing.ButtonGroup bnGrpDatabasePlatforms; private javax.swing.JButton bnOk; - private javax.swing.JComboBox cbDatabaseType; + private javax.swing.JComboBox cbDatabaseType; private javax.swing.JScrollPane dataBaseFileScrollPane; private javax.swing.JTextArea dataBaseFileTextArea; private javax.swing.JFileChooser fcDatabasePath; diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java index b3499250c9..129091b60c 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java @@ -33,12 +33,12 @@ import org.openide.util.NbBundle.Messages; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoDbManager; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoException; +import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoPlatforms; import org.sleuthkit.autopsy.corecomponents.OptionsPanel; import org.sleuthkit.autopsy.events.AutopsyEvent; import org.sleuthkit.autopsy.ingest.IngestManager; import org.sleuthkit.autopsy.ingest.IngestModuleGlobalSettingsPanel; -import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoPlatforms; -import static org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoPlatforms.DISABLED; +import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoDbChoice; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoDbUtil; import org.sleuthkit.autopsy.centralrepository.datamodel.PostgresCentralRepoSettings; import org.sleuthkit.autopsy.centralrepository.datamodel.SqliteCentralRepoSettings; @@ -110,7 +110,7 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i "GlobalSettingsPanel.onMultiUserChange.disabledMu.description=Since mult-user cases have been disabled, 'PostgreSQL using multi-user settings' is no longer a valid option for Central Repository." }) public static void onMultiUserChange(Component parent, boolean muPreviouslySelected, boolean muCurrentlySelected) { - boolean crMultiUser = CentralRepoPlatforms.getSelectedPlatform() == CentralRepoPlatforms.POSTGRESQL_MULTIUSER; + boolean crMultiUser = CentralRepoDbManager.getSavedDbChoice() == CentralRepoDbChoice.POSTGRESQL_MULTIUSER; if (!muPreviouslySelected && muCurrentlySelected) { if (JOptionPane.YES_OPTION == JOptionPane.showConfirmDialog(parent, @@ -119,7 +119,7 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i JOptionPane.YES_NO_OPTION)) { // setup database for CR - CentralRepoPlatforms.setSelectedPlatform(CentralRepoPlatforms.POSTGRESQL_MULTIUSER); + CentralRepoDbManager.saveDbChoice(CentralRepoDbChoice.POSTGRESQL_MULTIUSER); updateDatabase(parent); } } @@ -135,7 +135,7 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i } else { // disable central repository - CentralRepoPlatforms.setSelectedPlatform(CentralRepoPlatforms.DISABLED); + CentralRepoDbManager.saveDbChoice(CentralRepoDbChoice.DISABLED); } } // changing multi-user settings connection && 'PostgreSQL using multi-user settings' is selected @@ -147,7 +147,7 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i @Messages({"GlobalSettingsPanel.updateFailed.title=Central repository disabled"}) private static void updateDatabase(Component parent) { - if (CentralRepoPlatforms.getSelectedPlatform().equals(DISABLED)) { + if (CentralRepoDbManager.getSelectedChoice().equals(CentralRepoDbChoice.DISABLED)) { return; } parent.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); @@ -522,31 +522,30 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i public void load() { tbOops.setText(""); enableButtonSubComponents(false); - CentralRepoPlatforms selectedPlatform = CentralRepoPlatforms.getSelectedPlatform(); + CentralRepoDbChoice selectedChoice = CentralRepoDbManager.getSavedDbChoice(); cbUseCentralRepo.setSelected(CentralRepoDbUtil.allowUseOfCentralRepository()); // NON-NLS - switch (selectedPlatform) { - case POSTGRESQL: + + lbDbPlatformValue.setText(selectedChoice.getTitle()); + CentralRepoPlatforms selectedDb = selectedChoice.getDbPlatform(); + + if (selectedChoice == null || selectedDb == CentralRepoPlatforms.DISABLED) { + lbDbNameValue.setText(""); + lbDbLocationValue.setText(""); + tbOops.setText(Bundle.GlobalSettingsPanel_validationerrMsg_mustConfigure()); + } + else { + enableButtonSubComponents(cbUseCentralRepo.isSelected()); + if (selectedDb == CentralRepoPlatforms.POSTGRESQL) { PostgresCentralRepoSettings dbSettingsPg = new PostgresCentralRepoSettings(); - lbDbPlatformValue.setText(CentralRepoPlatforms.POSTGRESQL.toString()); lbDbNameValue.setText(dbSettingsPg.getDbName()); lbDbLocationValue.setText(dbSettingsPg.getHost()); - enableButtonSubComponents(cbUseCentralRepo.isSelected()); - break; - case SQLITE: + } + else if (selectedDb == CentralRepoPlatforms.SQLITE) { SqliteCentralRepoSettings dbSettingsSqlite = new SqliteCentralRepoSettings(); - lbDbPlatformValue.setText(CentralRepoPlatforms.SQLITE.toString()); lbDbNameValue.setText(dbSettingsSqlite.getDbName()); lbDbLocationValue.setText(dbSettingsSqlite.getDbDirectory()); - enableButtonSubComponents(cbUseCentralRepo.isSelected()); - break; - default: - lbDbPlatformValue.setText(CentralRepoPlatforms.DISABLED.toString()); - lbDbNameValue.setText(""); - lbDbLocationValue.setText(""); - tbOops.setText(Bundle.GlobalSettingsPanel_validationerrMsg_mustConfigure()); - break; + } } - } @Override From ab8473db4e59544b237fb1622e279282c5b7431a Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Wed, 26 Feb 2020 16:05:07 -0500 Subject: [PATCH 007/100] fixed some build errors --- .../datamodel/CentralRepoDbManager.java | 70 +++++++++---------- .../datamodel/CentralRepository.java | 2 +- .../ingestmodule/CentralRepoIngestModule.java | 1 + .../optionspanel/EamDbSettingsDialog.java | 22 +++--- .../optionspanel/GlobalSettingsPanel.java | 4 +- 5 files changed, 48 insertions(+), 51 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java index 6af0072de7..73a1a53c7d 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java @@ -24,6 +24,7 @@ import java.util.logging.Level; import org.openide.util.NbBundle; import org.sleuthkit.autopsy.coordinationservice.CoordinationService; import org.sleuthkit.autopsy.coreutils.Logger; +import org.sleuthkit.autopsy.coreutils.ModuleSettings; /** * Contains business logic for saving and validating settings for central repo @@ -249,29 +250,25 @@ public class CentralRepoDbManager { } private CentralRepoDbSettings getSelectedSettings() throws CentralRepoException { - switch (selectedDbChoice) { - case POSTGRESQL: - return dbSettingsPostgres; - case SQLITE: - return dbSettingsSqlite; - case DISABLED: - return null; - default: - throw new CentralRepoException("Unknown database type: " + selectedDbChoice); - } + if (selectedDbChoice == CentralRepoDbChoice.POSTGRESQL_CUSTOM) + return dbSettingsPostgres; + if (selectedDbChoice == CentralRepoDbChoice.SQLITE) + return dbSettingsSqlite; + if (selectedDbChoice == CentralRepoDbChoice.DISABLED) + return null; + + throw new CentralRepoException("Unknown database type: " + selectedDbChoice); } private RdbmsCentralRepoFactory getDbFactory() throws CentralRepoException { - switch (selectedDbChoice) { - case POSTGRESQL: - return new RdbmsCentralRepoFactory(selectedDbChoice, dbSettingsPostgres); - case SQLITE: - return new RdbmsCentralRepoFactory(selectedDbChoice, dbSettingsSqlite); - case DISABLED: - return null; - default: - throw new CentralRepoException("Unknown database type: " + selectedDbChoice); - } + if (selectedDbChoice == CentralRepoDbChoice.POSTGRESQL_CUSTOM) + return new RdbmsCentralRepoFactory(CentralRepoPlatforms.POSTGRESQL, dbSettingsPostgres); + if (selectedDbChoice == CentralRepoDbChoice.SQLITE) + return new RdbmsCentralRepoFactory(CentralRepoPlatforms.SQLITE, dbSettingsSqlite); + if (selectedDbChoice == CentralRepoDbChoice.DISABLED) + return null; + + throw new CentralRepoException("Unknown database type: " + selectedDbChoice); } public boolean createDb() throws CentralRepoException { @@ -382,28 +379,27 @@ public class CentralRepoDbManager { public boolean testDatabaseSettingsAreValid( String tbDbHostname, String tbDbPort, String tbDbUsername, String tfDatabasePath, String jpDbPassword) throws CentralRepoException, NumberFormatException { - switch (selectedDbChoice) { - case POSTGRESQL: - dbSettingsPostgres.setHost(tbDbHostname); - dbSettingsPostgres.setPort(Integer.parseInt(tbDbPort)); - dbSettingsPostgres.setDbName(CENTRAL_REPO_DB_NAME); - dbSettingsPostgres.setUserName(tbDbUsername); - dbSettingsPostgres.setPassword(jpDbPassword); - break; - case SQLITE: - File databasePath = new File(tfDatabasePath); - dbSettingsSqlite.setDbName(SqliteCentralRepoSettings.DEFAULT_DBNAME); - dbSettingsSqlite.setDbDirectory(databasePath.getPath()); - break; - default: - throw new IllegalStateException("Central Repo has an unknown selected platform: " + selectedDbChoice); + if (selectedDbChoice == CentralRepoDbChoice.POSTGRESQL_CUSTOM) { + dbSettingsPostgres.setHost(tbDbHostname); + dbSettingsPostgres.setPort(Integer.parseInt(tbDbPort)); + dbSettingsPostgres.setDbName(CENTRAL_REPO_DB_NAME); + dbSettingsPostgres.setUserName(tbDbUsername); + dbSettingsPostgres.setPassword(jpDbPassword); + } + else if (selectedDbChoice == CentralRepoDbChoice.SQLITE) { + File databasePath = new File(tfDatabasePath); + dbSettingsSqlite.setDbName(SqliteCentralRepoSettings.DEFAULT_DBNAME); + dbSettingsSqlite.setDbDirectory(databasePath.getPath()); + } + else { + throw new IllegalStateException("Central Repo has an unknown selected platform: " + selectedDbChoice); } return true; } public DatabaseTestResult testStatus() { - if (selectedDbChoice == CentralRepoPlatforms.POSTGRESQL) { + if (selectedDbChoice == CentralRepoDbChoice.POSTGRESQL_CUSTOM) { if (dbSettingsPostgres.verifyConnection()) { if (dbSettingsPostgres.verifyDatabaseExists()) { if (dbSettingsPostgres.verifyDatabaseSchema()) { @@ -417,7 +413,7 @@ public class CentralRepoDbManager { } else { testingStatus = DatabaseTestResult.CONNECTION_FAILED; } - } else if (selectedDbChoice == CentralRepoPlatforms.SQLITE) { + } else if (selectedDbChoice == CentralRepoDbChoice.SQLITE) { if (dbSettingsSqlite.dbFileExists()) { if (dbSettingsSqlite.verifyConnection()) { if (dbSettingsSqlite.verifyDatabaseSchema()) { diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepository.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepository.java index 3311c8d957..65d9c028f6 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepository.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepository.java @@ -92,7 +92,7 @@ public interface CentralRepository { */ static boolean isEnabled() { return CentralRepoDbUtil.allowUseOfCentralRepository() - && CentralRepoPlatforms.getSelectedPlatform() != CentralRepoPlatforms.DISABLED; + && CentralRepoDbManager.getSavedDbChoice() != CentralRepoDbChoice.DISABLED; } /** diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/CentralRepoIngestModule.java b/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/CentralRepoIngestModule.java index a3fba73778..4754f77b3e 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/CentralRepoIngestModule.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/CentralRepoIngestModule.java @@ -34,6 +34,7 @@ import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeUti import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoException; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoPlatforms; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoDbChoice; +import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoDbManager; import org.sleuthkit.autopsy.centralrepository.eventlisteners.IngestEventsListener; import org.sleuthkit.autopsy.core.RuntimeProperties; import org.sleuthkit.autopsy.coreutils.Logger; diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java index b041912565..5cf4f62820 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java @@ -23,6 +23,7 @@ import java.awt.Cursor; import java.io.File; import java.io.IOException; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.logging.Level; import javax.swing.JDialog; @@ -43,6 +44,7 @@ import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoDbManager; import org.sleuthkit.autopsy.corecomponents.TextPrompt; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoException; +import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoPlatforms; import org.sleuthkit.autopsy.centralrepository.datamodel.DatabaseTestResult; import org.sleuthkit.autopsy.centralrepository.datamodel.SqliteCentralRepoSettings; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository; @@ -149,17 +151,15 @@ public class EamDbSettingsDialog extends JDialog { } catch (CentralRepoException e) { // in the event that there is a failure to connect, notify user with corresponding message - String errorMessage; - switch (manager.getSelectedPlatform()) { - case POSTGRESQL: - errorMessage = Bundle.EamDbSettingsDialog_okButton_createPostgresDbError_message(); - break; - case SQLITE: - errorMessage = Bundle.EamDbSettingsDialog_okButton_createSQLiteDbError_message(); - break; - default: - errorMessage = ""; - break; + String errorMessage = ""; + if (manager == null || manager.getSelectedDbChoice() == null) { + errorMessage = ""; + } + else if (manager.getSelectedDbChoice().getDbPlatform() == CentralRepoPlatforms.POSTGRESQL) { + errorMessage = Bundle.EamDbSettingsDialog_okButton_createPostgresDbError_message(); + } + else if (manager.getSelectedDbChoice().getDbPlatform() == CentralRepoPlatforms.SQLITE) { + errorMessage = Bundle.EamDbSettingsDialog_okButton_createSQLiteDbError_message(); } JOptionPane.showMessageDialog(WindowManager.getDefault().getMainWindow(), diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java index 129091b60c..22891da01d 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java @@ -147,7 +147,7 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i @Messages({"GlobalSettingsPanel.updateFailed.title=Central repository disabled"}) private static void updateDatabase(Component parent) { - if (CentralRepoDbManager.getSelectedChoice().equals(CentralRepoDbChoice.DISABLED)) { + if (CentralRepoDbChoice.DISABLED.equals(CentralRepoDbManager.getSavedDbChoice())) { return; } parent.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); @@ -559,7 +559,7 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i * @return true if it's okay, false otherwise. */ public boolean valid() { - return !cbUseCentralRepo.isSelected() || !lbDbPlatformValue.getText().equals(DISABLED.toString()); + return !cbUseCentralRepo.isSelected() || !lbDbPlatformValue.getText().equals(CentralRepoDbChoice.DISABLED.toString()); } @Override From 7dba95ed2f561a79c136cad86b15743f34d1aa06 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Thu, 27 Feb 2020 12:17:52 -0500 Subject: [PATCH 008/100] working through refactoring postgres settings in central repo --- ... => CentralRepoDbConnectivityManager.java} | 4 +- .../datamodel/CentralRepoDbManager.java | 6 +- .../CentralRepoPostgresSettingsManager.java | 153 +++++++++++++ .../PostgresCentralRepoSettings.java | 215 ++++-------------- .../datamodel/PostgresConnectionSettings.java | 166 ++++++++++++++ .../datamodel/SqliteCentralRepoSettings.java | 2 +- 6 files changed, 362 insertions(+), 184 deletions(-) rename Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/{CentralRepoDbSettings.java => CentralRepoDbConnectivityManager.java} (95%) create mode 100644 Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoPostgresSettingsManager.java create mode 100644 Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresConnectionSettings.java diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbSettings.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbConnectivityManager.java similarity index 95% rename from Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbSettings.java rename to Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbConnectivityManager.java index f9bf520654..6744b70541 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbSettings.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbConnectivityManager.java @@ -21,10 +21,8 @@ package org.sleuthkit.autopsy.centralrepository.datamodel; /** * common interface for settings pertaining to the database in central repository */ -public interface CentralRepoDbSettings { +public interface CentralRepoDbConnectivityManager { - void saveSettings(); - boolean createDatabase(); boolean deleteDatabase(); diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java index 73a1a53c7d..80763a86f8 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java @@ -249,7 +249,7 @@ public class CentralRepoDbManager { return configurationChanged; } - private CentralRepoDbSettings getSelectedSettings() throws CentralRepoException { + private CentralRepoDbConnectivityManager getSelectedSettings() throws CentralRepoException { if (selectedDbChoice == CentralRepoDbChoice.POSTGRESQL_CUSTOM) return dbSettingsPostgres; if (selectedDbChoice == CentralRepoDbChoice.SQLITE) @@ -275,7 +275,7 @@ public class CentralRepoDbManager { boolean result = false; boolean dbCreated = true; - CentralRepoDbSettings selectedDbSettings = getSelectedSettings(); + CentralRepoDbConnectivityManager selectedDbSettings = getSelectedSettings(); if (!selectedDbSettings.verifyDatabaseExists()) { dbCreated = selectedDbSettings.createDatabase(); @@ -336,7 +336,7 @@ public class CentralRepoDbManager { // start with the new settings. saveDbChoice(selectedDbChoice); - CentralRepoDbSettings selectedDbSettings = getSelectedSettings(); + CentralRepoDbConnectivityManager selectedDbSettings = getSelectedSettings(); // save the new settings selectedDbSettings.saveSettings(); diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoPostgresSettingsManager.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoPostgresSettingsManager.java new file mode 100644 index 0000000000..b4feffbcd9 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoPostgresSettingsManager.java @@ -0,0 +1,153 @@ +/* + * 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.centralrepository.datamodel; + +import java.util.HashMap; +import java.util.Map; +import java.util.logging.Level; +import org.openide.util.Exceptions; +import org.sleuthkit.autopsy.core.UserPreferences; +import org.sleuthkit.autopsy.core.UserPreferencesException; +import org.sleuthkit.autopsy.coreutils.Logger; +import org.sleuthkit.autopsy.coreutils.ModuleSettings; +import org.sleuthkit.autopsy.coreutils.TextConverter; +import org.sleuthkit.autopsy.coreutils.TextConverterException; +import org.sleuthkit.datamodel.CaseDbConnectionInfo; + +/** + * + * @author gregd + */ +public class CentralRepoPostgresSettingsManager { + private final static Logger LOGGER = Logger.getLogger(CentralRepoPostgresSettingsManager.class.getName()); + + private final static String DEFAULT_HOST = ""; // NON-NLS + private final static int DEFAULT_PORT = 5432; + private final static String DEFAULT_DBNAME = "central_repository"; // NON-NLS + private final static String DEFAULT_USERNAME = ""; + private final static String DEFAULT_PASSWORD = ""; + + private static final String PASSWORD_KEY = "db.postgresql.password"; + private static final String BULK_THRESHOLD_KEY = "db.postgresql.bulkThreshold"; + private static final String PORT_KEY = "db.postgresql.port"; + private static final String USER_KEY = "db.postgresql.user"; + private static final String DBNAME_KEY = "db.postgresql.dbName"; + private static final String HOST_KEY = "db.postgresql.host"; + + private static final String MODULE_KEY = "CentralRepository"; + + + + private static String valOrDefault(String val, String defaultVal) { + if (val == null || val.isEmpty()) + return defaultVal; + + return val; + } + + private static int valOrDefault(String val, int defaultVal, Integer min, Integer max) { + try { + if (val == null || val.isEmpty()) { + return defaultVal; + } else { + int retVal = Integer.parseInt(val); + if ((min != null && retVal < min) || (max != null && retVal > max)) { + return defaultVal; + } + else { + return retVal; + } + } + } catch (NumberFormatException ex) { + return defaultVal; + } + } + + private static void handleTry(TryHandler handler) { + try { + handler.op(); + } + catch (CentralRepoException e) {} + } + + private interface TryHandler { + public void op() throws CentralRepoException; + } + + + public static PostgresConnectionSettings loadMultiUserSettings() { + PostgresConnectionSettings settings = new PostgresConnectionSettings(); + + CaseDbConnectionInfo muConn; + try { + muConn = UserPreferences.getDatabaseConnectionInfo(); + } catch (UserPreferencesException ex) { + LOGGER.log(Level.SEVERE, "Failed to import settings from multi-user settings.", ex); + return settings; + } + + handleTry(() -> settings.setHost(valOrDefault(muConn.getHost(), DEFAULT_HOST))); + handleTry(() -> settings.setDbName(DEFAULT_DBNAME)); + handleTry(() -> settings.setUserName(valOrDefault(muConn.getUserName(), DEFAULT_USERNAME))); + + handleTry(() -> settings.setPort(valOrDefault(muConn.getPort(), DEFAULT_PORT, 1, 65535))); + handleTry(() -> settings.setBulkThreshold(RdbmsCentralRepo.DEFAULT_BULK_THRESHHOLD)); + + handleTry(() -> settings.setPassword(valOrDefault(muConn.getPassword(), DEFAULT_PASSWORD))); + + return settings; + } + + + public static PostgresConnectionSettings loadSettings() { + PostgresConnectionSettings settings = new PostgresConnectionSettings(); + Map keyVals = ModuleSettings.getConfigSettings(MODULE_KEY); + + + handleTry(() -> settings.setHost(valOrDefault(keyVals.get(HOST_KEY), DEFAULT_HOST))); + handleTry(() -> settings.setDbName(valOrDefault(keyVals.get(DBNAME_KEY), DEFAULT_DBNAME))); + handleTry(() -> settings.setUserName(valOrDefault(keyVals.get(USER_KEY), DEFAULT_USERNAME))); + + handleTry(() -> settings.setPort(valOrDefault(keyVals.get(PORT_KEY), DEFAULT_PORT, 1, 65535))); + handleTry(() -> settings.setBulkThreshold(valOrDefault(keyVals.get(BULK_THRESHOLD_KEY), RdbmsCentralRepo.DEFAULT_BULK_THRESHHOLD, 1, null))); + + String passwordHex = keyVals.get(PASSWORD_KEY); + String password; + try { + password = TextConverter.convertHexTextToText(passwordHex); + } catch (TextConverterException ex) { + LOGGER.log(Level.WARNING, "Failed to convert password from hex text to text.", ex); + password = DEFAULT_PASSWORD; + } + + final String finalPassword = password; + + handleTry(() -> settings.setPassword(finalPassword)); + return settings; + } + + public static void saveSettings(PostgresConnectionSettings settings) { + Map map = new HashMap(); + map.put(HOST_KEY, settings.getHost()); + map.put(PORT_KEY, Integer.toString(settings.getPort())); + map.put(DBNAME_KEY, settings.getDbName()); + map.put(BULK_THRESHOLD_KEY, Integer.toString(settings.getBulkThreshold())); + map.put(USER_KEY, settings.getUserName()); + try { + map.put(PASSWORD_KEY, TextConverter.convertTextToHexText(settings.getPassword())); // NON-NLS + } catch (TextConverterException ex) { + LOGGER.log(Level.SEVERE, "Failed to convert password from text to hex text.", ex); + } + + ModuleSettings.setConfigSettings(MODULE_KEY, map); + } + + + public static boolean isChanged(PostgresConnectionSettings settings) { + PostgresConnectionSettings saved = loadSettings(); + return saved.equals(settings); + } +} diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresCentralRepoSettings.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresCentralRepoSettings.java index 476b67dbc2..54855fb250 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresCentralRepoSettings.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresCentralRepoSettings.java @@ -24,7 +24,6 @@ import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; -import java.util.List; import java.util.Properties; import java.util.logging.Level; import java.util.regex.Pattern; @@ -32,7 +31,6 @@ import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.ModuleSettings; import org.sleuthkit.autopsy.coreutils.TextConverter; import org.sleuthkit.autopsy.coreutils.TextConverterException; -import static org.sleuthkit.autopsy.centralrepository.datamodel.RdbmsCentralRepo.SOFTWARE_CR_DB_SCHEMA_VERSION; /** * Settings for the Postgres implementation of the Central Repository database @@ -40,28 +38,18 @@ import static org.sleuthkit.autopsy.centralrepository.datamodel.RdbmsCentralRepo * NOTE: This is public scope because the options panel calls it directly to * set/get */ -public final class PostgresCentralRepoSettings implements CentralRepoDbSettings { +public final class PostgresCentralRepoSettings implements CentralRepoDbConnectivityManager { private final static Logger LOGGER = Logger.getLogger(PostgresCentralRepoSettings.class.getName()); - private final static String DEFAULT_HOST = ""; // NON-NLS - private final static int DEFAULT_PORT = 5432; - private final static String DEFAULT_DBNAME = "central_repository"; // NON-NLS - private final static String DEFAULT_USERNAME = ""; - private final static String DEFAULT_PASSWORD = ""; private final static String VALIDATION_QUERY = "SELECT version()"; // NON-NLS private final static String JDBC_BASE_URI = "jdbc:postgresql://"; // NON-NLS private final static String JDBC_DRIVER = "org.postgresql.Driver"; // NON-NLS - private final static String DB_NAMES_REGEX = "[a-z][a-z0-9_]*"; // only lower case - private final static String DB_USER_NAMES_REGEX = "[a-zA-Z]\\w*"; - private String host; - private int port; - private String dbName; - private int bulkThreshold; - private String userName; - private String password; - - public PostgresCentralRepoSettings() { - loadSettings(); + + + private final PostgresConnectionSettings connSettings; + + public PostgresCentralRepoSettings(PostgresConnectionSettings connSettings) { + this.connSettings = connSettings; } @Override @@ -70,76 +58,29 @@ public final class PostgresCentralRepoSettings implements CentralRepoDbSettings getHost(), getPort(), getDbName(), getUserName()); } - public void loadSettings() { - host = ModuleSettings.getConfigSetting("CentralRepository", "db.postgresql.host"); // NON-NLS - if (host == null || host.isEmpty()) { - host = DEFAULT_HOST; - } - - try { - String portString = ModuleSettings.getConfigSetting("CentralRepository", "db.postgresql.port"); // NON-NLS - if (portString == null || portString.isEmpty()) { - port = DEFAULT_PORT; - } else { - port = Integer.parseInt(portString); - if (port < 0 || port > 65535) { - port = DEFAULT_PORT; - } - } - } catch (NumberFormatException ex) { - port = DEFAULT_PORT; - } - - dbName = ModuleSettings.getConfigSetting("CentralRepository", "db.postgresql.dbName"); // NON-NLS - if (dbName == null || dbName.isEmpty()) { - dbName = DEFAULT_DBNAME; - } - - try { - String bulkThresholdString = ModuleSettings.getConfigSetting("CentralRepository", "db.postgresql.bulkThreshold"); // NON-NLS - if (bulkThresholdString == null || bulkThresholdString.isEmpty()) { - this.bulkThreshold = RdbmsCentralRepo.DEFAULT_BULK_THRESHHOLD; - } else { - this.bulkThreshold = Integer.parseInt(bulkThresholdString); - if (getBulkThreshold() <= 0) { - this.bulkThreshold = RdbmsCentralRepo.DEFAULT_BULK_THRESHHOLD; - } - } - } catch (NumberFormatException ex) { - this.bulkThreshold = RdbmsCentralRepo.DEFAULT_BULK_THRESHHOLD; - } - - userName = ModuleSettings.getConfigSetting("CentralRepository", "db.postgresql.user"); // NON-NLS - if (userName == null || userName.isEmpty()) { - userName = DEFAULT_USERNAME; - } - - password = ModuleSettings.getConfigSetting("CentralRepository", "db.postgresql.password"); // NON-NLS - if (password == null || password.isEmpty()) { - password = DEFAULT_PASSWORD; - } else { - try { - password = TextConverter.convertHexTextToText(password); - } catch (TextConverterException ex) { - LOGGER.log(Level.WARNING, "Failed to convert password from hex text to text.", ex); - password = DEFAULT_PASSWORD; - } - } + + /** + * @return the VALIDATION_QUERY + */ + String getValidationQuery() { + return VALIDATION_QUERY; } - public void saveSettings() { - ModuleSettings.setConfigSetting("CentralRepository", "db.postgresql.host", getHost()); // NON-NLS - ModuleSettings.setConfigSetting("CentralRepository", "db.postgresql.port", Integer.toString(port)); // NON-NLS - ModuleSettings.setConfigSetting("CentralRepository", "db.postgresql.dbName", getDbName()); // NON-NLS - ModuleSettings.setConfigSetting("CentralRepository", "db.postgresql.bulkThreshold", Integer.toString(getBulkThreshold())); // NON-NLS - ModuleSettings.setConfigSetting("CentralRepository", "db.postgresql.user", getUserName()); // NON-NLS - try { - ModuleSettings.setConfigSetting("CentralRepository", "db.postgresql.password", TextConverter.convertTextToHexText(getPassword())); // NON-NLS - } catch (TextConverterException ex) { - LOGGER.log(Level.SEVERE, "Failed to convert password from text to hex text.", ex); - } + /** + * @return the POSTGRES_DRIVER + */ + String getDriver() { + return JDBC_DRIVER; } + /** + * @return the JDBC_BASE_URI + */ + String getJDBCBaseURI() { + return JDBC_BASE_URI; + } + + /** * Get the full connection URL as a String * @@ -301,73 +242,33 @@ public final class PostgresCentralRepoSettings implements CentralRepoDbSettings } - - - - - - - - - - - - - - - - - - - - - boolean isChanged() { - String hostString = ModuleSettings.getConfigSetting("CentralRepository", "db.postgresql.host"); // NON-NLS - String portString = ModuleSettings.getConfigSetting("CentralRepository", "db.postgresql.port"); // NON-NLS - String dbNameString = ModuleSettings.getConfigSetting("CentralRepository", "db.postgresql.dbName"); // NON-NLS - String bulkThresholdString = ModuleSettings.getConfigSetting("CentralRepository", "db.postgresql.bulkThreshold"); // NON-NLS - String userNameString = ModuleSettings.getConfigSetting("CentralRepository", "db.postgresql.user"); // NON-NLS - String userPasswordString = ModuleSettings.getConfigSetting("CentralRepository", "db.postgresql.password"); // NON-NLS - - return !host.equals(hostString) || !Integer.toString(port).equals(portString) - || !dbName.equals(dbNameString) || !Integer.toString(bulkThreshold).equals(bulkThresholdString) - || !userName.equals(userNameString) || !password.equals(userPasswordString); - } /** * @return the host */ public String getHost() { - return host; + return connSettings.getHost(); } /** * @param host the host to set */ public void setHost(String host) throws CentralRepoException { - if (null != host && !host.isEmpty()) { - this.host = host; - } else { - throw new CentralRepoException("Invalid host name. Cannot be empty."); // NON-NLS - } + connSettings.setHost(host); } /** * @return the port */ public int getPort() { - return port; + return connSettings.getPort(); } /** * @param port the port to set */ public void setPort(int port) throws CentralRepoException { - if (port > 0 && port < 65535) { - this.port = port; - } else { - throw new CentralRepoException("Invalid port. Must be a number greater than 0."); // NON-NLS - } + connSettings.setPort(port); } /** @@ -377,95 +278,55 @@ public final class PostgresCentralRepoSettings implements CentralRepoDbSettings * @return the dbName */ public String getDbName() { - return dbName.toLowerCase(); + return connSettings.getDbName() == null ? null : connSettings.getDbName().toLowerCase(); } /** * @param dbName the dbName to set */ public void setDbName(String dbName) throws CentralRepoException { - if (dbName == null || dbName.isEmpty()) { - throw new CentralRepoException("Invalid database name. Cannot be empty."); // NON-NLS - } else if (!Pattern.matches(DB_NAMES_REGEX, dbName)) { - throw new CentralRepoException("Invalid database name. Name must start with a lowercase letter and can only contain lowercase letters, numbers, and '_'."); // NON-NLS - } - - this.dbName = dbName.toLowerCase(); + connSettings.setDbName(dbName); } /** * @return the bulkThreshold */ int getBulkThreshold() { - return bulkThreshold; + return connSettings.getBulkThreshold(); } /** * @param bulkThreshold the bulkThreshold to set */ public void setBulkThreshold(int bulkThreshold) throws CentralRepoException { - if (bulkThreshold > 0) { - this.bulkThreshold = bulkThreshold; - } else { - throw new CentralRepoException("Invalid bulk threshold."); // NON-NLS - } + connSettings.setBulkThreshold(bulkThreshold); } /** * @return the userName */ public String getUserName() { - return userName; + return connSettings.getUserName(); } /** * @param userName the userName to set */ public void setUserName(String userName) throws CentralRepoException { - if (userName == null || userName.isEmpty()) { - throw new CentralRepoException("Invalid user name. Cannot be empty."); // NON-NLS - } else if (!Pattern.matches(DB_USER_NAMES_REGEX, userName)) { - throw new CentralRepoException("Invalid user name. Name must start with a letter and can only contain letters, numbers, and '_'."); // NON-NLS - } - this.userName = userName; + connSettings.setUserName(userName); } /** * @return the password */ public String getPassword() { - return password; + return connSettings.getPassword(); } /** * @param password the password to set */ public void setPassword(String password) throws CentralRepoException { - if (password == null || password.isEmpty()) { - throw new CentralRepoException("Invalid user password. Cannot be empty."); // NON-NLS - } - this.password = password; + connSettings.setPassword(password); } - - /** - * @return the VALIDATION_QUERY - */ - String getValidationQuery() { - return VALIDATION_QUERY; - } - - /** - * @return the POSTGRES_DRIVER - */ - String getDriver() { - return JDBC_DRIVER; - } - - /** - * @return the JDBC_BASE_URI - */ - String getJDBCBaseURI() { - return JDBC_BASE_URI; - } - } diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresConnectionSettings.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresConnectionSettings.java new file mode 100644 index 0000000000..2f22c8545b --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresConnectionSettings.java @@ -0,0 +1,166 @@ +/* + * 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.centralrepository.datamodel; + +import java.util.Objects; +import java.util.regex.Pattern; + +/** + * + * @author gregd + */ +public class PostgresConnectionSettings { + private final static String DB_NAMES_REGEX = "[a-z][a-z0-9_]*"; // only lower case + private final static String DB_USER_NAMES_REGEX = "[a-zA-Z]\\w*"; + + private String host; + private int port; + private String dbName; + private int bulkThreshold; + private String userName; + private String password; + + public String getHost() { + return host; + } + + public int getPort() { + return port; + } + + public String getDbName() { + return dbName; + } + + public int getBulkThreshold() { + return bulkThreshold; + } + + public String getUserName() { + return userName; + } + + public String getPassword() { + return password; + } + + + private static void validateStr(String s, String errMessage) throws CentralRepoException { + if (null == s || s.isEmpty()) + throw new CentralRepoException(errMessage); + } + + private static void validateRegex(String s, String pattern, String errMessage) throws CentralRepoException { + if (!Pattern.matches(pattern, s)) + throw new CentralRepoException(errMessage); + } + + private static void validateNum(int num, Integer min, Integer max, String errMessage) throws CentralRepoException { + if ((min != null && num < min) || (max != null && num > max)) + throw new CentralRepoException(errMessage); + } + + + /** + * @param host the host to set + */ + public void setHost(String host) throws CentralRepoException { + validateStr(host, "Invalid host name. Cannot be empty."); + this.host = host; + } + + + /** + * @param port the port to set + */ + public void setPort(int port) throws CentralRepoException { + validateNum(port, 1, 65535, "Invalid port. Must be a number greater than 0."); + this.port = port; + } + + + /** + * @param dbName the dbName to set + */ + public void setDbName(String dbName) throws CentralRepoException { + validateStr(dbName, "Invalid database name. Cannot be empty."); // NON-NLS + validateRegex(dbName, DB_NAMES_REGEX, + "Invalid database name. Name must start with a lowercase letter and can only contain lowercase letters, numbers, and '_'."); // NON-NLS + + this.dbName = dbName.toLowerCase(); + } + + + /** + * @param bulkThreshold the bulkThreshold to set + */ + public void setBulkThreshold(int bulkThreshold) throws CentralRepoException { + validateNum(bulkThreshold, 1, null, "Invalid bulk threshold."); + this.bulkThreshold = bulkThreshold; + } + + + /** + * @param userName the userName to set + */ + public void setUserName(String userName) throws CentralRepoException { + validateStr(userName, "Invalid user name. Cannot be empty."); // NON-NLS + validateRegex(userName, DB_USER_NAMES_REGEX, + "Invalid user name. Name must start with a letter and can only contain letters, numbers, and '_'."); + + this.userName = userName; + } + + + /** + * @param password the password to set + */ + public void setPassword(String password) throws CentralRepoException { + validateStr(password, "Invalid user password. Cannot be empty."); + this.password = password; + } + + + + @Override + public int hashCode() { + int hash = 3; + return hash; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final PostgresConnectionSettings other = (PostgresConnectionSettings) obj; + if (this.port != other.port) { + return false; + } + if (this.bulkThreshold != other.bulkThreshold) { + return false; + } + if (!Objects.equals(this.host, other.host)) { + return false; + } + if (!Objects.equals(this.dbName, other.dbName)) { + return false; + } + if (!Objects.equals(this.userName, other.userName)) { + return false; + } + if (!Objects.equals(this.password, other.password)) { + return false; + } + return true; + } +} diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteCentralRepoSettings.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteCentralRepoSettings.java index 675a164972..dcf45d02fa 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteCentralRepoSettings.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteCentralRepoSettings.java @@ -37,7 +37,7 @@ import org.sleuthkit.autopsy.coreutils.PlatformUtil; * NOTE: This is public scope because the options panel calls it directly to * set/get */ -public final class SqliteCentralRepoSettings implements CentralRepoDbSettings { +public final class SqliteCentralRepoSettings implements CentralRepoDbConnectivityManager { public final static String DEFAULT_DBNAME = "central_repository.db"; // NON-NLS private final static Logger LOGGER = Logger.getLogger(SqliteCentralRepoSettings.class.getName()); From 097aa7075ada6380df76d6d747e43c0274aba887 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Thu, 27 Feb 2020 16:05:10 -0500 Subject: [PATCH 009/100] updates for consistency --- .../CentralRepoDbConnectivityManager.java | 5 ++- ...a => CentralRepoPostgresSettingsUtil.java} | 18 +++++--- .../PostgresCentralRepoSettings.java | 32 +++++++++++--- .../datamodel/PostgresSettingsLoader.java | 43 +++++++++++++++++++ 4 files changed, 83 insertions(+), 15 deletions(-) rename Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/{CentralRepoPostgresSettingsManager.java => CentralRepoPostgresSettingsUtil.java} (90%) create mode 100644 Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresSettingsLoader.java diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbConnectivityManager.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbConnectivityManager.java index 6744b70541..9d50cfc039 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbConnectivityManager.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbConnectivityManager.java @@ -22,7 +22,10 @@ package org.sleuthkit.autopsy.centralrepository.datamodel; * common interface for settings pertaining to the database in central repository */ public interface CentralRepoDbConnectivityManager { - + void loadSettings(); + + void saveSettings(); + boolean createDatabase(); boolean deleteDatabase(); diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoPostgresSettingsManager.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoPostgresSettingsUtil.java similarity index 90% rename from Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoPostgresSettingsManager.java rename to Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoPostgresSettingsUtil.java index b4feffbcd9..c4fec65793 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoPostgresSettingsManager.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoPostgresSettingsUtil.java @@ -21,8 +21,8 @@ import org.sleuthkit.datamodel.CaseDbConnectionInfo; * * @author gregd */ -public class CentralRepoPostgresSettingsManager { - private final static Logger LOGGER = Logger.getLogger(CentralRepoPostgresSettingsManager.class.getName()); +public class CentralRepoPostgresSettingsUtil { + private final static Logger LOGGER = Logger.getLogger(CentralRepoPostgresSettingsUtil.class.getName()); private final static String DEFAULT_HOST = ""; // NON-NLS private final static int DEFAULT_PORT = 5432; @@ -102,7 +102,7 @@ public class CentralRepoPostgresSettingsManager { } - public static PostgresConnectionSettings loadSettings() { + public static PostgresConnectionSettings loadCustomSettings() { PostgresConnectionSettings settings = new PostgresConnectionSettings(); Map keyVals = ModuleSettings.getConfigSettings(MODULE_KEY); @@ -129,7 +129,7 @@ public class CentralRepoPostgresSettingsManager { return settings; } - public static void saveSettings(PostgresConnectionSettings settings) { + public static void saveCustomSettings(PostgresConnectionSettings settings) { Map map = new HashMap(); map.put(HOST_KEY, settings.getHost()); map.put(PORT_KEY, Integer.toString(settings.getPort())); @@ -145,9 +145,13 @@ public class CentralRepoPostgresSettingsManager { ModuleSettings.setConfigSettings(MODULE_KEY, map); } - - public static boolean isChanged(PostgresConnectionSettings settings) { - PostgresConnectionSettings saved = loadSettings(); + /** + * checks if saved settings differ from the in-memory object provided in the 'settings' parameter + * @param settings the in-memory object + * @return whether or not settings parameter differs from saved custom settings + */ + public static boolean areCustomSettingsChanged(PostgresConnectionSettings settings) { + PostgresConnectionSettings saved = loadCustomSettings(); return saved.equals(settings); } } diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresCentralRepoSettings.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresCentralRepoSettings.java index 54855fb250..5cd246648b 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresCentralRepoSettings.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresCentralRepoSettings.java @@ -26,11 +26,7 @@ import java.sql.SQLException; import java.sql.Statement; import java.util.Properties; import java.util.logging.Level; -import java.util.regex.Pattern; import org.sleuthkit.autopsy.coreutils.Logger; -import org.sleuthkit.autopsy.coreutils.ModuleSettings; -import org.sleuthkit.autopsy.coreutils.TextConverter; -import org.sleuthkit.autopsy.coreutils.TextConverterException; /** * Settings for the Postgres implementation of the Central Repository database @@ -46,12 +42,34 @@ public final class PostgresCentralRepoSettings implements CentralRepoDbConnectiv private final static String JDBC_DRIVER = "org.postgresql.Driver"; // NON-NLS - private final PostgresConnectionSettings connSettings; + private final PostgresSettingsLoader loader; + private PostgresConnectionSettings connSettings; - public PostgresCentralRepoSettings(PostgresConnectionSettings connSettings) { - this.connSettings = connSettings; + + public PostgresCentralRepoSettings(PostgresSettingsLoader loader) { + this.loader = loader; + loadSettings(); + } + + /** + * default constructor that loads custom postgres settings from + */ + public PostgresCentralRepoSettings() { + this(PostgresSettingsLoader.CUSTOM_LOADER); } + + @Override + public void loadSettings() { + this.connSettings = loader.loadSettings(); + } + + @Override + public void saveSettings() { + loader.saveSettings(connSettings); + } + + @Override public String toString() { return String.format("PostgresCentralRepoSettings: [db type: postgres, host: %s:%d, db name: %s, username: %s]", diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresSettingsLoader.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresSettingsLoader.java new file mode 100644 index 0000000000..9450a3e235 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresSettingsLoader.java @@ -0,0 +1,43 @@ +/* + * 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.centralrepository.datamodel; + +/** + * + * @author gregd + */ +public interface PostgresSettingsLoader { + PostgresConnectionSettings loadSettings(); + void saveSettings(PostgresConnectionSettings settings); + + public static PostgresSettingsLoader CUSTOM_LOADER = new Custom(); + public static PostgresSettingsLoader MULTIUSER_LOADER = new MultiUser(); + + + static class Custom implements PostgresSettingsLoader { + @Override + public PostgresConnectionSettings loadSettings() { + return CentralRepoPostgresSettingsUtil.loadCustomSettings(); + } + + @Override + public void saveSettings(PostgresConnectionSettings settings) { + CentralRepoPostgresSettingsUtil.saveCustomSettings(settings); + } + } + + + static class MultiUser implements PostgresSettingsLoader { + + @Override + public PostgresConnectionSettings loadSettings() { + return CentralRepoPostgresSettingsUtil.loadMultiUserSettings(); + } + + @Override + public void saveSettings(PostgresConnectionSettings settings) {} + } +} From 13719c3e706323d87efdd9efe42fba45cc68fd78 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Thu, 27 Feb 2020 17:28:13 -0500 Subject: [PATCH 010/100] updates for some initial debugging --- .../datamodel/CentralRepoDbManager.java | 2 +- .../optionspanel/EamDbSettingsDialog.java | 73 +++++++++++++++---- .../optionspanel/GlobalSettingsPanel.java | 28 ++++--- 3 files changed, 77 insertions(+), 26 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java index 80763a86f8..8897884825 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java @@ -391,7 +391,7 @@ public class CentralRepoDbManager { dbSettingsSqlite.setDbName(SqliteCentralRepoSettings.DEFAULT_DBNAME); dbSettingsSqlite.setDbDirectory(databasePath.getPath()); } - else { + else if (selectedDbChoice != CentralRepoDbChoice.POSTGRESQL_MULTIUSER) { throw new IllegalStateException("Central Repo has an unknown selected platform: " + selectedDbChoice); } diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java index 5cf4f62820..ee79034282 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java @@ -19,6 +19,7 @@ package org.sleuthkit.autopsy.centralrepository.optionspanel; import java.awt.Color; +import java.awt.Component; import java.awt.Cursor; import java.io.File; import java.io.IOException; @@ -29,12 +30,14 @@ import java.util.logging.Level; import javax.swing.JDialog; import javax.swing.JFileChooser; import javax.swing.JFrame; +import javax.swing.JList; import javax.swing.JOptionPane; import javax.swing.JTextField; import javax.swing.SwingUtilities; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import javax.swing.filechooser.FileFilter; +import javax.swing.plaf.basic.BasicComboBoxRenderer; import org.netbeans.spi.options.OptionsPanelController; import org.openide.util.NbBundle; import org.openide.util.NbBundle.Messages; @@ -49,6 +52,7 @@ import org.sleuthkit.autopsy.centralrepository.datamodel.DatabaseTestResult; import org.sleuthkit.autopsy.centralrepository.datamodel.SqliteCentralRepoSettings; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository; import org.sleuthkit.autopsy.centralrepository.datamodel.RdbmsCentralRepoFactory; +import org.sleuthkit.autopsy.core.UserPreferences; /** * Configuration dialog for Central Repository database settings. @@ -59,11 +63,38 @@ public class EamDbSettingsDialog extends JDialog { private static final Logger logger = Logger.getLogger(EamDbSettingsDialog.class.getName()); private static final long serialVersionUID = 1L; + private static final DbChoiceRenderer DB_CHOICE_RENDERER = new DbChoiceRenderer(); + + private static boolean isDbChoiceSelectable(CentralRepoDbChoice item) { + if (item == CentralRepoDbChoice.POSTGRESQL_MULTIUSER && !UserPreferences.getIsMultiUserModeEnabled()) { + return false; + } + else { + return true; + } + } + + private static class DbChoiceRenderer extends BasicComboBoxRenderer { + + public Component getListCellRendererComponent(JList list, Object value, + int index, boolean isSelected, boolean cellHasFocus) { + + CentralRepoDbChoice item = (CentralRepoDbChoice) value; + + // disable cell if it is the db connection from multi user settings + // and that option is not enabled in multi user settings + setText(item.getTitle()); + setEnabled(isDbChoiceSelectable(item)); + return this; + } + } + + private final Collection textBoxes; private final TextBoxChangedListener textBoxChangedListener; private final CentralRepoDbManager manager = new CentralRepoDbManager(); - + /** * Creates new form EamDbSettingsDialog */ @@ -98,19 +129,24 @@ public class EamDbSettingsDialog extends JDialog { } }); - setSelectedChoice(manager); + setupDbChoice(); customizeComponents(); valid(); display(); } - - private void setSelectedChoice(CentralRepoDbManager manager) { + + + private void setupDbChoice() { + // setup initially selected item CentralRepoDbChoice toSelect = (Arrays.asList(CentralRepoDbChoice.DB_CHOICES).contains(manager.getSelectedDbChoice())) ? manager.getSelectedDbChoice() : CentralRepoDbChoice.DB_CHOICES[0]; cbDatabaseType.setSelectedItem(toSelect); + + // set the renderer so item is unselectable if inappropriate + cbDatabaseType.setRenderer(DB_CHOICE_RENDERER); } @@ -436,7 +472,7 @@ public class EamDbSettingsDialog extends JDialog { updateSqliteFields(false); } - displayDatabaseSettings(CentralRepoDbChoice.POSTGRESQL_CUSTOM.equals(manager.getSelectedDbChoice())); + displayDatabaseSettings(manager.getSelectedDbChoice()); } private void display() { @@ -511,7 +547,14 @@ public class EamDbSettingsDialog extends JDialog { private void cbDatabaseTypeActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cbDatabaseTypeActionPerformed - manager.setSelctedDbChoice((CentralRepoDbChoice) cbDatabaseType.getSelectedItem()); + CentralRepoDbChoice selectedItem = (CentralRepoDbChoice) cbDatabaseType.getSelectedItem(); + if (isDbChoiceSelectable(selectedItem)) { + manager.setSelctedDbChoice(selectedItem); + } + else { + cbDatabaseType.setSelectedItem(manager.getSelectedDbChoice()); + } + customizeComponents(); }//GEN-LAST:event_cbDatabaseTypeActionPerformed @@ -520,13 +563,17 @@ public class EamDbSettingsDialog extends JDialog { dataBaseFileTextArea.setCaretPosition(dataBaseFileTextArea.getText().length()); } - private void displayDatabaseSettings(boolean isPostgres) { - lbDatabasePath.setVisible(!isPostgres); - tfDatabasePath.setVisible(!isPostgres); - lbDatabaseDesc.setVisible(!isPostgres); - dataBaseFileTextArea.setVisible(!isPostgres); - lbSingleUserSqLite.setVisible(!isPostgres); - bnDatabasePathFileOpen.setVisible(!isPostgres); + private void displayDatabaseSettings(CentralRepoDbChoice choice) { + boolean isSqlite = choice == CentralRepoDbChoice.SQLITE; + boolean isPostgres = choice == CentralRepoDbChoice.POSTGRESQL_CUSTOM; + + lbDatabasePath.setVisible(isSqlite); + tfDatabasePath.setVisible(isSqlite); + lbDatabaseDesc.setVisible(isSqlite); + dataBaseFileTextArea.setVisible(isSqlite); + lbSingleUserSqLite.setVisible(isSqlite); + bnDatabasePathFileOpen.setVisible(isSqlite); + lbHostName.setVisible(isPostgres); tbDbHostname.setVisible(isPostgres); lbPort.setVisible(isPostgres); diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java index 22891da01d..ac2c90a9bd 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java @@ -113,6 +113,7 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i boolean crMultiUser = CentralRepoDbManager.getSavedDbChoice() == CentralRepoDbChoice.POSTGRESQL_MULTIUSER; if (!muPreviouslySelected && muCurrentlySelected) { + SwingUtilities.invokeLater(() -> { if (JOptionPane.YES_OPTION == JOptionPane.showConfirmDialog(parent, NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.onMultiUserChange.enable.description"), NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.onMultiUserChange.enable.title"), @@ -122,21 +123,24 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i CentralRepoDbManager.saveDbChoice(CentralRepoDbChoice.POSTGRESQL_MULTIUSER); updateDatabase(parent); } + }); } // moving from selected to not selected && 'PostgreSQL using multi-user settings' is selected else if (muPreviouslySelected && !muCurrentlySelected && crMultiUser) { - if (JOptionPane.YES_OPTION == JOptionPane.showConfirmDialog(parent, - NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.onMultiUserChange.disabledMu.description"), - NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.onMultiUserChange.disabledMu.title"), - JOptionPane.YES_NO_OPTION)) { - - // present user with central repository choice - invokeCrChoice(parent); - } - else { - // disable central repository - CentralRepoDbManager.saveDbChoice(CentralRepoDbChoice.DISABLED); - } + SwingUtilities.invokeLater(() -> { + if (JOptionPane.YES_OPTION == JOptionPane.showConfirmDialog(parent, + NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.onMultiUserChange.disabledMu.description"), + NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.onMultiUserChange.disabledMu.title"), + JOptionPane.YES_NO_OPTION)) { + + // present user with central repository choice + invokeCrChoice(parent); + } + else { + // disable central repository + CentralRepoDbManager.saveDbChoice(CentralRepoDbChoice.DISABLED); + } + }); } // changing multi-user settings connection && 'PostgreSQL using multi-user settings' is selected else if (muPreviouslySelected && muCurrentlySelected && crMultiUser) { From 00a94d649ba5cc4c528cf6c13a7d2e4a2d633ec7 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Fri, 28 Feb 2020 09:28:19 -0500 Subject: [PATCH 011/100] updates from debugging --- .../datamodel/CentralRepoDbManager.java | 33 ++++++++++++++----- .../optionspanel/EamDbSettingsDialog.form | 4 +-- .../optionspanel/EamDbSettingsDialog.java | 4 +-- 3 files changed, 29 insertions(+), 12 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java index 8897884825..48eb4d99bc 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java @@ -194,14 +194,21 @@ public class CentralRepoDbManager { private CentralRepoDbChoice selectedDbChoice; private final PostgresCentralRepoSettings dbSettingsPostgres; + private final PostgresCentralRepoSettings dbSettingsMultiUser; private final SqliteCentralRepoSettings dbSettingsSqlite; private boolean configurationChanged = false; public CentralRepoDbManager() { - dbSettingsPostgres = new PostgresCentralRepoSettings(); - dbSettingsSqlite = new SqliteCentralRepoSettings(); selectedDbChoice = getSavedDbChoice(); + dbSettingsPostgres = new PostgresCentralRepoSettings(PostgresSettingsLoader.CUSTOM_LOADER); + dbSettingsMultiUser = new PostgresCentralRepoSettings(PostgresSettingsLoader.MULTIUSER_LOADER); + dbSettingsSqlite = new SqliteCentralRepoSettings(); + } + + + public PostgresCentralRepoSettings getDbSettingsMultiUser() { + return dbSettingsMultiUser; } public PostgresCentralRepoSettings getDbSettingsPostgres() { @@ -250,6 +257,8 @@ public class CentralRepoDbManager { } private CentralRepoDbConnectivityManager getSelectedSettings() throws CentralRepoException { + if (selectedDbChoice == CentralRepoDbChoice.POSTGRESQL_MULTIUSER) + return dbSettingsMultiUser; if (selectedDbChoice == CentralRepoDbChoice.POSTGRESQL_CUSTOM) return dbSettingsPostgres; if (selectedDbChoice == CentralRepoDbChoice.SQLITE) @@ -257,10 +266,12 @@ public class CentralRepoDbManager { if (selectedDbChoice == CentralRepoDbChoice.DISABLED) return null; - throw new CentralRepoException("Unknown database type: " + selectedDbChoice); + throw new CentralRepoException("Unknown database type: " + selectedDbChoice); } private RdbmsCentralRepoFactory getDbFactory() throws CentralRepoException { + if (selectedDbChoice == CentralRepoDbChoice.POSTGRESQL_MULTIUSER) + return new RdbmsCentralRepoFactory(CentralRepoPlatforms.POSTGRESQL, dbSettingsMultiUser); if (selectedDbChoice == CentralRepoDbChoice.POSTGRESQL_CUSTOM) return new RdbmsCentralRepoFactory(CentralRepoPlatforms.POSTGRESQL, dbSettingsPostgres); if (selectedDbChoice == CentralRepoDbChoice.SQLITE) @@ -271,12 +282,19 @@ public class CentralRepoDbManager { throw new CentralRepoException("Unknown database type: " + selectedDbChoice); } + /** + * create central repo database if it does not already exist + * @return true if successful; false if unsuccessful + * @throws CentralRepoException if + */ public boolean createDb() throws CentralRepoException { boolean result = false; boolean dbCreated = true; CentralRepoDbConnectivityManager selectedDbSettings = getSelectedSettings(); - + if (selectedDbSettings == null) + throw new CentralRepoException("Unable to derive connectivity manager from settings: " + selectedDbChoice); + if (!selectedDbSettings.verifyDatabaseExists()) { dbCreated = selectedDbSettings.createDatabase(); } @@ -294,7 +312,6 @@ public class CentralRepoDbManager { if (!result) { // Remove the incomplete database if (dbCreated) { - // RAMAN TBD: migrate deleteDatabase() to RdbmsCentralRepoFactory selectedDbSettings.deleteDatabase(); } @@ -344,7 +361,7 @@ public class CentralRepoDbManager { // in case we are still using the same instance. if (selectedDbChoice != null && selectedDbSettings != CentralRepoDbChoice.DISABLED) { try { - logger.info("Creating central repo db with settings: " + selectedDbSettings); + logger.info("Saving central repo settings for db: " + selectedDbSettings); CentralRepository.getInstance().updateSettings(); configurationChanged = true; } catch (CentralRepoException ex) { @@ -399,7 +416,7 @@ public class CentralRepoDbManager { } public DatabaseTestResult testStatus() { - if (selectedDbChoice == CentralRepoDbChoice.POSTGRESQL_CUSTOM) { + if (selectedDbChoice.getDbPlatform() == CentralRepoPlatforms.POSTGRESQL) { if (dbSettingsPostgres.verifyConnection()) { if (dbSettingsPostgres.verifyDatabaseExists()) { if (dbSettingsPostgres.verifyDatabaseSchema()) { @@ -413,7 +430,7 @@ public class CentralRepoDbManager { } else { testingStatus = DatabaseTestResult.CONNECTION_FAILED; } - } else if (selectedDbChoice == CentralRepoDbChoice.SQLITE) { + } else if (selectedDbChoice.getDbPlatform() == CentralRepoPlatforms.SQLITE) { if (dbSettingsSqlite.dbFileExists()) { if (dbSettingsSqlite.verifyConnection()) { if (dbSettingsSqlite.verifyDatabaseSchema()) { diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.form b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.form index 2e9b63530e..5a1e2de77e 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.form +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.form @@ -145,9 +145,9 @@ - + - + diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java index ee79034282..c043687586 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java @@ -377,9 +377,9 @@ public class EamDbSettingsDialog extends JDialog { .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(bnDatabasePathFileOpen)) .addGroup(pnSQLiteSettingsLayout.createSequentialGroup() - .addComponent(cbDatabaseType, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(cbDatabaseType, javax.swing.GroupLayout.PREFERRED_SIZE, 210, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(lbSingleUserSqLite, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(lbSingleUserSqLite, javax.swing.GroupLayout.PREFERRED_SIZE, 1, Short.MAX_VALUE)) .addComponent(jpDbPassword, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(tbDbUsername, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(tbDbPort, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) From 94d6a8c01249b647f7301e6f39793cb92a9510e1 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Fri, 28 Feb 2020 13:47:49 -0500 Subject: [PATCH 012/100] working through bugs in 6035 implementation --- .../datamodel/Bundle.properties-MERGED | 3 +- .../datamodel/CentralRepoDbChoice.java | 2 +- .../CentralRepoDbConnectivityManager.java | 2 + .../datamodel/CentralRepoDbManager.java | 47 ++++------ .../PostgresCentralRepoSettings.java | 32 ++++++- .../datamodel/PostgresSettingsLoader.java | 2 +- .../datamodel/SqliteCentralRepoSettings.java | 27 ++++-- .../eventlisteners/Bundle.properties-MERGED | 3 - .../optionspanel/GlobalSettingsPanel.java | 53 +++++++++-- .../contextviewer/Bundle.properties-MERGED | 3 + .../autopsy/core/Bundle.properties-MERGED | 8 +- .../corecomponents/Bundle.properties-MERGED | 6 +- .../MultiUserSettingsPanel.java | 93 +++++++++---------- .../coreutils/Bundle.properties-MERGED | 4 +- .../filesearch/Bundle.properties-MERGED | 4 +- .../autopsy/ingest/Bundle.properties-MERGED | 2 +- .../Bundle.properties-MERGED | 8 +- .../modules/exif/Bundle.properties-MERGED | 4 +- .../fileextmismatch/Bundle.properties-MERGED | 18 ++-- .../hashdatabase/Bundle.properties-MERGED | 10 +- .../interestingitems/Bundle.properties-MERGED | 4 +- .../photoreccarver/Bundle.properties-MERGED | 2 +- .../modules/html/Bundle.properties-MERGED | 6 +- .../datamodel/CentralRepoDatamodelTest.java | 3 +- .../InterCaseTestUtils.java | 5 +- .../recentactivity/Bundle.properties-MERGED | 11 ++- .../netbeans/core/startup/Bundle.properties | 4 +- .../core/windows/view/ui/Bundle.properties | 6 +- 28 files changed, 211 insertions(+), 161 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/Bundle.properties-MERGED index 345d5a420e..9b43833ee2 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/Bundle.properties-MERGED @@ -7,10 +7,8 @@ AbstractSqlEamDb.cannotUpgrage.message=Currently selected database platform "{0} AbstractSqlEamDb.failedToReadMajorVersion.message=Failed to read schema version for Central Repository. AbstractSqlEamDb.failedToReadMinorVersion.message=Failed to read schema minor version for Central Repository. AbstractSqlEamDb.upgradeSchema.incompatible=The selected Central Repository is not compatible with the current version of the application, please upgrade the application if you wish to use this Central Repository. -CentralRepoDbManager.connectionErrorMsg.text=Failed to connect to central repository database. CorrelationAttributeInstance.invalidName.message=Invalid database table name. Name must start with a lowercase letter and can only contain lowercase letters, numbers, and '_'. CorrelationAttributeInstance.nullName.message=Database name is null. -CorrelationAttributeUtil.emailaddresses.text=Email Addresses CorrelationType.DOMAIN.displayName=Domains CorrelationType.EMAIL.displayName=Email Addresses CorrelationType.FILES.displayName=Files @@ -25,6 +23,7 @@ DataSourceUpdateService.serviceName.text=Update Central Repository Data Sources EamArtifactInstances.knownStatus.bad=Bad EamArtifactInstances.knownStatus.known=Known EamArtifactInstances.knownStatus.unknown=Unknown +EamArtifactUtil.emailaddresses.text=Email Addresses EamCase.title.caseDisplayName=Case Name: EamCase.title.caseNumber=Case Number: EamCase.title.caseUUID=Case UUID: diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbChoice.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbChoice.java index f0d1080f10..b0084702ae 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbChoice.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbChoice.java @@ -22,7 +22,7 @@ package org.sleuthkit.autopsy.centralrepository.datamodel; * */ public class CentralRepoDbChoice { - public static final CentralRepoDbChoice DISABLED = new CentralRepoDbChoice("Disabled", null); + public static final CentralRepoDbChoice DISABLED = new CentralRepoDbChoice("Disabled", CentralRepoPlatforms.DISABLED); public static final CentralRepoDbChoice SQLITE = new CentralRepoDbChoice("Sqlite", CentralRepoPlatforms.SQLITE); diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbConnectivityManager.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbConnectivityManager.java index 9d50cfc039..ef261601ab 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbConnectivityManager.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbConnectivityManager.java @@ -53,4 +53,6 @@ public interface CentralRepoDbConnectivityManager { */ boolean verifyDatabaseSchema(); + DatabaseTestResult testStatus(); + } diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java index 48eb4d99bc..c116e79c94 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java @@ -23,6 +23,7 @@ import java.sql.SQLException; import java.util.logging.Level; import org.openide.util.NbBundle; import org.sleuthkit.autopsy.coordinationservice.CoordinationService; +import org.sleuthkit.autopsy.core.UserPreferences; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.ModuleSettings; @@ -55,7 +56,14 @@ public class CentralRepoDbManager { public static CentralRepoDbChoice getSavedDbChoice() { if (SAVED_CHOICE == null) { String selectedPlatformString = ModuleSettings.getConfigSetting("CentralRepository", "db.selectedPlatform"); // NON-NLS - SAVED_CHOICE = fromKey(selectedPlatformString); + SAVED_CHOICE = fromKey(selectedPlatformString); + } + + // do a sanity check: if loading multi user postgres connection, make sure setting is enabled. + // if not, disable central repo + if (SAVED_CHOICE == CentralRepoDbChoice.POSTGRESQL_MULTIUSER && !UserPreferences.getIsMultiUserModeEnabled()) { + CentralRepoDbUtil.setUseCentralRepo(false); + SAVED_CHOICE = CentralRepoDbChoice.DISABLED; } return SAVED_CHOICE; @@ -416,36 +424,15 @@ public class CentralRepoDbManager { } public DatabaseTestResult testStatus() { - if (selectedDbChoice.getDbPlatform() == CentralRepoPlatforms.POSTGRESQL) { - if (dbSettingsPostgres.verifyConnection()) { - if (dbSettingsPostgres.verifyDatabaseExists()) { - if (dbSettingsPostgres.verifyDatabaseSchema()) { - testingStatus = DatabaseTestResult.TESTEDOK; - } else { - testingStatus = DatabaseTestResult.SCHEMA_INVALID; - } - } else { - testingStatus = DatabaseTestResult.DB_DOES_NOT_EXIST; - } - } else { - testingStatus = DatabaseTestResult.CONNECTION_FAILED; - } - } else if (selectedDbChoice.getDbPlatform() == CentralRepoPlatforms.SQLITE) { - if (dbSettingsSqlite.dbFileExists()) { - if (dbSettingsSqlite.verifyConnection()) { - if (dbSettingsSqlite.verifyDatabaseSchema()) { - testingStatus = DatabaseTestResult.TESTEDOK; - } else { - testingStatus = DatabaseTestResult.SCHEMA_INVALID; - } - } else { - testingStatus = DatabaseTestResult.SCHEMA_INVALID; - } - } else { - testingStatus = DatabaseTestResult.DB_DOES_NOT_EXIST; - } + try { + CentralRepoDbConnectivityManager manager = getSelectedSettings(); + if (manager != null) + testingStatus = manager.testStatus(); } - + catch (CentralRepoException e) { + logger.log(Level.WARNING, "unable to test status of db connection in central repo", e); + } + return testingStatus; } } diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresCentralRepoSettings.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresCentralRepoSettings.java index 5cd246648b..2bb275bef6 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresCentralRepoSettings.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresCentralRepoSettings.java @@ -45,6 +45,15 @@ public final class PostgresCentralRepoSettings implements CentralRepoDbConnectiv private final PostgresSettingsLoader loader; private PostgresConnectionSettings connSettings; + private static PostgresSettingsLoader getLoaderFromSaved() throws CentralRepoException { + CentralRepoDbChoice choice = CentralRepoDbManager.getSavedDbChoice(); + if (choice == CentralRepoDbChoice.POSTGRESQL_CUSTOM) + return PostgresSettingsLoader.CUSTOM_LOADER; + else if (choice == CentralRepoDbChoice.POSTGRESQL_MULTIUSER) + return PostgresSettingsLoader.MULTIUSER_LOADER; + else + throw new CentralRepoException("cannot load or save postgres settings for selection: " + choice); + } public PostgresCentralRepoSettings(PostgresSettingsLoader loader) { this.loader = loader; @@ -52,10 +61,10 @@ public final class PostgresCentralRepoSettings implements CentralRepoDbConnectiv } /** - * default constructor that loads custom postgres settings from + * default constructor that loads settings from selected db choice */ - public PostgresCentralRepoSettings() { - this(PostgresSettingsLoader.CUSTOM_LOADER); + public PostgresCentralRepoSettings() throws CentralRepoException { + this(getLoaderFromSaved()); } @@ -347,4 +356,21 @@ public final class PostgresCentralRepoSettings implements CentralRepoDbConnectiv public void setPassword(String password) throws CentralRepoException { connSettings.setPassword(password); } + + @Override + public DatabaseTestResult testStatus() { + if (verifyConnection()) { + if (verifyDatabaseExists()) { + if (verifyDatabaseSchema()) { + return DatabaseTestResult.TESTEDOK; + } else { + return DatabaseTestResult.SCHEMA_INVALID; + } + } else { + return DatabaseTestResult.DB_DOES_NOT_EXIST; + } + } else { + return DatabaseTestResult.CONNECTION_FAILED; + } + } } diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresSettingsLoader.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresSettingsLoader.java index 9450a3e235..855482784d 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresSettingsLoader.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresSettingsLoader.java @@ -15,7 +15,7 @@ public interface PostgresSettingsLoader { public static PostgresSettingsLoader CUSTOM_LOADER = new Custom(); public static PostgresSettingsLoader MULTIUSER_LOADER = new MultiUser(); - + static class Custom implements PostgresSettingsLoader { @Override diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteCentralRepoSettings.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteCentralRepoSettings.java index dcf45d02fa..f2e8dac25c 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteCentralRepoSettings.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteCentralRepoSettings.java @@ -45,7 +45,7 @@ public final class SqliteCentralRepoSettings implements CentralRepoDbConnectivit private final static String JDBC_DRIVER = "org.sqlite.JDBC"; // NON-NLS private final static String JDBC_BASE_URI = "jdbc:sqlite:"; // NON-NLS private final static String VALIDATION_QUERY = "SELECT count(*) from sqlite_master"; // NON-NLS - + private final static String DB_NAMES_REGEX = "[a-z][a-z0-9_]*(\\.db)?"; private String dbName; private String dbDirectory; @@ -80,11 +80,11 @@ public final class SqliteCentralRepoSettings implements CentralRepoDbConnectivit this.bulkThreshold = RdbmsCentralRepo.DEFAULT_BULK_THRESHHOLD; } } - + public String toString() { return String.format("SqliteCentralRepoSettings: [db type: sqlite, directory: %s, name: %s]", getDbDirectory(), getDbName()); } - + /** * sets database directory and name to defaults */ @@ -115,13 +115,11 @@ public final class SqliteCentralRepoSettings implements CentralRepoDbConnectivit return (!dbFile.isDirectory()); } - @Override public boolean verifyDatabaseExists() { return dbDirectoryExists(); } - /** * Verify that the db directory path exists. * @@ -143,6 +141,7 @@ public final class SqliteCentralRepoSettings implements CentralRepoDbConnectivit /** * creates database directory for sqlite database if it does not exist + * * @return whether or not operation occurred successfully */ @Override @@ -150,7 +149,6 @@ public final class SqliteCentralRepoSettings implements CentralRepoDbConnectivit return createDbDirectory(); } - /** * Create the db directory if it does not exist. * @@ -354,4 +352,21 @@ public final class SqliteCentralRepoSettings implements CentralRepoDbConnectivit String getJDBCBaseURI() { return JDBC_BASE_URI; } + + @Override + public DatabaseTestResult testStatus() { + if (dbFileExists()) { + if (verifyConnection()) { + if (verifyDatabaseSchema()) { + return DatabaseTestResult.TESTEDOK; + } else { + return DatabaseTestResult.SCHEMA_INVALID; + } + } else { + return DatabaseTestResult.SCHEMA_INVALID; + } + } else { + return DatabaseTestResult.DB_DOES_NOT_EXIST; + } + } } diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/Bundle.properties-MERGED index cd654a5b37..b7c3df2c53 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/Bundle.properties-MERGED @@ -7,6 +7,3 @@ IngestEventsListener.prevCount.text=Number of previous {0}: {1} IngestEventsListener.prevExists.text=Previously Seen Devices (Central Repository) IngestEventsListener.prevTaggedSet.text=Previously Tagged As Notable (Central Repository) Installer.centralRepoUpgradeFailed.title=Central repository disabled -Installer.initialCreateSqlite.messageDesc=It will store information about all hashes and identifiers that you process. You can use this to ignore previously seen files and make connections between cases. -Installer.initialCreateSqlite.messageHeader=The Central Repository is not enabled. Would you like to? -Installer.initialCreateSqlite.title=Enable Central Repository? diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java index ac2c90a9bd..4ebdcd31dd 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java @@ -43,6 +43,9 @@ import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoDbUtil; import org.sleuthkit.autopsy.centralrepository.datamodel.PostgresCentralRepoSettings; import org.sleuthkit.autopsy.centralrepository.datamodel.SqliteCentralRepoSettings; import java.awt.Component; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.logging.Level; /** * Main settings panel for the Central Repository @@ -50,17 +53,37 @@ import java.awt.Component; @SuppressWarnings("PMD.SingularField") // UI widgets cause lots of false positives public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel implements OptionsPanel { + private static interface OnSettingsChangeListener { + void onSettingsChange(); + } + + private static OnSettingsChangeListener listener = null; + + private static void onSettingsChange() { + if (listener != null) + listener.onSettingsChange(); + } + + private static void setSettingsChangeListener(OnSettingsChangeListener newListener) { + listener = newListener; + } + + private static final long serialVersionUID = 1L; private static final Logger logger = Logger.getLogger(GlobalSettingsPanel.class.getName()); private static final Set INGEST_JOB_EVENTS_OF_INTEREST = EnumSet.of(IngestManager.IngestJobEvent.STARTED, IngestManager.IngestJobEvent.CANCELLED, IngestManager.IngestJobEvent.COMPLETED); private final IngestJobEventPropertyChangeListener ingestJobEventListener; - + + + /** * Creates new form EamOptionsPanel */ public GlobalSettingsPanel() { ingestJobEventListener = new IngestJobEventPropertyChangeListener(); - + + // most recently created panel will receive update events + GlobalSettingsPanel.setSettingsChangeListener(() -> GlobalSettingsPanel.this.load()); initComponents(); customizeComponents(); addIngestJobEventsListener(); @@ -69,7 +92,8 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i ingestStateUpdated(evt.getNewValue() != null); }); } - + + private void customizeComponents() { setName(NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.pnCorrelationProperties.border.title")); } @@ -107,7 +131,7 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i "GlobalSettingsPanel.onMultiUserChange.enable.title=Enable Central Repository?", "GlobalSettingsPanel.onMultiUserChange.enable.description=Do you want to enable Central Repository using these settings?", "GlobalSettingsPanel.onMultiUserChange.disabledMu.title=Central Repository Change Necessary", - "GlobalSettingsPanel.onMultiUserChange.disabledMu.description=Since mult-user cases have been disabled, 'PostgreSQL using multi-user settings' is no longer a valid option for Central Repository." + "GlobalSettingsPanel.onMultiUserChange.disabledMu.description=Since mult-user cases have been disabled, 'PostgreSQL using multi-user settings' is no longer a valid option for Central Repository. Would you like to choose another Central Repository database?" }) public static void onMultiUserChange(Component parent, boolean muPreviouslySelected, boolean muCurrentlySelected) { boolean crMultiUser = CentralRepoDbManager.getSavedDbChoice() == CentralRepoDbChoice.POSTGRESQL_MULTIUSER; @@ -122,6 +146,7 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i // setup database for CR CentralRepoDbManager.saveDbChoice(CentralRepoDbChoice.POSTGRESQL_MULTIUSER); updateDatabase(parent); + GlobalSettingsPanel.onSettingsChange(); } }); } @@ -129,7 +154,11 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i else if (muPreviouslySelected && !muCurrentlySelected && crMultiUser) { SwingUtilities.invokeLater(() -> { if (JOptionPane.YES_OPTION == JOptionPane.showConfirmDialog(parent, - NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.onMultiUserChange.disabledMu.description"), + "" + + "
" + + "

" + NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.onMultiUserChange.disabledMu.description") + "

" + + "
" + + "", NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.onMultiUserChange.disabledMu.title"), JOptionPane.YES_NO_OPTION)) { @@ -138,14 +167,17 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i } else { // disable central repository + CentralRepoDbUtil.setUseCentralRepo(false); CentralRepoDbManager.saveDbChoice(CentralRepoDbChoice.DISABLED); } + GlobalSettingsPanel.onSettingsChange(); }); } // changing multi-user settings connection && 'PostgreSQL using multi-user settings' is selected else if (muPreviouslySelected && muCurrentlySelected && crMultiUser) { // test databse for CR change updateDatabase(parent); + GlobalSettingsPanel.onSettingsChange(); } } @@ -540,9 +572,14 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i else { enableButtonSubComponents(cbUseCentralRepo.isSelected()); if (selectedDb == CentralRepoPlatforms.POSTGRESQL) { - PostgresCentralRepoSettings dbSettingsPg = new PostgresCentralRepoSettings(); - lbDbNameValue.setText(dbSettingsPg.getDbName()); - lbDbLocationValue.setText(dbSettingsPg.getHost()); + try { + PostgresCentralRepoSettings dbSettingsPg = new PostgresCentralRepoSettings(); + lbDbNameValue.setText(dbSettingsPg.getDbName()); + lbDbLocationValue.setText(dbSettingsPg.getHost()); + } + catch (CentralRepoException e) { + logger.log(Level.WARNING, "Unable to load settings into global panel for postgres settings", e); + } } else if (selectedDb == CentralRepoPlatforms.SQLITE) { SqliteCentralRepoSettings dbSettingsSqlite = new SqliteCentralRepoSettings(); diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/Bundle.properties-MERGED index 79f4f61bfa..b29e7190fd 100755 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/Bundle.properties-MERGED @@ -3,6 +3,7 @@ ContextViewer.downloadedOn=On ContextViewer.downloadSource=Downloaded from: ContextViewer.downloadURL=URL ContextViewer.email=Email +ContextViewer.file=File ContextViewer.jSourceGoToResultButton.text=Go to Result ContextViewer.jSourceTextLabel.text=jLabel2 ContextViewer.jSourceNameLabel.text=jSourceNameLabel @@ -11,5 +12,7 @@ ContextViewer.message=Message ContextViewer.messageFrom=From ContextViewer.messageOn=On ContextViewer.messageTo=To +ContextViewer.on=On +ContextViewer.recentDocs=Recent Documents: ContextViewer.title=Context ContextViewer.toolTip=Displays context for selected file. diff --git a/Core/src/org/sleuthkit/autopsy/core/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/core/Bundle.properties-MERGED index 0b16a9701f..c84f1f1b86 100755 --- a/Core/src/org/sleuthkit/autopsy/core/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/core/Bundle.properties-MERGED @@ -3,13 +3,7 @@ Installer.closing.confirmationDialog.title=Ingest is Running # {0} - exception message Installer.closing.messageBox.caseCloseExceptionMessage=Error closing case: {0} OpenIDE-Module-Display-Category=Infrastructure -OpenIDE-Module-Long-Description=\ - This is the core Autopsy module.\n\n\ - The module contains the core components needed for the bare application to run; the RCP platform, windowing GUI, sleuthkit bindings, datamodel / storage, explorer, result viewers, content viewers, ingest framework, reporting, and core tools, such as the file search.\n\n\ - The framework included in the module contains APIs for developing modules for ingest, viewers and reporting. \ - The modules can be deployed as Plugins using the Autopsy plugin installer.\n\ - This module should not be uninstalled - without it, Autopsy will not run.\n\n\ - For more information, see http://www.sleuthkit.org/autopsy/ +OpenIDE-Module-Long-Description=This is the core Autopsy module.\n\nThe module contains the core components needed for the bare application to run; the RCP platform, windowing GUI, sleuthkit bindings, datamodel / storage, explorer, result viewers, content viewers, ingest framework, reporting, and core tools, such as the file search.\n\nThe framework included in the module contains APIs for developing modules for ingest, viewers and reporting. The modules can be deployed as Plugins using the Autopsy plugin installer.\nThis module should not be uninstalled - without it, Autopsy will not run.\n\nFor more information, see http://www.sleuthkit.org/autopsy/ OpenIDE-Module-Name=Autopsy-Core OpenIDE-Module-Short-Description=Autopsy Core Module org_sleuthkit_autopsy_core_update_center=http://sleuthkit.org/autopsy/updates.xml diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle.properties-MERGED index 9f363b7723..f252420726 100755 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle.properties-MERGED @@ -63,9 +63,9 @@ DataContentViewerHex.totalPageLabel.text_1=100 DataContentViewerHex.pageLabel2.text=Page # Product Information panel -LBL_Description=
\n Product Version: {0} ({9})
Sleuth Kit Version: {7}
Netbeans RCP Build: {8}
Java: {1}; {2}
System: {3}; {4}; {5}
Userdir: {6}
+LBL_Description=
\n Product Version: {0} ({9})
Sleuth Kit Version: {7}
Netbeans RCP Build: {8}
Java: {1}; {2}
System: {3}; {4}; {5}
Userdir: {6}
Format_OperatingSystem_Value={0} version {1} running on {2} -LBL_Copyright=
Autopsy™ is a digital forensics platform based on The Sleuth Kit™ and other tools.
Copyright © 2003-2018.
+LBL_Copyright=
Autopsy™ is a digital forensics platform based on The Sleuth Kit™ and other tools.
Copyright © 2003-2018.
SortChooser.dialogTitle=Choose Sort Criteria ThumbnailViewChildren.progress.cancelling=(Cancelling) # {0} - file name @@ -95,7 +95,7 @@ DataResultViewerThumbnail.pageNextButton.text= DataResultViewerThumbnail.imagesLabel.text=Images: DataResultViewerThumbnail.imagesRangeLabel.text=- DataResultViewerThumbnail.pageNumLabel.text=- -DataResultViewerThumbnail.filePathLabel.text=\ \ \ +DataResultViewerThumbnail.filePathLabel.text=\ DataResultViewerThumbnail.goToPageLabel.text=Go to Page: DataResultViewerThumbnail.goToPageField.text= AdvancedConfigurationDialog.cancelButton.text=Cancel diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/MultiUserSettingsPanel.java b/Core/src/org/sleuthkit/autopsy/corecomponents/MultiUserSettingsPanel.java index 49373330c7..13cf9401d7 100644 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/MultiUserSettingsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/MultiUserSettingsPanel.java @@ -699,55 +699,54 @@ public final class MultiUserSettingsPanel extends javax.swing.JPanel { boolean multiUserCasesEnabled = cbEnableMultiUser.isSelected(); UserPreferences.setIsMultiUserModeEnabled(multiUserCasesEnabled); - if (multiUserCasesEnabled == false) { - return; - } - - /* - * Currently only supporting multi-user cases with PostgreSQL case - * databases. - */ - DbType dbType = DbType.POSTGRESQL; - CaseDbConnectionInfo info = new CaseDbConnectionInfo( - tbDbHostname.getText().trim(), - tbDbPort.getText().trim(), - tbDbUsername.getText().trim(), - new String(tbDbPassword.getPassword()), - dbType); - try { - UserPreferences.setDatabaseConnectionInfo(info); - } catch (UserPreferencesException ex) { - logger.log(Level.SEVERE, "Error saving case database connection info", ex); //NON-NLS - } - - int msgServicePort = 0; - try { - msgServicePort = Integer.parseInt(this.tbMsgPort.getText().trim()); - } catch (NumberFormatException ex) { - logger.log(Level.SEVERE, "Could not parse messaging service port setting", ex); - } - - MessageServiceConnectionInfo msgServiceInfo = new MessageServiceConnectionInfo( - tbMsgHostname.getText().trim(), - msgServicePort, - tbMsgUsername.getText().trim(), - new String(tbMsgPassword.getPassword())); - - try { - UserPreferences.setMessageServiceConnectionInfo(msgServiceInfo); - } catch (UserPreferencesException ex) { - logger.log(Level.SEVERE, "Error saving messaging service connection info", ex); //NON-NLS - } - - UserPreferences.setIndexingServerHost(tbSolrHostname.getText().trim()); - UserPreferences.setIndexingServerPort(Integer.parseInt(tbSolrPort.getText().trim())); - - boolean curSelected = multiUserCasesEnabled; - CaseDbConnectionInfo curConn = info; + CaseDbConnectionInfo info = null; - if (prevSelected != curSelected || !areCaseDbConnectionEqual(prevConn, curConn)) - GlobalSettingsPanel.onMultiUserChange(this, prevSelected, curSelected); + if (multiUserCasesEnabled == true) { + + /* + * Currently only supporting multi-user cases with PostgreSQL case + * databases. + */ + DbType dbType = DbType.POSTGRESQL; + info = new CaseDbConnectionInfo( + tbDbHostname.getText().trim(), + tbDbPort.getText().trim(), + tbDbUsername.getText().trim(), + new String(tbDbPassword.getPassword()), + dbType); + try { + UserPreferences.setDatabaseConnectionInfo(info); + } catch (UserPreferencesException ex) { + logger.log(Level.SEVERE, "Error saving case database connection info", ex); //NON-NLS + } + + int msgServicePort = 0; + try { + msgServicePort = Integer.parseInt(this.tbMsgPort.getText().trim()); + } catch (NumberFormatException ex) { + logger.log(Level.SEVERE, "Could not parse messaging service port setting", ex); + } + + MessageServiceConnectionInfo msgServiceInfo = new MessageServiceConnectionInfo( + tbMsgHostname.getText().trim(), + msgServicePort, + tbMsgUsername.getText().trim(), + new String(tbMsgPassword.getPassword())); + + try { + UserPreferences.setMessageServiceConnectionInfo(msgServiceInfo); + } catch (UserPreferencesException ex) { + logger.log(Level.SEVERE, "Error saving messaging service connection info", ex); //NON-NLS + } + + UserPreferences.setIndexingServerHost(tbSolrHostname.getText().trim()); + UserPreferences.setIndexingServerPort(Integer.parseInt(tbSolrPort.getText().trim())); + } + + // trigger changes to whether or not user can use multi user settings for central repository + if (prevSelected != multiUserCasesEnabled || !areCaseDbConnectionEqual(prevConn, info)) + GlobalSettingsPanel.onMultiUserChange(this, prevSelected, multiUserCasesEnabled); } private static boolean arePropsEqual(Object a, Object b) { diff --git a/Core/src/org/sleuthkit/autopsy/coreutils/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/coreutils/Bundle.properties-MERGED index a0d535f8e6..18e279dd2c 100755 --- a/Core/src/org/sleuthkit/autopsy/coreutils/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/coreutils/Bundle.properties-MERGED @@ -30,9 +30,7 @@ PlatformUtil.getProcVmUsed.sigarNotInit.msg=Cannot get virt mem used, sigar not PlatformUtil.getProcVmUsed.gen.msg=Cannot get virt mem used, {0} PlatformUtil.getJvmMemInfo.usageText=JVM heap usage: {0}, JVM non-heap usage: {1} PlatformUtil.getPhysicalMemInfo.usageText=Physical memory usage (max, total, free): {0}, {1}, {2} -PlatformUtil.getAllMemUsageInfo.usageText={0}\n\ -{1}\n\ -Process Virtual Memory: {2} +PlatformUtil.getAllMemUsageInfo.usageText={0}\n{1}\nProcess Virtual Memory: {2} # {0} - file name ReadImageTask.mesageText=Reading image: {0} StringExtract.illegalStateException.cannotInit.msg=Unicode table not properly initialized, cannot instantiate StringExtract diff --git a/Core/src/org/sleuthkit/autopsy/filesearch/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/filesearch/Bundle.properties-MERGED index 0e732c1519..c585d0edf5 100755 --- a/Core/src/org/sleuthkit/autopsy/filesearch/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/filesearch/Bundle.properties-MERGED @@ -14,7 +14,7 @@ KnownStatusSearchPanel.knownCheckBox.text=Known Status: KnownStatusSearchPanel.knownBadOptionCheckBox.text=Notable KnownStatusSearchPanel.knownOptionCheckBox.text=Known (NSRL or other) KnownStatusSearchPanel.unknownOptionCheckBox.text=Unknown -DateSearchFilter.noneSelectedMsg.text=At least one date type must be selected\! +DateSearchFilter.noneSelectedMsg.text=At least one date type must be selected! DateSearchPanel.dateCheckBox.text=Date: DateSearchPanel.jLabel4.text=Timezone: DateSearchPanel.jLabel3.text=*The date format is mm/dd/yyyy @@ -57,7 +57,7 @@ FileSearchPanel.search.results.details=Large number of matches may impact perfor FileSearchPanel.search.exception.noFilterSelected.msg=At least one filter must be selected. FileSearchPanel.search.validationErr.msg=Validation Error: {0} FileSearchPanel.emptyWhereClause.text=Invalid options, nothing to show. -KnownStatusSearchFilter.noneSelectedMsg.text=At least one known status must be selected\! +KnownStatusSearchFilter.noneSelectedMsg.text=At least one known status must be selected! NameSearchFilter.emptyNameMsg.text=Must enter something for name search. SizeSearchPanel.sizeCompareComboBox.equalTo=equal to SizeSearchPanel.sizeCompareComboBox.greaterThan=greater than diff --git a/Core/src/org/sleuthkit/autopsy/ingest/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/ingest/Bundle.properties-MERGED index 9e4f612b6b..6be3e48e71 100755 --- a/Core/src/org/sleuthkit/autopsy/ingest/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/ingest/Bundle.properties-MERGED @@ -140,7 +140,7 @@ IngestJob.cancelReason.outOfDiskSpace.text=Out of disk space IngestJob.cancelReason.servicesDown.text=Services Down IngestJob.cancelReason.caseClosed.text=Case closed IngestJobSettingsPanel.globalSettingsButton.text=Global Settings -gest +gest= IngestJobSettingsPanel.globalSettingsButton.actionCommand=Advanced IngestJobSettingsPanel.globalSettingsButton.text=Global Settings IngestJobSettingsPanel.pastJobsButton.text=History diff --git a/Core/src/org/sleuthkit/autopsy/modules/embeddedfileextractor/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/modules/embeddedfileextractor/Bundle.properties-MERGED index 4585d86449..4729293fb9 100755 --- a/Core/src/org/sleuthkit/autopsy/modules/embeddedfileextractor/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/modules/embeddedfileextractor/Bundle.properties-MERGED @@ -11,12 +11,7 @@ ExtractArchiveWithPasswordAction.progress.text=Unpacking contents of archive: {0 ExtractArchiveWithPasswordAction.prompt.text=Enter Password ExtractArchiveWithPasswordAction.prompt.title=Enter Password OpenIDE-Module-Display-Category=Ingest Module -OpenIDE-Module-Long-Description=\ - Embedded File Extraction Ingest Module\n\nThe Embedded File Extraction Ingest Module processes document files (such as doc, docx, ppt, pptx, xls, xlsx) and archive files (such as zip and others archive types supported by the 7zip extractor).\n\ - Contents of these files are extracted and the derived files are added back to the current ingest to be processed by the configured ingest modules.\n\ - If the derived file happens to be an archive file, it will be re-processed by the 7zip extractor - the extractor will process archive files N-levels deep.\n\n\ - The extracted files are navigable in the directory tree.\n\n\ - The module is supported on Windows, Linux and Mac operating systems. +OpenIDE-Module-Long-Description=Embedded File Extraction Ingest Module\n\nThe Embedded File Extraction Ingest Module processes document files (such as doc, docx, ppt, pptx, xls, xlsx) and archive files (such as zip and others archive types supported by the 7zip extractor).\nContents of these files are extracted and the derived files are added back to the current ingest to be processed by the configured ingest modules.\nIf the derived file happens to be an archive file, it will be re-processed by the 7zip extractor - the extractor will process archive files N-levels deep.\n\nThe extracted files are navigable in the directory tree.\n\nThe module is supported on Windows, Linux and Mac operating systems. OpenIDE-Module-Name=Embedded File Extraction OpenIDE-Module-Short-Description=Embedded File Extraction Ingest Module EmbeddedFileExtractorIngestModule.SevenZipContentReadStream.seek.exception.invalidOrigin=Invalid seek origin: {0} @@ -28,6 +23,7 @@ EmbeddedFileExtractorIngestModule.ArchiveExtractor.isZipBombCheck.warnMsg=Possib EmbeddedFileExtractorIngestModule.ArchiveExtractor.isZipBombCheck.warnDetails=Compression ratio is {0}, skipping items in {1}. EmbeddedFileExtractorIngestModule.ArchiveExtractor.unpack.warnMsg.zipBomb=Possible ZIP bomb detected: {0} EmbeddedFileExtractorIngestModule.ArchiveExtractor.unpack.warnDetails.zipBomb=The archive is {0} levels deep, skipping processing of {1} +EmbeddedFileExtractorIngestModule.ArchiveExtractor.unpack.unknownPath.msg=Unknown item path in archive: {0}, will use: {1} EmbeddedFileExtractorIngestModule.ArchiveExtractor.unpack.notEnoughDiskSpace.msg=Not enough disk space to unpack archive item: {0}, {1} EmbeddedFileExtractorIngestModule.ArchiveExtractor.unpack.notEnoughDiskSpace.details=The archive item is too large to unpack, skipping unpacking this item. EmbeddedFileExtractorIngestModule.ArchiveExtractor.unpack.errUnpacking.msg=Error unpacking {0} diff --git a/Core/src/org/sleuthkit/autopsy/modules/exif/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/modules/exif/Bundle.properties-MERGED index f9a5a88b1b..4915d5a124 100755 --- a/Core/src/org/sleuthkit/autopsy/modules/exif/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/modules/exif/Bundle.properties-MERGED @@ -2,9 +2,7 @@ CannotRunFileTypeDetection=Cannot run file type detection. ExifParserFileIngestModule.indexError.message=Failed to post EXIF Metadata artifact(s). ExifParserFileIngestModule.userContent.description=EXIF metadata exists for this file. OpenIDE-Module-Display-Category=Ingest Module -OpenIDE-Module-Long-Description=\ - Exif metadata ingest module. \n\n\ - The ingest module analyzes image files, extracts Exif information and posts the Exif data as results. +OpenIDE-Module-Long-Description=Exif metadata ingest module. \n\nThe ingest module analyzes image files, extracts Exif information and posts the Exif data as results. OpenIDE-Module-Name=ExifParser OpenIDE-Module-Short-Description=Exif metadata ingest module ExifParserFileIngestModule.moduleName.text=Exif Parser diff --git a/Core/src/org/sleuthkit/autopsy/modules/fileextmismatch/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/modules/fileextmismatch/Bundle.properties-MERGED index cfaadf1635..5063bd55fa 100755 --- a/Core/src/org/sleuthkit/autopsy/modules/fileextmismatch/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/modules/fileextmismatch/Bundle.properties-MERGED @@ -36,27 +36,27 @@ FileExtMismatchSettingsPanel.jLabel1.text=File Types: FileExtMismatchSettingsPanel.newExtButton.text=New Extension FileExtMismatchSettingsPanel.newMimePrompt.message=Add a new MIME file type: FileExtMismatchSettingsPanel.newMimePrompt.title=New MIME -FileExtMismatchSettingsPanel.newMimePrompt.emptyMime.message=MIME type text is empty\! +FileExtMismatchSettingsPanel.newMimePrompt.emptyMime.message=MIME type text is empty! FileExtMismatchSettingsPanel.newMimePrompt.emptyMime.title=Empty type -FileExtMismatchSettingsPanel.newMimePrompt.mimeTypeNotSupported.message=MIME type not supported\! +FileExtMismatchSettingsPanel.newMimePrompt.mimeTypeNotSupported.message=MIME type not supported! FileExtMismatchSettingsPanel.newMimePrompt.mimeTypeNotSupported.title=Type not supported -FileExtMismatchSettingsPanel.newMimePrompt.mimeTypeExists.message=MIME type already exists\! +FileExtMismatchSettingsPanel.newMimePrompt.mimeTypeExists.message=MIME type already exists! FileExtMismatchSettingsPanel.newMimePrompt.mimeTypeExists.title=Type already exists FileExtMismatchSettingsPanel.newMimePrompt.mimeTypeNotDetectable.message=MIME type is not detectable by this module. FileExtMismatchSettingsPanel.newMimePrompt.mimeTypeNotDetectable.title=Type not detectable -FileExtMismatchSettingsPanel.removeTypeButton.noneSelected.message=No MIME type selected\! +FileExtMismatchSettingsPanel.removeTypeButton.noneSelected.message=No MIME type selected! FileExtMismatchSettingsPanel.removeTypeButton.noneSelected.title=No type selected FileExtMismatchSettingsPanel.newExtPrompt.message=Add an allowed extension: FileExtMismatchSettingsPanel.newExtPrompt.title=New allowed extension -FileExtMismatchSettingsPanel.newExtPrompt.empty.message=Extension text is empty\! +FileExtMismatchSettingsPanel.newExtPrompt.empty.message=Extension text is empty! FileExtMismatchSettingsPanel.newExtPrompt.empty.title=Extension text empty -FileExtMismatchSettingsPanel.newExtPrompt.noMimeType.message=No MIME type selected\! +FileExtMismatchSettingsPanel.newExtPrompt.noMimeType.message=No MIME type selected! FileExtMismatchSettingsPanel.newExtPrompt.noMimeType.title=No MIME type selected -FileExtMismatchSettingsPanel.newExtPrompt.extExists.message=Extension already exists\! +FileExtMismatchSettingsPanel.newExtPrompt.extExists.message=Extension already exists! FileExtMismatchSettingsPanel.newExtPrompt.extExists.title=Extension already exists -FileExtMismatchSettingsPanel.removeExtButton.noneSelected.message=No extension selected\! +FileExtMismatchSettingsPanel.removeExtButton.noneSelected.message=No extension selected! FileExtMismatchSettingsPanel.removeExtButton.noneSelected.title=No extension selected -FileExtMismatchSettingsPanel.removeExtButton.noMimeTypeSelected.message=No MIME type selected\! +FileExtMismatchSettingsPanel.removeExtButton.noMimeTypeSelected.message=No MIME type selected! FileExtMismatchSettingsPanel.removeExtButton.noMimeTypeSelected.title=No MIME type selected FileExtMismatchSettingsPanel.removeTypeButton.toolTipText= FileExtMismatchModuleSettingsPanel.checkAllRadioButton.text=Check all file types diff --git a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/Bundle.properties-MERGED index 0b470ce6b1..44057d0016 100755 --- a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/Bundle.properties-MERGED @@ -49,10 +49,7 @@ ImportCentralRepoDbProgressDialog.errorParsingFile.message=Error parsing hash se ImportCentralRepoDbProgressDialog.linesProcessed.message=\ hashes processed ImportCentralRepoDbProgressDialog.title.text=Central Repository Import Progress OpenIDE-Module-Display-Category=Ingest Module -OpenIDE-Module-Long-Description=\ - Hash Set ingest module. \n\n\ - The ingest module analyzes files in the disk image and marks them as "known" (based on NSRL hashset lookup for "known" files) and "bad / interesting" (based on one or more hash sets supplied by the user).\n\n\ - The module also contains additional non-ingest tools that are integrated in the GUI, such as file lookup by hash and hash set configuration. +OpenIDE-Module-Long-Description=Hash Set ingest module. \n\nThe ingest module analyzes files in the disk image and marks them as "known" (based on NSRL hashset lookup for "known" files) and "bad / interesting" (based on one or more hash sets supplied by the user).\n\nThe module also contains additional non-ingest tools that are integrated in the GUI, such as file lookup by hash and hash set configuration. OpenIDE-Module-Name=HashDatabases OptionsCategory_Name_HashDatabase=Hash Sets OptionsCategory_Keywords_HashDatabase=Hash Sets @@ -181,10 +178,7 @@ HashDbSearchThread.name.searching=Searching HashDbSearchThread.noMoreFilesWithMD5Msg=No other files with the same MD5 hash were found. ModalNoButtons.indexingDbsTitle=Indexing hash sets ModalNoButtons.indexingDbTitle=Indexing hash set -ModalNoButtons.exitHashDbIndexingMsg=You are about to exit out of indexing your hash sets. \n\ -The generated index will be left unusable. If you choose to continue,\n\ - please delete the corresponding -md5.idx file in the hash folder.\n\ - Exit indexing? +ModalNoButtons.exitHashDbIndexingMsg=You are about to exit out of indexing your hash sets. \nThe generated index will be left unusable. If you choose to continue,\nplease delete the corresponding -md5.idx file in the hash folder.\nExit indexing? ModalNoButtons.dlgTitle.unfinishedIndexing=Unfinished Indexing ModalNoButtons.indexThis.currentlyIndexing1Db=Currently indexing 1 hash set ModalNoButtons.indexThese.currentlyIndexing1OfNDbs=Currently indexing 1 of {0} diff --git a/Core/src/org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties-MERGED index 1279d3642b..31a0690b82 100755 --- a/Core/src/org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties-MERGED @@ -83,8 +83,8 @@ FilesSetRulePanel.nameTextField.text= FilesSetRulePanel.ruleNameLabel.text=Rule Name (Optional): FilesSetRulePanel.messages.emptyNameCondition=You must specify a name pattern for this rule. FilesSetRulePanel.messages.invalidNameRegex=The name regular expression is not valid:\n\n{0} -FilesSetRulePanel.messages.invalidCharInName=The name cannot contain \\, /, :, *, ?, \", <, or > unless it is a regular expression. -FilesSetRulePanel.messages.invalidCharInPath=The path cannot contain \\, :, *, ?, \", <, or > unless it is a regular expression. +FilesSetRulePanel.messages.invalidCharInName=The name cannot contain \\, /, :, *, ?, ", <, or > unless it is a regular expression. +FilesSetRulePanel.messages.invalidCharInPath=The path cannot contain \\, :, *, ?, ", <, or > unless it is a regular expression. FilesSetRulePanel.messages.invalidPathRegex=The path regular expression is not valid:\n\n{0} FilesSetDefsPanel.doFileSetsDialog.duplicateRuleSet.text=Rule set with name {0} already exists. FilesSetRulePanel.pathSeparatorInfoLabel.text=Folder must be in parent path. Use '/' to give consecutive names diff --git a/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/Bundle.properties-MERGED index 87dacfc16c..2dc971a40d 100755 --- a/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/Bundle.properties-MERGED @@ -21,7 +21,7 @@ PhotoRecIngestModule.complete.totalParsetime=Total Parsing Time: PhotoRecIngestModule.complete.photoRecResults=PhotoRec Results PhotoRecIngestModule.NotEnoughDiskSpace.detail.msg=PhotoRec error processing {0} with {1} Not enough space on primary disk to save unallocated space. PhotoRecIngestModule.cancelledByUser=PhotoRec cancelled by user. -PhotoRecIngestModule.error.exitValue=PhotoRec carver returned error exit value \= {0} when scanning {1} +PhotoRecIngestModule.error.exitValue=PhotoRec carver returned error exit value = {0} when scanning {1} PhotoRecIngestModule.error.msg=Error processing {0} with PhotoRec carver. PhotoRecIngestModule.complete.numberOfErrors=Number of Errors while Carving: PhotoRecCarverIngestJobSettingsPanel.detectionSettingsLabel.text=PhotoRec Settings diff --git a/Core/src/org/sleuthkit/autopsy/report/modules/html/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/report/modules/html/Bundle.properties-MERGED index 32f6867f0c..0be7595111 100755 --- a/Core/src/org/sleuthkit/autopsy/report/modules/html/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/report/modules/html/Bundle.properties-MERGED @@ -5,8 +5,8 @@ ReportHTML.getName.text=HTML Report ReportHTML.getDesc.text=A report about results and tagged items in HTML format. ReportHTML.writeIndex.title=for case {0} ReportHTML.writeIndex.noFrames.msg=Your browser is not compatible with our frame setup. -ReportHTML.writeIndex.noFrames.seeNav=Please see the navigation page for artifact links, -ReportHTML.writeIndex.seeSum=and the summary page for a case summary. +ReportHTML.writeIndex.noFrames.seeNav=Please see the navigation page for artifact links, +ReportHTML.writeIndex.seeSum=and the summary page for a case summary. ReportHTML.writeNav.title=Report Navigation ReportHTML.writeNav.h1=Report Navigation ReportHTML.writeNav.summary=Case Summary @@ -16,7 +16,7 @@ ReportHTML.writeSum.caseNumber=Case Number: ReportHTML.writeSum.caseNumImages=Number of Images: ReportHTML.writeSum.examiner=Examiner: ReportHTML.writeSum.title=Case Summary -ReportHTML.writeSum.warningMsg=Warning, this report was run before ingest services completed\! +ReportHTML.writeSum.warningMsg=Warning, this report was run before ingest services completed! # # autopsy/test/scripts/regression.py._html_report_diff() uses reportGenOn.text, caseName, caseNum, # examiner as a regex signature to skip report.html and summary.html diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDatamodelTest.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDatamodelTest.java index c95b58b874..0016428a0d 100755 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDatamodelTest.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDatamodelTest.java @@ -130,8 +130,7 @@ public class CentralRepoDatamodelTest extends TestCase { dbSettingsSqlite.saveSettings(); CentralRepoDbUtil.setUseCentralRepo(true); - CentralRepoPlatforms.setSelectedPlatform(CentralRepoPlatforms.SQLITE.name()); - CentralRepoPlatforms.saveSelectedPlatform(); + CentralRepoDbManager.saveDbChoice(CentralRepoDbChoice.SQLITE); } catch (CentralRepoException ex) { Exceptions.printStackTrace(ex); Assert.fail(ex.getMessage()); diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonpropertiessearch/InterCaseTestUtils.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonpropertiessearch/InterCaseTestUtils.java index 65b47bcb3b..bd297579a7 100644 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonpropertiessearch/InterCaseTestUtils.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonpropertiessearch/InterCaseTestUtils.java @@ -47,6 +47,8 @@ import org.sleuthkit.autopsy.testutils.IngestUtils; import org.sleuthkit.datamodel.TskCoreException; import junit.framework.Assert; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; +import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoDbChoice; +import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoDbManager; import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance; import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationCase; import org.sleuthkit.autopsy.coreutils.TimeStampUtils; @@ -303,8 +305,7 @@ class InterCaseTestUtils { centralRepoSchemaFactory.insertDefaultDatabaseContent(); crSettings.saveSettings(); - CentralRepoPlatforms.setSelectedPlatform(CentralRepoPlatforms.SQLITE.name()); - CentralRepoPlatforms.saveSelectedPlatform(); + CentralRepoDbManager.saveDbChoice(CentralRepoDbChoice.SQLITE); } /** diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Bundle.properties-MERGED b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Bundle.properties-MERGED index ebdce8a327..18deff87f4 100755 --- a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Bundle.properties-MERGED +++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Bundle.properties-MERGED @@ -1,6 +1,7 @@ cannotBuildXmlParser=Unable to build XML parser: cannotLoadSEUQA=Unable to load Search Engine URL Query Analyzer settings file, SEUQAMappings.xml: cannotParseXml=Unable to parse XML file: +Chrome.getBookmark.errMsg.errAnalyzeFile={0}: Error while trying to analyze file: {1} ChromeCacheExtract_adding_artifacts_msg=Chrome Cache: Adding %d artifacts for analysis. ChromeCacheExtract_adding_extracted_files_msg=Chrome Cache: Adding %d extracted files for analysis. ChromeCacheExtract_loading_files_msg=Chrome Cache: Loading files from %s. @@ -13,9 +14,9 @@ ChromeCacheExtractor.progressMsg={0}: Extracting cache entry {1} of {2} entries DataSourceUsage_AndroidMedia=Android Media Card DataSourceUsage_DJU_Drone_DAT=DJI Internal SD Card DataSourceUsage_FlashDrive=Flash Drive -# {0} - OS name DataSourceUsageAnalyzer.customVolume.label=OS Drive ({0}) DataSourceUsageAnalyzer.parentModuleName=Recent Activity +Extract.dbConn.errMsg.failedToQueryDb={0}: Failed to query database. Extract.indexError.message=Failed to index artifact for keyword search. Extract.noOpenCase.errMsg=No open case available. ExtractEdge_getHistory_containerFileNotFound=Error while trying to analyze Edge history @@ -24,6 +25,11 @@ ExtractEdge_process_errMsg_errGettingWebCacheFiles=Error trying to retrieving Ed ExtractEdge_process_errMsg_spartanFail=Failure processing Microsoft Edge spartan.edb file ExtractEdge_process_errMsg_unableFindESEViewer=Unable to find ESEDatabaseViewer ExtractEdge_process_errMsg_webcacheFail=Failure processing Microsoft Edge WebCacheV01.dat file +ExtractIE.getBookmark.ere.noSpace=RecentActivity +ExtractIE.getBookmark.errMsg.errPostingBookmarks=Error posting Internet Explorer Bookmark artifacts. +ExtractIE.getCookie.errMsg.errPostingCookies=Error posting Internet Explorer Cookie artifacts. +ExtractIE.getHistory.errMsg.errPostingHistory=Error posting Internet Explorer History artifacts. +Extractor.errPostingArtifacts=Error posting {0} artifacts to the blackboard. ExtractOs.androidOs.label=Android ExtractOs.androidVolume.label=OS Drive (Android) ExtractOs.debianLinuxOs.label=Linux (Debian) @@ -90,7 +96,7 @@ Chrome.getLogin.errMsg.errAnalyzingFiles={0}: Error while trying to analyze file Chrome.getAutofill.errMsg.errGettingFiles=Error when trying to get Chrome Web Data files. Chrome.getAutofill.errMsg.errAnalyzingFiles={0}: Error while trying to analyze file:{1} ExtractIE.moduleName.text=Internet Explorer -ExtractIE.getBookmark.errMsg.errGettingBookmarks={0}: Error getting Internet Explorer Bookmarks. +ExtractIE.getBookmark.errMsg.errGettingBookmarks=Error getting Internet Explorer Bookmarks. ExtractIE.parentModuleName.noSpace=RecentActivity ExtractIE.parentModuleName=Recent Activity ExtractIE.getURLFromIEBmkFile.errMsg={0}: Error parsing IE bookmark File {1} @@ -192,7 +198,6 @@ RecentDocumentsByLnk.parentModuleName.noSpace=RecentActivity RecentDocumentsByLnk.parentModuleName=Recent Activity RegRipperFullNotFound=Full version RegRipper executable not found. RegRipperNotFound=Autopsy RegRipper executable not found. -# {0} - file name SearchEngineURLQueryAnalyzer.init.exception.msg=Unable to find {0}. SearchEngineURLQueryAnalyzer.moduleName.text=Search Engine SearchEngineURLQueryAnalyzer.engineName.none=NONE 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 32871906e7..b20ccf5912 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 -#Thu, 27 Feb 2020 08:01:10 -0500 +#Tue, 12 Nov 2019 17:21:46 -0500 LBL_splash_window_title=Starting Autopsy SPLASH_HEIGHT=314 SPLASH_WIDTH=538 @@ -8,4 +8,4 @@ SplashRunningTextBounds=0,289,538,18 SplashRunningTextColor=0x0 SplashRunningTextFontSize=19 -currentVersion=Autopsy 4.14.0 +currentVersion=Autopsy 4.13.0 diff --git a/branding/modules/org-netbeans-core-windows.jar/org/netbeans/core/windows/view/ui/Bundle.properties b/branding/modules/org-netbeans-core-windows.jar/org/netbeans/core/windows/view/ui/Bundle.properties index 6c1cb1455b..998d3f715c 100644 --- a/branding/modules/org-netbeans-core-windows.jar/org/netbeans/core/windows/view/ui/Bundle.properties +++ b/branding/modules/org-netbeans-core-windows.jar/org/netbeans/core/windows/view/ui/Bundle.properties @@ -1,4 +1,4 @@ #Updated by build script -#Thu, 27 Feb 2020 08:01:10 -0500 -CTL_MainWindow_Title=Autopsy 4.14.0 -CTL_MainWindow_Title_No_Project=Autopsy 4.14.0 +#Tue, 12 Nov 2019 17:21:46 -0500 +CTL_MainWindow_Title=Autopsy 4.13.0 +CTL_MainWindow_Title_No_Project=Autopsy 4.13.0 From b64cf35611ff34ff541e56f7800128755d220add Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Fri, 28 Feb 2020 15:34:11 -0500 Subject: [PATCH 013/100] change for small issue found --- .../centralrepository/datamodel/Bundle.properties-MERGED | 3 ++- .../centralrepository/datamodel/CentralRepoDbManager.java | 7 ------- .../eventlisteners/Bundle.properties-MERGED | 3 +++ .../optionspanel/Bundle.properties-MERGED | 4 ++++ 4 files changed, 9 insertions(+), 8 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/Bundle.properties-MERGED index 9b43833ee2..345d5a420e 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/Bundle.properties-MERGED @@ -7,8 +7,10 @@ AbstractSqlEamDb.cannotUpgrage.message=Currently selected database platform "{0} AbstractSqlEamDb.failedToReadMajorVersion.message=Failed to read schema version for Central Repository. AbstractSqlEamDb.failedToReadMinorVersion.message=Failed to read schema minor version for Central Repository. AbstractSqlEamDb.upgradeSchema.incompatible=The selected Central Repository is not compatible with the current version of the application, please upgrade the application if you wish to use this Central Repository. +CentralRepoDbManager.connectionErrorMsg.text=Failed to connect to central repository database. CorrelationAttributeInstance.invalidName.message=Invalid database table name. Name must start with a lowercase letter and can only contain lowercase letters, numbers, and '_'. CorrelationAttributeInstance.nullName.message=Database name is null. +CorrelationAttributeUtil.emailaddresses.text=Email Addresses CorrelationType.DOMAIN.displayName=Domains CorrelationType.EMAIL.displayName=Email Addresses CorrelationType.FILES.displayName=Files @@ -23,7 +25,6 @@ DataSourceUpdateService.serviceName.text=Update Central Repository Data Sources EamArtifactInstances.knownStatus.bad=Bad EamArtifactInstances.knownStatus.known=Known EamArtifactInstances.knownStatus.unknown=Unknown -EamArtifactUtil.emailaddresses.text=Email Addresses EamCase.title.caseDisplayName=Case Name: EamCase.title.caseNumber=Case Number: EamCase.title.caseUUID=Case UUID: diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java index c116e79c94..35acc1b2b2 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java @@ -58,13 +58,6 @@ public class CentralRepoDbManager { String selectedPlatformString = ModuleSettings.getConfigSetting("CentralRepository", "db.selectedPlatform"); // NON-NLS SAVED_CHOICE = fromKey(selectedPlatformString); } - - // do a sanity check: if loading multi user postgres connection, make sure setting is enabled. - // if not, disable central repo - if (SAVED_CHOICE == CentralRepoDbChoice.POSTGRESQL_MULTIUSER && !UserPreferences.getIsMultiUserModeEnabled()) { - CentralRepoDbUtil.setUseCentralRepo(false); - SAVED_CHOICE = CentralRepoDbChoice.DISABLED; - } return SAVED_CHOICE; } diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/Bundle.properties-MERGED index b7c3df2c53..cd654a5b37 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/Bundle.properties-MERGED @@ -7,3 +7,6 @@ IngestEventsListener.prevCount.text=Number of previous {0}: {1} IngestEventsListener.prevExists.text=Previously Seen Devices (Central Repository) IngestEventsListener.prevTaggedSet.text=Previously Tagged As Notable (Central Repository) Installer.centralRepoUpgradeFailed.title=Central repository disabled +Installer.initialCreateSqlite.messageDesc=It will store information about all hashes and identifiers that you process. You can use this to ignore previously seen files and make connections between cases. +Installer.initialCreateSqlite.messageHeader=The Central Repository is not enabled. Would you like to? +Installer.initialCreateSqlite.title=Enable Central Repository? diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/Bundle.properties-MERGED index 7277910e7d..143347b06c 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/Bundle.properties-MERGED @@ -33,6 +33,10 @@ EamDbSettingsDialog.validation.finished=Click OK to save your database settings EamDbSettingsDialog.validation.incompleteFields=Fill in all values for the selected database. EamOptionsController.moduleErr=Error processing value changes. EamOptionsController.moduleErr.msg=Value change processing failed. +GlobalSettingsPanel.onMultiUserChange.disabledMu.description=Since mult-user cases have been disabled, 'PostgreSQL using multi-user settings' is no longer a valid option for Central Repository. Would you like to choose another Central Repository database? +GlobalSettingsPanel.onMultiUserChange.disabledMu.title=Central Repository Change Necessary +GlobalSettingsPanel.onMultiUserChange.enable.description=Do you want to enable Central Repository using these settings? +GlobalSettingsPanel.onMultiUserChange.enable.title=Enable Central Repository? GlobalSettingsPanel.updateFailed.title=Central repository disabled GlobalSettingsPanel.validationErrMsg.ingestRunning=You cannot change settings while ingest is running. GlobalSettingsPanel.validationerrMsg.mustConfigure=Configure the database to enable this module. From d0fca6e2aca6b21d69954315aa1c244397e4d66e Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Mon, 2 Mar 2020 10:00:06 -0500 Subject: [PATCH 014/100] updates for creating db if does not exist --- .../optionspanel/EamDbSettingsDialog.java | 53 ++++++++++++++----- .../optionspanel/GlobalSettingsPanel.java | 21 ++++++-- 2 files changed, 57 insertions(+), 17 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java index c043687586..c2932c84fb 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java @@ -153,6 +153,8 @@ public class EamDbSettingsDialog extends JDialog { /** * prompts user based on testing status (i.e. failure to connect, invalid schema, db does not exist, etc.) + * @param manager the manager to use when setting up the database + * @param dialog if non-null value, validates settings and updates 'okay' button enabled state * @return whether or not the ultimate status after prompts is okay to continue */ @NbBundle.Messages({"EamDbSettingsDialog.okButton.corruptDatabaseExists.title=Error Loading Database", @@ -164,7 +166,7 @@ public class EamDbSettingsDialog extends JDialog { "EamDbSettingsDialog.okButton.createSQLiteDbError.message=Unable to create SQLite Database, please ensure location exists and you have write permissions and try again.", "EamDbSettingsDialog.okButton.createPostgresDbError.message=Unable to create Postgres Database, please ensure address, port, and login credentials are correct for Postgres server and try again.", "EamDbSettingsDialog.okButton.createDbError.title=Unable to Create Database"}) - private boolean promptTestStatusWarnings() { + private static boolean promptTestStatusWarnings(CentralRepoDbManager manager, EamDbSettingsDialog dialog) { if (manager.getStatus() == DatabaseTestResult.CONNECTION_FAILED) { JOptionPane.showMessageDialog(WindowManager.getDefault().getMainWindow(), Bundle.EamDbSettingsDialog_okButton_databaseConnectionFailed_message(), @@ -204,7 +206,8 @@ public class EamDbSettingsDialog extends JDialog { JOptionPane.WARNING_MESSAGE); } - valid(); + if (dialog != null) + dialog.valid(); } } @@ -502,14 +505,40 @@ public class EamDbSettingsDialog extends JDialog { "EamDbSettingsDialog.okButton.errorMsg.text=Please restart Autopsy to begin using the new database platform.", "EamDbSettingsDialog.okButton.connectionErrorMsg.text=Failed to connect to central repository database."}) private void bnOkActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnOkActionPerformed - setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); + testStatusAndCreate(this, manager, this); + dispose(); + }//GEN-LAST:event_bnOkActionPerformed + + + /** + * tests status for central repo db / creation and prompts user accordingly + * @param parent the parent component (the anchor for displaying dialogs) + * @param manager the central repo db manager with settings to be tested and saved + * @return whether or not central repo db was successfully be created or found + */ + public static boolean testStatusAndCreate(Component parent, CentralRepoDbManager manager) { + return testStatusAndCreate(parent, manager, null); + } + + + /** + * tests status for central repo db / creation and prompts user accordingly + * @param parent the parent component (the anchor for displaying dialogs) + * @param manager the central repo db manager with settings to be tested and saved + * @param dialog the db settings dialog; if non-null, will validate okay button state + * @return whether or not central repo db was successfully be created or found + */ + private static boolean testStatusAndCreate(Component parent, CentralRepoDbManager manager, EamDbSettingsDialog dialog) { + parent.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); manager.testStatus(); - valid(); - boolean testedOk = promptTestStatusWarnings(); + if (dialog != null) + dialog.valid(); + + boolean testedOk = promptTestStatusWarnings(manager, dialog); if (!testedOk) { - setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); - return; + parent.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); + return false; } try{ @@ -517,18 +546,16 @@ public class EamDbSettingsDialog extends JDialog { } catch (CentralRepoException e) { SwingUtilities.invokeLater(() -> { - JOptionPane.showMessageDialog(this, + JOptionPane.showMessageDialog(parent, Bundle.EamDbSettingsDialog_okButton_errorMsg_text(), Bundle.EamDbSettingsDialog_okButton_errorTitle_text(), JOptionPane.WARNING_MESSAGE); }); } - - - setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); - dispose(); - }//GEN-LAST:event_bnOkActionPerformed + parent.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); + return true; + } /** * Returns if changes to the central repository configuration were diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java index 4ebdcd31dd..69079329cd 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java @@ -145,8 +145,7 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i // setup database for CR CentralRepoDbManager.saveDbChoice(CentralRepoDbChoice.POSTGRESQL_MULTIUSER); - updateDatabase(parent); - GlobalSettingsPanel.onSettingsChange(); + HandleDbChange(parent); } }); } @@ -176,11 +175,25 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i // changing multi-user settings connection && 'PostgreSQL using multi-user settings' is selected else if (muPreviouslySelected && muCurrentlySelected && crMultiUser) { // test databse for CR change - updateDatabase(parent); - GlobalSettingsPanel.onSettingsChange(); + HandleDbChange(parent); } } + + private static void HandleDbChange(Component parent) { + boolean successful = EamDbSettingsDialog.testStatusAndCreate(parent, new CentralRepoDbManager()); + if (successful) { + updateDatabase(parent); + onSettingsChange(); + } + else { + // disable central repository + CentralRepoDbUtil.setUseCentralRepo(false); + CentralRepoDbManager.saveDbChoice(CentralRepoDbChoice.DISABLED); + } + } + + @Messages({"GlobalSettingsPanel.updateFailed.title=Central repository disabled"}) private static void updateDatabase(Component parent) { if (CentralRepoDbChoice.DISABLED.equals(CentralRepoDbManager.getSavedDbChoice())) { From bd5f846d246aa015919dc435c6292ea75c928c4f Mon Sep 17 00:00:00 2001 From: Mark McKinnon Date: Mon, 2 Mar 2020 11:08:29 -0500 Subject: [PATCH 015/100] Update viber.py Added the coalesce sqlite function to the sql statement, this function will return the first column included in it that does not contain a null value. --- InternalPythonModules/android/viber.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/InternalPythonModules/android/viber.py b/InternalPythonModules/android/viber.py index a5edef4ce9..ded45e186f 100644 --- a/InternalPythonModules/android/viber.py +++ b/InternalPythonModules/android/viber.py @@ -268,8 +268,8 @@ class ViberContactsParser(TskContactsParser): def __init__(self, contact_db): super(ViberContactsParser, self).__init__(contact_db.runQuery( """ - SELECT C.display_name AS name, - D.data2 AS number + SELECT C.display_name AS name, + coalesce(D.data2, D.data1, D.data3) AS number FROM phonebookcontact AS C JOIN phonebookdata AS D ON C._id = D.contact_id From 0dfead369942412dcfdc2273d3ed5dc4fa78f645 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Mon, 2 Mar 2020 14:39:08 -0500 Subject: [PATCH 016/100] updates of gui and codacy items --- .../datamodel/CentralRepoDbChoice.java | 2 +- .../datamodel/CentralRepoDbManager.java | 8 +- .../datamodel/CentralRepoPlatforms.java | 2 +- .../CentralRepoPostgresSettingsUtil.java | 38 +++++-- .../datamodel/PostgresConnectionSettings.java | 21 +++- .../datamodel/PostgresSettingsLoader.java | 41 +++++-- .../ingestmodule/CentralRepoIngestModule.java | 1 - .../optionspanel/EamDbSettingsDialog.java | 81 ++++++++------ .../optionspanel/GlobalSettingsPanel.java | 105 ++++++++++++------ .../MultiUserSettingsPanel.java | 6 +- .../recentactivity/ExtractRegistry.java | 1 + .../recentactivity/RecentDocumentsByLnk.java | 1 + 12 files changed, 208 insertions(+), 99 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbChoice.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbChoice.java index b0084702ae..7670580708 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbChoice.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbChoice.java @@ -19,7 +19,7 @@ package org.sleuthkit.autopsy.centralrepository.datamodel; /** - * + * the database choices available for central repo */ public class CentralRepoDbChoice { public static final CentralRepoDbChoice DISABLED = new CentralRepoDbChoice("Disabled", CentralRepoPlatforms.DISABLED); diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java index 35acc1b2b2..0b7011a8b4 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java @@ -23,7 +23,6 @@ import java.sql.SQLException; import java.util.logging.Level; import org.openide.util.NbBundle; import org.sleuthkit.autopsy.coordinationservice.CoordinationService; -import org.sleuthkit.autopsy.core.UserPreferences; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.ModuleSettings; @@ -38,12 +37,12 @@ public class CentralRepoDbManager { - private static CentralRepoDbChoice SAVED_CHOICE = null; + private static volatile CentralRepoDbChoice SAVED_CHOICE = null; /** * Save the selected platform to the config file. */ - public static CentralRepoDbChoice saveDbChoice(CentralRepoDbChoice choice) { + public static synchronized CentralRepoDbChoice saveDbChoice(CentralRepoDbChoice choice) { choice = (choice == null) ? CentralRepoDbChoice.DISABLED : choice; SAVED_CHOICE = choice; ModuleSettings.setConfigSetting("CentralRepository", "db.selectedPlatform", choice.getSettingKey()); @@ -53,7 +52,7 @@ public class CentralRepoDbManager { /** * Load the selectedPlatform boolean from the config file, if it is set. */ - public static CentralRepoDbChoice getSavedDbChoice() { + public static synchronized CentralRepoDbChoice getSavedDbChoice() { if (SAVED_CHOICE == null) { String selectedPlatformString = ModuleSettings.getConfigSetting("CentralRepository", "db.selectedPlatform"); // NON-NLS SAVED_CHOICE = fromKey(selectedPlatformString); @@ -352,6 +351,7 @@ public class CentralRepoDbManager { // Even if we fail to close the existing connections, make sure that we // save the new connection settings, so an Autopsy restart will correctly // start with the new settings. + CentralRepoDbUtil.setUseCentralRepo(selectedDbChoice != CentralRepoDbChoice.DISABLED); saveDbChoice(selectedDbChoice); CentralRepoDbConnectivityManager selectedDbSettings = getSelectedSettings(); diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoPlatforms.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoPlatforms.java index b9c1a7b4e7..8e909626e0 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoPlatforms.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoPlatforms.java @@ -19,7 +19,7 @@ package org.sleuthkit.autopsy.centralrepository.datamodel; /** - * + * describes the possible database types for central repo */ public enum CentralRepoPlatforms { DISABLED, diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoPostgresSettingsUtil.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoPostgresSettingsUtil.java index c4fec65793..2aa7ca6e29 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoPostgresSettingsUtil.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoPostgresSettingsUtil.java @@ -1,14 +1,30 @@ /* - * 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 2012-2020 Basis Technology Corp. + * + * Copyright 2012 42six Solutions. + * Contact: aebadirad 42six com + * Project Contact/Architect: 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.centralrepository.datamodel; import java.util.HashMap; import java.util.Map; import java.util.logging.Level; -import org.openide.util.Exceptions; import org.sleuthkit.autopsy.core.UserPreferences; import org.sleuthkit.autopsy.core.UserPreferencesException; import org.sleuthkit.autopsy.coreutils.Logger; @@ -18,8 +34,7 @@ import org.sleuthkit.autopsy.coreutils.TextConverterException; import org.sleuthkit.datamodel.CaseDbConnectionInfo; /** - * - * @author gregd + * handles saving and loading of postgres settings for central repo */ public class CentralRepoPostgresSettingsUtil { private final static Logger LOGGER = Logger.getLogger(CentralRepoPostgresSettingsUtil.class.getName()); @@ -68,13 +83,18 @@ public class CentralRepoPostgresSettingsUtil { private static void handleTry(TryHandler handler) { try { - handler.op(); + handler.operation(); + } + catch (CentralRepoException e) { + LOGGER.log(Level.WARNING, "There was an error in converting central repo postgres settings", e); } - catch (CentralRepoException e) {} } + /** + * an action that potentially throws an exception + */ private interface TryHandler { - public void op() throws CentralRepoException; + void operation() throws CentralRepoException; } diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresConnectionSettings.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresConnectionSettings.java index 2f22c8545b..1a4b4ca0b2 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresConnectionSettings.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresConnectionSettings.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. + * Central Repository + * + * Copyright 2015-2020 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.centralrepository.datamodel; @@ -10,7 +23,7 @@ import java.util.regex.Pattern; /** * - * @author gregd + * POJO for postgres settings */ public class PostgresConnectionSettings { private final static String DB_NAMES_REGEX = "[a-z][a-z0-9_]*"; // only lower case diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresSettingsLoader.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresSettingsLoader.java index 855482784d..e293f8bece 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresSettingsLoader.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresSettingsLoader.java @@ -1,23 +1,38 @@ /* - * 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. + * Central Repository + * + * Copyright 2015-2020 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.centralrepository.datamodel; /** - * - * @author gregd + * interface to load or save postgres settings */ public interface PostgresSettingsLoader { PostgresConnectionSettings loadSettings(); void saveSettings(PostgresConnectionSettings settings); - public static PostgresSettingsLoader CUSTOM_LOADER = new Custom(); - public static PostgresSettingsLoader MULTIUSER_LOADER = new MultiUser(); + PostgresSettingsLoader CUSTOM_LOADER = new Custom(); + PostgresSettingsLoader MULTIUSER_LOADER = new MultiUser(); - static class Custom implements PostgresSettingsLoader { + /** + * loads and saves custom postgres settings + */ + class Custom implements PostgresSettingsLoader { @Override public PostgresConnectionSettings loadSettings() { return CentralRepoPostgresSettingsUtil.loadCustomSettings(); @@ -30,13 +45,21 @@ public interface PostgresSettingsLoader { } - static class MultiUser implements PostgresSettingsLoader { + /** + * loads multi user postgres settings to be used with central repo + * NOTE: does not save settings on save operation as this is merely a proxy + */ + class MultiUser implements PostgresSettingsLoader { @Override public PostgresConnectionSettings loadSettings() { return CentralRepoPostgresSettingsUtil.loadMultiUserSettings(); } + /** + * no need to save since this is just a proxy to multi user settings + * @param settings the settings to save + */ @Override public void saveSettings(PostgresConnectionSettings settings) {} } diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/CentralRepoIngestModule.java b/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/CentralRepoIngestModule.java index 4754f77b3e..1f7472d330 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/CentralRepoIngestModule.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/CentralRepoIngestModule.java @@ -33,7 +33,6 @@ import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationDataSource; import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeUtil; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoException; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoPlatforms; -import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoDbChoice; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoDbManager; import org.sleuthkit.autopsy.centralrepository.eventlisteners.IngestEventsListener; import org.sleuthkit.autopsy.core.RuntimeProperties; diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java index c2932c84fb..a3a19fe811 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java @@ -21,6 +21,7 @@ package org.sleuthkit.autopsy.centralrepository.optionspanel; import java.awt.Color; import java.awt.Component; import java.awt.Cursor; +import java.awt.HeadlessException; import java.io.File; import java.io.IOException; import java.util.ArrayList; @@ -50,8 +51,6 @@ import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoException; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoPlatforms; import org.sleuthkit.autopsy.centralrepository.datamodel.DatabaseTestResult; import org.sleuthkit.autopsy.centralrepository.datamodel.SqliteCentralRepoSettings; -import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository; -import org.sleuthkit.autopsy.centralrepository.datamodel.RdbmsCentralRepoFactory; import org.sleuthkit.autopsy.core.UserPreferences; /** @@ -66,16 +65,15 @@ public class EamDbSettingsDialog extends JDialog { private static final DbChoiceRenderer DB_CHOICE_RENDERER = new DbChoiceRenderer(); private static boolean isDbChoiceSelectable(CentralRepoDbChoice item) { - if (item == CentralRepoDbChoice.POSTGRESQL_MULTIUSER && !UserPreferences.getIsMultiUserModeEnabled()) { - return false; - } - else { - return true; - } + return (item != CentralRepoDbChoice.POSTGRESQL_MULTIUSER || UserPreferences.getIsMultiUserModeEnabled()); } + /** + * handles displaying and rendering drop down menu for database choices in central repo + */ private static class DbChoiceRenderer extends BasicComboBoxRenderer { - + private static final long serialVersionUID = 1L; + public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { @@ -94,6 +92,9 @@ public class EamDbSettingsDialog extends JDialog { private final TextBoxChangedListener textBoxChangedListener; private final CentralRepoDbManager manager = new CentralRepoDbManager(); + public EamDbSettingsDialog() { + this(null); + } /** * Creates new form EamDbSettingsDialog @@ -102,7 +103,7 @@ public class EamDbSettingsDialog extends JDialog { "EamDbSettingsDialog.lbSingleUserSqLite.text=SQLite should only be used by one examiner at a time.", "EamDbSettingsDialog.lbDatabaseType.text=Database Type :", "EamDbSettingsDialog.fcDatabasePath.title=Select location for central_repository.db"}) - public EamDbSettingsDialog() { + public EamDbSettingsDialog(CentralRepoDbChoice initialMenuItem) { super((JFrame) WindowManager.getDefault().getMainWindow(), Bundle.EamDbSettingsDialog_title_text(), true); @@ -129,24 +130,24 @@ public class EamDbSettingsDialog extends JDialog { } }); - setupDbChoice(); - customizeComponents(); + setupDbChoice(initialMenuItem); valid(); display(); } - private void setupDbChoice() { + private void setupDbChoice(CentralRepoDbChoice initialMenuItem) { // setup initially selected item - CentralRepoDbChoice toSelect = + CentralRepoDbChoice toSelect = (initialMenuItem == null) ? (Arrays.asList(CentralRepoDbChoice.DB_CHOICES).contains(manager.getSelectedDbChoice())) ? manager.getSelectedDbChoice() : - CentralRepoDbChoice.DB_CHOICES[0]; - - cbDatabaseType.setSelectedItem(toSelect); + CentralRepoDbChoice.DB_CHOICES[0] : + initialMenuItem; // set the renderer so item is unselectable if inappropriate cbDatabaseType.setRenderer(DB_CHOICE_RENDERER); + + changeDbSelection(toSelect); } @@ -188,22 +189,7 @@ public class EamDbSettingsDialog extends JDialog { manager.createDb(); } catch (CentralRepoException e) { - // in the event that there is a failure to connect, notify user with corresponding message - String errorMessage = ""; - if (manager == null || manager.getSelectedDbChoice() == null) { - errorMessage = ""; - } - else if (manager.getSelectedDbChoice().getDbPlatform() == CentralRepoPlatforms.POSTGRESQL) { - errorMessage = Bundle.EamDbSettingsDialog_okButton_createPostgresDbError_message(); - } - else if (manager.getSelectedDbChoice().getDbPlatform() == CentralRepoPlatforms.SQLITE) { - errorMessage = Bundle.EamDbSettingsDialog_okButton_createSQLiteDbError_message(); - } - - JOptionPane.showMessageDialog(WindowManager.getDefault().getMainWindow(), - errorMessage, - Bundle.EamDbSettingsDialog_okButton_createDbError_title(), - JOptionPane.WARNING_MESSAGE); + onPromptStatusError(manager); } if (dialog != null) @@ -213,6 +199,28 @@ public class EamDbSettingsDialog extends JDialog { return (manager.getStatus() == DatabaseTestResult.TESTEDOK); } + + + /** + * when an error occurs while going through promptTestStatusWarning, this method is called + * @param manager1 the manager to use as service class + * @throws HeadlessException + */ + private static void onPromptStatusError(CentralRepoDbManager manager1) { + // in the event that there is a failure to connect, notify user with corresponding message + String errorMessage = ""; + if (manager1 == null || manager1.getSelectedDbChoice() == null) { + errorMessage = ""; + } else if (manager1.getSelectedDbChoice().getDbPlatform() == CentralRepoPlatforms.POSTGRESQL) { + errorMessage = Bundle.EamDbSettingsDialog_okButton_createPostgresDbError_message(); + } else if (manager1.getSelectedDbChoice().getDbPlatform() == CentralRepoPlatforms.SQLITE) { + errorMessage = Bundle.EamDbSettingsDialog_okButton_createSQLiteDbError_message(); + } + JOptionPane.showMessageDialog(WindowManager.getDefault().getMainWindow(), + errorMessage, + Bundle.EamDbSettingsDialog_okButton_createDbError_title(), + JOptionPane.WARNING_MESSAGE); + } /** @@ -575,15 +583,20 @@ public class EamDbSettingsDialog extends JDialog { private void cbDatabaseTypeActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cbDatabaseTypeActionPerformed CentralRepoDbChoice selectedItem = (CentralRepoDbChoice) cbDatabaseType.getSelectedItem(); + changeDbSelection(selectedItem); + }//GEN-LAST:event_cbDatabaseTypeActionPerformed + + private void changeDbSelection(CentralRepoDbChoice selectedItem) { if (isDbChoiceSelectable(selectedItem)) { manager.setSelctedDbChoice(selectedItem); + cbDatabaseType.setSelectedItem(selectedItem); } else { cbDatabaseType.setSelectedItem(manager.getSelectedDbChoice()); } customizeComponents(); - }//GEN-LAST:event_cbDatabaseTypeActionPerformed + } private void updateFullDbPath() { dataBaseFileTextArea.setText(tfDatabasePath.getText() + File.separator + SqliteCentralRepoSettings.DEFAULT_DBNAME); diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java index 69079329cd..2d906d70f4 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java @@ -43,8 +43,8 @@ import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoDbUtil; import org.sleuthkit.autopsy.centralrepository.datamodel.PostgresCentralRepoSettings; import org.sleuthkit.autopsy.centralrepository.datamodel.SqliteCentralRepoSettings; import java.awt.Component; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; +import java.awt.HeadlessException; +import java.util.MissingResourceException; import java.util.logging.Level; /** @@ -53,7 +53,10 @@ import java.util.logging.Level; @SuppressWarnings("PMD.SingularField") // UI widgets cause lots of false positives public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel implements OptionsPanel { - private static interface OnSettingsChangeListener { + /** + * listener to handle when settings change and an instance of this class needs to be notified. + */ + private interface OnSettingsChangeListener { void onSettingsChange(); } @@ -83,7 +86,7 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i ingestJobEventListener = new IngestJobEventPropertyChangeListener(); // most recently created panel will receive update events - GlobalSettingsPanel.setSettingsChangeListener(() -> GlobalSettingsPanel.this.load()); + GlobalSettingsPanel.setSettingsChangeListener(() -> load()); initComponents(); customizeComponents(); addIngestJobEventsListener(); @@ -107,8 +110,18 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i updateDatabase(this); } - private static boolean invokeCrChoice(Component parent) { - EamDbSettingsDialog dialog = new EamDbSettingsDialog(); + /** + * invokes central repository database choice selection as well as input for necessary configuration + * @param parent the parent component for displaying dialogs + * @param initialSelection if non-null, the menu item will be set to this choice; if null, + * the currently selected db choice will be selected + * @return true if there was a change + */ + private static boolean invokeCrChoice(Component parent, CentralRepoDbChoice initialSelection) { + EamDbSettingsDialog dialog = (initialSelection != null) ? + new EamDbSettingsDialog(initialSelection) : + new EamDbSettingsDialog(); + if (dialog.wasConfigurationChanged()) { updateDatabase(parent); return true; @@ -128,8 +141,9 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i * @param muCurrentlySelected if multi user settings are currently enabled as of most recent change */ @NbBundle.Messages({ - "GlobalSettingsPanel.onMultiUserChange.enable.title=Enable Central Repository?", - "GlobalSettingsPanel.onMultiUserChange.enable.description=Do you want to enable Central Repository using these settings?", + "GlobalSettingsPanel.onMultiUserChange.enable.title=Use with Central Repository?", + "GlobalSettingsPanel.onMultiUserChange.enable.description=Do you want to update the Central Repository to use this PostgreSQL database?", + "GlobalSettingsPanel.onMultiUserChange.enable.description2=The Central Repository stores hash values and accounts from past cases.", "GlobalSettingsPanel.onMultiUserChange.disabledMu.title=Central Repository Change Necessary", "GlobalSettingsPanel.onMultiUserChange.disabledMu.description=Since mult-user cases have been disabled, 'PostgreSQL using multi-user settings' is no longer a valid option for Central Repository. Would you like to choose another Central Repository database?" }) @@ -139,48 +153,77 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i if (!muPreviouslySelected && muCurrentlySelected) { SwingUtilities.invokeLater(() -> { if (JOptionPane.YES_OPTION == JOptionPane.showConfirmDialog(parent, - NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.onMultiUserChange.enable.description"), + "" + + "
" + + "

" + NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.onMultiUserChange.enable.description") + "

" + + "

" + NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.onMultiUserChange.enable.description2") + "

" + + "
" + + "", NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.onMultiUserChange.enable.title"), JOptionPane.YES_NO_OPTION)) { // setup database for CR CentralRepoDbManager.saveDbChoice(CentralRepoDbChoice.POSTGRESQL_MULTIUSER); - HandleDbChange(parent); + handleDbChange(parent); } }); } // moving from selected to not selected && 'PostgreSQL using multi-user settings' is selected else if (muPreviouslySelected && !muCurrentlySelected && crMultiUser) { SwingUtilities.invokeLater(() -> { - if (JOptionPane.YES_OPTION == JOptionPane.showConfirmDialog(parent, - "" + - "
" + - "

" + NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.onMultiUserChange.disabledMu.description") + "

" + - "
" + - "", - NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.onMultiUserChange.disabledMu.title"), - JOptionPane.YES_NO_OPTION)) { - - // present user with central repository choice - invokeCrChoice(parent); - } - else { - // disable central repository - CentralRepoDbUtil.setUseCentralRepo(false); - CentralRepoDbManager.saveDbChoice(CentralRepoDbChoice.DISABLED); - } - GlobalSettingsPanel.onSettingsChange(); + askForCentralRepoDbChoice(parent); }); } // changing multi-user settings connection && 'PostgreSQL using multi-user settings' is selected else if (muPreviouslySelected && muCurrentlySelected && crMultiUser) { // test databse for CR change - HandleDbChange(parent); + handleDbChange(parent); } } + + + /** + * when a user must select a new database other than using database from multi user settings + * @param parent the parent component to use for displaying dialogs in reference + */ + private static void askForCentralRepoDbChoice(Component parent) { + // disable central repository until user makes choice + CentralRepoDbUtil.setUseCentralRepo(false); + CentralRepoDbManager.saveDbChoice(CentralRepoDbChoice.DISABLED); + + Object[] options = { + "Use SQLite", + "Configure PostgreSQL", + "Disable Central Repository" + }; + + int result = JOptionPane.showOptionDialog( + parent, + "" + + "
" + + "

" + NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.onMultiUserChange.disabledMu.description") + "

" + + "
" + + "", + NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.onMultiUserChange.disabledMu.title"), + JOptionPane.YES_NO_CANCEL_OPTION, + JOptionPane.PLAIN_MESSAGE, + null, + options, + options[0] + ); + + if (JOptionPane.YES_OPTION == result) { + invokeCrChoice(parent, CentralRepoDbChoice.SQLITE); + } + else if (JOptionPane.NO_OPTION == result) { + invokeCrChoice(parent, CentralRepoDbChoice.POSTGRESQL_CUSTOM); + } + + GlobalSettingsPanel.onSettingsChange(); + } - private static void HandleDbChange(Component parent) { + private static void handleDbChange(Component parent) { boolean successful = EamDbSettingsDialog.testStatusAndCreate(parent, new CentralRepoDbManager()); if (successful) { updateDatabase(parent); @@ -540,7 +583,7 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i private void bnDbConfigureActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnDbConfigureActionPerformed store(); - boolean changed = invokeCrChoice(this); + boolean changed = invokeCrChoice(this, null); if (changed) { load(); // reload db settings content and update buttons firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/MultiUserSettingsPanel.java b/Core/src/org/sleuthkit/autopsy/corecomponents/MultiUserSettingsPanel.java index 13cf9401d7..6f15ba1484 100644 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/MultiUserSettingsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/MultiUserSettingsPanel.java @@ -34,7 +34,6 @@ import org.sleuthkit.autopsy.coreutils.Logger; import java.awt.Cursor; import java.util.logging.Level; import javax.swing.ImageIcon; -import javax.swing.JOptionPane; import org.openide.util.ImageUtilities; import org.openide.util.Lookup; import org.sleuthkit.autopsy.core.UserPreferencesException; @@ -763,10 +762,7 @@ public final class MultiUserSettingsPanel extends javax.swing.JPanel { private static boolean areCaseDbConnectionEqual(CaseDbConnectionInfo a, CaseDbConnectionInfo b) { if (a == null || b == null) { - if (a == null && b == null) - return true; - else - return false; + return (a == null && b == null); } return diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractRegistry.java b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractRegistry.java index dbad25708c..0b119e00d0 100644 --- a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractRegistry.java +++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractRegistry.java @@ -67,6 +67,7 @@ import java.util.Set; import java.util.HashSet; import static java.util.Locale.US; import static java.util.TimeZone.getTimeZone; +import org.apache.commons.io.FilenameUtils; import org.openide.util.Lookup; import org.sleuthkit.autopsy.ingest.DataSourceIngestModuleProgress; import org.sleuthkit.autopsy.ingest.IngestModule.IngestModuleException; diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/RecentDocumentsByLnk.java b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/RecentDocumentsByLnk.java index 331bb76524..42e5d2ecb0 100644 --- a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/RecentDocumentsByLnk.java +++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/RecentDocumentsByLnk.java @@ -30,6 +30,7 @@ import java.util.logging.Level; import org.openide.util.NbBundle; import org.sleuthkit.autopsy.coreutils.Logger; import java.util.Collection; +import org.apache.commons.io.FilenameUtils; import org.openide.util.NbBundle.Messages; import org.sleuthkit.autopsy.coreutils.JLNK; import org.sleuthkit.autopsy.coreutils.JLnkParser; From 67dfdaa71654dc4531bc5ff674b98057a495f5e6 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Mon, 2 Mar 2020 15:11:27 -0500 Subject: [PATCH 017/100] updated based on codacy comments --- .../datamodel/CentralRepoDbManager.java | 6 +++--- .../datamodel/PostgresConnectionSettings.java | 13 +++++++++---- .../optionspanel/Bundle.properties-MERGED | 5 +++-- .../optionspanel/GlobalSettingsPanel.java | 2 -- .../autopsy/core/Bundle.properties-MERGED | 8 +++++++- .../corecomponents/Bundle.properties-MERGED | 6 +++--- .../corecomponents/MultiUserSettingsPanel.java | 5 +---- .../autopsy/coreutils/Bundle.properties-MERGED | 4 +++- .../filesearch/Bundle.properties-MERGED | 4 ++-- .../autopsy/ingest/Bundle.properties-MERGED | 2 +- .../Bundle.properties-MERGED | 8 ++++++-- .../modules/exif/Bundle.properties-MERGED | 4 +++- .../fileextmismatch/Bundle.properties-MERGED | 18 +++++++++--------- .../hashdatabase/Bundle.properties-MERGED | 10 ++++++++-- .../interestingitems/Bundle.properties-MERGED | 4 ++-- .../photoreccarver/Bundle.properties-MERGED | 2 +- .../modules/html/Bundle.properties-MERGED | 6 +++--- .../recentactivity/Bundle.properties-MERGED | 11 +++-------- .../netbeans/core/startup/Bundle.properties | 4 ++-- .../core/windows/view/ui/Bundle.properties | 6 +++--- 20 files changed, 72 insertions(+), 56 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java index 0b7011a8b4..07e024d431 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java @@ -288,12 +288,12 @@ public class CentralRepoDbManager { * @throws CentralRepoException if */ public boolean createDb() throws CentralRepoException { - boolean result = false; - boolean dbCreated = true; - CentralRepoDbConnectivityManager selectedDbSettings = getSelectedSettings(); if (selectedDbSettings == null) throw new CentralRepoException("Unable to derive connectivity manager from settings: " + selectedDbChoice); + + boolean result = false; + boolean dbCreated = true; if (!selectedDbSettings.verifyDatabaseExists()) { dbCreated = selectedDbSettings.createDatabase(); diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresConnectionSettings.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresConnectionSettings.java index 1a4b4ca0b2..1e1f2c4e66 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresConnectionSettings.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresConnectionSettings.java @@ -135,14 +135,19 @@ public class PostgresConnectionSettings { validateStr(password, "Invalid user password. Cannot be empty."); this.password = password; } - - - + @Override public int hashCode() { - int hash = 3; + int hash = 7; + hash = 43 * hash + Objects.hashCode(this.host); + hash = 43 * hash + this.port; + hash = 43 * hash + Objects.hashCode(this.dbName); + hash = 43 * hash + this.bulkThreshold; + hash = 43 * hash + Objects.hashCode(this.userName); + hash = 43 * hash + Objects.hashCode(this.password); return hash; } + @Override public boolean equals(Object obj) { diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/Bundle.properties-MERGED index 143347b06c..2c5910b85c 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/Bundle.properties-MERGED @@ -35,8 +35,9 @@ EamOptionsController.moduleErr=Error processing value changes. EamOptionsController.moduleErr.msg=Value change processing failed. GlobalSettingsPanel.onMultiUserChange.disabledMu.description=Since mult-user cases have been disabled, 'PostgreSQL using multi-user settings' is no longer a valid option for Central Repository. Would you like to choose another Central Repository database? GlobalSettingsPanel.onMultiUserChange.disabledMu.title=Central Repository Change Necessary -GlobalSettingsPanel.onMultiUserChange.enable.description=Do you want to enable Central Repository using these settings? -GlobalSettingsPanel.onMultiUserChange.enable.title=Enable Central Repository? +GlobalSettingsPanel.onMultiUserChange.enable.description=Do you want to update the Central Repository to use this PostgreSQL database? +GlobalSettingsPanel.onMultiUserChange.enable.description2=The Central Repository stores hash values and accounts from past cases. +GlobalSettingsPanel.onMultiUserChange.enable.title=Use with Central Repository? GlobalSettingsPanel.updateFailed.title=Central repository disabled GlobalSettingsPanel.validationErrMsg.ingestRunning=You cannot change settings while ingest is running. GlobalSettingsPanel.validationerrMsg.mustConfigure=Configure the database to enable this module. diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java index 2d906d70f4..92ca9e4d2f 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java @@ -43,8 +43,6 @@ import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoDbUtil; import org.sleuthkit.autopsy.centralrepository.datamodel.PostgresCentralRepoSettings; import org.sleuthkit.autopsy.centralrepository.datamodel.SqliteCentralRepoSettings; import java.awt.Component; -import java.awt.HeadlessException; -import java.util.MissingResourceException; import java.util.logging.Level; /** diff --git a/Core/src/org/sleuthkit/autopsy/core/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/core/Bundle.properties-MERGED index c84f1f1b86..0b16a9701f 100755 --- a/Core/src/org/sleuthkit/autopsy/core/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/core/Bundle.properties-MERGED @@ -3,7 +3,13 @@ Installer.closing.confirmationDialog.title=Ingest is Running # {0} - exception message Installer.closing.messageBox.caseCloseExceptionMessage=Error closing case: {0} OpenIDE-Module-Display-Category=Infrastructure -OpenIDE-Module-Long-Description=This is the core Autopsy module.\n\nThe module contains the core components needed for the bare application to run; the RCP platform, windowing GUI, sleuthkit bindings, datamodel / storage, explorer, result viewers, content viewers, ingest framework, reporting, and core tools, such as the file search.\n\nThe framework included in the module contains APIs for developing modules for ingest, viewers and reporting. The modules can be deployed as Plugins using the Autopsy plugin installer.\nThis module should not be uninstalled - without it, Autopsy will not run.\n\nFor more information, see http://www.sleuthkit.org/autopsy/ +OpenIDE-Module-Long-Description=\ + This is the core Autopsy module.\n\n\ + The module contains the core components needed for the bare application to run; the RCP platform, windowing GUI, sleuthkit bindings, datamodel / storage, explorer, result viewers, content viewers, ingest framework, reporting, and core tools, such as the file search.\n\n\ + The framework included in the module contains APIs for developing modules for ingest, viewers and reporting. \ + The modules can be deployed as Plugins using the Autopsy plugin installer.\n\ + This module should not be uninstalled - without it, Autopsy will not run.\n\n\ + For more information, see http://www.sleuthkit.org/autopsy/ OpenIDE-Module-Name=Autopsy-Core OpenIDE-Module-Short-Description=Autopsy Core Module org_sleuthkit_autopsy_core_update_center=http://sleuthkit.org/autopsy/updates.xml diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle.properties-MERGED index f252420726..9f363b7723 100755 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle.properties-MERGED @@ -63,9 +63,9 @@ DataContentViewerHex.totalPageLabel.text_1=100 DataContentViewerHex.pageLabel2.text=Page # Product Information panel -LBL_Description=
\n Product Version: {0} ({9})
Sleuth Kit Version: {7}
Netbeans RCP Build: {8}
Java: {1}; {2}
System: {3}; {4}; {5}
Userdir: {6}
+LBL_Description=
\n Product Version: {0} ({9})
Sleuth Kit Version: {7}
Netbeans RCP Build: {8}
Java: {1}; {2}
System: {3}; {4}; {5}
Userdir: {6}
Format_OperatingSystem_Value={0} version {1} running on {2} -LBL_Copyright=
Autopsy™ is a digital forensics platform based on The Sleuth Kit™ and other tools.
Copyright © 2003-2018.
+LBL_Copyright=
Autopsy™ is a digital forensics platform based on The Sleuth Kit™ and other tools.
Copyright © 2003-2018.
SortChooser.dialogTitle=Choose Sort Criteria ThumbnailViewChildren.progress.cancelling=(Cancelling) # {0} - file name @@ -95,7 +95,7 @@ DataResultViewerThumbnail.pageNextButton.text= DataResultViewerThumbnail.imagesLabel.text=Images: DataResultViewerThumbnail.imagesRangeLabel.text=- DataResultViewerThumbnail.pageNumLabel.text=- -DataResultViewerThumbnail.filePathLabel.text=\ +DataResultViewerThumbnail.filePathLabel.text=\ \ \ DataResultViewerThumbnail.goToPageLabel.text=Go to Page: DataResultViewerThumbnail.goToPageField.text= AdvancedConfigurationDialog.cancelButton.text=Cancel diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/MultiUserSettingsPanel.java b/Core/src/org/sleuthkit/autopsy/corecomponents/MultiUserSettingsPanel.java index 6f15ba1484..67ce973d3b 100644 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/MultiUserSettingsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/MultiUserSettingsPanel.java @@ -750,10 +750,7 @@ public final class MultiUserSettingsPanel extends javax.swing.JPanel { private static boolean arePropsEqual(Object a, Object b) { if (a == null || b == null) { - if (a == null && b == null) - return true; - else - return false; + return (a == null && b == null); } else { return a.equals(b); diff --git a/Core/src/org/sleuthkit/autopsy/coreutils/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/coreutils/Bundle.properties-MERGED index 18e279dd2c..a0d535f8e6 100755 --- a/Core/src/org/sleuthkit/autopsy/coreutils/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/coreutils/Bundle.properties-MERGED @@ -30,7 +30,9 @@ PlatformUtil.getProcVmUsed.sigarNotInit.msg=Cannot get virt mem used, sigar not PlatformUtil.getProcVmUsed.gen.msg=Cannot get virt mem used, {0} PlatformUtil.getJvmMemInfo.usageText=JVM heap usage: {0}, JVM non-heap usage: {1} PlatformUtil.getPhysicalMemInfo.usageText=Physical memory usage (max, total, free): {0}, {1}, {2} -PlatformUtil.getAllMemUsageInfo.usageText={0}\n{1}\nProcess Virtual Memory: {2} +PlatformUtil.getAllMemUsageInfo.usageText={0}\n\ +{1}\n\ +Process Virtual Memory: {2} # {0} - file name ReadImageTask.mesageText=Reading image: {0} StringExtract.illegalStateException.cannotInit.msg=Unicode table not properly initialized, cannot instantiate StringExtract diff --git a/Core/src/org/sleuthkit/autopsy/filesearch/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/filesearch/Bundle.properties-MERGED index c585d0edf5..0e732c1519 100755 --- a/Core/src/org/sleuthkit/autopsy/filesearch/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/filesearch/Bundle.properties-MERGED @@ -14,7 +14,7 @@ KnownStatusSearchPanel.knownCheckBox.text=Known Status: KnownStatusSearchPanel.knownBadOptionCheckBox.text=Notable KnownStatusSearchPanel.knownOptionCheckBox.text=Known (NSRL or other) KnownStatusSearchPanel.unknownOptionCheckBox.text=Unknown -DateSearchFilter.noneSelectedMsg.text=At least one date type must be selected! +DateSearchFilter.noneSelectedMsg.text=At least one date type must be selected\! DateSearchPanel.dateCheckBox.text=Date: DateSearchPanel.jLabel4.text=Timezone: DateSearchPanel.jLabel3.text=*The date format is mm/dd/yyyy @@ -57,7 +57,7 @@ FileSearchPanel.search.results.details=Large number of matches may impact perfor FileSearchPanel.search.exception.noFilterSelected.msg=At least one filter must be selected. FileSearchPanel.search.validationErr.msg=Validation Error: {0} FileSearchPanel.emptyWhereClause.text=Invalid options, nothing to show. -KnownStatusSearchFilter.noneSelectedMsg.text=At least one known status must be selected! +KnownStatusSearchFilter.noneSelectedMsg.text=At least one known status must be selected\! NameSearchFilter.emptyNameMsg.text=Must enter something for name search. SizeSearchPanel.sizeCompareComboBox.equalTo=equal to SizeSearchPanel.sizeCompareComboBox.greaterThan=greater than diff --git a/Core/src/org/sleuthkit/autopsy/ingest/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/ingest/Bundle.properties-MERGED index 6be3e48e71..9e4f612b6b 100755 --- a/Core/src/org/sleuthkit/autopsy/ingest/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/ingest/Bundle.properties-MERGED @@ -140,7 +140,7 @@ IngestJob.cancelReason.outOfDiskSpace.text=Out of disk space IngestJob.cancelReason.servicesDown.text=Services Down IngestJob.cancelReason.caseClosed.text=Case closed IngestJobSettingsPanel.globalSettingsButton.text=Global Settings -gest= +gest IngestJobSettingsPanel.globalSettingsButton.actionCommand=Advanced IngestJobSettingsPanel.globalSettingsButton.text=Global Settings IngestJobSettingsPanel.pastJobsButton.text=History diff --git a/Core/src/org/sleuthkit/autopsy/modules/embeddedfileextractor/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/modules/embeddedfileextractor/Bundle.properties-MERGED index 4729293fb9..4585d86449 100755 --- a/Core/src/org/sleuthkit/autopsy/modules/embeddedfileextractor/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/modules/embeddedfileextractor/Bundle.properties-MERGED @@ -11,7 +11,12 @@ ExtractArchiveWithPasswordAction.progress.text=Unpacking contents of archive: {0 ExtractArchiveWithPasswordAction.prompt.text=Enter Password ExtractArchiveWithPasswordAction.prompt.title=Enter Password OpenIDE-Module-Display-Category=Ingest Module -OpenIDE-Module-Long-Description=Embedded File Extraction Ingest Module\n\nThe Embedded File Extraction Ingest Module processes document files (such as doc, docx, ppt, pptx, xls, xlsx) and archive files (such as zip and others archive types supported by the 7zip extractor).\nContents of these files are extracted and the derived files are added back to the current ingest to be processed by the configured ingest modules.\nIf the derived file happens to be an archive file, it will be re-processed by the 7zip extractor - the extractor will process archive files N-levels deep.\n\nThe extracted files are navigable in the directory tree.\n\nThe module is supported on Windows, Linux and Mac operating systems. +OpenIDE-Module-Long-Description=\ + Embedded File Extraction Ingest Module\n\nThe Embedded File Extraction Ingest Module processes document files (such as doc, docx, ppt, pptx, xls, xlsx) and archive files (such as zip and others archive types supported by the 7zip extractor).\n\ + Contents of these files are extracted and the derived files are added back to the current ingest to be processed by the configured ingest modules.\n\ + If the derived file happens to be an archive file, it will be re-processed by the 7zip extractor - the extractor will process archive files N-levels deep.\n\n\ + The extracted files are navigable in the directory tree.\n\n\ + The module is supported on Windows, Linux and Mac operating systems. OpenIDE-Module-Name=Embedded File Extraction OpenIDE-Module-Short-Description=Embedded File Extraction Ingest Module EmbeddedFileExtractorIngestModule.SevenZipContentReadStream.seek.exception.invalidOrigin=Invalid seek origin: {0} @@ -23,7 +28,6 @@ EmbeddedFileExtractorIngestModule.ArchiveExtractor.isZipBombCheck.warnMsg=Possib EmbeddedFileExtractorIngestModule.ArchiveExtractor.isZipBombCheck.warnDetails=Compression ratio is {0}, skipping items in {1}. EmbeddedFileExtractorIngestModule.ArchiveExtractor.unpack.warnMsg.zipBomb=Possible ZIP bomb detected: {0} EmbeddedFileExtractorIngestModule.ArchiveExtractor.unpack.warnDetails.zipBomb=The archive is {0} levels deep, skipping processing of {1} -EmbeddedFileExtractorIngestModule.ArchiveExtractor.unpack.unknownPath.msg=Unknown item path in archive: {0}, will use: {1} EmbeddedFileExtractorIngestModule.ArchiveExtractor.unpack.notEnoughDiskSpace.msg=Not enough disk space to unpack archive item: {0}, {1} EmbeddedFileExtractorIngestModule.ArchiveExtractor.unpack.notEnoughDiskSpace.details=The archive item is too large to unpack, skipping unpacking this item. EmbeddedFileExtractorIngestModule.ArchiveExtractor.unpack.errUnpacking.msg=Error unpacking {0} diff --git a/Core/src/org/sleuthkit/autopsy/modules/exif/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/modules/exif/Bundle.properties-MERGED index 4915d5a124..f9a5a88b1b 100755 --- a/Core/src/org/sleuthkit/autopsy/modules/exif/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/modules/exif/Bundle.properties-MERGED @@ -2,7 +2,9 @@ CannotRunFileTypeDetection=Cannot run file type detection. ExifParserFileIngestModule.indexError.message=Failed to post EXIF Metadata artifact(s). ExifParserFileIngestModule.userContent.description=EXIF metadata exists for this file. OpenIDE-Module-Display-Category=Ingest Module -OpenIDE-Module-Long-Description=Exif metadata ingest module. \n\nThe ingest module analyzes image files, extracts Exif information and posts the Exif data as results. +OpenIDE-Module-Long-Description=\ + Exif metadata ingest module. \n\n\ + The ingest module analyzes image files, extracts Exif information and posts the Exif data as results. OpenIDE-Module-Name=ExifParser OpenIDE-Module-Short-Description=Exif metadata ingest module ExifParserFileIngestModule.moduleName.text=Exif Parser diff --git a/Core/src/org/sleuthkit/autopsy/modules/fileextmismatch/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/modules/fileextmismatch/Bundle.properties-MERGED index 5063bd55fa..cfaadf1635 100755 --- a/Core/src/org/sleuthkit/autopsy/modules/fileextmismatch/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/modules/fileextmismatch/Bundle.properties-MERGED @@ -36,27 +36,27 @@ FileExtMismatchSettingsPanel.jLabel1.text=File Types: FileExtMismatchSettingsPanel.newExtButton.text=New Extension FileExtMismatchSettingsPanel.newMimePrompt.message=Add a new MIME file type: FileExtMismatchSettingsPanel.newMimePrompt.title=New MIME -FileExtMismatchSettingsPanel.newMimePrompt.emptyMime.message=MIME type text is empty! +FileExtMismatchSettingsPanel.newMimePrompt.emptyMime.message=MIME type text is empty\! FileExtMismatchSettingsPanel.newMimePrompt.emptyMime.title=Empty type -FileExtMismatchSettingsPanel.newMimePrompt.mimeTypeNotSupported.message=MIME type not supported! +FileExtMismatchSettingsPanel.newMimePrompt.mimeTypeNotSupported.message=MIME type not supported\! FileExtMismatchSettingsPanel.newMimePrompt.mimeTypeNotSupported.title=Type not supported -FileExtMismatchSettingsPanel.newMimePrompt.mimeTypeExists.message=MIME type already exists! +FileExtMismatchSettingsPanel.newMimePrompt.mimeTypeExists.message=MIME type already exists\! FileExtMismatchSettingsPanel.newMimePrompt.mimeTypeExists.title=Type already exists FileExtMismatchSettingsPanel.newMimePrompt.mimeTypeNotDetectable.message=MIME type is not detectable by this module. FileExtMismatchSettingsPanel.newMimePrompt.mimeTypeNotDetectable.title=Type not detectable -FileExtMismatchSettingsPanel.removeTypeButton.noneSelected.message=No MIME type selected! +FileExtMismatchSettingsPanel.removeTypeButton.noneSelected.message=No MIME type selected\! FileExtMismatchSettingsPanel.removeTypeButton.noneSelected.title=No type selected FileExtMismatchSettingsPanel.newExtPrompt.message=Add an allowed extension: FileExtMismatchSettingsPanel.newExtPrompt.title=New allowed extension -FileExtMismatchSettingsPanel.newExtPrompt.empty.message=Extension text is empty! +FileExtMismatchSettingsPanel.newExtPrompt.empty.message=Extension text is empty\! FileExtMismatchSettingsPanel.newExtPrompt.empty.title=Extension text empty -FileExtMismatchSettingsPanel.newExtPrompt.noMimeType.message=No MIME type selected! +FileExtMismatchSettingsPanel.newExtPrompt.noMimeType.message=No MIME type selected\! FileExtMismatchSettingsPanel.newExtPrompt.noMimeType.title=No MIME type selected -FileExtMismatchSettingsPanel.newExtPrompt.extExists.message=Extension already exists! +FileExtMismatchSettingsPanel.newExtPrompt.extExists.message=Extension already exists\! FileExtMismatchSettingsPanel.newExtPrompt.extExists.title=Extension already exists -FileExtMismatchSettingsPanel.removeExtButton.noneSelected.message=No extension selected! +FileExtMismatchSettingsPanel.removeExtButton.noneSelected.message=No extension selected\! FileExtMismatchSettingsPanel.removeExtButton.noneSelected.title=No extension selected -FileExtMismatchSettingsPanel.removeExtButton.noMimeTypeSelected.message=No MIME type selected! +FileExtMismatchSettingsPanel.removeExtButton.noMimeTypeSelected.message=No MIME type selected\! FileExtMismatchSettingsPanel.removeExtButton.noMimeTypeSelected.title=No MIME type selected FileExtMismatchSettingsPanel.removeTypeButton.toolTipText= FileExtMismatchModuleSettingsPanel.checkAllRadioButton.text=Check all file types diff --git a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/Bundle.properties-MERGED index 44057d0016..0b470ce6b1 100755 --- a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/Bundle.properties-MERGED @@ -49,7 +49,10 @@ ImportCentralRepoDbProgressDialog.errorParsingFile.message=Error parsing hash se ImportCentralRepoDbProgressDialog.linesProcessed.message=\ hashes processed ImportCentralRepoDbProgressDialog.title.text=Central Repository Import Progress OpenIDE-Module-Display-Category=Ingest Module -OpenIDE-Module-Long-Description=Hash Set ingest module. \n\nThe ingest module analyzes files in the disk image and marks them as "known" (based on NSRL hashset lookup for "known" files) and "bad / interesting" (based on one or more hash sets supplied by the user).\n\nThe module also contains additional non-ingest tools that are integrated in the GUI, such as file lookup by hash and hash set configuration. +OpenIDE-Module-Long-Description=\ + Hash Set ingest module. \n\n\ + The ingest module analyzes files in the disk image and marks them as "known" (based on NSRL hashset lookup for "known" files) and "bad / interesting" (based on one or more hash sets supplied by the user).\n\n\ + The module also contains additional non-ingest tools that are integrated in the GUI, such as file lookup by hash and hash set configuration. OpenIDE-Module-Name=HashDatabases OptionsCategory_Name_HashDatabase=Hash Sets OptionsCategory_Keywords_HashDatabase=Hash Sets @@ -178,7 +181,10 @@ HashDbSearchThread.name.searching=Searching HashDbSearchThread.noMoreFilesWithMD5Msg=No other files with the same MD5 hash were found. ModalNoButtons.indexingDbsTitle=Indexing hash sets ModalNoButtons.indexingDbTitle=Indexing hash set -ModalNoButtons.exitHashDbIndexingMsg=You are about to exit out of indexing your hash sets. \nThe generated index will be left unusable. If you choose to continue,\nplease delete the corresponding -md5.idx file in the hash folder.\nExit indexing? +ModalNoButtons.exitHashDbIndexingMsg=You are about to exit out of indexing your hash sets. \n\ +The generated index will be left unusable. If you choose to continue,\n\ + please delete the corresponding -md5.idx file in the hash folder.\n\ + Exit indexing? ModalNoButtons.dlgTitle.unfinishedIndexing=Unfinished Indexing ModalNoButtons.indexThis.currentlyIndexing1Db=Currently indexing 1 hash set ModalNoButtons.indexThese.currentlyIndexing1OfNDbs=Currently indexing 1 of {0} diff --git a/Core/src/org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties-MERGED index 31a0690b82..1279d3642b 100755 --- a/Core/src/org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties-MERGED @@ -83,8 +83,8 @@ FilesSetRulePanel.nameTextField.text= FilesSetRulePanel.ruleNameLabel.text=Rule Name (Optional): FilesSetRulePanel.messages.emptyNameCondition=You must specify a name pattern for this rule. FilesSetRulePanel.messages.invalidNameRegex=The name regular expression is not valid:\n\n{0} -FilesSetRulePanel.messages.invalidCharInName=The name cannot contain \\, /, :, *, ?, ", <, or > unless it is a regular expression. -FilesSetRulePanel.messages.invalidCharInPath=The path cannot contain \\, :, *, ?, ", <, or > unless it is a regular expression. +FilesSetRulePanel.messages.invalidCharInName=The name cannot contain \\, /, :, *, ?, \", <, or > unless it is a regular expression. +FilesSetRulePanel.messages.invalidCharInPath=The path cannot contain \\, :, *, ?, \", <, or > unless it is a regular expression. FilesSetRulePanel.messages.invalidPathRegex=The path regular expression is not valid:\n\n{0} FilesSetDefsPanel.doFileSetsDialog.duplicateRuleSet.text=Rule set with name {0} already exists. FilesSetRulePanel.pathSeparatorInfoLabel.text=Folder must be in parent path. Use '/' to give consecutive names diff --git a/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/Bundle.properties-MERGED index 2dc971a40d..87dacfc16c 100755 --- a/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/Bundle.properties-MERGED @@ -21,7 +21,7 @@ PhotoRecIngestModule.complete.totalParsetime=Total Parsing Time: PhotoRecIngestModule.complete.photoRecResults=PhotoRec Results PhotoRecIngestModule.NotEnoughDiskSpace.detail.msg=PhotoRec error processing {0} with {1} Not enough space on primary disk to save unallocated space. PhotoRecIngestModule.cancelledByUser=PhotoRec cancelled by user. -PhotoRecIngestModule.error.exitValue=PhotoRec carver returned error exit value = {0} when scanning {1} +PhotoRecIngestModule.error.exitValue=PhotoRec carver returned error exit value \= {0} when scanning {1} PhotoRecIngestModule.error.msg=Error processing {0} with PhotoRec carver. PhotoRecIngestModule.complete.numberOfErrors=Number of Errors while Carving: PhotoRecCarverIngestJobSettingsPanel.detectionSettingsLabel.text=PhotoRec Settings diff --git a/Core/src/org/sleuthkit/autopsy/report/modules/html/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/report/modules/html/Bundle.properties-MERGED index 0be7595111..32f6867f0c 100755 --- a/Core/src/org/sleuthkit/autopsy/report/modules/html/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/report/modules/html/Bundle.properties-MERGED @@ -5,8 +5,8 @@ ReportHTML.getName.text=HTML Report ReportHTML.getDesc.text=A report about results and tagged items in HTML format. ReportHTML.writeIndex.title=for case {0} ReportHTML.writeIndex.noFrames.msg=Your browser is not compatible with our frame setup. -ReportHTML.writeIndex.noFrames.seeNav=Please see the navigation page for artifact links, -ReportHTML.writeIndex.seeSum=and the summary page for a case summary. +ReportHTML.writeIndex.noFrames.seeNav=Please see the navigation page for artifact links, +ReportHTML.writeIndex.seeSum=and the summary page for a case summary. ReportHTML.writeNav.title=Report Navigation ReportHTML.writeNav.h1=Report Navigation ReportHTML.writeNav.summary=Case Summary @@ -16,7 +16,7 @@ ReportHTML.writeSum.caseNumber=Case Number: ReportHTML.writeSum.caseNumImages=Number of Images: ReportHTML.writeSum.examiner=Examiner: ReportHTML.writeSum.title=Case Summary -ReportHTML.writeSum.warningMsg=Warning, this report was run before ingest services completed! +ReportHTML.writeSum.warningMsg=Warning, this report was run before ingest services completed\! # # autopsy/test/scripts/regression.py._html_report_diff() uses reportGenOn.text, caseName, caseNum, # examiner as a regex signature to skip report.html and summary.html diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Bundle.properties-MERGED b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Bundle.properties-MERGED index 18deff87f4..ebdce8a327 100755 --- a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Bundle.properties-MERGED +++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Bundle.properties-MERGED @@ -1,7 +1,6 @@ cannotBuildXmlParser=Unable to build XML parser: cannotLoadSEUQA=Unable to load Search Engine URL Query Analyzer settings file, SEUQAMappings.xml: cannotParseXml=Unable to parse XML file: -Chrome.getBookmark.errMsg.errAnalyzeFile={0}: Error while trying to analyze file: {1} ChromeCacheExtract_adding_artifacts_msg=Chrome Cache: Adding %d artifacts for analysis. ChromeCacheExtract_adding_extracted_files_msg=Chrome Cache: Adding %d extracted files for analysis. ChromeCacheExtract_loading_files_msg=Chrome Cache: Loading files from %s. @@ -14,9 +13,9 @@ ChromeCacheExtractor.progressMsg={0}: Extracting cache entry {1} of {2} entries DataSourceUsage_AndroidMedia=Android Media Card DataSourceUsage_DJU_Drone_DAT=DJI Internal SD Card DataSourceUsage_FlashDrive=Flash Drive +# {0} - OS name DataSourceUsageAnalyzer.customVolume.label=OS Drive ({0}) DataSourceUsageAnalyzer.parentModuleName=Recent Activity -Extract.dbConn.errMsg.failedToQueryDb={0}: Failed to query database. Extract.indexError.message=Failed to index artifact for keyword search. Extract.noOpenCase.errMsg=No open case available. ExtractEdge_getHistory_containerFileNotFound=Error while trying to analyze Edge history @@ -25,11 +24,6 @@ ExtractEdge_process_errMsg_errGettingWebCacheFiles=Error trying to retrieving Ed ExtractEdge_process_errMsg_spartanFail=Failure processing Microsoft Edge spartan.edb file ExtractEdge_process_errMsg_unableFindESEViewer=Unable to find ESEDatabaseViewer ExtractEdge_process_errMsg_webcacheFail=Failure processing Microsoft Edge WebCacheV01.dat file -ExtractIE.getBookmark.ere.noSpace=RecentActivity -ExtractIE.getBookmark.errMsg.errPostingBookmarks=Error posting Internet Explorer Bookmark artifacts. -ExtractIE.getCookie.errMsg.errPostingCookies=Error posting Internet Explorer Cookie artifacts. -ExtractIE.getHistory.errMsg.errPostingHistory=Error posting Internet Explorer History artifacts. -Extractor.errPostingArtifacts=Error posting {0} artifacts to the blackboard. ExtractOs.androidOs.label=Android ExtractOs.androidVolume.label=OS Drive (Android) ExtractOs.debianLinuxOs.label=Linux (Debian) @@ -96,7 +90,7 @@ Chrome.getLogin.errMsg.errAnalyzingFiles={0}: Error while trying to analyze file Chrome.getAutofill.errMsg.errGettingFiles=Error when trying to get Chrome Web Data files. Chrome.getAutofill.errMsg.errAnalyzingFiles={0}: Error while trying to analyze file:{1} ExtractIE.moduleName.text=Internet Explorer -ExtractIE.getBookmark.errMsg.errGettingBookmarks=Error getting Internet Explorer Bookmarks. +ExtractIE.getBookmark.errMsg.errGettingBookmarks={0}: Error getting Internet Explorer Bookmarks. ExtractIE.parentModuleName.noSpace=RecentActivity ExtractIE.parentModuleName=Recent Activity ExtractIE.getURLFromIEBmkFile.errMsg={0}: Error parsing IE bookmark File {1} @@ -198,6 +192,7 @@ RecentDocumentsByLnk.parentModuleName.noSpace=RecentActivity RecentDocumentsByLnk.parentModuleName=Recent Activity RegRipperFullNotFound=Full version RegRipper executable not found. RegRipperNotFound=Autopsy RegRipper executable not found. +# {0} - file name SearchEngineURLQueryAnalyzer.init.exception.msg=Unable to find {0}. SearchEngineURLQueryAnalyzer.moduleName.text=Search Engine SearchEngineURLQueryAnalyzer.engineName.none=NONE 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 b20ccf5912..7d080bac65 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 -#Tue, 12 Nov 2019 17:21:46 -0500 +#Mon, 02 Mar 2020 15:07:07 -0500 LBL_splash_window_title=Starting Autopsy SPLASH_HEIGHT=314 SPLASH_WIDTH=538 @@ -8,4 +8,4 @@ SplashRunningTextBounds=0,289,538,18 SplashRunningTextColor=0x0 SplashRunningTextFontSize=19 -currentVersion=Autopsy 4.13.0 +currentVersion=Autopsy 4.14.0 diff --git a/branding/modules/org-netbeans-core-windows.jar/org/netbeans/core/windows/view/ui/Bundle.properties b/branding/modules/org-netbeans-core-windows.jar/org/netbeans/core/windows/view/ui/Bundle.properties index 998d3f715c..206dd6db16 100644 --- a/branding/modules/org-netbeans-core-windows.jar/org/netbeans/core/windows/view/ui/Bundle.properties +++ b/branding/modules/org-netbeans-core-windows.jar/org/netbeans/core/windows/view/ui/Bundle.properties @@ -1,4 +1,4 @@ #Updated by build script -#Tue, 12 Nov 2019 17:21:46 -0500 -CTL_MainWindow_Title=Autopsy 4.13.0 -CTL_MainWindow_Title_No_Project=Autopsy 4.13.0 +#Mon, 02 Mar 2020 15:07:07 -0500 +CTL_MainWindow_Title=Autopsy 4.14.0 +CTL_MainWindow_Title_No_Project=Autopsy 4.14.0 From 7a7fa90945d1f8716e488b0c30f61641f8ef2a68 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Tue, 3 Mar 2020 11:40:00 -0500 Subject: [PATCH 018/100] fixes to address comments in central repo and multi user coordination --- .../datamodel/CentralRepoDbChoice.java | 2 +- .../optionspanel/GlobalSettingsPanel.form | 4 ++-- .../optionspanel/GlobalSettingsPanel.java | 16 ++++++++++------ 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbChoice.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbChoice.java index 7670580708..92f0af775b 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbChoice.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbChoice.java @@ -24,7 +24,7 @@ package org.sleuthkit.autopsy.centralrepository.datamodel; public class CentralRepoDbChoice { public static final CentralRepoDbChoice DISABLED = new CentralRepoDbChoice("Disabled", CentralRepoPlatforms.DISABLED); - public static final CentralRepoDbChoice SQLITE = new CentralRepoDbChoice("Sqlite", CentralRepoPlatforms.SQLITE); + public static final CentralRepoDbChoice SQLITE = new CentralRepoDbChoice("Sqlite", "SQLite", CentralRepoPlatforms.SQLITE); public static final CentralRepoDbChoice POSTGRESQL_MULTIUSER = new CentralRepoDbChoice("PostgreSQL_Multiuser", "PostgreSQL using multi-user settings", CentralRepoPlatforms.POSTGRESQL); diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.form b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.form index 13ba7876cd..99594871b0 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.form +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.form @@ -61,7 +61,7 @@ - + @@ -258,7 +258,7 @@ - + diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java index 92ca9e4d2f..44da0c3b31 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java @@ -141,9 +141,7 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i @NbBundle.Messages({ "GlobalSettingsPanel.onMultiUserChange.enable.title=Use with Central Repository?", "GlobalSettingsPanel.onMultiUserChange.enable.description=Do you want to update the Central Repository to use this PostgreSQL database?", - "GlobalSettingsPanel.onMultiUserChange.enable.description2=The Central Repository stores hash values and accounts from past cases.", - "GlobalSettingsPanel.onMultiUserChange.disabledMu.title=Central Repository Change Necessary", - "GlobalSettingsPanel.onMultiUserChange.disabledMu.description=Since mult-user cases have been disabled, 'PostgreSQL using multi-user settings' is no longer a valid option for Central Repository. Would you like to choose another Central Repository database?" + "GlobalSettingsPanel.onMultiUserChange.enable.description2=The Central Repository stores hash values and accounts from past cases." }) public static void onMultiUserChange(Component parent, boolean muPreviouslySelected, boolean muCurrentlySelected) { boolean crMultiUser = CentralRepoDbManager.getSavedDbChoice() == CentralRepoDbChoice.POSTGRESQL_MULTIUSER; @@ -184,6 +182,11 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i * when a user must select a new database other than using database from multi user settings * @param parent the parent component to use for displaying dialogs in reference */ + @NbBundle.Messages({ + "GlobalSettingsPanel.onMultiUserChange.disabledMu.title=Central Repository Change Necessary", + "GlobalSettingsPanel.onMultiUserChange.disabledMu.description=The Central Repository will be reconfigured to use a local SQLite database.", + "GlobalSettingsPanel.onMultiUserChange.disabledMu.description2=Press Configure PostgreSQL to change to a PostgreSQL database." + }) private static void askForCentralRepoDbChoice(Component parent) { // disable central repository until user makes choice CentralRepoDbUtil.setUseCentralRepo(false); @@ -198,10 +201,11 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i int result = JOptionPane.showOptionDialog( parent, "" + - "
" + + "
" + "

" + NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.onMultiUserChange.disabledMu.description") + "

" + - "
" + - "", + "

" + NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.onMultiUserChange.disabledMu.description2") + "

" + + "
" + + "", NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.onMultiUserChange.disabledMu.title"), JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE, From 1103ed53bdd155014e34288f54f3d036e910f170 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Tue, 3 Mar 2020 15:47:41 -0500 Subject: [PATCH 019/100] updates in ui --- .../optionspanel/Bundle.properties-MERGED | 3 +- .../optionspanel/GlobalSettingsPanel.java | 29 +++++++++++-------- .../autopsy/core/UserPreferences.java | 3 +- .../datamodel/AbstractAbstractFileNode.java | 4 +-- 4 files changed, 23 insertions(+), 16 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/Bundle.properties-MERGED index 2c5910b85c..b4a3b7ed03 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/Bundle.properties-MERGED @@ -33,7 +33,8 @@ EamDbSettingsDialog.validation.finished=Click OK to save your database settings EamDbSettingsDialog.validation.incompleteFields=Fill in all values for the selected database. EamOptionsController.moduleErr=Error processing value changes. EamOptionsController.moduleErr.msg=Value change processing failed. -GlobalSettingsPanel.onMultiUserChange.disabledMu.description=Since mult-user cases have been disabled, 'PostgreSQL using multi-user settings' is no longer a valid option for Central Repository. Would you like to choose another Central Repository database? +GlobalSettingsPanel.onMultiUserChange.disabledMu.description=The Central Repository will be reconfigured to use a local SQLite database. +GlobalSettingsPanel.onMultiUserChange.disabledMu.description2=Press Configure PostgreSQL to change to a PostgreSQL database. GlobalSettingsPanel.onMultiUserChange.disabledMu.title=Central Repository Change Necessary GlobalSettingsPanel.onMultiUserChange.enable.description=Do you want to update the Central Repository to use this PostgreSQL database? GlobalSettingsPanel.onMultiUserChange.enable.description2=The Central Repository stores hash values and accounts from past cases. diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java index 44da0c3b31..0becdf59f8 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java @@ -84,7 +84,7 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i ingestJobEventListener = new IngestJobEventPropertyChangeListener(); // most recently created panel will receive update events - GlobalSettingsPanel.setSettingsChangeListener(() -> load()); + GlobalSettingsPanel.setSettingsChangeListener(() -> ingestStateUpdated(Case.isCaseOpen())); initComponents(); customizeComponents(); addIngestJobEventsListener(); @@ -144,7 +144,8 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i "GlobalSettingsPanel.onMultiUserChange.enable.description2=The Central Repository stores hash values and accounts from past cases." }) public static void onMultiUserChange(Component parent, boolean muPreviouslySelected, boolean muCurrentlySelected) { - boolean crMultiUser = CentralRepoDbManager.getSavedDbChoice() == CentralRepoDbChoice.POSTGRESQL_MULTIUSER; + boolean crMultiUser = CentralRepoDbUtil.allowUseOfCentralRepository() && + CentralRepoDbManager.getSavedDbChoice() == CentralRepoDbChoice.POSTGRESQL_MULTIUSER; if (!muPreviouslySelected && muCurrentlySelected) { SwingUtilities.invokeLater(() -> { @@ -159,6 +160,7 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i JOptionPane.YES_NO_OPTION)) { // setup database for CR + CentralRepoDbUtil.setUseCentralRepo(true); CentralRepoDbManager.saveDbChoice(CentralRepoDbChoice.POSTGRESQL_MULTIUSER); handleDbChange(parent); } @@ -226,16 +228,19 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i private static void handleDbChange(Component parent) { - boolean successful = EamDbSettingsDialog.testStatusAndCreate(parent, new CentralRepoDbManager()); - if (successful) { - updateDatabase(parent); - onSettingsChange(); - } - else { - // disable central repository - CentralRepoDbUtil.setUseCentralRepo(false); - CentralRepoDbManager.saveDbChoice(CentralRepoDbChoice.DISABLED); - } + SwingUtilities.invokeLater(() -> { + boolean successful = EamDbSettingsDialog.testStatusAndCreate(parent, new CentralRepoDbManager()); + if (successful) { + updateDatabase(parent); + onSettingsChange(); + } + else { + // disable central repository + CentralRepoDbUtil.setUseCentralRepo(false); + CentralRepoDbManager.saveDbChoice(CentralRepoDbChoice.DISABLED); + GlobalSettingsPanel.onSettingsChange(); + } + }); } diff --git a/Core/src/org/sleuthkit/autopsy/core/UserPreferences.java b/Core/src/org/sleuthkit/autopsy/core/UserPreferences.java index 409e27f080..116f212dd9 100644 --- a/Core/src/org/sleuthkit/autopsy/core/UserPreferences.java +++ b/Core/src/org/sleuthkit/autopsy/core/UserPreferences.java @@ -75,6 +75,7 @@ public final class UserPreferences { public static final String SHOW_ONLY_CURRENT_USER_TAGS = "ShowOnlyCurrentUserTags"; public static final String HIDE_SCO_COLUMNS = "HideCentralRepoCommentsAndOccurrences"; //The key for this setting pre-dates the settings current functionality //NON-NLS public static final String DISPLAY_TRANSLATED_NAMES = "DisplayTranslatedNames"; + private static final boolean DISPLAY_TRANSLATED_NAMES_DEFAULT = true; public static final String EXTERNAL_HEX_EDITOR_PATH = "ExternalHexEditorPath"; public static final String SOLR_MAX_JVM_SIZE = "SolrMaxJVMSize"; public static final String RESULTS_TABLE_PAGE_SIZE = "ResultsTablePageSize"; @@ -265,7 +266,7 @@ public final class UserPreferences { } public static boolean displayTranslatedFileNames() { - return preferences.getBoolean(DISPLAY_TRANSLATED_NAMES, false); + return preferences.getBoolean(DISPLAY_TRANSLATED_NAMES, DISPLAY_TRANSLATED_NAMES_DEFAULT); } /** diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java index a60964aa19..1d53e46ca6 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java @@ -105,7 +105,7 @@ public abstract class AbstractAbstractFileNode extends A this.content.getName(), this.content.getId()), ex); } - if (UserPreferences.displayTranslatedFileNames()) { + if (TextTranslationService.getInstance().hasProvider() && UserPreferences.displayTranslatedFileNames()) { backgroundTasksPool.submit(new TranslationTask( new WeakReference<>(this), weakPcl)); } @@ -331,7 +331,7 @@ public abstract class AbstractAbstractFileNode extends A * background task that promises to update these values. */ - if (UserPreferences.displayTranslatedFileNames()) { + if (TextTranslationService.getInstance().hasProvider() && UserPreferences.displayTranslatedFileNames()) { properties.add(new NodeProperty<>(ORIGINAL_NAME.toString(), ORIGINAL_NAME.toString(), NO_DESCR, "")); } From b3347aa58a0617183a17f8cf626ed22b4a29d3cc Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Thu, 5 Mar 2020 07:42:28 -0500 Subject: [PATCH 020/100] updated merged property files --- .../datamodel/Bundle.properties-MERGED | 3 +-- .../eventlisteners/Bundle.properties-MERGED | 3 --- .../optionspanel/Bundle.properties-MERGED | 6 ------ .../autopsy/core/Bundle.properties-MERGED | 8 +------- .../corecomponents/Bundle.properties-MERGED | 6 +++--- .../autopsy/coreutils/Bundle.properties-MERGED | 4 +--- .../filesearch/Bundle.properties-MERGED | 4 ++-- .../autopsy/ingest/Bundle.properties-MERGED | 2 +- .../Bundle.properties-MERGED | 8 ++------ .../modules/exif/Bundle.properties-MERGED | 4 +--- .../fileextmismatch/Bundle.properties-MERGED | 18 +++++++++--------- .../hashdatabase/Bundle.properties-MERGED | 10 ++-------- .../interestingitems/Bundle.properties-MERGED | 4 ++-- .../photoreccarver/Bundle.properties-MERGED | 2 +- .../modules/html/Bundle.properties-MERGED | 6 +++--- .../recentactivity/Bundle.properties-MERGED | 11 ++++++++--- .../netbeans/core/startup/Bundle.properties | 4 ++-- .../core/windows/view/ui/Bundle.properties | 6 +++--- 18 files changed, 42 insertions(+), 67 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/Bundle.properties-MERGED index 345d5a420e..9b43833ee2 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/Bundle.properties-MERGED @@ -7,10 +7,8 @@ AbstractSqlEamDb.cannotUpgrage.message=Currently selected database platform "{0} AbstractSqlEamDb.failedToReadMajorVersion.message=Failed to read schema version for Central Repository. AbstractSqlEamDb.failedToReadMinorVersion.message=Failed to read schema minor version for Central Repository. AbstractSqlEamDb.upgradeSchema.incompatible=The selected Central Repository is not compatible with the current version of the application, please upgrade the application if you wish to use this Central Repository. -CentralRepoDbManager.connectionErrorMsg.text=Failed to connect to central repository database. CorrelationAttributeInstance.invalidName.message=Invalid database table name. Name must start with a lowercase letter and can only contain lowercase letters, numbers, and '_'. CorrelationAttributeInstance.nullName.message=Database name is null. -CorrelationAttributeUtil.emailaddresses.text=Email Addresses CorrelationType.DOMAIN.displayName=Domains CorrelationType.EMAIL.displayName=Email Addresses CorrelationType.FILES.displayName=Files @@ -25,6 +23,7 @@ DataSourceUpdateService.serviceName.text=Update Central Repository Data Sources EamArtifactInstances.knownStatus.bad=Bad EamArtifactInstances.knownStatus.known=Known EamArtifactInstances.knownStatus.unknown=Unknown +EamArtifactUtil.emailaddresses.text=Email Addresses EamCase.title.caseDisplayName=Case Name: EamCase.title.caseNumber=Case Number: EamCase.title.caseUUID=Case UUID: diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/Bundle.properties-MERGED index cd654a5b37..b7c3df2c53 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/Bundle.properties-MERGED @@ -7,6 +7,3 @@ IngestEventsListener.prevCount.text=Number of previous {0}: {1} IngestEventsListener.prevExists.text=Previously Seen Devices (Central Repository) IngestEventsListener.prevTaggedSet.text=Previously Tagged As Notable (Central Repository) Installer.centralRepoUpgradeFailed.title=Central repository disabled -Installer.initialCreateSqlite.messageDesc=It will store information about all hashes and identifiers that you process. You can use this to ignore previously seen files and make connections between cases. -Installer.initialCreateSqlite.messageHeader=The Central Repository is not enabled. Would you like to? -Installer.initialCreateSqlite.title=Enable Central Repository? diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/Bundle.properties-MERGED index b4a3b7ed03..7277910e7d 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/Bundle.properties-MERGED @@ -33,12 +33,6 @@ EamDbSettingsDialog.validation.finished=Click OK to save your database settings EamDbSettingsDialog.validation.incompleteFields=Fill in all values for the selected database. EamOptionsController.moduleErr=Error processing value changes. EamOptionsController.moduleErr.msg=Value change processing failed. -GlobalSettingsPanel.onMultiUserChange.disabledMu.description=The Central Repository will be reconfigured to use a local SQLite database. -GlobalSettingsPanel.onMultiUserChange.disabledMu.description2=Press Configure PostgreSQL to change to a PostgreSQL database. -GlobalSettingsPanel.onMultiUserChange.disabledMu.title=Central Repository Change Necessary -GlobalSettingsPanel.onMultiUserChange.enable.description=Do you want to update the Central Repository to use this PostgreSQL database? -GlobalSettingsPanel.onMultiUserChange.enable.description2=The Central Repository stores hash values and accounts from past cases. -GlobalSettingsPanel.onMultiUserChange.enable.title=Use with Central Repository? GlobalSettingsPanel.updateFailed.title=Central repository disabled GlobalSettingsPanel.validationErrMsg.ingestRunning=You cannot change settings while ingest is running. GlobalSettingsPanel.validationerrMsg.mustConfigure=Configure the database to enable this module. diff --git a/Core/src/org/sleuthkit/autopsy/core/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/core/Bundle.properties-MERGED index 0b16a9701f..c84f1f1b86 100755 --- a/Core/src/org/sleuthkit/autopsy/core/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/core/Bundle.properties-MERGED @@ -3,13 +3,7 @@ Installer.closing.confirmationDialog.title=Ingest is Running # {0} - exception message Installer.closing.messageBox.caseCloseExceptionMessage=Error closing case: {0} OpenIDE-Module-Display-Category=Infrastructure -OpenIDE-Module-Long-Description=\ - This is the core Autopsy module.\n\n\ - The module contains the core components needed for the bare application to run; the RCP platform, windowing GUI, sleuthkit bindings, datamodel / storage, explorer, result viewers, content viewers, ingest framework, reporting, and core tools, such as the file search.\n\n\ - The framework included in the module contains APIs for developing modules for ingest, viewers and reporting. \ - The modules can be deployed as Plugins using the Autopsy plugin installer.\n\ - This module should not be uninstalled - without it, Autopsy will not run.\n\n\ - For more information, see http://www.sleuthkit.org/autopsy/ +OpenIDE-Module-Long-Description=This is the core Autopsy module.\n\nThe module contains the core components needed for the bare application to run; the RCP platform, windowing GUI, sleuthkit bindings, datamodel / storage, explorer, result viewers, content viewers, ingest framework, reporting, and core tools, such as the file search.\n\nThe framework included in the module contains APIs for developing modules for ingest, viewers and reporting. The modules can be deployed as Plugins using the Autopsy plugin installer.\nThis module should not be uninstalled - without it, Autopsy will not run.\n\nFor more information, see http://www.sleuthkit.org/autopsy/ OpenIDE-Module-Name=Autopsy-Core OpenIDE-Module-Short-Description=Autopsy Core Module org_sleuthkit_autopsy_core_update_center=http://sleuthkit.org/autopsy/updates.xml diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle.properties-MERGED index 9f363b7723..f252420726 100755 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle.properties-MERGED @@ -63,9 +63,9 @@ DataContentViewerHex.totalPageLabel.text_1=100 DataContentViewerHex.pageLabel2.text=Page # Product Information panel -LBL_Description=
\n Product Version: {0} ({9})
Sleuth Kit Version: {7}
Netbeans RCP Build: {8}
Java: {1}; {2}
System: {3}; {4}; {5}
Userdir: {6}
+LBL_Description=
\n Product Version: {0} ({9})
Sleuth Kit Version: {7}
Netbeans RCP Build: {8}
Java: {1}; {2}
System: {3}; {4}; {5}
Userdir: {6}
Format_OperatingSystem_Value={0} version {1} running on {2} -LBL_Copyright=
Autopsy™ is a digital forensics platform based on The Sleuth Kit™ and other tools.
Copyright © 2003-2018.
+LBL_Copyright=
Autopsy™ is a digital forensics platform based on The Sleuth Kit™ and other tools.
Copyright © 2003-2018.
SortChooser.dialogTitle=Choose Sort Criteria ThumbnailViewChildren.progress.cancelling=(Cancelling) # {0} - file name @@ -95,7 +95,7 @@ DataResultViewerThumbnail.pageNextButton.text= DataResultViewerThumbnail.imagesLabel.text=Images: DataResultViewerThumbnail.imagesRangeLabel.text=- DataResultViewerThumbnail.pageNumLabel.text=- -DataResultViewerThumbnail.filePathLabel.text=\ \ \ +DataResultViewerThumbnail.filePathLabel.text=\ DataResultViewerThumbnail.goToPageLabel.text=Go to Page: DataResultViewerThumbnail.goToPageField.text= AdvancedConfigurationDialog.cancelButton.text=Cancel diff --git a/Core/src/org/sleuthkit/autopsy/coreutils/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/coreutils/Bundle.properties-MERGED index a0d535f8e6..18e279dd2c 100755 --- a/Core/src/org/sleuthkit/autopsy/coreutils/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/coreutils/Bundle.properties-MERGED @@ -30,9 +30,7 @@ PlatformUtil.getProcVmUsed.sigarNotInit.msg=Cannot get virt mem used, sigar not PlatformUtil.getProcVmUsed.gen.msg=Cannot get virt mem used, {0} PlatformUtil.getJvmMemInfo.usageText=JVM heap usage: {0}, JVM non-heap usage: {1} PlatformUtil.getPhysicalMemInfo.usageText=Physical memory usage (max, total, free): {0}, {1}, {2} -PlatformUtil.getAllMemUsageInfo.usageText={0}\n\ -{1}\n\ -Process Virtual Memory: {2} +PlatformUtil.getAllMemUsageInfo.usageText={0}\n{1}\nProcess Virtual Memory: {2} # {0} - file name ReadImageTask.mesageText=Reading image: {0} StringExtract.illegalStateException.cannotInit.msg=Unicode table not properly initialized, cannot instantiate StringExtract diff --git a/Core/src/org/sleuthkit/autopsy/filesearch/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/filesearch/Bundle.properties-MERGED index 0e732c1519..c585d0edf5 100755 --- a/Core/src/org/sleuthkit/autopsy/filesearch/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/filesearch/Bundle.properties-MERGED @@ -14,7 +14,7 @@ KnownStatusSearchPanel.knownCheckBox.text=Known Status: KnownStatusSearchPanel.knownBadOptionCheckBox.text=Notable KnownStatusSearchPanel.knownOptionCheckBox.text=Known (NSRL or other) KnownStatusSearchPanel.unknownOptionCheckBox.text=Unknown -DateSearchFilter.noneSelectedMsg.text=At least one date type must be selected\! +DateSearchFilter.noneSelectedMsg.text=At least one date type must be selected! DateSearchPanel.dateCheckBox.text=Date: DateSearchPanel.jLabel4.text=Timezone: DateSearchPanel.jLabel3.text=*The date format is mm/dd/yyyy @@ -57,7 +57,7 @@ FileSearchPanel.search.results.details=Large number of matches may impact perfor FileSearchPanel.search.exception.noFilterSelected.msg=At least one filter must be selected. FileSearchPanel.search.validationErr.msg=Validation Error: {0} FileSearchPanel.emptyWhereClause.text=Invalid options, nothing to show. -KnownStatusSearchFilter.noneSelectedMsg.text=At least one known status must be selected\! +KnownStatusSearchFilter.noneSelectedMsg.text=At least one known status must be selected! NameSearchFilter.emptyNameMsg.text=Must enter something for name search. SizeSearchPanel.sizeCompareComboBox.equalTo=equal to SizeSearchPanel.sizeCompareComboBox.greaterThan=greater than diff --git a/Core/src/org/sleuthkit/autopsy/ingest/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/ingest/Bundle.properties-MERGED index 9e4f612b6b..6be3e48e71 100755 --- a/Core/src/org/sleuthkit/autopsy/ingest/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/ingest/Bundle.properties-MERGED @@ -140,7 +140,7 @@ IngestJob.cancelReason.outOfDiskSpace.text=Out of disk space IngestJob.cancelReason.servicesDown.text=Services Down IngestJob.cancelReason.caseClosed.text=Case closed IngestJobSettingsPanel.globalSettingsButton.text=Global Settings -gest +gest= IngestJobSettingsPanel.globalSettingsButton.actionCommand=Advanced IngestJobSettingsPanel.globalSettingsButton.text=Global Settings IngestJobSettingsPanel.pastJobsButton.text=History diff --git a/Core/src/org/sleuthkit/autopsy/modules/embeddedfileextractor/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/modules/embeddedfileextractor/Bundle.properties-MERGED index 4585d86449..4729293fb9 100755 --- a/Core/src/org/sleuthkit/autopsy/modules/embeddedfileextractor/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/modules/embeddedfileextractor/Bundle.properties-MERGED @@ -11,12 +11,7 @@ ExtractArchiveWithPasswordAction.progress.text=Unpacking contents of archive: {0 ExtractArchiveWithPasswordAction.prompt.text=Enter Password ExtractArchiveWithPasswordAction.prompt.title=Enter Password OpenIDE-Module-Display-Category=Ingest Module -OpenIDE-Module-Long-Description=\ - Embedded File Extraction Ingest Module\n\nThe Embedded File Extraction Ingest Module processes document files (such as doc, docx, ppt, pptx, xls, xlsx) and archive files (such as zip and others archive types supported by the 7zip extractor).\n\ - Contents of these files are extracted and the derived files are added back to the current ingest to be processed by the configured ingest modules.\n\ - If the derived file happens to be an archive file, it will be re-processed by the 7zip extractor - the extractor will process archive files N-levels deep.\n\n\ - The extracted files are navigable in the directory tree.\n\n\ - The module is supported on Windows, Linux and Mac operating systems. +OpenIDE-Module-Long-Description=Embedded File Extraction Ingest Module\n\nThe Embedded File Extraction Ingest Module processes document files (such as doc, docx, ppt, pptx, xls, xlsx) and archive files (such as zip and others archive types supported by the 7zip extractor).\nContents of these files are extracted and the derived files are added back to the current ingest to be processed by the configured ingest modules.\nIf the derived file happens to be an archive file, it will be re-processed by the 7zip extractor - the extractor will process archive files N-levels deep.\n\nThe extracted files are navigable in the directory tree.\n\nThe module is supported on Windows, Linux and Mac operating systems. OpenIDE-Module-Name=Embedded File Extraction OpenIDE-Module-Short-Description=Embedded File Extraction Ingest Module EmbeddedFileExtractorIngestModule.SevenZipContentReadStream.seek.exception.invalidOrigin=Invalid seek origin: {0} @@ -28,6 +23,7 @@ EmbeddedFileExtractorIngestModule.ArchiveExtractor.isZipBombCheck.warnMsg=Possib EmbeddedFileExtractorIngestModule.ArchiveExtractor.isZipBombCheck.warnDetails=Compression ratio is {0}, skipping items in {1}. EmbeddedFileExtractorIngestModule.ArchiveExtractor.unpack.warnMsg.zipBomb=Possible ZIP bomb detected: {0} EmbeddedFileExtractorIngestModule.ArchiveExtractor.unpack.warnDetails.zipBomb=The archive is {0} levels deep, skipping processing of {1} +EmbeddedFileExtractorIngestModule.ArchiveExtractor.unpack.unknownPath.msg=Unknown item path in archive: {0}, will use: {1} EmbeddedFileExtractorIngestModule.ArchiveExtractor.unpack.notEnoughDiskSpace.msg=Not enough disk space to unpack archive item: {0}, {1} EmbeddedFileExtractorIngestModule.ArchiveExtractor.unpack.notEnoughDiskSpace.details=The archive item is too large to unpack, skipping unpacking this item. EmbeddedFileExtractorIngestModule.ArchiveExtractor.unpack.errUnpacking.msg=Error unpacking {0} diff --git a/Core/src/org/sleuthkit/autopsy/modules/exif/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/modules/exif/Bundle.properties-MERGED index f9a5a88b1b..4915d5a124 100755 --- a/Core/src/org/sleuthkit/autopsy/modules/exif/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/modules/exif/Bundle.properties-MERGED @@ -2,9 +2,7 @@ CannotRunFileTypeDetection=Cannot run file type detection. ExifParserFileIngestModule.indexError.message=Failed to post EXIF Metadata artifact(s). ExifParserFileIngestModule.userContent.description=EXIF metadata exists for this file. OpenIDE-Module-Display-Category=Ingest Module -OpenIDE-Module-Long-Description=\ - Exif metadata ingest module. \n\n\ - The ingest module analyzes image files, extracts Exif information and posts the Exif data as results. +OpenIDE-Module-Long-Description=Exif metadata ingest module. \n\nThe ingest module analyzes image files, extracts Exif information and posts the Exif data as results. OpenIDE-Module-Name=ExifParser OpenIDE-Module-Short-Description=Exif metadata ingest module ExifParserFileIngestModule.moduleName.text=Exif Parser diff --git a/Core/src/org/sleuthkit/autopsy/modules/fileextmismatch/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/modules/fileextmismatch/Bundle.properties-MERGED index cfaadf1635..5063bd55fa 100755 --- a/Core/src/org/sleuthkit/autopsy/modules/fileextmismatch/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/modules/fileextmismatch/Bundle.properties-MERGED @@ -36,27 +36,27 @@ FileExtMismatchSettingsPanel.jLabel1.text=File Types: FileExtMismatchSettingsPanel.newExtButton.text=New Extension FileExtMismatchSettingsPanel.newMimePrompt.message=Add a new MIME file type: FileExtMismatchSettingsPanel.newMimePrompt.title=New MIME -FileExtMismatchSettingsPanel.newMimePrompt.emptyMime.message=MIME type text is empty\! +FileExtMismatchSettingsPanel.newMimePrompt.emptyMime.message=MIME type text is empty! FileExtMismatchSettingsPanel.newMimePrompt.emptyMime.title=Empty type -FileExtMismatchSettingsPanel.newMimePrompt.mimeTypeNotSupported.message=MIME type not supported\! +FileExtMismatchSettingsPanel.newMimePrompt.mimeTypeNotSupported.message=MIME type not supported! FileExtMismatchSettingsPanel.newMimePrompt.mimeTypeNotSupported.title=Type not supported -FileExtMismatchSettingsPanel.newMimePrompt.mimeTypeExists.message=MIME type already exists\! +FileExtMismatchSettingsPanel.newMimePrompt.mimeTypeExists.message=MIME type already exists! FileExtMismatchSettingsPanel.newMimePrompt.mimeTypeExists.title=Type already exists FileExtMismatchSettingsPanel.newMimePrompt.mimeTypeNotDetectable.message=MIME type is not detectable by this module. FileExtMismatchSettingsPanel.newMimePrompt.mimeTypeNotDetectable.title=Type not detectable -FileExtMismatchSettingsPanel.removeTypeButton.noneSelected.message=No MIME type selected\! +FileExtMismatchSettingsPanel.removeTypeButton.noneSelected.message=No MIME type selected! FileExtMismatchSettingsPanel.removeTypeButton.noneSelected.title=No type selected FileExtMismatchSettingsPanel.newExtPrompt.message=Add an allowed extension: FileExtMismatchSettingsPanel.newExtPrompt.title=New allowed extension -FileExtMismatchSettingsPanel.newExtPrompt.empty.message=Extension text is empty\! +FileExtMismatchSettingsPanel.newExtPrompt.empty.message=Extension text is empty! FileExtMismatchSettingsPanel.newExtPrompt.empty.title=Extension text empty -FileExtMismatchSettingsPanel.newExtPrompt.noMimeType.message=No MIME type selected\! +FileExtMismatchSettingsPanel.newExtPrompt.noMimeType.message=No MIME type selected! FileExtMismatchSettingsPanel.newExtPrompt.noMimeType.title=No MIME type selected -FileExtMismatchSettingsPanel.newExtPrompt.extExists.message=Extension already exists\! +FileExtMismatchSettingsPanel.newExtPrompt.extExists.message=Extension already exists! FileExtMismatchSettingsPanel.newExtPrompt.extExists.title=Extension already exists -FileExtMismatchSettingsPanel.removeExtButton.noneSelected.message=No extension selected\! +FileExtMismatchSettingsPanel.removeExtButton.noneSelected.message=No extension selected! FileExtMismatchSettingsPanel.removeExtButton.noneSelected.title=No extension selected -FileExtMismatchSettingsPanel.removeExtButton.noMimeTypeSelected.message=No MIME type selected\! +FileExtMismatchSettingsPanel.removeExtButton.noMimeTypeSelected.message=No MIME type selected! FileExtMismatchSettingsPanel.removeExtButton.noMimeTypeSelected.title=No MIME type selected FileExtMismatchSettingsPanel.removeTypeButton.toolTipText= FileExtMismatchModuleSettingsPanel.checkAllRadioButton.text=Check all file types diff --git a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/Bundle.properties-MERGED index 0b470ce6b1..44057d0016 100755 --- a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/Bundle.properties-MERGED @@ -49,10 +49,7 @@ ImportCentralRepoDbProgressDialog.errorParsingFile.message=Error parsing hash se ImportCentralRepoDbProgressDialog.linesProcessed.message=\ hashes processed ImportCentralRepoDbProgressDialog.title.text=Central Repository Import Progress OpenIDE-Module-Display-Category=Ingest Module -OpenIDE-Module-Long-Description=\ - Hash Set ingest module. \n\n\ - The ingest module analyzes files in the disk image and marks them as "known" (based on NSRL hashset lookup for "known" files) and "bad / interesting" (based on one or more hash sets supplied by the user).\n\n\ - The module also contains additional non-ingest tools that are integrated in the GUI, such as file lookup by hash and hash set configuration. +OpenIDE-Module-Long-Description=Hash Set ingest module. \n\nThe ingest module analyzes files in the disk image and marks them as "known" (based on NSRL hashset lookup for "known" files) and "bad / interesting" (based on one or more hash sets supplied by the user).\n\nThe module also contains additional non-ingest tools that are integrated in the GUI, such as file lookup by hash and hash set configuration. OpenIDE-Module-Name=HashDatabases OptionsCategory_Name_HashDatabase=Hash Sets OptionsCategory_Keywords_HashDatabase=Hash Sets @@ -181,10 +178,7 @@ HashDbSearchThread.name.searching=Searching HashDbSearchThread.noMoreFilesWithMD5Msg=No other files with the same MD5 hash were found. ModalNoButtons.indexingDbsTitle=Indexing hash sets ModalNoButtons.indexingDbTitle=Indexing hash set -ModalNoButtons.exitHashDbIndexingMsg=You are about to exit out of indexing your hash sets. \n\ -The generated index will be left unusable. If you choose to continue,\n\ - please delete the corresponding -md5.idx file in the hash folder.\n\ - Exit indexing? +ModalNoButtons.exitHashDbIndexingMsg=You are about to exit out of indexing your hash sets. \nThe generated index will be left unusable. If you choose to continue,\nplease delete the corresponding -md5.idx file in the hash folder.\nExit indexing? ModalNoButtons.dlgTitle.unfinishedIndexing=Unfinished Indexing ModalNoButtons.indexThis.currentlyIndexing1Db=Currently indexing 1 hash set ModalNoButtons.indexThese.currentlyIndexing1OfNDbs=Currently indexing 1 of {0} diff --git a/Core/src/org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties-MERGED index 1279d3642b..31a0690b82 100755 --- a/Core/src/org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties-MERGED @@ -83,8 +83,8 @@ FilesSetRulePanel.nameTextField.text= FilesSetRulePanel.ruleNameLabel.text=Rule Name (Optional): FilesSetRulePanel.messages.emptyNameCondition=You must specify a name pattern for this rule. FilesSetRulePanel.messages.invalidNameRegex=The name regular expression is not valid:\n\n{0} -FilesSetRulePanel.messages.invalidCharInName=The name cannot contain \\, /, :, *, ?, \", <, or > unless it is a regular expression. -FilesSetRulePanel.messages.invalidCharInPath=The path cannot contain \\, :, *, ?, \", <, or > unless it is a regular expression. +FilesSetRulePanel.messages.invalidCharInName=The name cannot contain \\, /, :, *, ?, ", <, or > unless it is a regular expression. +FilesSetRulePanel.messages.invalidCharInPath=The path cannot contain \\, :, *, ?, ", <, or > unless it is a regular expression. FilesSetRulePanel.messages.invalidPathRegex=The path regular expression is not valid:\n\n{0} FilesSetDefsPanel.doFileSetsDialog.duplicateRuleSet.text=Rule set with name {0} already exists. FilesSetRulePanel.pathSeparatorInfoLabel.text=Folder must be in parent path. Use '/' to give consecutive names diff --git a/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/Bundle.properties-MERGED index 87dacfc16c..2dc971a40d 100755 --- a/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/Bundle.properties-MERGED @@ -21,7 +21,7 @@ PhotoRecIngestModule.complete.totalParsetime=Total Parsing Time: PhotoRecIngestModule.complete.photoRecResults=PhotoRec Results PhotoRecIngestModule.NotEnoughDiskSpace.detail.msg=PhotoRec error processing {0} with {1} Not enough space on primary disk to save unallocated space. PhotoRecIngestModule.cancelledByUser=PhotoRec cancelled by user. -PhotoRecIngestModule.error.exitValue=PhotoRec carver returned error exit value \= {0} when scanning {1} +PhotoRecIngestModule.error.exitValue=PhotoRec carver returned error exit value = {0} when scanning {1} PhotoRecIngestModule.error.msg=Error processing {0} with PhotoRec carver. PhotoRecIngestModule.complete.numberOfErrors=Number of Errors while Carving: PhotoRecCarverIngestJobSettingsPanel.detectionSettingsLabel.text=PhotoRec Settings diff --git a/Core/src/org/sleuthkit/autopsy/report/modules/html/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/report/modules/html/Bundle.properties-MERGED index 32f6867f0c..0be7595111 100755 --- a/Core/src/org/sleuthkit/autopsy/report/modules/html/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/report/modules/html/Bundle.properties-MERGED @@ -5,8 +5,8 @@ ReportHTML.getName.text=HTML Report ReportHTML.getDesc.text=A report about results and tagged items in HTML format. ReportHTML.writeIndex.title=for case {0} ReportHTML.writeIndex.noFrames.msg=Your browser is not compatible with our frame setup. -ReportHTML.writeIndex.noFrames.seeNav=Please see the navigation page for artifact links, -ReportHTML.writeIndex.seeSum=and the summary page for a case summary. +ReportHTML.writeIndex.noFrames.seeNav=Please see the navigation page for artifact links, +ReportHTML.writeIndex.seeSum=and the summary page for a case summary. ReportHTML.writeNav.title=Report Navigation ReportHTML.writeNav.h1=Report Navigation ReportHTML.writeNav.summary=Case Summary @@ -16,7 +16,7 @@ ReportHTML.writeSum.caseNumber=Case Number: ReportHTML.writeSum.caseNumImages=Number of Images: ReportHTML.writeSum.examiner=Examiner: ReportHTML.writeSum.title=Case Summary -ReportHTML.writeSum.warningMsg=Warning, this report was run before ingest services completed\! +ReportHTML.writeSum.warningMsg=Warning, this report was run before ingest services completed! # # autopsy/test/scripts/regression.py._html_report_diff() uses reportGenOn.text, caseName, caseNum, # examiner as a regex signature to skip report.html and summary.html diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Bundle.properties-MERGED b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Bundle.properties-MERGED index ebdce8a327..18deff87f4 100755 --- a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Bundle.properties-MERGED +++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Bundle.properties-MERGED @@ -1,6 +1,7 @@ cannotBuildXmlParser=Unable to build XML parser: cannotLoadSEUQA=Unable to load Search Engine URL Query Analyzer settings file, SEUQAMappings.xml: cannotParseXml=Unable to parse XML file: +Chrome.getBookmark.errMsg.errAnalyzeFile={0}: Error while trying to analyze file: {1} ChromeCacheExtract_adding_artifacts_msg=Chrome Cache: Adding %d artifacts for analysis. ChromeCacheExtract_adding_extracted_files_msg=Chrome Cache: Adding %d extracted files for analysis. ChromeCacheExtract_loading_files_msg=Chrome Cache: Loading files from %s. @@ -13,9 +14,9 @@ ChromeCacheExtractor.progressMsg={0}: Extracting cache entry {1} of {2} entries DataSourceUsage_AndroidMedia=Android Media Card DataSourceUsage_DJU_Drone_DAT=DJI Internal SD Card DataSourceUsage_FlashDrive=Flash Drive -# {0} - OS name DataSourceUsageAnalyzer.customVolume.label=OS Drive ({0}) DataSourceUsageAnalyzer.parentModuleName=Recent Activity +Extract.dbConn.errMsg.failedToQueryDb={0}: Failed to query database. Extract.indexError.message=Failed to index artifact for keyword search. Extract.noOpenCase.errMsg=No open case available. ExtractEdge_getHistory_containerFileNotFound=Error while trying to analyze Edge history @@ -24,6 +25,11 @@ ExtractEdge_process_errMsg_errGettingWebCacheFiles=Error trying to retrieving Ed ExtractEdge_process_errMsg_spartanFail=Failure processing Microsoft Edge spartan.edb file ExtractEdge_process_errMsg_unableFindESEViewer=Unable to find ESEDatabaseViewer ExtractEdge_process_errMsg_webcacheFail=Failure processing Microsoft Edge WebCacheV01.dat file +ExtractIE.getBookmark.ere.noSpace=RecentActivity +ExtractIE.getBookmark.errMsg.errPostingBookmarks=Error posting Internet Explorer Bookmark artifacts. +ExtractIE.getCookie.errMsg.errPostingCookies=Error posting Internet Explorer Cookie artifacts. +ExtractIE.getHistory.errMsg.errPostingHistory=Error posting Internet Explorer History artifacts. +Extractor.errPostingArtifacts=Error posting {0} artifacts to the blackboard. ExtractOs.androidOs.label=Android ExtractOs.androidVolume.label=OS Drive (Android) ExtractOs.debianLinuxOs.label=Linux (Debian) @@ -90,7 +96,7 @@ Chrome.getLogin.errMsg.errAnalyzingFiles={0}: Error while trying to analyze file Chrome.getAutofill.errMsg.errGettingFiles=Error when trying to get Chrome Web Data files. Chrome.getAutofill.errMsg.errAnalyzingFiles={0}: Error while trying to analyze file:{1} ExtractIE.moduleName.text=Internet Explorer -ExtractIE.getBookmark.errMsg.errGettingBookmarks={0}: Error getting Internet Explorer Bookmarks. +ExtractIE.getBookmark.errMsg.errGettingBookmarks=Error getting Internet Explorer Bookmarks. ExtractIE.parentModuleName.noSpace=RecentActivity ExtractIE.parentModuleName=Recent Activity ExtractIE.getURLFromIEBmkFile.errMsg={0}: Error parsing IE bookmark File {1} @@ -192,7 +198,6 @@ RecentDocumentsByLnk.parentModuleName.noSpace=RecentActivity RecentDocumentsByLnk.parentModuleName=Recent Activity RegRipperFullNotFound=Full version RegRipper executable not found. RegRipperNotFound=Autopsy RegRipper executable not found. -# {0} - file name SearchEngineURLQueryAnalyzer.init.exception.msg=Unable to find {0}. SearchEngineURLQueryAnalyzer.moduleName.text=Search Engine SearchEngineURLQueryAnalyzer.engineName.none=NONE 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 7d080bac65..b20ccf5912 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 -#Mon, 02 Mar 2020 15:07:07 -0500 +#Tue, 12 Nov 2019 17:21:46 -0500 LBL_splash_window_title=Starting Autopsy SPLASH_HEIGHT=314 SPLASH_WIDTH=538 @@ -8,4 +8,4 @@ SplashRunningTextBounds=0,289,538,18 SplashRunningTextColor=0x0 SplashRunningTextFontSize=19 -currentVersion=Autopsy 4.14.0 +currentVersion=Autopsy 4.13.0 diff --git a/branding/modules/org-netbeans-core-windows.jar/org/netbeans/core/windows/view/ui/Bundle.properties b/branding/modules/org-netbeans-core-windows.jar/org/netbeans/core/windows/view/ui/Bundle.properties index 206dd6db16..998d3f715c 100644 --- a/branding/modules/org-netbeans-core-windows.jar/org/netbeans/core/windows/view/ui/Bundle.properties +++ b/branding/modules/org-netbeans-core-windows.jar/org/netbeans/core/windows/view/ui/Bundle.properties @@ -1,4 +1,4 @@ #Updated by build script -#Mon, 02 Mar 2020 15:07:07 -0500 -CTL_MainWindow_Title=Autopsy 4.14.0 -CTL_MainWindow_Title_No_Project=Autopsy 4.14.0 +#Tue, 12 Nov 2019 17:21:46 -0500 +CTL_MainWindow_Title=Autopsy 4.13.0 +CTL_MainWindow_Title_No_Project=Autopsy 4.13.0 From e2fbc59cf3082967a0bac7bd298ce0d1e469c8a7 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Thu, 5 Mar 2020 07:48:57 -0500 Subject: [PATCH 021/100] merge from develop --- .../org/sleuthkit/autopsy/recentactivity/ExtractRegistry.java | 1 - .../sleuthkit/autopsy/recentactivity/RecentDocumentsByLnk.java | 1 - 2 files changed, 2 deletions(-) diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractRegistry.java b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractRegistry.java index 592fa4b233..08b575c572 100644 --- a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractRegistry.java +++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractRegistry.java @@ -68,7 +68,6 @@ import java.util.Set; import java.util.HashSet; import static java.util.Locale.US; import static java.util.TimeZone.getTimeZone; -import org.apache.commons.io.FilenameUtils; import org.openide.util.Lookup; import org.sleuthkit.autopsy.ingest.DataSourceIngestModuleProgress; import org.sleuthkit.autopsy.ingest.IngestModule.IngestModuleException; diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/RecentDocumentsByLnk.java b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/RecentDocumentsByLnk.java index d2cf93e0f0..2b93720fcd 100644 --- a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/RecentDocumentsByLnk.java +++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/RecentDocumentsByLnk.java @@ -30,7 +30,6 @@ import org.apache.commons.io.FilenameUtils; import org.openide.util.NbBundle; import org.sleuthkit.autopsy.coreutils.Logger; import java.util.Collection; -import org.apache.commons.io.FilenameUtils; import org.openide.util.NbBundle.Messages; import org.sleuthkit.autopsy.coreutils.JLNK; import org.sleuthkit.autopsy.coreutils.JLnkParser; From da9059ed0c8a20777a7bdfdfe32586cb040cf87a Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Thu, 5 Mar 2020 07:57:15 -0500 Subject: [PATCH 022/100] merge from develop --- .../centralrepository/datamodel/Bundle.properties-MERGED | 3 ++- .../centralrepository/eventlisteners/Bundle.properties-MERGED | 3 +++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/Bundle.properties-MERGED index 9b43833ee2..345d5a420e 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/Bundle.properties-MERGED @@ -7,8 +7,10 @@ AbstractSqlEamDb.cannotUpgrage.message=Currently selected database platform "{0} AbstractSqlEamDb.failedToReadMajorVersion.message=Failed to read schema version for Central Repository. AbstractSqlEamDb.failedToReadMinorVersion.message=Failed to read schema minor version for Central Repository. AbstractSqlEamDb.upgradeSchema.incompatible=The selected Central Repository is not compatible with the current version of the application, please upgrade the application if you wish to use this Central Repository. +CentralRepoDbManager.connectionErrorMsg.text=Failed to connect to central repository database. CorrelationAttributeInstance.invalidName.message=Invalid database table name. Name must start with a lowercase letter and can only contain lowercase letters, numbers, and '_'. CorrelationAttributeInstance.nullName.message=Database name is null. +CorrelationAttributeUtil.emailaddresses.text=Email Addresses CorrelationType.DOMAIN.displayName=Domains CorrelationType.EMAIL.displayName=Email Addresses CorrelationType.FILES.displayName=Files @@ -23,7 +25,6 @@ DataSourceUpdateService.serviceName.text=Update Central Repository Data Sources EamArtifactInstances.knownStatus.bad=Bad EamArtifactInstances.knownStatus.known=Known EamArtifactInstances.knownStatus.unknown=Unknown -EamArtifactUtil.emailaddresses.text=Email Addresses EamCase.title.caseDisplayName=Case Name: EamCase.title.caseNumber=Case Number: EamCase.title.caseUUID=Case UUID: diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/Bundle.properties-MERGED index b7c3df2c53..cd654a5b37 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/Bundle.properties-MERGED @@ -7,3 +7,6 @@ IngestEventsListener.prevCount.text=Number of previous {0}: {1} IngestEventsListener.prevExists.text=Previously Seen Devices (Central Repository) IngestEventsListener.prevTaggedSet.text=Previously Tagged As Notable (Central Repository) Installer.centralRepoUpgradeFailed.title=Central repository disabled +Installer.initialCreateSqlite.messageDesc=It will store information about all hashes and identifiers that you process. You can use this to ignore previously seen files and make connections between cases. +Installer.initialCreateSqlite.messageHeader=The Central Repository is not enabled. Would you like to? +Installer.initialCreateSqlite.title=Enable Central Repository? From 64d73e04348572539f174820c5888450b8015787 Mon Sep 17 00:00:00 2001 From: Mark McKinnon Date: Thu, 5 Mar 2020 16:44:23 -0500 Subject: [PATCH 023/100] Update viber.py If contact does not have an email or phone number then create a TSK_Contact artifact outside of comms helper so we do not loose the contact. --- InternalPythonModules/android/viber.py | 29 +++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/InternalPythonModules/android/viber.py b/InternalPythonModules/android/viber.py index ded45e186f..aadd1a2104 100644 --- a/InternalPythonModules/android/viber.py +++ b/InternalPythonModules/android/viber.py @@ -117,13 +117,28 @@ class ViberAnalyzer(general.AndroidComponentAnalyzer): try: contacts_parser = ViberContactsParser(contacts_db) while contacts_parser.next(): - helper.addContact( - contacts_parser.get_contact_name(), - contacts_parser.get_phone(), - contacts_parser.get_home_phone(), - contacts_parser.get_mobile_phone(), - contacts_parser.get_email() - ) + if contacts_parser.get_phone() is not None: + helper.addContact( + contacts_parser.get_contact_name(), + contacts_parser.get_phone(), + contacts_parser.get_home_phone(), + contacts_parser.get_mobile_phone(), + contacts_parser.get_email() + ) + else: + current_case = Case.getCurrentCase().getSleuthkitCase() + attributes = ArrayList() + artifact = contacts_db.getDBFile().newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_CONTACT) + attributes.add(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_NAME.getTypeID(), self._PARSER_NAME, contacts_parser.get_contact_name())) + artifact.addAttributes(attributes) + + try: + # Post the artifact to blackboard + current_case.getBlackboard().postArtifact(artifact, self._PARSER_NAME) + except Blackboard.BlackboardException as e: + self.log(Level.WARNING, "Error adding viber contacts artifact to case database.", ex ) + self._logger.log(Level.WARNING, traceback.format_exc()) + contacts_parser.close() except SQLException as ex: self._logger.log(Level.WARNING, "Error querying the viber database for contacts.", ex) From 167c12f00c8b54c2525a0b73bd14fd7aa6b6252e Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Fri, 6 Mar 2020 08:36:42 -0500 Subject: [PATCH 024/100] updates from PR --- .../datamodel/CentralRepoDbChoice.java | 31 ++++++++----------- .../datamodel/CentralRepoDbManager.java | 22 ++++++------- .../CentralRepoPostgresSettingsUtil.java | 26 ++++++++-------- .../datamodel/DatabaseTestResult.java | 2 +- .../PostgresCentralRepoSettings.java | 6 ++-- .../datamodel/PostgresSettingsLoader.java | 4 +-- .../datamodel/SqliteCentralRepoSettings.java | 2 +- .../optionspanel/EamDbSettingsDialog.java | 2 +- .../autopsy/core/UserPreferences.java | 3 +- 9 files changed, 46 insertions(+), 52 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbChoice.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbChoice.java index 92f0af775b..574408b619 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbChoice.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbChoice.java @@ -18,23 +18,22 @@ */ package org.sleuthkit.autopsy.centralrepository.datamodel; +import org.openide.util.NbBundle.Messages; + /** * the database choices available for central repo */ -public class CentralRepoDbChoice { - public static final CentralRepoDbChoice DISABLED = new CentralRepoDbChoice("Disabled", CentralRepoPlatforms.DISABLED); - - public static final CentralRepoDbChoice SQLITE = new CentralRepoDbChoice("Sqlite", "SQLite", CentralRepoPlatforms.SQLITE); - - public static final CentralRepoDbChoice POSTGRESQL_MULTIUSER = - new CentralRepoDbChoice("PostgreSQL_Multiuser", "PostgreSQL using multi-user settings", CentralRepoPlatforms.POSTGRESQL); - - public static final CentralRepoDbChoice POSTGRESQL_CUSTOM = - new CentralRepoDbChoice("PostgreSQL", "Custom PostgreSQL", CentralRepoPlatforms.POSTGRESQL); - - public static final CentralRepoDbChoice[] CHOICES = new CentralRepoDbChoice[]{ - DISABLED, SQLITE, POSTGRESQL_MULTIUSER, POSTGRESQL_CUSTOM - }; +@Messages({ + "CentralRepoDbChoice.Disabled.Text=Disabled", + "CentralRepoDbChoice.Sqlite.Text=SQLite", + "CentralRepoDbChoice.PostgreSQL_Multiuser.Text=PostgreSQL using multi-user settings", + "CentralRepoDbChoice.PostgreSQL.Text=Custom PostgreSQL", +}) +public enum CentralRepoDbChoice { + DISABLED("Disabled", Bundle.CentralRepoDbChoice_Disabled_Text(), CentralRepoPlatforms.DISABLED), + SQLITE("Sqlite", Bundle.CentralRepoDbChoice_Sqlite_Text(), CentralRepoPlatforms.SQLITE), + POSTGRESQL_MULTIUSER("PostgreSQL_Multiuser", Bundle.CentralRepoDbChoice_PostgreSQL_Multiuser_Text(), CentralRepoPlatforms.POSTGRESQL), + POSTGRESQL_CUSTOM("PostgreSQL", Bundle.CentralRepoDbChoice_PostgreSQL_Text(), CentralRepoPlatforms.POSTGRESQL); public static final CentralRepoDbChoice[] DB_CHOICES = new CentralRepoDbChoice[]{ SQLITE, POSTGRESQL_MULTIUSER, POSTGRESQL_CUSTOM @@ -50,10 +49,6 @@ public class CentralRepoDbChoice { this.title = title; this.platform = platform; } - - CentralRepoDbChoice(String key, CentralRepoPlatforms platform) { - this(key, key, platform); - } public String getSettingKey() { return settingKey; diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java index 07e024d431..20309fca7b 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java @@ -37,14 +37,14 @@ public class CentralRepoDbManager { - private static volatile CentralRepoDbChoice SAVED_CHOICE = null; + private static volatile CentralRepoDbChoice savedChoice = null; /** * Save the selected platform to the config file. */ public static synchronized CentralRepoDbChoice saveDbChoice(CentralRepoDbChoice choice) { choice = (choice == null) ? CentralRepoDbChoice.DISABLED : choice; - SAVED_CHOICE = choice; + savedChoice = choice; ModuleSettings.setConfigSetting("CentralRepository", "db.selectedPlatform", choice.getSettingKey()); return choice; } @@ -53,17 +53,17 @@ public class CentralRepoDbManager { * Load the selectedPlatform boolean from the config file, if it is set. */ public static synchronized CentralRepoDbChoice getSavedDbChoice() { - if (SAVED_CHOICE == null) { + if (savedChoice == null) { String selectedPlatformString = ModuleSettings.getConfigSetting("CentralRepository", "db.selectedPlatform"); // NON-NLS - SAVED_CHOICE = fromKey(selectedPlatformString); + savedChoice = fromKey(selectedPlatformString); } - return SAVED_CHOICE; + return savedChoice; } private static CentralRepoDbChoice fromKey(String keyName) { - for (CentralRepoDbChoice dbChoice : CentralRepoDbChoice.CHOICES) { + for (CentralRepoDbChoice dbChoice : CentralRepoDbChoice.values()) { if (dbChoice.getSettingKey().equalsIgnoreCase(keyName)) { return dbChoice; } @@ -201,8 +201,8 @@ public class CentralRepoDbManager { public CentralRepoDbManager() { selectedDbChoice = getSavedDbChoice(); - dbSettingsPostgres = new PostgresCentralRepoSettings(PostgresSettingsLoader.CUSTOM_LOADER); - dbSettingsMultiUser = new PostgresCentralRepoSettings(PostgresSettingsLoader.MULTIUSER_LOADER); + dbSettingsPostgres = new PostgresCentralRepoSettings(PostgresSettingsLoader.CUSTOM_SETTINGS_LOADER); + dbSettingsMultiUser = new PostgresCentralRepoSettings(PostgresSettingsLoader.MULTIUSER_SETTINGS_LOADER); dbSettingsSqlite = new SqliteCentralRepoSettings(); } @@ -236,7 +236,7 @@ public class CentralRepoDbManager { } // the only successful setup status is tested ok - if (curStatus != DatabaseTestResult.TESTEDOK) { + if (curStatus != DatabaseTestResult.TESTED_OK) { throw new CentralRepoException("Unable to successfully create sqlite database"); } @@ -320,7 +320,7 @@ public class CentralRepoDbManager { throw new CentralRepoException(schemaError); } - testingStatus = DatabaseTestResult.TESTEDOK; + testingStatus = DatabaseTestResult.TESTED_OK; return true; } @@ -360,7 +360,7 @@ public class CentralRepoDbManager { selectedDbSettings.saveSettings(); // Load those newly saved settings into the postgres db manager instance // in case we are still using the same instance. - if (selectedDbChoice != null && selectedDbSettings != CentralRepoDbChoice.DISABLED) { + if (selectedDbChoice != null && selectedDbChoice != CentralRepoDbChoice.DISABLED) { try { logger.info("Saving central repo settings for db: " + selectedDbSettings); CentralRepository.getInstance().updateSettings(); diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoPostgresSettingsUtil.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoPostgresSettingsUtil.java index 2aa7ca6e29..69e50768a5 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoPostgresSettingsUtil.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoPostgresSettingsUtil.java @@ -81,7 +81,7 @@ public class CentralRepoPostgresSettingsUtil { } } - private static void handleTry(TryHandler handler) { + private static void logException(TryHandler handler) { try { handler.operation(); } @@ -109,14 +109,14 @@ public class CentralRepoPostgresSettingsUtil { return settings; } - handleTry(() -> settings.setHost(valOrDefault(muConn.getHost(), DEFAULT_HOST))); - handleTry(() -> settings.setDbName(DEFAULT_DBNAME)); - handleTry(() -> settings.setUserName(valOrDefault(muConn.getUserName(), DEFAULT_USERNAME))); + logException(() -> settings.setHost(valOrDefault(muConn.getHost(), DEFAULT_HOST))); + logException(() -> settings.setDbName(DEFAULT_DBNAME)); + logException(() -> settings.setUserName(valOrDefault(muConn.getUserName(), DEFAULT_USERNAME))); - handleTry(() -> settings.setPort(valOrDefault(muConn.getPort(), DEFAULT_PORT, 1, 65535))); - handleTry(() -> settings.setBulkThreshold(RdbmsCentralRepo.DEFAULT_BULK_THRESHHOLD)); + logException(() -> settings.setPort(valOrDefault(muConn.getPort(), DEFAULT_PORT, 1, 65535))); + logException(() -> settings.setBulkThreshold(RdbmsCentralRepo.DEFAULT_BULK_THRESHHOLD)); - handleTry(() -> settings.setPassword(valOrDefault(muConn.getPassword(), DEFAULT_PASSWORD))); + logException(() -> settings.setPassword(valOrDefault(muConn.getPassword(), DEFAULT_PASSWORD))); return settings; } @@ -127,12 +127,12 @@ public class CentralRepoPostgresSettingsUtil { Map keyVals = ModuleSettings.getConfigSettings(MODULE_KEY); - handleTry(() -> settings.setHost(valOrDefault(keyVals.get(HOST_KEY), DEFAULT_HOST))); - handleTry(() -> settings.setDbName(valOrDefault(keyVals.get(DBNAME_KEY), DEFAULT_DBNAME))); - handleTry(() -> settings.setUserName(valOrDefault(keyVals.get(USER_KEY), DEFAULT_USERNAME))); + logException(() -> settings.setHost(valOrDefault(keyVals.get(HOST_KEY), DEFAULT_HOST))); + logException(() -> settings.setDbName(valOrDefault(keyVals.get(DBNAME_KEY), DEFAULT_DBNAME))); + logException(() -> settings.setUserName(valOrDefault(keyVals.get(USER_KEY), DEFAULT_USERNAME))); - handleTry(() -> settings.setPort(valOrDefault(keyVals.get(PORT_KEY), DEFAULT_PORT, 1, 65535))); - handleTry(() -> settings.setBulkThreshold(valOrDefault(keyVals.get(BULK_THRESHOLD_KEY), RdbmsCentralRepo.DEFAULT_BULK_THRESHHOLD, 1, null))); + logException(() -> settings.setPort(valOrDefault(keyVals.get(PORT_KEY), DEFAULT_PORT, 1, 65535))); + logException(() -> settings.setBulkThreshold(valOrDefault(keyVals.get(BULK_THRESHOLD_KEY), RdbmsCentralRepo.DEFAULT_BULK_THRESHHOLD, 1, null))); String passwordHex = keyVals.get(PASSWORD_KEY); String password; @@ -145,7 +145,7 @@ public class CentralRepoPostgresSettingsUtil { final String finalPassword = password; - handleTry(() -> settings.setPassword(finalPassword)); + logException(() -> settings.setPassword(finalPassword)); return settings; } diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/DatabaseTestResult.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/DatabaseTestResult.java index 27a7b16278..b18a8a28cd 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/DatabaseTestResult.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/DatabaseTestResult.java @@ -26,6 +26,6 @@ public enum DatabaseTestResult { CONNECTION_FAILED, SCHEMA_INVALID, DB_DOES_NOT_EXIST, - TESTEDOK; + TESTED_OK; } diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresCentralRepoSettings.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresCentralRepoSettings.java index 2bb275bef6..df37a3fec2 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresCentralRepoSettings.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresCentralRepoSettings.java @@ -48,9 +48,9 @@ public final class PostgresCentralRepoSettings implements CentralRepoDbConnectiv private static PostgresSettingsLoader getLoaderFromSaved() throws CentralRepoException { CentralRepoDbChoice choice = CentralRepoDbManager.getSavedDbChoice(); if (choice == CentralRepoDbChoice.POSTGRESQL_CUSTOM) - return PostgresSettingsLoader.CUSTOM_LOADER; + return PostgresSettingsLoader.CUSTOM_SETTINGS_LOADER; else if (choice == CentralRepoDbChoice.POSTGRESQL_MULTIUSER) - return PostgresSettingsLoader.MULTIUSER_LOADER; + return PostgresSettingsLoader.MULTIUSER_SETTINGS_LOADER; else throw new CentralRepoException("cannot load or save postgres settings for selection: " + choice); } @@ -362,7 +362,7 @@ public final class PostgresCentralRepoSettings implements CentralRepoDbConnectiv if (verifyConnection()) { if (verifyDatabaseExists()) { if (verifyDatabaseSchema()) { - return DatabaseTestResult.TESTEDOK; + return DatabaseTestResult.TESTED_OK; } else { return DatabaseTestResult.SCHEMA_INVALID; } diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresSettingsLoader.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresSettingsLoader.java index e293f8bece..611cf25f2d 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresSettingsLoader.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresSettingsLoader.java @@ -25,8 +25,8 @@ public interface PostgresSettingsLoader { PostgresConnectionSettings loadSettings(); void saveSettings(PostgresConnectionSettings settings); - PostgresSettingsLoader CUSTOM_LOADER = new Custom(); - PostgresSettingsLoader MULTIUSER_LOADER = new MultiUser(); + PostgresSettingsLoader CUSTOM_SETTINGS_LOADER = new Custom(); + PostgresSettingsLoader MULTIUSER_SETTINGS_LOADER = new MultiUser(); /** diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteCentralRepoSettings.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteCentralRepoSettings.java index f2e8dac25c..a938dd166a 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteCentralRepoSettings.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteCentralRepoSettings.java @@ -358,7 +358,7 @@ public final class SqliteCentralRepoSettings implements CentralRepoDbConnectivit if (dbFileExists()) { if (verifyConnection()) { if (verifyDatabaseSchema()) { - return DatabaseTestResult.TESTEDOK; + return DatabaseTestResult.TESTED_OK; } else { return DatabaseTestResult.SCHEMA_INVALID; } diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java index a3a19fe811..7474f3618a 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java @@ -197,7 +197,7 @@ public class EamDbSettingsDialog extends JDialog { } } - return (manager.getStatus() == DatabaseTestResult.TESTEDOK); + return (manager.getStatus() == DatabaseTestResult.TESTED_OK); } diff --git a/Core/src/org/sleuthkit/autopsy/core/UserPreferences.java b/Core/src/org/sleuthkit/autopsy/core/UserPreferences.java index 116f212dd9..409e27f080 100644 --- a/Core/src/org/sleuthkit/autopsy/core/UserPreferences.java +++ b/Core/src/org/sleuthkit/autopsy/core/UserPreferences.java @@ -75,7 +75,6 @@ public final class UserPreferences { public static final String SHOW_ONLY_CURRENT_USER_TAGS = "ShowOnlyCurrentUserTags"; public static final String HIDE_SCO_COLUMNS = "HideCentralRepoCommentsAndOccurrences"; //The key for this setting pre-dates the settings current functionality //NON-NLS public static final String DISPLAY_TRANSLATED_NAMES = "DisplayTranslatedNames"; - private static final boolean DISPLAY_TRANSLATED_NAMES_DEFAULT = true; public static final String EXTERNAL_HEX_EDITOR_PATH = "ExternalHexEditorPath"; public static final String SOLR_MAX_JVM_SIZE = "SolrMaxJVMSize"; public static final String RESULTS_TABLE_PAGE_SIZE = "ResultsTablePageSize"; @@ -266,7 +265,7 @@ public final class UserPreferences { } public static boolean displayTranslatedFileNames() { - return preferences.getBoolean(DISPLAY_TRANSLATED_NAMES, DISPLAY_TRANSLATED_NAMES_DEFAULT); + return preferences.getBoolean(DISPLAY_TRANSLATED_NAMES, false); } /** From d07c6d5dd21b248f3794f43f7955945ec952fb98 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Fri, 6 Mar 2020 09:17:14 -0500 Subject: [PATCH 025/100] improved comments --- .../datamodel/PostgresConnectionSettings.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresConnectionSettings.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresConnectionSettings.java index 1e1f2c4e66..5ebdac7735 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresConnectionSettings.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresConnectionSettings.java @@ -87,7 +87,7 @@ public class PostgresConnectionSettings { /** - * @param port the port to set + * @param port the port to set (must be [1,65535]) */ public void setPort(int port) throws CentralRepoException { validateNum(port, 1, 65535, "Invalid port. Must be a number greater than 0."); @@ -96,7 +96,7 @@ public class PostgresConnectionSettings { /** - * @param dbName the dbName to set + * @param dbName the dbName to set */ public void setDbName(String dbName) throws CentralRepoException { validateStr(dbName, "Invalid database name. Cannot be empty."); // NON-NLS @@ -108,7 +108,7 @@ public class PostgresConnectionSettings { /** - * @param bulkThreshold the bulkThreshold to set + * @param bulkThreshold the bulkThreshold to set (must be greater than 0) */ public void setBulkThreshold(int bulkThreshold) throws CentralRepoException { validateNum(bulkThreshold, 1, null, "Invalid bulk threshold."); From 9b04404958935d390dbfcacaa1f6d8882d953947 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Fri, 6 Mar 2020 09:50:33 -0500 Subject: [PATCH 026/100] updates for handling defaults better on exception --- .../CentralRepoPostgresSettingsUtil.java | 58 +++++-------------- .../datamodel/PostgresConnectionSettings.java | 52 +++++++++-------- 2 files changed, 42 insertions(+), 68 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoPostgresSettingsUtil.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoPostgresSettingsUtil.java index 69e50768a5..7e24ef6fad 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoPostgresSettingsUtil.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoPostgresSettingsUtil.java @@ -38,12 +38,6 @@ import org.sleuthkit.datamodel.CaseDbConnectionInfo; */ public class CentralRepoPostgresSettingsUtil { private final static Logger LOGGER = Logger.getLogger(CentralRepoPostgresSettingsUtil.class.getName()); - - private final static String DEFAULT_HOST = ""; // NON-NLS - private final static int DEFAULT_PORT = 5432; - private final static String DEFAULT_DBNAME = "central_repository"; // NON-NLS - private final static String DEFAULT_USERNAME = ""; - private final static String DEFAULT_PASSWORD = ""; private static final String PASSWORD_KEY = "db.postgresql.password"; private static final String BULK_THRESHOLD_KEY = "db.postgresql.bulkThreshold"; @@ -56,36 +50,11 @@ public class CentralRepoPostgresSettingsUtil { - private static String valOrDefault(String val, String defaultVal) { - if (val == null || val.isEmpty()) - return defaultVal; - - return val; - } - - private static int valOrDefault(String val, int defaultVal, Integer min, Integer max) { - try { - if (val == null || val.isEmpty()) { - return defaultVal; - } else { - int retVal = Integer.parseInt(val); - if ((min != null && retVal < min) || (max != null && retVal > max)) { - return defaultVal; - } - else { - return retVal; - } - } - } catch (NumberFormatException ex) { - return defaultVal; - } - } - private static void logException(TryHandler handler) { try { handler.operation(); } - catch (CentralRepoException e) { + catch (CentralRepoException | NumberFormatException e) { LOGGER.log(Level.WARNING, "There was an error in converting central repo postgres settings", e); } } @@ -94,7 +63,7 @@ public class CentralRepoPostgresSettingsUtil { * an action that potentially throws an exception */ private interface TryHandler { - void operation() throws CentralRepoException; + void operation() throws CentralRepoException, NumberFormatException; } @@ -109,14 +78,14 @@ public class CentralRepoPostgresSettingsUtil { return settings; } - logException(() -> settings.setHost(valOrDefault(muConn.getHost(), DEFAULT_HOST))); - logException(() -> settings.setDbName(DEFAULT_DBNAME)); - logException(() -> settings.setUserName(valOrDefault(muConn.getUserName(), DEFAULT_USERNAME))); + logException(() -> settings.setHost(muConn.getHost())); + logException(() -> settings.setDbName(PostgresConnectionSettings.DEFAULT_DBNAME)); + logException(() -> settings.setUserName(muConn.getUserName())); - logException(() -> settings.setPort(valOrDefault(muConn.getPort(), DEFAULT_PORT, 1, 65535))); + logException(() -> settings.setPort(Integer.parseInt(muConn.getPort()))); logException(() -> settings.setBulkThreshold(RdbmsCentralRepo.DEFAULT_BULK_THRESHHOLD)); - logException(() -> settings.setPassword(valOrDefault(muConn.getPassword(), DEFAULT_PASSWORD))); + logException(() -> settings.setPassword(muConn.getPassword())); return settings; } @@ -127,12 +96,12 @@ public class CentralRepoPostgresSettingsUtil { Map keyVals = ModuleSettings.getConfigSettings(MODULE_KEY); - logException(() -> settings.setHost(valOrDefault(keyVals.get(HOST_KEY), DEFAULT_HOST))); - logException(() -> settings.setDbName(valOrDefault(keyVals.get(DBNAME_KEY), DEFAULT_DBNAME))); - logException(() -> settings.setUserName(valOrDefault(keyVals.get(USER_KEY), DEFAULT_USERNAME))); + logException(() -> settings.setHost(keyVals.get(HOST_KEY))); + logException(() -> settings.setDbName(keyVals.get(DBNAME_KEY))); + logException(() -> settings.setUserName(keyVals.get(USER_KEY))); - logException(() -> settings.setPort(valOrDefault(keyVals.get(PORT_KEY), DEFAULT_PORT, 1, 65535))); - logException(() -> settings.setBulkThreshold(valOrDefault(keyVals.get(BULK_THRESHOLD_KEY), RdbmsCentralRepo.DEFAULT_BULK_THRESHHOLD, 1, null))); + logException(() -> settings.setPort(Integer.parseInt(keyVals.get(PORT_KEY)))); + logException(() -> settings.setBulkThreshold(Integer.parseInt(keyVals.get((BULK_THRESHOLD_KEY))))); String passwordHex = keyVals.get(PASSWORD_KEY); String password; @@ -140,11 +109,10 @@ public class CentralRepoPostgresSettingsUtil { password = TextConverter.convertHexTextToText(passwordHex); } catch (TextConverterException ex) { LOGGER.log(Level.WARNING, "Failed to convert password from hex text to text.", ex); - password = DEFAULT_PASSWORD; + password = null; } final String finalPassword = password; - logException(() -> settings.setPassword(finalPassword)); return settings; } diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresConnectionSettings.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresConnectionSettings.java index 5ebdac7735..52b05966c0 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresConnectionSettings.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresConnectionSettings.java @@ -29,13 +29,35 @@ public class PostgresConnectionSettings { private final static String DB_NAMES_REGEX = "[a-z][a-z0-9_]*"; // only lower case private final static String DB_USER_NAMES_REGEX = "[a-zA-Z]\\w*"; - private String host; - private int port; - private String dbName; - private int bulkThreshold; - private String userName; - private String password; + public final static String DEFAULT_HOST = ""; // NON-NLS + public final static int DEFAULT_PORT = 5432; + public final static String DEFAULT_DBNAME = "central_repository"; // NON-NLS + public final static String DEFAULT_USERNAME = ""; + public final static String DEFAULT_PASSWORD = ""; + + private static void validateStr(String s, String errMessage) throws CentralRepoException { + if (null == s || s.isEmpty()) + throw new CentralRepoException(errMessage); + } + + private static void validateRegex(String s, String pattern, String errMessage) throws CentralRepoException { + if (!Pattern.matches(pattern, s)) + throw new CentralRepoException(errMessage); + } + + private static void validateNum(int num, Integer min, Integer max, String errMessage) throws CentralRepoException { + if ((min != null && num < min) || (max != null && num > max)) + throw new CentralRepoException(errMessage); + } + + private String host = DEFAULT_HOST; + private int port = DEFAULT_PORT; + private String dbName = DEFAULT_DBNAME; + private int bulkThreshold = RdbmsCentralRepo.DEFAULT_BULK_THRESHHOLD; + private String userName = DEFAULT_USERNAME; + private String password = DEFAULT_PASSWORD; + public String getHost() { return host; } @@ -60,23 +82,7 @@ public class PostgresConnectionSettings { return password; } - - private static void validateStr(String s, String errMessage) throws CentralRepoException { - if (null == s || s.isEmpty()) - throw new CentralRepoException(errMessage); - } - - private static void validateRegex(String s, String pattern, String errMessage) throws CentralRepoException { - if (!Pattern.matches(pattern, s)) - throw new CentralRepoException(errMessage); - } - - private static void validateNum(int num, Integer min, Integer max, String errMessage) throws CentralRepoException { - if ((min != null && num < min) || (max != null && num > max)) - throw new CentralRepoException(errMessage); - } - - + /** * @param host the host to set */ From 1d58cdcccbf94bf9ab8d24185ef23e9c73aa52ab Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Mon, 9 Mar 2020 08:11:28 -0400 Subject: [PATCH 027/100] revert abstract file node --- .../sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java index 1d53e46ca6..a60964aa19 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java @@ -105,7 +105,7 @@ public abstract class AbstractAbstractFileNode extends A this.content.getName(), this.content.getId()), ex); } - if (TextTranslationService.getInstance().hasProvider() && UserPreferences.displayTranslatedFileNames()) { + if (UserPreferences.displayTranslatedFileNames()) { backgroundTasksPool.submit(new TranslationTask( new WeakReference<>(this), weakPcl)); } @@ -331,7 +331,7 @@ public abstract class AbstractAbstractFileNode extends A * background task that promises to update these values. */ - if (TextTranslationService.getInstance().hasProvider() && UserPreferences.displayTranslatedFileNames()) { + if (UserPreferences.displayTranslatedFileNames()) { properties.add(new NodeProperty<>(ORIGINAL_NAME.toString(), ORIGINAL_NAME.toString(), NO_DESCR, "")); } From 0e8fcc9a17f250d6d37c5b1f3f5fc459374363a6 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Mon, 9 Mar 2020 08:33:26 -0400 Subject: [PATCH 028/100] addressed codacy issues --- .../CentralRepoPostgresSettingsUtil.java | 19 ++++++++++---- .../datamodel/PostgresSettingsLoader.java | 11 +++++--- .../optionspanel/EamDbSettingsDialog.java | 25 ++++++++++++------- 3 files changed, 37 insertions(+), 18 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoPostgresSettingsUtil.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoPostgresSettingsUtil.java index 7e24ef6fad..2c2a07fb24 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoPostgresSettingsUtil.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoPostgresSettingsUtil.java @@ -48,9 +48,18 @@ public class CentralRepoPostgresSettingsUtil { private static final String MODULE_KEY = "CentralRepository"; + private static CentralRepoPostgresSettingsUtil instance = null; + public static CentralRepoPostgresSettingsUtil getInstance() { + if (instance == null) + instance = new CentralRepoPostgresSettingsUtil(); + + return instance; + } - private static void logException(TryHandler handler) { + private CentralRepoPostgresSettingsUtil() {} + + private void logException(TryHandler handler) { try { handler.operation(); } @@ -67,7 +76,7 @@ public class CentralRepoPostgresSettingsUtil { } - public static PostgresConnectionSettings loadMultiUserSettings() { + public PostgresConnectionSettings loadMultiUserSettings() { PostgresConnectionSettings settings = new PostgresConnectionSettings(); CaseDbConnectionInfo muConn; @@ -91,7 +100,7 @@ public class CentralRepoPostgresSettingsUtil { } - public static PostgresConnectionSettings loadCustomSettings() { + public PostgresConnectionSettings loadCustomSettings() { PostgresConnectionSettings settings = new PostgresConnectionSettings(); Map keyVals = ModuleSettings.getConfigSettings(MODULE_KEY); @@ -117,7 +126,7 @@ public class CentralRepoPostgresSettingsUtil { return settings; } - public static void saveCustomSettings(PostgresConnectionSettings settings) { + public void saveCustomSettings(PostgresConnectionSettings settings) { Map map = new HashMap(); map.put(HOST_KEY, settings.getHost()); map.put(PORT_KEY, Integer.toString(settings.getPort())); @@ -138,7 +147,7 @@ public class CentralRepoPostgresSettingsUtil { * @param settings the in-memory object * @return whether or not settings parameter differs from saved custom settings */ - public static boolean areCustomSettingsChanged(PostgresConnectionSettings settings) { + public boolean areCustomSettingsChanged(PostgresConnectionSettings settings) { PostgresConnectionSettings saved = loadCustomSettings(); return saved.equals(settings); } diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresSettingsLoader.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresSettingsLoader.java index 611cf25f2d..08c7359e75 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresSettingsLoader.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresSettingsLoader.java @@ -27,6 +27,8 @@ public interface PostgresSettingsLoader { PostgresSettingsLoader CUSTOM_SETTINGS_LOADER = new Custom(); PostgresSettingsLoader MULTIUSER_SETTINGS_LOADER = new MultiUser(); + + static final CentralRepoPostgresSettingsUtil SETTINGS_UTIL = CentralRepoPostgresSettingsUtil.getInstance(); /** @@ -35,12 +37,12 @@ public interface PostgresSettingsLoader { class Custom implements PostgresSettingsLoader { @Override public PostgresConnectionSettings loadSettings() { - return CentralRepoPostgresSettingsUtil.loadCustomSettings(); + return SETTINGS_UTIL.loadCustomSettings(); } @Override public void saveSettings(PostgresConnectionSettings settings) { - CentralRepoPostgresSettingsUtil.saveCustomSettings(settings); + SETTINGS_UTIL.saveCustomSettings(settings); } } @@ -53,11 +55,12 @@ public interface PostgresSettingsLoader { @Override public PostgresConnectionSettings loadSettings() { - return CentralRepoPostgresSettingsUtil.loadMultiUserSettings(); + return SETTINGS_UTIL.loadMultiUserSettings(); } /** - * no need to save since this is just a proxy to multi user settings + * NOTE: this action does not do anything. There is no need to save since + * this is just a proxy to multi user settings. * @param settings the settings to save */ @Override diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java index 7474f3618a..3eb1f4d824 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java @@ -185,21 +185,28 @@ public class EamDbSettingsDialog extends JDialog { Bundle.EamDbSettingsDialog_okButton_createDbDialog_message(), Bundle.EamDbSettingsDialog_okButton_createDbDialog_title(), JOptionPane.YES_NO_OPTION)) { - try { - manager.createDb(); - } - catch (CentralRepoException e) { - onPromptStatusError(manager); - } - - if (dialog != null) - dialog.valid(); + onUserPromptCreateDb(manager, dialog); } } return (manager.getStatus() == DatabaseTestResult.TESTED_OK); } + /** + * when a new database needs to be created on user selecting cr, this code will be ran when user selects create cr + * @param manager the manager handling the database creation + * @param dialog the dialog that prompted database creation + */ + private static void onUserPromptCreateDb(CentralRepoDbManager manager, EamDbSettingsDialog dialog) { + try { + manager.createDb(); + } catch (CentralRepoException e) { + onPromptStatusError(manager); + } + if (dialog != null) + dialog.valid(); + } + /** * when an error occurs while going through promptTestStatusWarning, this method is called From 50c7ddb1a646a4efaae2383e2bd13fb540288799 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Mon, 9 Mar 2020 08:35:45 -0400 Subject: [PATCH 029/100] addressed codacy issues --- .../centralrepository/datamodel/CentralRepoDbManager.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java index 20309fca7b..e404758e40 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java @@ -43,10 +43,10 @@ public class CentralRepoDbManager { * Save the selected platform to the config file. */ public static synchronized CentralRepoDbChoice saveDbChoice(CentralRepoDbChoice choice) { - choice = (choice == null) ? CentralRepoDbChoice.DISABLED : choice; - savedChoice = choice; - ModuleSettings.setConfigSetting("CentralRepository", "db.selectedPlatform", choice.getSettingKey()); - return choice; + CentralRepoDbChoice newChoice = (choice == null) ? CentralRepoDbChoice.DISABLED : choice; + savedChoice = newChoice; + ModuleSettings.setConfigSetting("CentralRepository", "db.selectedPlatform", newChoice.getSettingKey()); + return newChoice; } /** From c63bfaf72ee4899a705d53485eedcfc2ecb5f3a0 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Mon, 9 Mar 2020 10:22:51 -0400 Subject: [PATCH 030/100] add property change listener --- .../datamodel/CentralRepoDbManager.java | 26 ++++++++++++++++- .../optionspanel/GlobalSettingsPanel.java | 29 ++----------------- 2 files changed, 28 insertions(+), 27 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java index e404758e40..bb9802b3cc 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java @@ -18,6 +18,8 @@ */ package org.sleuthkit.autopsy.centralrepository.datamodel; +import java.beans.PropertyChangeListener; +import java.beans.PropertyChangeSupport; import java.io.File; import java.sql.SQLException; import java.util.logging.Level; @@ -38,17 +40,39 @@ public class CentralRepoDbManager { private static volatile CentralRepoDbChoice savedChoice = null; - + + private static final PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(CentralRepoDbManager.class); + /** * Save the selected platform to the config file. */ public static synchronized CentralRepoDbChoice saveDbChoice(CentralRepoDbChoice choice) { CentralRepoDbChoice newChoice = (choice == null) ? CentralRepoDbChoice.DISABLED : choice; + CentralRepoDbChoice oldChoice = savedChoice; savedChoice = newChoice; ModuleSettings.setConfigSetting("CentralRepository", "db.selectedPlatform", newChoice.getSettingKey()); + propertyChangeSupport.firePropertyChange("savedChoice", oldChoice, newChoice); return newChoice; } + /** + * adds a property change listener + * NOTE: currently only listening for changes in currently saved db choice + * + * @param listener the listener for the event + */ + public static void addPropertyChangeListener(PropertyChangeListener listener) { + propertyChangeSupport.addPropertyChangeListener(listener); + } + + /** + * removes a propert change listener + * @param listener the listener to remove + */ + public static void removePropertyChangeListener(PropertyChangeListener listener) { + propertyChangeSupport.removePropertyChangeListener(listener); + } + /** * Load the selectedPlatform boolean from the config file, if it is set. */ diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java index 0becdf59f8..24a2431764 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java @@ -50,25 +50,6 @@ import java.util.logging.Level; */ @SuppressWarnings("PMD.SingularField") // UI widgets cause lots of false positives public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel implements OptionsPanel { - - /** - * listener to handle when settings change and an instance of this class needs to be notified. - */ - private interface OnSettingsChangeListener { - void onSettingsChange(); - } - - private static OnSettingsChangeListener listener = null; - - private static void onSettingsChange() { - if (listener != null) - listener.onSettingsChange(); - } - - private static void setSettingsChangeListener(OnSettingsChangeListener newListener) { - listener = newListener; - } - private static final long serialVersionUID = 1L; private static final Logger logger = Logger.getLogger(GlobalSettingsPanel.class.getName()); @@ -83,8 +64,8 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i public GlobalSettingsPanel() { ingestJobEventListener = new IngestJobEventPropertyChangeListener(); - // most recently created panel will receive update events - GlobalSettingsPanel.setSettingsChangeListener(() -> ingestStateUpdated(Case.isCaseOpen())); + // listen for change events in currently saved choice + CentralRepoDbManager.addPropertyChangeListener((PropertyChangeEvent evt) -> ingestStateUpdated(Case.isCaseOpen())); initComponents(); customizeComponents(); addIngestJobEventsListener(); @@ -222,8 +203,6 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i else if (JOptionPane.NO_OPTION == result) { invokeCrChoice(parent, CentralRepoDbChoice.POSTGRESQL_CUSTOM); } - - GlobalSettingsPanel.onSettingsChange(); } @@ -231,14 +210,12 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i SwingUtilities.invokeLater(() -> { boolean successful = EamDbSettingsDialog.testStatusAndCreate(parent, new CentralRepoDbManager()); if (successful) { - updateDatabase(parent); - onSettingsChange(); + updateDatabase(parent); } else { // disable central repository CentralRepoDbUtil.setUseCentralRepo(false); CentralRepoDbManager.saveDbChoice(CentralRepoDbChoice.DISABLED); - GlobalSettingsPanel.onSettingsChange(); } }); } From e842893a322a960bfc751423a8963cf6c4fa3c18 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Mon, 9 Mar 2020 13:20:01 -0400 Subject: [PATCH 031/100] codacy comments improvement --- .../datamodel/CentralRepoPostgresSettingsUtil.java | 2 +- .../centralrepository/datamodel/PostgresSettingsLoader.java | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoPostgresSettingsUtil.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoPostgresSettingsUtil.java index 2c2a07fb24..a932bcd187 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoPostgresSettingsUtil.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoPostgresSettingsUtil.java @@ -50,7 +50,7 @@ public class CentralRepoPostgresSettingsUtil { private static CentralRepoPostgresSettingsUtil instance = null; - public static CentralRepoPostgresSettingsUtil getInstance() { + public static synchronized CentralRepoPostgresSettingsUtil getInstance() { if (instance == null) instance = new CentralRepoPostgresSettingsUtil(); diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresSettingsLoader.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresSettingsLoader.java index 08c7359e75..4b0ab1895f 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresSettingsLoader.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresSettingsLoader.java @@ -27,8 +27,7 @@ public interface PostgresSettingsLoader { PostgresSettingsLoader CUSTOM_SETTINGS_LOADER = new Custom(); PostgresSettingsLoader MULTIUSER_SETTINGS_LOADER = new MultiUser(); - - static final CentralRepoPostgresSettingsUtil SETTINGS_UTIL = CentralRepoPostgresSettingsUtil.getInstance(); + CentralRepoPostgresSettingsUtil SETTINGS_UTIL = CentralRepoPostgresSettingsUtil.getInstance(); /** From e85968b897ea81340d8f4796a5f31e0d7cce89d8 Mon Sep 17 00:00:00 2001 From: Raman Arora Date: Mon, 9 Mar 2020 15:17:35 -0400 Subject: [PATCH 032/100] 6015: Upgrade existing central repositories to reflect accounts schema --- .../datamodel/CentralRepoDbUpgrader.java | 43 +++++++ .../CentralRepoDbUpgrader13To14.java | 114 ++++++++++++++++++ .../datamodel/CentralRepoDbUtil.java | 22 ++++ .../datamodel/RdbmsCentralRepo.java | 6 +- .../datamodel/RdbmsCentralRepoFactory.java | 35 +++++- 5 files changed, 216 insertions(+), 4 deletions(-) create mode 100644 Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbUpgrader.java create mode 100644 Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbUpgrader13To14.java diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbUpgrader.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbUpgrader.java new file mode 100644 index 0000000000..c461b841db --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbUpgrader.java @@ -0,0 +1,43 @@ +/* + * Central Repository + * + * Copyright 2020 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.centralrepository.datamodel; + +import java.sql.Connection; +import java.sql.SQLException; +import org.sleuthkit.datamodel.CaseDbSchemaVersionNumber; + +/** + * Common interface to upgrade central repository database schema + */ +public interface CentralRepoDbUpgrader { + + /** + * Updates the Central Repository schema using the given open connection. + * + * @param dbSchemaVersion Current schema version. + * @param connection Connection to use for upgrade + * + * @return New schema version. + * + * @throws CentralRepoException If there is an error in upgrade. + * @throws SQLException in case of any SQL errors. + */ + CaseDbSchemaVersionNumber upgradeSchema(CaseDbSchemaVersionNumber dbSchemaVersion, Connection connection) throws CentralRepoException, SQLException; + +} diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbUpgrader13To14.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbUpgrader13To14.java new file mode 100644 index 0000000000..b8eedacac4 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbUpgrader13To14.java @@ -0,0 +1,114 @@ +/* + * Central Repository + * + * Copyright 2020 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.centralrepository.datamodel; + +import java.sql.Connection; +import java.sql.SQLException; +import java.sql.Statement; +import org.sleuthkit.datamodel.CaseDbSchemaVersionNumber; + + +/** + * This class updates CR schema to 1.4 + * + * New correlation types for accounts are added, as well as some accounts related new tables are added in this version. + * + */ +public class CentralRepoDbUpgrader13To14 implements CentralRepoDbUpgrader { + + @Override + public CaseDbSchemaVersionNumber upgradeSchema(CaseDbSchemaVersionNumber dbSchemaVersion, Connection connection) throws CentralRepoException, SQLException { + + if (dbSchemaVersion.compareTo(new CaseDbSchemaVersionNumber(1, 4)) < 0) { + + try (Statement statement = connection.createStatement();) { + + CentralRepoPlatforms selectedPlatform = CentralRepoPlatforms.getSelectedPlatform(); + + // Create account_types and accounts tables which are referred by X_instances tables + statement.execute(RdbmsCentralRepoFactory.getCreateAccountTypesTableStatement(selectedPlatform)); + statement.execute(RdbmsCentralRepoFactory.getCreateAccountsTableStatement(selectedPlatform)); + + for (CorrelationAttributeInstance.Type type : CorrelationAttributeInstance.getDefaultCorrelationTypes()) { + String instance_type_dbname = CentralRepoDbUtil.correlationTypeToInstanceTableName(type); + + if (type.getId() >= CorrelationAttributeInstance.ADDITIONAL_TYPES_BASE_ID) { + + // these are new Correlation types - new tables need to be created + statement.execute(String.format(RdbmsCentralRepoFactory.getCreateArtifactInstancesTableTemplate(selectedPlatform), instance_type_dbname, instance_type_dbname)); + statement.execute(String.format(RdbmsCentralRepoFactory.getAddCaseIdIndexTemplate(), instance_type_dbname, instance_type_dbname)); + statement.execute(String.format(RdbmsCentralRepoFactory.getAddDataSourceIdIndexTemplate(), instance_type_dbname, instance_type_dbname)); + statement.execute(String.format(RdbmsCentralRepoFactory.getAddValueIndexTemplate(), instance_type_dbname, instance_type_dbname)); + statement.execute(String.format(RdbmsCentralRepoFactory.getAddKnownStatusIndexTemplate(), instance_type_dbname, instance_type_dbname)); + statement.execute(String.format(RdbmsCentralRepoFactory.getAddObjectIdIndexTemplate(), instance_type_dbname, instance_type_dbname)); + + // add new correlation type + CentralRepoDbUtil.insertCorrelationType(connection, type); + + } else { + + // Alter the existing X_Instance tables to add account_id column + String sqlStr = String.format(getAlterArtifactInstancesAddAccountIdTemplate(selectedPlatform), instance_type_dbname); + statement.execute(sqlStr); + + // SQLite does NOT allow adding a constraint with Alter Table statement. + if (selectedPlatform == CentralRepoPlatforms.POSTGRESQL) { + sqlStr = String.format(getAlterArtifactInstancesAddAccountIdConstraintTemplate(), instance_type_dbname); + statement.execute(sqlStr); + } + } + } + + // insert default data + RdbmsCentralRepoFactory.insertDefaultAccountsTablesContent(connection, selectedPlatform); + } + } + + return new CaseDbSchemaVersionNumber(1, 4); + } + + /** + * Returns ALTER TABLE SQL string template to add an account_id column to a + * TYPE_instances table. + * + * @param selectedPlatform + * + * @return SQL string template to alter the table. + */ + static String getAlterArtifactInstancesAddAccountIdTemplate(CentralRepoPlatforms selectedPlatform) { + // Each "%s" will be replaced with the relevant TYPE_instances table name. + return "ALTER TABLE %s" + + " ADD account_id " + RdbmsCentralRepoFactory.getBigIntType(selectedPlatform) + " DEFAULT NULL"; + + } + + /** + * Returns ALTER TABLE SQL string template to add a Foreign Key constraint + * to a TYPE_instances table. + * + * @return SQL string template to alter the table. + */ + static String getAlterArtifactInstancesAddAccountIdConstraintTemplate() { + // Each "%s" will be replaced with the relevant TYPE_instances table name. + return "ALTER TABLE %s" + + " ADD CONSTRAINT account_id_fk foreign key (account_id) references accounts(id)"; + } + + +} diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbUtil.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbUtil.java index 60701b44e5..826c315c02 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbUtil.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbUtil.java @@ -123,6 +123,28 @@ public class CentralRepoDbUtil { return true; } + /** + * Inserts the specified correlation type into the database. + * + * @param conn Open connection to use. + * @param correlationType New correlation type to add. + * + */ + public static void insertCorrelationType(Connection conn, CorrelationAttributeInstance.Type correlationType) throws SQLException { + + String sql = "INSERT INTO correlation_types(id, display_name, db_table_name, supported, enabled) VALUES (?, ?, ?, ?, ?)"; + try (PreparedStatement preparedStatement = conn.prepareStatement(sql)) { + + preparedStatement.setInt(1, correlationType.getId()); + preparedStatement.setString(2, correlationType.getDisplayName()); + preparedStatement.setString(3, correlationType.getDbTableName()); + preparedStatement.setInt(4, correlationType.isSupported() ? 1 : 0); + preparedStatement.setInt(5, correlationType.isEnabled() ? 1 : 0); + + preparedStatement.execute(); + } + } + /** * Writes the current schema version into the database. * diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/RdbmsCentralRepo.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/RdbmsCentralRepo.java index 93f6268979..752eb1dfe4 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/RdbmsCentralRepo.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/RdbmsCentralRepo.java @@ -65,7 +65,7 @@ abstract class RdbmsCentralRepo implements CentralRepository { static final String SCHEMA_MINOR_VERSION_KEY = "SCHEMA_MINOR_VERSION"; static final String CREATION_SCHEMA_MAJOR_VERSION_KEY = "CREATION_SCHEMA_MAJOR_VERSION"; static final String CREATION_SCHEMA_MINOR_VERSION_KEY = "CREATION_SCHEMA_MINOR_VERSION"; - static final CaseDbSchemaVersionNumber SOFTWARE_CR_DB_SCHEMA_VERSION = new CaseDbSchemaVersionNumber(1, 3); + static final CaseDbSchemaVersionNumber SOFTWARE_CR_DB_SCHEMA_VERSION = new CaseDbSchemaVersionNumber(1, 4); protected final List defaultCorrelationTypes; @@ -3808,6 +3808,10 @@ abstract class RdbmsCentralRepo implements CentralRepository { throw new CentralRepoException("Currently selected database platform \"" + selectedPlatform.name() + "\" can not be upgraded.", Bundle.AbstractSqlEamDb_cannotUpgrage_message(selectedPlatform.name())); } } + + // Upgrade to 1.4 + CaseDbSchemaVersionNumber newVer = new CentralRepoDbUpgrader13To14().upgradeSchema(dbSchemaVersion, conn); + updateSchemaVersion(conn); conn.commit(); logger.log(Level.INFO, String.format("Central Repository schema updated to version %s", SOFTWARE_CR_DB_SCHEMA_VERSION)); diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/RdbmsCentralRepoFactory.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/RdbmsCentralRepoFactory.java index 66227ea366..06d9c6d1b3 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/RdbmsCentralRepoFactory.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/RdbmsCentralRepoFactory.java @@ -532,7 +532,7 @@ public class RdbmsCentralRepoFactory { * * @return SQL clause. */ - private static String getBigIntType(CentralRepoPlatforms selectedPlatform) { + static String getBigIntType(CentralRepoPlatforms selectedPlatform) { switch (selectedPlatform) { case POSTGRESQL: return " BIGINT "; @@ -800,7 +800,7 @@ public class RdbmsCentralRepoFactory { * * @return True if success, false otherwise. */ - private boolean insertDefaultPersonaTablesContent(Connection conn) { + private static boolean insertDefaultPersonaTablesContent(Connection conn, CentralRepoPlatforms selectedPlatform) { try (Statement stmt = conn.createStatement()) { // populate the confidence table @@ -825,6 +825,35 @@ public class RdbmsCentralRepoFactory { return true; } + /** + * Inserts the default content in accounts related tables. + * + * @param conn Database connection to use. + * + * @return True if success, false otherwise. + */ + static boolean insertDefaultAccountsTablesContent(Connection conn, CentralRepoPlatforms selectedPlatform) { + + try (Statement stmt = conn.createStatement();) { + + // Populate the account_types table + for (Account.Type type : Account.Type.PREDEFINED_ACCOUNT_TYPES) { + int correlationTypeId = getCorrelationTypeIdForAccountType(conn, type); + if (correlationTypeId > 0) { + String sqlString = String.format("INSERT INTO account_types (type_name, display_name, correlation_type_id) VALUES ('%s', '%s', %d)" + getOnConflictDoNothingClause(selectedPlatform), + type.getTypeName(), type.getDisplayName(), correlationTypeId); + stmt.execute(sqlString); + } + } + + } catch (SQLException ex) { + LOGGER.log(Level.SEVERE, String.format("Failed to populate default data in Persona tables."), ex); + return false; + } + + return true; + } + /** * Returns the correlation type id for the given account type, * from the correlation_types table. @@ -834,7 +863,7 @@ public class RdbmsCentralRepoFactory { * ' * @return correlation type id. */ - private int getCorrelationTypeIdForAccountType(Connection conn, Account.Type accountType) { + static int getCorrelationTypeIdForAccountType(Connection conn, Account.Type accountType) { int typeId = -1; if (accountType == Account.Type.EMAIL) { From b6957fe2bcb1ac3736bc1823a6624c0e42829125 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Tue, 10 Mar 2020 17:25:21 -0400 Subject: [PATCH 033/100] fixes to capture disabled due to failure and validity checks on re-enable --- .../datamodel/CentralRepoDbManager.java | 77 ++++++++++++++----- .../optionspanel/Bundle.properties-MERGED | 8 +- .../optionspanel/EamDbSettingsDialog.java | 5 +- .../optionspanel/GlobalSettingsPanel.java | 28 +++++-- 4 files changed, 89 insertions(+), 29 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java index bb9802b3cc..4008f609b3 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java @@ -36,23 +36,69 @@ public class CentralRepoDbManager { private static final Logger logger = Logger.getLogger(CentralRepoDbManager.class.getName()); private static final String CENTRAL_REPO_DB_NAME = "central_repository"; - - + private static final String CENTRAL_REPOSITORY_SETTINGS_KEY = "CentralRepository"; + private static final String DB_SELECTED_PLATFORM_KEY = "db.selectedPlatform"; + private static final String DISABLED_DUE_TO_FAILURE_KEY = "disabledDueToFailure"; private static volatile CentralRepoDbChoice savedChoice = null; private static final PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(CentralRepoDbManager.class); + private static final Object dbChoiceLock = new Object(); + private static final Object disabledDueToFailureLock = new Object(); + /** * Save the selected platform to the config file. */ - public static synchronized CentralRepoDbChoice saveDbChoice(CentralRepoDbChoice choice) { - CentralRepoDbChoice newChoice = (choice == null) ? CentralRepoDbChoice.DISABLED : choice; - CentralRepoDbChoice oldChoice = savedChoice; - savedChoice = newChoice; - ModuleSettings.setConfigSetting("CentralRepository", "db.selectedPlatform", newChoice.getSettingKey()); - propertyChangeSupport.firePropertyChange("savedChoice", oldChoice, newChoice); - return newChoice; + public static CentralRepoDbChoice saveDbChoice(CentralRepoDbChoice choice) { + synchronized(dbChoiceLock) { + CentralRepoDbChoice newChoice = (choice == null) ? CentralRepoDbChoice.DISABLED : choice; + CentralRepoDbChoice oldChoice = savedChoice; + savedChoice = newChoice; + ModuleSettings.setConfigSetting(CENTRAL_REPOSITORY_SETTINGS_KEY, DB_SELECTED_PLATFORM_KEY, newChoice.getSettingKey()); + propertyChangeSupport.firePropertyChange("savedChoice", oldChoice, newChoice); + return newChoice; + } + + } + + + /** + * Load the selectedPlatform boolean from the config file, if it is set. + */ + public static CentralRepoDbChoice getSavedDbChoice() { + synchronized(dbChoiceLock) { + if (savedChoice == null) { + String selectedPlatformString = ModuleSettings.getConfigSetting(CENTRAL_REPOSITORY_SETTINGS_KEY, DB_SELECTED_PLATFORM_KEY); // NON-NLS + savedChoice = fromKey(selectedPlatformString); + } + + return savedChoice; + } + } + + /** + * set whether or not the repository has been disabled due to a database setup issue; + * this is used when re-enabling multi-user as a flag to determine whether or not CR should be re-enabled + * + * @param disabledDueToFailure whether or not the repository has been disabled due to a database setup issue + */ + public static void setDisabledDueToFailure(boolean disabledDueToFailure) { + synchronized(disabledDueToFailureLock) { + ModuleSettings.setConfigSetting(CENTRAL_REPOSITORY_SETTINGS_KEY, DISABLED_DUE_TO_FAILURE_KEY, Boolean.toString(disabledDueToFailure)); + } + } + + /** + * retrieves setting whether or not the repository has been disabled due to a database setup issue; + * this is used when re-enabling multi-user as a flag to determine whether or not CR should be re-enabled + * + * @return whether or not the repository has been disabled due to a database setup issue + */ + public static boolean isDisabledDueToFailure() { + synchronized(disabledDueToFailureLock) { + return Boolean.toString(true).equals(ModuleSettings.getConfigSetting(CENTRAL_REPOSITORY_SETTINGS_KEY, DISABLED_DUE_TO_FAILURE_KEY)); + } } /** @@ -72,18 +118,7 @@ public class CentralRepoDbManager { public static void removePropertyChangeListener(PropertyChangeListener listener) { propertyChangeSupport.removePropertyChangeListener(listener); } - - /** - * Load the selectedPlatform boolean from the config file, if it is set. - */ - public static synchronized CentralRepoDbChoice getSavedDbChoice() { - if (savedChoice == null) { - String selectedPlatformString = ModuleSettings.getConfigSetting("CentralRepository", "db.selectedPlatform"); // NON-NLS - savedChoice = fromKey(selectedPlatformString); - } - return savedChoice; - } private static CentralRepoDbChoice fromKey(String keyName) { @@ -214,6 +249,8 @@ public class CentralRepoDbManager { } } + + private DatabaseTestResult testingStatus; private CentralRepoDbChoice selectedDbChoice; diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/Bundle.properties-MERGED index 7277910e7d..9ea90a452a 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/Bundle.properties-MERGED @@ -19,7 +19,7 @@ EamDbSettingsDialog.okButton.createDbDialog.title=Database Does Not Exist EamDbSettingsDialog.okButton.createDbError.title=Unable to Create Database EamDbSettingsDialog.okButton.createPostgresDbError.message=Unable to create Postgres Database, please ensure address, port, and login credentials are correct for Postgres server and try again. EamDbSettingsDialog.okButton.createSQLiteDbError.message=Unable to create SQLite Database, please ensure location exists and you have write permissions and try again. -EamDbSettingsDialog.okButton.databaseConnectionFailed.message=Unable to connect to database please check your settings and try again. +EamDbSettingsDialog.okButton.databaseConnectionFailed.message=Unable to connect to database. Please check your settings and try again. EamDbSettingsDialog.okButton.databaseConnectionFailed.title=Database Connection Failed EamDbSettingsDialog.okButton.errorMsg.text=Please restart Autopsy to begin using the new database platform. EamDbSettingsDialog.okButton.errorTitle.text=Restart Required. @@ -33,6 +33,12 @@ EamDbSettingsDialog.validation.finished=Click OK to save your database settings EamDbSettingsDialog.validation.incompleteFields=Fill in all values for the selected database. EamOptionsController.moduleErr=Error processing value changes. EamOptionsController.moduleErr.msg=Value change processing failed. +GlobalSettingsPanel.onMultiUserChange.disabledMu.description=The Central Repository will be reconfigured to use a local SQLite database. +GlobalSettingsPanel.onMultiUserChange.disabledMu.description2=Press Configure PostgreSQL to change to a PostgreSQL database. +GlobalSettingsPanel.onMultiUserChange.disabledMu.title=Central Repository Change Necessary +GlobalSettingsPanel.onMultiUserChange.enable.description=Do you want to update the Central Repository to use this PostgreSQL database? +GlobalSettingsPanel.onMultiUserChange.enable.description2=The Central Repository stores hash values and accounts from past cases. +GlobalSettingsPanel.onMultiUserChange.enable.title=Use with Central Repository? GlobalSettingsPanel.updateFailed.title=Central repository disabled GlobalSettingsPanel.validationErrMsg.ingestRunning=You cannot change settings while ingest is running. GlobalSettingsPanel.validationerrMsg.mustConfigure=Configure the database to enable this module. diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java index 3eb1f4d824..de06d6c9ab 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java @@ -163,7 +163,7 @@ public class EamDbSettingsDialog extends JDialog { "EamDbSettingsDialog.okButton.createDbDialog.title=Database Does Not Exist", "EamDbSettingsDialog.okButton.createDbDialog.message=Database does not exist, would you like to create it?", "EamDbSettingsDialog.okButton.databaseConnectionFailed.title=Database Connection Failed", - "EamDbSettingsDialog.okButton.databaseConnectionFailed.message=Unable to connect to database please check your settings and try again.", + "EamDbSettingsDialog.okButton.databaseConnectionFailed.message=Unable to connect to database. Please check your settings and try again.", "EamDbSettingsDialog.okButton.createSQLiteDbError.message=Unable to create SQLite Database, please ensure location exists and you have write permissions and try again.", "EamDbSettingsDialog.okButton.createPostgresDbError.message=Unable to create Postgres Database, please ensure address, port, and login credentials are correct for Postgres server and try again.", "EamDbSettingsDialog.okButton.createDbError.title=Unable to Create Database"}) @@ -566,6 +566,9 @@ public class EamDbSettingsDialog extends JDialog { Bundle.EamDbSettingsDialog_okButton_errorTitle_text(), JOptionPane.WARNING_MESSAGE); }); + + parent.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); + return false; } parent.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java index 24a2431764..4d9d453f36 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java @@ -44,6 +44,7 @@ import org.sleuthkit.autopsy.centralrepository.datamodel.PostgresCentralRepoSett import org.sleuthkit.autopsy.centralrepository.datamodel.SqliteCentralRepoSettings; import java.awt.Component; import java.util.logging.Level; +import org.sleuthkit.autopsy.core.UserPreferences; /** * Main settings panel for the Central Repository @@ -125,8 +126,9 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i "GlobalSettingsPanel.onMultiUserChange.enable.description2=The Central Repository stores hash values and accounts from past cases." }) public static void onMultiUserChange(Component parent, boolean muPreviouslySelected, boolean muCurrentlySelected) { - boolean crMultiUser = CentralRepoDbUtil.allowUseOfCentralRepository() && - CentralRepoDbManager.getSavedDbChoice() == CentralRepoDbChoice.POSTGRESQL_MULTIUSER; + boolean crEnabled = CentralRepoDbUtil.allowUseOfCentralRepository(); + boolean crMultiUser = CentralRepoDbManager.getSavedDbChoice() == CentralRepoDbChoice.POSTGRESQL_MULTIUSER; + boolean crDisabledDueToFailure = CentralRepoDbManager.isDisabledDueToFailure(); if (!muPreviouslySelected && muCurrentlySelected) { SwingUtilities.invokeLater(() -> { @@ -148,14 +150,16 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i }); } // moving from selected to not selected && 'PostgreSQL using multi-user settings' is selected - else if (muPreviouslySelected && !muCurrentlySelected && crMultiUser) { + else if (muPreviouslySelected && !muCurrentlySelected && crEnabled && crMultiUser) { SwingUtilities.invokeLater(() -> { askForCentralRepoDbChoice(parent); }); } - // changing multi-user settings connection && 'PostgreSQL using multi-user settings' is selected - else if (muPreviouslySelected && muCurrentlySelected && crMultiUser) { + // changing multi-user settings connection && 'PostgreSQL using multi-user settings' is selected && + // central repo either enabled or was disabled due to error + else if (muPreviouslySelected && muCurrentlySelected && crMultiUser && (crEnabled || crDisabledDueToFailure)) { // test databse for CR change + CentralRepoDbUtil.setUseCentralRepo(true); handleDbChange(parent); } } @@ -210,12 +214,14 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i SwingUtilities.invokeLater(() -> { boolean successful = EamDbSettingsDialog.testStatusAndCreate(parent, new CentralRepoDbManager()); if (successful) { + // clear any error if there was one + CentralRepoDbManager.setDisabledDueToFailure(false); updateDatabase(parent); } else { - // disable central repository + // disable central repository due to error + CentralRepoDbManager.setDisabledDueToFailure(true); CentralRepoDbUtil.setUseCentralRepo(false); - CentralRepoDbManager.saveDbChoice(CentralRepoDbChoice.DISABLED); } }); } @@ -632,6 +638,14 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i @Override public void store() { // Click OK or Apply on Options Panel CentralRepoDbUtil.setUseCentralRepo(cbUseCentralRepo.isSelected()); + + // if moving to using CR, multi-user mode is disabled and selection is multiuser settings, set to disabled + if (cbUseCentralRepo.isSelected() && + !UserPreferences.getIsMultiUserModeEnabled() && + CentralRepoDbManager.getSavedDbChoice() == CentralRepoDbChoice.POSTGRESQL_MULTIUSER) { + + CentralRepoDbManager.saveDbChoice(CentralRepoDbChoice.DISABLED); + } } /** From f4cf0cb2689c6bb9518caed18ec8e6ea08b19490 Mon Sep 17 00:00:00 2001 From: Mark McKinnon Date: Tue, 10 Mar 2020 17:35:41 -0400 Subject: [PATCH 034/100] Initial commit Initial commit of multiple contexts in context viewer. --- .../contextviewer/Bundle.properties | 16 +- .../contextviewer/Bundle.properties-MERGED | 17 +- .../contextviewer/ContextSourcePanel.form | 100 ++++++++ .../contextviewer/ContextSourcePanel.java | 169 +++++++++++++ .../contextviewer/ContextUsagePanel.form | 100 ++++++++ .../contextviewer/ContextUsagePanel.java | 183 ++++++++++++++ .../contextviewer/ContextViewer.form | 134 +--------- .../contextviewer/ContextViewer.java | 234 ++++-------------- 8 files changed, 628 insertions(+), 325 deletions(-) create mode 100644 Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextSourcePanel.form create mode 100644 Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextSourcePanel.java create mode 100644 Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextUsagePanel.form create mode 100644 Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextUsagePanel.java diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/Bundle.properties b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/Bundle.properties index 6a74bbcb06..554f364be2 100755 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/Bundle.properties @@ -1,8 +1,8 @@ -ContextViewer.jSourceGoToResultButton.text=Go to Result -ContextViewer.jSourceTextLabel.text=jLabel2 -ContextViewer.jSourceNameLabel.text=jSourceNameLabel -ContextViewer.jSourceLabel.text=Source -ContextViewer.jUsageGoToResultButton.text=Go to Result -ContextViewer.jUsageLabel.text=Usage -ContextViewer.jUsageNameLabel.text=jSourceNameLabel -ContextViewer.jUsageTextLabel.text=jLabel2 +ContextUsagePanel.jUsageGoToResultButton.text=Go to Result +ContextSourcePanel.jSourceGoToResultButton.text=Go to Result +ContextSourcePanel.jSourceLabel.text=Source +ContextUsagePanel.jUsageLabel.text=Usage +ContextUsagePanel.jUsageTextLabel.text=Label2 +ContextUsagePanel.jUsageNameLabel.text=jUsageLabel +ContextSourcePanel.jSourceTextLabel.text=Label2 +ContextSourcePanel.jSourceNameLabel.text=jSourceNameLabel diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/Bundle.properties-MERGED index 76df8c7b3c..304d3f6cb2 100755 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/Bundle.properties-MERGED @@ -1,16 +1,16 @@ +ContextUsagePanel.jUsageGoToResultButton.text=Go to Result +ContextSourcePanel.jSourceGoToResultButton.text=Go to Result +ContextSourcePanel.jSourceLabel.text=Source +ContextUsagePanel.jUsageLabel.text=Usage +ContextUsagePanel.jUsageTextLabel.text=Label2 +ContextUsagePanel.jUsageNameLabel.text=jUsageLabel +ContextSourcePanel.jSourceTextLabel.text=Label2 +ContextSourcePanel.jSourceNameLabel.text=jSourceNameLabel ContextViewer.attachmentSource=Attached to: ContextViewer.downloadedOn=On ContextViewer.downloadSource=Downloaded from: ContextViewer.downloadURL=URL ContextViewer.email=Email -ContextViewer.jSourceGoToResultButton.text=Go to Result -ContextViewer.jSourceTextLabel.text=jLabel2 -ContextViewer.jSourceNameLabel.text=jSourceNameLabel -ContextViewer.jSourceLabel.text=Source -ContextViewer.jUsageGoToResultButton.text=Go to Result -ContextViewer.jUsageLabel.text=Usage -ContextViewer.jUsageNameLabel.text=jSourceNameLabel -ContextViewer.jUsageTextLabel.text=jLabel2 ContextViewer.message=Message ContextViewer.messageFrom=From ContextViewer.messageOn=On @@ -20,3 +20,4 @@ ContextViewer.recentDocs=Recent Documents: ContextViewer.title=Context ContextViewer.toolTip=Displays context for selected file. ContextViewer.unknown=Opened at unknown time +ContextViewer.unknownSource=Unknown diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextSourcePanel.form b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextSourcePanel.form new file mode 100644 index 0000000000..14c45e2f50 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextSourcePanel.form @@ -0,0 +1,100 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextSourcePanel.java b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextSourcePanel.java new file mode 100644 index 0000000000..670d2c1347 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextSourcePanel.java @@ -0,0 +1,169 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2019 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.contextviewer; + +import java.util.ArrayList; +import java.util.List; +import org.sleuthkit.autopsy.coreutils.Logger; +import org.sleuthkit.autopsy.directorytree.DirectoryTreeTopComponent; +import org.sleuthkit.datamodel.BlackboardArtifact; +import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_ASSOCIATED_OBJECT; + +/** + * Displays additional context for the selected file, such as its source, and + * usage, if known. + * + */ +public final class ContextSourcePanel extends javax.swing.JPanel { + + private static final long serialVersionUID = 1L; + private static final Logger logger = Logger.getLogger(ContextSourcePanel.class.getName()); + private static final int ARTIFACT_STR_MAX_LEN = 1024; + private static final int ATTRIBUTE_STR_MAX_LEN = 200; + + // defines a list of artifacts that provide context for a file + private static final List SOURCE_CONTEXT_ARTIFACTS = new ArrayList<>(); + static { + SOURCE_CONTEXT_ARTIFACTS.add(TSK_ASSOCIATED_OBJECT); + } + + private BlackboardArtifact sourceContextArtifact; + + /** + * Creates new form ContextViewer + */ + public ContextSourcePanel(String sourceName, String sourceText, BlackboardArtifact associatedArtifact) { + + initComponents(); + sourceContextArtifact = associatedArtifact; + setSourceName(sourceName); + setSourceText(sourceText); + } + + /** + * 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() { + + jSourceGoToResultButton = new javax.swing.JButton(); + jSourceLabel = new javax.swing.JLabel(); + jSourceNameLabel = new javax.swing.JLabel(); + jSourceTextLabel = new javax.swing.JLabel(); + + setBackground(new java.awt.Color(255, 255, 255)); + setPreferredSize(new java.awt.Dimension(495, 120)); + + org.openide.awt.Mnemonics.setLocalizedText(jSourceGoToResultButton, org.openide.util.NbBundle.getMessage(ContextSourcePanel.class, "ContextSourcePanel.jSourceGoToResultButton.text")); // NOI18N + jSourceGoToResultButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jSourceGoToResultButtonActionPerformed(evt); + } + }); + + jSourceLabel.setFont(new java.awt.Font("Dialog", 1, 14)); // NOI18N + org.openide.awt.Mnemonics.setLocalizedText(jSourceLabel, org.openide.util.NbBundle.getMessage(ContextSourcePanel.class, "ContextSourcePanel.jSourceLabel.text")); // NOI18N + + org.openide.awt.Mnemonics.setLocalizedText(jSourceNameLabel, org.openide.util.NbBundle.getMessage(ContextSourcePanel.class, "ContextSourcePanel.jSourceNameLabel.text")); // NOI18N + + org.openide.awt.Mnemonics.setLocalizedText(jSourceTextLabel, org.openide.util.NbBundle.getMessage(ContextSourcePanel.class, "ContextSourcePanel.jSourceTextLabel.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.LEADING) + .addComponent(jSourceLabel) + .addGroup(layout.createSequentialGroup() + .addGap(6, 6, 6) + .addComponent(jSourceNameLabel) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jSourceTextLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 257, Short.MAX_VALUE))) + .addGap(36, 36, 36)) + .addGroup(layout.createSequentialGroup() + .addGap(64, 64, 64) + .addComponent(jSourceGoToResultButton) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addGap(18, 18, 18) + .addComponent(jSourceLabel) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jSourceNameLabel) + .addComponent(jSourceTextLabel)) + .addGap(18, 18, 18) + .addComponent(jSourceGoToResultButton) + .addGap(0, 16, Short.MAX_VALUE)) + ); + }// //GEN-END:initComponents + + private void jSourceGoToResultButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jSourceGoToResultButtonActionPerformed + + final DirectoryTreeTopComponent dtc = DirectoryTreeTopComponent.findInstance(); + + // Navigate to the source context artifact. + if (sourceContextArtifact != null) { + dtc.viewArtifact(sourceContextArtifact); + } + }//GEN-LAST:event_jSourceGoToResultButtonActionPerformed + + /** + * Sets the source label string. + * + * @param nameLabel String value for source label. + */ + private void setSourceName(String nameLabel) { + jSourceNameLabel.setText(nameLabel); + } + + /** + * Sets the source text string. + * + * @param text String value for source text. + */ + private void setSourceText(String text) { + jSourceTextLabel.setText(text); + showSourceButton(!text.isEmpty()); + showSourceText(true); + } + + private void showSourceText(boolean show) { + jSourceTextLabel.setVisible(show); + jSourceLabel.setVisible(show); + } + + private void showSourceButton(boolean show) { + jSourceGoToResultButton.setEnabled(show); + } + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton jSourceGoToResultButton; + private javax.swing.JLabel jSourceLabel; + private javax.swing.JLabel jSourceNameLabel; + private javax.swing.JLabel jSourceTextLabel; + // End of variables declaration//GEN-END:variables +} diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextUsagePanel.form b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextUsagePanel.form new file mode 100644 index 0000000000..dc65310ac5 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextUsagePanel.form @@ -0,0 +1,100 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextUsagePanel.java b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextUsagePanel.java new file mode 100644 index 0000000000..c72de3acdf --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextUsagePanel.java @@ -0,0 +1,183 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2019 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.contextviewer; + +import java.awt.Component; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.logging.Level; +import org.apache.commons.lang.StringUtils; +import org.openide.nodes.Node; +import org.openide.util.NbBundle; +import org.openide.util.lookup.ServiceProvider; +import org.sleuthkit.autopsy.casemodule.Case; +import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; +import org.sleuthkit.autopsy.corecomponentinterfaces.DataContentViewer; +import org.sleuthkit.autopsy.coreutils.Logger; +import org.sleuthkit.autopsy.directorytree.DirectoryTreeTopComponent; +import org.sleuthkit.datamodel.AbstractFile; +import org.sleuthkit.datamodel.BlackboardArtifact; +import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_ASSOCIATED_OBJECT; +import org.sleuthkit.datamodel.BlackboardAttribute; +import org.sleuthkit.datamodel.SleuthkitCase; +import org.sleuthkit.datamodel.TskCoreException; + +/** + * Displays additional context for the selected file, such as its source, and + * usage, if known. + * + */ +public final class ContextUsagePanel extends javax.swing.JPanel { + + private static final long serialVersionUID = 1L; + private static final Logger logger = Logger.getLogger(ContextUsagePanel.class.getName()); + private static final int ARTIFACT_STR_MAX_LEN = 1024; + private static final int ATTRIBUTE_STR_MAX_LEN = 200; + + // defines a list of artifacts that provide context for a file + private static final List SOURCE_CONTEXT_ARTIFACTS = new ArrayList<>(); + static { + SOURCE_CONTEXT_ARTIFACTS.add(TSK_ASSOCIATED_OBJECT); + } + + private BlackboardArtifact sourceContextArtifact; + + /** + * Creates new form ContextViewer + */ + public ContextUsagePanel(String sourceName, String sourceText, BlackboardArtifact associatedArtifact) { + + initComponents(); + sourceContextArtifact = associatedArtifact; + setUsageName(sourceName); + setUsageText(sourceText); + } + + /** + * 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() { + + jUsageGoToResultButton = new javax.swing.JButton(); + jUsageLabel = new javax.swing.JLabel(); + jUsageNameLabel = new javax.swing.JLabel(); + jUsageTextLabel = new javax.swing.JLabel(); + + setBackground(new java.awt.Color(255, 255, 255)); + setPreferredSize(new java.awt.Dimension(495, 120)); + + org.openide.awt.Mnemonics.setLocalizedText(jUsageGoToResultButton, org.openide.util.NbBundle.getMessage(ContextUsagePanel.class, "ContextUsagePanel.jUsageGoToResultButton.text")); // NOI18N + jUsageGoToResultButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jUsageGoToResultButtonActionPerformed(evt); + } + }); + + jUsageLabel.setFont(new java.awt.Font("Dialog", 1, 14)); // NOI18N + org.openide.awt.Mnemonics.setLocalizedText(jUsageLabel, org.openide.util.NbBundle.getMessage(ContextUsagePanel.class, "ContextUsagePanel.jUsageLabel.text")); // NOI18N + + org.openide.awt.Mnemonics.setLocalizedText(jUsageNameLabel, org.openide.util.NbBundle.getMessage(ContextUsagePanel.class, "ContextUsagePanel.jUsageNameLabel.text")); // NOI18N + + org.openide.awt.Mnemonics.setLocalizedText(jUsageTextLabel, org.openide.util.NbBundle.getMessage(ContextUsagePanel.class, "ContextUsagePanel.jUsageTextLabel.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.LEADING) + .addComponent(jUsageLabel) + .addGroup(layout.createSequentialGroup() + .addGap(6, 6, 6) + .addComponent(jUsageNameLabel) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jUsageTextLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 281, Short.MAX_VALUE))) + .addGap(36, 36, 36)) + .addGroup(layout.createSequentialGroup() + .addGap(64, 64, 64) + .addComponent(jUsageGoToResultButton) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addGap(18, 18, 18) + .addComponent(jUsageLabel) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jUsageNameLabel) + .addComponent(jUsageTextLabel)) + .addGap(18, 18, 18) + .addComponent(jUsageGoToResultButton) + .addGap(0, 24, Short.MAX_VALUE)) + ); + }// //GEN-END:initComponents + + private void jUsageGoToResultButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jUsageGoToResultButtonActionPerformed + final DirectoryTreeTopComponent dtc = DirectoryTreeTopComponent.findInstance(); + + // Navigate to the source context artifact. + if (sourceContextArtifact != null) { + dtc.viewArtifact(sourceContextArtifact); + } + }//GEN-LAST:event_jUsageGoToResultButtonActionPerformed + + /** + * Sets the usage label string. + * + * @param nameLabel String value for usage label. + */ + private void setUsageName(String nameLabel) { + jUsageNameLabel.setText(nameLabel); + } + + /** + * Sets the Usage text string. + * + * @param text String value for Usage text. + */ + private void setUsageText(String text) { + jUsageTextLabel.setText(text); + showUsageButton(!text.isEmpty()); + showUsageText(true); + } + + private void showUsageText(boolean show) { + jUsageTextLabel.setVisible(show); + jUsageLabel.setVisible(show); + } + + private void showUsageButton(boolean show) { + jUsageGoToResultButton.setEnabled(show); + } + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton jUsageGoToResultButton; + private javax.swing.JLabel jUsageLabel; + private javax.swing.JLabel jUsageNameLabel; + private javax.swing.JLabel jUsageTextLabel; + // End of variables declaration//GEN-END:variables +} diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextViewer.form b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextViewer.form index 020705e938..ef3dc9910f 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextViewer.form +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextViewer.form @@ -5,6 +5,9 @@ + + + @@ -21,138 +24,19 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextViewer.java b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextViewer.java index 0c457be704..296ae39306 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextViewer.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextViewer.java @@ -20,10 +20,12 @@ package org.sleuthkit.autopsy.contentviewers.contextviewer; import java.awt.Component; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.logging.Level; +import javax.swing.BoxLayout; import org.apache.commons.lang.StringUtils; import org.openide.nodes.Node; import org.openide.util.NbBundle; @@ -55,6 +57,8 @@ public final class ContextViewer extends javax.swing.JPanel implements DataConte // defines a list of artifacts that provide context for a file private static final List SOURCE_CONTEXT_ARTIFACTS = new ArrayList<>(); + private final List contextSourcePanels = new ArrayList<>(); + private final List contextUsagePanels = new ArrayList<>(); static { SOURCE_CONTEXT_ARTIFACTS.add(TSK_ASSOCIATED_OBJECT); @@ -79,119 +83,23 @@ public final class ContextViewer extends javax.swing.JPanel implements DataConte // //GEN-BEGIN:initComponents private void initComponents() { - jSourceGoToResultButton = new javax.swing.JButton(); - jSourceLabel = new javax.swing.JLabel(); - jSourceNameLabel = new javax.swing.JLabel(); - jSourceTextLabel = new javax.swing.JLabel(); - jUsageGoToResultButton = new javax.swing.JButton(); - jUsageLabel = new javax.swing.JLabel(); - jUsageNameLabel = new javax.swing.JLabel(); - jUsageTextLabel = new javax.swing.JLabel(); + jScrollPane1 = new javax.swing.JScrollPane(); setBackground(new java.awt.Color(255, 255, 255)); - - org.openide.awt.Mnemonics.setLocalizedText(jSourceGoToResultButton, org.openide.util.NbBundle.getMessage(ContextViewer.class, "ContextViewer.jSourceGoToResultButton.text")); // NOI18N - jSourceGoToResultButton.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - jSourceGoToResultButtonActionPerformed(evt); - } - }); - - jSourceLabel.setFont(new java.awt.Font("Dialog", 1, 14)); // NOI18N - org.openide.awt.Mnemonics.setLocalizedText(jSourceLabel, org.openide.util.NbBundle.getMessage(ContextViewer.class, "ContextViewer.jSourceLabel.text")); // NOI18N - - org.openide.awt.Mnemonics.setLocalizedText(jSourceNameLabel, org.openide.util.NbBundle.getMessage(ContextViewer.class, "ContextViewer.jSourceNameLabel.text")); // NOI18N - - org.openide.awt.Mnemonics.setLocalizedText(jSourceTextLabel, org.openide.util.NbBundle.getMessage(ContextViewer.class, "ContextViewer.jSourceTextLabel.text")); // NOI18N - - org.openide.awt.Mnemonics.setLocalizedText(jUsageGoToResultButton, org.openide.util.NbBundle.getMessage(ContextViewer.class, "ContextViewer.jUsageGoToResultButton.text")); // NOI18N - jUsageGoToResultButton.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - jUsageGoToResultButtonActionPerformed(evt); - } - }); - - jUsageLabel.setFont(new java.awt.Font("Dialog", 1, 14)); // NOI18N - org.openide.awt.Mnemonics.setLocalizedText(jUsageLabel, org.openide.util.NbBundle.getMessage(ContextViewer.class, "ContextViewer.jUsageLabel.text")); // NOI18N - - org.openide.awt.Mnemonics.setLocalizedText(jUsageNameLabel, org.openide.util.NbBundle.getMessage(ContextViewer.class, "ContextViewer.jUsageNameLabel.text")); // NOI18N - - org.openide.awt.Mnemonics.setLocalizedText(jUsageTextLabel, org.openide.util.NbBundle.getMessage(ContextViewer.class, "ContextViewer.jUsageTextLabel.text")); // NOI18N + setPreferredSize(new java.awt.Dimension(495, 358)); 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.LEADING) - .addComponent(jSourceLabel) - .addComponent(jUsageLabel) - .addGroup(layout.createSequentialGroup() - .addGap(6, 6, 6) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addComponent(jSourceNameLabel) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(jSourceTextLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 192, Short.MAX_VALUE)) - .addGroup(layout.createSequentialGroup() - .addComponent(jUsageNameLabel) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(jUsageTextLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 192, Short.MAX_VALUE))))) - .addGap(36, 36, 36)) - .addGroup(layout.createSequentialGroup() - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addGap(45, 45, 45) - .addComponent(jUsageGoToResultButton)) - .addGroup(layout.createSequentialGroup() - .addGap(46, 46, 46) - .addComponent(jSourceGoToResultButton))) - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 509, Short.MAX_VALUE) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addContainerGap() - .addComponent(jSourceLabel) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(jSourceNameLabel) - .addComponent(jSourceTextLabel)) - .addGap(18, 18, 18) - .addComponent(jSourceGoToResultButton) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(jUsageLabel) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(jUsageNameLabel) - .addComponent(jUsageTextLabel)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(jUsageGoToResultButton) - .addGap(0, 62, Short.MAX_VALUE)) + .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 335, Short.MAX_VALUE) ); }// //GEN-END:initComponents - private void jSourceGoToResultButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jSourceGoToResultButtonActionPerformed - - final DirectoryTreeTopComponent dtc = DirectoryTreeTopComponent.findInstance(); - - // Navigate to the source context artifact. - if (sourceContextArtifact != null) { - dtc.viewArtifact(sourceContextArtifact); - } - - }//GEN-LAST:event_jSourceGoToResultButtonActionPerformed - - private void jUsageGoToResultButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jUsageGoToResultButtonActionPerformed - final DirectoryTreeTopComponent dtc = DirectoryTreeTopComponent.findInstance(); - - // Navigate to the source context artifact. - if (sourceContextArtifact != null) { - dtc.viewArtifact(sourceContextArtifact); - } - }//GEN-LAST:event_jUsageGoToResultButtonActionPerformed - @Override public void setNode(Node selectedNode) { if ((selectedNode == null) || (!isSupported(selectedNode))) { @@ -234,9 +142,8 @@ public final class ContextViewer extends javax.swing.JPanel implements DataConte @Override public void resetComponent() { - jSourceGoToResultButton.setVisible(false); - setSourceName(""); - setSourceText(""); + contextSourcePanels.clear(); + contextUsagePanels.clear(); } @Override @@ -268,6 +175,9 @@ public final class ContextViewer extends javax.swing.JPanel implements DataConte return 1; } + @NbBundle.Messages({ + "ContextViewer.unknownSource=Unknown ", + }) /** * Looks for context providing artifacts for the given file and populates * the source context. @@ -280,7 +190,7 @@ public final class ContextViewer extends javax.swing.JPanel implements DataConte private void populateSourceContextData(AbstractFile sourceFile) throws NoCurrentCaseException, TskCoreException { SleuthkitCase tskCase = Case.getCurrentCaseThrows().getSleuthkitCase(); - + // Check for all context artifacts boolean foundASource = false; for (BlackboardArtifact.ARTIFACT_TYPE artifactType : SOURCE_CONTEXT_ARTIFACTS) { @@ -291,15 +201,29 @@ public final class ContextViewer extends javax.swing.JPanel implements DataConte addSourceEntry(contextArtifact); } } - jSourceGoToResultButton.setVisible(true); - jUsageGoToResultButton.setVisible(true); - if (foundASource == false) { - setSourceName("Unknown"); - showSourceText(false); - setUsageName("Unknown"); - showUsageText(false); - } - + javax.swing.JPanel contextContainer = new javax.swing.JPanel(); + contextContainer.setLayout(new BoxLayout(contextContainer, BoxLayout.Y_AXIS)); + if (contextSourcePanels.isEmpty()) { + contextContainer.add(new ContextSourcePanel(Bundle.ContextViewer_unknownSource(), "", null)); + } else + for (javax.swing.JPanel sourcePanel : contextSourcePanels) { + contextContainer.add(sourcePanel); + } + if (contextUsagePanels.isEmpty()) { + contextContainer.add(new ContextUsagePanel(Bundle.ContextViewer_unknownSource(), "", null)); + } else + for (javax.swing.JPanel usagePanel : contextUsagePanels) { + contextContainer.add(usagePanel); + } + contextContainer.setEnabled(foundASource); + contextContainer.setVisible(foundASource); + jScrollPane1.getViewport().setView(contextContainer); + jScrollPane1.setEnabled(foundASource); + jScrollPane1.setVisible(foundASource); + jScrollPane1.repaint(); + jScrollPane1.revalidate(); + + } /** @@ -312,10 +236,6 @@ public final class ContextViewer extends javax.swing.JPanel implements DataConte * @throws TskCoreException */ private void addSourceEntry(BlackboardArtifact artifact) throws TskCoreException { - setSourceName("Unknown"); - showSourceText(false); - setUsageName("Unknown"); - showUsageText(false); if (BlackboardArtifact.ARTIFACT_TYPE.TSK_ASSOCIATED_OBJECT.getTypeID() == artifact.getArtifactTypeID()) { BlackboardAttribute associatedArtifactAttribute = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT)); @@ -347,74 +267,27 @@ public final class ContextViewer extends javax.swing.JPanel implements DataConte private void setSourceFields(BlackboardArtifact associatedArtifact) throws TskCoreException { if (BlackboardArtifact.ARTIFACT_TYPE.TSK_MESSAGE.getTypeID() == associatedArtifact.getArtifactTypeID() || BlackboardArtifact.ARTIFACT_TYPE.TSK_EMAIL_MSG.getTypeID() == associatedArtifact.getArtifactTypeID()) { - - setSourceName(Bundle.ContextViewer_attachmentSource()); - setSourceText(msgArtifactToAbbreviatedString(associatedArtifact)); + String sourceName = Bundle.ContextViewer_attachmentSource(); + String sourceText = msgArtifactToAbbreviatedString(associatedArtifact); + javax.swing.JPanel sourcePanel = new ContextSourcePanel(sourceName, sourceText, associatedArtifact); + contextSourcePanels.add(sourcePanel); } else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_DOWNLOAD.getTypeID() == associatedArtifact.getArtifactTypeID() || BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_CACHE.getTypeID() == associatedArtifact.getArtifactTypeID()) { + String sourceName = Bundle.ContextViewer_downloadSource(); + String sourceText = webDownloadArtifactToString(associatedArtifact); + javax.swing.JPanel sourcePanel = new ContextSourcePanel(sourceName, sourceText, associatedArtifact); + contextSourcePanels.add(sourcePanel); - setSourceName(Bundle.ContextViewer_downloadSource()); - setSourceText(webDownloadArtifactToString(associatedArtifact)); } else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_RECENT_OBJECT.getTypeID() == associatedArtifact.getArtifactTypeID()) { - setUsageName(Bundle.ContextViewer_recentDocs()); - setUsageText(recentDocArtifactToString(associatedArtifact)); + String sourceName = Bundle.ContextViewer_recentDocs(); + String sourceText = recentDocArtifactToString(associatedArtifact); + javax.swing.JPanel usagePanel = new ContextUsagePanel(sourceName, sourceText, associatedArtifact); + contextUsagePanels.add(usagePanel); } } - /** - * Sets the source label string. - * - * @param nameLabel String value for source label. - */ - private void setSourceName(String nameLabel) { - jSourceNameLabel.setText(nameLabel); - } - - /** - * Sets the usage label string. - * - * @param nameLabel String value for usage label. - */ - private void setUsageName(String nameLabel) { - jUsageNameLabel.setText(nameLabel); - } - - /** - * Sets the source text string. - * - * @param text String value for source text. - */ - private void setSourceText(String text) { - jSourceTextLabel.setText(text); - showSourceText(!text.isEmpty()); - } - - private void showSourceText(boolean show) { - jSourceTextLabel.setVisible(show); - jSourceGoToResultButton.setEnabled(show); - jSourceLabel.setVisible(show); - jUsageLabel.setVisible(show); - } - - /** - * Sets the Usage text string. - * - * @param text String value for Usage text. - */ - private void setUsageText(String text) { - jUsageTextLabel.setText(text); - showUsageText(!text.isEmpty()); - } - - private void showUsageText(boolean show) { - jUsageTextLabel.setVisible(show); - jUsageGoToResultButton.setEnabled(show); - jUsageLabel.setVisible(show); - jSourceLabel.setVisible(show); - } - /** * Returns a display string with download source URL from the given * artifact. @@ -554,13 +427,6 @@ public final class ContextViewer extends javax.swing.JPanel implements DataConte // Variables declaration - do not modify//GEN-BEGIN:variables - private javax.swing.JButton jSourceGoToResultButton; - private javax.swing.JLabel jSourceLabel; - private javax.swing.JLabel jSourceNameLabel; - private javax.swing.JLabel jSourceTextLabel; - private javax.swing.JButton jUsageGoToResultButton; - private javax.swing.JLabel jUsageLabel; - private javax.swing.JLabel jUsageNameLabel; - private javax.swing.JLabel jUsageTextLabel; + private javax.swing.JScrollPane jScrollPane1; // End of variables declaration//GEN-END:variables } From bd3a79a5980acdd34885f52ca478351e00048522 Mon Sep 17 00:00:00 2001 From: Raman Arora Date: Tue, 10 Mar 2020 17:39:51 -0400 Subject: [PATCH 035/100] 6082: Create Email & Phone correlation attribute instances only for actual accounts created in CaseDB --- .../datamodel/CorrelationAttributeUtil.java | 65 +------------------ 1 file changed, 1 insertion(+), 64 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java index 04aa6fc16e..3d2abc5dd0 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java @@ -84,23 +84,12 @@ public class CorrelationAttributeUtil { BlackboardArtifact sourceArtifact = getCorrAttrSourceArtifact(artifact); if (sourceArtifact != null) { int artifactTypeID = sourceArtifact.getArtifactTypeID(); - if (artifactTypeID == ARTIFACT_TYPE.TSK_KEYWORD_HIT.getTypeID()) { - BlackboardAttribute setNameAttr = sourceArtifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME)); - if (setNameAttr != null && CorrelationAttributeUtil.getEmailAddressAttrDisplayName().equals(setNameAttr.getValueString())) { - makeCorrAttrFromArtifactAttr(correlationAttrs, sourceArtifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD, CorrelationAttributeInstance.EMAIL_TYPE_ID); - } - - } else if (artifactTypeID == ARTIFACT_TYPE.TSK_WEB_BOOKMARK.getTypeID() + if (artifactTypeID == ARTIFACT_TYPE.TSK_WEB_BOOKMARK.getTypeID() || artifactTypeID == ARTIFACT_TYPE.TSK_WEB_COOKIE.getTypeID() || artifactTypeID == ARTIFACT_TYPE.TSK_WEB_DOWNLOAD.getTypeID() || artifactTypeID == ARTIFACT_TYPE.TSK_WEB_HISTORY.getTypeID()) { makeCorrAttrFromArtifactAttr(correlationAttrs, sourceArtifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DOMAIN, CorrelationAttributeInstance.DOMAIN_TYPE_ID); - } else if (artifactTypeID == ARTIFACT_TYPE.TSK_CONTACT.getTypeID() - || artifactTypeID == ARTIFACT_TYPE.TSK_CALLLOG.getTypeID() - || artifactTypeID == ARTIFACT_TYPE.TSK_MESSAGE.getTypeID()) { - makeCorrAttrFromArtifactPhoneAttr(sourceArtifact); - } else if (artifactTypeID == ARTIFACT_TYPE.TSK_DEVICE_ATTACHED.getTypeID()) { makeCorrAttrFromArtifactAttr(correlationAttrs, sourceArtifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DEVICE_ID, CorrelationAttributeInstance.USBID_TYPE_ID); makeCorrAttrFromArtifactAttr(correlationAttrs, sourceArtifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_MAC_ADDRESS, CorrelationAttributeInstance.MAC_TYPE_ID); @@ -169,58 +158,6 @@ public class CorrelationAttributeUtil { return sourceArtifact; } - /** - * Makes a correlation attribute instance from a phone number attribute of an - * artifact. - * - * @param artifact An artifact with a phone number attribute. - * - * @return The correlation instance artifact or null, if the phone number is - * not a valid correlation attribute. - * - * @throws TskCoreException If there is an error querying the case - * database. - * @throws CentralRepoException If there is an error querying the central - * repository. - */ - private static CorrelationAttributeInstance makeCorrAttrFromArtifactPhoneAttr(BlackboardArtifact artifact) throws TskCoreException, CentralRepoException { - CorrelationAttributeInstance corrAttr = null; - - /* - * Extract the phone number from the artifact attribute. - */ - String value = null; - if (null != artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER))) { - value = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER)).getValueString(); - } else if (null != artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_FROM))) { - value = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_FROM)).getValueString(); - } else if (null != artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_TO))) { - value = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_TO)).getValueString(); - } - - /* - * Normalize the phone number. - */ - if (value != null) { - String newValue = value.replaceAll("\\D", ""); - if (value.startsWith("+")) { - newValue = "+" + newValue; - } - value = newValue; - - /* - * Validate the phone number. Three to five digit phone numbers may - * be valid, but they are too short to use as correlation - * attributes. - */ - if (value.length() > 5) { - corrAttr = makeCorrAttr(artifact, CentralRepository.getInstance().getCorrelationTypeById(CorrelationAttributeInstance.PHONE_TYPE_ID), value); - } - } - - return corrAttr; - } - /** * Makes a correlation attribute instance for an account artifact. * From 487d680d4174e7b0f7a7fd14ec676a71494225da Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Wed, 11 Mar 2020 10:53:28 -0400 Subject: [PATCH 036/100] update for display of change due to failure --- .../centralrepository/datamodel/CentralRepoDbManager.java | 2 ++ .../centralrepository/optionspanel/GlobalSettingsPanel.java | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java index 4008f609b3..f346ab281e 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java @@ -85,7 +85,9 @@ public class CentralRepoDbManager { */ public static void setDisabledDueToFailure(boolean disabledDueToFailure) { synchronized(disabledDueToFailureLock) { + boolean oldValue = isDisabledDueToFailure(); ModuleSettings.setConfigSetting(CENTRAL_REPOSITORY_SETTINGS_KEY, DISABLED_DUE_TO_FAILURE_KEY, Boolean.toString(disabledDueToFailure)); + propertyChangeSupport.firePropertyChange("disabledDueToFailure", oldValue, disabledDueToFailure); } } diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java index 4d9d453f36..0064e16e51 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java @@ -214,14 +214,14 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i SwingUtilities.invokeLater(() -> { boolean successful = EamDbSettingsDialog.testStatusAndCreate(parent, new CentralRepoDbManager()); if (successful) { + updateDatabase(parent); // clear any error if there was one CentralRepoDbManager.setDisabledDueToFailure(false); - updateDatabase(parent); } else { + CentralRepoDbUtil.setUseCentralRepo(false); // disable central repository due to error CentralRepoDbManager.setDisabledDueToFailure(true); - CentralRepoDbUtil.setUseCentralRepo(false); } }); } From 276242d3192a029064869020b91a35fcb1c42e33 Mon Sep 17 00:00:00 2001 From: Mark McKinnon Date: Wed, 11 Mar 2020 11:10:02 -0400 Subject: [PATCH 037/100] Update viber.py Added check for only spaces, blanks and special characters. --- InternalPythonModules/android/viber.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/InternalPythonModules/android/viber.py b/InternalPythonModules/android/viber.py index aadd1a2104..4bc2d0c5d2 100644 --- a/InternalPythonModules/android/viber.py +++ b/InternalPythonModules/android/viber.py @@ -117,7 +117,7 @@ class ViberAnalyzer(general.AndroidComponentAnalyzer): try: contacts_parser = ViberContactsParser(contacts_db) while contacts_parser.next(): - if contacts_parser.get_phone() is not None: + if (not(not contacts_parser.get_phone() or contacts_parser.get_phone().isspace())): helper.addContact( contacts_parser.get_contact_name(), contacts_parser.get_phone(), @@ -125,7 +125,8 @@ class ViberAnalyzer(general.AndroidComponentAnalyzer): contacts_parser.get_mobile_phone(), contacts_parser.get_email() ) - else: + # Check if contact_name is blank and if it is not create a TSK_CONTACT otherwise ignore as not Contact Info + elif (not(not contacts_parser.get_contact_name() or contacts_parser.get_contact_name().isspace())): current_case = Case.getCurrentCase().getSleuthkitCase() attributes = ArrayList() artifact = contacts_db.getDBFile().newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_CONTACT) From 219bb5b2e06da3d2a09bb1c4409ea381ce61be6a Mon Sep 17 00:00:00 2001 From: esaunders Date: Wed, 11 Mar 2020 11:21:47 -0400 Subject: [PATCH 038/100] Upgrade version of JNA. --- Core/nbproject/project.properties | 2 -- Core/nbproject/project.xml | 4 ---- CoreLibs/ivy.xml | 6 +----- CoreLibs/nbproject/project.properties | 4 ++-- CoreLibs/nbproject/project.xml | 16 ++++++++-------- 5 files changed, 11 insertions(+), 21 deletions(-) diff --git a/Core/nbproject/project.properties b/Core/nbproject/project.properties index 94dffdeb9b..80e8cfd4d4 100644 --- a/Core/nbproject/project.properties +++ b/Core/nbproject/project.properties @@ -45,7 +45,6 @@ file.reference.jericho-html-3.3.jar=release/modules/ext/jericho-html-3.3.jar file.reference.jgraphx-v3.8.0.jar=release/modules/ext/jgraphx-v3.8.0.jar file.reference.jhighlight-1.0.3.jar=release\\modules\\ext\\jhighlight-1.0.3.jar file.reference.jmatio-1.5.jar=release\\modules\\ext\\jmatio-1.5.jar -file.reference.jna-5.1.0.jar=release\\modules\\ext\\jna-5.1.0.jar file.reference.json-simple-1.1.1.jar=release\\modules\\ext\\json-simple-1.1.1.jar file.reference.jsoup-1.11.3.jar=release\\modules\\ext\\jsoup-1.11.3.jar file.reference.jul-to-slf4j-1.7.25.jar=release\\modules\\ext\\jul-to-slf4j-1.7.25.jar @@ -97,7 +96,6 @@ file.reference.xz-1.8.jar=release\\modules\\ext\\xz-1.8.jar file.reference.zookeeper-3.4.6.jar=release/modules/ext/zookeeper-3.4.6.jar file.reference.SparseBitSet-1.1.jar=release/modules/ext/SparseBitSet-1.1.jar file.reference.commons-validator-1.6.jar=release/modules/ext/commons-validator-1.6.jar -file.reference.jna-3.4.0.jar=release/modules/ext/jna-3.4.0.jar file.reference.api-common-1.7.0.jar=release/modules/ext/api-common-1.7.0.jar file.reference.gax-1.44.0.jar=release/modules/ext/gax-1.44.0.jar file.reference.gax-grpc-1.44.0.jar=release/modules/ext/gax-grpc-1.44.0.jar diff --git a/Core/nbproject/project.xml b/Core/nbproject/project.xml index 182b92a661..02d37221a7 100644 --- a/Core/nbproject/project.xml +++ b/Core/nbproject/project.xml @@ -615,10 +615,6 @@ ext/commons-validator-1.6.jar release/modules/ext/commons-validator-1.6.jar - - ext/jna-5.1.0.jar - release\modules\ext\jna-5.1.0.jar - ext/jbig2-imageio-3.0.2.jar release\modules\ext\jbig2-imageio-3.0.2.jar diff --git a/CoreLibs/ivy.xml b/CoreLibs/ivy.xml index 6819dac82d..4853d1f90e 100644 --- a/CoreLibs/ivy.xml +++ b/CoreLibs/ivy.xml @@ -14,8 +14,7 @@ - - + @@ -73,8 +72,5 @@ - - - diff --git a/CoreLibs/nbproject/project.properties b/CoreLibs/nbproject/project.properties index 677f823e67..42f8292d5b 100644 --- a/CoreLibs/nbproject/project.properties +++ b/CoreLibs/nbproject/project.properties @@ -21,7 +21,6 @@ file.reference.dom4j-1.6.1.jar=release/modules/ext/dom4j-1.6.1.jar file.reference.geronimo-jms_1.1_spec-1.0.jar=release/modules/ext/geronimo-jms_1.1_spec-1.0.jar file.reference.gson-2.8.5.jar=release/modules/ext/gson-2.8.5.jar file.reference.gst1-java-core-1.0.0.jar=release\\modules\\ext\\gst1-java-core-1.0.0.jar -file.reference.jna-3.4.0.jar=release/modules/ext/jna-3.4.0.jar file.reference.guava-19.0.jar=release/modules/ext/guava-19.0.jar file.reference.imageio-bmp-3.2.jar=release/modules/ext/imageio-bmp-3.2.jar file.reference.imageio-core-3.2.jar=release/modules/ext/imageio-core-3.2.jar @@ -44,6 +43,8 @@ file.reference.jfxtras-common-8.0-r4.jar=release/modules/ext/jfxtras-common-8.0- file.reference.jfxtras-controls-8.0-r4.jar=release/modules/ext/jfxtras-controls-8.0-r4.jar file.reference.jfxtras-fxml-8.0-r4.jar=release/modules/ext/jfxtras-fxml-8.0-r4.jar file.reference.jna-3.4.0.jar=release/modules/ext/jna-3.4.0.jar +file.reference.jna-5.5.0.jar=release\\modules\\ext\\jna-5.5.0.jar +file.reference.jna-platform-5.5.0.jar=release\\modules\\ext\\jna-platform-5.5.0.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-10.3.1.jar=release/modules/ext/LGoodDatePicker-10.3.1.jar @@ -52,7 +53,6 @@ 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 file.reference.opencv-248.jar=release/modules/ext/opencv-248.jar file.reference.openjfx-dialogs-1.0.2.jar=release/modules/ext/openjfx-dialogs-1.0.3.jar -file.reference.platform-3.4.0.jar=release/modules/ext/platform-3.4.0.jar file.reference.poi-4.0.1.jar=release\\modules\\ext\\poi-4.0.1.jar file.reference.poi-excelant-4.0.1.jar=release\\modules\\ext\\poi-excelant-4.0.1.jar file.reference.poi-ooxml-4.0.1.jar=release\\modules\\ext\\poi-ooxml-4.0.1.jar diff --git a/CoreLibs/nbproject/project.xml b/CoreLibs/nbproject/project.xml index 0498669b04..d5169a8965 100644 --- a/CoreLibs/nbproject/project.xml +++ b/CoreLibs/nbproject/project.xml @@ -806,10 +806,6 @@ ext/sigar-1.6.4.jar release/modules/ext/sigar-1.6.4.jar - - ext/jna-3.4.0.jar - release/modules/ext/jna-3.4.0.jar - ext/gson-2.8.5.jar release/modules/ext/gson-2.8.5.jar @@ -902,6 +898,10 @@ ext/commons-csv-1.4.jar release/modules/ext/commons-csv-1.4.jar + + ext/jna-5.5.0.jar + release/modules/ext/jna-5.5.0.jar + ext/imageio-sgi-3.2.jar release/modules/ext/imageio-sgi-3.2.jar @@ -946,10 +946,6 @@ ext/imageio-bmp-3.2.jar release/modules/ext/imageio-bmp-3.2.jar - - ext/platform-3.4.0.jar - release/modules/ext/platform-3.4.0.jar - ext/commons-lang-2.6.jar release/modules/ext/commons-lang-2.6.jar @@ -1018,6 +1014,10 @@ ext/dom4j-1.6.1.jar release/modules/ext/dom4j-1.6.1.jar + + ext/jna-platform-5.5.0.jar + release/modules/ext/jna-platform-5.5.0.jar + ext/imageio-metadata-3.2.jar release/modules/ext/imageio-metadata-3.2.jar From c64cbb351f023c844ebd779720a790a51bddc53e Mon Sep 17 00:00:00 2001 From: Raman Arora Date: Wed, 11 Mar 2020 12:07:29 -0400 Subject: [PATCH 039/100] 6111: CVT displays incorrect To phone number for Outgoing calls. --- .../relationships/CallLogNode.java | 60 ++++++++++++++++--- 1 file changed, 51 insertions(+), 9 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/communications/relationships/CallLogNode.java b/Core/src/org/sleuthkit/autopsy/communications/relationships/CallLogNode.java index 288b3efa3f..055cddcc09 100755 --- a/Core/src/org/sleuthkit/autopsy/communications/relationships/CallLogNode.java +++ b/Core/src/org/sleuthkit/autopsy/communications/relationships/CallLogNode.java @@ -19,6 +19,7 @@ package org.sleuthkit.autopsy.communications.relationships; import java.util.logging.Level; +import org.apache.commons.lang.StringUtils; import org.openide.nodes.Sheet; import org.sleuthkit.autopsy.communications.Utils; import static org.sleuthkit.autopsy.communications.relationships.RelationshipsNodeUtilities.getAttributeDisplayString; @@ -67,14 +68,6 @@ final class CallLogNode extends BlackboardArtifactNode { return sheet; } - String phoneNumber = getAttributeDisplayString(artifact, TSK_PHONE_NUMBER_FROM); - if(phoneNumber == null || phoneNumber.isEmpty()) { - phoneNumber = getAttributeDisplayString(artifact, TSK_PHONE_NUMBER_TO); - } - if(phoneNumber == null || phoneNumber.isEmpty()) { - phoneNumber = getAttributeDisplayString(artifact, TSK_PHONE_NUMBER); - } - long duration = -1; try{ duration = getCallDuration(artifact); @@ -84,7 +77,7 @@ final class CallLogNode extends BlackboardArtifactNode { sheetSet.put(createNode(TSK_DATETIME_START, artifact)); sheetSet.put(createNode(TSK_DIRECTION, artifact)); - sheetSet.put(new NodeProperty<>(TSK_PHONE_NUMBER.getLabel(), TSK_PHONE_NUMBER.getDisplayName(), "", phoneNumber)); + sheetSet.put(new NodeProperty<>(TSK_PHONE_NUMBER.getLabel(), TSK_PHONE_NUMBER.getDisplayName(), "", getPhoneNumber(artifact))); if(duration != -1) { sheetSet.put(new NodeProperty<>("duration", "Duration", "", Long.toString(duration))); } @@ -107,6 +100,55 @@ final class CallLogNode extends BlackboardArtifactNode { return endAttribute.getValueLong() - startAttribute.getValueLong(); } + /** + * Returns the phone number to display in the To/From column. The number is + * picked from one the the 3 possible phone number attributes, based on the + * direction of the call. + * + * @param artifact Call log artifact. + * + * @return Phone number. + */ + private String getPhoneNumber(BlackboardArtifact artifact) { + String direction = getAttributeDisplayString(artifact, TSK_DIRECTION); + + String phoneNumberToReturn = ""; + String fromPhoneNumber = getAttributeDisplayString(artifact, TSK_PHONE_NUMBER_FROM); + String toPhoneNumber = getAttributeDisplayString(artifact, TSK_PHONE_NUMBER_TO); + String phoneNumber = getAttributeDisplayString(artifact, TSK_PHONE_NUMBER); + + switch (direction.toLowerCase()) { + case "incoming": // NON-NLS + + if (!StringUtils.isBlank(fromPhoneNumber)) { + phoneNumberToReturn = fromPhoneNumber; + } else if (!StringUtils.isBlank(phoneNumber)) { + phoneNumberToReturn = phoneNumber; + } else if (!StringUtils.isBlank(toPhoneNumber)) { + phoneNumberToReturn = toPhoneNumber; + } + break; + case "outgoing": // NON-NLS + if (!StringUtils.isBlank(toPhoneNumber)) { + phoneNumberToReturn = toPhoneNumber; + } else if (!StringUtils.isBlank(phoneNumber)) { + phoneNumberToReturn = phoneNumber; + } else if (!StringUtils.isBlank(fromPhoneNumber)) { + phoneNumberToReturn = fromPhoneNumber; + } + break; + default: + if (!StringUtils.isBlank(toPhoneNumber)) { + phoneNumberToReturn = toPhoneNumber; + } else if (!StringUtils.isBlank(fromPhoneNumber)) { + phoneNumberToReturn = fromPhoneNumber; + } else if (!StringUtils.isBlank(phoneNumber)) { + phoneNumberToReturn = phoneNumber; + } + } + + return phoneNumberToReturn; + } /** * Circumvent DataResultFilterNode's slightly odd delegation to * BlackboardArtifactNode.getSourceName(). From 92a3667a1419c68d73a5cd6d8bdadb67cf5cb674 Mon Sep 17 00:00:00 2001 From: esaunders Date: Wed, 11 Mar 2020 12:08:56 -0400 Subject: [PATCH 040/100] Revert Gst initialization on Windows since it didn't have any impact on crashes. --- .../contentviewers/MediaPlayerPanel.java | 86 +++++++++---------- 1 file changed, 41 insertions(+), 45 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.java b/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.java index c518abdd45..6df0cf8161 100755 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.java @@ -74,7 +74,6 @@ import org.freedesktop.gstreamer.Format; import org.freedesktop.gstreamer.GstException; import org.freedesktop.gstreamer.event.SeekFlags; import org.freedesktop.gstreamer.event.SeekType; -import org.sleuthkit.autopsy.coreutils.PlatformUtil; /** * This is a video player that is part of the Media View layered pane. It uses @@ -222,14 +221,6 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie //True for fairness. In other words, //acquire() calls are processed in order of invocation. sliderLock = new Semaphore(1, true); - - /** - * See JIRA-5888 for details. Initializing gstreamer here is more stable - * on Windows. - */ - if (PlatformUtil.isWindowsOS()) { - Gst.init(); - } } private void customizeComponents() { @@ -264,7 +255,7 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie //Manage the video while the user is performing actions on the track. progressSlider.addMouseListener(new MouseListener() { private State previousState = State.NULL; - + @Override public void mousePressed(MouseEvent e) { previousState = gstPlayBin.getState(); @@ -273,11 +264,12 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie @Override public void mouseReleased(MouseEvent e) { - if(previousState.equals(State.PLAYING)) { + if (previousState.equals(State.PLAYING)) { gstPlayBin.play(); } previousState = State.NULL; } + @Override public void mouseClicked(MouseEvent e) { } @@ -289,7 +281,7 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie @Override public void mouseExited(MouseEvent e) { } - + }); //Manage the audio level when the user is adjusting the volume slider audioSlider.addChangeListener((ChangeEvent event) -> { @@ -389,6 +381,7 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie gstPlayBin.getBus().disconnect(endOfStreamListener); gstPlayBin.getBus().disconnect(stateChangeListener); gstPlayBin.getBus().disconnect(errorListener); + gstPlayBin.getBus().dispose(); gstPlayBin.dispose(); fxAppSink.clear(); gstPlayBin = null; @@ -548,10 +541,8 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie // Initialize Gstreamer. It is safe to call this for every file. // It was moved here from the constructor because having it happen - // earlier resulted in conflicts on Linux. See JIRA-5888. - if (!PlatformUtil.isWindowsOS()) { - Gst.init(); - } + // earlier resulted in crashes on Linux. See JIRA-5888. + Gst.init(); //Video is ready for playback. Create new components gstPlayBin = new PlayBin("VideoPlayer", tempFile.toURI()); @@ -599,23 +590,27 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie @Override public void actionPerformed(ActionEvent e) { if (!progressSlider.getValueIsAdjusting()) { - sliderLock.acquireUninterruptibly(); - long position = gstPlayBin.queryPosition(TimeUnit.NANOSECONDS); - long duration = gstPlayBin.queryDuration(TimeUnit.NANOSECONDS); - /** - * Duration may not be known until there is video data in the - * pipeline. We start this updater when data-flow has just been - * initiated so buffering may still be in progress. - */ - if (duration >= 0 && position >= 0) { - double relativePosition = (double) position / duration; - progressSlider.setValue((int) (relativePosition * PROGRESS_SLIDER_SIZE)); - } + try { + sliderLock.acquireUninterruptibly(); + long position = gstPlayBin.queryPosition(TimeUnit.NANOSECONDS); + long duration = gstPlayBin.queryDuration(TimeUnit.NANOSECONDS); + /** + * Duration may not be known until there is video data in + * the pipeline. We start this updater when data-flow has + * just been initiated so buffering may still be in + * progress. + */ + if (duration >= 0 && position >= 0) { + double relativePosition = (double) position / duration; + progressSlider.setValue((int) (relativePosition * PROGRESS_SLIDER_SIZE)); + } - SwingUtilities.invokeLater(() -> { - updateTimeLabel(position, duration); - }); - sliderLock.release(); + SwingUtilities.invokeLater(() -> { + updateTimeLabel(position, duration); + }); + } finally { + sliderLock.release(); + } } } } @@ -635,13 +630,13 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie * thumb at the given width and height. It also paints the track blue as * the thumb progresses. * - * @param slider JSlider component + * @param slider JSlider component * @param thumbDimension */ public CircularJSliderUI(JSlider slider, Dimension thumbDimension) { super(slider); this.thumbDimension = thumbDimension; - + //Configure track and thumb colors. Color lightBlue = new Color(0, 130, 255); thumbColor = lightBlue; @@ -655,8 +650,8 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie } /** - * Modifies the View to be an oval rather than the underlying - * rectangle Controller. + * Modifies the View to be an oval rather than the underlying rectangle + * Controller. */ @Override public void paintThumb(Graphics graphic) { @@ -705,12 +700,13 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie @Override protected TrackListener createTrackListener(JSlider slider) { /** - * This track listener will force the thumb to be snapped to the mouse - * location. This makes grabbing and dragging the JSlider much easier. - * Using the default track listener, the user would have to click - * exactly on the slider thumb to drag it. Now the thumb positions - * itself under the mouse so that it can always be dragged. - */ + * This track listener will force the thumb to be snapped to the + * mouse location. This makes grabbing and dragging the JSlider much + * easier. Using the default track listener, the user would have to + * click exactly on the slider thumb to drag it. Now the thumb + * positions itself under the mouse so that it can always be + * dragged. + */ return new TrackListener() { @Override public void mousePressed(MouseEvent e) { @@ -1007,14 +1003,14 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie //Don't allow skipping within 2 seconds of video ending. Skipping right to //the end causes undefined behavior for some gstreamer plugins. long twoSecondsInNano = TimeUnit.NANOSECONDS.convert(2, TimeUnit.SECONDS); - if((duration - currentTime) <= twoSecondsInNano) { + if ((duration - currentTime) <= twoSecondsInNano) { return; } - + long newTime; if (currentTime + fastForwardDelta >= duration) { //If there are less than 30 seconds left, only fast forward to the midpoint. - newTime = currentTime + (duration - currentTime)/2; + newTime = currentTime + (duration - currentTime) / 2; } else { newTime = currentTime + fastForwardDelta; } From ad5106d7d431aaf4d1eba68aff3c737b83d65c7b Mon Sep 17 00:00:00 2001 From: Raman Arora Date: Wed, 11 Mar 2020 13:43:31 -0400 Subject: [PATCH 041/100] Addressed Codacy comments. --- .../relationships/CallLogNode.java | 56 ++++++++++--------- 1 file changed, 30 insertions(+), 26 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/communications/relationships/CallLogNode.java b/Core/src/org/sleuthkit/autopsy/communications/relationships/CallLogNode.java index 055cddcc09..3151d75780 100755 --- a/Core/src/org/sleuthkit/autopsy/communications/relationships/CallLogNode.java +++ b/Core/src/org/sleuthkit/autopsy/communications/relationships/CallLogNode.java @@ -102,53 +102,57 @@ final class CallLogNode extends BlackboardArtifactNode { /** * Returns the phone number to display in the To/From column. The number is - * picked from one the the 3 possible phone number attributes, based on the + * picked from one of the 3 possible phone number attributes, based on the * direction of the call. * * @param artifact Call log artifact. * - * @return Phone number. + * @return Phone number to display. */ private String getPhoneNumber(BlackboardArtifact artifact) { String direction = getAttributeDisplayString(artifact, TSK_DIRECTION); - String phoneNumberToReturn = ""; + String phoneNumberToReturn; String fromPhoneNumber = getAttributeDisplayString(artifact, TSK_PHONE_NUMBER_FROM); String toPhoneNumber = getAttributeDisplayString(artifact, TSK_PHONE_NUMBER_TO); String phoneNumber = getAttributeDisplayString(artifact, TSK_PHONE_NUMBER); - switch (direction.toLowerCase()) { case "incoming": // NON-NLS - - if (!StringUtils.isBlank(fromPhoneNumber)) { - phoneNumberToReturn = fromPhoneNumber; - } else if (!StringUtils.isBlank(phoneNumber)) { - phoneNumberToReturn = phoneNumber; - } else if (!StringUtils.isBlank(toPhoneNumber)) { - phoneNumberToReturn = toPhoneNumber; - } + phoneNumberToReturn = getFirstNonBlank(fromPhoneNumber, phoneNumber, toPhoneNumber); break; case "outgoing": // NON-NLS - if (!StringUtils.isBlank(toPhoneNumber)) { - phoneNumberToReturn = toPhoneNumber; - } else if (!StringUtils.isBlank(phoneNumber)) { - phoneNumberToReturn = phoneNumber; - } else if (!StringUtils.isBlank(fromPhoneNumber)) { - phoneNumberToReturn = fromPhoneNumber; - } + phoneNumberToReturn = getFirstNonBlank(toPhoneNumber, phoneNumber, fromPhoneNumber); break; default: - if (!StringUtils.isBlank(toPhoneNumber)) { - phoneNumberToReturn = toPhoneNumber; - } else if (!StringUtils.isBlank(fromPhoneNumber)) { - phoneNumberToReturn = fromPhoneNumber; - } else if (!StringUtils.isBlank(phoneNumber)) { - phoneNumberToReturn = phoneNumber; - } + phoneNumberToReturn = getFirstNonBlank(toPhoneNumber, fromPhoneNumber, phoneNumber ); + break; } return phoneNumberToReturn; } + + /** + * Checks the given string arguments in order and returns the first non blank string. + * Returns a blank string if all the input strings are blank. + * + * @param string1 First string to check + * @param string2 Second string to check + * @param string3 Third string to check + * + * @retunr first non blank string if there is one, blank string otherwise. + * + */ + private String getFirstNonBlank(String string1, String string2, String string3 ) { + + if (!StringUtils.isBlank(string1)) { + return string1; + } else if (!StringUtils.isBlank(string2)) { + return string2; + } else if (!StringUtils.isBlank(string3)) { + return string3; + } + return ""; + } /** * Circumvent DataResultFilterNode's slightly odd delegation to * BlackboardArtifactNode.getSourceName(). From 41981a722ed4f34a44b57d3aa71ed91baae6daf2 Mon Sep 17 00:00:00 2001 From: Mark McKinnon Date: Wed, 11 Mar 2020 15:41:51 -0400 Subject: [PATCH 042/100] Make so headings only appear once Make headings only apper once per source/usage --- .../contextviewer/Bundle.properties | 2 ++ .../contextviewer/Bundle.properties-MERGED | 2 ++ .../contextviewer/ContextSourcePanel.java | 30 ++++++++++++----- .../contextviewer/ContextUsagePanel.form | 23 +++++++++---- .../contextviewer/ContextUsagePanel.java | 32 +++++++++++++------ .../contextviewer/ContextViewer.java | 21 +++++++++--- 6 files changed, 81 insertions(+), 29 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/Bundle.properties b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/Bundle.properties index 554f364be2..1f229fd721 100755 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/Bundle.properties @@ -6,3 +6,5 @@ ContextUsagePanel.jUsageTextLabel.text=Label2 ContextUsagePanel.jUsageNameLabel.text=jUsageLabel ContextSourcePanel.jSourceTextLabel.text=Label2 ContextSourcePanel.jSourceNameLabel.text=jSourceNameLabel +ContextUsagePanel.jBlankLabel.text= +ContextSourcePanel.jLabel1.text=\ diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/Bundle.properties-MERGED index 304d3f6cb2..ccb13c972b 100755 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/Bundle.properties-MERGED @@ -6,6 +6,8 @@ ContextUsagePanel.jUsageTextLabel.text=Label2 ContextUsagePanel.jUsageNameLabel.text=jUsageLabel ContextSourcePanel.jSourceTextLabel.text=Label2 ContextSourcePanel.jSourceNameLabel.text=jSourceNameLabel +ContextUsagePanel.jBlankLabel.text= +ContextSourcePanel.jLabel1.text=\ ContextViewer.attachmentSource=Attached to: ContextViewer.downloadedOn=On ContextViewer.downloadSource=Downloaded from: diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextSourcePanel.java b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextSourcePanel.java index 670d2c1347..9fd9d5ae4e 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextSourcePanel.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextSourcePanel.java @@ -48,12 +48,13 @@ public final class ContextSourcePanel extends javax.swing.JPanel { /** * Creates new form ContextViewer */ - public ContextSourcePanel(String sourceName, String sourceText, BlackboardArtifact associatedArtifact) { + public ContextSourcePanel(String sourceName, String sourceText, BlackboardArtifact associatedArtifact, Boolean showSourceHeading) { initComponents(); sourceContextArtifact = associatedArtifact; setSourceName(sourceName); setSourceText(sourceText); + showSourceLabel(showSourceHeading); } /** @@ -69,6 +70,7 @@ public final class ContextSourcePanel extends javax.swing.JPanel { jSourceLabel = new javax.swing.JLabel(); jSourceNameLabel = new javax.swing.JLabel(); jSourceTextLabel = new javax.swing.JLabel(); + jLabel1 = new javax.swing.JLabel(); setBackground(new java.awt.Color(255, 255, 255)); setPreferredSize(new java.awt.Dimension(495, 120)); @@ -87,6 +89,8 @@ public final class ContextSourcePanel extends javax.swing.JPanel { org.openide.awt.Mnemonics.setLocalizedText(jSourceTextLabel, org.openide.util.NbBundle.getMessage(ContextSourcePanel.class, "ContextSourcePanel.jSourceTextLabel.text")); // NOI18N + org.openide.awt.Mnemonics.setLocalizedText(jLabel1, org.openide.util.NbBundle.getMessage(ContextSourcePanel.class, "ContextSourcePanel.jLabel1.text")); // NOI18N + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); layout.setHorizontalGroup( @@ -96,11 +100,13 @@ public final class ContextSourcePanel extends javax.swing.JPanel { .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(jSourceLabel) .addGroup(layout.createSequentialGroup() - .addGap(6, 6, 6) + .addGap(10, 10, 10) .addComponent(jSourceNameLabel) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(jSourceTextLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 257, Short.MAX_VALUE))) - .addGap(36, 36, 36)) + .addGap(5, 5, 5) + .addComponent(jLabel1) + .addGap(36, 36, 36) + .addComponent(jSourceTextLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))) + .addGap(260, 260, 260)) .addGroup(layout.createSequentialGroup() .addGap(64, 64, 64) .addComponent(jSourceGoToResultButton) @@ -114,10 +120,11 @@ public final class ContextSourcePanel extends javax.swing.JPanel { .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(jSourceNameLabel) - .addComponent(jSourceTextLabel)) + .addComponent(jSourceTextLabel) + .addComponent(jLabel1)) .addGap(18, 18, 18) .addComponent(jSourceGoToResultButton) - .addGap(0, 16, Short.MAX_VALUE)) + .addGap(0, 0, Short.MAX_VALUE)) ); }// //GEN-END:initComponents @@ -151,9 +158,15 @@ public final class ContextSourcePanel extends javax.swing.JPanel { showSourceText(true); } + private void showSourceLabel(boolean show) { + if (!show) { + jSourceLabel.setText(" "); + } + jSourceLabel.setVisible(show); + } + private void showSourceText(boolean show) { jSourceTextLabel.setVisible(show); - jSourceLabel.setVisible(show); } private void showSourceButton(boolean show) { @@ -161,6 +174,7 @@ public final class ContextSourcePanel extends javax.swing.JPanel { } // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JLabel jLabel1; private javax.swing.JButton jSourceGoToResultButton; private javax.swing.JLabel jSourceLabel; private javax.swing.JLabel jSourceNameLabel; diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextUsagePanel.form b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextUsagePanel.form index dc65310ac5..3dcaf08d66 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextUsagePanel.form +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextUsagePanel.form @@ -29,10 +29,11 @@ - - + - + + + @@ -49,14 +50,15 @@ - + - + + - + - +
@@ -96,5 +98,12 @@
+ + + + + + + diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextUsagePanel.java b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextUsagePanel.java index c72de3acdf..f6ae7e6395 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextUsagePanel.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextUsagePanel.java @@ -63,12 +63,14 @@ public final class ContextUsagePanel extends javax.swing.JPanel { /** * Creates new form ContextViewer */ - public ContextUsagePanel(String sourceName, String sourceText, BlackboardArtifact associatedArtifact) { + public ContextUsagePanel(String sourceName, String sourceText, BlackboardArtifact associatedArtifact, Boolean showUsageHeading) { initComponents(); sourceContextArtifact = associatedArtifact; setUsageName(sourceName); setUsageText(sourceText); + showUsageLabel(showUsageHeading); + } /** @@ -84,6 +86,7 @@ public final class ContextUsagePanel extends javax.swing.JPanel { jUsageLabel = new javax.swing.JLabel(); jUsageNameLabel = new javax.swing.JLabel(); jUsageTextLabel = new javax.swing.JLabel(); + jBlankLabel = new javax.swing.JLabel(); setBackground(new java.awt.Color(255, 255, 255)); setPreferredSize(new java.awt.Dimension(495, 120)); @@ -102,6 +105,8 @@ public final class ContextUsagePanel extends javax.swing.JPanel { org.openide.awt.Mnemonics.setLocalizedText(jUsageTextLabel, org.openide.util.NbBundle.getMessage(ContextUsagePanel.class, "ContextUsagePanel.jUsageTextLabel.text")); // NOI18N + org.openide.awt.Mnemonics.setLocalizedText(jBlankLabel, org.openide.util.NbBundle.getMessage(ContextUsagePanel.class, "ContextUsagePanel.jBlankLabel.text")); // NOI18N + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); layout.setHorizontalGroup( @@ -111,10 +116,11 @@ public final class ContextUsagePanel extends javax.swing.JPanel { .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(jUsageLabel) .addGroup(layout.createSequentialGroup() - .addGap(6, 6, 6) - .addComponent(jUsageNameLabel) + .addComponent(jBlankLabel) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(jUsageTextLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 281, Short.MAX_VALUE))) + .addComponent(jUsageNameLabel) + .addGap(36, 36, 36) + .addComponent(jUsageTextLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))) .addGap(36, 36, 36)) .addGroup(layout.createSequentialGroup() .addGap(64, 64, 64) @@ -126,13 +132,14 @@ public final class ContextUsagePanel extends javax.swing.JPanel { .addGroup(layout.createSequentialGroup() .addGap(18, 18, 18) .addComponent(jUsageLabel) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jUsageTextLabel) .addComponent(jUsageNameLabel) - .addComponent(jUsageTextLabel)) - .addGap(18, 18, 18) + .addComponent(jBlankLabel)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jUsageGoToResultButton) - .addGap(0, 24, Short.MAX_VALUE)) + .addGap(0, 0, Short.MAX_VALUE)) ); }// //GEN-END:initComponents @@ -165,9 +172,15 @@ public final class ContextUsagePanel extends javax.swing.JPanel { showUsageText(true); } + private void showUsageLabel(boolean show) { + if (!show) { + jUsageLabel.setText(" "); + } + jUsageLabel.setVisible(show); + } + private void showUsageText(boolean show) { jUsageTextLabel.setVisible(show); - jUsageLabel.setVisible(show); } private void showUsageButton(boolean show) { @@ -175,6 +188,7 @@ public final class ContextUsagePanel extends javax.swing.JPanel { } // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JLabel jBlankLabel; private javax.swing.JButton jUsageGoToResultButton; private javax.swing.JLabel jUsageLabel; private javax.swing.JLabel jUsageNameLabel; diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextViewer.java b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextViewer.java index 296ae39306..a1a25ce14a 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextViewer.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextViewer.java @@ -204,13 +204,13 @@ public final class ContextViewer extends javax.swing.JPanel implements DataConte javax.swing.JPanel contextContainer = new javax.swing.JPanel(); contextContainer.setLayout(new BoxLayout(contextContainer, BoxLayout.Y_AXIS)); if (contextSourcePanels.isEmpty()) { - contextContainer.add(new ContextSourcePanel(Bundle.ContextViewer_unknownSource(), "", null)); + contextContainer.add(new ContextSourcePanel(Bundle.ContextViewer_unknownSource(), "", null, true)); } else for (javax.swing.JPanel sourcePanel : contextSourcePanels) { contextContainer.add(sourcePanel); } if (contextUsagePanels.isEmpty()) { - contextContainer.add(new ContextUsagePanel(Bundle.ContextViewer_unknownSource(), "", null)); + contextContainer.add(new ContextUsagePanel(Bundle.ContextViewer_unknownSource(), "", null, true)); } else for (javax.swing.JPanel usagePanel : contextUsagePanels) { contextContainer.add(usagePanel); @@ -265,24 +265,35 @@ public final class ContextViewer extends javax.swing.JPanel implements DataConte "ContextViewer.recentDocs=Recent Documents: " }) private void setSourceFields(BlackboardArtifact associatedArtifact) throws TskCoreException { + Boolean showHeading = true; if (BlackboardArtifact.ARTIFACT_TYPE.TSK_MESSAGE.getTypeID() == associatedArtifact.getArtifactTypeID() || BlackboardArtifact.ARTIFACT_TYPE.TSK_EMAIL_MSG.getTypeID() == associatedArtifact.getArtifactTypeID()) { String sourceName = Bundle.ContextViewer_attachmentSource(); String sourceText = msgArtifactToAbbreviatedString(associatedArtifact); - javax.swing.JPanel sourcePanel = new ContextSourcePanel(sourceName, sourceText, associatedArtifact); + if (!contextUsagePanels.isEmpty()) { + showHeading = false; + } + javax.swing.JPanel sourcePanel = new ContextSourcePanel(sourceName, sourceText, associatedArtifact, showHeading); contextSourcePanels.add(sourcePanel); } else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_DOWNLOAD.getTypeID() == associatedArtifact.getArtifactTypeID() || BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_CACHE.getTypeID() == associatedArtifact.getArtifactTypeID()) { String sourceName = Bundle.ContextViewer_downloadSource(); String sourceText = webDownloadArtifactToString(associatedArtifact); - javax.swing.JPanel sourcePanel = new ContextSourcePanel(sourceName, sourceText, associatedArtifact); + if (!contextUsagePanels.isEmpty()) { + showHeading = false; + } + javax.swing.JPanel sourcePanel = new ContextSourcePanel(sourceName, sourceText, associatedArtifact, showHeading); contextSourcePanels.add(sourcePanel); } else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_RECENT_OBJECT.getTypeID() == associatedArtifact.getArtifactTypeID()) { String sourceName = Bundle.ContextViewer_recentDocs(); String sourceText = recentDocArtifactToString(associatedArtifact); - javax.swing.JPanel usagePanel = new ContextUsagePanel(sourceName, sourceText, associatedArtifact); + if (!contextUsagePanels.isEmpty()) { + showHeading = false; + } + javax.swing.JPanel usagePanel = new ContextUsagePanel(sourceName, sourceText, associatedArtifact, showHeading); + contextUsagePanels.add(usagePanel); } From 615f34e32bfce34e5f19f23210e1dfbd4535c2d4 Mon Sep 17 00:00:00 2001 From: Mark McKinnon Date: Wed, 11 Mar 2020 16:01:57 -0400 Subject: [PATCH 043/100] Update for Codacy Update for Codacy --- .../contextviewer/Bundle.properties | 2 +- .../contextviewer/Bundle.properties-MERGED | 2 +- .../contextviewer/ContextSourcePanel.form | 20 ++++++++++++++----- .../contextviewer/ContextSourcePanel.java | 15 ++++++-------- .../contextviewer/ContextUsagePanel.java | 19 +----------------- 5 files changed, 24 insertions(+), 34 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/Bundle.properties b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/Bundle.properties index 1f229fd721..11348a5758 100755 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/Bundle.properties @@ -7,4 +7,4 @@ ContextUsagePanel.jUsageNameLabel.text=jUsageLabel ContextSourcePanel.jSourceTextLabel.text=Label2 ContextSourcePanel.jSourceNameLabel.text=jSourceNameLabel ContextUsagePanel.jBlankLabel.text= -ContextSourcePanel.jLabel1.text=\ +ContextSourcePanel.jBlankLabel.text=\ diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/Bundle.properties-MERGED index ccb13c972b..2e3b0cea59 100755 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/Bundle.properties-MERGED @@ -7,7 +7,7 @@ ContextUsagePanel.jUsageNameLabel.text=jUsageLabel ContextSourcePanel.jSourceTextLabel.text=Label2 ContextSourcePanel.jSourceNameLabel.text=jSourceNameLabel ContextUsagePanel.jBlankLabel.text= -ContextSourcePanel.jLabel1.text=\ +ContextSourcePanel.jBlankLabel.text=\ ContextViewer.attachmentSource=Attached to: ContextViewer.downloadedOn=On ContextViewer.downloadSource=Downloaded from: diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextSourcePanel.form b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextSourcePanel.form index 14c45e2f50..d81a72050b 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextSourcePanel.form +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextSourcePanel.form @@ -29,13 +29,15 @@ - + - - + + + + - +
@@ -53,10 +55,11 @@ + - +
@@ -96,5 +99,12 @@
+ + + + + + + diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextSourcePanel.java b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextSourcePanel.java index 9fd9d5ae4e..4c60d9d09a 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextSourcePanel.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextSourcePanel.java @@ -33,9 +33,6 @@ import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_ASSOC public final class ContextSourcePanel extends javax.swing.JPanel { private static final long serialVersionUID = 1L; - private static final Logger logger = Logger.getLogger(ContextSourcePanel.class.getName()); - private static final int ARTIFACT_STR_MAX_LEN = 1024; - private static final int ATTRIBUTE_STR_MAX_LEN = 200; // defines a list of artifacts that provide context for a file private static final List SOURCE_CONTEXT_ARTIFACTS = new ArrayList<>(); @@ -43,7 +40,7 @@ public final class ContextSourcePanel extends javax.swing.JPanel { SOURCE_CONTEXT_ARTIFACTS.add(TSK_ASSOCIATED_OBJECT); } - private BlackboardArtifact sourceContextArtifact; + private final BlackboardArtifact sourceContextArtifact; /** * Creates new form ContextViewer @@ -70,7 +67,7 @@ public final class ContextSourcePanel extends javax.swing.JPanel { jSourceLabel = new javax.swing.JLabel(); jSourceNameLabel = new javax.swing.JLabel(); jSourceTextLabel = new javax.swing.JLabel(); - jLabel1 = new javax.swing.JLabel(); + jBlankLabel = new javax.swing.JLabel(); setBackground(new java.awt.Color(255, 255, 255)); setPreferredSize(new java.awt.Dimension(495, 120)); @@ -89,7 +86,7 @@ public final class ContextSourcePanel extends javax.swing.JPanel { org.openide.awt.Mnemonics.setLocalizedText(jSourceTextLabel, org.openide.util.NbBundle.getMessage(ContextSourcePanel.class, "ContextSourcePanel.jSourceTextLabel.text")); // NOI18N - org.openide.awt.Mnemonics.setLocalizedText(jLabel1, org.openide.util.NbBundle.getMessage(ContextSourcePanel.class, "ContextSourcePanel.jLabel1.text")); // NOI18N + org.openide.awt.Mnemonics.setLocalizedText(jBlankLabel, org.openide.util.NbBundle.getMessage(ContextSourcePanel.class, "ContextSourcePanel.jBlankLabel.text")); // NOI18N javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); @@ -103,7 +100,7 @@ public final class ContextSourcePanel extends javax.swing.JPanel { .addGap(10, 10, 10) .addComponent(jSourceNameLabel) .addGap(5, 5, 5) - .addComponent(jLabel1) + .addComponent(jBlankLabel) .addGap(36, 36, 36) .addComponent(jSourceTextLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))) .addGap(260, 260, 260)) @@ -121,7 +118,7 @@ public final class ContextSourcePanel extends javax.swing.JPanel { .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(jSourceNameLabel) .addComponent(jSourceTextLabel) - .addComponent(jLabel1)) + .addComponent(jBlankLabel)) .addGap(18, 18, 18) .addComponent(jSourceGoToResultButton) .addGap(0, 0, Short.MAX_VALUE)) @@ -174,7 +171,7 @@ public final class ContextSourcePanel extends javax.swing.JPanel { } // Variables declaration - do not modify//GEN-BEGIN:variables - private javax.swing.JLabel jLabel1; + private javax.swing.JLabel jBlankLabel; private javax.swing.JButton jSourceGoToResultButton; private javax.swing.JLabel jSourceLabel; private javax.swing.JLabel jSourceNameLabel; diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextUsagePanel.java b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextUsagePanel.java index f6ae7e6395..1031c9a943 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextUsagePanel.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextUsagePanel.java @@ -18,27 +18,13 @@ */ package org.sleuthkit.autopsy.contentviewers.contextviewer; -import java.awt.Component; import java.util.ArrayList; -import java.util.HashMap; import java.util.List; -import java.util.Map; import java.util.logging.Level; -import org.apache.commons.lang.StringUtils; -import org.openide.nodes.Node; -import org.openide.util.NbBundle; -import org.openide.util.lookup.ServiceProvider; -import org.sleuthkit.autopsy.casemodule.Case; -import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; -import org.sleuthkit.autopsy.corecomponentinterfaces.DataContentViewer; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.directorytree.DirectoryTreeTopComponent; -import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.BlackboardArtifact; import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_ASSOCIATED_OBJECT; -import org.sleuthkit.datamodel.BlackboardAttribute; -import org.sleuthkit.datamodel.SleuthkitCase; -import org.sleuthkit.datamodel.TskCoreException; /** * Displays additional context for the selected file, such as its source, and @@ -48,9 +34,6 @@ import org.sleuthkit.datamodel.TskCoreException; public final class ContextUsagePanel extends javax.swing.JPanel { private static final long serialVersionUID = 1L; - private static final Logger logger = Logger.getLogger(ContextUsagePanel.class.getName()); - private static final int ARTIFACT_STR_MAX_LEN = 1024; - private static final int ATTRIBUTE_STR_MAX_LEN = 200; // defines a list of artifacts that provide context for a file private static final List SOURCE_CONTEXT_ARTIFACTS = new ArrayList<>(); @@ -58,7 +41,7 @@ public final class ContextUsagePanel extends javax.swing.JPanel { SOURCE_CONTEXT_ARTIFACTS.add(TSK_ASSOCIATED_OBJECT); } - private BlackboardArtifact sourceContextArtifact; + private final BlackboardArtifact sourceContextArtifact; /** * Creates new form ContextViewer From 1581e07ea29d764536590500b72c50898dd3ee92 Mon Sep 17 00:00:00 2001 From: esaunders Date: Wed, 11 Mar 2020 16:35:22 -0400 Subject: [PATCH 044/100] Make all interactions with Gstreamer happen on the GST Java bindings service thread. --- .../contentviewers/MediaPlayerPanel.java | 265 ++++++++++-------- 1 file changed, 145 insertions(+), 120 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.java b/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.java index 6df0cf8161..d2d8ace001 100755 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.java @@ -377,14 +377,16 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie } timer.stop(); if (gstPlayBin != null) { - gstPlayBin.stop(); - gstPlayBin.getBus().disconnect(endOfStreamListener); - gstPlayBin.getBus().disconnect(stateChangeListener); - gstPlayBin.getBus().disconnect(errorListener); - gstPlayBin.getBus().dispose(); - gstPlayBin.dispose(); - fxAppSink.clear(); - gstPlayBin = null; + Gst.getExecutor().submit(() -> { + gstPlayBin.stop(); + gstPlayBin.getBus().disconnect(endOfStreamListener); + gstPlayBin.getBus().disconnect(stateChangeListener); + gstPlayBin.getBus().disconnect(errorListener); + gstPlayBin.getBus().dispose(); + gstPlayBin.dispose(); + fxAppSink.clear(); + gstPlayBin = null; + }); } videoPanel.removeAll(); resetComponents(); @@ -539,39 +541,52 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie return; } + // Setting the following property causes the GST + // Java bindings to call dispose() on the GST + // service thread instead of running it in the GST + // Native Object Reaper thread. + System.setProperty("glib.reapOnEDT", "true"); + // Initialize Gstreamer. It is safe to call this for every file. // It was moved here from the constructor because having it happen // earlier resulted in crashes on Linux. See JIRA-5888. Gst.init(); - //Video is ready for playback. Create new components - gstPlayBin = new PlayBin("VideoPlayer", tempFile.toURI()); - //Configure event handling - Bus playBinBus = gstPlayBin.getBus(); - playBinBus.connect(endOfStreamListener); - playBinBus.connect(stateChangeListener); - playBinBus.connect(errorListener); - - if (this.isCancelled()) { + if (!Gst.isInitialized()) { + logger.log(Level.INFO, "GStreamer is not initialized."); //NON-NLS return; } - JFXPanel fxPanel = new JFXPanel(); - videoPanel.removeAll(); - videoPanel.setLayout(new BoxLayout(videoPanel, BoxLayout.Y_AXIS)); - videoPanel.add(fxPanel); - fxAppSink = new JavaFxAppSink("JavaFxAppSink", fxPanel); - gstPlayBin.setVideoSink(fxAppSink); + Gst.getExecutor().submit(() -> { + //Video is ready for playback. Create new components + gstPlayBin = new PlayBin("VideoPlayer", tempFile.toURI()); + //Configure event handling + Bus playBinBus = gstPlayBin.getBus(); + playBinBus.connect(endOfStreamListener); + playBinBus.connect(stateChangeListener); + playBinBus.connect(errorListener); - if (this.isCancelled()) { - return; - } + if (this.isCancelled()) { + return; + } - gstPlayBin.setVolume((audioSlider.getValue() * 2.0) / 100.0); - gstPlayBin.pause(); + JFXPanel fxPanel = new JFXPanel(); + videoPanel.removeAll(); + videoPanel.setLayout(new BoxLayout(videoPanel, BoxLayout.Y_AXIS)); + videoPanel.add(fxPanel); + fxAppSink = new JavaFxAppSink("JavaFxAppSink", fxPanel); + gstPlayBin.setVideoSink(fxAppSink); - timer.start(); - enableComponents(true); + if (this.isCancelled()) { + return; + } + + gstPlayBin.setVolume((audioSlider.getValue() * 2.0) / 100.0); + gstPlayBin.pause(); + + timer.start(); + enableComponents(true); + }); } catch (CancellationException ex) { logger.log(Level.INFO, "Media buffering was canceled."); //NON-NLS } catch (InterruptedException ex) { @@ -588,29 +603,31 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie private class VideoPanelUpdater implements ActionListener { @Override - public void actionPerformed(ActionEvent e) { + public void actionPerformed(ActionEvent e) { if (!progressSlider.getValueIsAdjusting()) { - try { - sliderLock.acquireUninterruptibly(); - long position = gstPlayBin.queryPosition(TimeUnit.NANOSECONDS); - long duration = gstPlayBin.queryDuration(TimeUnit.NANOSECONDS); - /** - * Duration may not be known until there is video data in - * the pipeline. We start this updater when data-flow has - * just been initiated so buffering may still be in - * progress. - */ - if (duration >= 0 && position >= 0) { - double relativePosition = (double) position / duration; - progressSlider.setValue((int) (relativePosition * PROGRESS_SLIDER_SIZE)); - } + Gst.getExecutor().submit(() -> { + try { + sliderLock.acquireUninterruptibly(); + long position = gstPlayBin.queryPosition(TimeUnit.NANOSECONDS); + long duration = gstPlayBin.queryDuration(TimeUnit.NANOSECONDS); + /** + * Duration may not be known until there is video data + * in the pipeline. We start this updater when data-flow + * has just been initiated so buffering may still be in + * progress. + */ + if (duration >= 0 && position >= 0) { + double relativePosition = (double) position / duration; + progressSlider.setValue((int) (relativePosition * PROGRESS_SLIDER_SIZE)); + } - SwingUtilities.invokeLater(() -> { - updateTimeLabel(position, duration); - }); - } finally { - sliderLock.release(); - } + SwingUtilities.invokeLater(() -> { + updateTimeLabel(position, duration); + }); + } finally { + sliderLock.release(); + } + }); } } } @@ -978,87 +995,95 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie }// //GEN-END:initComponents private void rewindButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_rewindButtonActionPerformed - long currentTime = gstPlayBin.queryPosition(TimeUnit.NANOSECONDS); - //Skip 30 seconds. - long rewindDelta = TimeUnit.NANOSECONDS.convert(SKIP_IN_SECONDS, TimeUnit.SECONDS); - //Ensure new video position is within bounds - long newTime = Math.max(currentTime - rewindDelta, 0); - double playBackRate = getPlayBackRate(); - gstPlayBin.seek(playBackRate, - Format.TIME, - //FLUSH - flushes the pipeline - //ACCURATE - video will seek exactly to the position requested - EnumSet.of(SeekFlags.FLUSH, SeekFlags.ACCURATE), - //Set the start position to newTime - SeekType.SET, newTime, - //Do nothing for the end position - SeekType.NONE, -1); - }//GEN-LAST:event_rewindButtonActionPerformed - - private void fastForwardButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_fastForwardButtonActionPerformed - long duration = gstPlayBin.queryDuration(TimeUnit.NANOSECONDS); - long currentTime = gstPlayBin.queryPosition(TimeUnit.NANOSECONDS); - //Skip 30 seconds. - long fastForwardDelta = TimeUnit.NANOSECONDS.convert(SKIP_IN_SECONDS, TimeUnit.SECONDS); - //Don't allow skipping within 2 seconds of video ending. Skipping right to - //the end causes undefined behavior for some gstreamer plugins. - long twoSecondsInNano = TimeUnit.NANOSECONDS.convert(2, TimeUnit.SECONDS); - if ((duration - currentTime) <= twoSecondsInNano) { - return; - } - - long newTime; - if (currentTime + fastForwardDelta >= duration) { - //If there are less than 30 seconds left, only fast forward to the midpoint. - newTime = currentTime + (duration - currentTime) / 2; - } else { - newTime = currentTime + fastForwardDelta; - } - - double playBackRate = getPlayBackRate(); - gstPlayBin.seek(playBackRate, - Format.TIME, - //FLUSH - flushes the pipeline - //ACCURATE - video will seek exactly to the position requested - EnumSet.of(SeekFlags.FLUSH, SeekFlags.ACCURATE), - //Set the start position to newTime - SeekType.SET, newTime, - //Do nothing for the end position - SeekType.NONE, -1); - }//GEN-LAST:event_fastForwardButtonActionPerformed - - private void playButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_playButtonActionPerformed - if (gstPlayBin.isPlaying()) { - gstPlayBin.pause(); - } else { - double playBackRate = getPlayBackRate(); + Gst.getExecutor().submit(() -> { long currentTime = gstPlayBin.queryPosition(TimeUnit.NANOSECONDS); - //Set playback rate before play. + //Skip 30 seconds. + long rewindDelta = TimeUnit.NANOSECONDS.convert(SKIP_IN_SECONDS, TimeUnit.SECONDS); + //Ensure new video position is within bounds + long newTime = Math.max(currentTime - rewindDelta, 0); + double playBackRate = getPlayBackRate(); gstPlayBin.seek(playBackRate, Format.TIME, //FLUSH - flushes the pipeline //ACCURATE - video will seek exactly to the position requested EnumSet.of(SeekFlags.FLUSH, SeekFlags.ACCURATE), //Set the start position to newTime - SeekType.SET, currentTime, + SeekType.SET, newTime, //Do nothing for the end position SeekType.NONE, -1); - gstPlayBin.play(); - } + }); + }//GEN-LAST:event_rewindButtonActionPerformed + + private void fastForwardButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_fastForwardButtonActionPerformed + Gst.getExecutor().submit(() -> { + long duration = gstPlayBin.queryDuration(TimeUnit.NANOSECONDS); + long currentTime = gstPlayBin.queryPosition(TimeUnit.NANOSECONDS); + //Skip 30 seconds. + long fastForwardDelta = TimeUnit.NANOSECONDS.convert(SKIP_IN_SECONDS, TimeUnit.SECONDS); + //Don't allow skipping within 2 seconds of video ending. Skipping right to + //the end causes undefined behavior for some gstreamer plugins. + long twoSecondsInNano = TimeUnit.NANOSECONDS.convert(2, TimeUnit.SECONDS); + if ((duration - currentTime) <= twoSecondsInNano) { + return; + } + + long newTime; + if (currentTime + fastForwardDelta >= duration) { + //If there are less than 30 seconds left, only fast forward to the midpoint. + newTime = currentTime + (duration - currentTime) / 2; + } else { + newTime = currentTime + fastForwardDelta; + } + + double playBackRate = getPlayBackRate(); + gstPlayBin.seek(playBackRate, + Format.TIME, + //FLUSH - flushes the pipeline + //ACCURATE - video will seek exactly to the position requested + EnumSet.of(SeekFlags.FLUSH, SeekFlags.ACCURATE), + //Set the start position to newTime + SeekType.SET, newTime, + //Do nothing for the end position + SeekType.NONE, -1); + }); + }//GEN-LAST:event_fastForwardButtonActionPerformed + + private void playButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_playButtonActionPerformed + Gst.getExecutor().submit(() -> { + if (gstPlayBin.isPlaying()) { + gstPlayBin.pause(); + } else { + double playBackRate = getPlayBackRate(); + long currentTime = gstPlayBin.queryPosition(TimeUnit.NANOSECONDS); + //Set playback rate before play. + gstPlayBin.seek(playBackRate, + Format.TIME, + //FLUSH - flushes the pipeline + //ACCURATE - video will seek exactly to the position requested + EnumSet.of(SeekFlags.FLUSH, SeekFlags.ACCURATE), + //Set the start position to newTime + SeekType.SET, currentTime, + //Do nothing for the end position + SeekType.NONE, -1); + gstPlayBin.play(); + } + }); }//GEN-LAST:event_playButtonActionPerformed private void playBackSpeedComboBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_playBackSpeedComboBoxActionPerformed - double playBackRate = getPlayBackRate(); - long currentTime = gstPlayBin.queryPosition(TimeUnit.NANOSECONDS); - gstPlayBin.seek(playBackRate, - Format.TIME, - //FLUSH - flushes the pipeline - //ACCURATE - video will seek exactly to the position requested - EnumSet.of(SeekFlags.FLUSH, SeekFlags.ACCURATE), - //Set the position to the currentTime, we are only adjusting the - //playback rate. - SeekType.SET, currentTime, - SeekType.NONE, 0); + Gst.getExecutor().submit(() -> { + double playBackRate = getPlayBackRate(); + long currentTime = gstPlayBin.queryPosition(TimeUnit.NANOSECONDS); + gstPlayBin.seek(playBackRate, + Format.TIME, + //FLUSH - flushes the pipeline + //ACCURATE - video will seek exactly to the position requested + EnumSet.of(SeekFlags.FLUSH, SeekFlags.ACCURATE), + //Set the position to the currentTime, we are only adjusting the + //playback rate. + SeekType.SET, currentTime, + SeekType.NONE, 0); + }); }//GEN-LAST:event_playBackSpeedComboBoxActionPerformed // Variables declaration - do not modify//GEN-BEGIN:variables From 43e44ff3ded355cc3ba5c86107b3a0a76f8cff9d Mon Sep 17 00:00:00 2001 From: Mark McKinnon Date: Wed, 11 Mar 2020 17:17:50 -0400 Subject: [PATCH 045/100] More codacy more codacy fixes --- .../contentviewers/contextviewer/ContextSourcePanel.java | 1 - .../autopsy/contentviewers/contextviewer/ContextUsagePanel.java | 2 -- .../autopsy/contentviewers/contextviewer/ContextViewer.java | 1 - 3 files changed, 4 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextSourcePanel.java b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextSourcePanel.java index 4c60d9d09a..9a29dd3023 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextSourcePanel.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextSourcePanel.java @@ -20,7 +20,6 @@ package org.sleuthkit.autopsy.contentviewers.contextviewer; import java.util.ArrayList; import java.util.List; -import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.directorytree.DirectoryTreeTopComponent; import org.sleuthkit.datamodel.BlackboardArtifact; import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_ASSOCIATED_OBJECT; diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextUsagePanel.java b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextUsagePanel.java index 1031c9a943..b1b67461f7 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextUsagePanel.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextUsagePanel.java @@ -20,8 +20,6 @@ package org.sleuthkit.autopsy.contentviewers.contextviewer; import java.util.ArrayList; import java.util.List; -import java.util.logging.Level; -import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.directorytree.DirectoryTreeTopComponent; import org.sleuthkit.datamodel.BlackboardArtifact; import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_ASSOCIATED_OBJECT; diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextViewer.java b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextViewer.java index a1a25ce14a..095a54f4e5 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextViewer.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextViewer.java @@ -20,7 +20,6 @@ package org.sleuthkit.autopsy.contentviewers.contextviewer; import java.awt.Component; import java.util.ArrayList; -import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; From e6e8b7c34336798992c5df581ecf5d1a13bac3e4 Mon Sep 17 00:00:00 2001 From: Mark McKinnon Date: Wed, 11 Mar 2020 17:58:07 -0400 Subject: [PATCH 046/100] Change display of button if unknown source/usage Change display of button if unknown source/usage --- .../contextviewer/Bundle.properties | 2 -- .../contextviewer/Bundle.properties-MERGED | 2 -- .../contextviewer/ContextSourcePanel.form | 14 ++--------- .../contextviewer/ContextSourcePanel.java | 14 +++-------- .../contextviewer/ContextUsagePanel.form | 25 ++++++------------- .../contextviewer/ContextUsagePanel.java | 21 ++++++---------- 6 files changed, 22 insertions(+), 56 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/Bundle.properties b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/Bundle.properties index 11348a5758..554f364be2 100755 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/Bundle.properties @@ -6,5 +6,3 @@ ContextUsagePanel.jUsageTextLabel.text=Label2 ContextUsagePanel.jUsageNameLabel.text=jUsageLabel ContextSourcePanel.jSourceTextLabel.text=Label2 ContextSourcePanel.jSourceNameLabel.text=jSourceNameLabel -ContextUsagePanel.jBlankLabel.text= -ContextSourcePanel.jBlankLabel.text=\ diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/Bundle.properties-MERGED index 2e3b0cea59..304d3f6cb2 100755 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/Bundle.properties-MERGED @@ -6,8 +6,6 @@ ContextUsagePanel.jUsageTextLabel.text=Label2 ContextUsagePanel.jUsageNameLabel.text=jUsageLabel ContextSourcePanel.jSourceTextLabel.text=Label2 ContextSourcePanel.jSourceNameLabel.text=jSourceNameLabel -ContextUsagePanel.jBlankLabel.text= -ContextSourcePanel.jBlankLabel.text=\ ContextViewer.attachmentSource=Attached to: ContextViewer.downloadedOn=On ContextViewer.downloadSource=Downloaded from: diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextSourcePanel.form b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextSourcePanel.form index d81a72050b..5cb66f842b 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextSourcePanel.form +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextSourcePanel.form @@ -29,10 +29,8 @@ - + - - @@ -55,9 +53,8 @@ - - + @@ -99,12 +96,5 @@
- - - - - - - diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextSourcePanel.java b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextSourcePanel.java index 9a29dd3023..073405e6f3 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextSourcePanel.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextSourcePanel.java @@ -66,7 +66,6 @@ public final class ContextSourcePanel extends javax.swing.JPanel { jSourceLabel = new javax.swing.JLabel(); jSourceNameLabel = new javax.swing.JLabel(); jSourceTextLabel = new javax.swing.JLabel(); - jBlankLabel = new javax.swing.JLabel(); setBackground(new java.awt.Color(255, 255, 255)); setPreferredSize(new java.awt.Dimension(495, 120)); @@ -85,8 +84,6 @@ public final class ContextSourcePanel extends javax.swing.JPanel { org.openide.awt.Mnemonics.setLocalizedText(jSourceTextLabel, org.openide.util.NbBundle.getMessage(ContextSourcePanel.class, "ContextSourcePanel.jSourceTextLabel.text")); // NOI18N - org.openide.awt.Mnemonics.setLocalizedText(jBlankLabel, org.openide.util.NbBundle.getMessage(ContextSourcePanel.class, "ContextSourcePanel.jBlankLabel.text")); // NOI18N - javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); layout.setHorizontalGroup( @@ -96,10 +93,8 @@ public final class ContextSourcePanel extends javax.swing.JPanel { .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(jSourceLabel) .addGroup(layout.createSequentialGroup() - .addGap(10, 10, 10) + .addGap(23, 23, 23) .addComponent(jSourceNameLabel) - .addGap(5, 5, 5) - .addComponent(jBlankLabel) .addGap(36, 36, 36) .addComponent(jSourceTextLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))) .addGap(260, 260, 260)) @@ -116,9 +111,8 @@ public final class ContextSourcePanel extends javax.swing.JPanel { .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(jSourceNameLabel) - .addComponent(jSourceTextLabel) - .addComponent(jBlankLabel)) - .addGap(18, 18, 18) + .addComponent(jSourceTextLabel)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jSourceGoToResultButton) .addGap(0, 0, Short.MAX_VALUE)) ); @@ -166,11 +160,11 @@ public final class ContextSourcePanel extends javax.swing.JPanel { } private void showSourceButton(boolean show) { + jSourceGoToResultButton.setVisible(show); jSourceGoToResultButton.setEnabled(show); } // Variables declaration - do not modify//GEN-BEGIN:variables - private javax.swing.JLabel jBlankLabel; private javax.swing.JButton jSourceGoToResultButton; private javax.swing.JLabel jSourceLabel; private javax.swing.JLabel jSourceNameLabel; diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextUsagePanel.form b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextUsagePanel.form index 3dcaf08d66..eac940a85e 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextUsagePanel.form +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextUsagePanel.form @@ -29,11 +29,10 @@ - - + - - + + @@ -48,13 +47,12 @@ - + - - - - - + + + + @@ -98,12 +96,5 @@ - - - - - - - diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextUsagePanel.java b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextUsagePanel.java index b1b67461f7..147fb9179c 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextUsagePanel.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextUsagePanel.java @@ -67,7 +67,6 @@ public final class ContextUsagePanel extends javax.swing.JPanel { jUsageLabel = new javax.swing.JLabel(); jUsageNameLabel = new javax.swing.JLabel(); jUsageTextLabel = new javax.swing.JLabel(); - jBlankLabel = new javax.swing.JLabel(); setBackground(new java.awt.Color(255, 255, 255)); setPreferredSize(new java.awt.Dimension(495, 120)); @@ -86,8 +85,6 @@ public final class ContextUsagePanel extends javax.swing.JPanel { org.openide.awt.Mnemonics.setLocalizedText(jUsageTextLabel, org.openide.util.NbBundle.getMessage(ContextUsagePanel.class, "ContextUsagePanel.jUsageTextLabel.text")); // NOI18N - org.openide.awt.Mnemonics.setLocalizedText(jBlankLabel, org.openide.util.NbBundle.getMessage(ContextUsagePanel.class, "ContextUsagePanel.jBlankLabel.text")); // NOI18N - javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); layout.setHorizontalGroup( @@ -97,11 +94,10 @@ public final class ContextUsagePanel extends javax.swing.JPanel { .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(jUsageLabel) .addGroup(layout.createSequentialGroup() - .addComponent(jBlankLabel) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGap(33, 33, 33) .addComponent(jUsageNameLabel) - .addGap(36, 36, 36) - .addComponent(jUsageTextLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jUsageTextLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 231, Short.MAX_VALUE))) .addGap(36, 36, 36)) .addGroup(layout.createSequentialGroup() .addGap(64, 64, 64) @@ -111,13 +107,12 @@ public final class ContextUsagePanel extends javax.swing.JPanel { layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() - .addGap(18, 18, 18) + .addGap(1, 1, 1) .addComponent(jUsageLabel) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(jUsageTextLabel) - .addComponent(jUsageNameLabel) - .addComponent(jBlankLabel)) + .addComponent(jUsageNameLabel, javax.swing.GroupLayout.Alignment.TRAILING)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jUsageGoToResultButton) .addGap(0, 0, Short.MAX_VALUE)) @@ -165,11 +160,11 @@ public final class ContextUsagePanel extends javax.swing.JPanel { } private void showUsageButton(boolean show) { + jUsageGoToResultButton.setVisible(show); jUsageGoToResultButton.setEnabled(show); } // Variables declaration - do not modify//GEN-BEGIN:variables - private javax.swing.JLabel jBlankLabel; private javax.swing.JButton jUsageGoToResultButton; private javax.swing.JLabel jUsageLabel; private javax.swing.JLabel jUsageNameLabel; From af551fbed0f1276a354c94e47a9d5e21452f4374 Mon Sep 17 00:00:00 2001 From: Raman Arora Date: Thu, 12 Mar 2020 11:45:55 -0400 Subject: [PATCH 047/100] Addressed review comments. --- .../datamodel/CentralRepoDbUpgrader.java | 10 ++++------ .../datamodel/CentralRepoDbUpgrader13To14.java | 7 ++++--- .../centralrepository/datamodel/RdbmsCentralRepo.java | 2 +- .../datamodel/RdbmsCentralRepoFactory.java | 2 +- 4 files changed, 10 insertions(+), 11 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbUpgrader.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbUpgrader.java index c461b841db..ffd0d2936e 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbUpgrader.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbUpgrader.java @@ -23,7 +23,7 @@ import java.sql.SQLException; import org.sleuthkit.datamodel.CaseDbSchemaVersionNumber; /** - * Common interface to upgrade central repository database schema + * Common interface to upgrade central repository database schema. */ public interface CentralRepoDbUpgrader { @@ -31,13 +31,11 @@ public interface CentralRepoDbUpgrader { * Updates the Central Repository schema using the given open connection. * * @param dbSchemaVersion Current schema version. - * @param connection Connection to use for upgrade - * - * @return New schema version. + * @param connection Connection to use for upgrade. * * @throws CentralRepoException If there is an error in upgrade. - * @throws SQLException in case of any SQL errors. + * @throws SQLException If there is any SQL errors. */ - CaseDbSchemaVersionNumber upgradeSchema(CaseDbSchemaVersionNumber dbSchemaVersion, Connection connection) throws CentralRepoException, SQLException; + void upgradeSchema(CaseDbSchemaVersionNumber dbSchemaVersion, Connection connection) throws CentralRepoException, SQLException; } diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbUpgrader13To14.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbUpgrader13To14.java index b8eedacac4..f4ddbca089 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbUpgrader13To14.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbUpgrader13To14.java @@ -33,7 +33,7 @@ import org.sleuthkit.datamodel.CaseDbSchemaVersionNumber; public class CentralRepoDbUpgrader13To14 implements CentralRepoDbUpgrader { @Override - public CaseDbSchemaVersionNumber upgradeSchema(CaseDbSchemaVersionNumber dbSchemaVersion, Connection connection) throws CentralRepoException, SQLException { + public void upgradeSchema(CaseDbSchemaVersionNumber dbSchemaVersion, Connection connection) throws CentralRepoException, SQLException { if (dbSchemaVersion.compareTo(new CaseDbSchemaVersionNumber(1, 4)) < 0) { @@ -68,6 +68,8 @@ public class CentralRepoDbUpgrader13To14 implements CentralRepoDbUpgrader { statement.execute(sqlStr); // SQLite does NOT allow adding a constraint with Alter Table statement. + // The alternative would be to create new tables, copy all data over, and delete old tables - potentially a time consuming process. + // We decided to not add this constraint for SQLite, since there likely aren't many users using SQLite based Central Repo. if (selectedPlatform == CentralRepoPlatforms.POSTGRESQL) { sqlStr = String.format(getAlterArtifactInstancesAddAccountIdConstraintTemplate(), instance_type_dbname); statement.execute(sqlStr); @@ -75,12 +77,11 @@ public class CentralRepoDbUpgrader13To14 implements CentralRepoDbUpgrader { } } - // insert default data + // insert default accounts data RdbmsCentralRepoFactory.insertDefaultAccountsTablesContent(connection, selectedPlatform); } } - return new CaseDbSchemaVersionNumber(1, 4); } /** diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/RdbmsCentralRepo.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/RdbmsCentralRepo.java index 752eb1dfe4..727008971c 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/RdbmsCentralRepo.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/RdbmsCentralRepo.java @@ -3810,7 +3810,7 @@ abstract class RdbmsCentralRepo implements CentralRepository { } // Upgrade to 1.4 - CaseDbSchemaVersionNumber newVer = new CentralRepoDbUpgrader13To14().upgradeSchema(dbSchemaVersion, conn); + (new CentralRepoDbUpgrader13To14()).upgradeSchema(dbSchemaVersion, conn); updateSchemaVersion(conn); conn.commit(); diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/RdbmsCentralRepoFactory.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/RdbmsCentralRepoFactory.java index 06d9c6d1b3..1232d708a6 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/RdbmsCentralRepoFactory.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/RdbmsCentralRepoFactory.java @@ -847,7 +847,7 @@ public class RdbmsCentralRepoFactory { } } catch (SQLException ex) { - LOGGER.log(Level.SEVERE, String.format("Failed to populate default data in Persona tables."), ex); + LOGGER.log(Level.SEVERE, String.format("Failed to populate default data in account_types table."), ex); return false; } From ddbab95c112a49179d52760a06c3e3a566dfbf99 Mon Sep 17 00:00:00 2001 From: apriestman Date: Thu, 12 Mar 2020 14:49:55 -0400 Subject: [PATCH 048/100] Doxygen fixes --- Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.java | 2 +- .../autopsy/texttranslation/ui/TranslateTextTask.java | 4 ++-- .../autopsy/texttranslation/ui/TranslatedTextViewer.java | 4 +--- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.java b/Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.java index 8c6e879c76..0462e77842 100755 --- a/Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.java +++ b/Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.java @@ -434,7 +434,7 @@ final public class MapPanel extends javax.swing.JPanel { /** * Find the waypoint that is closest to the given mouse click point. * - * @param mouseClickPoint The mouse click point + * @param clickPoint The mouse click point * * @return A waypoint that is within 10 pixels of the given point, or null * if none was found. diff --git a/Core/src/org/sleuthkit/autopsy/texttranslation/ui/TranslateTextTask.java b/Core/src/org/sleuthkit/autopsy/texttranslation/ui/TranslateTextTask.java index 9fe93b21ab..245052d4a4 100644 --- a/Core/src/org/sleuthkit/autopsy/texttranslation/ui/TranslateTextTask.java +++ b/Core/src/org/sleuthkit/autopsy/texttranslation/ui/TranslateTextTask.java @@ -81,9 +81,9 @@ public abstract class TranslateTextTask extends SwingWorker Date: Thu, 12 Mar 2020 14:54:31 -0400 Subject: [PATCH 049/100] Missed one --- .../autopsy/commandlineingest/CommandLineIngestManager.java | 1 + 1 file changed, 1 insertion(+) diff --git a/Core/src/org/sleuthkit/autopsy/commandlineingest/CommandLineIngestManager.java b/Core/src/org/sleuthkit/autopsy/commandlineingest/CommandLineIngestManager.java index 3dfaf53001..f5d9a5c641 100755 --- a/Core/src/org/sleuthkit/autopsy/commandlineingest/CommandLineIngestManager.java +++ b/Core/src/org/sleuthkit/autopsy/commandlineingest/CommandLineIngestManager.java @@ -343,6 +343,7 @@ public class CommandLineIngestManager { * @param baseCaseName Case name * @param rootOutputDirectory Full path to directory in which case * output folder will be created + * @param caseType Type of case being created * * @throws CaseActionException */ From 769bdc430b9f1c1b4dcd6944f8123100b973a325 Mon Sep 17 00:00:00 2001 From: Mark McKinnon Date: Thu, 12 Mar 2020 14:56:05 -0400 Subject: [PATCH 050/100] Use more Panels and COdacy Use more panels to cleanup display and codacy changes. --- .../contextviewer/Bundle.properties | 5 +- .../contextviewer/Bundle.properties-MERGED | 5 +- .../contextviewer/ContextSourcePanel.form | 34 ++--- .../contextviewer/ContextSourcePanel.java | 39 ++---- .../contextviewer/ContextUsagePanel.form | 33 +---- .../contextviewer/ContextUsagePanel.java | 41 ++---- .../contextviewer/ContextViewer.form | 130 +++++++++++++++++- .../contextviewer/ContextViewer.java | 126 +++++++++++++---- 8 files changed, 267 insertions(+), 146 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/Bundle.properties b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/Bundle.properties index 554f364be2..45a1603c17 100755 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/Bundle.properties @@ -1,8 +1,9 @@ ContextUsagePanel.jUsageGoToResultButton.text=Go to Result ContextSourcePanel.jSourceGoToResultButton.text=Go to Result -ContextSourcePanel.jSourceLabel.text=Source -ContextUsagePanel.jUsageLabel.text=Usage ContextUsagePanel.jUsageTextLabel.text=Label2 ContextUsagePanel.jUsageNameLabel.text=jUsageLabel ContextSourcePanel.jSourceTextLabel.text=Label2 ContextSourcePanel.jSourceNameLabel.text=jSourceNameLabel +ContextViewer.jSourceLabel.text=Usage +ContextViewer.jUsageLabel.text=Source +ContextViewer.jUnknownLabel.text=Unknown diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/Bundle.properties-MERGED index 304d3f6cb2..c8cebe69fc 100755 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/Bundle.properties-MERGED @@ -1,7 +1,5 @@ ContextUsagePanel.jUsageGoToResultButton.text=Go to Result ContextSourcePanel.jSourceGoToResultButton.text=Go to Result -ContextSourcePanel.jSourceLabel.text=Source -ContextUsagePanel.jUsageLabel.text=Usage ContextUsagePanel.jUsageTextLabel.text=Label2 ContextUsagePanel.jUsageNameLabel.text=jUsageLabel ContextSourcePanel.jSourceTextLabel.text=Label2 @@ -11,6 +9,9 @@ ContextViewer.downloadedOn=On ContextViewer.downloadSource=Downloaded from: ContextViewer.downloadURL=URL ContextViewer.email=Email +ContextViewer.jSourceLabel.text=Usage +ContextViewer.jUsageLabel.text=Source +ContextViewer.jUnknownLabel.text=Unknown ContextViewer.message=Message ContextViewer.messageFrom=From ContextViewer.messageOn=On diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextSourcePanel.form b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextSourcePanel.form index 5cb66f842b..c57a0990a8 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextSourcePanel.form +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextSourcePanel.form @@ -6,7 +6,7 @@ - + @@ -25,20 +25,14 @@ - - - - - - - - - - + + + + - + @@ -47,16 +41,14 @@ - - - + - + @@ -72,16 +64,6 @@ - - - - - - - - - - diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextSourcePanel.java b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextSourcePanel.java index 073405e6f3..284a66cf04 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextSourcePanel.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextSourcePanel.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2019 Basis Technology Corp. + * Copyright 2020 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -44,13 +44,12 @@ public final class ContextSourcePanel extends javax.swing.JPanel { /** * Creates new form ContextViewer */ - public ContextSourcePanel(String sourceName, String sourceText, BlackboardArtifact associatedArtifact, Boolean showSourceHeading) { + public ContextSourcePanel(String sourceName, String sourceText, BlackboardArtifact associatedArtifact) { initComponents(); sourceContextArtifact = associatedArtifact; setSourceName(sourceName); setSourceText(sourceText); - showSourceLabel(showSourceHeading); } /** @@ -63,12 +62,11 @@ public final class ContextSourcePanel extends javax.swing.JPanel { private void initComponents() { jSourceGoToResultButton = new javax.swing.JButton(); - jSourceLabel = new javax.swing.JLabel(); jSourceNameLabel = new javax.swing.JLabel(); jSourceTextLabel = new javax.swing.JLabel(); setBackground(new java.awt.Color(255, 255, 255)); - setPreferredSize(new java.awt.Dimension(495, 120)); + setPreferredSize(new java.awt.Dimension(495, 75)); org.openide.awt.Mnemonics.setLocalizedText(jSourceGoToResultButton, org.openide.util.NbBundle.getMessage(ContextSourcePanel.class, "ContextSourcePanel.jSourceGoToResultButton.text")); // NOI18N jSourceGoToResultButton.addActionListener(new java.awt.event.ActionListener() { @@ -77,9 +75,6 @@ public final class ContextSourcePanel extends javax.swing.JPanel { } }); - jSourceLabel.setFont(new java.awt.Font("Dialog", 1, 14)); // NOI18N - org.openide.awt.Mnemonics.setLocalizedText(jSourceLabel, org.openide.util.NbBundle.getMessage(ContextSourcePanel.class, "ContextSourcePanel.jSourceLabel.text")); // NOI18N - org.openide.awt.Mnemonics.setLocalizedText(jSourceNameLabel, org.openide.util.NbBundle.getMessage(ContextSourcePanel.class, "ContextSourcePanel.jSourceNameLabel.text")); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(jSourceTextLabel, org.openide.util.NbBundle.getMessage(ContextSourcePanel.class, "ContextSourcePanel.jSourceTextLabel.text")); // NOI18N @@ -89,32 +84,26 @@ public final class ContextSourcePanel extends javax.swing.JPanel { layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() - .addContainerGap() - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(jSourceLabel) - .addGroup(layout.createSequentialGroup() - .addGap(23, 23, 23) - .addComponent(jSourceNameLabel) - .addGap(36, 36, 36) - .addComponent(jSourceTextLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))) + .addGap(50, 50, 50) + .addComponent(jSourceNameLabel) + .addGap(36, 36, 36) + .addComponent(jSourceTextLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addGap(260, 260, 260)) .addGroup(layout.createSequentialGroup() - .addGap(64, 64, 64) + .addGap(90, 90, 90) .addComponent(jSourceGoToResultButton) .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() - .addGap(18, 18, 18) - .addComponent(jSourceLabel) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGap(2, 2, 2) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(jSourceNameLabel) .addComponent(jSourceTextLabel)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jSourceGoToResultButton) - .addGap(0, 0, Short.MAX_VALUE)) + .addGap(0, 0, 0)) ); }// //GEN-END:initComponents @@ -148,13 +137,6 @@ public final class ContextSourcePanel extends javax.swing.JPanel { showSourceText(true); } - private void showSourceLabel(boolean show) { - if (!show) { - jSourceLabel.setText(" "); - } - jSourceLabel.setVisible(show); - } - private void showSourceText(boolean show) { jSourceTextLabel.setVisible(show); } @@ -166,7 +148,6 @@ public final class ContextSourcePanel extends javax.swing.JPanel { // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JButton jSourceGoToResultButton; - private javax.swing.JLabel jSourceLabel; private javax.swing.JLabel jSourceNameLabel; private javax.swing.JLabel jSourceTextLabel; // End of variables declaration//GEN-END:variables diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextUsagePanel.form b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextUsagePanel.form index eac940a85e..a3e2a90f84 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextUsagePanel.form +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextUsagePanel.form @@ -6,7 +6,7 @@ - + @@ -25,20 +25,14 @@ - - - - - - - - - - + + + + - + @@ -47,16 +41,13 @@ - - - + - @@ -72,16 +63,6 @@ - - - - - - - - - - diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextUsagePanel.java b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextUsagePanel.java index 147fb9179c..de87d7a5e5 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextUsagePanel.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextUsagePanel.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2019 Basis Technology Corp. + * Copyright 2020 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -44,14 +44,12 @@ public final class ContextUsagePanel extends javax.swing.JPanel { /** * Creates new form ContextViewer */ - public ContextUsagePanel(String sourceName, String sourceText, BlackboardArtifact associatedArtifact, Boolean showUsageHeading) { + public ContextUsagePanel(String sourceName, String sourceText, BlackboardArtifact associatedArtifact) { initComponents(); sourceContextArtifact = associatedArtifact; setUsageName(sourceName); setUsageText(sourceText); - showUsageLabel(showUsageHeading); - } /** @@ -64,12 +62,11 @@ public final class ContextUsagePanel extends javax.swing.JPanel { private void initComponents() { jUsageGoToResultButton = new javax.swing.JButton(); - jUsageLabel = new javax.swing.JLabel(); jUsageNameLabel = new javax.swing.JLabel(); jUsageTextLabel = new javax.swing.JLabel(); setBackground(new java.awt.Color(255, 255, 255)); - setPreferredSize(new java.awt.Dimension(495, 120)); + setPreferredSize(new java.awt.Dimension(495, 75)); org.openide.awt.Mnemonics.setLocalizedText(jUsageGoToResultButton, org.openide.util.NbBundle.getMessage(ContextUsagePanel.class, "ContextUsagePanel.jUsageGoToResultButton.text")); // NOI18N jUsageGoToResultButton.addActionListener(new java.awt.event.ActionListener() { @@ -78,9 +75,6 @@ public final class ContextUsagePanel extends javax.swing.JPanel { } }); - jUsageLabel.setFont(new java.awt.Font("Dialog", 1, 14)); // NOI18N - org.openide.awt.Mnemonics.setLocalizedText(jUsageLabel, org.openide.util.NbBundle.getMessage(ContextUsagePanel.class, "ContextUsagePanel.jUsageLabel.text")); // NOI18N - org.openide.awt.Mnemonics.setLocalizedText(jUsageNameLabel, org.openide.util.NbBundle.getMessage(ContextUsagePanel.class, "ContextUsagePanel.jUsageNameLabel.text")); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(jUsageTextLabel, org.openide.util.NbBundle.getMessage(ContextUsagePanel.class, "ContextUsagePanel.jUsageTextLabel.text")); // NOI18N @@ -90,32 +84,25 @@ public final class ContextUsagePanel extends javax.swing.JPanel { layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() - .addContainerGap() - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(jUsageLabel) - .addGroup(layout.createSequentialGroup() - .addGap(33, 33, 33) - .addComponent(jUsageNameLabel) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(jUsageTextLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 231, Short.MAX_VALUE))) + .addGap(50, 50, 50) + .addComponent(jUsageNameLabel) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jUsageTextLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 240, Short.MAX_VALUE) .addGap(36, 36, 36)) .addGroup(layout.createSequentialGroup() - .addGap(64, 64, 64) + .addGap(90, 90, 90) .addComponent(jUsageGoToResultButton) .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() - .addGap(1, 1, 1) - .addComponent(jUsageLabel) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGap(2, 2, 2) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(jUsageTextLabel) .addComponent(jUsageNameLabel, javax.swing.GroupLayout.Alignment.TRAILING)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(jUsageGoToResultButton) - .addGap(0, 0, Short.MAX_VALUE)) + .addComponent(jUsageGoToResultButton)) ); }// //GEN-END:initComponents @@ -148,13 +135,6 @@ public final class ContextUsagePanel extends javax.swing.JPanel { showUsageText(true); } - private void showUsageLabel(boolean show) { - if (!show) { - jUsageLabel.setText(" "); - } - jUsageLabel.setVisible(show); - } - private void showUsageText(boolean show) { jUsageTextLabel.setVisible(show); } @@ -166,7 +146,6 @@ public final class ContextUsagePanel extends javax.swing.JPanel { // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JButton jUsageGoToResultButton; - private javax.swing.JLabel jUsageLabel; private javax.swing.JLabel jUsageNameLabel; private javax.swing.JLabel jUsageTextLabel; // End of variables declaration//GEN-END:variables diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextViewer.form b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextViewer.form index ef3dc9910f..d770a3ee48 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextViewer.form +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextViewer.form @@ -1,6 +1,125 @@
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -24,17 +143,22 @@ - + - + - + + + + + + diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextViewer.java b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextViewer.java index 095a54f4e5..07b6f657be 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextViewer.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextViewer.java @@ -82,20 +82,93 @@ public final class ContextViewer extends javax.swing.JPanel implements DataConte // //GEN-BEGIN:initComponents private void initComponents() { - jScrollPane1 = new javax.swing.JScrollPane(); + jSourcePanel = new javax.swing.JPanel(); + jSourceLabel = new javax.swing.JLabel(); + jUsagePanel = new javax.swing.JPanel(); + jUsageLabel = new javax.swing.JLabel(); + jUnknownPanel = new javax.swing.JPanel(); + jUnknownLabel = new javax.swing.JLabel(); + jScrollPane = new javax.swing.JScrollPane(); + + jSourcePanel.setBackground(javax.swing.UIManager.getDefaults().getColor("window")); + + jSourceLabel.setFont(new java.awt.Font("Dialog", 1, 14)); // NOI18N + org.openide.awt.Mnemonics.setLocalizedText(jSourceLabel, org.openide.util.NbBundle.getMessage(ContextViewer.class, "ContextViewer.jSourceLabel.text")); // NOI18N + + javax.swing.GroupLayout jSourcePanelLayout = new javax.swing.GroupLayout(jSourcePanel); + jSourcePanel.setLayout(jSourcePanelLayout); + jSourcePanelLayout.setHorizontalGroup( + jSourcePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jSourcePanelLayout.createSequentialGroup() + .addGap(40, 40, 40) + .addComponent(jSourceLabel) + .addContainerGap(304, Short.MAX_VALUE)) + ); + jSourcePanelLayout.setVerticalGroup( + jSourcePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jSourcePanelLayout.createSequentialGroup() + .addGap(5, 5, 5) + .addComponent(jSourceLabel) + .addGap(2, 2, 2)) + ); + + jUsagePanel.setBackground(javax.swing.UIManager.getDefaults().getColor("window")); + + jUsageLabel.setFont(new java.awt.Font("Dialog", 1, 14)); // NOI18N + org.openide.awt.Mnemonics.setLocalizedText(jUsageLabel, org.openide.util.NbBundle.getMessage(ContextViewer.class, "ContextViewer.jUsageLabel.text")); // NOI18N + + javax.swing.GroupLayout jUsagePanelLayout = new javax.swing.GroupLayout(jUsagePanel); + jUsagePanel.setLayout(jUsagePanelLayout); + jUsagePanelLayout.setHorizontalGroup( + jUsagePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jUsagePanelLayout.createSequentialGroup() + .addGap(40, 40, 40) + .addComponent(jUsageLabel) + .addContainerGap(298, Short.MAX_VALUE)) + ); + jUsagePanelLayout.setVerticalGroup( + jUsagePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jUsagePanelLayout.createSequentialGroup() + .addGap(2, 2, 2) + .addComponent(jUsageLabel) + .addGap(2, 2, 2)) + ); + + jUnknownPanel.setBackground(new java.awt.Color(255, 255, 255)); + + org.openide.awt.Mnemonics.setLocalizedText(jUnknownLabel, org.openide.util.NbBundle.getMessage(ContextViewer.class, "ContextViewer.jUnknownLabel.text")); // NOI18N + + javax.swing.GroupLayout jUnknownPanelLayout = new javax.swing.GroupLayout(jUnknownPanel); + jUnknownPanel.setLayout(jUnknownPanelLayout); + jUnknownPanelLayout.setHorizontalGroup( + jUnknownPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jUnknownPanelLayout.createSequentialGroup() + .addGap(50, 50, 50) + .addComponent(jUnknownLabel) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + jUnknownPanelLayout.setVerticalGroup( + jUnknownPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jUnknownPanelLayout.createSequentialGroup() + .addGap(2, 2, 2) + .addComponent(jUnknownLabel) + .addGap(2, 2, 2)) + ); setBackground(new java.awt.Color(255, 255, 255)); setPreferredSize(new java.awt.Dimension(495, 358)); + jScrollPane.setBackground(new java.awt.Color(255, 255, 255)); + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 509, Short.MAX_VALUE) + .addComponent(jScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 509, Short.MAX_VALUE) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 335, Short.MAX_VALUE) + .addComponent(jScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 335, Short.MAX_VALUE) ); }// //GEN-END:initComponents @@ -201,26 +274,30 @@ public final class ContextViewer extends javax.swing.JPanel implements DataConte } } javax.swing.JPanel contextContainer = new javax.swing.JPanel(); + contextContainer.add(jSourcePanel); contextContainer.setLayout(new BoxLayout(contextContainer, BoxLayout.Y_AXIS)); if (contextSourcePanels.isEmpty()) { - contextContainer.add(new ContextSourcePanel(Bundle.ContextViewer_unknownSource(), "", null, true)); - } else + contextContainer.add(jUnknownPanel); + } else { for (javax.swing.JPanel sourcePanel : contextSourcePanels) { contextContainer.add(sourcePanel); } + } + contextContainer.add(jUsagePanel); if (contextUsagePanels.isEmpty()) { - contextContainer.add(new ContextUsagePanel(Bundle.ContextViewer_unknownSource(), "", null, true)); - } else + contextContainer.add(jUnknownPanel); + } else { for (javax.swing.JPanel usagePanel : contextUsagePanels) { contextContainer.add(usagePanel); } + } contextContainer.setEnabled(foundASource); contextContainer.setVisible(foundASource); - jScrollPane1.getViewport().setView(contextContainer); - jScrollPane1.setEnabled(foundASource); - jScrollPane1.setVisible(foundASource); - jScrollPane1.repaint(); - jScrollPane1.revalidate(); + jScrollPane.getViewport().setView(contextContainer); + jScrollPane.setEnabled(foundASource); + jScrollPane.setVisible(foundASource); + jScrollPane.repaint(); + jScrollPane.revalidate(); } @@ -264,35 +341,24 @@ public final class ContextViewer extends javax.swing.JPanel implements DataConte "ContextViewer.recentDocs=Recent Documents: " }) private void setSourceFields(BlackboardArtifact associatedArtifact) throws TskCoreException { - Boolean showHeading = true; if (BlackboardArtifact.ARTIFACT_TYPE.TSK_MESSAGE.getTypeID() == associatedArtifact.getArtifactTypeID() || BlackboardArtifact.ARTIFACT_TYPE.TSK_EMAIL_MSG.getTypeID() == associatedArtifact.getArtifactTypeID()) { String sourceName = Bundle.ContextViewer_attachmentSource(); String sourceText = msgArtifactToAbbreviatedString(associatedArtifact); - if (!contextUsagePanels.isEmpty()) { - showHeading = false; - } - javax.swing.JPanel sourcePanel = new ContextSourcePanel(sourceName, sourceText, associatedArtifact, showHeading); + javax.swing.JPanel sourcePanel = new ContextSourcePanel(sourceName, sourceText, associatedArtifact); contextSourcePanels.add(sourcePanel); } else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_DOWNLOAD.getTypeID() == associatedArtifact.getArtifactTypeID() || BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_CACHE.getTypeID() == associatedArtifact.getArtifactTypeID()) { String sourceName = Bundle.ContextViewer_downloadSource(); String sourceText = webDownloadArtifactToString(associatedArtifact); - if (!contextUsagePanels.isEmpty()) { - showHeading = false; - } - javax.swing.JPanel sourcePanel = new ContextSourcePanel(sourceName, sourceText, associatedArtifact, showHeading); + javax.swing.JPanel sourcePanel = new ContextSourcePanel(sourceName, sourceText, associatedArtifact); contextSourcePanels.add(sourcePanel); } else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_RECENT_OBJECT.getTypeID() == associatedArtifact.getArtifactTypeID()) { String sourceName = Bundle.ContextViewer_recentDocs(); String sourceText = recentDocArtifactToString(associatedArtifact); - if (!contextUsagePanels.isEmpty()) { - showHeading = false; - } - javax.swing.JPanel usagePanel = new ContextUsagePanel(sourceName, sourceText, associatedArtifact, showHeading); - + javax.swing.JPanel usagePanel = new ContextUsagePanel(sourceName, sourceText, associatedArtifact); contextUsagePanels.add(usagePanel); } @@ -437,6 +503,12 @@ public final class ContextViewer extends javax.swing.JPanel implements DataConte // Variables declaration - do not modify//GEN-BEGIN:variables - private javax.swing.JScrollPane jScrollPane1; + private javax.swing.JScrollPane jScrollPane; + private javax.swing.JLabel jSourceLabel; + private javax.swing.JPanel jSourcePanel; + private javax.swing.JLabel jUnknownLabel; + private javax.swing.JPanel jUnknownPanel; + private javax.swing.JLabel jUsageLabel; + private javax.swing.JPanel jUsagePanel; // End of variables declaration//GEN-END:variables } From e734541e4790b79572dc1d04c5564b572a2856a5 Mon Sep 17 00:00:00 2001 From: Mark McKinnon Date: Thu, 12 Mar 2020 15:25:28 -0400 Subject: [PATCH 051/100] Update ContextViewer.java Codacy Fixes --- .../autopsy/contentviewers/contextviewer/ContextViewer.java | 6 ------ 1 file changed, 6 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextViewer.java b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextViewer.java index 07b6f657be..cc2680b102 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextViewer.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextViewer.java @@ -33,7 +33,6 @@ import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; import org.sleuthkit.autopsy.corecomponentinterfaces.DataContentViewer; import org.sleuthkit.autopsy.coreutils.Logger; -import org.sleuthkit.autopsy.directorytree.DirectoryTreeTopComponent; import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.BlackboardArtifact; import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_ASSOCIATED_OBJECT; @@ -63,8 +62,6 @@ public final class ContextViewer extends javax.swing.JPanel implements DataConte SOURCE_CONTEXT_ARTIFACTS.add(TSK_ASSOCIATED_OBJECT); } - private BlackboardArtifact sourceContextArtifact; - /** * Creates new form ContextViewer */ @@ -319,9 +316,6 @@ public final class ContextViewer extends javax.swing.JPanel implements DataConte long artifactId = associatedArtifactAttribute.getValueLong(); BlackboardArtifact associatedArtifact = artifact.getSleuthkitCase().getBlackboardArtifact(artifactId); - //save the artifact for "Go to Result" button - sourceContextArtifact = associatedArtifact; - setSourceFields(associatedArtifact); } } From 6ee3aeeecdf28df3901e5b4ba09fbf94d00a4f9b Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Thu, 12 Mar 2020 16:17:26 -0400 Subject: [PATCH 052/100] updated to enforce invariants --- .../datamodel/CentralRepoDbManager.java | 52 +++++++++++++++++-- .../optionspanel/EamDbSettingsDialog.java | 16 +++--- .../optionspanel/GlobalSettingsPanel.java | 27 +++++----- 3 files changed, 71 insertions(+), 24 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java index f346ab281e..e7933edbee 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java @@ -25,6 +25,7 @@ import java.sql.SQLException; import java.util.logging.Level; import org.openide.util.NbBundle; import org.sleuthkit.autopsy.coordinationservice.CoordinationService; +import org.sleuthkit.autopsy.core.UserPreferences; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.ModuleSettings; @@ -47,11 +48,30 @@ public class CentralRepoDbManager { private static final Object dbChoiceLock = new Object(); private static final Object disabledDueToFailureLock = new Object(); + + /** - * Save the selected platform to the config file. + * This saves the currently selected database choice and clears any disabledDueToFailure flag. + * @param choice the choice to save. + * @return the newly saved choice */ public static CentralRepoDbChoice saveDbChoice(CentralRepoDbChoice choice) { + return saveDbChoice(choice, true); + } + + /** + * This saves the currently selected database choice. + * @param choice the choice to save. + * @param clearDisabledDueToError whether or not to clear the 'disabledDueToFailure' settings key. + * @return the newly saved choice + */ + public static CentralRepoDbChoice saveDbChoice(CentralRepoDbChoice choice, boolean clearDisabledDueToError) { synchronized(dbChoiceLock) { + // clear disabling due to a failure + if (clearDisabledDueToError) + setDisabledDueToFailure(false); + + // change the settings CentralRepoDbChoice newChoice = (choice == null) ? CentralRepoDbChoice.DISABLED : choice; CentralRepoDbChoice oldChoice = savedChoice; savedChoice = newChoice; @@ -61,6 +81,22 @@ public class CentralRepoDbManager { } } + + /** + * This method indicates whether or not 'PostgreSQL using multi-user settings' is a valid option. + * @return true if 'PostgreSQL using multi-user settings' is valid. + */ + public static boolean isPostgresMultiuserAllowed() { + // if multi user mode is not enabled, then this cannot be used + if (!UserPreferences.getIsMultiUserModeEnabled()) + return false; + + // also validate the connection as well + PostgresCentralRepoSettings multiUserSettings = + new PostgresCentralRepoSettings(PostgresSettingsLoader.MULTIUSER_SETTINGS_LOADER); + + return multiUserSettings.testStatus() == DatabaseTestResult.TESTED_OK; + } /** @@ -77,13 +113,23 @@ public class CentralRepoDbManager { } } + /** + * disable the central repository and indicate through a flag that this was due to a failure during database setup. + * this is used when re-enabling multi-user as a flag to determine whether or not CR should be re-enabled. + * NOTE: cr is disabled while persisting database choice. + */ + public static void disableDueToFailure() { + CentralRepoDbUtil.setUseCentralRepo(false); + setDisabledDueToFailure(true); + } + /** * set whether or not the repository has been disabled due to a database setup issue; * this is used when re-enabling multi-user as a flag to determine whether or not CR should be re-enabled * * @param disabledDueToFailure whether or not the repository has been disabled due to a database setup issue */ - public static void setDisabledDueToFailure(boolean disabledDueToFailure) { + private static void setDisabledDueToFailure(boolean disabledDueToFailure) { synchronized(disabledDueToFailureLock) { boolean oldValue = isDisabledDueToFailure(); ModuleSettings.setConfigSetting(CENTRAL_REPOSITORY_SETTINGS_KEY, DISABLED_DUE_TO_FAILURE_KEY, Boolean.toString(disabledDueToFailure)); @@ -243,7 +289,7 @@ public class CentralRepoDbManager { } catch (CentralRepoException ex2) { logger.log(Level.SEVERE, "Error shutting down central repo connection pool", ex2); } - saveDbChoice(CentralRepoDbChoice.DISABLED); + saveDbChoice(CentralRepoDbChoice.DISABLED, false); if (innerException == null) { throw new CentralRepoException(message, desc); } else { diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java index de06d6c9ab..b599784d9a 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java @@ -62,16 +62,11 @@ public class EamDbSettingsDialog extends JDialog { private static final Logger logger = Logger.getLogger(EamDbSettingsDialog.class.getName()); private static final long serialVersionUID = 1L; - private static final DbChoiceRenderer DB_CHOICE_RENDERER = new DbChoiceRenderer(); - - private static boolean isDbChoiceSelectable(CentralRepoDbChoice item) { - return (item != CentralRepoDbChoice.POSTGRESQL_MULTIUSER || UserPreferences.getIsMultiUserModeEnabled()); - } /** * handles displaying and rendering drop down menu for database choices in central repo */ - private static class DbChoiceRenderer extends BasicComboBoxRenderer { + private class DbChoiceRenderer extends BasicComboBoxRenderer { private static final long serialVersionUID = 1L; public Component getListCellRendererComponent(JList list, Object value, @@ -91,11 +86,18 @@ public class EamDbSettingsDialog extends JDialog { private final Collection textBoxes; private final TextBoxChangedListener textBoxChangedListener; private final CentralRepoDbManager manager = new CentralRepoDbManager(); - + private final boolean isMultiUserSelectable = CentralRepoDbManager.isPostgresMultiuserAllowed(); + private final DbChoiceRenderer DB_CHOICE_RENDERER = new DbChoiceRenderer(); + public EamDbSettingsDialog() { this(null); } + private boolean isDbChoiceSelectable(CentralRepoDbChoice item) { + return (item != CentralRepoDbChoice.POSTGRESQL_MULTIUSER || isMultiUserSelectable); + } + + /** * Creates new form EamDbSettingsDialog */ diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java index 0064e16e51..2b594a0ce1 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java @@ -177,7 +177,7 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i private static void askForCentralRepoDbChoice(Component parent) { // disable central repository until user makes choice CentralRepoDbUtil.setUseCentralRepo(false); - CentralRepoDbManager.saveDbChoice(CentralRepoDbChoice.DISABLED); + CentralRepoDbManager.saveDbChoice(CentralRepoDbChoice.DISABLED, false); Object[] options = { "Use SQLite", @@ -214,14 +214,11 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i SwingUtilities.invokeLater(() -> { boolean successful = EamDbSettingsDialog.testStatusAndCreate(parent, new CentralRepoDbManager()); if (successful) { - updateDatabase(parent); - // clear any error if there was one - CentralRepoDbManager.setDisabledDueToFailure(false); + updateDatabase(parent); } else { - CentralRepoDbUtil.setUseCentralRepo(false); // disable central repository due to error - CentralRepoDbManager.setDisabledDueToFailure(true); + CentralRepoDbManager.disableDueToFailure(); } }); } @@ -593,6 +590,16 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i private void cbUseCentralRepoActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cbUseCentralRepoActionPerformed //if saved setting is disabled checkbox should be disabled already store(); + + // if moving to using CR, multi-user mode is disabled and selection is multiuser settings, set to disabled + if (cbUseCentralRepo.isSelected() && + !CentralRepoDbManager.isPostgresMultiuserAllowed() && + CentralRepoDbManager.getSavedDbChoice() == CentralRepoDbChoice.POSTGRESQL_MULTIUSER) { + + CentralRepoDbManager.saveDbChoice(CentralRepoDbChoice.DISABLED); + } + + updateDatabase(); load(); this.ingestStateUpdated(Case.isCaseOpen()); @@ -638,14 +645,6 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i @Override public void store() { // Click OK or Apply on Options Panel CentralRepoDbUtil.setUseCentralRepo(cbUseCentralRepo.isSelected()); - - // if moving to using CR, multi-user mode is disabled and selection is multiuser settings, set to disabled - if (cbUseCentralRepo.isSelected() && - !UserPreferences.getIsMultiUserModeEnabled() && - CentralRepoDbManager.getSavedDbChoice() == CentralRepoDbChoice.POSTGRESQL_MULTIUSER) { - - CentralRepoDbManager.saveDbChoice(CentralRepoDbChoice.DISABLED); - } } /** From 67e06fd853c36e5d7c063b3708000312dbf69f6b Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Thu, 12 Mar 2020 16:29:11 -0400 Subject: [PATCH 053/100] removed unused imports --- .../centralrepository/optionspanel/EamDbSettingsDialog.java | 1 - .../centralrepository/optionspanel/GlobalSettingsPanel.java | 1 - 2 files changed, 2 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java index b599784d9a..c422e04d76 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java @@ -51,7 +51,6 @@ import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoException; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoPlatforms; import org.sleuthkit.autopsy.centralrepository.datamodel.DatabaseTestResult; import org.sleuthkit.autopsy.centralrepository.datamodel.SqliteCentralRepoSettings; -import org.sleuthkit.autopsy.core.UserPreferences; /** * Configuration dialog for Central Repository database settings. diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java index 2b594a0ce1..c65ac2f0c6 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java @@ -44,7 +44,6 @@ import org.sleuthkit.autopsy.centralrepository.datamodel.PostgresCentralRepoSett import org.sleuthkit.autopsy.centralrepository.datamodel.SqliteCentralRepoSettings; import java.awt.Component; import java.util.logging.Level; -import org.sleuthkit.autopsy.core.UserPreferences; /** * Main settings panel for the Central Repository From 8ec00bd05093ce4414a0889c5064386906232baa Mon Sep 17 00:00:00 2001 From: Mark McKinnon Date: Thu, 12 Mar 2020 20:37:59 -0400 Subject: [PATCH 054/100] Set sHorizontal Scrollbar as needed and codacy Set sHorizontal Scrollbar as needed and codacy --- .../contentviewers/contextviewer/ContextViewer.form | 12 ++++++++++++ .../contentviewers/contextviewer/ContextViewer.java | 11 +++++------ 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextViewer.form b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextViewer.form index d770a3ee48..42c7b19f1a 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextViewer.form +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextViewer.form @@ -39,6 +39,10 @@ + + + + @@ -79,6 +83,10 @@ + + + + @@ -116,6 +124,10 @@ + + + + diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextViewer.java b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextViewer.java index cc2680b102..f6d7e8f366 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextViewer.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextViewer.java @@ -25,6 +25,7 @@ import java.util.List; import java.util.Map; import java.util.logging.Level; import javax.swing.BoxLayout; +import static javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED; import org.apache.commons.lang.StringUtils; import org.openide.nodes.Node; import org.openide.util.NbBundle; @@ -68,6 +69,7 @@ public final class ContextViewer extends javax.swing.JPanel implements DataConte public ContextViewer() { initComponents(); + jScrollPane.setHorizontalScrollBarPolicy(HORIZONTAL_SCROLLBAR_AS_NEEDED); } /** @@ -80,11 +82,11 @@ public final class ContextViewer extends javax.swing.JPanel implements DataConte private void initComponents() { jSourcePanel = new javax.swing.JPanel(); - jSourceLabel = new javax.swing.JLabel(); + javax.swing.JLabel jSourceLabel = new javax.swing.JLabel(); jUsagePanel = new javax.swing.JPanel(); - jUsageLabel = new javax.swing.JLabel(); + javax.swing.JLabel jUsageLabel = new javax.swing.JLabel(); jUnknownPanel = new javax.swing.JPanel(); - jUnknownLabel = new javax.swing.JLabel(); + javax.swing.JLabel jUnknownLabel = new javax.swing.JLabel(); jScrollPane = new javax.swing.JScrollPane(); jSourcePanel.setBackground(javax.swing.UIManager.getDefaults().getColor("window")); @@ -498,11 +500,8 @@ public final class ContextViewer extends javax.swing.JPanel implements DataConte // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JScrollPane jScrollPane; - private javax.swing.JLabel jSourceLabel; private javax.swing.JPanel jSourcePanel; - private javax.swing.JLabel jUnknownLabel; private javax.swing.JPanel jUnknownPanel; - private javax.swing.JLabel jUsageLabel; private javax.swing.JPanel jUsagePanel; // End of variables declaration//GEN-END:variables } From e947e4d530c137d1b658542ef78c97e99360ecba Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Fri, 13 Mar 2020 07:51:51 -0400 Subject: [PATCH 055/100] Tidy up BlackboardArtifactNOde.java --- .../datamodel/BlackboardArtifactNode.java | 485 ++++++++++-------- .../datamodel/Bundle.properties-MERGED | 3 - 2 files changed, 261 insertions(+), 227 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java index 17b8248f06..1126cb1c80 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java @@ -60,7 +60,6 @@ import org.sleuthkit.autopsy.core.UserPreferences; import org.sleuthkit.autopsy.corecomponents.DataResultViewerTable; import org.sleuthkit.autopsy.corecomponents.DataResultViewerTable.Score; import org.sleuthkit.autopsy.coreutils.Logger; -import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil; import static org.sleuthkit.autopsy.datamodel.DisplayableItemNode.findLinked; import org.sleuthkit.autopsy.corecomponents.DataResultViewerTable.HasCommentStatus; import static org.sleuthkit.autopsy.datamodel.AbstractContentNode.backgroundTasksPool; @@ -79,45 +78,56 @@ import org.sleuthkit.datamodel.TskData; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository; /** - * Node wrapping a blackboard artifact object. This is generated from several - * places in the tree. + * An AbstractNode implementation representing an artifact of any type. */ public class BlackboardArtifactNode extends AbstractContentNode { private static final Logger logger = Logger.getLogger(BlackboardArtifactNode.class.getName()); - private static final Set CASE_EVENTS_OF_INTEREST = EnumSet.of(Case.Events.BLACKBOARD_ARTIFACT_TAG_ADDED, + + /* + * This cache is used to avoid repeated trips to the case database for + * Content objects that are the source of multiple artifacts. + */ + private static final Cache contentCache = CacheBuilder.newBuilder().expireAfterWrite(1, TimeUnit.MINUTES).build(); + + /* + * Case application events that affect the property sheets of + * BlackboardArtifactNodes, with one exception, CURRENT_CASE (closed) events + * which triggers content cache invalidation and unregistering of the node's + * ProeprtyChangeListener. + */ + private static final Set CASE_EVENTS_OF_INTEREST = EnumSet.of( + Case.Events.BLACKBOARD_ARTIFACT_TAG_ADDED, Case.Events.BLACKBOARD_ARTIFACT_TAG_DELETED, Case.Events.CONTENT_TAG_ADDED, Case.Events.CONTENT_TAG_DELETED, Case.Events.CURRENT_CASE, Case.Events.CR_COMMENT_CHANGED); - private static Cache contentCache = CacheBuilder.newBuilder() - .expireAfterWrite(1, TimeUnit.MINUTES). - build(); - - private final BlackboardArtifact artifact; - private Content associated = null; - - private List> customProperties; - /* - * Artifact types which should have the full unique path of the associated - * content as a property. + * Artifact types which should display the full unique path of the source + * content in their property sheets. */ private static final Integer[] SHOW_UNIQUE_PATH = new Integer[]{ BlackboardArtifact.ARTIFACT_TYPE.TSK_HASHSET_HIT.getTypeID(), BlackboardArtifact.ARTIFACT_TYPE.TSK_KEYWORD_HIT.getTypeID(), BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT.getTypeID(), - BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_ARTIFACT_HIT.getTypeID(),}; + BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_ARTIFACT_HIT.getTypeID() + }; - // TODO (RC): This is an unattractive alternative to subclassing BlackboardArtifactNode, - // cut from the same cloth as the equally unattractive SHOW_UNIQUE_PATH array - // above. It should be removed when and if the subclassing is implemented. + /* + * Artifact types which should display the file metadata of the source + * content, in these cases always a file, in their property sheets. + */ private static final Integer[] SHOW_FILE_METADATA = new Integer[]{ - BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT.getTypeID(),}; + BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT.getTypeID() + }; - private final PropertyChangeListener pcl = new PropertyChangeListener() { + private final BlackboardArtifact artifact; + private Content sourceContent; + private List> customProperties; + + private final PropertyChangeListener appEventListener = new PropertyChangeListener() { @Override public void propertyChange(PropertyChangeEvent evt) { String eventType = evt.getPropertyName(); @@ -133,23 +143,25 @@ public class BlackboardArtifactNode extends AbstractContentNode actionsList = new ArrayList<>(); actionsList.addAll(Arrays.asList(super.getActions(context))); - AbstractFile file = getLookup().lookup(AbstractFile.class); - //if this artifact has a time stamp add the action to view it in the timeline + /* + * If this artifact has a timestamp, add an action to view it in the + * timeline. + */ try { if (ViewArtifactInTimelineAction.hasSupportedTimeStamp(artifact)) { actionsList.add(new ViewArtifactInTimelineAction(artifact)); } } catch (TskCoreException ex) { - logger.log(Level.SEVERE, MessageFormat.format("Error getting arttribute(s) from blackboard artifact{0}.", artifact.getArtifactID()), ex); //NON-NLS - MessageNotifyUtil.Notify.error(Bundle.BlackboardArtifactNode_getAction_errorTitle(), Bundle.BlackboardArtifactNode_getAction_resultErrorMessage()); + logger.log(Level.SEVERE, MessageFormat.format("Error getting attributes of artifact (onbjID={0})", artifact.getArtifactID()), ex); //NON-NLS } - // if the artifact links to another file, add an action to go to that file + /* + * If the artifact is linked to a file via a TSK_PATH_ID attribute add + * an action to view the file in the timeline. + */ try { - AbstractFile c = findLinked(artifact); - if (c != null) { - actionsList.add(ViewFileInTimelineAction.createViewFileAction(c)); + AbstractFile linkedFile = findLinked(artifact); + if (linkedFile != null) { + actionsList.add(ViewFileInTimelineAction.createViewFileAction(linkedFile)); } } catch (TskCoreException ex) { - logger.log(Level.SEVERE, MessageFormat.format("Error getting linked file from blackboard artifact{0}.", artifact.getArtifactID()), ex); //NON-NLS - MessageNotifyUtil.Notify.error(Bundle.BlackboardArtifactNode_getAction_errorTitle(), Bundle.BlackboardArtifactNode_getAction_linkedFileMessage()); + logger.log(Level.SEVERE, MessageFormat.format("Error getting linked file of artifact (onbjID={0})", artifact.getArtifactID()), ex); //NON-NLS } - //if the artifact has associated content, add the action to view the content in the timeline + /* + * If the source content of the artifact is a file, add an action to + * view the file in the data source tree. + */ + AbstractFile file = getLookup().lookup(AbstractFile.class); if (null != file) { actionsList.add(ViewFileInTimelineAction.createViewSourceFileAction(file)); } @@ -288,12 +301,12 @@ public class BlackboardArtifactNode extends AbstractContentNode map = new LinkedHashMap<>(); - fillPropertyMap(map, artifact); - + /* + * Add the name of the artifact's source content to the sheet. + */ sheetSet.put(new NodeProperty<>(NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.srcFile.name"), NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.srcFile.displayName"), NO_DESCR, this.getSourceName())); - // Create place holders for S C O if (!UserPreferences.getHideSCOColumns()) { + /* + * Add the S, C, and O columns to the sheet and start a background + * task to compute the S, C, O values of the artifact. + */ sheetSet.put(new NodeProperty<>(Bundle.BlackboardArtifactNode_createSheet_score_name(), Bundle.BlackboardArtifactNode_createSheet_score_displayName(), VALUE_LOADING, "")); sheetSet.put(new NodeProperty<>(Bundle.BlackboardArtifactNode_createSheet_comment_name(), Bundle.BlackboardArtifactNode_createSheet_comment_displayName(), VALUE_LOADING, "")); if (CentralRepository.isEnabled()) { sheetSet.put(new NodeProperty<>(Bundle.BlackboardArtifactNode_createSheet_count_name(), Bundle.BlackboardArtifactNode_createSheet_count_displayName(), VALUE_LOADING, "")); } - // Get the SCO columns data in a background task - backgroundTasksPool.submit(new GetSCOTask( - new WeakReference<>(this), weakPcl)); + backgroundTasksPool.submit(new GetSCOTask(new WeakReference<>(this), weakAppEventListener)); } + /* + * If the artifact is an interesting artifact hit, add the type and + * description of the interesting artifact to the sheet. + */ if (artifact.getArtifactTypeID() == ARTIFACT_TYPE.TSK_INTERESTING_ARTIFACT_HIT.getTypeID()) { try { BlackboardAttribute attribute = artifact.getAttribute(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT)); @@ -404,10 +420,15 @@ public class BlackboardArtifactNode extends AbstractContentNode map = new LinkedHashMap<>(); + fillPropertyMap(map, artifact); for (Map.Entry entry : map.entrySet()) { sheetSet.put(new NodeProperty<>(entry.getKey(), entry.getKey(), @@ -415,23 +436,28 @@ public class BlackboardArtifactNode extends AbstractContentNode np : customProperties) { sheetSet.put(np); } } - final int artifactTypeId = artifact.getArtifactTypeID(); - // If mismatch, add props for extension and file type + /* + * If the artifact is a file extension mismatch artifact, add the + * extension and type of the file to the sheet. + */ + final int artifactTypeId = artifact.getArtifactTypeID(); if (artifactTypeId == BlackboardArtifact.ARTIFACT_TYPE.TSK_EXT_MISMATCH_DETECTED.getTypeID()) { String ext = ""; //NON-NLS String actualMimeType = ""; //NON-NLS - if (associated instanceof AbstractFile) { - AbstractFile af = (AbstractFile) associated; - ext = af.getNameExtension(); - actualMimeType = af.getMIMEType(); + if (sourceContent instanceof AbstractFile) { + AbstractFile file = (AbstractFile) sourceContent; + ext = file.getNameExtension(); + actualMimeType = file.getMIMEType(); if (actualMimeType == null) { actualMimeType = ""; //NON-NLS } @@ -447,12 +473,16 @@ public class BlackboardArtifactNode extends AbstractContentNode(NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileModifiedTime.name"), NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileModifiedTime.displayName"), "", @@ -484,7 +519,7 @@ public class BlackboardArtifactNode extends AbstractContentNode(NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileSize.name"), NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileSize.displayName"), "", - associated.getSize())); + sourceContent.getSize())); sheetSet.put(new NodeProperty<>(Bundle.BlackboardArtifactNode_createSheet_artifactMD5_name(), Bundle.BlackboardArtifactNode_createSheet_artifactMD5_displayName(), "", @@ -493,14 +528,14 @@ public class BlackboardArtifactNode extends AbstractContentNode getAllTagsFromDatabase() { List tags = new ArrayList<>(); try { tags.addAll(Case.getCurrentCaseThrows().getServices().getTagsManager().getBlackboardArtifactTagsByArtifact(artifact)); - tags.addAll(Case.getCurrentCaseThrows().getServices().getTagsManager().getContentTagsByContent(associated)); + tags.addAll(Case.getCurrentCaseThrows().getServices().getTagsManager().getContentTagsByContent(sourceContent)); } catch (TskCoreException | NoCurrentCaseException ex) { logger.log(Level.SEVERE, "Failed to get tags for artifact " + artifact.getDisplayName(), ex); } @@ -560,89 +595,30 @@ public class BlackboardArtifactNode extends AbstractContentNode tags = new ArrayList<>(); - try { - tags.addAll(Case.getCurrentCaseThrows().getServices().getTagsManager().getBlackboardArtifactTagsByArtifact(artifact)); - tags.addAll(Case.getCurrentCaseThrows().getServices().getTagsManager().getContentTagsByContent(associated)); - } catch (TskCoreException | NoCurrentCaseException ex) { - logger.log(Level.SEVERE, "Failed to get tags for artifact " + artifact.getDisplayName(), ex); - } - sheetSet.put(new NodeProperty<>("Tags", Bundle.BlackboardArtifactNode_createSheet_tags_displayName(), - NO_DESCR, tags.stream().map(t -> t.getName().getDisplayName()).collect(Collectors.joining(", ")))); - } - - /** - * Used by (subclasses of) BlackboardArtifactNode to add the tags property - * to their sheets. - * - * @param sheetSet the modifiable Sheet.Set returned by - * Sheet.get(Sheet.PROPERTIES) - * @param tags the list of tags which should appear as the value for the - * property - */ - @Deprecated - protected final void addTagProperty(Sheet.Set sheetSet, List tags) { - sheetSet.put(new NodeProperty<>("Tags", Bundle.BlackboardArtifactNode_createSheet_tags_displayName(), - NO_DESCR, tags.stream().map(t -> t.getName().getDisplayName()).collect(Collectors.joining(", ")))); - } - - /** - * Gets the correlation attribute for the associated file - * - * @return the correlation attribute for the file associated with this - * BlackboardArtifactNode + * @return The correlation attribute instance, may be null. */ @Override protected final CorrelationAttributeInstance getCorrelationAttributeInstance() { CorrelationAttributeInstance correlationAttribute = null; - if (CentralRepository.isEnabled() && associated instanceof AbstractFile) { - correlationAttribute = CorrelationAttributeUtil.getCorrAttrForFile((AbstractFile)associated); + if (CentralRepository.isEnabled() && sourceContent instanceof AbstractFile) { + correlationAttribute = CorrelationAttributeUtil.getCorrAttrForFile((AbstractFile) sourceContent); } return correlationAttribute; } /** - * Used by (subclasses of) BlackboardArtifactNode to add the comment - * property to their sheets. + * Computes the value of the comment property ("C" in S, C, O) for this + * artifact. * - * @param sheetSet the modifiable Sheet.Set to add the property to - * @param tags the list of tags associated with the file - * @param attribute the correlation attribute associated with this - * artifact's associated file, null if central repo is not - * enabled + * @param tags The tags applied to the artifact and its source content. + * @param attribute The correlation attribute for the MD5 hash of the source + * file of the artifact, may be null. * - * @deprecated Use the GetSCOTask to get this data on a background - * thread..., and then update the property sheet asynchronously - */ - @NbBundle.Messages({"BlackboardArtifactNode.createSheet.comment.name=C", - "BlackboardArtifactNode.createSheet.comment.displayName=C"}) - @Deprecated - protected final void addCommentProperty(Sheet.Set sheetSet, List tags, CorrelationAttributeInstance attribute) { - HasCommentStatus status = getCommentProperty(tags, attribute); - sheetSet.put(new NodeProperty<>(Bundle.BlackboardArtifactNode_createSheet_comment_name(), Bundle.BlackboardArtifactNode_createSheet_comment_displayName(), NO_DESCR, - status)); - } - - /** - * Gets the comment property for the node - * - * @param tags the list of tags associated with the file - * @param attribute the correlation attribute associated with this - * artifact's associated file, null if central repo is not - * enabled - * - * @return comment property + * @return The value of the comment property. */ @Override protected DataResultViewerTable.HasCommentStatus getCommentProperty(List tags, CorrelationAttributeInstance attribute) { @@ -702,8 +678,8 @@ public class BlackboardArtifactNode extends AbstractContentNode getScorePropertyAndDescription(List tags) { Score score = Score.NO_SCORE; String description = Bundle.BlackboardArtifactNode_createSheet_noScore_description(); - if (associated instanceof AbstractFile) { - if (((AbstractFile) associated).getKnown() == TskData.FileKnown.BAD) { + if (sourceContent instanceof AbstractFile) { + if (((AbstractFile) sourceContent).getKnown() == TskData.FileKnown.BAD) { score = Score.NOTABLE_SCORE; description = Bundle.BlackboardArtifactNode_createSheet_notableFile_description(); } @@ -748,30 +724,6 @@ public class BlackboardArtifactNode extends AbstractContentNode countAndDescription = getCountPropertyAndDescription(attribute.getCorrelationType(), attribute.getCorrelationValue(), Bundle.BlackboardArtifactNode_createSheet_count_noCorrelationAttributes_description()); - sheetSet.put( - new NodeProperty<>(Bundle.BlackboardArtifactNode_createSheet_count_name(), Bundle.BlackboardArtifactNode_createSheet_count_displayName(), countAndDescription.getRight(), countAndDescription.getLeft())); - } - /** * Gets the Occurrences property for the node. * @@ -808,14 +760,14 @@ public class BlackboardArtifactNode extends AbstractContentNode T accept(ContentNodeVisitor visitor) { return visitor.visit(this); } + + /** + * Used by (subclasses of) BlackboardArtifactNode to add the tags property + * to their sheets. + * + * @param sheetSet the modifiable Sheet.Set returned by + * Sheet.get(Sheet.PROPERTIES) + */ + @NbBundle.Messages({ + "BlackboardArtifactNode.createSheet.tags.displayName=Tags"}) + @Deprecated + protected void addTagProperty(Sheet.Set sheetSet) throws MissingResourceException { + // add properties for tags + List tags = new ArrayList<>(); + try { + tags.addAll(Case.getCurrentCaseThrows().getServices().getTagsManager().getBlackboardArtifactTagsByArtifact(artifact)); + tags.addAll(Case.getCurrentCaseThrows().getServices().getTagsManager().getContentTagsByContent(sourceContent)); + } catch (TskCoreException | NoCurrentCaseException ex) { + logger.log(Level.SEVERE, "Failed to get tags for artifact " + artifact.getDisplayName(), ex); + } + sheetSet.put(new NodeProperty<>("Tags", Bundle.BlackboardArtifactNode_createSheet_tags_displayName(), + NO_DESCR, tags.stream().map(t -> t.getName().getDisplayName()).collect(Collectors.joining(", ")))); + } + + /** + * Used by (subclasses of) BlackboardArtifactNode to add the tags property + * to their sheets. + * + * @param sheetSet the modifiable Sheet.Set returned by + * Sheet.get(Sheet.PROPERTIES) + * @param tags the list of tags which should appear as the value for the + * property + */ + @Deprecated + protected final void addTagProperty(Sheet.Set sheetSet, List tags) { + sheetSet.put(new NodeProperty<>("Tags", Bundle.BlackboardArtifactNode_createSheet_tags_displayName(), + NO_DESCR, tags.stream().map(t -> t.getName().getDisplayName()).collect(Collectors.joining(", ")))); + } + + /** + * Used by (subclasses of) BlackboardArtifactNode to add the Occurrences + * property to their sheets. + * + * @param sheetSet the modifiable Sheet.Set to add the property to + * @param attribute correlation attribute instance + * + * @deprecated Use the GetSCOTask to get this data on a background + * thread..., and then update the property sheet asynchronously + */ + @NbBundle.Messages({"BlackboardArtifactNode.createSheet.count.name=O", + "BlackboardArtifactNode.createSheet.count.displayName=O", + "BlackboardArtifactNode.createSheet.count.noCorrelationAttributes.description=No correlation properties found", + "BlackboardArtifactNode.createSheet.count.noCorrelationValues.description=Unable to find other occurrences because no value exists for the available correlation property", + "# {0} - occurrenceCount", + "# {1} - attributeType", + "BlackboardArtifactNode.createSheet.count.description=There were {0} datasource(s) found with occurrences of the correlation value of type {1}"}) + @Deprecated + protected final void addCountProperty(Sheet.Set sheetSet, CorrelationAttributeInstance attribute) { + Pair countAndDescription = getCountPropertyAndDescription(attribute.getCorrelationType(), attribute.getCorrelationValue(), Bundle.BlackboardArtifactNode_createSheet_count_noCorrelationAttributes_description()); + sheetSet.put( + new NodeProperty<>(Bundle.BlackboardArtifactNode_createSheet_count_name(), Bundle.BlackboardArtifactNode_createSheet_count_displayName(), countAndDescription.getRight(), countAndDescription.getLeft())); + } + + /** + * Used by (subclasses of) BlackboardArtifactNode to add the comment + * property to their sheets. + * + * @param sheetSet the modifiable Sheet.Set to add the property to + * @param tags the list of tags associated with the file + * @param attribute the correlation attribute associated with this + * artifact's associated file, null if central repo is not + * enabled + * + * @deprecated Use the GetSCOTask to get this data on a background + * thread..., and then update the property sheet asynchronously + */ + @NbBundle.Messages({"BlackboardArtifactNode.createSheet.comment.name=C", + "BlackboardArtifactNode.createSheet.comment.displayName=C"}) + @Deprecated + protected final void addCommentProperty(Sheet.Set sheetSet, List tags, CorrelationAttributeInstance attribute) { + HasCommentStatus status = getCommentProperty(tags, attribute); + sheetSet.put(new NodeProperty<>(Bundle.BlackboardArtifactNode_createSheet_comment_name(), Bundle.BlackboardArtifactNode_createSheet_comment_displayName(), NO_DESCR, + status)); + } + } diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/datamodel/Bundle.properties-MERGED index 9ac85bd1e7..8289f947da 100755 --- a/Core/src/org/sleuthkit/autopsy/datamodel/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/datamodel/Bundle.properties-MERGED @@ -78,9 +78,6 @@ BlackboardArtifactNode.createSheet.taggedItem.description=Result or associated f BlackboardArtifactNode.createSheet.tags.displayName=Tags # {0} - artifactDisplayName BlackboardArtifactNode.displayName.artifact={0} Artifact -BlackboardArtifactNode.getAction.errorTitle=Error getting actions -BlackboardArtifactNode.getAction.linkedFileMessage=There was a problem getting actions for the selected result. The 'View File in Timeline' action will not be available. -BlackboardArtifactNode.getAction.resultErrorMessage=There was a problem getting actions for the selected result. The 'View Result in Timeline' action will not be available. BlackboardArtifactTagNode.createSheet.userName.text=User Name BlackboardArtifactTagNode.viewSourceArtifact.text=View Source Result Category.five=CAT-5: Non-pertinent From e3e86dd20f736e9c5efaaf4094328939d7b986fd Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Fri, 13 Mar 2020 10:14:23 -0400 Subject: [PATCH 056/100] improved commenting --- .../datamodel/CentralRepoDbChoice.java | 14 ++- .../CentralRepoDbConnectivityManager.java | 32 +++-- .../datamodel/CentralRepoDbManager.java | 119 +++++++++++------- .../datamodel/CentralRepoPlatforms.java | 2 +- .../CentralRepoPostgresSettingsUtil.java | 31 ++++- .../datamodel/DatabaseTestResult.java | 2 +- .../PostgresCentralRepoSettings.java | 6 +- .../datamodel/PostgresConnectionSettings.java | 46 +++++-- .../datamodel/PostgresSettingsLoader.java | 21 +++- .../optionspanel/EamDbSettingsDialog.java | 48 +++---- .../optionspanel/GlobalSettingsPanel.java | 30 ++--- 11 files changed, 239 insertions(+), 112 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbChoice.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbChoice.java index 574408b619..86f80e843a 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbChoice.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbChoice.java @@ -21,7 +21,7 @@ package org.sleuthkit.autopsy.centralrepository.datamodel; import org.openide.util.NbBundle.Messages; /** - * the database choices available for central repo + * This represents a database choices available for central repo. */ @Messages({ "CentralRepoDbChoice.Disabled.Text=Disabled", @@ -50,14 +50,26 @@ public enum CentralRepoDbChoice { this.platform = platform; } + /** + * This is the value of this setting when saved to central repo properties. + * @return The value associated with this choice. + */ public String getSettingKey() { return settingKey; } + /** + * This is the human-readable title for this choice. + * @return The human-readable title for this choice. + */ public String getTitle() { return title; } + /** + * This represents the database type (i.e. Postgres, SQLite) associated with this choice. + * @return The database type associated with this choice. + */ public CentralRepoPlatforms getDbPlatform() { return platform; } diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbConnectivityManager.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbConnectivityManager.java index ef261601ab..ade4094013 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbConnectivityManager.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbConnectivityManager.java @@ -19,40 +19,58 @@ package org.sleuthkit.autopsy.centralrepository.datamodel; /** - * common interface for settings pertaining to the database in central repository + * This class is a common interface for settings pertaining to the database in central repository. */ public interface CentralRepoDbConnectivityManager { + /** + * This method loads the current settings for this connection. + */ void loadSettings(); + /** + * This method saves the altered settings to disk. + */ void saveSettings(); + /** + * This method will create a central repository database if necessary. + * @return Whether or not the operation was successful. + */ boolean createDatabase(); + /** + * This method deletes a central repository database (used for deleting a corrupted database). + * @return Whether or not the operation was successful. + */ boolean deleteDatabase(); /** - * Use the current settings and the validation query to test the connection + * This method uses the current settings and the validation query to test the connection * to the database. * - * @return true if successfull connection, else false. + * @return True if successfull connection, else false. */ boolean verifyConnection(); /** - * Check to see if the database exists. + * This method checks to see if the database exists. * - * @return true if exists, else false + * @return True if exists, else false. */ boolean verifyDatabaseExists(); /** - * Use the current settings and the schema version query to test the + * This method is uses the current settings and the schema version query to test the * database schema. * - * @return true if successful connection, else false. + * @return True if successful connection, else false. */ boolean verifyDatabaseSchema(); + /** + * This method tests the connectivity status of this connection and returns the testing result. + * @return The result of testing the database connectivity status. + */ DatabaseTestResult testStatus(); } diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java index e7933edbee..3fab7af47f 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java @@ -30,7 +30,7 @@ import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.ModuleSettings; /** - * Contains business logic for saving and validating settings for central repo + * This class contains business logic for saving and validating settings for central repository. */ public class CentralRepoDbManager { @@ -52,8 +52,8 @@ public class CentralRepoDbManager { /** * This saves the currently selected database choice and clears any disabledDueToFailure flag. - * @param choice the choice to save. - * @return the newly saved choice + * @param choice The choice to save. + * @return The newly saved choice. */ public static CentralRepoDbChoice saveDbChoice(CentralRepoDbChoice choice) { return saveDbChoice(choice, true); @@ -61,9 +61,9 @@ public class CentralRepoDbManager { /** * This saves the currently selected database choice. - * @param choice the choice to save. - * @param clearDisabledDueToError whether or not to clear the 'disabledDueToFailure' settings key. - * @return the newly saved choice + * @param choice The choice to save. + * @param clearDisabledDueToError Whether or not to clear the 'disabledDueToFailure' settings key. + * @return The newly saved choice. */ public static CentralRepoDbChoice saveDbChoice(CentralRepoDbChoice choice, boolean clearDisabledDueToError) { synchronized(dbChoiceLock) { @@ -84,7 +84,7 @@ public class CentralRepoDbManager { /** * This method indicates whether or not 'PostgreSQL using multi-user settings' is a valid option. - * @return true if 'PostgreSQL using multi-user settings' is valid. + * @return True if 'PostgreSQL using multi-user settings' is valid. */ public static boolean isPostgresMultiuserAllowed() { // if multi user mode is not enabled, then this cannot be used @@ -100,7 +100,7 @@ public class CentralRepoDbManager { /** - * Load the selectedPlatform boolean from the config file, if it is set. + * This method loads the selectedPlatform boolean from the config file if it is set. */ public static CentralRepoDbChoice getSavedDbChoice() { synchronized(dbChoiceLock) { @@ -114,9 +114,8 @@ public class CentralRepoDbManager { } /** - * disable the central repository and indicate through a flag that this was due to a failure during database setup. - * this is used when re-enabling multi-user as a flag to determine whether or not CR should be re-enabled. - * NOTE: cr is disabled while persisting database choice. + * This method disables the central repository and indicates through a flag that this was due to a failure during database setup. + * This is used when re-enabling multi-user as a flag to determine whether or not CR should be re-enabled. */ public static void disableDueToFailure() { CentralRepoDbUtil.setUseCentralRepo(false); @@ -124,10 +123,10 @@ public class CentralRepoDbManager { } /** - * set whether or not the repository has been disabled due to a database setup issue; - * this is used when re-enabling multi-user as a flag to determine whether or not CR should be re-enabled + * This method sets whether or not the repository has been disabled due to a database setup issue; + * This is used when re-enabling multi-user as a flag to determine whether or not CR should be re-enabled. * - * @param disabledDueToFailure whether or not the repository has been disabled due to a database setup issue + * @param disabledDueToFailure Whether or not the repository has been disabled due to a database setup issue. */ private static void setDisabledDueToFailure(boolean disabledDueToFailure) { synchronized(disabledDueToFailureLock) { @@ -138,10 +137,10 @@ public class CentralRepoDbManager { } /** - * retrieves setting whether or not the repository has been disabled due to a database setup issue; - * this is used when re-enabling multi-user as a flag to determine whether or not CR should be re-enabled + * This method retrieves setting whether or not the repository has been disabled due to a database setup issue; + * this is used when re-enabling multi-user as a flag to determine whether or not CR should be re-enabled. * - * @return whether or not the repository has been disabled due to a database setup issue + * @return Whether or not the repository has been disabled due to a database setup issue. */ public static boolean isDisabledDueToFailure() { synchronized(disabledDueToFailureLock) { @@ -150,18 +149,18 @@ public class CentralRepoDbManager { } /** - * adds a property change listener - * NOTE: currently only listening for changes in currently saved db choice + * This method adds a property change listener. + * NOTE: currently only listening for changes in currently saved db choice and disabling due to failure. * - * @param listener the listener for the event + * @param listener The listener for the event. */ public static void addPropertyChangeListener(PropertyChangeListener listener) { propertyChangeSupport.addPropertyChangeListener(listener); } /** - * removes a propert change listener - * @param listener the listener to remove + * This method removes a propert change listener. + * @param listener The listener to remove. */ public static void removePropertyChangeListener(PropertyChangeListener listener) { propertyChangeSupport.removePropertyChangeListener(listener); @@ -182,9 +181,9 @@ public class CentralRepoDbManager { /** - * obtains the database connectivity for central repository + * This method obtains the database connectivity for central repository. * - * @return the CentralRepository object to connect to + * @return The CentralRepository object that will be used for connection. * @throws CentralRepoException */ private static CentralRepository obtainCentralRepository() throws CentralRepoException { @@ -202,10 +201,10 @@ public class CentralRepoDbManager { } /** - * obtains central repository lock + * This method obtains a central repository lock. * - * @param db the database connection - * @return the lock if acquired + * @param db The database connection. + * @return The lock if acquired. * @throws CentralRepoException */ private static CoordinationService.Lock obtainCentralRepoLock(CentralRepository db) throws CentralRepoException { @@ -226,10 +225,10 @@ public class CentralRepoDbManager { } /** - * updates central repository schema if necessary + * This method updates the central repository schema if necessary. * - * @param db the database connectivity - * @param lock the acquired lock + * @param db The database connectivity object. + * @param lock The acquired lock. * @throws CentralRepoException */ private static void updatedDbSchema(CentralRepository db, CoordinationService.Lock lock) throws CentralRepoException { @@ -258,7 +257,7 @@ public class CentralRepoDbManager { } /** - * Upgrade the current Central Reposity schema to the newest version. If the + * This method upgrades the current Central Reposity schema to the newest version. If the * upgrade fails, the Central Repository will be disabled and the current * settings will be cleared. */ @@ -316,21 +315,33 @@ public class CentralRepoDbManager { } + /** + * This method retrieves the current multi-user database settings. + * @return The current multi-user database settings. + */ public PostgresCentralRepoSettings getDbSettingsMultiUser() { return dbSettingsMultiUser; } + /** + * This method retrieves the current custom postgres database settings. + * @return The current custom postgres database settings. + */ public PostgresCentralRepoSettings getDbSettingsPostgres() { return dbSettingsPostgres; } + /** + * This method returns the current SQLite database settings for central repository. + * @return The current SQLite database settings + */ public SqliteCentralRepoSettings getDbSettingsSqlite() { return dbSettingsSqlite; } /** - * setup sqlite db with default settings - * @throws CentralRepoException if unable to successfully set up database + * This method sets up the sqlite database with default settings. + * @throws CentralRepoException if unable to successfully set up database. */ public void setupDefaultSqliteDb() throws CentralRepoException { // change in-memory settings to default sqlite @@ -355,11 +366,11 @@ public class CentralRepoDbManager { } /** - * Returns if changes to the central repository configuration were - * successfully applied + * This method returns if changes to the central repository configuration were + * successfully applied. * - * @return true if the database configuration was successfully changed false - * if it was not + * @return Returns true if the database configuration was successfully changed false + * if it was not. */ public boolean wasConfigurationChanged() { return configurationChanged; @@ -392,9 +403,9 @@ public class CentralRepoDbManager { } /** - * create central repo database if it does not already exist - * @return true if successful; false if unsuccessful - * @throws CentralRepoException if + * This method creates a central repo database if it does not already exist. + * @return True if successful; false if unsuccessful. + * @throws CentralRepoException */ public boolean createDb() throws CentralRepoException { CentralRepoDbConnectivityManager selectedDbSettings = getSelectedSettings(); @@ -434,7 +445,7 @@ public class CentralRepoDbManager { } /** - * saves a new central repository based on current settings + * This method saves a new central repository based on current settings. */ @NbBundle.Messages({"CentralRepoDbManager.connectionErrorMsg.text=Failed to connect to central repository database."}) public void saveNewCentralRepo() throws CentralRepoException { @@ -481,27 +492,45 @@ public class CentralRepoDbManager { } } + /** + * This method retrieves the current status. + * Note: this could be a dirty value if testing of the connection has not been performed. + * @return The current status of the database connection. + */ public DatabaseTestResult getStatus() { return testingStatus; } + /** + * This method retrieves the currently selected database choice. + * NOTE: This choice may not align with the saved setting. + * @return The currently selected database choice. + */ public CentralRepoDbChoice getSelectedDbChoice() { return selectedDbChoice; } + /** + * This method clears the current database testing status. + */ public void clearStatus() { testingStatus = DatabaseTestResult.UNTESTED; } + /** + * This method sets the currently selected database choice and sets the testing status to untested. + * @param newSelected The new database choice. + */ public void setSelctedDbChoice(CentralRepoDbChoice newSelected) { selectedDbChoice = newSelected; testingStatus = DatabaseTestResult.UNTESTED; } /** - * Tests whether or not the database settings are valid. + * This method tests whether or not the settings have been filled in for the UI. + * NOTE: This does not check the connectivity status of these settings. * - * @return True or false. + * @return True if database settings are valid. */ public boolean testDatabaseSettingsAreValid( String tbDbHostname, String tbDbPort, String tbDbUsername, String tfDatabasePath, String jpDbPassword) throws CentralRepoException, NumberFormatException { @@ -525,6 +554,10 @@ public class CentralRepoDbManager { return true; } + /** + * This method tests the current database settings to see if a valid connection can be made. + * @return The result of testing the connection. + */ public DatabaseTestResult testStatus() { try { CentralRepoDbConnectivityManager manager = getSelectedSettings(); diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoPlatforms.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoPlatforms.java index 8e909626e0..b830e98d16 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoPlatforms.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoPlatforms.java @@ -19,7 +19,7 @@ package org.sleuthkit.autopsy.centralrepository.datamodel; /** - * describes the possible database types for central repo + * This enum describes the possible database types for central repo. */ public enum CentralRepoPlatforms { DISABLED, diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoPostgresSettingsUtil.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoPostgresSettingsUtil.java index a932bcd187..3f75e9e183 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoPostgresSettingsUtil.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoPostgresSettingsUtil.java @@ -34,7 +34,7 @@ import org.sleuthkit.autopsy.coreutils.TextConverterException; import org.sleuthkit.datamodel.CaseDbConnectionInfo; /** - * handles saving and loading of postgres settings for central repo + * This class handles saving and loading of postgres settings for central repository. */ public class CentralRepoPostgresSettingsUtil { private final static Logger LOGGER = Logger.getLogger(CentralRepoPostgresSettingsUtil.class.getName()); @@ -50,6 +50,10 @@ public class CentralRepoPostgresSettingsUtil { private static CentralRepoPostgresSettingsUtil instance = null; + /** + * This method retrieves a singleton instance of this class. + * @return The singleton instance of this class. + */ public static synchronized CentralRepoPostgresSettingsUtil getInstance() { if (instance == null) instance = new CentralRepoPostgresSettingsUtil(); @@ -69,13 +73,18 @@ public class CentralRepoPostgresSettingsUtil { } /** - * an action that potentially throws an exception + * This interface represents an action that potentially throws an exception. */ private interface TryHandler { void operation() throws CentralRepoException, NumberFormatException; } - + /** + * This method loads multi-user settings to be used as a postgres connection to central repository. If + * settings could not be loaded, default values will be returned. + * + * @return The settings loaded from multi-user settings. + */ public PostgresConnectionSettings loadMultiUserSettings() { PostgresConnectionSettings settings = new PostgresConnectionSettings(); @@ -100,6 +109,12 @@ public class CentralRepoPostgresSettingsUtil { } + /** + * This method loads the custom postgres settings for central repository. If + * settings could not be loaded, default values will be returned. + * + * @return The settings loaded from custom postgres settings. + */ public PostgresConnectionSettings loadCustomSettings() { PostgresConnectionSettings settings = new PostgresConnectionSettings(); Map keyVals = ModuleSettings.getConfigSettings(MODULE_KEY); @@ -126,6 +141,10 @@ public class CentralRepoPostgresSettingsUtil { return settings; } + /** + * This method saves the settings for a custom postgres central repository connection. + * @param settings The settings to save. + */ public void saveCustomSettings(PostgresConnectionSettings settings) { Map map = new HashMap(); map.put(HOST_KEY, settings.getHost()); @@ -143,9 +162,9 @@ public class CentralRepoPostgresSettingsUtil { } /** - * checks if saved settings differ from the in-memory object provided in the 'settings' parameter - * @param settings the in-memory object - * @return whether or not settings parameter differs from saved custom settings + * This method checks if saved settings differ from the in-memory object provided in the 'settings' parameter. + * @param settings The in-memory object. + * @return Whether or not settings parameter differs from saved custom settings. */ public boolean areCustomSettingsChanged(PostgresConnectionSettings settings) { PostgresConnectionSettings saved = loadCustomSettings(); diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/DatabaseTestResult.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/DatabaseTestResult.java index b18a8a28cd..ecd72341cf 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/DatabaseTestResult.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/DatabaseTestResult.java @@ -19,7 +19,7 @@ package org.sleuthkit.autopsy.centralrepository.datamodel; /** - * provides the status of the database after attempting to validate central repo settings + * This enum provides the status of the database after attempting to validate central repo settings. */ public enum DatabaseTestResult { UNTESTED, diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresCentralRepoSettings.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresCentralRepoSettings.java index df37a3fec2..165d4ca6e0 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresCentralRepoSettings.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresCentralRepoSettings.java @@ -55,13 +55,17 @@ public final class PostgresCentralRepoSettings implements CentralRepoDbConnectiv throw new CentralRepoException("cannot load or save postgres settings for selection: " + choice); } + /** + * This method loads the settings with a custom {@link PostgresSettingsLoader PostgresSettingsLoader} object. + * @param loader The loader to be used. + */ public PostgresCentralRepoSettings(PostgresSettingsLoader loader) { this.loader = loader; loadSettings(); } /** - * default constructor that loads settings from selected db choice + * This is the default constructor that loads settings from selected db choice. */ public PostgresCentralRepoSettings() throws CentralRepoException { this(getLoaderFromSaved()); diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresConnectionSettings.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresConnectionSettings.java index 52b05966c0..c835d0c8fc 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresConnectionSettings.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresConnectionSettings.java @@ -23,7 +23,7 @@ import java.util.regex.Pattern; /** * - * POJO for postgres settings + * This class is a POJO for postgres settings to be used with central repository. */ public class PostgresConnectionSettings { private final static String DB_NAMES_REGEX = "[a-z][a-z0-9_]*"; // only lower case @@ -57,33 +57,58 @@ public class PostgresConnectionSettings { private String userName = DEFAULT_USERNAME; private String password = DEFAULT_PASSWORD; - + /** + * This method retrieves the postgres host. + * @return The host for these settings. + */ public String getHost() { return host; } + /** + * This method returns the port number for these settings. + * @return The port number for these settings. + */ public int getPort() { return port; } + /** + * This method returns the database name for these settings. + * @return The database name for these settings. + */ public String getDbName() { return dbName; } + /** + * This method returns the bulk threshold. + * @return The bulk threshold. + */ public int getBulkThreshold() { return bulkThreshold; } + /** + * This method returns the username to use for this connection. + * @return The username to use. + */ public String getUserName() { return userName; } + /** + * This method returns the password to use for this connection. + * @return The password to use for this connection. + */ public String getPassword() { return password; } /** + * This method sets the host for this connection. + * NOTE: must be non-empty string. * @param host the host to set */ public void setHost(String host) throws CentralRepoException { @@ -93,7 +118,8 @@ public class PostgresConnectionSettings { /** - * @param port the port to set (must be [1,65535]) + * This method sets the port for this connection. + * @param port The port to set (must be [1,65535]). */ public void setPort(int port) throws CentralRepoException { validateNum(port, 1, 65535, "Invalid port. Must be a number greater than 0."); @@ -102,7 +128,9 @@ public class PostgresConnectionSettings { /** - * @param dbName the dbName to set + * This methods sets the name of the database. + * NOTE: this name needs to be a valid postgres database name. + * @param dbName The database name. */ public void setDbName(String dbName) throws CentralRepoException { validateStr(dbName, "Invalid database name. Cannot be empty."); // NON-NLS @@ -114,7 +142,8 @@ public class PostgresConnectionSettings { /** - * @param bulkThreshold the bulkThreshold to set (must be greater than 0) + * This method sets the bulk threshold of this connection. + * @param bulkThreshold The bulk threshold to set (must be greater than 0). */ public void setBulkThreshold(int bulkThreshold) throws CentralRepoException { validateNum(bulkThreshold, 1, null, "Invalid bulk threshold."); @@ -123,7 +152,9 @@ public class PostgresConnectionSettings { /** - * @param userName the userName to set + * This method sets the username for this connection. + * NOTE: must be a valid postgres username. + * @param userName The user name to set. */ public void setUserName(String userName) throws CentralRepoException { validateStr(userName, "Invalid user name. Cannot be empty."); // NON-NLS @@ -135,7 +166,8 @@ public class PostgresConnectionSettings { /** - * @param password the password to set + * This method sets the password for this connection. + * @param password The password to set. */ public void setPassword(String password) throws CentralRepoException { validateStr(password, "Invalid user password. Cannot be empty."); diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresSettingsLoader.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresSettingsLoader.java index 4b0ab1895f..b3514d0ccb 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresSettingsLoader.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresSettingsLoader.java @@ -19,10 +19,19 @@ package org.sleuthkit.autopsy.centralrepository.datamodel; /** - * interface to load or save postgres settings + * This is an interface to load or save postgres settings. */ public interface PostgresSettingsLoader { + /** + * This method loads the current settings. + * @return The settings that were loaded. + */ PostgresConnectionSettings loadSettings(); + + /** + * This method saves the current settings. + * @param settings The settings to save. + */ void saveSettings(PostgresConnectionSettings settings); PostgresSettingsLoader CUSTOM_SETTINGS_LOADER = new Custom(); @@ -31,7 +40,7 @@ public interface PostgresSettingsLoader { /** - * loads and saves custom postgres settings + * This class loads and saves custom postgres settings. */ class Custom implements PostgresSettingsLoader { @Override @@ -47,8 +56,8 @@ public interface PostgresSettingsLoader { /** - * loads multi user postgres settings to be used with central repo - * NOTE: does not save settings on save operation as this is merely a proxy + * This class loads multi-user postgres settings to be used with central repo. + * NOTE: This class does not save settings on save operation as this is merely a proxy. */ class MultiUser implements PostgresSettingsLoader { @@ -58,9 +67,9 @@ public interface PostgresSettingsLoader { } /** - * NOTE: this action does not do anything. There is no need to save since + * NOTE: This action does not do anything. There is no need to save since * this is just a proxy to multi user settings. - * @param settings the settings to save + * @param settings The settings to save. */ @Override public void saveSettings(PostgresConnectionSettings settings) {} diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java index c422e04d76..3b047b0e10 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java @@ -63,7 +63,7 @@ public class EamDbSettingsDialog extends JDialog { private static final long serialVersionUID = 1L; /** - * handles displaying and rendering drop down menu for database choices in central repo + * This class handles displaying and rendering drop down menu for database choices in central repo. */ private class DbChoiceRenderer extends BasicComboBoxRenderer { private static final long serialVersionUID = 1L; @@ -154,10 +154,10 @@ public class EamDbSettingsDialog extends JDialog { /** - * prompts user based on testing status (i.e. failure to connect, invalid schema, db does not exist, etc.) - * @param manager the manager to use when setting up the database - * @param dialog if non-null value, validates settings and updates 'okay' button enabled state - * @return whether or not the ultimate status after prompts is okay to continue + * This method prompts user based on testing status (i.e. failure to connect, invalid schema, db does not exist, etc.). + * @param manager The manager to use when setting up the database. + * @param dialog If non-null value, validates settings and updates 'okay' button enabled state. + * @return Whether or not the ultimate status after prompts is okay to continue. */ @NbBundle.Messages({"EamDbSettingsDialog.okButton.corruptDatabaseExists.title=Error Loading Database", "EamDbSettingsDialog.okButton.corruptDatabaseExists.message=Database exists but is not the right format. Manually delete it or choose a different path (if applicable).", @@ -194,9 +194,9 @@ public class EamDbSettingsDialog extends JDialog { } /** - * when a new database needs to be created on user selecting cr, this code will be ran when user selects create cr - * @param manager the manager handling the database creation - * @param dialog the dialog that prompted database creation + * When a new database needs to be created on user selecting cr, this code will be ran when user selects create cr. + * @param manager The manager handling the database creation. + * @param dialog The dialog that prompted database creation. */ private static void onUserPromptCreateDb(CentralRepoDbManager manager, EamDbSettingsDialog dialog) { try { @@ -210,8 +210,8 @@ public class EamDbSettingsDialog extends JDialog { /** - * when an error occurs while going through promptTestStatusWarning, this method is called - * @param manager1 the manager to use as service class + * When an error occurs while going through promptTestStatusWarning, this method is called. + * @param manager1 The manager to use as service class. * @throws HeadlessException */ private static void onPromptStatusError(CentralRepoDbManager manager1) { @@ -526,11 +526,11 @@ public class EamDbSettingsDialog extends JDialog { }//GEN-LAST:event_bnOkActionPerformed - /** - * tests status for central repo db / creation and prompts user accordingly - * @param parent the parent component (the anchor for displaying dialogs) - * @param manager the central repo db manager with settings to be tested and saved - * @return whether or not central repo db was successfully be created or found + /** + * This method tests status for central repo db / creation and prompts user accordingly. + * @param parent The parent component (the anchor for displaying dialogs). + * @param manager The central repo db manager with settings to be tested and saved. + * @return Whether or not central repo db was successfully be created or found. */ public static boolean testStatusAndCreate(Component parent, CentralRepoDbManager manager) { return testStatusAndCreate(parent, manager, null); @@ -538,11 +538,11 @@ public class EamDbSettingsDialog extends JDialog { /** - * tests status for central repo db / creation and prompts user accordingly - * @param parent the parent component (the anchor for displaying dialogs) - * @param manager the central repo db manager with settings to be tested and saved - * @param dialog the db settings dialog; if non-null, will validate okay button state - * @return whether or not central repo db was successfully be created or found + * This method tests status for central repo db / creation and prompts user accordingly. + * @param parent The parent component (the anchor for displaying dialogs). + * @param manager The central repo db manager with settings to be tested and saved. + * @param dialog The db settings dialog; if non-null, will validate okay button state. + * @return Whether or not central repo db was successfully be created or found. */ private static boolean testStatusAndCreate(Component parent, CentralRepoDbManager manager, EamDbSettingsDialog dialog) { parent.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); @@ -577,11 +577,11 @@ public class EamDbSettingsDialog extends JDialog { } /** - * Returns if changes to the central repository configuration were - * successfully applied + * This method returns if changes to the central repository configuration were + * successfully applied. * - * @return true if the database configuration was successfully changed false - * if it was not + * @return True if the database configuration was successfully changed; false + * if it was not. */ public boolean wasConfigurationChanged() { return manager.wasConfigurationChanged(); diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java index c65ac2f0c6..78b2e9ca87 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java @@ -90,11 +90,11 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i } /** - * invokes central repository database choice selection as well as input for necessary configuration - * @param parent the parent component for displaying dialogs - * @param initialSelection if non-null, the menu item will be set to this choice; if null, - * the currently selected db choice will be selected - * @return true if there was a change + * This method invokes central repository database choice selection as well as input for necessary configuration. + * @param parent The parent component for displaying dialogs. + * @param initialSelection If non-null, the menu item will be set to this choice; if null, + * the currently selected db choice will be selected. + * @return True if there was a change. */ private static boolean invokeCrChoice(Component parent, CentralRepoDbChoice initialSelection) { EamDbSettingsDialog dialog = (initialSelection != null) ? @@ -111,13 +111,13 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i /** - * when multi user settings are updated, this function triggers pertinent updates for central repository - * NOTE: if multi user settings were previously enabled and multi user settings are currently selected, this function assumes - * there is a change in the postgres connectivity + * When multi user settings are updated, this function triggers pertinent updates for central repository. + * NOTE: If multi user settings were previously enabled and multi user settings are currently selected, this function assumes + * there is a change in the postgres connectivity. * - * @param parent the swing component that serves as a parent for dialogs that may arise - * @param muPreviouslySelected if multi user settings were previously enabled - * @param muCurrentlySelected if multi user settings are currently enabled as of most recent change + * @param parent The swing component that serves as a parent for dialogs that may arise. + * @param muPreviouslySelected If multi user settings were previously enabled. + * @param muCurrentlySelected If multi user settings are currently enabled as of most recent change. */ @NbBundle.Messages({ "GlobalSettingsPanel.onMultiUserChange.enable.title=Use with Central Repository?", @@ -165,8 +165,8 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i /** - * when a user must select a new database other than using database from multi user settings - * @param parent the parent component to use for displaying dialogs in reference + * This method is called when a user must select a new database other than using database from multi user settings. + * @param parent The parent component to use for displaying dialogs in reference. */ @NbBundle.Messages({ "GlobalSettingsPanel.onMultiUserChange.disabledMu.title=Central Repository Change Necessary", @@ -647,9 +647,9 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i } /** - * Validates that the dialog/panel is filled out correctly for our usage. + * This method validates that the dialog/panel is filled out correctly for our usage. * - * @return true if it's okay, false otherwise. + * @return True if it is okay, false otherwise. */ public boolean valid() { return !cbUseCentralRepo.isSelected() || !lbDbPlatformValue.getText().equals(CentralRepoDbChoice.DISABLED.toString()); From 2977b986010539d10721f64a1c9d909cf2ea9dd7 Mon Sep 17 00:00:00 2001 From: Raman Arora Date: Fri, 13 Mar 2020 13:49:33 -0400 Subject: [PATCH 057/100] Fix for changes to the CentralRepoPlatform class. --- .../datamodel/CentralRepoDbUpgrader13To14.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbUpgrader13To14.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbUpgrader13To14.java index f4ddbca089..9d6473055e 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbUpgrader13To14.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbUpgrader13To14.java @@ -39,7 +39,7 @@ public class CentralRepoDbUpgrader13To14 implements CentralRepoDbUpgrader { try (Statement statement = connection.createStatement();) { - CentralRepoPlatforms selectedPlatform = CentralRepoPlatforms.getSelectedPlatform(); + CentralRepoPlatforms selectedPlatform = CentralRepoDbManager.getSavedDbChoice().getDbPlatform(); // Create account_types and accounts tables which are referred by X_instances tables statement.execute(RdbmsCentralRepoFactory.getCreateAccountTypesTableStatement(selectedPlatform)); From a158cfcf699742431a9e80243734a68b66c237e7 Mon Sep 17 00:00:00 2001 From: Raman Arora Date: Fri, 13 Mar 2020 13:56:58 -0400 Subject: [PATCH 058/100] 6147: Do not create device accounts in Central Repo --- .../CorrelationAttributeInstance.java | 3 +- .../datamodel/CorrelationAttributeUtil.java | 39 ++++++++++-------- .../datamodel/RdbmsCentralRepoFactory.java | 41 ++++--------------- 3 files changed, 32 insertions(+), 51 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeInstance.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeInstance.java index 1ab978bc84..4d5e2857a1 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeInstance.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeInstance.java @@ -294,8 +294,9 @@ public class CorrelationAttributeInstance implements Serializable { // Create Correlation Types for Accounts. int correlationTypeId = ADDITIONAL_TYPES_BASE_ID; for (Account.Type type : Account.Type.PREDEFINED_ACCOUNT_TYPES) { + // Skip Device account type - we dont want to correlate on those. // Skip Phone and Email accounts as there are already Correlation types defined for those. - if (type != Account.Type.EMAIL && type != Account.Type.PHONE) { + if (type != Account.Type.DEVICE && type != Account.Type.EMAIL && type != Account.Type.PHONE) { defaultCorrelationTypes.add(new CorrelationAttributeInstance.Type(correlationTypeId, type.getDisplayName(), type.getTypeName().toLowerCase() + "_acct", true, true)); //NON-NLS correlationTypeId++; } diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java index 04aa6fc16e..636c59886e 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java @@ -27,6 +27,7 @@ import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoAccount.CentralRepoAccountType; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.datamodel.AbstractFile; +import org.sleuthkit.datamodel.Account; import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE; import org.sleuthkit.datamodel.BlackboardAttribute; @@ -247,25 +248,29 @@ public class CorrelationAttributeUtil { // Get the account type from the artifact BlackboardAttribute accountTypeAttribute = acctArtifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ACCOUNT_TYPE)); String accountTypeStr = accountTypeAttribute.getValueString(); + + // do not create any correlation attribute instance for a Device account + if (Account.Type.DEVICE.getTypeName().equalsIgnoreCase(accountTypeStr) == false) { - // Get the corresponding CentralRepoAccountType from the database. - CentralRepoAccountType crAccountType = CentralRepository.getInstance().getAccountTypeByName(accountTypeStr); + // Get the corresponding CentralRepoAccountType from the database. + CentralRepoAccountType crAccountType = CentralRepository.getInstance().getAccountTypeByName(accountTypeStr); - int corrTypeId = crAccountType.getCorrelationTypeId(); - CorrelationAttributeInstance.Type corrType = CentralRepository.getInstance().getCorrelationTypeById(corrTypeId); - - // Get the account identifier - BlackboardAttribute accountIdAttribute = acctArtifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ID)); - String accountIdStr = accountIdAttribute.getValueString(); - - // add/get the account and get its accountId. - CentralRepoAccount crAccount = CentralRepository.getInstance().getOrCreateAccount(crAccountType, accountIdStr); - - CorrelationAttributeInstance corrAttr = makeCorrAttr(acctArtifact, corrType, accountIdStr); - if (corrAttr != null) { - // set the account_id in correlation attribute - corrAttr.setAccountId(crAccount.getAccountId()); - corrAttrInstances.add(corrAttr); + int corrTypeId = crAccountType.getCorrelationTypeId(); + CorrelationAttributeInstance.Type corrType = CentralRepository.getInstance().getCorrelationTypeById(corrTypeId); + + // Get the account identifier + BlackboardAttribute accountIdAttribute = acctArtifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ID)); + String accountIdStr = accountIdAttribute.getValueString(); + + // add/get the account and get its accountId. + CentralRepoAccount crAccount = CentralRepository.getInstance().getOrCreateAccount(crAccountType, accountIdStr); + + CorrelationAttributeInstance corrAttr = makeCorrAttr(acctArtifact, corrType, accountIdStr); + if (corrAttr != null) { + // set the account_id in correlation attribute + corrAttr.setAccountId(crAccount.getAccountId()); + corrAttrInstances.add(corrAttr); + } } } diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/RdbmsCentralRepoFactory.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/RdbmsCentralRepoFactory.java index 1232d708a6..6129ea45b6 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/RdbmsCentralRepoFactory.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/RdbmsCentralRepoFactory.java @@ -193,7 +193,7 @@ public class RdbmsCentralRepoFactory { result = CentralRepoDbUtil.insertDefaultCorrelationTypes(conn) && CentralRepoDbUtil.insertDefaultOrganization(conn) && - insertDefaultAccountsTablesContent(conn); + RdbmsCentralRepoFactory.insertDefaultAccountsTablesContent(conn, selectedPlatform ); // @TODO: uncomment when ready to create/populate persona tables // && insertDefaultPersonaTablesContent(conn); @@ -766,33 +766,6 @@ public class RdbmsCentralRepoFactory { } - /** - * Inserts the default content in accounts related tables. - * - * @param conn Database connection to use. - * - * @return True if success, false otherwise. - */ - private boolean insertDefaultAccountsTablesContent(Connection conn) { - - try (Statement stmt = conn.createStatement()) { - // Populate the account_types table - for (Account.Type type : Account.Type.PREDEFINED_ACCOUNT_TYPES) { - int correlationTypeId = getCorrelationTypeIdForAccountType(conn, type); - if (correlationTypeId > 0) { - String sqlString = String.format("INSERT INTO account_types (type_name, display_name, correlation_type_id) VALUES ('%s', '%s', %d)" + getOnConflictDoNothingClause(selectedPlatform), - type.getTypeName(), type.getDisplayName(), correlationTypeId); - stmt.execute(sqlString); - } - } - } catch (SQLException ex) { - LOGGER.log(Level.SEVERE, String.format("Failed to populate default data in Accounts tables."), ex); - return false; - } - - return true; - } - /** * Inserts the default content in persona related tables. * @@ -838,11 +811,13 @@ public class RdbmsCentralRepoFactory { // Populate the account_types table for (Account.Type type : Account.Type.PREDEFINED_ACCOUNT_TYPES) { - int correlationTypeId = getCorrelationTypeIdForAccountType(conn, type); - if (correlationTypeId > 0) { - String sqlString = String.format("INSERT INTO account_types (type_name, display_name, correlation_type_id) VALUES ('%s', '%s', %d)" + getOnConflictDoNothingClause(selectedPlatform), - type.getTypeName(), type.getDisplayName(), correlationTypeId); - stmt.execute(sqlString); + if (type != Account.Type.DEVICE) { + int correlationTypeId = getCorrelationTypeIdForAccountType(conn, type); + if (correlationTypeId > 0) { + String sqlString = String.format("INSERT INTO account_types (type_name, display_name, correlation_type_id) VALUES ('%s', '%s', %d)" + getOnConflictDoNothingClause(selectedPlatform), + type.getTypeName(), type.getDisplayName(), correlationTypeId); + stmt.execute(sqlString); + } } } From 1fc3bd524a4e6b8bc092160c521210d2ac4f4212 Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Fri, 13 Mar 2020 15:35:55 -0400 Subject: [PATCH 059/100] 6132 prevent NPE in video content viewers when video is unplayable --- .../contentviewers/MediaPlayerPanel.java | 219 ++++++++++-------- 1 file changed, 118 insertions(+), 101 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.java b/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.java index c518abdd45..53cf9e8bf4 100755 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.java @@ -241,7 +241,7 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie progressSlider.addChangeListener(new ChangeListener() { @Override public void stateChanged(ChangeEvent e) { - if (progressSlider.getValueIsAdjusting()) { + if (progressSlider.getValueIsAdjusting() && gstPlayBin != null) { long duration = gstPlayBin.queryDuration(TimeUnit.NANOSECONDS); double relativePosition = progressSlider.getValue() * 1.0 / PROGRESS_SLIDER_SIZE; long newStartTime = (long) (relativePosition * duration); @@ -264,20 +264,23 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie //Manage the video while the user is performing actions on the track. progressSlider.addMouseListener(new MouseListener() { private State previousState = State.NULL; - + @Override public void mousePressed(MouseEvent e) { - previousState = gstPlayBin.getState(); - gstPlayBin.pause(); + if (gstPlayBin != null) { + previousState = gstPlayBin.getState(); + gstPlayBin.pause(); + } } @Override public void mouseReleased(MouseEvent e) { - if(previousState.equals(State.PLAYING)) { + if (previousState.equals(State.PLAYING) && gstPlayBin != null) { gstPlayBin.play(); } previousState = State.NULL; } + @Override public void mouseClicked(MouseEvent e) { } @@ -289,11 +292,11 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie @Override public void mouseExited(MouseEvent e) { } - + }); //Manage the audio level when the user is adjusting the volume slider audioSlider.addChangeListener((ChangeEvent event) -> { - if (audioSlider.getValueIsAdjusting()) { + if (audioSlider.getValueIsAdjusting() && gstPlayBin != null) { double audioPercent = (audioSlider.getValue() * 2.0) / 100.0; gstPlayBin.setVolume(audioPercent); } @@ -327,11 +330,13 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie endOfStreamListener = new Bus.EOS() { @Override public void endOfStream(GstObject go) { - gstPlayBin.seek(ClockTime.ZERO); - /** - * Keep the video from automatically playing - */ - Gst.getExecutor().submit(() -> gstPlayBin.pause()); + if (gstPlayBin != null) { + gstPlayBin.seek(ClockTime.ZERO); + /** + * Keep the video from automatically playing + */ + Gst.getExecutor().submit(() -> gstPlayBin.pause()); + } } }; } @@ -556,10 +561,12 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie //Video is ready for playback. Create new components gstPlayBin = new PlayBin("VideoPlayer", tempFile.toURI()); //Configure event handling - Bus playBinBus = gstPlayBin.getBus(); - playBinBus.connect(endOfStreamListener); - playBinBus.connect(stateChangeListener); - playBinBus.connect(errorListener); + if (gstPlayBin != null) { + Bus playBinBus = gstPlayBin.getBus(); + playBinBus.connect(endOfStreamListener); + playBinBus.connect(stateChangeListener); + playBinBus.connect(errorListener); + } if (this.isCancelled()) { return; @@ -570,15 +577,16 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie videoPanel.setLayout(new BoxLayout(videoPanel, BoxLayout.Y_AXIS)); videoPanel.add(fxPanel); fxAppSink = new JavaFxAppSink("JavaFxAppSink", fxPanel); - gstPlayBin.setVideoSink(fxAppSink); - + if (gstPlayBin != null) { + gstPlayBin.setVideoSink(fxAppSink); + } if (this.isCancelled()) { return; } - - gstPlayBin.setVolume((audioSlider.getValue() * 2.0) / 100.0); - gstPlayBin.pause(); - + if (gstPlayBin != null) { + gstPlayBin.setVolume((audioSlider.getValue() * 2.0) / 100.0); + gstPlayBin.pause(); + } timer.start(); enableComponents(true); } catch (CancellationException ex) { @@ -598,7 +606,7 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie @Override public void actionPerformed(ActionEvent e) { - if (!progressSlider.getValueIsAdjusting()) { + if (!progressSlider.getValueIsAdjusting() && gstPlayBin != null) { sliderLock.acquireUninterruptibly(); long position = gstPlayBin.queryPosition(TimeUnit.NANOSECONDS); long duration = gstPlayBin.queryDuration(TimeUnit.NANOSECONDS); @@ -635,13 +643,13 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie * thumb at the given width and height. It also paints the track blue as * the thumb progresses. * - * @param slider JSlider component + * @param slider JSlider component * @param thumbDimension */ public CircularJSliderUI(JSlider slider, Dimension thumbDimension) { super(slider); this.thumbDimension = thumbDimension; - + //Configure track and thumb colors. Color lightBlue = new Color(0, 130, 255); thumbColor = lightBlue; @@ -655,8 +663,8 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie } /** - * Modifies the View to be an oval rather than the underlying - * rectangle Controller. + * Modifies the View to be an oval rather than the underlying rectangle + * Controller. */ @Override public void paintThumb(Graphics graphic) { @@ -705,12 +713,13 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie @Override protected TrackListener createTrackListener(JSlider slider) { /** - * This track listener will force the thumb to be snapped to the mouse - * location. This makes grabbing and dragging the JSlider much easier. - * Using the default track listener, the user would have to click - * exactly on the slider thumb to drag it. Now the thumb positions - * itself under the mouse so that it can always be dragged. - */ + * This track listener will force the thumb to be snapped to the + * mouse location. This makes grabbing and dragging the JSlider much + * easier. Using the default track listener, the user would have to + * click exactly on the slider thumb to drag it. Now the thumb + * positions itself under the mouse so that it can always be + * dragged. + */ return new TrackListener() { @Override public void mousePressed(MouseEvent e) { @@ -982,87 +991,95 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie }// //GEN-END:initComponents private void rewindButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_rewindButtonActionPerformed - long currentTime = gstPlayBin.queryPosition(TimeUnit.NANOSECONDS); - //Skip 30 seconds. - long rewindDelta = TimeUnit.NANOSECONDS.convert(SKIP_IN_SECONDS, TimeUnit.SECONDS); - //Ensure new video position is within bounds - long newTime = Math.max(currentTime - rewindDelta, 0); - double playBackRate = getPlayBackRate(); - gstPlayBin.seek(playBackRate, - Format.TIME, - //FLUSH - flushes the pipeline - //ACCURATE - video will seek exactly to the position requested - EnumSet.of(SeekFlags.FLUSH, SeekFlags.ACCURATE), - //Set the start position to newTime - SeekType.SET, newTime, - //Do nothing for the end position - SeekType.NONE, -1); - }//GEN-LAST:event_rewindButtonActionPerformed - - private void fastForwardButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_fastForwardButtonActionPerformed - long duration = gstPlayBin.queryDuration(TimeUnit.NANOSECONDS); - long currentTime = gstPlayBin.queryPosition(TimeUnit.NANOSECONDS); - //Skip 30 seconds. - long fastForwardDelta = TimeUnit.NANOSECONDS.convert(SKIP_IN_SECONDS, TimeUnit.SECONDS); - //Don't allow skipping within 2 seconds of video ending. Skipping right to - //the end causes undefined behavior for some gstreamer plugins. - long twoSecondsInNano = TimeUnit.NANOSECONDS.convert(2, TimeUnit.SECONDS); - if((duration - currentTime) <= twoSecondsInNano) { - return; - } - - long newTime; - if (currentTime + fastForwardDelta >= duration) { - //If there are less than 30 seconds left, only fast forward to the midpoint. - newTime = currentTime + (duration - currentTime)/2; - } else { - newTime = currentTime + fastForwardDelta; - } - - double playBackRate = getPlayBackRate(); - gstPlayBin.seek(playBackRate, - Format.TIME, - //FLUSH - flushes the pipeline - //ACCURATE - video will seek exactly to the position requested - EnumSet.of(SeekFlags.FLUSH, SeekFlags.ACCURATE), - //Set the start position to newTime - SeekType.SET, newTime, - //Do nothing for the end position - SeekType.NONE, -1); - }//GEN-LAST:event_fastForwardButtonActionPerformed - - private void playButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_playButtonActionPerformed - if (gstPlayBin.isPlaying()) { - gstPlayBin.pause(); - } else { - double playBackRate = getPlayBackRate(); + if (gstPlayBin != null) { long currentTime = gstPlayBin.queryPosition(TimeUnit.NANOSECONDS); - //Set playback rate before play. + //Skip 30 seconds. + long rewindDelta = TimeUnit.NANOSECONDS.convert(SKIP_IN_SECONDS, TimeUnit.SECONDS); + //Ensure new video position is within bounds + long newTime = Math.max(currentTime - rewindDelta, 0); + double playBackRate = getPlayBackRate(); gstPlayBin.seek(playBackRate, Format.TIME, //FLUSH - flushes the pipeline //ACCURATE - video will seek exactly to the position requested EnumSet.of(SeekFlags.FLUSH, SeekFlags.ACCURATE), //Set the start position to newTime - SeekType.SET, currentTime, + SeekType.SET, newTime, //Do nothing for the end position SeekType.NONE, -1); - gstPlayBin.play(); + } + }//GEN-LAST:event_rewindButtonActionPerformed + + private void fastForwardButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_fastForwardButtonActionPerformed + if (gstPlayBin != null) { + long duration = gstPlayBin.queryDuration(TimeUnit.NANOSECONDS); + long currentTime = gstPlayBin.queryPosition(TimeUnit.NANOSECONDS); + //Skip 30 seconds. + long fastForwardDelta = TimeUnit.NANOSECONDS.convert(SKIP_IN_SECONDS, TimeUnit.SECONDS); + //Don't allow skipping within 2 seconds of video ending. Skipping right to + //the end causes undefined behavior for some gstreamer plugins. + long twoSecondsInNano = TimeUnit.NANOSECONDS.convert(2, TimeUnit.SECONDS); + if ((duration - currentTime) <= twoSecondsInNano) { + return; + } + + long newTime; + if (currentTime + fastForwardDelta >= duration) { + //If there are less than 30 seconds left, only fast forward to the midpoint. + newTime = currentTime + (duration - currentTime) / 2; + } else { + newTime = currentTime + fastForwardDelta; + } + + double playBackRate = getPlayBackRate(); + gstPlayBin.seek(playBackRate, + Format.TIME, + //FLUSH - flushes the pipeline + //ACCURATE - video will seek exactly to the position requested + EnumSet.of(SeekFlags.FLUSH, SeekFlags.ACCURATE), + //Set the start position to newTime + SeekType.SET, newTime, + //Do nothing for the end position + SeekType.NONE, -1); + } + }//GEN-LAST:event_fastForwardButtonActionPerformed + + private void playButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_playButtonActionPerformed + if (gstPlayBin != null) { + if (gstPlayBin.isPlaying()) { + gstPlayBin.pause(); + } else { + double playBackRate = getPlayBackRate(); + long currentTime = gstPlayBin.queryPosition(TimeUnit.NANOSECONDS); + //Set playback rate before play. + gstPlayBin.seek(playBackRate, + Format.TIME, + //FLUSH - flushes the pipeline + //ACCURATE - video will seek exactly to the position requested + EnumSet.of(SeekFlags.FLUSH, SeekFlags.ACCURATE), + //Set the start position to newTime + SeekType.SET, currentTime, + //Do nothing for the end position + SeekType.NONE, -1); + gstPlayBin.play(); + } } }//GEN-LAST:event_playButtonActionPerformed private void playBackSpeedComboBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_playBackSpeedComboBoxActionPerformed - double playBackRate = getPlayBackRate(); - long currentTime = gstPlayBin.queryPosition(TimeUnit.NANOSECONDS); - gstPlayBin.seek(playBackRate, - Format.TIME, - //FLUSH - flushes the pipeline - //ACCURATE - video will seek exactly to the position requested - EnumSet.of(SeekFlags.FLUSH, SeekFlags.ACCURATE), - //Set the position to the currentTime, we are only adjusting the - //playback rate. - SeekType.SET, currentTime, - SeekType.NONE, 0); + if (gstPlayBin != null) { + double playBackRate = getPlayBackRate(); + long currentTime = gstPlayBin.queryPosition(TimeUnit.NANOSECONDS); + gstPlayBin.seek(playBackRate, + Format.TIME, + //FLUSH - flushes the pipeline + //ACCURATE - video will seek exactly to the position requested + EnumSet.of(SeekFlags.FLUSH, SeekFlags.ACCURATE), + //Set the position to the currentTime, we are only adjusting the + //playback rate. + SeekType.SET, currentTime, + SeekType.NONE, 0); + } }//GEN-LAST:event_playBackSpeedComboBoxActionPerformed // Variables declaration - do not modify//GEN-BEGIN:variables From 87cc28942665aebf5a87e115f3e96a788ea12f21 Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Fri, 13 Mar 2020 21:28:48 -0400 Subject: [PATCH 060/100] Tidy up BlackboardArtifactNode.java --- .../datamodel/BlackboardArtifactNode.java | 477 ++++++++++-------- 1 file changed, 277 insertions(+), 200 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java index 1126cb1c80..0b4d09a7b1 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java @@ -78,23 +78,27 @@ import org.sleuthkit.datamodel.TskData; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository; /** - * An AbstractNode implementation representing an artifact of any type. + * A BlackboardArtifactNode is an AbstractNode implementation that can be used + * to represent an artifact of any type. */ public class BlackboardArtifactNode extends AbstractContentNode { private static final Logger logger = Logger.getLogger(BlackboardArtifactNode.class.getName()); /* - * This cache is used to avoid repeated trips to the case database for - * Content objects that are the source of multiple artifacts. + * Cache of Content objects used to avoid repeated trips to the case + * database to retrieve Content objects that are the source of multiple + * artifacts. */ private static final Cache contentCache = CacheBuilder.newBuilder().expireAfterWrite(1, TimeUnit.MINUTES).build(); /* * Case application events that affect the property sheets of - * BlackboardArtifactNodes, with one exception, CURRENT_CASE (closed) events - * which triggers content cache invalidation and unregistering of the node's - * ProeprtyChangeListener. + * BlackboardArtifactNodes. + * + * NOTE: CURRENT_CASE (closed) events trigger content cache invalidation and + * unregistering of the PropertyChangeListener subscribed to the application + * events. */ private static final Set CASE_EVENTS_OF_INTEREST = EnumSet.of( Case.Events.BLACKBOARD_ARTIFACT_TAG_ADDED, @@ -105,8 +109,8 @@ public class BlackboardArtifactNode extends AbstractContentNode> customProperties; + /* + * The node's application event listener. + */ private final PropertyChangeListener appEventListener = new PropertyChangeListener() { @Override public void propertyChange(PropertyChangeEvent evt) { @@ -180,19 +187,20 @@ public class BlackboardArtifactNode extends AbstractContentNode artifact.getSleuthkitCase().getContentById(objectID)); + if (content == null) { + return Lookups.fixed(artifact); + } else { + return Lookups.fixed(artifact, content); + } + } catch (ExecutionException ex) { + logger.log(Level.SEVERE, MessageFormat.format("Error getting source content (artifact objID={0}, content objID={1})", artifact.getId(), objectID), ex); //NON-NLS + /* + * RC: NPE ALERT!! The decision to return a Lookup without the + * source content in it has the potential to cause NPEs within this + * class and in the UI component clients of this class. The node + * constructor should throw. However, that would be an exported + * public API change. + */ + return Lookups.fixed(artifact); + } + } + + /** + * Unregisters the application event listener when this node is garbage + * collected, if this finalizer is called. + * + * RC: Isn't there some node lifecycle property change event that could be + * used to unregister the listener? * * @throws Throwable */ @@ -244,7 +292,7 @@ public class BlackboardArtifactNode extends AbstractContentNode(NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.srcFile.name"), NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.srcFile.displayName"), @@ -390,8 +447,11 @@ public class BlackboardArtifactNode extends AbstractContentNode(Bundle.BlackboardArtifactNode_createSheet_score_name(), Bundle.BlackboardArtifactNode_createSheet_score_displayName(), VALUE_LOADING, "")); sheetSet.put(new NodeProperty<>(Bundle.BlackboardArtifactNode_createSheet_comment_name(), Bundle.BlackboardArtifactNode_createSheet_comment_displayName(), VALUE_LOADING, "")); @@ -402,8 +462,9 @@ public class BlackboardArtifactNode extends AbstractContentNode map = new LinkedHashMap<>(); fillPropertyMap(map, artifact); @@ -437,7 +499,7 @@ public class BlackboardArtifactNode extends AbstractContentNode np : customProperties) { @@ -445,10 +507,10 @@ public class BlackboardArtifactNode extends AbstractContentNode getAllTagsFromDatabase() { @@ -589,15 +652,16 @@ public class BlackboardArtifactNode extends AbstractContentNode 0 ? HasCommentStatus.TAG_NO_COMMENT : HasCommentStatus.NO_COMMENT; for (Tag tag : tags) { if (!StringUtils.isBlank(tag.getComment())) { - //if the tag is null or empty or contains just white space it will indicate there is not a comment status = HasCommentStatus.TAG_COMMENT; break; } } - //currently checks for a comment on the associated file in the central repo not the artifact itself - //what we want the column property to reflect should be revisted when we have added a way to comment - //on the artifact itself + if (attribute != null && !StringUtils.isBlank(attribute.getComment())) { if (status == HasCommentStatus.TAG_COMMENT) { status = HasCommentStatus.CR_AND_TAG_COMMENTS; @@ -641,38 +705,25 @@ public class BlackboardArtifactNode extends AbstractContentNode tags) { - Pair scoreAndDescription = getScorePropertyAndDescription(tags); - sheetSet.put(new NodeProperty<>(Bundle.BlackboardArtifactNode_createSheet_score_name(), Bundle.BlackboardArtifactNode_createSheet_score_displayName(), scoreAndDescription.getRight(), scoreAndDescription.getLeft())); - } - - /** - * Get the score property for the node. - * - * @param tags the list of tags associated with the file - * - * @return score property and description + * @return The value of the score property as an enum element and a + * description string for dislpay in a tool tip. */ @Override protected Pair getScorePropertyAndDescription(List tags) { @@ -697,8 +748,8 @@ public class BlackboardArtifactNode extends AbstractContentNode 0 && (score == Score.NO_SCORE || score == Score.INTERESTING_SCORE)) { score = Score.INTERESTING_SCORE; @@ -725,41 +776,57 @@ public class BlackboardArtifactNode extends AbstractContentNode getCountPropertyAndDescription(Type attributeType, String attributeValue, String defaultDescription) { + protected Pair getCountPropertyAndDescription(Type corrAttrType, String attributeValue, String defaultDescription) { Long count = -1L; String description = defaultDescription; try { //don't perform the query if there is no correlation value - if (attributeType != null && StringUtils.isNotBlank(attributeValue)) { - count = CentralRepository.getInstance().getCountUniqueCaseDataSourceTuplesHavingTypeValue(attributeType, attributeValue); - description = Bundle.BlackboardArtifactNode_createSheet_count_description(count, attributeType.getDisplayName()); - } else if (attributeType != null) { + if (corrAttrType != null && StringUtils.isNotBlank(attributeValue)) { + count = CentralRepository.getInstance().getCountUniqueCaseDataSourceTuplesHavingTypeValue(corrAttrType, attributeValue); + description = Bundle.BlackboardArtifactNode_createSheet_count_description(count, corrAttrType.getDisplayName()); + } else if (corrAttrType != null) { description = Bundle.BlackboardArtifactNode_createSheet_count_noCorrelationValues_description(); } } catch (CentralRepoException ex) { - logger.log(Level.WARNING, "Error getting count of datasources with correlation attribute", ex); + logger.log(Level.SEVERE, MessageFormat.format("Error querying central repository for other occurences count (artifact objID={0}, content objID={1}, corrAttrType={2}, corrAttrValue={3})", artifact.getId(), sourceContent.getId(), corrAttrType, attributeValue), ex); } catch (CorrelationAttributeNormalizationException ex) { - logger.log(Level.WARNING, "Unable to normalize data to get count of datasources with correlation attribute", ex); + logger.log(Level.SEVERE, MessageFormat.format("Error normalizing correlation attribute for central repository query (artifact objID={0}, content objID={1}, corrAttrType={2}, corrAttrValue={3})", artifact.getId(), sourceContent.getId(), corrAttrType, attributeValue), ex); } return Pair.of(count, description); } + /** + * Refreshes this node's property sheet. + */ private void updateSheet() { this.setSheet(createSheet()); } - private String getRootParentName() { + /** + * Gets the name of the root ancestor of the source content for the artifact + * represented by this node. + * + * @return The root ancestor name or the empty string if an error occurs. + */ + private String getRootAncestorName() { String parentName = sourceContent.getName(); Content parent = sourceContent; try { @@ -767,32 +834,31 @@ public class BlackboardArtifactNode extends AbstractContentNode np) { - if (null == customProperties) { - //lazy create the list + public void addNodeProperty(NodeProperty property) { + if (customProperties == null) { customProperties = new ArrayList<>(); } - customProperties.add(np); + customProperties.add(property); } /** - * Fill map with Artifact properties + * Converts the attributes of the artifact this node represents to a map of + * name-value pairs, where the names are attribute type display names. * - * @param map map with preserved ordering, where property names/values - * are put - * @param artifact to extract properties from + * @param map The map to be populated with the artifact attribute + * name-value pairs. + * @param artifact The artifact. */ @SuppressWarnings("deprecation") private void fillPropertyMap(Map map, BlackboardArtifact artifact) { @@ -806,7 +872,9 @@ public class BlackboardArtifactNode extends AbstractContentNode 512) { @@ -830,16 +899,18 @@ public class BlackboardArtifactNode extends AbstractContentNode map, BlackboardAttribute attribute) { @@ -852,10 +923,10 @@ public class BlackboardArtifactNode extends AbstractContentNode 160) { value = value.substring(0, 160) + "..."; @@ -874,30 +945,6 @@ public class BlackboardArtifactNode extends AbstractContentNode artifact.getSleuthkitCase().getContentById(objectID)); - if (content == null) { - return Lookups.fixed(artifact); - } else { - return Lookups.fixed(artifact, content); - } - } catch (ExecutionException ex) { - logger.log(Level.WARNING, "Getting associated content for artifact failed", ex); //NON-NLS - return Lookups.fixed(artifact); - } - } - @Override public boolean isLeafTypeNode() { return true; @@ -914,52 +961,83 @@ public class BlackboardArtifactNode extends AbstractContentNode tags) { + Pair scoreAndDescription = getScorePropertyAndDescription(tags); + sheetSet.put(new NodeProperty<>(Bundle.BlackboardArtifactNode_createSheet_score_name(), Bundle.BlackboardArtifactNode_createSheet_score_displayName(), scoreAndDescription.getRight(), scoreAndDescription.getLeft())); + } + + /** + * Adds the tags property for the artifact represented by this node to the + * node property sheet. + * + * @param sheetSet The property sheet. + * + * @deprecated Do not use. The tags property is now computed in a background + * thread and added to the property sheet in this node's event + * PropertyChangeEventListner. */ @NbBundle.Messages({ - "BlackboardArtifactNode.createSheet.tags.displayName=Tags"}) + "BlackboardArtifactNode.createSheet.tags.displayName=Tags"} + ) @Deprecated protected void addTagProperty(Sheet.Set sheetSet) throws MissingResourceException { - // add properties for tags List tags = new ArrayList<>(); try { tags.addAll(Case.getCurrentCaseThrows().getServices().getTagsManager().getBlackboardArtifactTagsByArtifact(artifact)); tags.addAll(Case.getCurrentCaseThrows().getServices().getTagsManager().getContentTagsByContent(sourceContent)); } catch (TskCoreException | NoCurrentCaseException ex) { - logger.log(Level.SEVERE, "Failed to get tags for artifact " + artifact.getDisplayName(), ex); + logger.log(Level.SEVERE, MessageFormat.format("Error getting tags for artifact and source content (artifact objID={0}, content objID={1})", artifact.getId(), sourceContent.getId()), ex); } - sheetSet.put(new NodeProperty<>("Tags", Bundle.BlackboardArtifactNode_createSheet_tags_displayName(), - NO_DESCR, tags.stream().map(t -> t.getName().getDisplayName()).collect(Collectors.joining(", ")))); + sheetSet.put(new NodeProperty<>("Tags", Bundle.BlackboardArtifactNode_createSheet_tags_displayName(), NO_DESCR, tags.stream().map(t -> t.getName().getDisplayName()).collect(Collectors.joining(", ")))); } /** - * Used by (subclasses of) BlackboardArtifactNode to add the tags property - * to their sheets. + * Adds the tags property for the artifact represented by this node to the + * node property sheet. * - * @param sheetSet the modifiable Sheet.Set returned by - * Sheet.get(Sheet.PROPERTIES) - * @param tags the list of tags which should appear as the value for the - * property + * @param sheetSet The property sheet. + * @param tags The tags that have been applied to the artifact and its + * source content. + * + * @deprecated Do not use. The tags property is now computed in a background + * thread and added to the property sheet in this node's event + * PropertyChangeEventListner. */ @Deprecated protected final void addTagProperty(Sheet.Set sheetSet, List tags) { - sheetSet.put(new NodeProperty<>("Tags", Bundle.BlackboardArtifactNode_createSheet_tags_displayName(), - NO_DESCR, tags.stream().map(t -> t.getName().getDisplayName()).collect(Collectors.joining(", ")))); + sheetSet.put(new NodeProperty<>("Tags", Bundle.BlackboardArtifactNode_createSheet_tags_displayName(), NO_DESCR, tags.stream().map(t -> t.getName().getDisplayName()).collect(Collectors.joining(", ")))); } /** - * Used by (subclasses of) BlackboardArtifactNode to add the Occurrences - * property to their sheets. + * Adds the count property for the artifact represented by this node to the + * node property sheet. * - * @param sheetSet the modifiable Sheet.Set to add the property to - * @param attribute correlation attribute instance + * @param sheetSet The property sheet. + * @param attribute The correlation attribute instance to use for the + * central repository lookup. * - * @deprecated Use the GetSCOTask to get this data on a background - * thread..., and then update the property sheet asynchronously + * @deprecated Do not use. The count property is now computed in a + * background thread and added to the property sheet in this node's event + * PropertyChangeEventListner. */ @NbBundle.Messages({"BlackboardArtifactNode.createSheet.count.name=O", "BlackboardArtifactNode.createSheet.count.displayName=O", @@ -971,30 +1049,29 @@ public class BlackboardArtifactNode extends AbstractContentNode countAndDescription = getCountPropertyAndDescription(attribute.getCorrelationType(), attribute.getCorrelationValue(), Bundle.BlackboardArtifactNode_createSheet_count_noCorrelationAttributes_description()); - sheetSet.put( - new NodeProperty<>(Bundle.BlackboardArtifactNode_createSheet_count_name(), Bundle.BlackboardArtifactNode_createSheet_count_displayName(), countAndDescription.getRight(), countAndDescription.getLeft())); + sheetSet.put(new NodeProperty<>(Bundle.BlackboardArtifactNode_createSheet_count_name(), Bundle.BlackboardArtifactNode_createSheet_count_displayName(), countAndDescription.getRight(), countAndDescription.getLeft())); } /** - * Used by (subclasses of) BlackboardArtifactNode to add the comment - * property to their sheets. + * Adds the other occurrences property for the artifact represented by this + * node to the node property sheet. * - * @param sheetSet the modifiable Sheet.Set to add the property to - * @param tags the list of tags associated with the file - * @param attribute the correlation attribute associated with this - * artifact's associated file, null if central repo is not - * enabled + * @param sheetSet The property sheet. + * @param tags The tags that have been applied to the artifact and its + * source content. + * @param attribute The correlation attribute instance to use for the + * central repository lookup. * - * @deprecated Use the GetSCOTask to get this data on a background - * thread..., and then update the property sheet asynchronously + * @deprecated Do not use. The count property is now computed in a + * background thread and added to the property sheet in this node's event + * PropertyChangeEventListner. */ @NbBundle.Messages({"BlackboardArtifactNode.createSheet.comment.name=C", "BlackboardArtifactNode.createSheet.comment.displayName=C"}) @Deprecated protected final void addCommentProperty(Sheet.Set sheetSet, List tags, CorrelationAttributeInstance attribute) { HasCommentStatus status = getCommentProperty(tags, attribute); - sheetSet.put(new NodeProperty<>(Bundle.BlackboardArtifactNode_createSheet_comment_name(), Bundle.BlackboardArtifactNode_createSheet_comment_displayName(), NO_DESCR, - status)); + sheetSet.put(new NodeProperty<>(Bundle.BlackboardArtifactNode_createSheet_comment_name(), Bundle.BlackboardArtifactNode_createSheet_comment_displayName(), NO_DESCR, status)); } } From fccf6b53cde0e62d8dac6dba3971b95875a5ef09 Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Fri, 13 Mar 2020 21:35:06 -0400 Subject: [PATCH 061/100] Tidy up BlackboardArtifactNode.java --- .../sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java index 0b4d09a7b1..eb3571e0f1 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java @@ -268,9 +268,9 @@ public class BlackboardArtifactNode extends AbstractContentNode Date: Sat, 14 Mar 2020 10:53:24 -0400 Subject: [PATCH 062/100] Tidy up BlackboardArtifactNode.java --- .../datamodel/BlackboardArtifactNode.java | 384 +++++++++--------- 1 file changed, 201 insertions(+), 183 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java index eb3571e0f1..2283e9d14f 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java @@ -93,20 +93,16 @@ public class BlackboardArtifactNode extends AbstractContentNode contentCache = CacheBuilder.newBuilder().expireAfterWrite(1, TimeUnit.MINUTES).build(); /* - * Case application events that affect the property sheets of - * BlackboardArtifactNodes. - * - * NOTE: CURRENT_CASE (closed) events trigger content cache invalidation and - * unregistering of the PropertyChangeListener subscribed to the application - * events. + * Case events that indicate an update to the node's property sheet may be + * required. */ private static final Set CASE_EVENTS_OF_INTEREST = EnumSet.of( Case.Events.BLACKBOARD_ARTIFACT_TAG_ADDED, Case.Events.BLACKBOARD_ARTIFACT_TAG_DELETED, Case.Events.CONTENT_TAG_ADDED, Case.Events.CONTENT_TAG_DELETED, - Case.Events.CURRENT_CASE, - Case.Events.CR_COMMENT_CHANGED); + Case.Events.CR_COMMENT_CHANGED, + Case.Events.CURRENT_CASE); /* * Artifact types for which the unique path of the artifact's source content @@ -120,20 +116,23 @@ public class BlackboardArtifactNode extends AbstractContentNode> customProperties; + private Content srcContent; // May be null. /* - * The node's application event listener. + * A method has been provided to allow the injection of properties into this + * node for display in the node's property sheet, independent of the + * artifact the node represents. */ + private List> customProperties; + private final PropertyChangeListener appEventListener = new PropertyChangeListener() { @Override public void propertyChange(PropertyChangeEvent evt) { @@ -149,19 +148,25 @@ public class BlackboardArtifactNode extends AbstractContentNode(NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileModifiedTime.name"), NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileModifiedTime.displayName"), "", @@ -581,7 +570,7 @@ public class BlackboardArtifactNode extends AbstractContentNode(NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileSize.name"), NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileSize.displayName"), "", - sourceContent.getSize())); + file == null ? "" : file.getSize())); sheetSet.put(new NodeProperty<>(Bundle.BlackboardArtifactNode_createSheet_artifactMD5_name(), Bundle.BlackboardArtifactNode_createSheet_artifactMD5_displayName(), "", @@ -589,15 +578,17 @@ public class BlackboardArtifactNode extends AbstractContentNode tags = new ArrayList<>(); try { tags.addAll(Case.getCurrentCaseThrows().getServices().getTagsManager().getBlackboardArtifactTagsByArtifact(artifact)); - tags.addAll(Case.getCurrentCaseThrows().getServices().getTagsManager().getContentTagsByContent(sourceContent)); + if (srcContent != null) { + tags.addAll(Case.getCurrentCaseThrows().getServices().getTagsManager().getContentTagsByContent(srcContent)); + } } catch (TskCoreException | NoCurrentCaseException ex) { - logger.log(Level.SEVERE, MessageFormat.format("Error getting tags for artifact and its source content (artifact objID={0}, content objID={1})", artifact.getId(), sourceContent.getId()), ex); + logger.log(Level.SEVERE, MessageFormat.format("Error getting tags for artifact and its source content (artifact objID={0})", artifact.getId()), ex); } return tags; } @@ -668,28 +661,34 @@ public class BlackboardArtifactNode extends AbstractContentNode tags, CorrelationAttributeInstance attribute) { + /* + * Has a tag with a comment been applied to the artifact or its source + * content? + */ HasCommentStatus status = tags.size() > 0 ? HasCommentStatus.TAG_NO_COMMENT : HasCommentStatus.NO_COMMENT; for (Tag tag : tags) { if (!StringUtils.isBlank(tag.getComment())) { @@ -698,6 +697,10 @@ public class BlackboardArtifactNode extends AbstractContentNode getScorePropertyAndDescription(List tags) { + /* + * Is the artifact's source content marked as notable? + */ Score score = Score.NO_SCORE; String description = Bundle.BlackboardArtifactNode_createSheet_noScore_description(); - if (sourceContent instanceof AbstractFile) { - if (((AbstractFile) sourceContent).getKnown() == TskData.FileKnown.BAD) { + if (srcContent != null && srcContent instanceof AbstractFile) { + if (((AbstractFile) srcContent).getKnown() == TskData.FileKnown.BAD) { score = Score.NOTABLE_SCORE; description = Bundle.BlackboardArtifactNode_createSheet_notableFile_description(); } } - //if the artifact being viewed is a hashhit check if the hashset is notable - if ((score == Score.NO_SCORE || score == Score.INTERESTING_SCORE) && content.getArtifactTypeID() == ARTIFACT_TYPE.TSK_HASHSET_HIT.getTypeID()) { + + /* + * If the artifact is a hash set hit, is the hash set a notable hashes + * hash set? + */ + if (score == Score.NO_SCORE && artifact.getArtifactTypeID() == ARTIFACT_TYPE.TSK_HASHSET_HIT.getTypeID()) { try { - BlackboardAttribute attr = content.getAttribute(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_SET_NAME)); + BlackboardAttribute attr = artifact.getAttribute(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_SET_NAME)); List notableHashsets = HashDbManager.getInstance().getKnownBadFileHashSets(); for (HashDbManager.HashDb hashDb : notableHashsets) { if (hashDb.getHashSetName().equals(attr.getValueString())) { @@ -748,18 +762,29 @@ public class BlackboardArtifactNode extends AbstractContentNode 0 && (score == Score.NO_SCORE || score == Score.INTERESTING_SCORE)) { score = Score.INTERESTING_SCORE; description = Bundle.BlackboardArtifactNode_createSheet_taggedItem_description(); @@ -798,7 +823,6 @@ public class BlackboardArtifactNode extends AbstractContentNode map, BlackboardAttribute attribute) { - final int attributeTypeID = attribute.getAttributeType().getTypeID(); - - // Skip certain Email msg attributes if (attributeTypeID == ATTRIBUTE_TYPE.TSK_DATETIME_SENT.getTypeID() || attributeTypeID == ATTRIBUTE_TYPE.TSK_EMAIL_CONTENT_HTML.getTypeID() || attributeTypeID == ATTRIBUTE_TYPE.TSK_EMAIL_CONTENT_RTF.getTypeID() @@ -933,11 +954,10 @@ public class BlackboardArtifactNode extends AbstractContentNode tags = new ArrayList<>(); try { tags.addAll(Case.getCurrentCaseThrows().getServices().getTagsManager().getBlackboardArtifactTagsByArtifact(artifact)); - tags.addAll(Case.getCurrentCaseThrows().getServices().getTagsManager().getContentTagsByContent(sourceContent)); + tags.addAll(Case.getCurrentCaseThrows().getServices().getTagsManager().getContentTagsByContent(srcContent)); } catch (TskCoreException | NoCurrentCaseException ex) { - logger.log(Level.SEVERE, MessageFormat.format("Error getting tags for artifact and source content (artifact objID={0}, content objID={1})", artifact.getId(), sourceContent.getId()), ex); + logger.log(Level.SEVERE, MessageFormat.format("Error getting tags for artifact and source content (artifact objID={0})", artifact.getId()), ex); } sheetSet.put(new NodeProperty<>("Tags", Bundle.BlackboardArtifactNode_createSheet_tags_displayName(), NO_DESCR, tags.stream().map(t -> t.getName().getDisplayName()).collect(Collectors.joining(", ")))); } @@ -1019,8 +1038,7 @@ public class BlackboardArtifactNode extends AbstractContentNode tags) { @@ -1036,8 +1054,8 @@ public class BlackboardArtifactNode extends AbstractContentNode Date: Sat, 14 Mar 2020 11:20:51 -0400 Subject: [PATCH 063/100] Tidy up BlackboardArtifactNode.java --- .../org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java index 2283e9d14f..caa2481a4c 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java @@ -394,7 +394,7 @@ public class BlackboardArtifactNode extends AbstractContentNode Date: Sat, 14 Mar 2020 11:32:47 -0400 Subject: [PATCH 064/100] Improve performance of set display name for BlackboardArtifactNode --- .../datamodel/BlackboardArtifactNode.java | 48 +------------------ 1 file changed, 2 insertions(+), 46 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java index caa2481a4c..b4aafc2bcc 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java @@ -207,6 +207,7 @@ public class BlackboardArtifactNode extends AbstractContentNode Date: Sun, 15 Mar 2020 21:07:08 -0400 Subject: [PATCH 065/100] Update viber.py Address comments, remove inner try block. --- InternalPythonModules/android/viber.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/InternalPythonModules/android/viber.py b/InternalPythonModules/android/viber.py index 4bc2d0c5d2..1ad418b478 100644 --- a/InternalPythonModules/android/viber.py +++ b/InternalPythonModules/android/viber.py @@ -133,12 +133,8 @@ class ViberAnalyzer(general.AndroidComponentAnalyzer): attributes.add(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_NAME.getTypeID(), self._PARSER_NAME, contacts_parser.get_contact_name())) artifact.addAttributes(attributes) - try: # Post the artifact to blackboard - current_case.getBlackboard().postArtifact(artifact, self._PARSER_NAME) - except Blackboard.BlackboardException as e: - self.log(Level.WARNING, "Error adding viber contacts artifact to case database.", ex ) - self._logger.log(Level.WARNING, traceback.format_exc()) + current_case.getBlackboard().postArtifact(artifact, self._PARSER_NAME) contacts_parser.close() except SQLException as ex: From 77cafd322b14d8027b53e2d96ee74cd95c8e8ed2 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Mon, 16 Mar 2020 07:45:41 -0400 Subject: [PATCH 066/100] suppressed warnings for BasicComboBoxRenderer usage --- .../optionspanel/EamDbSettingsDialog.java | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java index 3b047b0e10..3322460b7d 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java @@ -68,6 +68,7 @@ public class EamDbSettingsDialog extends JDialog { private class DbChoiceRenderer extends BasicComboBoxRenderer { private static final long serialVersionUID = 1L; + @SuppressWarnings("rawtypes") public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { @@ -137,6 +138,14 @@ public class EamDbSettingsDialog extends JDialog { } + /** + * Sets the drowndown renderer so that an item is unselectable if inappropriate. + */ + @SuppressWarnings("unchecked") + private void setDropdownRenderer() { + cbDatabaseType.setRenderer(DB_CHOICE_RENDERER); + } + private void setupDbChoice(CentralRepoDbChoice initialMenuItem) { // setup initially selected item CentralRepoDbChoice toSelect = (initialMenuItem == null) ? @@ -144,10 +153,8 @@ public class EamDbSettingsDialog extends JDialog { manager.getSelectedDbChoice() : CentralRepoDbChoice.DB_CHOICES[0] : initialMenuItem; - - // set the renderer so item is unselectable if inappropriate - cbDatabaseType.setRenderer(DB_CHOICE_RENDERER); - + + setDropdownRenderer(); changeDbSelection(toSelect); } From d732e20839e7e8c10d4eda295487cd5e1b4ea3ee Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Mon, 16 Mar 2020 12:33:44 -0400 Subject: [PATCH 067/100] 6032 Move file name translation and make task --- .../datamodel/utils/FileNameTransTask.java | 61 ++++++++++++++++ .../utils/FileNameTranslator.java | 69 +++++++++++++++++++ 2 files changed, 130 insertions(+) create mode 100755 Core/src/org/sleuthkit/autopsy/datamodel/utils/FileNameTransTask.java create mode 100755 Core/src/org/sleuthkit/autopsy/texttranslation/utils/FileNameTranslator.java diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/utils/FileNameTransTask.java b/Core/src/org/sleuthkit/autopsy/datamodel/utils/FileNameTransTask.java new file mode 100755 index 0000000000..b11b7e2c64 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/datamodel/utils/FileNameTransTask.java @@ -0,0 +1,61 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2020 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.datamodel.utils; + +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import org.openide.nodes.AbstractNode; +import org.sleuthkit.autopsy.texttranslation.utils.FileNameTranslator; + +/** + * An AbstractNodePropertySheetTask that translates a file name for an + * AbstractNode's property sheet. + */ +public class FileNameTransTask extends AbstractNodePropertySheetTask { + + private final static String EVENT_SOURCE = FileNameTransTask.class.getName(); + private final static String PROPERTY_NAME = EVENT_SOURCE + ".TranslatedFileName"; + private final String fileName; + + public static String getPropertyName() { + return PROPERTY_NAME; + } + + /** + * Constructs an AbstractNodePropertySheetTask that translates a file name + * for an AbstractNode's property sheet. When the translation is complete, a + * PropertyChangeEvent will be fired to the node's PropertyChangeListener. + * Call getPropertyName() to identify the property. + * + * @param node The node. + * @param listener The node's PropertyChangeListener. + * @param fileName THe file name. + */ + public FileNameTransTask(String fileName, AbstractNode node, PropertyChangeListener listener) { + super(node, listener); + this.fileName = fileName; + } + + @Override + protected PropertyChangeEvent computePropertyValue(AbstractNode node) throws Exception { + String translatedFileName = FileNameTranslator.translate(fileName); + return new PropertyChangeEvent(EVENT_SOURCE, PROPERTY_NAME, fileName, "Foo"); + } + +} diff --git a/Core/src/org/sleuthkit/autopsy/texttranslation/utils/FileNameTranslator.java b/Core/src/org/sleuthkit/autopsy/texttranslation/utils/FileNameTranslator.java new file mode 100755 index 0000000000..34a6506d02 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/texttranslation/utils/FileNameTranslator.java @@ -0,0 +1,69 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2020-2020 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.texttranslation.utils; + +import org.apache.commons.io.FilenameUtils; +import org.sleuthkit.autopsy.texttranslation.NoServiceProviderException; +import org.sleuthkit.autopsy.texttranslation.TextTranslationService; +import org.sleuthkit.autopsy.texttranslation.TranslationException; + +/** + * A utility to translate file names. + */ +public class FileNameTranslator { + + /** + * Translates a file name using the configured machine translation service. + * + * @param fileName The file name. + * + * @return The translation of the file name. + * + * @throws NoServiceProviderException If machine translation is not + * configured. + * @throws TranslationException If there is an error doing the + * translation. + */ + public static String translate(String fileName) throws NoServiceProviderException, TranslationException { + +// //If already in complete English, don't translate. +// if (fileName.matches("^\\p{ASCII}+$")) { +// return ""; +// } + + TextTranslationService translator = TextTranslationService.getInstance(); + String baseName = FilenameUtils.getBaseName(fileName); + String translation = translator.translate(baseName); + if (!translation.isEmpty()) { + String extension = FilenameUtils.getExtension(fileName); + if (!extension.isEmpty()) { + String extensionDelimiter = (extension.isEmpty()) ? "" : "."; + translation += extensionDelimiter + extension; + } + } + return translation; + } + + /** + * Prevent instantiation of this utility class + */ + private FileNameTranslator() { + } + +} From e64d7bec042bab3d77bc142edfce17de4e10e324 Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Mon, 16 Mar 2020 14:25:21 -0400 Subject: [PATCH 068/100] 6032 Remove per node message box for missing context men item --- .../sleuthkit/autopsy/datamodel/BlackboardArtifactTagNode.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactTagNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactTagNode.java index 16cf40680c..a6a0a66590 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactTagNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactTagNode.java @@ -119,7 +119,6 @@ public class BlackboardArtifactTagNode extends DisplayableItemNode { } } catch (TskCoreException ex) { LOGGER.log(Level.SEVERE, MessageFormat.format("Error getting arttribute(s) from blackboard artifact{0}.", artifact.getArtifactID()), ex); //NON-NLS - MessageNotifyUtil.Notify.error(Bundle.BlackboardArtifactNode_getAction_errorTitle(), Bundle.BlackboardArtifactNode_getAction_resultErrorMessage()); } // if the artifact links to another file, add an action to go to that file @@ -130,7 +129,6 @@ public class BlackboardArtifactTagNode extends DisplayableItemNode { } } catch (TskCoreException ex) { LOGGER.log(Level.SEVERE, MessageFormat.format("Error getting linked file from blackboard artifact{0}.", artifact.getArtifactID()), ex); //NON-NLS - MessageNotifyUtil.Notify.error(Bundle.BlackboardArtifactNode_getAction_errorTitle(), Bundle.BlackboardArtifactNode_getAction_linkedFileMessage()); } //if this artifact has associated content, add the action to view the content in the timeline AbstractFile file = getLookup().lookup(AbstractFile.class); From 1085baf9cdf32763e9c0365161bd4c64084ecb44 Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Tue, 17 Mar 2020 08:43:04 -0400 Subject: [PATCH 069/100] Extend file name translation to BlackboardArtifactNodes --- .../datamodel/AbstractAbstractFileNode.java | 44 +--- .../datamodel/BlackboardArtifactNode.java | 202 +++++++++++++----- .../autopsy/datamodel/Bundle.properties | 2 - .../datamodel/Bundle.properties-MERGED | 6 +- .../utils/AbstractNodePropertySheetTask.java | 16 +- .../datamodel/utils/FileNameTransTask.java | 2 +- .../utils/FileNameTranslator.java | 14 +- 7 files changed, 182 insertions(+), 104 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java index 1d53e46ca6..e2043846fe 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java @@ -21,6 +21,7 @@ package org.sleuthkit.autopsy.datamodel; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.lang.ref.WeakReference; +import java.text.MessageFormat; import java.util.ArrayList; import java.util.EnumSet; import java.util.List; @@ -28,7 +29,6 @@ import java.util.Map; import java.util.Set; import java.util.logging.Level; import java.util.stream.Collectors; -import org.apache.commons.io.FilenameUtils; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.tuple.Pair; import org.openide.nodes.Sheet; @@ -66,6 +66,7 @@ import org.sleuthkit.datamodel.Tag; import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.datamodel.TskData; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository; +import org.sleuthkit.autopsy.texttranslation.utils.FileNameTranslator; /** * An abstract node that encapsulates AbstractFile data @@ -94,15 +95,15 @@ public abstract class AbstractAbstractFileNode extends A IngestManager.getInstance().addIngestModuleEventListener(INGEST_MODULE_EVENTS_OF_INTEREST, weakPcl); } } - + try { //See JIRA-5971 //Attempt to cache file path during construction of this UI component. this.content.getUniquePath(); } catch (TskCoreException ex) { logger.log(Level.SEVERE, String.format("Failed attempt to cache the " - + "unique path of the abstract file instance. Name: %s (objID=%d)", - this.content.getName(), this.content.getId()), ex); + + "unique path of the abstract file instance. Name: %s (objID=%d)", + this.content.getName(), this.content.getId()), ex); } if (TextTranslationService.getInstance().hasProvider() && UserPreferences.displayTranslatedFileNames()) { @@ -490,39 +491,16 @@ public abstract class AbstractAbstractFileNode extends A } /** - * Translates this nodes content name. Doesn't attempt translation if the - * name is in english or if there is now translation service available. + * Translates the name of the file this node represents. An empty string + * will be returned if the translation fails for any reason. */ String getTranslatedFileName() { - //If already in complete English, don't translate. - if (content.getName().matches("^\\p{ASCII}+$")) { + try { + return FileNameTranslator.translate(content.getName()); + } catch (NoServiceProviderException | TranslationException ex) { + logger.log(Level.WARNING, MessageFormat.format("Error translating file name (objID={0}))", content.getId()), ex); return ""; } - TextTranslationService tts = TextTranslationService.getInstance(); - if (tts.hasProvider()) { - //Seperate out the base and ext from the contents file name. - String base = FilenameUtils.getBaseName(content.getName()); - try { - String translation = tts.translate(base); - String ext = FilenameUtils.getExtension(content.getName()); - - //If we have no extension, then we shouldn't add the . - String extensionDelimiter = (ext.isEmpty()) ? "" : "."; - - //Talk directly to this nodes pcl, fire an update when the translation - //is complete. - if (!translation.isEmpty()) { - return translation + extensionDelimiter + ext; - } - } catch (NoServiceProviderException noServiceEx) { - logger.log(Level.WARNING, "Translate unsuccessful because no TextTranslator " - + "implementation was provided.", noServiceEx.getMessage()); - } catch (TranslationException noTranslationEx) { - logger.log(Level.WARNING, "Could not successfully translate file name " - + content.getName(), noTranslationEx.getMessage()); - } - } - return ""; } /** diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java index b4aafc2bcc..055d322203 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java @@ -76,6 +76,9 @@ import org.sleuthkit.datamodel.Tag; import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.datamodel.TskData; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository; +import static org.sleuthkit.autopsy.datamodel.AbstractContentNode.NO_DESCR; +import org.sleuthkit.autopsy.texttranslation.TextTranslationService; +import org.sleuthkit.autopsy.datamodel.utils.FileNameTransTask; /** * A BlackboardArtifactNode is an AbstractNode implementation that can be used @@ -124,7 +127,7 @@ public class BlackboardArtifactNode extends AbstractContentNode> customProperties; - private final PropertyChangeListener appEventListener = new PropertyChangeListener() { + private final PropertyChangeListener listener = new PropertyChangeListener() { @Override public void propertyChange(PropertyChangeEvent evt) { String eventType = evt.getPropertyName(); @@ -187,6 +190,17 @@ public class BlackboardArtifactNode extends AbstractContentNode(Bundle.BlackboardArtifactNode_createSheet_count_name(), Bundle.BlackboardArtifactNode_createSheet_count_displayName(), scoData.getCountAndDescription().getRight(), scoData.getCountAndDescription().getLeft())); } + } else if (eventType.equals(FileNameTransTask.getPropertyName())) { + /* + * Replace the value of the Source File property with the + * translated name via setDisplayName (see note in createSheet), + * and put the untranslated name in the Original Name property. + * Also set the tooltip to the original name. + */ + setDisplayName(evt.getNewValue().toString()); + setShortDescription(evt.getOldValue().toString()); + updateSheet(new NodeProperty<>(Bundle.BlackboardArtifactNode_createSheet_srcFile_name(), Bundle.BlackboardArtifactNode_createSheet_srcFile_displayName(), NO_DESCR, (String) evt.getNewValue())); + //updateSheet(new NodeProperty<>(Bundle.BlackboardArtifactNode_createSheet_srcFile_origName(), Bundle.BlackboardArtifactNode_createSheet_srcFile_origDisplayName(), NO_DESCR, (String) evt.getOldValue())); } } }; @@ -198,7 +212,7 @@ public class BlackboardArtifactNode extends AbstractContentNode(NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.srcFile.name"), - NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.srcFile.displayName"), + sheetSet.put(new NodeProperty<>( + Bundle.BlackboardArtifactNode_createSheet_srcFile_name(), + Bundle.BlackboardArtifactNode_createSheet_srcFile_displayName(), NO_DESCR, this.getSourceName())); + if (TextTranslationService.getInstance().hasProvider() && UserPreferences.displayTranslatedFileNames()) { + /* + * If machine translation is configured, add the original name of + * the of the source content of the artifact represented by this + * node to the sheet. + */ + sheetSet.put(new NodeProperty<>( + Bundle.BlackboardArtifactNode_createSheet_srcFile_origName(), + Bundle.BlackboardArtifactNode_createSheet_srcFile_origDisplayName(), + NO_DESCR, + "")); + if (srcContent != null) { + new FileNameTransTask(srcContent.getName(), this, listener).submit(); + } + } + if (!UserPreferences.getHideSCOColumns()) { /* * Add S(core), C(omments), and O(ther occurences) columns to the @@ -414,14 +463,20 @@ public class BlackboardArtifactNode extends AbstractContentNode(NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.artifactType.name"), - NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.artifactType.displayName"), - NO_DESCR, - associatedArtifact.getDisplayName())); - sheetSet.put(new NodeProperty<>(NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.artifactDetails.name"), - NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.artifactDetails.displayName"), - NO_DESCR, - associatedArtifact.getShortDescription())); + sheetSet + .put(new NodeProperty<>(NbBundle.getMessage(BlackboardArtifactNode.class, + "BlackboardArtifactNode.createSheet.artifactType.name"), + NbBundle.getMessage(BlackboardArtifactNode.class, + "BlackboardArtifactNode.createSheet.artifactType.displayName"), + NO_DESCR, + associatedArtifact.getDisplayName())); + sheetSet + .put(new NodeProperty<>(NbBundle.getMessage(BlackboardArtifactNode.class, + "BlackboardArtifactNode.createSheet.artifactDetails.name"), + NbBundle.getMessage(BlackboardArtifactNode.class, + "BlackboardArtifactNode.createSheet.artifactDetails.displayName"), + NO_DESCR, + associatedArtifact.getShortDescription())); } } catch (TskCoreException | NoCurrentCaseException ex) { logger.log(Level.SEVERE, MessageFormat.format("Error getting associated artifact of TSK_INTERESTING_ARTIFACT_HIT artifact (objID={0}))", artifact.getId()), ex); //NON-NLS @@ -465,17 +520,23 @@ public class BlackboardArtifactNode extends AbstractContentNode(NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.ext.name"), - NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.ext.displayName"), + sheetSet.put(new NodeProperty<>(NbBundle.getMessage(BlackboardArtifactNode.class, + "BlackboardArtifactNode.createSheet.ext.name"), + NbBundle.getMessage(BlackboardArtifactNode.class, + "BlackboardArtifactNode.createSheet.ext.displayName"), NO_DESCR, ext)); - sheetSet.put(new NodeProperty<>( - NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.mimeType.name"), - NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.mimeType.displayName"), - NO_DESCR, - actualMimeType)); + sheetSet + .put(new NodeProperty<>( + NbBundle.getMessage(BlackboardArtifactNode.class, + "BlackboardArtifactNode.createSheet.mimeType.name"), + NbBundle.getMessage(BlackboardArtifactNode.class, + "BlackboardArtifactNode.createSheet.mimeType.displayName"), + NO_DESCR, + actualMimeType)); } /* @@ -489,13 +550,16 @@ public class BlackboardArtifactNode extends AbstractContentNode( - NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.filePath.name"), - NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.filePath.displayName"), + NbBundle.getMessage(BlackboardArtifactNode.class, + "BlackboardArtifactNode.createSheet.filePath.name"), + NbBundle.getMessage(BlackboardArtifactNode.class, + "BlackboardArtifactNode.createSheet.filePath.displayName"), NO_DESCR, sourcePath)); } @@ -507,26 +571,41 @@ public class BlackboardArtifactNode extends AbstractContentNode(NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileModifiedTime.name"), - NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileModifiedTime.displayName"), - "", - file == null ? "" : ContentUtils.getStringTime(file.getMtime(), file))); - sheetSet.put(new NodeProperty<>(NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileChangedTime.name"), - NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileChangedTime.displayName"), - "", - file == null ? "" : ContentUtils.getStringTime(file.getCtime(), file))); - sheetSet.put(new NodeProperty<>(NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileAccessedTime.name"), - NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileAccessedTime.displayName"), - "", - file == null ? "" : ContentUtils.getStringTime(file.getAtime(), file))); - sheetSet.put(new NodeProperty<>(NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileCreatedTime.name"), - NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileCreatedTime.displayName"), - "", - file == null ? "" : ContentUtils.getStringTime(file.getCrtime(), file))); - sheetSet.put(new NodeProperty<>(NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileSize.name"), - NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileSize.displayName"), - "", - file == null ? "" : file.getSize())); + sheetSet + .put(new NodeProperty<>(NbBundle.getMessage(BlackboardArtifactNode.class, + "ContentTagNode.createSheet.fileModifiedTime.name"), + NbBundle.getMessage(BlackboardArtifactNode.class, + "ContentTagNode.createSheet.fileModifiedTime.displayName"), + "", + file == null ? "" : ContentUtils.getStringTime(file.getMtime(), file))); + sheetSet + .put(new NodeProperty<>(NbBundle.getMessage(BlackboardArtifactNode.class, + "ContentTagNode.createSheet.fileChangedTime.name"), + NbBundle.getMessage(BlackboardArtifactNode.class, + "ContentTagNode.createSheet.fileChangedTime.displayName"), + "", + file == null ? "" : ContentUtils.getStringTime(file.getCtime(), file))); + sheetSet + .put(new NodeProperty<>(NbBundle.getMessage(BlackboardArtifactNode.class, + "ContentTagNode.createSheet.fileAccessedTime.name"), + NbBundle.getMessage(BlackboardArtifactNode.class, + "ContentTagNode.createSheet.fileAccessedTime.displayName"), + "", + file == null ? "" : ContentUtils.getStringTime(file.getAtime(), file))); + sheetSet + .put(new NodeProperty<>(NbBundle.getMessage(BlackboardArtifactNode.class, + "ContentTagNode.createSheet.fileCreatedTime.name"), + NbBundle.getMessage(BlackboardArtifactNode.class, + "ContentTagNode.createSheet.fileCreatedTime.displayName"), + "", + file == null ? "" : ContentUtils.getStringTime(file.getCrtime(), file))); + sheetSet + .put(new NodeProperty<>(NbBundle.getMessage(BlackboardArtifactNode.class, + "ContentTagNode.createSheet.fileSize.name"), + NbBundle.getMessage(BlackboardArtifactNode.class, + "ContentTagNode.createSheet.fileSize.displayName"), + "", + file == null ? "" : file.getSize())); sheetSet.put(new NodeProperty<>(Bundle.BlackboardArtifactNode_createSheet_artifactMD5_name(), Bundle.BlackboardArtifactNode_createSheet_artifactMD5_displayName(), "", @@ -544,13 +623,16 @@ public class BlackboardArtifactNode extends AbstractContentNode( - NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.dataSrc.name"), - NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.dataSrc.displayName"), + NbBundle.getMessage(BlackboardArtifactNode.class, + "BlackboardArtifactNode.createSheet.dataSrc.name"), + NbBundle.getMessage(BlackboardArtifactNode.class, + "BlackboardArtifactNode.createSheet.dataSrc.displayName"), NO_DESCR, dataSourceStr)); } @@ -570,17 +652,23 @@ public class BlackboardArtifactNode extends AbstractContentNode(NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.fileSize.name"), - NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.fileSize.displayName"), + sheetSet.put(new NodeProperty<>(NbBundle.getMessage(BlackboardArtifactNode.class, + "BlackboardArtifactNode.createSheet.fileSize.name"), + NbBundle.getMessage(BlackboardArtifactNode.class, + "BlackboardArtifactNode.createSheet.fileSize.displayName"), NO_DESCR, size)); - sheetSet.put(new NodeProperty<>( - NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.path.name"), - NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.path.displayName"), - NO_DESCR, - path)); + sheetSet + .put(new NodeProperty<>( + NbBundle.getMessage(BlackboardArtifactNode.class, + "BlackboardArtifactNode.createSheet.path.name"), + NbBundle.getMessage(BlackboardArtifactNode.class, + "BlackboardArtifactNode.createSheet.path.displayName"), + NO_DESCR, + path)); } return sheet; @@ -1036,8 +1124,8 @@ public class BlackboardArtifactNode extends AbstractContentNode impl * @return The Future of the task, may be used for task cancellation by * calling Future.cancel(true). */ - public static Future submitTask(AbstractNodePropertySheetTask task) { + private static Future submitTask(AbstractNodePropertySheetTask task) { return executor.submit(task); } @@ -104,12 +104,22 @@ public abstract class AbstractNodePropertySheetTask impl * * @param node The AbstractNode. * - * @return The result of the computation as a PropertyChangeEvent. + * @return The result of the computation as a PropertyChangeEvent, may be + * null. */ protected abstract PropertyChangeEvent computePropertyValue(T node) throws Exception; + /** + * Submits this task to the ExecutorService for the thread pool. + * + * @return The task's Future from the ExecutorService. + */ + public final Future submit() { + return submitTask(this); + } + @Override - final public void run() { + public final void run() { try { T node = this.weakNodeRef.get(); PropertyChangeListener listener = this.weakListenerRef.get(); diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/utils/FileNameTransTask.java b/Core/src/org/sleuthkit/autopsy/datamodel/utils/FileNameTransTask.java index b11b7e2c64..88ccac2d2f 100755 --- a/Core/src/org/sleuthkit/autopsy/datamodel/utils/FileNameTransTask.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/utils/FileNameTransTask.java @@ -55,7 +55,7 @@ public class FileNameTransTask extends AbstractNodePropertySheetTask Date: Tue, 17 Mar 2020 09:44:15 -0400 Subject: [PATCH 070/100] Update cachelocation.py Change GPS_TRACKPOINT to GPS_BOOKMARK. Change how cache file is processed and read. --- .../android/cachelocation.py | 73 +++++-------------- 1 file changed, 18 insertions(+), 55 deletions(-) diff --git a/InternalPythonModules/android/cachelocation.py b/InternalPythonModules/android/cachelocation.py index 1fb162a817..3697fb44b0 100644 --- a/InternalPythonModules/android/cachelocation.py +++ b/InternalPythonModules/android/cachelocation.py @@ -41,6 +41,7 @@ from org.sleuthkit.datamodel import TskCoreException import traceback import general +import struct """ Parses cache files that Android maintains for Wifi and cell towers. Adds GPS points to blackboard. @@ -74,60 +75,24 @@ class CacheLocationAnalyzer(general.AndroidComponentAnalyzer): def __findGeoLocationsInFile(self, file, abstractFile): - tempBytes = bytearray([0] * 2) # will temporarily hold bytes to be converted into the correct data types - try: - inputStream = FileInputStream(file) - - inputStream.read(tempBytes) # version - - tempBytes = bytearray([0] * 2) - inputStream.read(tempBytes) # number of location entries - - iterations = BigInteger(tempBytes).intValue() - - for i in range(iterations): # loop through every entry - tempBytes = bytearray([0] * 2) - inputStream.read(tempBytes) - - tempBytes = bytearray([0]) - inputStream.read(tempBytes) - - while BigInteger(tempBytes).intValue() != 0: # pass through non important values until the start of accuracy(around 7-10 bytes) - if 0 > inputStream.read(tempBytes): - break # we've passed the end of the file, so stop - - tempBytes = bytearray([0] * 3) - inputStream.read(tempBytes) - if BigInteger(tempBytes).intValue() <= 0: # This refers to a location that could not be calculated - tempBytes = bytearray([0] * 28) # read rest of the row's bytes - inputStream.read(tempBytes) - continue - accuracy = "" + BigInteger(tempBytes).intValue() - - tempBytes = bytearray([0] * 4) - inputStream.read(tempBytes) - confidence = "" + BigInteger(tempBytes).intValue() - - tempBytes = bytearray([0] * 8) - inputStream.read(tempBytes) - latitude = CacheLocationAnalyzer.toDouble(bytes) - - tempBytes = bytearray([0] * 8) - inputStream.read(tempBytes) - longitude = CacheLocationAnalyzer.toDouble(bytes) - - tempBytes = bytearray([0] * 8) - inputStream.read(tempBytes) - timestamp = BigInteger(tempBytes).longValue() / 1000 + # code to parse the cache.wifi and cache.cell taken from https://forensics.spreitzenbarth.de/2011/10/28/decoding-cache-cell-and-cache-wifi-files/ + cacheFile = open(str(file), 'rb') + (version, entries) = struct.unpack('>hh', cacheFile.read(4)) + i = 0 + while i < entries: + key = cacheFile.read(struct.unpack('>h', cacheFile.read(2))[0]) + (accuracy, confidence, latitude, longitude, readtime) = struct.unpack('>iiddQ', cacheFile.read(32)) + timestamp = readtime/1000 + i = i + 1 attributes = ArrayList() - artifact = abstractFile.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_TRACKPOINT) - attributes.add(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LATITUDE, AndroidAnalyzer.MODULE_NAME, latitude)) - attributes.add(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LONGITUDE, AndroidAnalyzer.MODULE_NAME, longitude)) - attributes.add(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME, AndroidModuleFactorymodule.Name, timestamp)) - attributes.add(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME, AndroidAnalyzer.MODULE_NAME, - file.getName() + "Location History")) + artifact = abstractFile.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_BOOKMARK) + attributes.add(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LATITUDE, general.MODULE_NAME, latitude)) + attributes.add(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LONGITUDE, general.MODULE_NAME, longitude)) + attributes.add(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME, general.MODULE_NAME, timestamp)) + attributes.add(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME, general.MODULE_NAME, + abstractFile.getName() + " Location History")) artifact.addAttributes(attributes) #Not storing these for now. @@ -136,15 +101,13 @@ class CacheLocationAnalyzer(general.AndroidComponentAnalyzer): try: # index the artifact for keyword search blackboard = Case.getCurrentCase().getSleuthkitCase().getBlackboard() - blackboard.postArtifact(artifact, MODULE_NAME) + blackboard.postArtifact(artifact, general.MODULE_NAME) except Blackboard.BlackboardException as ex: self._logger.log(Level.SEVERE, "Unable to index blackboard artifact " + str(artifact.getArtifactID()), ex) self._logger.log(Level.SEVERE, traceback.format_exc()) MessageNotifyUtil.Notify.error("Failed to index GPS trackpoint artifact for keyword search.", artifact.getDisplayName()) + cacheFile.close() - except SQLException as ex: - # Unable to execute Cached GPS locations SQL query against database. - pass except Exception as ex: self._logger.log(Level.SEVERE, "Error parsing Cached GPS locations to blackboard", ex) self._logger.log(Level.SEVERE, traceback.format_exc()) From da735c673e88667f532f0b1a77bef51a7b354f93 Mon Sep 17 00:00:00 2001 From: Mark McKinnon Date: Tue, 17 Mar 2020 10:10:56 -0400 Subject: [PATCH 071/100] Update browserlocation.py Change GPS_Trackpoint to GPS_Bookmark --- InternalPythonModules/android/browserlocation.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/InternalPythonModules/android/browserlocation.py b/InternalPythonModules/android/browserlocation.py index 84c2a601e7..c202c36d2a 100644 --- a/InternalPythonModules/android/browserlocation.py +++ b/InternalPythonModules/android/browserlocation.py @@ -95,7 +95,7 @@ class BrowserLocationAnalyzer(general.AndroidComponentAnalyzer): longitude = Double.valueOf(resultSet.getString("longitude")) attributes = ArrayList() - artifact = abstractFile.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_TRACKPOINT) + artifact = abstractFile.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_BOOKMARK) attributes.add(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LATITUDE, general.MODULE_NAME, latitude)) attributes.add(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LONGITUDE, general.MODULE_NAME, longitude)) attributes.add(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME, general.MODULE_NAME, timestamp)) From 04638faa85268212992ad7917ce346f76df40dca Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Tue, 17 Mar 2020 14:57:11 -0400 Subject: [PATCH 072/100] updated to use TypedBasicComboBoxRenderer --- .../optionspanel/EamDbSettingsDialog.java | 25 ++++++------------- 1 file changed, 7 insertions(+), 18 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java index 3322460b7d..09b98a7337 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java @@ -38,7 +38,6 @@ import javax.swing.SwingUtilities; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import javax.swing.filechooser.FileFilter; -import javax.swing.plaf.basic.BasicComboBoxRenderer; import org.netbeans.spi.options.OptionsPanelController; import org.openide.util.NbBundle; import org.openide.util.NbBundle.Messages; @@ -65,19 +64,17 @@ public class EamDbSettingsDialog extends JDialog { /** * This class handles displaying and rendering drop down menu for database choices in central repo. */ - private class DbChoiceRenderer extends BasicComboBoxRenderer { + private class DbChoiceRenderer extends TypedBasicComboBoxRenderer { private static final long serialVersionUID = 1L; - @SuppressWarnings("rawtypes") - public Component getListCellRendererComponent(JList list, Object value, + public Component getListCellRendererComponent( + JList list, CentralRepoDbChoice value, int index, boolean isSelected, boolean cellHasFocus) { - CentralRepoDbChoice item = (CentralRepoDbChoice) value; - // disable cell if it is the db connection from multi user settings // and that option is not enabled in multi user settings - setText(item.getTitle()); - setEnabled(isDbChoiceSelectable(item)); + setText(value.getTitle()); + setEnabled(isDbChoiceSelectable(value)); return this; } } @@ -136,15 +133,7 @@ public class EamDbSettingsDialog extends JDialog { valid(); display(); } - - - /** - * Sets the drowndown renderer so that an item is unselectable if inappropriate. - */ - @SuppressWarnings("unchecked") - private void setDropdownRenderer() { - cbDatabaseType.setRenderer(DB_CHOICE_RENDERER); - } + private void setupDbChoice(CentralRepoDbChoice initialMenuItem) { // setup initially selected item @@ -154,7 +143,7 @@ public class EamDbSettingsDialog extends JDialog { CentralRepoDbChoice.DB_CHOICES[0] : initialMenuItem; - setDropdownRenderer(); + cbDatabaseType.setRenderer(DB_CHOICE_RENDERER); changeDbSelection(toSelect); } From 87b6398cfc6ce5396e0bfa4706493fc80b52559f Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Tue, 17 Mar 2020 14:57:20 -0400 Subject: [PATCH 073/100] updated to use TypedBasicComboBoxRenderer --- .../TypedBasicComboBoxRenderer.java | 71 +++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/TypedBasicComboBoxRenderer.java diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/TypedBasicComboBoxRenderer.java b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/TypedBasicComboBoxRenderer.java new file mode 100644 index 0000000000..8788651f73 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/TypedBasicComboBoxRenderer.java @@ -0,0 +1,71 @@ +/* + * Central Repository + * + * Copyright 2015-2020 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.centralrepository.optionspanel; + +import java.awt.Dimension; +import java.io.Serializable; +import javax.swing.JLabel; +import javax.swing.ListCellRenderer; +import javax.swing.border.Border; +import javax.swing.border.EmptyBorder; + +/** + * This class implements the same behavior as the BasicComboBoxRenderer while + * providing type safety. + * @param The object type that will be used in the combo box. + */ +public abstract class TypedBasicComboBoxRenderer extends JLabel +implements ListCellRenderer, Serializable { + + protected static Border noFocusBorder = new EmptyBorder(1, 1, 1, 1); + private final static Border SAFE_NO_FOCUS_BORDER = new EmptyBorder(1, 1, 1, 1); + + /** + * The main constructor for this class. + */ + public TypedBasicComboBoxRenderer() { + super(); + setOpaque(true); + setBorder(getNoFocusBorder()); + } + + private static Border getNoFocusBorder() { + if (System.getSecurityManager() != null) { + return SAFE_NO_FOCUS_BORDER; + } else { + return noFocusBorder; + } + } + + @Override + public Dimension getPreferredSize() { + Dimension size; + + if ((this.getText() == null) || (this.getText().equals( "" ))) { + setText( " " ); + size = super.getPreferredSize(); + setText( "" ); + } + else { + size = super.getPreferredSize(); + } + + return size; + } +} From 291d778ee2a96bf2d36e15f08ebe50650ed719f7 Mon Sep 17 00:00:00 2001 From: Raman Arora Date: Tue, 17 Mar 2020 16:16:04 -0400 Subject: [PATCH 074/100] 6151: Do not add account_id column to non-account correlation attribute instance tables --- .../CentralRepoDbUpgrader13To14.java | 25 ++++++------ .../datamodel/CentralRepoDbUtil.java | 13 +++++++ .../datamodel/RdbmsCentralRepo.java | 31 ++++++++++----- .../datamodel/RdbmsCentralRepoFactory.java | 38 +++++++++++++++++-- 4 files changed, 82 insertions(+), 25 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbUpgrader13To14.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbUpgrader13To14.java index 9d6473055e..dbd1e77da4 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbUpgrader13To14.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbUpgrader13To14.java @@ -51,7 +51,7 @@ public class CentralRepoDbUpgrader13To14 implements CentralRepoDbUpgrader { if (type.getId() >= CorrelationAttributeInstance.ADDITIONAL_TYPES_BASE_ID) { // these are new Correlation types - new tables need to be created - statement.execute(String.format(RdbmsCentralRepoFactory.getCreateArtifactInstancesTableTemplate(selectedPlatform), instance_type_dbname, instance_type_dbname)); + statement.execute(String.format(RdbmsCentralRepoFactory.getCreateAccountInstancesTableTemplate(selectedPlatform), instance_type_dbname, instance_type_dbname)); statement.execute(String.format(RdbmsCentralRepoFactory.getAddCaseIdIndexTemplate(), instance_type_dbname, instance_type_dbname)); statement.execute(String.format(RdbmsCentralRepoFactory.getAddDataSourceIdIndexTemplate(), instance_type_dbname, instance_type_dbname)); statement.execute(String.format(RdbmsCentralRepoFactory.getAddValueIndexTemplate(), instance_type_dbname, instance_type_dbname)); @@ -61,18 +61,19 @@ public class CentralRepoDbUpgrader13To14 implements CentralRepoDbUpgrader { // add new correlation type CentralRepoDbUtil.insertCorrelationType(connection, type); - } else { - - // Alter the existing X_Instance tables to add account_id column - String sqlStr = String.format(getAlterArtifactInstancesAddAccountIdTemplate(selectedPlatform), instance_type_dbname); - statement.execute(sqlStr); - - // SQLite does NOT allow adding a constraint with Alter Table statement. - // The alternative would be to create new tables, copy all data over, and delete old tables - potentially a time consuming process. - // We decided to not add this constraint for SQLite, since there likely aren't many users using SQLite based Central Repo. - if (selectedPlatform == CentralRepoPlatforms.POSTGRESQL) { - sqlStr = String.format(getAlterArtifactInstancesAddAccountIdConstraintTemplate(), instance_type_dbname); + } else { // existing attributes + // Alter the existing _instance tables for Phone and Email attributes to add account_id column + if (type.getId() == CorrelationAttributeInstance.EMAIL_TYPE_ID || type.getId() == CorrelationAttributeInstance.PHONE_TYPE_ID) { + String sqlStr = String.format(getAlterArtifactInstancesAddAccountIdTemplate(selectedPlatform), instance_type_dbname); statement.execute(sqlStr); + + // SQLite does NOT allow adding a constraint with Alter Table statement. + // The alternative would be to create new tables, copy all data over, and delete old tables - potentially a time consuming process. + // We decided to not add this constraint for SQLite, since there likely aren't many users using SQLite based Central Repo. + if (selectedPlatform == CentralRepoPlatforms.POSTGRESQL) { + sqlStr = String.format(getAlterArtifactInstancesAddAccountIdConstraintTemplate(), instance_type_dbname); + statement.execute(sqlStr); + } } } } diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbUtil.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbUtil.java index 826c315c02..69ea8d4e05 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbUtil.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbUtil.java @@ -325,4 +325,17 @@ public class CentralRepoDbUtil { closeStatement(preparedStatement); } + /** + * Checks if the given correlation attribute type has an account behind it. + * + * @param type Correlation type to check. + * + * @return True If the specified correlation type has an account. + */ + static boolean correlationAttribHasAnAccount(CorrelationAttributeInstance.Type type) { + return (type.getId() >= CorrelationAttributeInstance.ADDITIONAL_TYPES_BASE_ID) + || type.getId() == CorrelationAttributeInstance.PHONE_TYPE_ID + || type.getId() == CorrelationAttributeInstance.EMAIL_TYPE_ID; + } + } diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/RdbmsCentralRepo.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/RdbmsCentralRepo.java index 63f8e2f13a..148513f40c 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/RdbmsCentralRepo.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/RdbmsCentralRepo.java @@ -1002,18 +1002,26 @@ abstract class RdbmsCentralRepo implements CentralRepository { public void addArtifactInstance(CorrelationAttributeInstance eamArtifact) throws CentralRepoException { checkAddArtifactInstanceNulls(eamArtifact); - - - - // @@@ We should cache the case and data source IDs in memory String tableName = CentralRepoDbUtil.correlationTypeToInstanceTableName(eamArtifact.getCorrelationType()); - String sql - = "INSERT INTO " + boolean artifactHasAnAccount = CentralRepoDbUtil.correlationAttribHasAnAccount(eamArtifact.getCorrelationType()); + + String sql; + // _instance table for accounts have an additional account_id column + if (artifactHasAnAccount) { + sql = "INSERT INTO " + tableName + "(case_id, data_source_id, value, file_path, known_status, comment, file_obj_id, account_id) " + "VALUES (?, ?, ?, ?, ?, ?, ?, ?) " + getConflictClause(); + } + else { + sql = "INSERT INTO " + + tableName + + "(case_id, data_source_id, value, file_path, known_status, comment, file_obj_id) " + + "VALUES (?, ?, ?, ?, ?, ?, ?) " + + getConflictClause(); + } try (Connection conn = connect(); PreparedStatement preparedStatement = conn.prepareStatement(sql);) { @@ -1032,10 +1040,13 @@ abstract class RdbmsCentralRepo implements CentralRepository { } preparedStatement.setLong(7, eamArtifact.getFileObjectId()); - if (eamArtifact.getAccountId() >= 0) { - preparedStatement.setLong(8, eamArtifact.getAccountId()); - } else { - preparedStatement.setNull(8, Types.INTEGER); + // set in the accountId only for artifacts that represent accounts + if (artifactHasAnAccount) { + if (eamArtifact.getAccountId() >= 0) { + preparedStatement.setLong(8, eamArtifact.getAccountId()); + } else { + preparedStatement.setNull(8, Types.INTEGER); + } } preparedStatement.executeUpdate(); diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/RdbmsCentralRepoFactory.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/RdbmsCentralRepoFactory.java index 1232d708a6..d50d344a5e 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/RdbmsCentralRepoFactory.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/RdbmsCentralRepoFactory.java @@ -83,6 +83,7 @@ public class RdbmsCentralRepoFactory { public boolean initializeDatabaseSchema() { String createArtifactInstancesTableTemplate = getCreateArtifactInstancesTableTemplate(selectedPlatform); + String createAccountInstancesTableTemplate = getCreateAccountInstancesTableTemplate(selectedPlatform); String instancesCaseIdIdx = getAddCaseIdIndexTemplate(); String instancesDatasourceIdIdx = getAddDataSourceIdIndexTemplate(); @@ -147,7 +148,13 @@ public class RdbmsCentralRepoFactory { reference_type_dbname = CentralRepoDbUtil.correlationTypeToReferenceTableName(type); instance_type_dbname = CentralRepoDbUtil.correlationTypeToInstanceTableName(type); - stmt.execute(String.format(createArtifactInstancesTableTemplate, instance_type_dbname, instance_type_dbname)); + // use the correct create table template, based on whether the attribute type represents an account or not. + String createTableTemplate = (CentralRepoDbUtil.correlationAttribHasAnAccount(type)) + ? createAccountInstancesTableTemplate + : createArtifactInstancesTableTemplate; + + stmt.execute(String.format(createTableTemplate, instance_type_dbname, instance_type_dbname)); + stmt.execute(String.format(instancesCaseIdIdx, instance_type_dbname, instance_type_dbname)); stmt.execute(String.format(instancesDatasourceIdIdx, instance_type_dbname, instance_type_dbname)); stmt.execute(String.format(instancesValueIdx, instance_type_dbname, instance_type_dbname)); @@ -357,7 +364,7 @@ public class RdbmsCentralRepoFactory { + ")"; } /** - * Get the template String for creating a new _instances table in a Sqlite + * Get the template String for creating a new _instances table for non account artifacts in * central repository. %s will exist in the template where the name of the * new table will be added. * @@ -365,6 +372,31 @@ public class RdbmsCentralRepoFactory { */ static String getCreateArtifactInstancesTableTemplate(CentralRepoPlatforms selectedPlatform) { // Each "%s" will be replaced with the relevant TYPE_instances table name. + + return "CREATE TABLE IF NOT EXISTS %s (" + + getNumericPrimaryKeyClause("id", selectedPlatform) + + "case_id integer NOT NULL," + + "data_source_id integer NOT NULL," + + "value text NOT NULL," + + "file_path text NOT NULL," + + "known_status integer NOT NULL," + + "comment text," + + "file_obj_id " + getBigIntType(selectedPlatform) + " ," + + "CONSTRAINT %s_multi_unique UNIQUE(data_source_id, value, file_path)" + getOnConflictIgnoreClause(selectedPlatform) + "," + + "foreign key (case_id) references cases(id) ON UPDATE SET NULL ON DELETE SET NULL," + + "foreign key (data_source_id) references data_sources(id) ON UPDATE SET NULL ON DELETE SET NULL)"; + } + + /** + * Get the template String for creating a new _instances table for Accounts in + * central repository. %s will exist in the template where the name of the + * new table will be added. + * + * @return a String which is a template for creating a _instances table + */ + static String getCreateAccountInstancesTableTemplate(CentralRepoPlatforms selectedPlatform) { + // Each "%s" will be replaced with the relevant TYPE_instances table name. + return "CREATE TABLE IF NOT EXISTS %s (" + getNumericPrimaryKeyClause("id", selectedPlatform) + "case_id integer NOT NULL," @@ -380,7 +412,7 @@ public class RdbmsCentralRepoFactory { + "foreign key (case_id) references cases(id) ON UPDATE SET NULL ON DELETE SET NULL," + "foreign key (data_source_id) references data_sources(id) ON UPDATE SET NULL ON DELETE SET NULL)"; } - + /** * Get the statement String for creating a new data_sources table in a * Sqlite central repository. From 6b2f81134a9fcc4392e3e60e4db597d6cfe540f9 Mon Sep 17 00:00:00 2001 From: Raman Arora Date: Tue, 17 Mar 2020 18:48:29 -0400 Subject: [PATCH 075/100] Address Codacy comment. --- .../CentralRepoDbUpgrader13To14.java | 20 +++++++++---------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbUpgrader13To14.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbUpgrader13To14.java index dbd1e77da4..0acfd34ea5 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbUpgrader13To14.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbUpgrader13To14.java @@ -61,19 +61,17 @@ public class CentralRepoDbUpgrader13To14 implements CentralRepoDbUpgrader { // add new correlation type CentralRepoDbUtil.insertCorrelationType(connection, type); - } else { // existing attributes + } else if (type.getId() == CorrelationAttributeInstance.EMAIL_TYPE_ID || type.getId() == CorrelationAttributeInstance.PHONE_TYPE_ID) { // Alter the existing _instance tables for Phone and Email attributes to add account_id column - if (type.getId() == CorrelationAttributeInstance.EMAIL_TYPE_ID || type.getId() == CorrelationAttributeInstance.PHONE_TYPE_ID) { - String sqlStr = String.format(getAlterArtifactInstancesAddAccountIdTemplate(selectedPlatform), instance_type_dbname); - statement.execute(sqlStr); + String sqlStr = String.format(getAlterArtifactInstancesAddAccountIdTemplate(selectedPlatform), instance_type_dbname); + statement.execute(sqlStr); - // SQLite does NOT allow adding a constraint with Alter Table statement. - // The alternative would be to create new tables, copy all data over, and delete old tables - potentially a time consuming process. - // We decided to not add this constraint for SQLite, since there likely aren't many users using SQLite based Central Repo. - if (selectedPlatform == CentralRepoPlatforms.POSTGRESQL) { - sqlStr = String.format(getAlterArtifactInstancesAddAccountIdConstraintTemplate(), instance_type_dbname); - statement.execute(sqlStr); - } + // SQLite does NOT allow adding a constraint with Alter Table statement. + // The alternative would be to create new tables, copy all data over, and delete old tables - potentially a time consuming process. + // We decided to not add this constraint for SQLite, since there likely aren't many users using SQLite based Central Repo. + if (selectedPlatform == CentralRepoPlatforms.POSTGRESQL) { + sqlStr = String.format(getAlterArtifactInstancesAddAccountIdConstraintTemplate(), instance_type_dbname); + statement.execute(sqlStr); } } } From 8fdb645124e0b0233668f9d2e74221204da10d96 Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Wed, 18 Mar 2020 09:36:46 -0400 Subject: [PATCH 076/100] Remove X-log from file discovery to focus on user created docs --- Core/src/org/sleuthkit/autopsy/filequery/FileSearchData.java | 1 - 1 file changed, 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/filequery/FileSearchData.java b/Core/src/org/sleuthkit/autopsy/filequery/FileSearchData.java index d86d470102..32a2cf19cb 100644 --- a/Core/src/org/sleuthkit/autopsy/filequery/FileSearchData.java +++ b/Core/src/org/sleuthkit/autopsy/filequery/FileSearchData.java @@ -273,7 +273,6 @@ final class FileSearchData { = new ImmutableSet.Builder() .add("text/html", //NON-NLS "text/csv", //NON-NLS - "text/x-log", //NON-NLS "application/rtf", //NON-NLS "application/pdf", //NON-NLS "application/xhtml+xml", //NON-NLS From 906fc50a087cf5fe944b452ee94e68e1cf5a744e Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Wed, 18 Mar 2020 11:02:53 -0400 Subject: [PATCH 077/100] using list renderer --- .../optionspanel/EamDbSettingsDialog.java | 5 +- .../TypedBasicComboBoxRenderer.java | 71 ------------------- 2 files changed, 4 insertions(+), 72 deletions(-) delete mode 100644 Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/TypedBasicComboBoxRenderer.java diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java index 09b98a7337..fda6935999 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java @@ -24,6 +24,7 @@ import java.awt.Cursor; import java.awt.HeadlessException; import java.io.File; import java.io.IOException; +import java.io.Serializable; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -31,9 +32,11 @@ import java.util.logging.Level; import javax.swing.JDialog; import javax.swing.JFileChooser; import javax.swing.JFrame; +import javax.swing.JLabel; import javax.swing.JList; import javax.swing.JOptionPane; import javax.swing.JTextField; +import javax.swing.ListCellRenderer; import javax.swing.SwingUtilities; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; @@ -64,7 +67,7 @@ public class EamDbSettingsDialog extends JDialog { /** * This class handles displaying and rendering drop down menu for database choices in central repo. */ - private class DbChoiceRenderer extends TypedBasicComboBoxRenderer { + private class DbChoiceRenderer extends JLabel implements ListCellRenderer, Serializable { private static final long serialVersionUID = 1L; public Component getListCellRendererComponent( diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/TypedBasicComboBoxRenderer.java b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/TypedBasicComboBoxRenderer.java deleted file mode 100644 index 8788651f73..0000000000 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/TypedBasicComboBoxRenderer.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Central Repository - * - * Copyright 2015-2020 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.centralrepository.optionspanel; - -import java.awt.Dimension; -import java.io.Serializable; -import javax.swing.JLabel; -import javax.swing.ListCellRenderer; -import javax.swing.border.Border; -import javax.swing.border.EmptyBorder; - -/** - * This class implements the same behavior as the BasicComboBoxRenderer while - * providing type safety. - * @param The object type that will be used in the combo box. - */ -public abstract class TypedBasicComboBoxRenderer extends JLabel -implements ListCellRenderer, Serializable { - - protected static Border noFocusBorder = new EmptyBorder(1, 1, 1, 1); - private final static Border SAFE_NO_FOCUS_BORDER = new EmptyBorder(1, 1, 1, 1); - - /** - * The main constructor for this class. - */ - public TypedBasicComboBoxRenderer() { - super(); - setOpaque(true); - setBorder(getNoFocusBorder()); - } - - private static Border getNoFocusBorder() { - if (System.getSecurityManager() != null) { - return SAFE_NO_FOCUS_BORDER; - } else { - return noFocusBorder; - } - } - - @Override - public Dimension getPreferredSize() { - Dimension size; - - if ((this.getText() == null) || (this.getText().equals( "" ))) { - setText( " " ); - size = super.getPreferredSize(); - setText( "" ); - } - else { - size = super.getPreferredSize(); - } - - return size; - } -} From 065a7313c399f10a27a143e5c6f840697c40abc3 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Wed, 18 Mar 2020 12:01:35 -0400 Subject: [PATCH 078/100] added override annotation --- .../centralrepository/optionspanel/EamDbSettingsDialog.java | 1 + 1 file changed, 1 insertion(+) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java index fda6935999..4c70d6aa5c 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java @@ -70,6 +70,7 @@ public class EamDbSettingsDialog extends JDialog { private class DbChoiceRenderer extends JLabel implements ListCellRenderer, Serializable { private static final long serialVersionUID = 1L; + @Override public Component getListCellRendererComponent( JList list, CentralRepoDbChoice value, int index, boolean isSelected, boolean cellHasFocus) { From aa6ed94b14f5e95b2f543eb0e220865ef73f3dd1 Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dsmyda" Date: Wed, 18 Mar 2020 14:07:34 -0400 Subject: [PATCH 079/100] Implemented a safer and correct way of calling Gst.init() --- .../contentviewers/MediaPlayerPanel.java | 21 ++---- .../contentviewers/utils/GstLoader.java | 72 +++++++++++++++++++ 2 files changed, 78 insertions(+), 15 deletions(-) create mode 100755 Core/src/org/sleuthkit/autopsy/contentviewers/utils/GstLoader.java diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.java b/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.java index d2d8ace001..53bae5638d 100755 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.java @@ -74,6 +74,8 @@ import org.freedesktop.gstreamer.Format; import org.freedesktop.gstreamer.GstException; import org.freedesktop.gstreamer.event.SeekFlags; import org.freedesktop.gstreamer.event.SeekType; +import org.sleuthkit.autopsy.contentviewers.utils.GstLoader; +import org.sleuthkit.autopsy.contentviewers.utils.GstLoader.GstStatus; /** * This is a video player that is part of the Media View layered pane. It uses @@ -540,23 +542,12 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie if (this.isCancelled()) { return; } - - // Setting the following property causes the GST - // Java bindings to call dispose() on the GST - // service thread instead of running it in the GST - // Native Object Reaper thread. - System.setProperty("glib.reapOnEDT", "true"); - - // Initialize Gstreamer. It is safe to call this for every file. - // It was moved here from the constructor because having it happen - // earlier resulted in crashes on Linux. See JIRA-5888. - Gst.init(); - - if (!Gst.isInitialized()) { - logger.log(Level.INFO, "GStreamer is not initialized."); //NON-NLS + + GstStatus loadStatus = GstLoader.tryLoad(); + if(loadStatus == GstStatus.FAILURE) { return; } - + Gst.getExecutor().submit(() -> { //Video is ready for playback. Create new components gstPlayBin = new PlayBin("VideoPlayer", tempFile.toURI()); diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/utils/GstLoader.java b/Core/src/org/sleuthkit/autopsy/contentviewers/utils/GstLoader.java new file mode 100755 index 0000000000..d04e0f4ac0 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/utils/GstLoader.java @@ -0,0 +1,72 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2020 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.utils; + +import java.util.logging.Level; +import org.freedesktop.gstreamer.Gst; +import org.sleuthkit.autopsy.coreutils.Logger; +import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil; + +/** + * + * @author dsmyda + */ +public class GstLoader { + + private static final Logger logger = Logger.getLogger(GstLoader.class.getName()); + private static GstStatus status; + + /** + * Attempts to load the gstreamer bindings. Only one attempt will be + * performed per Autopsy process. Clients should not attempt to interact + * with the gstreamer bindings unless the load was successful. + * + * @return Status - SUCCESS or FAILURE + */ + public synchronized static GstStatus tryLoad() { + // Null is our 'unknown' status. Prior to the first call, the status + // is unknown. + if (status != null) { + return status; + } + + try { + // Setting the following property causes the GST + // Java bindings to call dispose() on the GST + // service thread instead of running it in the GST + // Native Object Reaper thread. + System.setProperty("glib.reapOnEDT", "true"); + Gst.init(); + status = GstStatus.SUCCESS; + } catch (Throwable ex) { + status = GstStatus.FAILURE; + MessageNotifyUtil.Message.error("A problem was encountered with" + + "the video playback service. Video playback will" + + " be disabled for the remainder of the session."); + logger.log(Level.WARNING, "Failed to load gsteamer bindings", ex); + } + + return status; + } + + public enum GstStatus { + SUCCESS, FAILURE + } +} From 10e16281ed0904206b0e701c8a0a3985ed8c3a07 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Wed, 18 Mar 2020 16:31:04 -0400 Subject: [PATCH 080/100] don't raise warning if settings not located --- .../CentralRepoPostgresSettingsUtil.java | 64 +++++++++++-------- 1 file changed, 38 insertions(+), 26 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoPostgresSettingsUtil.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoPostgresSettingsUtil.java index 3f75e9e183..86f929ba0e 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoPostgresSettingsUtil.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoPostgresSettingsUtil.java @@ -63,9 +63,21 @@ public class CentralRepoPostgresSettingsUtil { private CentralRepoPostgresSettingsUtil() {} - private void logException(TryHandler handler) { + /** + * Uses setter object to set a value as specified by 'value'. In the event that 'value' + * is null, the setter will not be called. Exceptions that are raised from the setter will + * be logged. + * + * @param setter The setter to call. + * @param value The value to use with the setter. + */ + private void setValOrLog(ValueSetter setter, String value) { + // ignore null values as they indicate a setting that is not set yet + if (value == null || value.isEmpty()) + return; + try { - handler.operation(); + setter.set(value); } catch (CentralRepoException | NumberFormatException e) { LOGGER.log(Level.WARNING, "There was an error in converting central repo postgres settings", e); @@ -73,10 +85,10 @@ public class CentralRepoPostgresSettingsUtil { } /** - * This interface represents an action that potentially throws an exception. + * This interface represents a setter that potentially throws an exception. */ - private interface TryHandler { - void operation() throws CentralRepoException, NumberFormatException; + private interface ValueSetter { + void set(String value) throws CentralRepoException, NumberFormatException; } /** @@ -96,15 +108,12 @@ public class CentralRepoPostgresSettingsUtil { return settings; } - logException(() -> settings.setHost(muConn.getHost())); - logException(() -> settings.setDbName(PostgresConnectionSettings.DEFAULT_DBNAME)); - logException(() -> settings.setUserName(muConn.getUserName())); - - logException(() -> settings.setPort(Integer.parseInt(muConn.getPort()))); - logException(() -> settings.setBulkThreshold(RdbmsCentralRepo.DEFAULT_BULK_THRESHHOLD)); - - logException(() -> settings.setPassword(muConn.getPassword())); + setValOrLog((v) -> settings.setHost(v), muConn.getHost()); + setValOrLog((v) -> settings.setUserName(v), muConn.getUserName()); + setValOrLog((v) -> settings.setPassword(v), muConn.getPassword()); + setValOrLog((v) -> settings.setPort(Integer.parseInt(v)), muConn.getPort()); + return settings; } @@ -120,24 +129,27 @@ public class CentralRepoPostgresSettingsUtil { Map keyVals = ModuleSettings.getConfigSettings(MODULE_KEY); - logException(() -> settings.setHost(keyVals.get(HOST_KEY))); - logException(() -> settings.setDbName(keyVals.get(DBNAME_KEY))); - logException(() -> settings.setUserName(keyVals.get(USER_KEY))); + setValOrLog((v) -> settings.setHost(v), keyVals.get(HOST_KEY)); + setValOrLog((v) -> settings.setDbName(v), keyVals.get(DBNAME_KEY)); + setValOrLog((v) -> settings.setUserName(v), keyVals.get(USER_KEY)); - logException(() -> settings.setPort(Integer.parseInt(keyVals.get(PORT_KEY)))); - logException(() -> settings.setBulkThreshold(Integer.parseInt(keyVals.get((BULK_THRESHOLD_KEY))))); + setValOrLog((v) -> settings.setPort(Integer.parseInt(v)), keyVals.get(PORT_KEY)); + setValOrLog((v) -> settings.setBulkThreshold(Integer.parseInt(v)), keyVals.get((BULK_THRESHOLD_KEY))); String passwordHex = keyVals.get(PASSWORD_KEY); - String password; - try { - password = TextConverter.convertHexTextToText(passwordHex); - } catch (TextConverterException ex) { - LOGGER.log(Level.WARNING, "Failed to convert password from hex text to text.", ex); - password = null; + if (passwordHex != null) { + String password; + try { + password = TextConverter.convertHexTextToText(passwordHex); + } catch (TextConverterException ex) { + LOGGER.log(Level.WARNING, "Failed to convert password from hex text to text.", ex); + password = null; + } + + final String finalPassword = password; + setValOrLog((v) -> settings.setPassword(v), finalPassword); } - final String finalPassword = password; - logException(() -> settings.setPassword(finalPassword)); return settings; } From 60f6077fc7ff807f08987027820fb1dc81acb667 Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dsmyda" Date: Wed, 18 Mar 2020 22:20:53 -0400 Subject: [PATCH 081/100] Reverted form changes --- .../autopsy/contentviewers/MediaPlayerPanel.form | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.form b/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.form index 793e31830b..e5a4279d54 100755 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.form +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.form @@ -63,7 +63,7 @@ - + @@ -129,6 +129,12 @@ + + + + + + @@ -326,4 +332,4 @@ - + \ No newline at end of file From 0ff95aa2769e66e3e2f4cdbeb1f6ab8e3b850a25 Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dsmyda" Date: Wed, 18 Mar 2020 22:22:05 -0400 Subject: [PATCH 082/100] Added new line ending : --- .../org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.form | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.form b/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.form index e5a4279d54..0b00c43d8a 100755 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.form +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.form @@ -332,4 +332,4 @@ - \ No newline at end of file + From 2a439826dafa961f318ca7e24e57336bd50db321 Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dsmyda" Date: Wed, 18 Mar 2020 22:33:22 -0400 Subject: [PATCH 083/100] Updated bundle message and form file --- .../autopsy/contentviewers/Bundle.properties-MERGED | 2 +- .../autopsy/contentviewers/MediaPlayerPanel.form | 8 +------- .../autopsy/contentviewers/MediaPlayerPanel.java | 12 ++++++------ 3 files changed, 8 insertions(+), 14 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/contentviewers/Bundle.properties-MERGED index bf669b8cc4..c0a6f73aaf 100755 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/Bundle.properties-MERGED @@ -41,7 +41,7 @@ MediaFileViewer.AccessibleContext.accessibleDescription= MediaFileViewer.title=Media MediaFileViewer.toolTip=Displays supported multimedia files (images, videos, audio) MediaPlayerPanel.noSupport=File not supported. -MediaPlayerPanel.playbackDisabled=A problem was encountered with the video playback service. Video playback will be disabled for the remainder of the session. +MediaPlayerPanel.playbackDisabled=A problem was encountered with the video and audio playback service. Video and audio playback will be disabled for the remainder of the session. MediaPlayerPanel.timeFormat=%02d:%02d:%02d MediaPlayerPanel.unknownTime=Unknown MediaViewImagePanel.createTagOption=Create diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.form b/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.form index 0b00c43d8a..793e31830b 100755 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.form +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.form @@ -63,7 +63,7 @@ - +
@@ -129,12 +129,6 @@ - - - - - - diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.java b/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.java index 2d69819e1a..40122acea7 100755 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.java @@ -214,7 +214,7 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie //The slider is a shared resource between the VideoPanelUpdater //and the TrackListener on the slider itself. private final Semaphore sliderLock; - + private static volatile boolean IS_GST_ENABLED = true; /** @@ -424,10 +424,10 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie @Override public boolean isSupported(AbstractFile file) { - if(!IS_GST_ENABLED) { + if (!IS_GST_ENABLED) { return false; } - + String extension = file.getNameExtension(); /** * Although it seems too restrictive, requiring both a supported @@ -547,8 +547,8 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie */ @NbBundle.Messages({ "MediaPlayerPanel.playbackDisabled=A problem was encountered with" - + " the video playback service. Video playback will" - + " be disabled for the remainder of the session." + + " the video and audio playback service. Video and audio " + + "playback will be disabled for the remainder of the session." }) @Override protected void done() { @@ -562,7 +562,7 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie GstStatus loadStatus = GstLoader.tryLoad(); if (loadStatus == GstStatus.FAILURE) { MessageNotifyUtil.Message.error(Bundle.MediaPlayerPanel_playbackDisabled()); - + // This will disable the panel for future use. IS_GST_ENABLED = false; return; From 9d58f0220cfbd919c01afa1f5f5bb0cd847a958e Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dsmyda" Date: Wed, 18 Mar 2020 22:42:01 -0400 Subject: [PATCH 084/100] Codacy comments and adjusted bundle message --- .../sleuthkit/autopsy/contentviewers/utils/GstLoader.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/utils/GstLoader.java b/Core/src/org/sleuthkit/autopsy/contentviewers/utils/GstLoader.java index b2ad257847..57da88e0a2 100755 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/utils/GstLoader.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/utils/GstLoader.java @@ -61,7 +61,14 @@ public class GstLoader { return status; } + /** + * The various init statuses that tryLoad can return. + */ public enum GstStatus { SUCCESS, FAILURE } + + private GstLoader() { + + } } From 45e9222bccda7c2add909fdd09255d2251ad1848 Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Thu, 19 Mar 2020 07:48:10 -0400 Subject: [PATCH 085/100] 6032 translated file names in results view --- .../datamodel/BlackboardArtifactNode.java | 234 ++++++++++-------- .../datamodel/BlackboardArtifactTagNode.java | 15 +- .../datamodel/Bundle.properties-MERGED | 3 + .../autopsy/datamodel/ContentTagNode.java | 48 ++-- .../datamodel/DisplayableItemNode.java | 25 +- .../sleuthkit/autopsy/datamodel/TagNode.java | 135 ++++++++++ .../directorytree/DataResultFilterNode.java | 23 +- 7 files changed, 317 insertions(+), 166 deletions(-) create mode 100755 Core/src/org/sleuthkit/autopsy/datamodel/TagNode.java diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java index 055d322203..6663c87bb3 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java @@ -127,7 +127,8 @@ public class BlackboardArtifactNode extends AbstractContentNode(Bundle.BlackboardArtifactNode_createSheet_score_name(), Bundle.BlackboardArtifactNode_createSheet_score_displayName(), scoData.getScoreAndDescription().getRight(), scoData.getScoreAndDescription().getLeft())); + updateSheet(new NodeProperty<>( + Bundle.BlackboardArtifactNode_createSheet_score_name(), + Bundle.BlackboardArtifactNode_createSheet_score_displayName(), + scoData.getScoreAndDescription().getRight(), + scoData.getScoreAndDescription().getLeft())); } if (scoData.getComment() != null) { - updateSheet(new NodeProperty<>(Bundle.BlackboardArtifactNode_createSheet_comment_name(), Bundle.BlackboardArtifactNode_createSheet_comment_displayName(), NO_DESCR, scoData.getComment())); + updateSheet(new NodeProperty<>( + Bundle.BlackboardArtifactNode_createSheet_comment_name(), + Bundle.BlackboardArtifactNode_createSheet_comment_displayName(), + NO_DESCR, scoData.getComment())); } if (scoData.getCountAndDescription() != null) { - updateSheet(new NodeProperty<>(Bundle.BlackboardArtifactNode_createSheet_count_name(), Bundle.BlackboardArtifactNode_createSheet_count_displayName(), scoData.getCountAndDescription().getRight(), scoData.getCountAndDescription().getLeft())); + updateSheet(new NodeProperty<>( + Bundle.BlackboardArtifactNode_createSheet_count_name(), + Bundle.BlackboardArtifactNode_createSheet_count_displayName(), + scoData.getCountAndDescription().getRight(), + scoData.getCountAndDescription().getLeft())); } } else if (eventType.equals(FileNameTransTask.getPropertyName())) { /* * Replace the value of the Source File property with the * translated name via setDisplayName (see note in createSheet), - * and put the untranslated name in the Original Name property. - * Also set the tooltip to the original name. + * and put the untranslated name in the Original Name property + * and in the tooltip. */ + translatedSourceName = evt.getNewValue().toString(); setDisplayName(evt.getNewValue().toString()); setShortDescription(evt.getOldValue().toString()); - updateSheet(new NodeProperty<>(Bundle.BlackboardArtifactNode_createSheet_srcFile_name(), Bundle.BlackboardArtifactNode_createSheet_srcFile_displayName(), NO_DESCR, (String) evt.getNewValue())); - //updateSheet(new NodeProperty<>(Bundle.BlackboardArtifactNode_createSheet_srcFile_origName(), Bundle.BlackboardArtifactNode_createSheet_srcFile_origDisplayName(), NO_DESCR, (String) evt.getOldValue())); + updateSheet(new NodeProperty<>( + Bundle.BlackboardArtifactNode_createSheet_srcFile_origName(), + Bundle.BlackboardArtifactNode_createSheet_srcFile_origDisplayName(), + NO_DESCR, + evt.getOldValue().toString())); } } }; @@ -225,17 +241,15 @@ public class BlackboardArtifactNode extends AbstractContentNode( Bundle.BlackboardArtifactNode_createSheet_srcFile_name(), Bundle.BlackboardArtifactNode_createSheet_srcFile_displayName(), NO_DESCR, - this.getSourceName())); + getDisplayName())); if (TextTranslationService.getInstance().hasProvider() && UserPreferences.displayTranslatedFileNames()) { /* @@ -431,8 +459,8 @@ public class BlackboardArtifactNode extends AbstractContentNode(Bundle.BlackboardArtifactNode_createSheet_score_name(), Bundle.BlackboardArtifactNode_createSheet_score_displayName(), VALUE_LOADING, "")); - sheetSet.put(new NodeProperty<>(Bundle.BlackboardArtifactNode_createSheet_comment_name(), Bundle.BlackboardArtifactNode_createSheet_comment_displayName(), VALUE_LOADING, "")); + sheetSet.put(new NodeProperty<>( + Bundle.BlackboardArtifactNode_createSheet_score_name(), + Bundle.BlackboardArtifactNode_createSheet_score_displayName(), + VALUE_LOADING, + "")); + sheetSet.put(new NodeProperty<>( + Bundle.BlackboardArtifactNode_createSheet_comment_name(), + Bundle.BlackboardArtifactNode_createSheet_comment_displayName(), + VALUE_LOADING, + "")); if (CentralRepository.isEnabled()) { - sheetSet.put(new NodeProperty<>(Bundle.BlackboardArtifactNode_createSheet_count_name(), Bundle.BlackboardArtifactNode_createSheet_count_displayName(), VALUE_LOADING, "")); + sheetSet.put(new NodeProperty<>( + Bundle.BlackboardArtifactNode_createSheet_count_name(), + Bundle.BlackboardArtifactNode_createSheet_count_displayName(), + VALUE_LOADING, + "")); } backgroundTasksPool.submit(new GetSCOTask(new WeakReference<>(this), weakAppEventListener)); } @@ -463,20 +503,16 @@ public class BlackboardArtifactNode extends AbstractContentNode(NbBundle.getMessage(BlackboardArtifactNode.class, - "BlackboardArtifactNode.createSheet.artifactType.name"), - NbBundle.getMessage(BlackboardArtifactNode.class, - "BlackboardArtifactNode.createSheet.artifactType.displayName"), - NO_DESCR, - associatedArtifact.getDisplayName())); - sheetSet - .put(new NodeProperty<>(NbBundle.getMessage(BlackboardArtifactNode.class, - "BlackboardArtifactNode.createSheet.artifactDetails.name"), - NbBundle.getMessage(BlackboardArtifactNode.class, - "BlackboardArtifactNode.createSheet.artifactDetails.displayName"), - NO_DESCR, - associatedArtifact.getShortDescription())); + sheetSet.put(new NodeProperty<>( + NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.artifactType.name"), + NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.artifactType.displayName"), + NO_DESCR, + associatedArtifact.getDisplayName())); + sheetSet.put(new NodeProperty<>( + NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.artifactDetails.name"), + NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.artifactDetails.displayName"), + NO_DESCR, + associatedArtifact.getShortDescription())); } } catch (TskCoreException | NoCurrentCaseException ex) { logger.log(Level.SEVERE, MessageFormat.format("Error getting associated artifact of TSK_INTERESTING_ARTIFACT_HIT artifact (objID={0}))", artifact.getId()), ex); //NON-NLS @@ -523,20 +559,16 @@ public class BlackboardArtifactNode extends AbstractContentNode(NbBundle.getMessage(BlackboardArtifactNode.class, - "BlackboardArtifactNode.createSheet.ext.name"), - NbBundle.getMessage(BlackboardArtifactNode.class, - "BlackboardArtifactNode.createSheet.ext.displayName"), + sheetSet.put(new NodeProperty<>( + NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.ext.name"), + NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.ext.displayName"), NO_DESCR, ext)); - sheetSet - .put(new NodeProperty<>( - NbBundle.getMessage(BlackboardArtifactNode.class, - "BlackboardArtifactNode.createSheet.mimeType.name"), - NbBundle.getMessage(BlackboardArtifactNode.class, - "BlackboardArtifactNode.createSheet.mimeType.displayName"), - NO_DESCR, - actualMimeType)); + sheetSet.put(new NodeProperty<>( + NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.mimeType.name"), + NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.mimeType.displayName"), + NO_DESCR, + actualMimeType)); } /* @@ -556,10 +588,8 @@ public class BlackboardArtifactNode extends AbstractContentNode( - NbBundle.getMessage(BlackboardArtifactNode.class, - "BlackboardArtifactNode.createSheet.filePath.name"), - NbBundle.getMessage(BlackboardArtifactNode.class, - "BlackboardArtifactNode.createSheet.filePath.displayName"), + NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.filePath.name"), + NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.filePath.displayName"), NO_DESCR, sourcePath)); } @@ -571,42 +601,33 @@ public class BlackboardArtifactNode extends AbstractContentNode(NbBundle.getMessage(BlackboardArtifactNode.class, - "ContentTagNode.createSheet.fileModifiedTime.name"), - NbBundle.getMessage(BlackboardArtifactNode.class, - "ContentTagNode.createSheet.fileModifiedTime.displayName"), - "", - file == null ? "" : ContentUtils.getStringTime(file.getMtime(), file))); - sheetSet - .put(new NodeProperty<>(NbBundle.getMessage(BlackboardArtifactNode.class, - "ContentTagNode.createSheet.fileChangedTime.name"), - NbBundle.getMessage(BlackboardArtifactNode.class, - "ContentTagNode.createSheet.fileChangedTime.displayName"), - "", - file == null ? "" : ContentUtils.getStringTime(file.getCtime(), file))); - sheetSet - .put(new NodeProperty<>(NbBundle.getMessage(BlackboardArtifactNode.class, - "ContentTagNode.createSheet.fileAccessedTime.name"), - NbBundle.getMessage(BlackboardArtifactNode.class, - "ContentTagNode.createSheet.fileAccessedTime.displayName"), - "", - file == null ? "" : ContentUtils.getStringTime(file.getAtime(), file))); - sheetSet - .put(new NodeProperty<>(NbBundle.getMessage(BlackboardArtifactNode.class, - "ContentTagNode.createSheet.fileCreatedTime.name"), - NbBundle.getMessage(BlackboardArtifactNode.class, - "ContentTagNode.createSheet.fileCreatedTime.displayName"), - "", - file == null ? "" : ContentUtils.getStringTime(file.getCrtime(), file))); - sheetSet - .put(new NodeProperty<>(NbBundle.getMessage(BlackboardArtifactNode.class, - "ContentTagNode.createSheet.fileSize.name"), - NbBundle.getMessage(BlackboardArtifactNode.class, - "ContentTagNode.createSheet.fileSize.displayName"), - "", - file == null ? "" : file.getSize())); - sheetSet.put(new NodeProperty<>(Bundle.BlackboardArtifactNode_createSheet_artifactMD5_name(), + sheetSet.put(new NodeProperty<>( + NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileModifiedTime.name"), + NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileModifiedTime.displayName"), + "", + file == null ? "" : ContentUtils.getStringTime(file.getMtime(), file))); + sheetSet.put(new NodeProperty<>( + NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileChangedTime.name"), + NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileChangedTime.displayName"), + "", + file == null ? "" : ContentUtils.getStringTime(file.getCtime(), file))); + sheetSet.put(new NodeProperty<>( + NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileAccessedTime.name"), + NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileAccessedTime.displayName"), + "", + file == null ? "" : ContentUtils.getStringTime(file.getAtime(), file))); + sheetSet.put(new NodeProperty<>( + NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileCreatedTime.name"), + NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileCreatedTime.displayName"), + "", + file == null ? "" : ContentUtils.getStringTime(file.getCrtime(), file))); + sheetSet.put(new NodeProperty<>( + NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileSize.name"), + NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileSize.displayName"), + "", + file == null ? "" : file.getSize())); + sheetSet.put(new NodeProperty<>( + Bundle.BlackboardArtifactNode_createSheet_artifactMD5_name(), Bundle.BlackboardArtifactNode_createSheet_artifactMD5_displayName(), "", file == null ? "" : StringUtils.defaultString(file.getMd5Hash()))); @@ -629,10 +650,8 @@ public class BlackboardArtifactNode extends AbstractContentNode( - NbBundle.getMessage(BlackboardArtifactNode.class, - "BlackboardArtifactNode.createSheet.dataSrc.name"), - NbBundle.getMessage(BlackboardArtifactNode.class, - "BlackboardArtifactNode.createSheet.dataSrc.displayName"), + NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.dataSrc.name"), + NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.dataSrc.displayName"), NO_DESCR, dataSourceStr)); } @@ -655,18 +674,15 @@ public class BlackboardArtifactNode extends AbstractContentNode(NbBundle.getMessage(BlackboardArtifactNode.class, - "BlackboardArtifactNode.createSheet.fileSize.name"), - NbBundle.getMessage(BlackboardArtifactNode.class, - "BlackboardArtifactNode.createSheet.fileSize.displayName"), + sheetSet.put(new NodeProperty<>( + NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.fileSize.name"), + NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.fileSize.displayName"), NO_DESCR, size)); sheetSet .put(new NodeProperty<>( - NbBundle.getMessage(BlackboardArtifactNode.class, - "BlackboardArtifactNode.createSheet.path.name"), - NbBundle.getMessage(BlackboardArtifactNode.class, - "BlackboardArtifactNode.createSheet.path.displayName"), + NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.path.name"), + NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.path.displayName"), NO_DESCR, path)); } diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactTagNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactTagNode.java index a6a0a66590..6068615592 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactTagNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactTagNode.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2013-2018 Basis Technology Corp. + * Copyright 2013-2020 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -24,13 +24,11 @@ import java.util.Arrays; import java.util.List; import java.util.logging.Level; import javax.swing.Action; -import org.openide.nodes.Children; import org.openide.nodes.Sheet; import org.openide.util.NbBundle; import org.openide.util.NbBundle.Messages; import org.openide.util.lookup.Lookups; import org.sleuthkit.autopsy.coreutils.Logger; -import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil; import org.sleuthkit.autopsy.timeline.actions.ViewArtifactInTimelineAction; import org.sleuthkit.autopsy.timeline.actions.ViewFileInTimelineAction; import org.sleuthkit.datamodel.AbstractFile; @@ -46,14 +44,14 @@ import static org.sleuthkit.autopsy.datamodel.Bundle.*; * tag name nodes have tag type child nodes; tag type nodes are the parents of * either content or blackboard artifact tag nodes. */ -public class BlackboardArtifactTagNode extends DisplayableItemNode { +public class BlackboardArtifactTagNode extends TagNode { private static final Logger LOGGER = Logger.getLogger(BlackboardArtifactTagNode.class.getName()); private static final String ICON_PATH = "org/sleuthkit/autopsy/images/green-tag-icon-16.png"; //NON-NLS private final BlackboardArtifactTag tag; public BlackboardArtifactTagNode(BlackboardArtifactTag tag) { - super(Children.LEAF, Lookups.fixed(tag, tag.getArtifact(), tag.getContent())); + super(Lookups.fixed(tag, tag.getArtifact(), tag.getContent()), tag.getContent()); super.setName(tag.getContent().getName()); super.setDisplayName(tag.getContent().getName()); this.setIconBaseWithExtension(ICON_PATH); @@ -75,6 +73,7 @@ public class BlackboardArtifactTagNode extends DisplayableItemNode { NbBundle.getMessage(this.getClass(), "BlackboardArtifactTagNode.createSheet.srcFile.text"), "", tag.getContent().getName())); + addOriginalNameProp(properties); String contentPath; try { contentPath = tag.getContent().getUniquePath(); @@ -82,7 +81,6 @@ public class BlackboardArtifactTagNode extends DisplayableItemNode { Logger.getLogger(ContentTagNode.class.getName()).log(Level.SEVERE, "Failed to get path for content (id = " + tag.getContent().getId() + ")", ex); //NON-NLS contentPath = NbBundle.getMessage(this.getClass(), "BlackboardArtifactTagNode.createSheet.unavail.text"); } - properties.put(new NodeProperty<>( NbBundle.getMessage(this.getClass(), "BlackboardArtifactTagNode.createSheet.srcFilePath.text"), NbBundle.getMessage(this.getClass(), "BlackboardArtifactTagNode.createSheet.srcFilePath.text"), @@ -146,11 +144,6 @@ public class BlackboardArtifactTagNode extends DisplayableItemNode { return visitor.visit(this); } - @Override - public boolean isLeafTypeNode() { - return true; - } - @Override public String getItemType() { return getClass().getName(); diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/datamodel/Bundle.properties-MERGED index 3a16272a96..0d5c75740d 100755 --- a/Core/src/org/sleuthkit/autopsy/datamodel/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/datamodel/Bundle.properties-MERGED @@ -92,6 +92,7 @@ Category.two=CAT-2: Child Exploitation (Non-Illegal/Age Difficult) Category.zero=CAT-0: Uncategorized ContentTagNode.createSheet.artifactMD5.displayName=MD5 Hash ContentTagNode.createSheet.artifactMD5.name=MD5 Hash +ContentTagNode.createSheet.origFileName=Original Name ContentTagNode.createSheet.userName.text=User Name DeletedContent.allDelFilter.text=All DeletedContent.createSheet.filterType.desc=no description @@ -347,6 +348,8 @@ TagNameNode.bbArtTagTypeNodeKey.text=Result Tags TagNameNode.bookmark.text=Bookmark TagNameNode.createSheet.name.name=Name TagNameNode.createSheet.name.displayName=Name +TagNode.propertySheet.origName=Original Name +TagNode.propertySheet.origNameDisplayName=Original Name TagsNode.displayName.text=Tags TagsNode.createSheet.name.name=Name TagsNode.createSheet.name.displayName=Name diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/ContentTagNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/ContentTagNode.java index e213e460cb..89d6c2fae2 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/ContentTagNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/ContentTagNode.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2013-2016 Basis Technology Corp. + * Copyright 2013-2020 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -24,7 +24,6 @@ import java.util.List; import java.util.logging.Level; import javax.swing.Action; import org.apache.commons.lang3.StringUtils; -import org.openide.nodes.Children; import org.openide.nodes.Sheet; import org.openide.util.NbBundle; import org.openide.util.NbBundle.Messages; @@ -39,18 +38,16 @@ import org.sleuthkit.datamodel.TskCoreException; /** * Instances of this class wrap ContentTag objects. In the Autopsy presentation * of the SleuthKit data model, they are leaf nodes of a tree consisting of - * content and blackboard artifact tags, grouped first by tag type, then by tag - * name. + * content and artifact tags, grouped first by tag type, then by tag name. */ -class ContentTagNode extends DisplayableItemNode { +class ContentTagNode extends TagNode { private static final Logger LOGGER = Logger.getLogger(ContentTagNode.class.getName()); - private static final String ICON_PATH = "org/sleuthkit/autopsy/images/blue-tag-icon-16.png"; //NON-NLS private final ContentTag tag; - public ContentTagNode(ContentTag tag) { - super(Children.LEAF, Lookups.fixed(tag, tag.getContent())); + ContentTagNode(ContentTag tag) { + super(Lookups.fixed(tag, tag.getContent()), tag.getContent()); super.setName(tag.getContent().getName()); super.setDisplayName(tag.getContent().getName()); this.setIconBaseWithExtension(ICON_PATH); @@ -58,6 +55,7 @@ class ContentTagNode extends DisplayableItemNode { } @Messages({ + "ContentTagNode.createSheet.origFileName=Original Name", "ContentTagNode.createSheet.artifactMD5.displayName=MD5 Hash", "ContentTagNode.createSheet.artifactMD5.name=MD5 Hash", "ContentTagNode.createSheet.userName.text=User Name"}) @@ -79,15 +77,19 @@ class ContentTagNode extends DisplayableItemNode { properties = Sheet.createPropertiesSet(); propertySheet.put(properties); } - properties.put(new NodeProperty<>(NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.file.name"), + properties.put(new NodeProperty<>( + NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.file.name"), NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.file.displayName"), "", content.getName())); - properties.put(new NodeProperty<>(NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.filePath.name"), + addOriginalNameProp(properties); + properties.put(new NodeProperty<>( + NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.filePath.name"), NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.filePath.displayName"), "", contentPath)); - properties.put(new NodeProperty<>(NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.comment.name"), + properties.put(new NodeProperty<>( + NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.comment.name"), NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.comment.displayName"), "", tag.getComment())); @@ -95,23 +97,28 @@ class ContentTagNode extends DisplayableItemNode { NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.fileModifiedTime.displayName"), "", file != null ? ContentUtils.getStringTime(file.getMtime(), file) : "")); - properties.put(new NodeProperty<>(NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.fileChangedTime.name"), + properties.put(new NodeProperty<>( + NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.fileChangedTime.name"), NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.fileChangedTime.displayName"), "", file != null ? ContentUtils.getStringTime(file.getCtime(), file) : "")); - properties.put(new NodeProperty<>(NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.fileAccessedTime.name"), + properties.put(new NodeProperty<>( + NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.fileAccessedTime.name"), NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.fileAccessedTime.displayName"), "", file != null ? ContentUtils.getStringTime(file.getAtime(), file) : "")); - properties.put(new NodeProperty<>(NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.fileCreatedTime.name"), + properties.put(new NodeProperty<>( + NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.fileCreatedTime.name"), NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.fileCreatedTime.displayName"), "", file != null ? ContentUtils.getStringTime(file.getCrtime(), file) : "")); - properties.put(new NodeProperty<>(NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.fileSize.name"), + properties.put(new NodeProperty<>( + NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.fileSize.name"), NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.fileSize.displayName"), "", content.getSize())); - properties.put(new NodeProperty<>(Bundle.ContentTagNode_createSheet_artifactMD5_name(), + properties.put(new NodeProperty<>( + Bundle.ContentTagNode_createSheet_artifactMD5_name(), Bundle.ContentTagNode_createSheet_artifactMD5_displayName(), "", file != null ? StringUtils.defaultString(file.getMd5Hash()) : "")); @@ -128,8 +135,7 @@ class ContentTagNode extends DisplayableItemNode { List actions = new ArrayList<>(); actions.addAll(Arrays.asList(super.getActions(context))); - AbstractFile file = getLookup().lookup(AbstractFile.class - ); + AbstractFile file = getLookup().lookup(AbstractFile.class); if (file != null) { actions.add(ViewFileInTimelineAction.createViewFileAction(file)); } @@ -144,13 +150,9 @@ class ContentTagNode extends DisplayableItemNode { return visitor.visit(this); } - @Override - public boolean isLeafTypeNode() { - return true; - } - @Override public String getItemType() { return getClass().getName(); } + } diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/DisplayableItemNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/DisplayableItemNode.java index c723d99b55..c6bc88129a 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/DisplayableItemNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/DisplayableItemNode.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2011-2017 Basis Technology Corp. + * Copyright 2012-2020 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -20,6 +20,7 @@ package org.sleuthkit.autopsy.datamodel; import org.openide.nodes.AbstractNode; import org.openide.nodes.Children; +import org.openide.nodes.Sheet; import org.openide.util.Lookup; import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.BlackboardArtifact; @@ -142,4 +143,26 @@ public abstract class DisplayableItemNode extends AbstractNode { return selectedChildNodeInfo; } + /** + * Updates the node property sheet by replacing existing properties with new + * properties with the same property name. + * + * @param newProps The replacement property objects. + */ + protected synchronized final void updatePropertySheet(NodeProperty... newProps) { + Sheet currentSheet = this.getSheet(); + Sheet.Set currentPropsSet = currentSheet.get(Sheet.PROPERTIES); + Property[] currentProps = currentPropsSet.getProperties(); + for (NodeProperty newProp : newProps) { + for (int i = 0; i < currentProps.length; i++) { + if (currentProps[i].getName().equals(newProp.getName())) { + currentProps[i] = newProp; + } + } + } + currentPropsSet.put(currentProps); + currentSheet.put(currentPropsSet); + this.setSheet(currentSheet); + } + } diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/TagNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/TagNode.java new file mode 100755 index 0000000000..7d4d8d467c --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/datamodel/TagNode.java @@ -0,0 +1,135 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2020-2020 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.datamodel; + +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import org.openide.nodes.Children; +import org.openide.nodes.Sheet; +import org.openide.util.Lookup; +import org.openide.util.NbBundle; +import org.openide.util.WeakListeners; +import org.sleuthkit.autopsy.core.UserPreferences; +import org.sleuthkit.autopsy.datamodel.utils.FileNameTransTask; +import org.sleuthkit.autopsy.texttranslation.TextTranslationService; +import org.sleuthkit.datamodel.Content; + +/** + * An abstract superclass for a node that represents a tag, uses the name of a + * given Content object as its display name, and has a property sheet with an + * original name property when machine translation is enabled. + * + * The translation of the Content name is done in a background thread. The + * translated name is made the display name of the node and the untranslated + * name is put into both the original name property and into the node's tooltip. + * + * TODO (Jira-): Consider modifying this class to be able to use it more broadly + * within the Autopsy data model (i.e., AbstractNode suclasses). It's not really + * specific to a tag node. + */ +@NbBundle.Messages({ + "TagNode.propertySheet.origName=Original Name", + "TagNode.propertySheet.origNameDisplayName=Original Name" +}) +abstract class TagNode extends DisplayableItemNode { + + private final static String ORIG_NAME_PROP_NAME = Bundle.TagNode_propertySheet_origName(); + private final static String ORIG_NAME_PROP_DISPLAY_NAME = Bundle.TagNode_propertySheet_origNameDisplayName(); + + private final String originalName; + private volatile String translatedName; // Only computed once, in a background thread. + + /* + * The node has an event listener that is wrapped in a weak reference that + * allows the node to be garbage collected when the NetBeans infrastructure + * discards it. If this is not done, it has been shown that a strong + * reference to the listener prevents garbage collection of this node. + */ + private final PropertyChangeListener listener = WeakListeners.propertyChange(new NameTranslationListener(), null); + + /** + * An abstract superclass for a node that represents a tag, uses the name of + * a given Content object as its display name, and has a property sheet with + * an untranslated file name property when machine translation is enabled. + * + * @param lookup The Lookup of the node. + * @param content The Content to use for the node display name. + */ + TagNode(Lookup lookup, Content content) { + super(Children.LEAF, lookup); + originalName = content.getName(); + } + + @Override + public boolean isLeafTypeNode() { + return true; + } + + @Override + abstract public String getItemType(); + + @Override + abstract public T accept(DisplayableItemNodeVisitor visitor); + + /** + * Adds an original name property to the node's property sheet and submits + * an original name translation task. + * + * The translation of the original name is done in a background thread. The + * translated name is made the display name of the node and the untranslated + * name is put into both the original name property and into the node's + * tooltip. + * + * @param properties The node's property sheet. + */ + protected void addOriginalNameProp(Sheet.Set properties) { + if (TextTranslationService.getInstance().hasProvider() && UserPreferences.displayTranslatedFileNames()) { + properties.put(new NodeProperty<>( + ORIG_NAME_PROP_NAME, + ORIG_NAME_PROP_DISPLAY_NAME, + "", + translatedName != null ? translatedName : "")); + if (translatedName == null) { + new FileNameTransTask(originalName, this, listener).submit(); + } + } + } + + /* + * A listener for PropertyChangeEvents from a background task used to + * translate the original display name associated with the node. + */ + private class NameTranslationListener implements PropertyChangeListener { + + @Override + public void propertyChange(PropertyChangeEvent evt) { + String eventType = evt.getPropertyName(); + if (eventType.equals(FileNameTransTask.getPropertyName())) { + setDisplayName(evt.getNewValue().toString()); + setShortDescription(evt.getOldValue().toString()); + updatePropertySheet(new NodeProperty<>( + ORIG_NAME_PROP_NAME, + ORIG_NAME_PROP_DISPLAY_NAME, + "", + evt.getOldValue().toString())); + } + } + } + +} diff --git a/Core/src/org/sleuthkit/autopsy/directorytree/DataResultFilterNode.java b/Core/src/org/sleuthkit/autopsy/directorytree/DataResultFilterNode.java index 522d3836c3..a412bb5970 100644 --- a/Core/src/org/sleuthkit/autopsy/directorytree/DataResultFilterNode.java +++ b/Core/src/org/sleuthkit/autopsy/directorytree/DataResultFilterNode.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2011-2019 Basis Technology Corp. + * Copyright 2012-2020 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -187,27 +187,6 @@ public class DataResultFilterNode extends FilterNode { return propertySets; } - /** - * Gets the display name for the wrapped node. - * - * OutlineView used in the DataResult table uses getDisplayName() to - * populate the first column, which is Source File. - * - * Hence this override to return the 'correct' displayName for the wrapped - * node. - * - * @return The display name for the node. - */ - @Override - public String getDisplayName() { - final Node orig = getOriginal(); - String name = orig.getDisplayName(); - if ((orig instanceof BlackboardArtifactNode)) { - name = ((BlackboardArtifactNode) orig).getSourceName(); - } - return name; - } - /** * Adds information about which child node of this node, if any, should be * selected. Can be null. From 060467f6199039097a605caa1b8d31c99efe0108 Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Thu, 19 Mar 2020 07:57:27 -0400 Subject: [PATCH 086/100] 6032 translated file names in results view --- Core/src/org/sleuthkit/autopsy/datamodel/TagNode.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/TagNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/TagNode.java index 7d4d8d467c..e0b5d89905 100755 --- a/Core/src/org/sleuthkit/autopsy/datamodel/TagNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/TagNode.java @@ -39,7 +39,7 @@ import org.sleuthkit.datamodel.Content; * translated name is made the display name of the node and the untranslated * name is put into both the original name property and into the node's tooltip. * - * TODO (Jira-): Consider modifying this class to be able to use it more broadly + * TODO (Jira-6174): Consider modifying this class to be able to use it more broadly * within the Autopsy data model (i.e., AbstractNode suclasses). It's not really * specific to a tag node. */ From 89ccc44a56a36a776926655f4bd80cef40cea056 Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Thu, 19 Mar 2020 08:24:29 -0400 Subject: [PATCH 087/100] 6032 translated file names in results view --- .../sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java index e2043846fe..99685d29a4 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java @@ -493,6 +493,8 @@ public abstract class AbstractAbstractFileNode extends A /** * Translates the name of the file this node represents. An empty string * will be returned if the translation fails for any reason. + * + * @return The translated file name or the empty string. */ String getTranslatedFileName() { try { From cdea715cf702fe3f95f5e99b3f2d0fd9bc9559fc Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Thu, 19 Mar 2020 08:30:02 -0400 Subject: [PATCH 088/100] 6032 translated file names in results view --- .../autopsy/datamodel/BlackboardArtifactNode.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java index 6663c87bb3..a716d5eb64 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java @@ -209,14 +209,15 @@ public class BlackboardArtifactNode extends AbstractContentNode( Bundle.BlackboardArtifactNode_createSheet_srcFile_origName(), Bundle.BlackboardArtifactNode_createSheet_srcFile_origDisplayName(), NO_DESCR, - evt.getOldValue().toString())); + originalName)); } } }; From a287d4704ac7d2a9ddf139b8cf97f101e1f29915 Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Thu, 19 Mar 2020 08:31:36 -0400 Subject: [PATCH 089/100] 6032 translated file names in results view --- .../autopsy/datamodel/BlackboardArtifactNode.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java index a716d5eb64..cbf37d77ae 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java @@ -229,7 +229,7 @@ public class BlackboardArtifactNode extends AbstractContentNode(this), weakAppEventListener)); + backgroundTasksPool.submit(new GetSCOTask(new WeakReference<>(this), weakListener)); } /* From 915facbcb3fce881750d8feb8a283830e1b35600 Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Thu, 19 Mar 2020 08:36:46 -0400 Subject: [PATCH 090/100] 6032 translated file names in results view --- .../sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java index cbf37d77ae..87eb7b6610 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java @@ -462,6 +462,9 @@ public class BlackboardArtifactNode extends AbstractContentNode Date: Thu, 19 Mar 2020 08:43:03 -0400 Subject: [PATCH 091/100] 6032 translated file names in results view --- .../sleuthkit/autopsy/datamodel/TagNode.java | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/TagNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/TagNode.java index e0b5d89905..20bf7d9c95 100755 --- a/Core/src/org/sleuthkit/autopsy/datamodel/TagNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/TagNode.java @@ -55,14 +55,6 @@ abstract class TagNode extends DisplayableItemNode { private final String originalName; private volatile String translatedName; // Only computed once, in a background thread. - /* - * The node has an event listener that is wrapped in a weak reference that - * allows the node to be garbage collected when the NetBeans infrastructure - * discards it. If this is not done, it has been shown that a strong - * reference to the listener prevents garbage collection of this node. - */ - private final PropertyChangeListener listener = WeakListeners.propertyChange(new NameTranslationListener(), null); - /** * An abstract superclass for a node that represents a tag, uses the name of * a given Content object as its display name, and has a property sheet with @@ -106,7 +98,7 @@ abstract class TagNode extends DisplayableItemNode { "", translatedName != null ? translatedName : "")); if (translatedName == null) { - new FileNameTransTask(originalName, this, listener).submit(); + new FileNameTransTask(originalName, this, new NameTranslationListener()).submit(); } } } @@ -121,13 +113,15 @@ abstract class TagNode extends DisplayableItemNode { public void propertyChange(PropertyChangeEvent evt) { String eventType = evt.getPropertyName(); if (eventType.equals(FileNameTransTask.getPropertyName())) { - setDisplayName(evt.getNewValue().toString()); - setShortDescription(evt.getOldValue().toString()); + translatedName = evt.getNewValue().toString(); + String originalName = evt.getOldValue().toString(); + setDisplayName(translatedName); + setShortDescription(originalName); updatePropertySheet(new NodeProperty<>( ORIG_NAME_PROP_NAME, ORIG_NAME_PROP_DISPLAY_NAME, "", - evt.getOldValue().toString())); + originalName)); } } } From 9c14a4de791b96725f0c4e0bd391732f984142e1 Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Thu, 19 Mar 2020 09:05:40 -0400 Subject: [PATCH 092/100] 6032 translated file names in results view --- .../datamodel/BlackboardArtifactNode.java | 108 ++++++------------ .../datamodel/Bundle.properties-MERGED | 2 - 2 files changed, 37 insertions(+), 73 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java index 87eb7b6610..2c6bc93446 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java @@ -152,25 +152,19 @@ public class BlackboardArtifactNode extends AbstractContentNode( NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileModifiedTime.name"), NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileModifiedTime.displayName"), @@ -638,18 +608,16 @@ public class BlackboardArtifactNode extends AbstractContentNode tags = new ArrayList<>(); try { tags.addAll(Case.getCurrentCaseThrows().getServices().getTagsManager().getBlackboardArtifactTagsByArtifact(artifact)); - if (srcContent != null) { - tags.addAll(Case.getCurrentCaseThrows().getServices().getTagsManager().getContentTagsByContent(srcContent)); - } + tags.addAll(Case.getCurrentCaseThrows().getServices().getTagsManager().getContentTagsByContent(srcContent)); } catch (TskCoreException | NoCurrentCaseException ex) { logger.log(Level.SEVERE, MessageFormat.format("Error getting tags for artifact and its source content (artifact objID={0})", artifact.getId()), ex); } @@ -725,7 +691,7 @@ public class BlackboardArtifactNode extends AbstractContentNode Date: Thu, 19 Mar 2020 09:06:39 -0400 Subject: [PATCH 093/100] 6032 translated file names in results view --- .../sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java index 2c6bc93446..48d95b506d 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java @@ -127,8 +127,8 @@ public class BlackboardArtifactNode extends AbstractContentNode Date: Thu, 19 Mar 2020 09:13:20 -0400 Subject: [PATCH 094/100] 6032 translated file names in results view --- .../autopsy/texttranslation/utils/FileNameTranslator.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Core/src/org/sleuthkit/autopsy/texttranslation/utils/FileNameTranslator.java b/Core/src/org/sleuthkit/autopsy/texttranslation/utils/FileNameTranslator.java index 71b8a859b4..cfd04dcb93 100755 --- a/Core/src/org/sleuthkit/autopsy/texttranslation/utils/FileNameTranslator.java +++ b/Core/src/org/sleuthkit/autopsy/texttranslation/utils/FileNameTranslator.java @@ -44,6 +44,9 @@ public class FileNameTranslator { /* * Don't attempt translation if the characters of the file name are all * ASCII chars. + * + * TODO (Jira-6175): This filter prevents translation of many + * non-English file names composed entirely of Latin chars. */ if (fileName.matches("^\\p{ASCII}+$")) { return ""; From 06eba0fe63a2176a8abdbfe4ad7db606513be877 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Thu, 19 Mar 2020 10:45:19 -0400 Subject: [PATCH 095/100] checks whether or not cr buttons need to be enabled each event change --- .../centralrepository/optionspanel/GlobalSettingsPanel.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java index 78b2e9ca87..e84d2b90f7 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java @@ -731,9 +731,9 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i enableButtonSubComponents(cbUseCentralRepo.isSelected()); } else { load(); - enableDatabaseConfigureButton(cbUseCentralRepo.isSelected() && !caseIsOpen); } + enableDatabaseConfigureButton(cbUseCentralRepo.isSelected() && !caseIsOpen); } /** From df3f1ec2e81eaa68ddff0239765efd981d4c9e67 Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Thu, 19 Mar 2020 12:10:58 -0400 Subject: [PATCH 096/100] 6032 translated file names in results view --- .../autopsy/datamodel/AbstractAbstractFileNode.java | 4 ++-- Core/src/org/sleuthkit/autopsy/datamodel/TagNode.java | 5 ++--- .../sleuthkit/autopsy/datamodel/utils/FileNameTransTask.java | 4 ++-- ...{FileNameTranslator.java => FileNameTranslationUtil.java} | 4 ++-- 4 files changed, 8 insertions(+), 9 deletions(-) rename Core/src/org/sleuthkit/autopsy/texttranslation/utils/{FileNameTranslator.java => FileNameTranslationUtil.java} (96%) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java index 99685d29a4..74ac603e0b 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java @@ -66,7 +66,7 @@ import org.sleuthkit.datamodel.Tag; import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.datamodel.TskData; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository; -import org.sleuthkit.autopsy.texttranslation.utils.FileNameTranslator; +import org.sleuthkit.autopsy.texttranslation.utils.FileNameTranslationUtil; /** * An abstract node that encapsulates AbstractFile data @@ -498,7 +498,7 @@ public abstract class AbstractAbstractFileNode extends A */ String getTranslatedFileName() { try { - return FileNameTranslator.translate(content.getName()); + return FileNameTranslationUtil.translate(content.getName()); } catch (NoServiceProviderException | TranslationException ex) { logger.log(Level.WARNING, MessageFormat.format("Error translating file name (objID={0}))", content.getId()), ex); return ""; diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/TagNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/TagNode.java index 20bf7d9c95..9e0f1c7268 100755 --- a/Core/src/org/sleuthkit/autopsy/datamodel/TagNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/TagNode.java @@ -24,7 +24,6 @@ import org.openide.nodes.Children; import org.openide.nodes.Sheet; import org.openide.util.Lookup; import org.openide.util.NbBundle; -import org.openide.util.WeakListeners; import org.sleuthkit.autopsy.core.UserPreferences; import org.sleuthkit.autopsy.datamodel.utils.FileNameTransTask; import org.sleuthkit.autopsy.texttranslation.TextTranslationService; @@ -53,7 +52,7 @@ abstract class TagNode extends DisplayableItemNode { private final static String ORIG_NAME_PROP_DISPLAY_NAME = Bundle.TagNode_propertySheet_origNameDisplayName(); private final String originalName; - private volatile String translatedName; // Only computed once, in a background thread. + private volatile String translatedName; /** * An abstract superclass for a node that represents a tag, uses the name of @@ -103,7 +102,7 @@ abstract class TagNode extends DisplayableItemNode { } } - /* + /** * A listener for PropertyChangeEvents from a background task used to * translate the original display name associated with the node. */ diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/utils/FileNameTransTask.java b/Core/src/org/sleuthkit/autopsy/datamodel/utils/FileNameTransTask.java index 88ccac2d2f..8b755ec3dc 100755 --- a/Core/src/org/sleuthkit/autopsy/datamodel/utils/FileNameTransTask.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/utils/FileNameTransTask.java @@ -21,7 +21,7 @@ package org.sleuthkit.autopsy.datamodel.utils; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import org.openide.nodes.AbstractNode; -import org.sleuthkit.autopsy.texttranslation.utils.FileNameTranslator; +import org.sleuthkit.autopsy.texttranslation.utils.FileNameTranslationUtil; /** * An AbstractNodePropertySheetTask that translates a file name for an @@ -54,7 +54,7 @@ public class FileNameTransTask extends AbstractNodePropertySheetTask Date: Thu, 19 Mar 2020 16:15:23 -0400 Subject: [PATCH 097/100] Codacy suggestions round 2 --- .../org/sleuthkit/autopsy/contentviewers/utils/GstLoader.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/utils/GstLoader.java b/Core/src/org/sleuthkit/autopsy/contentviewers/utils/GstLoader.java index 57da88e0a2..b6804d488a 100755 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/utils/GstLoader.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/utils/GstLoader.java @@ -26,7 +26,7 @@ import org.sleuthkit.autopsy.coreutils.Logger; /** * A utility class that loads the gstreamer bindings. */ -public class GstLoader { +public final class GstLoader { private static final Logger logger = Logger.getLogger(GstLoader.class.getName()); private static GstStatus status; From 62be8d53605142d0864968627ab1d80860d5f389 Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Fri, 20 Mar 2020 08:05:53 -0400 Subject: [PATCH 098/100] 6133 add new default video thumb image --- .../autopsy/filequery/FileSearch.java | 49 +++++++++++------- .../images/failedToCreateVideoThumb.png | Bin 0 -> 2481 bytes 2 files changed, 29 insertions(+), 20 deletions(-) create mode 100644 Core/src/org/sleuthkit/autopsy/images/failedToCreateVideoThumb.png diff --git a/Core/src/org/sleuthkit/autopsy/filequery/FileSearch.java b/Core/src/org/sleuthkit/autopsy/filequery/FileSearch.java index daa4124e8d..ae0e939498 100644 --- a/Core/src/org/sleuthkit/autopsy/filequery/FileSearch.java +++ b/Core/src/org/sleuthkit/autopsy/filequery/FileSearch.java @@ -95,6 +95,7 @@ class FileSearch { .build(); private static final int PREVIEW_SIZE = 256; private static volatile TextSummarizer summarizerToUse = null; + private static final BufferedImage VIDEO_DEFAULT_IMAGE = getDefaultVideoThumbnail(); /** * Run the file search and returns the SearchResults object for debugging. @@ -456,6 +457,15 @@ class FileSearch { + "AND blackboard_artifacts.obj_id IN (" + objIdList + ") "; // NON-NLS } + private static BufferedImage getDefaultVideoThumbnail() { + try { + return ImageIO.read(ImageUtils.class.getResourceAsStream("/org/sleuthkit/autopsy/images/failedToCreateVideoThumb.png"));//NON-NLS + } catch (IOException ex) { + logger.log(Level.SEVERE, "Failed to load 'failed to create video' placeholder.", ex); //NON-NLS + } + return null; + } + /** * Get the video thumbnails for a file which exists in a * VideoThumbnailsWrapper and update the VideoThumbnailsWrapper to include @@ -476,7 +486,6 @@ class FileSearch { cacheDirectory = null; logger.log(Level.WARNING, "Unable to get cache directory, video thumbnails will not be saved", ex); } - if (cacheDirectory == null || file.getMd5Hash() == null || !Paths.get(cacheDirectory, VIDEO_THUMBNAIL_DIR, file.getMd5Hash()).toFile().exists()) { java.io.File tempFile; try { @@ -488,7 +497,7 @@ class FileSearch { 0, 0, 0}; - thumbnailWrapper.setThumbnails(createDefaultThumbnailList(), framePositions); + thumbnailWrapper.setThumbnails(createDefaultThumbnailList(VIDEO_DEFAULT_IMAGE), framePositions); return; } if (tempFile.exists() == false || tempFile.length() < file.getSize()) { @@ -502,7 +511,7 @@ class FileSearch { 0, 0, 0}; - thumbnailWrapper.setThumbnails(createDefaultThumbnailList(), framePositions); + thumbnailWrapper.setThumbnails(createDefaultThumbnailList(VIDEO_DEFAULT_IMAGE), framePositions); return; } ContentUtils.writeToFile(file, tempFile, progress, null, true); @@ -523,7 +532,7 @@ class FileSearch { 0, 0, 0}; - thumbnailWrapper.setThumbnails(createDefaultThumbnailList(), framePositions); + thumbnailWrapper.setThumbnails(createDefaultThumbnailList(VIDEO_DEFAULT_IMAGE), framePositions); return; } double fps = videoFile.get(5); // gets frame per second @@ -535,7 +544,7 @@ class FileSearch { 0, 0, 0}; - thumbnailWrapper.setThumbnails(createDefaultThumbnailList(), framePositions); + thumbnailWrapper.setThumbnails(createDefaultThumbnailList(VIDEO_DEFAULT_IMAGE), framePositions); return; } if (Thread.interrupted()) { @@ -544,7 +553,7 @@ class FileSearch { 0, 0, 0}; - thumbnailWrapper.setThumbnails(createDefaultThumbnailList(), framePositions); + thumbnailWrapper.setThumbnails(createDefaultThumbnailList(VIDEO_DEFAULT_IMAGE), framePositions); return; } @@ -573,10 +582,10 @@ class FileSearch { logger.log(Level.WARNING, "Error seeking to " + framePositions[i] + "ms in {0}", file.getParentPath() + "/" + file.getName()); //NON-NLS // If we can't set the time, continue to the next frame position and try again. - videoThumbnails.add(ImageUtils.getDefaultThumbnail()); + videoThumbnails.add(VIDEO_DEFAULT_IMAGE); if (cacheDirectory != null) { try { - ImageIO.write((RenderedImage) ImageUtils.getDefaultThumbnail(), THUMBNAIL_FORMAT, + ImageIO.write(VIDEO_DEFAULT_IMAGE, THUMBNAIL_FORMAT, Paths.get(cacheDirectory, VIDEO_THUMBNAIL_DIR, file.getMd5Hash(), i + "-" + framePositions[i] + "." + THUMBNAIL_FORMAT).toFile()); //NON-NLS) } catch (IOException ex) { logger.log(Level.WARNING, "Unable to save default video thumbnail for " + file.getMd5Hash() + " at frame position " + framePositions[i], ex); @@ -588,10 +597,10 @@ class FileSearch { if (!videoFile.read(imageMatrix)) { logger.log(Level.WARNING, "Error reading frame at " + framePositions[i] + "ms from {0}", file.getParentPath() + "/" + file.getName()); //NON-NLS // If the image is bad for some reason, continue to the next frame position and try again. - videoThumbnails.add(ImageUtils.getDefaultThumbnail()); + videoThumbnails.add(VIDEO_DEFAULT_IMAGE); if (cacheDirectory != null) { try { - ImageIO.write((RenderedImage) ImageUtils.getDefaultThumbnail(), THUMBNAIL_FORMAT, + ImageIO.write(VIDEO_DEFAULT_IMAGE, THUMBNAIL_FORMAT, Paths.get(cacheDirectory, VIDEO_THUMBNAIL_DIR, file.getMd5Hash(), i + "-" + framePositions[i] + "." + THUMBNAIL_FORMAT).toFile()); //NON-NLS) } catch (IOException ex) { logger.log(Level.WARNING, "Unable to save default video thumbnail for " + file.getMd5Hash() + " at frame position " + framePositions[i], ex); @@ -602,10 +611,10 @@ class FileSearch { } // If the image is empty, return since no buffered image can be created. if (imageMatrix.empty()) { - videoThumbnails.add(ImageUtils.getDefaultThumbnail()); + videoThumbnails.add(VIDEO_DEFAULT_IMAGE); if (cacheDirectory != null) { try { - ImageIO.write((RenderedImage) ImageUtils.getDefaultThumbnail(), THUMBNAIL_FORMAT, + ImageIO.write(VIDEO_DEFAULT_IMAGE, THUMBNAIL_FORMAT, Paths.get(cacheDirectory, VIDEO_THUMBNAIL_DIR, file.getMd5Hash(), i + "-" + framePositions[i] + "." + THUMBNAIL_FORMAT).toFile()); //NON-NLS) } catch (IOException ex) { logger.log(Level.WARNING, "Unable to save default video thumbnail for " + file.getMd5Hash() + " at frame position " + framePositions[i], ex); @@ -660,7 +669,7 @@ class FileSearch { videoFile.release(); // close the file} } } else { - loadSavedThumbnails(cacheDirectory, thumbnailWrapper); + loadSavedThumbnails(cacheDirectory, thumbnailWrapper, VIDEO_DEFAULT_IMAGE); } } @@ -674,7 +683,7 @@ class FileSearch { * information about the file and the thumbnails * associated with it. */ - private static void loadSavedThumbnails(String cacheDirectory, VideoThumbnailsWrapper thumbnailWrapper) { + private static void loadSavedThumbnails(String cacheDirectory, VideoThumbnailsWrapper thumbnailWrapper, BufferedImage failedVideoThumbImage) { int[] framePositions = new int[4]; List videoThumbnails = new ArrayList<>(); int thumbnailNumber = 0; @@ -683,7 +692,7 @@ class FileSearch { try { videoThumbnails.add(ImageIO.read(Paths.get(cacheDirectory, VIDEO_THUMBNAIL_DIR, md5, fileName).toFile())); } catch (IOException ex) { - videoThumbnails.add(ImageUtils.getDefaultThumbnail()); + videoThumbnails.add(failedVideoThumbImage); logger.log(Level.WARNING, "Unable to read saved video thumbnail " + fileName + " for " + md5, ex); } int framePos = Integer.valueOf(FilenameUtils.getBaseName(fileName).substring(2)); @@ -699,12 +708,12 @@ class FileSearch { * * @return List containing the default thumbnail. */ - private static List createDefaultThumbnailList() { + private static List createDefaultThumbnailList(BufferedImage failedVideoThumbImage) { List videoThumbnails = new ArrayList<>(); - videoThumbnails.add(ImageUtils.getDefaultThumbnail()); - videoThumbnails.add(ImageUtils.getDefaultThumbnail()); - videoThumbnails.add(ImageUtils.getDefaultThumbnail()); - videoThumbnails.add(ImageUtils.getDefaultThumbnail()); + videoThumbnails.add(failedVideoThumbImage); + videoThumbnails.add(failedVideoThumbImage); + videoThumbnails.add(failedVideoThumbImage); + videoThumbnails.add(failedVideoThumbImage); return videoThumbnails; } diff --git a/Core/src/org/sleuthkit/autopsy/images/failedToCreateVideoThumb.png b/Core/src/org/sleuthkit/autopsy/images/failedToCreateVideoThumb.png new file mode 100644 index 0000000000000000000000000000000000000000..876402c150904d298d8362f4f6b870cdf3735553 GIT binary patch literal 2481 zcmb7GX*?5-AD%gK%(X(p$Ppq(IYwBy8FMUilrp)O$kE)SlWa?eAxcrkL>fvzM~<9x zg>vSKY3}QX&G6Uz|BL_s#q&I$=Xv*i^L?HaM|&$leo1}+03c{%ZH_wB*N5=o1s*bS z;Qi2{aD=0*OaZ0c(u_mHxq zsH;oa#tu?8$6GV{<2hTIfHpTdgh^mfiiXQgMevJb;;6U0kd*1^X?q>ls;X&uNir{g zTS^2tuj+xsDW%YqdPh`_))4W0ebRZ(?M_;EcWET<=a$ShKec}w^Q!H|ljzVN_sP^3KLDiwgS;-TLF_XE`1oe-+X#)TxoBiwq@hoK{;$>e`9o51afxe26^b4|yMS8AE# zf%ZP6eueM9c0kAvIy;vWW0ry+D|=ghBW3H~ttQ;{@QbXaO|&E*G_02a9R?4sR72y? z{p<~llD|WvzfA5j@)>#Ba+8!Vte5kLONo{`QxZPgZ#HFnXD|3etvo+ncpS!J|3h%z zm`hJ`FqS4wAkn3AA1k?-!a~F7+ZCocup1Vh!jsrYvu=m&lfBTkdezgp>%O;=>(Vle z5J{v_3-&xnQ9dap)V73fkSL%NN#uvLBg6=IQ#zMPDpBLAnm@w&0vbsO3Nz+>j1)YdLKg?=jDJ0$SIXV>vfb=p?ZCery9TD~iuvQ9CA1kZ<@|M)Yy zD;j66bn7`eaO=%k{U!_Srit%H7uJ)wBTpF8#a zESmG*_dK$gCqa+CWb=7&C1Q7JdA50+P);di;6f%ftEA;`Kh%pj@jb99??v3doy#(E zYiwWYY4K5!G8Y8*wha8B(5Lc~25Zs~`XtEhiSjA(FQ#e^FlvNua>-gOPt(Y_Q|11L zi%4^L<|0(4F1urZ-?n-dL0iKmIqrev>^vVp->I}HgOg&(9~d}=%Q+fo@rBXUm*tf) z$tPn}U*7xrZYk-vZq4#yue2zu4s;&jgm*XwjQk3&ZXiCJZ=_>m;JNn5tx*YfKLAy9 zWYv|y>*aO&HhFU=dq1OgYWezsOQv^1&T)@i4wsqS(gBS{zbWVZ@jC48*+!MX1(1ok ztquTZ?cZ?8;GS>+v6qU&g-hYwixb_H$Y}U;9kX&&`QwtkCc>VhE^QrD(RU+x+N8O&SyTy}ta7#{lzJXYebXn2KFu0~{Dm>h=-j2QF zucGnvzJ)!fmi8aF>ddSKokc+k%#7+>@d;Pzr5Z$Mp47B|!e9*phbvj1=SfUlPj#RBd?#|t*Tafu?1Be@>;O1t^Apg z=*gXc`iUdieEaYnD~|v2D_TVL^+g^gKy=;^LZGq+-Om1~w-v6|AOiILQG+l~%N5s7 zf30YML=W$9^)>0F75(EsGj=T7uql2~-;YQUEiva|{bjj$A$=a#oT88jvL5ic53kf1 z1+UE=L#~kvI9YF&S_hcE*lMkH+wW*4bIZ0PS1olerpC0errOJDu%pEhm=_TL9?DIq zPifUwY^!LR01GXs(^lFG;dNq`+WNrf=LX)~xxDv9zuT7>W!8(Jm;1YMe(?y!b8!j@ zdA+u{QQ^5fa_Pf6cGt^ar?%q)T(B3#WUefn@!NF!E!WG(X8VF!Wpj)7Mq>?0y4rgl zk6`%~gY7GZLReM`MV-+sA zgSs3WN>u&m`_t))h>3QU++YJYQ2(*jdyAOyskLLf#WJ%h0RzfNDoC7-M#G9ezKv&>~(Sl zf3scKBXZEp2+BtOi{082wLZ+Ehx-#I}`k?fJV7rg-hYfFehcB=s$^s=lcz7VXKclQoc{@qa zRW-`LklvQRw^{K9LuKg_E!XDyDj9+|R@*+dn1L-Zspk$-z5iLb_`b)e+Zj4RApoFl zuZ4pv`KljY6AGKlTpE3|KlrMu-6=q9oxLhKj^P;Vjnf%$s`xF6z??IgG7_nPlVQWe z$RbOaW2I@c>Ked=r>FP*qWv1ur35giLT&f4y#s3+01KW~*HCTpUWyimi8J$>;GPt( z(Se1q2ZIN1O}E>B0|XWgq^~wfp2oBut$M=@u$~b4v*OC!g$Pb@(fe(WGD}iJ1V!Zx zgKic(?;QS{XwN2h4g9z+QL}C& zG->v}q%Kk6@0#caSrUGyBCcQ>cgNLB<}S|Ez4<{?)0#AlcVfg^L=ob+{B~TD#vFhJ vxhM=kx9%Xo_2-Es?!wJ@1w59E#u9E#j7^5egb5waEP#!Ly?LoA=FWcr<*cWz literal 0 HcmV?d00001 From ed367ac36a6423ee63d5e13cf09376414e8516ae Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Fri, 20 Mar 2020 08:08:58 -0400 Subject: [PATCH 099/100] 6133 clean up changes for video thumbnail --- Core/src/org/sleuthkit/autopsy/filequery/FileSearch.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/filequery/FileSearch.java b/Core/src/org/sleuthkit/autopsy/filequery/FileSearch.java index ae0e939498..6a5543c9c9 100644 --- a/Core/src/org/sleuthkit/autopsy/filequery/FileSearch.java +++ b/Core/src/org/sleuthkit/autopsy/filequery/FileSearch.java @@ -23,7 +23,6 @@ import com.google.common.cache.CacheBuilder; import com.google.common.io.Files; import java.awt.Image; import java.awt.image.BufferedImage; -import java.awt.image.RenderedImage; import java.io.IOException; import java.io.Reader; import java.nio.file.Paths; @@ -457,6 +456,11 @@ class FileSearch { + "AND blackboard_artifacts.obj_id IN (" + objIdList + ") "; // NON-NLS } + /** + * Get the default image to display when a thumbnail is not available. + * + * @return The default video thumbnail. + */ private static BufferedImage getDefaultVideoThumbnail() { try { return ImageIO.read(ImageUtils.class.getResourceAsStream("/org/sleuthkit/autopsy/images/failedToCreateVideoThumb.png"));//NON-NLS From 39dc88814071414652f3ab7cec1915779ecc8e8b Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Fri, 20 Mar 2020 10:14:47 -0400 Subject: [PATCH 100/100] 6032 fixes for review issues --- .../org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java | 2 +- Core/src/org/sleuthkit/autopsy/datamodel/TagNode.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java index 48d95b506d..8358dd7d34 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java @@ -432,7 +432,7 @@ public class BlackboardArtifactNode extends AbstractContentNode