From 70e62f28c0026b3d5f5ff01ef9bad896e7f6d580 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Mon, 24 Feb 2020 15:57:32 -0500 Subject: [PATCH 01/97] 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 02/97] 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 03/97] 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 04/97] 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 05/97] 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 06/97] 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 07/97] 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 08/97] 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 09/97] 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 10/97] 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 11/97] 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 12/97] 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 13/97] 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 14/97] 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 0dfead369942412dcfdc2273d3ed5dc4fa78f645 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Mon, 2 Mar 2020 14:39:08 -0500 Subject: [PATCH 15/97] 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 16/97] 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 17/97] 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 18/97] 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 f3f669684a9085deadf3a75d8da6377c6d996a9a Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Tue, 3 Mar 2020 17:23:40 -0500 Subject: [PATCH 19/97] translatable panel for message content viewer --- .../contentviewers/TranslatablePanel.form | 102 +++++++++++++ .../contentviewers/TranslatablePanel.java | 136 ++++++++++++++++++ 2 files changed, 238 insertions(+) create mode 100644 Core/src/org/sleuthkit/autopsy/contentviewers/TranslatablePanel.form create mode 100644 Core/src/org/sleuthkit/autopsy/contentviewers/TranslatablePanel.java diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/TranslatablePanel.form b/Core/src/org/sleuthkit/autopsy/contentviewers/TranslatablePanel.form new file mode 100644 index 0000000000..ad82eb8e67 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/TranslatablePanel.form @@ -0,0 +1,102 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/TranslatablePanel.java b/Core/src/org/sleuthkit/autopsy/contentviewers/TranslatablePanel.java new file mode 100644 index 0000000000..2746c68b6b --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/TranslatablePanel.java @@ -0,0 +1,136 @@ +/* + * 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; + +import org.apache.commons.lang.StringUtils; +import org.openide.util.NbBundle; +import javax.swing.JPanel; + +/** + * A JPanel used by TranslatedContentViewer to display machine translation of + * text. + */ +@SuppressWarnings("PMD.SingularField") // UI widgets cause lots of false positives +final class TranslatablePanel extends JPanel { + private static final long serialVersionUID = 1L; + private int lastSelectedIndex = 0; + private final TranslatableJPanel contentPanel; + private final String origOptionText; + private final String translatedOptionText; + + static abstract class TranslatableJPanel extends JPanel { + protected abstract String onTranslateChange(boolean translate); + } + + /** + * Creates new form TranslatedContentPanel + */ + TranslatablePanel(TranslatableJPanel contentPanel, String origOptionText, String translatedOptionText) { + this.contentPanel = contentPanel; + this.origOptionText = origOptionText; + this.translatedOptionText = translatedOptionText; + + initComponents(); + add(this.contentPanel, java.awt.BorderLayout.CENTER); + reset(); + + } + + + void setWarningLabelMsg(String msg) { + warningLabel.setText(msg); + warningLabel.setVisible(StringUtils.isEmpty(msg)); + } + +// @Messages({"TranslatedContentPanel.comboBoxOption.originalText=Original Text (Up to 25KB)", +// "TranslatedContentPanel.comboBoxOption.translatedText=Translated Text"}) + + + //@NbBundle.Messages({"TranslationContentPanel.autoDetectOCR=Autodetect language"}) + final void reset() { + setWarningLabelMsg(null); + displayTextComboBox.removeAllItems(); + displayTextComboBox.addItem(this.origOptionText); + displayTextComboBox.addItem(this.translatedOptionText); + } + + + /** + * 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() { + java.awt.GridBagConstraints gridBagConstraints; + + jPanel1 = new javax.swing.JPanel(); + displayTextComboBox = new javax.swing.JComboBox<>(); + warningLabel = new javax.swing.JLabel(); + showLabel = new javax.swing.JLabel(); + + setMaximumSize(new java.awt.Dimension(2000, 2000)); + setMinimumSize(new java.awt.Dimension(2, 2)); + setName(""); // NOI18N + setPreferredSize(new java.awt.Dimension(100, 58)); + setVerifyInputWhenFocusTarget(false); + setLayout(new java.awt.BorderLayout()); + + jPanel1.setBorder(javax.swing.BorderFactory.createEtchedBorder()); + jPanel1.setMaximumSize(new java.awt.Dimension(182, 24)); + jPanel1.setPreferredSize(new java.awt.Dimension(182, 24)); + jPanel1.setLayout(new java.awt.GridBagLayout()); + + displayTextComboBox.setMinimumSize(new java.awt.Dimension(43, 20)); + displayTextComboBox.setPreferredSize(new java.awt.Dimension(43, 20)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 3; + gridBagConstraints.gridy = 0; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST; + gridBagConstraints.weightx = 0.1; + gridBagConstraints.insets = new java.awt.Insets(0, 5, 0, 0); + jPanel1.add(displayTextComboBox, gridBagConstraints); + + warningLabel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/images/warning16.png"))); // NOI18N + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 0; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST; + gridBagConstraints.weightx = 0.25; + jPanel1.add(warningLabel, gridBagConstraints); + + org.openide.awt.Mnemonics.setLocalizedText(showLabel, org.openide.util.NbBundle.getMessage(TranslatablePanel.class, "TranslatablePanel.showLabel.text")); // NOI18N + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 2; + gridBagConstraints.gridy = 0; + jPanel1.add(showLabel, gridBagConstraints); + + add(jPanel1, java.awt.BorderLayout.NORTH); + }// //GEN-END:initComponents + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JComboBox displayTextComboBox; + private javax.swing.JPanel jPanel1; + private javax.swing.JLabel showLabel; + private javax.swing.JLabel warningLabel; + // End of variables declaration//GEN-END:variables +} \ No newline at end of file From 720980422a031f646281778bb706ef90beee310f Mon Sep 17 00:00:00 2001 From: Raman Arora Date: Wed, 4 Mar 2020 10:30:42 -0500 Subject: [PATCH 20/97] 6100: Suppress creation of Persona tables. --- .../datamodel/RdbmsCentralRepoFactory.java | 28 +++++-------------- 1 file changed, 7 insertions(+), 21 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/RdbmsCentralRepoFactory.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/RdbmsCentralRepoFactory.java index 2fa248598e..db7343ad50 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/RdbmsCentralRepoFactory.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/RdbmsCentralRepoFactory.java @@ -134,7 +134,7 @@ public class RdbmsCentralRepoFactory { stmt.execute("INSERT INTO db_info (name, value) VALUES ('" + RdbmsCentralRepo.CREATION_SCHEMA_MAJOR_VERSION_KEY + "', '" + SOFTWARE_CR_DB_SCHEMA_VERSION.getMajor() + "')"); stmt.execute("INSERT INTO db_info (name, value) VALUES ('" + RdbmsCentralRepo.CREATION_SCHEMA_MINOR_VERSION_KEY + "', '" + SOFTWARE_CR_DB_SCHEMA_VERSION.getMinor() + "')"); - // Create account_types and accounts tab;es which are referred by X_instances tables + // Create account_types and accounts tables which are referred by X_instances tables stmt.execute(getCreateAccountTypesTableStatement(selectedPlatform)); stmt.execute(getCreateAccountsTableStatement(selectedPlatform)); @@ -161,7 +161,8 @@ public class RdbmsCentralRepoFactory { stmt.execute(String.format(getReferenceTypeValueKnownstatusIndexTemplate(), reference_type_dbname, reference_type_dbname)); } } - createPersonaTables(stmt); + // @TODO: uncomment this when ready to create Persona tables. + //createPersonaTables(stmt); } catch (SQLException ex) { LOGGER.log(Level.SEVERE, "Error initializing db schema.", ex); // NON-NLS return false; @@ -191,8 +192,9 @@ public class RdbmsCentralRepoFactory { } result = CentralRepoDbUtil.insertDefaultCorrelationTypes(conn) - && CentralRepoDbUtil.insertDefaultOrganization(conn) - && insertDefaultPersonaTablesContent(conn); + && CentralRepoDbUtil.insertDefaultOrganization(conn); + // @TODO: uncomment when ready to create/populate persona tables + // && insertDefaultPersonaTablesContent(conn); } catch (SQLException ex) { LOGGER.log(Level.SEVERE, String.format("Failed to populate default data in CR tables."), ex); @@ -576,7 +578,6 @@ public class RdbmsCentralRepoFactory { stmt.execute(getCreateConfidenceTableStatement(selectedPlatform)); stmt.execute(getCreateExaminersTableStatement(selectedPlatform)); stmt.execute(getCreatePersonaStatusTableStatement(selectedPlatform)); - stmt.execute(getCreateAliasesTableStatement(selectedPlatform)); stmt.execute(getCreatePersonasTableStatement(selectedPlatform)); stmt.execute(getCreatePersonaAliasTableStatement(selectedPlatform)); @@ -653,20 +654,6 @@ public class RdbmsCentralRepoFactory { + ")"; } - /** - * Get the SQL String for creating a new aliases table in a central - * repository. - * - * @return SQL string for creating aliases table - */ - static String getCreateAliasesTableStatement(CentralRepoPlatforms selectedPlatform) { - - return "CREATE TABLE IF NOT EXISTS aliases (" - + getNumericPrimaryKeyClause("id", selectedPlatform) - + "alias TEXT NOT NULL," - + "CONSTRAINT alias_unique UNIQUE(alias)" - + ")"; - } /** * Get the SQL String for creating a new accounts table in a central @@ -719,13 +706,12 @@ public class RdbmsCentralRepoFactory { return "CREATE TABLE IF NOT EXISTS persona_alias (" + getNumericPrimaryKeyClause("id", selectedPlatform) + "persona_id " + getBigIntType(selectedPlatform) + " ," - + "alias_id " + getBigIntType(selectedPlatform) + " ," + + "alias TEXT NOT NULL, " + "justification TEXT NOT NULL," + "confidence_id integer NOT NULL," + "date_added " + getBigIntType(selectedPlatform) + " ," + "examiner_id integer NOT NULL," + "FOREIGN KEY (persona_id) REFERENCES personas(id)," - + "FOREIGN KEY (alias_id) REFERENCES aliases(id)," + "FOREIGN KEY (confidence_id) REFERENCES confidence(confidence_id)," + "FOREIGN KEY (examiner_id) REFERENCES examiners(id)" + ")"; From 901e82528689fcbcd38ce6807e03204a4d4f3caf Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Wed, 4 Mar 2020 10:59:53 -0500 Subject: [PATCH 21/97] text translation panel for message content viewer --- .../autopsy/contentviewers/Bundle.properties | 1 - .../contentviewers/Bundle_ja.properties | 1 - .../contentviewers/MessageContentViewer.form | 32 +--- .../contentviewers/MessageContentViewer.java | 141 ++++++++++++++-- .../contentviewers/TranslatablePanel.form | 7 +- .../contentviewers/TranslatablePanel.java | 154 ++++++++++++++---- 6 files changed, 256 insertions(+), 80 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/Bundle.properties b/Core/src/org/sleuthkit/autopsy/contentviewers/Bundle.properties index cf07682e5d..5eaf823310 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/Bundle.properties @@ -49,7 +49,6 @@ Metadata.nodeText.text=From The Sleuth Kit istat Tool: Metadata.nodeText.exceptionNotice.text=Error getting file metadata: MessageContentViewer.rtfbodyScrollPane.TabConstraints.tabTitle=RTF MessageContentViewer.headersScrollPane.TabConstraints.tabTitle=Headers -MessageContentViewer.textbodyScrollPane.TabConstraints.tabTitle=Text MessageContentViewer.htmlPane.TabConstraints.tabTitle=HTML MessageContentViewer.fromText.text=from address goes here MessageContentViewer.fromLabel.text=From: diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/Bundle_ja.properties b/Core/src/org/sleuthkit/autopsy/contentviewers/Bundle_ja.properties index f7b7844e60..5f15b483c3 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/Bundle_ja.properties +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/Bundle_ja.properties @@ -94,7 +94,6 @@ Metadata.nodeText.text=\u9001\u4fe1\u5143\u306eSleuth Kit\u306eistat\u30c4\u30fc Metadata.nodeText.exceptionNotice.text=\u30d5\u30a1\u30a4\u30eb\u306e\u30e1\u30bf\u30c7\u30fc\u30bf\u3092\u53d6\u5f97\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f: MessageContentViewer.rtfbodyScrollPane.TabConstraints.tabTitle=RTF MessageContentViewer.headersScrollPane.TabConstraints.tabTitle=\u30d8\u30c3\u30c0\u30fc -MessageContentViewer.textbodyScrollPane.TabConstraints.tabTitle=\u30c6\u30ad\u30b9\u30c8 MessageContentViewer.htmlPane.TabConstraints.tabTitle=HTML MessageContentViewer.fromText.text=\u9001\u4fe1\u5143\u30a2\u30c9\u30ec\u30b9\u3092\u3053\u3053\u306b\u8868\u793a MessageContentViewer.fromLabel.text=\u5dee\u51fa\u4eba: diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.form b/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.form index cf38160cd6..f0a971c143 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.form +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.form @@ -202,6 +202,11 @@ + + + + + @@ -233,33 +238,6 @@
- - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java b/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java index cadd311f70..1380299920 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java @@ -29,6 +29,8 @@ import java.util.List; import java.util.Optional; import java.util.Set; import java.util.logging.Level; +import javax.swing.JScrollPane; +import javax.swing.JTextArea; import javax.swing.text.JTextComponent; import org.apache.commons.lang3.StringUtils; import org.jsoup.Jsoup; @@ -41,12 +43,16 @@ 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.contentviewers.TranslatablePanel.TranslatableComponent; import org.sleuthkit.autopsy.corecomponentinterfaces.DataContentViewer; import org.sleuthkit.autopsy.corecomponents.DataResultPanel; import org.sleuthkit.autopsy.corecomponents.TableFilterNode; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.directorytree.DataResultFilterNode; import org.sleuthkit.autopsy.directorytree.NewWindowViewAction; +import org.sleuthkit.autopsy.texttranslation.NoServiceProviderException; +import org.sleuthkit.autopsy.texttranslation.TextTranslationService; +import org.sleuthkit.autopsy.texttranslation.TranslationException; import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.BlackboardArtifact; import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_ASSOCIATED_OBJECT; @@ -83,7 +89,106 @@ import org.sleuthkit.datamodel.blackboardutils.attributes.MessageAttachments.URL @ServiceProvider(service = DataContentViewer.class, position = 5) @SuppressWarnings("PMD.SingularField") // UI widgets cause lots of false positives public class MessageContentViewer extends javax.swing.JPanel implements DataContentViewer { + private static boolean tryHandle(Runnable runnable, String logErrorMessage) { + try { + runnable.run(); + } + catch (Exception e) { + LOGGER.log(Level.WARNING, logErrorMessage, e); + return false; + } + + return true; + } + + /** + * provides the interface to be injected into the TranslatablePanel and displays text + */ + static class TextTranslatableComponent implements TranslatableComponent { + private final Component parentComponent; + private final JTextArea textComponent; + private final TextTranslationService translationService; + + private boolean translate = false; + private String translated = null; + private String origContent = ""; + + TextTranslatableComponent() { + JTextArea textComponent = new JTextArea(); + textComponent.setEditable(false); + textComponent.setLineWrap(true); + textComponent.setRows(5); + textComponent.setWrapStyleWord(true); + + JScrollPane parentComponent = new JScrollPane(); + parentComponent.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); + parentComponent.setVerticalScrollBarPolicy(javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS); + parentComponent.setViewportView(textComponent); + + this.parentComponent = parentComponent; + this.textComponent = textComponent; + this.translationService = TextTranslationService.getInstance(); + } + + TextTranslatableComponent(Component parentComponent, JTextArea textComponent, TextTranslationService translationService) { + this.parentComponent = parentComponent; + this.textComponent = textComponent; + this.translationService = translationService; + } + + public Component getComponent() { + return parentComponent; + } + + public String getContent() { + return origContent; + } + + public boolean isTranslated() { + return translate; + } + + private boolean setPanelContent(String content) { + return tryHandle(() -> { + textComponent.setText(content == null ? "" : content); + }, "There was an error in setting up the text for MessageContentViewer text panel"); + + } + + @NbBundle.Messages("TextTranslatableComponent.setPanelContent.onSetContentError=Unable to display text at this time.") + private String onErr(boolean success) { + return (success) ? null : Bundle.MessageContentViewer_initTextPane_onError(); + } + + public String setContent(String content) { + this.origContent = content; + this.translated = null; + this.translate = false; + return onErr(setPanelContent(content)); + } + + @NbBundle.Messages("TextTranslatableComponent.setTranslated.onTranslateError=Unable to translate text at this time.") + public String setTranslated(boolean translate) { + this.translate = translate; + if (this.translate) { + if (this.translated == null) { + try { + this.translated = this.translationService.translate(this.origContent); + } catch (NoServiceProviderException | TranslationException ex) { + LOGGER.log(Level.WARNING, "Unable to translate text with translation service", ex); + return Bundle.TextTranslatableComponent_setTranslated_onTranslateError(); + } + } + return onErr(setPanelContent(this.translated == null ? "" : this.translated)); + } + else { + return onErr(setPanelContent(this.origContent)); + } + } + } + + private static final long serialVersionUID = 1L; private static final Logger LOGGER = Logger.getLogger(MessageContentViewer.class.getName()); private static final BlackboardAttribute.Type TSK_ASSOCIATED_TYPE = new BlackboardAttribute.Type(TSK_ASSOCIATED_ARTIFACT); @@ -94,8 +199,12 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont private static final int RTF_TAB_INDEX = 3; private static final int ATTM_TAB_INDEX = 4; + + + private final List textAreas; private final org.sleuthkit.autopsy.contentviewers.HtmlPanel htmlPanel = new org.sleuthkit.autopsy.contentviewers.HtmlPanel(); + private final TranslatablePanel textPanel = new TranslatablePanel(new TextTranslatableComponent()); /** * Artifact currently being displayed */ @@ -113,13 +222,21 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont envelopePanel.setBackground(new Color(0, 0, 0, 38)); drp = DataResultPanel.createInstanceUninitialized(Bundle.MessageContentViewer_AtrachmentsPanel_title(), "", new TableFilterNode(Node.EMPTY, false), 0, null); attachmentsScrollPane.setViewportView(drp); + + msgbodyTabbedPane.insertTab( + NbBundle.getMessage(MessageContentViewer.class, "MessageContentViewer.textbodyScrollPane.TabConstraints.tabTitle"), + null, + textPanel, + null, + TEXT_TAB_INDEX); + msgbodyTabbedPane.setEnabledAt(ATTM_TAB_INDEX, true); /* * HTML tab uses the HtmlPanel instead of an internal text pane, so we * use 'null' for that index. */ - textAreas = Arrays.asList(headersTextArea, textbodyTextArea, null, rtfbodyTextPane); + textAreas = Arrays.asList(headersTextArea, null, null, rtfbodyTextPane); Utilities.configureTextPaneAsRtf(rtfbodyTextPane); resetComponent(); @@ -136,6 +253,7 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont -> viewInNewWindowButton.setEnabled(drpExplorerManager.getSelectedNodes().length == 1)); } + /** * 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 @@ -159,8 +277,6 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont msgbodyTabbedPane = new javax.swing.JTabbedPane(); headersScrollPane = new javax.swing.JScrollPane(); headersTextArea = new javax.swing.JTextArea(); - textbodyScrollPane = new javax.swing.JScrollPane(); - textbodyTextArea = new javax.swing.JTextArea(); htmlPane = new javax.swing.JPanel(); rtfbodyScrollPane = new javax.swing.JScrollPane(); rtfbodyTextPane = new javax.swing.JTextPane(); @@ -263,17 +379,6 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont msgbodyTabbedPane.addTab(org.openide.util.NbBundle.getMessage(MessageContentViewer.class, "MessageContentViewer.headersScrollPane.TabConstraints.tabTitle"), headersScrollPane); // NOI18N - textbodyScrollPane.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); - textbodyScrollPane.setVerticalScrollBarPolicy(javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS); - - textbodyTextArea.setEditable(false); - textbodyTextArea.setLineWrap(true); - textbodyTextArea.setRows(5); - textbodyTextArea.setWrapStyleWord(true); - textbodyScrollPane.setViewportView(textbodyTextArea); - - msgbodyTabbedPane.addTab(org.openide.util.NbBundle.getMessage(MessageContentViewer.class, "MessageContentViewer.textbodyScrollPane.TabConstraints.tabTitle"), textbodyScrollPane); // NOI18N - htmlPane.setLayout(new java.awt.BorderLayout()); msgbodyTabbedPane.addTab(org.openide.util.NbBundle.getMessage(MessageContentViewer.class, "MessageContentViewer.htmlPane.TabConstraints.tabTitle"), htmlPane); // NOI18N @@ -335,6 +440,8 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont .addComponent(msgbodyTabbedPane) .addGap(5, 5, 5)) ); + + msgbodyTabbedPane.getAccessibleContext().setAccessibleParent(null); }// //GEN-END:initComponents private void viewInNewWindowButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_viewInNewWindowButtonActionPerformed @@ -360,8 +467,6 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont private javax.swing.JTextPane rtfbodyTextPane; private javax.swing.JLabel subjectLabel; private javax.swing.JLabel subjectText; - private javax.swing.JScrollPane textbodyScrollPane; - private javax.swing.JTextArea textbodyTextArea; private javax.swing.JLabel toLabel; private javax.swing.JLabel toText; private javax.swing.JButton viewInNewWindowButton; @@ -462,7 +567,7 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont headersTextArea.setText(""); rtfbodyTextPane.setText(""); htmlPanel.reset(); - textbodyTextArea.setText(""); + textPanel.reset(); msgbodyTabbedPane.setEnabled(false); drp.setNode(null); } @@ -570,6 +675,8 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont if (index == HTML_TAB_INDEX && StringUtils.isNotBlank(attributeText)) { htmlPanel.setHtmlText(attributeText); + } else if (index == TEXT_TAB_INDEX && StringUtils.isNotBlank(attributeText)) { + textPanel.setContent(attributeText); } else { JTextComponent textComponent = textAreas.get(index); if (textComponent != null) { diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/TranslatablePanel.form b/Core/src/org/sleuthkit/autopsy/contentviewers/TranslatablePanel.form index ad82eb8e67..2ac835e4e3 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/TranslatablePanel.form +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/TranslatablePanel.form @@ -51,7 +51,7 @@ - + @@ -63,8 +63,11 @@ + + + - + diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/TranslatablePanel.java b/Core/src/org/sleuthkit/autopsy/contentviewers/TranslatablePanel.java index 2746c68b6b..9d3ef27a4e 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/TranslatablePanel.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/TranslatablePanel.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"); @@ -18,56 +18,137 @@ */ package org.sleuthkit.autopsy.contentviewers; +import java.awt.Component; import org.apache.commons.lang.StringUtils; -import org.openide.util.NbBundle; import javax.swing.JPanel; +import javax.swing.SwingUtilities; +import org.openide.util.NbBundle.Messages; /** - * A JPanel used by TranslatedContentViewer to display machine translation of - * text. + * A panel for translation with a subcomponent that allows for translation */ -@SuppressWarnings("PMD.SingularField") // UI widgets cause lots of false positives final class TranslatablePanel extends JPanel { - private static final long serialVersionUID = 1L; - private int lastSelectedIndex = 0; - private final TranslatableJPanel contentPanel; - private final String origOptionText; - private final String translatedOptionText; - - static abstract class TranslatableJPanel extends JPanel { - protected abstract String onTranslateChange(boolean translate); + /** + * an option in drop down of whether or not to translate + */ + private class TranslateOption { + private final String text; + private final boolean translate; + + public TranslateOption(String text, boolean translate) { + this.text = text; + this.translate = translate; + } + + public String getText() { + return text; + } + + @Override + public String toString() { + return text; + } + + public boolean shouldTranslate() { + return translate; + } } + + /** + * describes a component that will allow for translation that has String-based content + */ + interface TranslatableComponent { + /** + * @return the underlying component to be added to TranslatablePanel as a parent + */ + Component getComponent(); + + + /** + * set the content for this subcomponent + * @param content the original content for the component; when this is reset, there is no translation initially + * @return if non-null string, this string will appear as error message + */ + String setContent(String content); + String getContent(); + + + /** + * sets the state of this component to translated + * @param translate whether or not to translate this component + * @return if non-null string, this string will appear as error message + */ + String setTranslated(boolean translate); + boolean isTranslated(); + } + + + + private static final long serialVersionUID = 1L; + + private final TranslatableComponent subcomponent; + private final String origOptionText; + private final String translatedOptionText; + + + @Messages({"TranslatablePanel.comboBoxOption.originalText=Original Text", + "TranslatablePanel.comboBoxOption.translatedText=Translated Text"}) + TranslatablePanel(TranslatableComponent subcomponent) { + this( + subcomponent, + Bundle.TranslatablePanel_comboBoxOption_originalText(), + Bundle.TranslatablePanel_comboBoxOption_translatedText(), + null); + } + /** * Creates new form TranslatedContentPanel */ - TranslatablePanel(TranslatableJPanel contentPanel, String origOptionText, String translatedOptionText) { - this.contentPanel = contentPanel; + TranslatablePanel(TranslatableComponent subcomponent, String origOptionText, String translatedOptionText, String origContent) { + this.subcomponent = subcomponent; this.origOptionText = origOptionText; this.translatedOptionText = translatedOptionText; initComponents(); - add(this.contentPanel, java.awt.BorderLayout.CENTER); - reset(); - + additionalInit(origContent); } - void setWarningLabelMsg(String msg) { + + private void setWarningLabelMsg(String msg) { warningLabel.setText(msg); warningLabel.setVisible(StringUtils.isEmpty(msg)); } -// @Messages({"TranslatedContentPanel.comboBoxOption.originalText=Original Text (Up to 25KB)", -// "TranslatedContentPanel.comboBoxOption.translatedText=Translated Text"}) + void reset() { + setContent(null); + } + + void setContent(String content) { + this.translateComboBox.setSelectedIndex(0); + SwingUtilities.invokeLater(() -> { + String errMess = this.subcomponent.setContent(content); + setWarningLabelMsg(errMess); + }); + } - - //@NbBundle.Messages({"TranslationContentPanel.autoDetectOCR=Autodetect language"}) - final void reset() { + + + private void additionalInit(String origContent) { + add(this.subcomponent.getComponent(), java.awt.BorderLayout.CENTER); setWarningLabelMsg(null); - displayTextComboBox.removeAllItems(); - displayTextComboBox.addItem(this.origOptionText); - displayTextComboBox.addItem(this.translatedOptionText); + translateComboBox.removeAllItems(); + translateComboBox.addItem(new TranslateOption(this.origOptionText, false)); + translateComboBox.addItem(new TranslateOption(this.translatedOptionText, true)); + this.subcomponent.setContent(origContent); + } + + private void handleComboBoxChange(TranslateOption translateOption) { + SwingUtilities.invokeLater(() -> { + String errMess = this.subcomponent.setTranslated(translateOption.shouldTranslate()); + setWarningLabelMsg(errMess); + }); } @@ -82,7 +163,7 @@ final class TranslatablePanel extends JPanel { java.awt.GridBagConstraints gridBagConstraints; jPanel1 = new javax.swing.JPanel(); - displayTextComboBox = new javax.swing.JComboBox<>(); + translateComboBox = new javax.swing.JComboBox<>(); warningLabel = new javax.swing.JLabel(); showLabel = new javax.swing.JLabel(); @@ -98,8 +179,13 @@ final class TranslatablePanel extends JPanel { jPanel1.setPreferredSize(new java.awt.Dimension(182, 24)); jPanel1.setLayout(new java.awt.GridBagLayout()); - displayTextComboBox.setMinimumSize(new java.awt.Dimension(43, 20)); - displayTextComboBox.setPreferredSize(new java.awt.Dimension(43, 20)); + translateComboBox.setMinimumSize(new java.awt.Dimension(43, 20)); + translateComboBox.setPreferredSize(new java.awt.Dimension(43, 20)); + translateComboBox.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + translateComboBoxActionPerformed(evt); + } + }); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 3; gridBagConstraints.gridy = 0; @@ -107,7 +193,7 @@ final class TranslatablePanel extends JPanel { gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST; gridBagConstraints.weightx = 0.1; gridBagConstraints.insets = new java.awt.Insets(0, 5, 0, 0); - jPanel1.add(displayTextComboBox, gridBagConstraints); + jPanel1.add(translateComboBox, gridBagConstraints); warningLabel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/images/warning16.png"))); // NOI18N gridBagConstraints = new java.awt.GridBagConstraints(); @@ -127,10 +213,14 @@ final class TranslatablePanel extends JPanel { add(jPanel1, java.awt.BorderLayout.NORTH); }// //GEN-END:initComponents + private void translateComboBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_translateComboBoxActionPerformed + handleComboBoxChange((TranslateOption) translateComboBox.getSelectedItem()); + }//GEN-LAST:event_translateComboBoxActionPerformed + // Variables declaration - do not modify//GEN-BEGIN:variables - private javax.swing.JComboBox displayTextComboBox; private javax.swing.JPanel jPanel1; private javax.swing.JLabel showLabel; + private javax.swing.JComboBox translateComboBox; private javax.swing.JLabel warningLabel; // End of variables declaration//GEN-END:variables } \ No newline at end of file From af82f8df4930cb2c65b1a48fa4ce94785267a661 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Wed, 4 Mar 2020 11:19:08 -0500 Subject: [PATCH 22/97] fix for bundle bug --- .../autopsy/actions/Bundle.properties-MERGED | 14 ---------- .../casemodule/Bundle.properties-MERGED | 28 ++++++------------- .../datamodel/Bundle.properties-MERGED | 2 +- .../Bundle.properties-MERGED | 11 -------- .../contentviewers/Bundle.properties-MERGED | 5 +++- .../contentviewers/MessageContentViewer.java | 2 +- .../datamodel/Bundle.properties-MERGED | 9 +++--- .../Bundle.properties-MERGED | 1 - .../interestingitems/Bundle.properties-MERGED | 1 - .../recentactivity/Bundle.properties-MERGED | 11 ++------ .../netbeans/core/startup/Bundle.properties | 4 +-- .../core/windows/view/ui/Bundle.properties | 6 ++-- 12 files changed, 26 insertions(+), 68 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/actions/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/actions/Bundle.properties-MERGED index a3a13c0cff..66af0efc85 100755 --- a/Core/src/org/sleuthkit/autopsy/actions/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/actions/Bundle.properties-MERGED @@ -1,35 +1,25 @@ AddBlackboardArtifactTagAction.pluralTagResult=Add Result Tags AddBlackboardArtifactTagAction.singularTagResult=Add Result Tag AddBlackboardArtifactTagAction.taggingErr=Tagging Error -# {0} - artifactName AddBlackboardArtifactTagAction.unableToTag.msg=Unable to tag {0}. AddContentTagAction.cannotApplyTagErr=Cannot Apply Tag AddContentTagAction.pluralTagFile=Add File Tags AddContentTagAction.singularTagFile=Add File Tag -# {0} - fileName -# {1} - tagName AddContentTagAction.tagExists={0} has been tagged as {1}. Cannot reapply the same tag. AddContentTagAction.taggingErr=Tagging Error -# {0} - fileName AddContentTagAction.unableToTag.msg=Unable to tag {0}, not a regular file. -# {0} - fileName AddContentTagAction.unableToTag.msg2=Unable to tag {0}. CTL_ShowIngestProgressSnapshotAction=Ingest Status Details DeleteBlackboardArtifactTagAction.deleteTag=Remove Selected Tag(s) DeleteBlackboardArtifactTagAction.tagDelErr=Tag Deletion Error -# {0} - tagName DeleteBlackboardArtifactTagAction.unableToDelTag.msg=Unable to delete tag {0}. DeleteContentTagAction.deleteTag=Remove Selected Tag(s) DeleteContentTagAction.tagDelErr=Tag Deletion Error -# {0} - tagName DeleteContentTagAction.unableToDelTag.msg=Unable to delete tag {0}. DeleteFileBlackboardArtifactTagAction.deleteTag=Remove Result Tag -# {0} - artifactID DeleteFileBlackboardArtifactTagAction.deleteTag.alert=Unable to untag artifact {0}. -# {0} - artifactID DeleteFileBlackboardArtifactTagAction.deleteTags.alert=Unable to untag artifact {0}. DeleteFileContentTagAction.deleteTag=Remove File Tag -# {0} - fileID DeleteFileContentTagAction.deleteTag.alert=Unable to untag file {0}. ExitAction.confirmationDialog.message=Ingest is running, are you sure you want to exit? ExitAction.confirmationDialog.title=Ingest is Running @@ -83,11 +73,7 @@ CTL_OpenOutputFolder=Open Case Folder OpenOutputFolder.error1=Case Folder Not Found: {0} OpenOutputFolder.noCaseOpen=No open case, therefore no current case folder available. OpenOutputFolder.CouldNotOpenOutputFolder=Could not open case folder -# {0} - old tag name -# {1} - artifactID ReplaceBlackboardArtifactTagAction.replaceTag.alert=Unable to replace tag {0} for artifact {1}. -# {0} - old tag name -# {1} - content obj id ReplaceContentTagAction.replaceTag.alert=Unable to replace tag {0} for {1}. ReplaceTagAction.replaceTag=Replace Selected Tag(s) With ShowIngestProgressSnapshotAction.actionName.text=Get Ingest Progress Snapshot diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/casemodule/Bundle.properties-MERGED index b56e46b377..a4939004e8 100755 --- a/Core/src/org/sleuthkit/autopsy/casemodule/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/casemodule/Bundle.properties-MERGED @@ -5,7 +5,6 @@ Case.closeException.couldNotCloseCase=Error closing case: {0} Case.creationException.couldNotAcquireResourcesLock=Failed to get lock on case resources Case.deleteCaseConfirmationDialog.message=Are you sure you want to close and delete the current case? Case.deleteCaseConfirmationDialog.title=Delete Current Case? -# {0} - exception message Case.deleteCaseFailureMessageBox.message=Error deleting case: {0} Case.deleteCaseFailureMessageBox.title=Failed to Delete Case Case.exceptionMessage.cancelled=Cancelled. @@ -242,15 +241,10 @@ AddImageWizardIngestConfigPanel.dsProcDone.errs.text=*Errors encountered in addi AddImageWizardIngestConfigVisual.getName.text=Configure Ingest Modules AddImageWizardIterator.stepXofN=Step {0} of {1} AddLocalFilesTask.localFileAdd.progress.text=Adding: {0}/{1} -Case.getCurCase.exception.noneOpen=Cannot get the current case; there is no case open\! +Case.getCurCase.exception.noneOpen=Cannot get the current case; there is no case open! Case.open.msgDlg.updated.msg=Updated case database schema.\nA backup copy of the database with the following path has been made:\n {0} Case.open.msgDlg.updated.title=Case Database Schema Update -Case.checkImgExist.confDlg.doesntExist.msg=One of the images associated with \n\ -this case are missing. Would you like to search for them now?\n\ -Previously, the image was located at:\n\ -{0}\n\ -Please note that you will still be able to browse directories and generate reports\n\ -if you choose No, but you will not be able to view file content or run the ingest process. +Case.checkImgExist.confDlg.doesntExist.msg=One of the images associated with \nthis case are missing. Would you like to search for them now?\nPreviously, the image was located at:\n{0}\nPlease note that you will still be able to browse directories and generate reports\nif you choose No, but you will not be able to view file content or run the ingest process. Case.checkImgExist.confDlg.doesntExist.title=Missing Image Case.addImg.exception.msg=Error adding image to the case Case.updateCaseName.exception.msg=Error while trying to update the case name. @@ -269,12 +263,9 @@ Case.GetCaseTypeGivenPath.Failure=Unable to get case type Case.metaDataFileCorrupt.exception.msg=The case metadata file (.aut) is corrupted. Case.deleteReports.deleteFromDiskException.log.msg=Unable to delete the report from the disk. Case.deleteReports.deleteFromDiskException.msg=Unable to delete the report {0} from the disk.\nYou may manually delete it from {1} -CaseDeleteAction.closeConfMsg.text=Are you sure want to close and delete this case? \n\ - Case Name: {0}\n\ - Case Directory: {1} +CaseDeleteAction.closeConfMsg.text=Are you sure want to close and delete this case? \nCase Name: {0}\nCase Directory: {1} CaseDeleteAction.closeConfMsg.title=Warning: Closing the Current Case -CaseDeleteAction.msgDlg.fileInUse.msg=The delete action cannot be fully completed because the folder or file in it is open by another program.\n\n\ -Close the folder and file and try again or you can delete the case manually. +CaseDeleteAction.msgDlg.fileInUse.msg=The delete action cannot be fully completed because the folder or file in it is open by another program.\n\nClose the folder and file and try again or you can delete the case manually. CaseDeleteAction.msgDlg.fileInUse.title=Error: Folder In Use CaseDeleteAction.msgDlg.caseDelete.msg=Case {0} has been deleted. CaseOpenAction.autFilter.title={0} Case File ( {1}) @@ -306,8 +297,7 @@ NewCaseWizardAction.databaseProblem1.text=Cannot open database. Cancelling case NewCaseWizardAction.databaseProblem2.text=Error NewCaseWizardPanel1.validate.errMsg.invalidSymbols=The Case Name cannot contain any of the following symbols: \\ / : * ? " < > | NewCaseWizardPanel1.validate.errMsg.dirExists=Case directory ''{0}'' already exists. -NewCaseWizardPanel1.validate.confMsg.createDir.msg=The base directory "{0}" does not exist. \n\n\ - Do you want to create that directory? +NewCaseWizardPanel1.validate.confMsg.createDir.msg=The base directory "{0}" does not exist. \n\nDo you want to create that directory? NewCaseWizardPanel1.validate.confMsg.createDir.title=Create directory NewCaseWizardPanel1.validate.errMsg.cantCreateParDir.msg=Error: Could not create case parent directory {0} NewCaseWizardPanel1.validate.errMsg.prevCreateBaseDir.msg=Prevented from creating base directory {0} @@ -336,14 +326,12 @@ OptionalCasePropertiesPanel.lbPointOfContactPhoneLabel.text=Phone: OptionalCasePropertiesPanel.orgainizationPanel.border.title=Organization RecentCases.exception.caseIdxOutOfRange.msg=Recent case index {0} is out of range. RecentCases.getName.text=Clear Recent Cases -# {0} - case name RecentItems.openRecentCase.msgDlg.text=Case {0} no longer exists. SelectDataSourceProcessorPanel.name.text=Select Type of Data Source To Add StartupWindow.title.text=Welcome UnpackagePortableCaseDialog.title.text=Unpackage Portable Case UnpackagePortableCaseDialog.UnpackagePortableCaseDialog.extensions=Portable case package (.zip, .zip.001) UnpackagePortableCaseDialog.validatePaths.badExtension=File extension must be .zip or .zip.001 -# {0} - case folder UnpackagePortableCaseDialog.validatePaths.caseFolderExists=Folder {0} already exists UnpackagePortableCaseDialog.validatePaths.caseIsNotFile=Selected path is not a file UnpackagePortableCaseDialog.validatePaths.caseNotFound=File does not exist @@ -358,15 +346,15 @@ UnpackageWorker.doInBackground.previouslySeenCase=Case has been previously opene UpdateRecentCases.menuItem.clearRecentCases.text=Clear Recent Cases UpdateRecentCases.menuItem.empty=-Empty- AddImageWizardIngestConfigPanel.CANCEL_BUTTON.text=Cancel -NewCaseVisualPanel1.CaseFolderOnCDriveError.text=Warning: Path to multi-user case folder is on \"C:\" drive -NewCaseVisualPanel1.CaseFolderOnInternalDriveWindowsError.text=Warning: Path to case folder is on \"C:\" drive. Case folder is created on the target system +NewCaseVisualPanel1.CaseFolderOnCDriveError.text=Warning: Path to multi-user case folder is on "C:" drive +NewCaseVisualPanel1.CaseFolderOnInternalDriveWindowsError.text=Warning: Path to case folder is on "C:" drive. Case folder is created on the target system NewCaseVisualPanel1.CaseFolderOnInternalDriveLinuxError.text=Warning: Path to case folder is on the target system. Create case folder in mounted drive. CollaborationMonitor.addingDataSourceStatus.msg={0} adding data source CollaborationMonitor.analyzingDataSourceStatus.msg={0} analyzing {1} MissingImageDialog.lbWarning.text= MissingImageDialog.lbWarning.toolTipText= NewCaseVisualPanel1.caseParentDirWarningLabel.text= -NewCaseVisualPanel1.multiUserCaseRadioButton.text=Multi-user +NewCaseVisualPanel1.multiUserCaseRadioButton.text=Multi-user\t\t NewCaseVisualPanel1.singleUserCaseRadioButton.text=Single-user NewCaseVisualPanel1.caseTypeLabel.text=Case Type: SingleUserCaseConverter.BadDatabaseFileName=Database file does not exist! 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..dbd40688b1 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/Bundle.properties-MERGED @@ -9,6 +9,7 @@ AbstractSqlEamDb.failedToReadMinorVersion.message=Failed to read schema minor ve 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. 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 +24,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/commonpropertiessearch/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/commonpropertiessearch/Bundle.properties-MERGED index d164529639..9cd17f566f 100755 --- a/Core/src/org/sleuthkit/autopsy/commonpropertiessearch/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/commonpropertiessearch/Bundle.properties-MERGED @@ -1,13 +1,8 @@ AbstractCommonFilesMetadataBuilder.buildCategorySelectionString.all=All File Categories AbstractCommonFilesMetadataBuilder.buildCategorySelectionString.doc=Documents AbstractCommonFilesMetadataBuilder.buildCategorySelectionString.media=Media -# {0} - threshold percent AbstractCommonFilesMetadataBuilder.getPercentFilter.thresholdPercent=, Threshold {0}% -# {0} - attr type -# {1} - threshold string AllInterCaseCommonAttributeSearcher.buildTabTitle.titleInterAll=Common Properties (All Central Repository Cases, {0}{1}) -# {0} - build category -# {1} - threshold string AllIntraCaseCommonAttributeSearcher.buildTabTitle.titleIntraAll=Common Properties (All Data Sources, {0}{1}) # {0} - number of datasources CommonAttributePanel.dataSourcesLabel.text=The current Central Repository contains {0} data source(s). @@ -103,13 +98,7 @@ CommonAttributePanel.organizeByCountRadio.text=Number of occurrences CommonAttributePanel.caseResultsRadioButton.text=Case CommonAttributePanel.countResultsRadioButton.text=Number of data sources CommonAttributePanel.displayResultsLabel.text_2=Display results organized by: -# {0} - case name -# {1} - attr type -# {2} - threshold string SingleInterCaseCommonAttributeSearcher.buildTabTitle.titleInterSingle=Common Properties (Central Repository Case: {0}, {1}{2}) -# {0} - data source name -# {1} - build category -# {2} - threshold string SingleIntraCaseCommonAttributeSearcher.buildTabTitle.titleIntraSingle=Common Properties (Data Source: {0}, {1}{2}) UserInputErrorManager.categories=No file categories are included in the search. UserInputErrorManager.frequency=Invalid Frequency Percentage: 0 < % < 100. diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/contentviewers/Bundle.properties-MERGED index 13f3ef0710..bf230f3c10 100755 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/Bundle.properties-MERGED @@ -95,7 +95,6 @@ Metadata.nodeText.text=From The Sleuth Kit istat Tool: Metadata.nodeText.exceptionNotice.text=Error getting file metadata: MessageContentViewer.rtfbodyScrollPane.TabConstraints.tabTitle=RTF MessageContentViewer.headersScrollPane.TabConstraints.tabTitle=Headers -MessageContentViewer.textbodyScrollPane.TabConstraints.tabTitle=Text MessageContentViewer.htmlPane.TabConstraints.tabTitle=HTML MessageContentViewer.fromText.text=from address goes here MessageContentViewer.fromLabel.text=From: @@ -168,3 +167,7 @@ MediaPlayerPanel.playBackSpeedLabel.text=Speed: SQLiteViewer.readTable.errorText=Error getting rows for table: {0} # {0} - tableName SQLiteViewer.selectTable.errorText=Error getting row count for table: {0} +TextTranslatableComponent.setPanelContent.onSetContentError=Unable to display text at this time. +TextTranslatableComponent.setTranslated.onTranslateError=Unable to translate text at this time. +TranslatablePanel.comboBoxOption.originalText=Original Text +TranslatablePanel.comboBoxOption.translatedText=Translated Text diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java b/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java index 1380299920..0f92181d69 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java @@ -158,7 +158,7 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont @NbBundle.Messages("TextTranslatableComponent.setPanelContent.onSetContentError=Unable to display text at this time.") private String onErr(boolean success) { - return (success) ? null : Bundle.MessageContentViewer_initTextPane_onError(); + return (success) ? null : Bundle.TextTranslatableComponent_setPanelContent_onSetContentError(); } public String setContent(String content) { diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/datamodel/Bundle.properties-MERGED index 9ac85bd1e7..f1507f0380 100755 --- a/Core/src/org/sleuthkit/autopsy/datamodel/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/datamodel/Bundle.properties-MERGED @@ -47,7 +47,6 @@ AttachmentNode.getActions.openInExtViewer.text=Open in External Viewer Ctrl+E AttachmentNode.getActions.searchFilesSameMD5.text=Search for files with the same MD5 hash AttachmentNode.getActions.viewFileInDir.text=View File in Directory AttachmentNode.getActions.viewInNewWin.text=View in New Window -# {0} - node name BaseChildFactory.NoSuchEventBusException.message=No event bus for node: {0} BlackboardArtifactNode.createSheet.artifactDetails.displayName=Result Details BlackboardArtifactNode.createSheet.artifactDetails.name=Result Details @@ -268,10 +267,10 @@ ImageNode.getActions.viewInNewWin.text=View in New Window ImageNode.createSheet.name.name=Name ImageNode.createSheet.name.displayName=Name ImageNode.createSheet.name.desc=no description -Installer.exception.tskVerStringNull.msg=Sleuth Kit JNI test call returned without error, but version string was null\! -Installer.exception.taskVerStringBang.msg=Sleuth Kit JNI test call returned without error, but version string was ""\! -Installer.tskLibErr.msg=Problem with Sleuth Kit JNI. Test call failed\!\n\nDetails: {0} -Installer.tskLibErr.err=Fatal Error\! +Installer.exception.tskVerStringNull.msg=Sleuth Kit JNI test call returned without error, but version string was null! +Installer.exception.taskVerStringBang.msg=Sleuth Kit JNI test call returned without error, but version string was ""! +Installer.tskLibErr.msg=Problem with Sleuth Kit JNI. Test call failed!\n\nDetails: {0} +Installer.tskLibErr.err=Fatal Error! InterestingHits.interestingItems.text=INTERESTING ITEMS InterestingHits.displayName.text=Interesting Items InterestingHits.createSheet.name.name=Name 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..5c0cdd1277 100755 --- a/Core/src/org/sleuthkit/autopsy/modules/embeddedfileextractor/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/modules/embeddedfileextractor/Bundle.properties-MERGED @@ -23,7 +23,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/interestingitems/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties-MERGED index 31a0690b82..e63c1878ac 100755 --- a/Core/src/org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties-MERGED @@ -2,7 +2,6 @@ FilesIdentifierIngestJobSettingsPanel.getError=Error getting interesting files s FilesIdentifierIngestJobSettingsPanel.updateError=Error updating interesting files sets settings file. FilesIdentifierIngestModule.getFilesError=Error getting interesting files sets from file. FilesIdentifierIngestModule.indexError.message=Failed to index interesting file hit artifact for keyword search. -# {0} - daysIncluded FilesSet.rule.dateRule.toString=(modified within {0} day(s)) FilesSetDefsPanel.bytes=Bytes FilesSetDefsPanel.cancelImportMsg=Cancel import 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..02435933ad 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 +#Wed, 04 Mar 2020 11:04:14 -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..b538422219 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 +#Wed, 04 Mar 2020 11:04:14 -0500 +CTL_MainWindow_Title=Autopsy 4.14.0 +CTL_MainWindow_Title_No_Project=Autopsy 4.14.0 From 0559bcc40d8a3890fab819b57784514f190ded3f Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Wed, 4 Mar 2020 11:21:14 -0500 Subject: [PATCH 23/97] revert bundle items --- .../autopsy/actions/Bundle.properties-MERGED | 14 ++++++++++ .../casemodule/Bundle.properties-MERGED | 28 +++++++++++++------ .../datamodel/Bundle.properties-MERGED | 2 +- .../Bundle.properties-MERGED | 11 ++++++++ .../datamodel/Bundle.properties-MERGED | 9 +++--- .../Bundle.properties-MERGED | 1 + .../interestingitems/Bundle.properties-MERGED | 1 + .../recentactivity/Bundle.properties-MERGED | 11 ++++++-- .../netbeans/core/startup/Bundle.properties | 4 +-- .../core/windows/view/ui/Bundle.properties | 6 ++-- 10 files changed, 66 insertions(+), 21 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/actions/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/actions/Bundle.properties-MERGED index 66af0efc85..a3a13c0cff 100755 --- a/Core/src/org/sleuthkit/autopsy/actions/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/actions/Bundle.properties-MERGED @@ -1,25 +1,35 @@ AddBlackboardArtifactTagAction.pluralTagResult=Add Result Tags AddBlackboardArtifactTagAction.singularTagResult=Add Result Tag AddBlackboardArtifactTagAction.taggingErr=Tagging Error +# {0} - artifactName AddBlackboardArtifactTagAction.unableToTag.msg=Unable to tag {0}. AddContentTagAction.cannotApplyTagErr=Cannot Apply Tag AddContentTagAction.pluralTagFile=Add File Tags AddContentTagAction.singularTagFile=Add File Tag +# {0} - fileName +# {1} - tagName AddContentTagAction.tagExists={0} has been tagged as {1}. Cannot reapply the same tag. AddContentTagAction.taggingErr=Tagging Error +# {0} - fileName AddContentTagAction.unableToTag.msg=Unable to tag {0}, not a regular file. +# {0} - fileName AddContentTagAction.unableToTag.msg2=Unable to tag {0}. CTL_ShowIngestProgressSnapshotAction=Ingest Status Details DeleteBlackboardArtifactTagAction.deleteTag=Remove Selected Tag(s) DeleteBlackboardArtifactTagAction.tagDelErr=Tag Deletion Error +# {0} - tagName DeleteBlackboardArtifactTagAction.unableToDelTag.msg=Unable to delete tag {0}. DeleteContentTagAction.deleteTag=Remove Selected Tag(s) DeleteContentTagAction.tagDelErr=Tag Deletion Error +# {0} - tagName DeleteContentTagAction.unableToDelTag.msg=Unable to delete tag {0}. DeleteFileBlackboardArtifactTagAction.deleteTag=Remove Result Tag +# {0} - artifactID DeleteFileBlackboardArtifactTagAction.deleteTag.alert=Unable to untag artifact {0}. +# {0} - artifactID DeleteFileBlackboardArtifactTagAction.deleteTags.alert=Unable to untag artifact {0}. DeleteFileContentTagAction.deleteTag=Remove File Tag +# {0} - fileID DeleteFileContentTagAction.deleteTag.alert=Unable to untag file {0}. ExitAction.confirmationDialog.message=Ingest is running, are you sure you want to exit? ExitAction.confirmationDialog.title=Ingest is Running @@ -73,7 +83,11 @@ CTL_OpenOutputFolder=Open Case Folder OpenOutputFolder.error1=Case Folder Not Found: {0} OpenOutputFolder.noCaseOpen=No open case, therefore no current case folder available. OpenOutputFolder.CouldNotOpenOutputFolder=Could not open case folder +# {0} - old tag name +# {1} - artifactID ReplaceBlackboardArtifactTagAction.replaceTag.alert=Unable to replace tag {0} for artifact {1}. +# {0} - old tag name +# {1} - content obj id ReplaceContentTagAction.replaceTag.alert=Unable to replace tag {0} for {1}. ReplaceTagAction.replaceTag=Replace Selected Tag(s) With ShowIngestProgressSnapshotAction.actionName.text=Get Ingest Progress Snapshot diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/casemodule/Bundle.properties-MERGED index a4939004e8..b56e46b377 100755 --- a/Core/src/org/sleuthkit/autopsy/casemodule/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/casemodule/Bundle.properties-MERGED @@ -5,6 +5,7 @@ Case.closeException.couldNotCloseCase=Error closing case: {0} Case.creationException.couldNotAcquireResourcesLock=Failed to get lock on case resources Case.deleteCaseConfirmationDialog.message=Are you sure you want to close and delete the current case? Case.deleteCaseConfirmationDialog.title=Delete Current Case? +# {0} - exception message Case.deleteCaseFailureMessageBox.message=Error deleting case: {0} Case.deleteCaseFailureMessageBox.title=Failed to Delete Case Case.exceptionMessage.cancelled=Cancelled. @@ -241,10 +242,15 @@ AddImageWizardIngestConfigPanel.dsProcDone.errs.text=*Errors encountered in addi AddImageWizardIngestConfigVisual.getName.text=Configure Ingest Modules AddImageWizardIterator.stepXofN=Step {0} of {1} AddLocalFilesTask.localFileAdd.progress.text=Adding: {0}/{1} -Case.getCurCase.exception.noneOpen=Cannot get the current case; there is no case open! +Case.getCurCase.exception.noneOpen=Cannot get the current case; there is no case open\! Case.open.msgDlg.updated.msg=Updated case database schema.\nA backup copy of the database with the following path has been made:\n {0} Case.open.msgDlg.updated.title=Case Database Schema Update -Case.checkImgExist.confDlg.doesntExist.msg=One of the images associated with \nthis case are missing. Would you like to search for them now?\nPreviously, the image was located at:\n{0}\nPlease note that you will still be able to browse directories and generate reports\nif you choose No, but you will not be able to view file content or run the ingest process. +Case.checkImgExist.confDlg.doesntExist.msg=One of the images associated with \n\ +this case are missing. Would you like to search for them now?\n\ +Previously, the image was located at:\n\ +{0}\n\ +Please note that you will still be able to browse directories and generate reports\n\ +if you choose No, but you will not be able to view file content or run the ingest process. Case.checkImgExist.confDlg.doesntExist.title=Missing Image Case.addImg.exception.msg=Error adding image to the case Case.updateCaseName.exception.msg=Error while trying to update the case name. @@ -263,9 +269,12 @@ Case.GetCaseTypeGivenPath.Failure=Unable to get case type Case.metaDataFileCorrupt.exception.msg=The case metadata file (.aut) is corrupted. Case.deleteReports.deleteFromDiskException.log.msg=Unable to delete the report from the disk. Case.deleteReports.deleteFromDiskException.msg=Unable to delete the report {0} from the disk.\nYou may manually delete it from {1} -CaseDeleteAction.closeConfMsg.text=Are you sure want to close and delete this case? \nCase Name: {0}\nCase Directory: {1} +CaseDeleteAction.closeConfMsg.text=Are you sure want to close and delete this case? \n\ + Case Name: {0}\n\ + Case Directory: {1} CaseDeleteAction.closeConfMsg.title=Warning: Closing the Current Case -CaseDeleteAction.msgDlg.fileInUse.msg=The delete action cannot be fully completed because the folder or file in it is open by another program.\n\nClose the folder and file and try again or you can delete the case manually. +CaseDeleteAction.msgDlg.fileInUse.msg=The delete action cannot be fully completed because the folder or file in it is open by another program.\n\n\ +Close the folder and file and try again or you can delete the case manually. CaseDeleteAction.msgDlg.fileInUse.title=Error: Folder In Use CaseDeleteAction.msgDlg.caseDelete.msg=Case {0} has been deleted. CaseOpenAction.autFilter.title={0} Case File ( {1}) @@ -297,7 +306,8 @@ NewCaseWizardAction.databaseProblem1.text=Cannot open database. Cancelling case NewCaseWizardAction.databaseProblem2.text=Error NewCaseWizardPanel1.validate.errMsg.invalidSymbols=The Case Name cannot contain any of the following symbols: \\ / : * ? " < > | NewCaseWizardPanel1.validate.errMsg.dirExists=Case directory ''{0}'' already exists. -NewCaseWizardPanel1.validate.confMsg.createDir.msg=The base directory "{0}" does not exist. \n\nDo you want to create that directory? +NewCaseWizardPanel1.validate.confMsg.createDir.msg=The base directory "{0}" does not exist. \n\n\ + Do you want to create that directory? NewCaseWizardPanel1.validate.confMsg.createDir.title=Create directory NewCaseWizardPanel1.validate.errMsg.cantCreateParDir.msg=Error: Could not create case parent directory {0} NewCaseWizardPanel1.validate.errMsg.prevCreateBaseDir.msg=Prevented from creating base directory {0} @@ -326,12 +336,14 @@ OptionalCasePropertiesPanel.lbPointOfContactPhoneLabel.text=Phone: OptionalCasePropertiesPanel.orgainizationPanel.border.title=Organization RecentCases.exception.caseIdxOutOfRange.msg=Recent case index {0} is out of range. RecentCases.getName.text=Clear Recent Cases +# {0} - case name RecentItems.openRecentCase.msgDlg.text=Case {0} no longer exists. SelectDataSourceProcessorPanel.name.text=Select Type of Data Source To Add StartupWindow.title.text=Welcome UnpackagePortableCaseDialog.title.text=Unpackage Portable Case UnpackagePortableCaseDialog.UnpackagePortableCaseDialog.extensions=Portable case package (.zip, .zip.001) UnpackagePortableCaseDialog.validatePaths.badExtension=File extension must be .zip or .zip.001 +# {0} - case folder UnpackagePortableCaseDialog.validatePaths.caseFolderExists=Folder {0} already exists UnpackagePortableCaseDialog.validatePaths.caseIsNotFile=Selected path is not a file UnpackagePortableCaseDialog.validatePaths.caseNotFound=File does not exist @@ -346,15 +358,15 @@ UnpackageWorker.doInBackground.previouslySeenCase=Case has been previously opene UpdateRecentCases.menuItem.clearRecentCases.text=Clear Recent Cases UpdateRecentCases.menuItem.empty=-Empty- AddImageWizardIngestConfigPanel.CANCEL_BUTTON.text=Cancel -NewCaseVisualPanel1.CaseFolderOnCDriveError.text=Warning: Path to multi-user case folder is on "C:" drive -NewCaseVisualPanel1.CaseFolderOnInternalDriveWindowsError.text=Warning: Path to case folder is on "C:" drive. Case folder is created on the target system +NewCaseVisualPanel1.CaseFolderOnCDriveError.text=Warning: Path to multi-user case folder is on \"C:\" drive +NewCaseVisualPanel1.CaseFolderOnInternalDriveWindowsError.text=Warning: Path to case folder is on \"C:\" drive. Case folder is created on the target system NewCaseVisualPanel1.CaseFolderOnInternalDriveLinuxError.text=Warning: Path to case folder is on the target system. Create case folder in mounted drive. CollaborationMonitor.addingDataSourceStatus.msg={0} adding data source CollaborationMonitor.analyzingDataSourceStatus.msg={0} analyzing {1} MissingImageDialog.lbWarning.text= MissingImageDialog.lbWarning.toolTipText= NewCaseVisualPanel1.caseParentDirWarningLabel.text= -NewCaseVisualPanel1.multiUserCaseRadioButton.text=Multi-user\t\t +NewCaseVisualPanel1.multiUserCaseRadioButton.text=Multi-user NewCaseVisualPanel1.singleUserCaseRadioButton.text=Single-user NewCaseVisualPanel1.caseTypeLabel.text=Case Type: SingleUserCaseConverter.BadDatabaseFileName=Database file does not exist! 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 dbd40688b1..9b43833ee2 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/Bundle.properties-MERGED @@ -9,7 +9,6 @@ AbstractSqlEamDb.failedToReadMinorVersion.message=Failed to read schema minor ve 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. 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 @@ -24,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/commonpropertiessearch/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/commonpropertiessearch/Bundle.properties-MERGED index 9cd17f566f..d164529639 100755 --- a/Core/src/org/sleuthkit/autopsy/commonpropertiessearch/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/commonpropertiessearch/Bundle.properties-MERGED @@ -1,8 +1,13 @@ AbstractCommonFilesMetadataBuilder.buildCategorySelectionString.all=All File Categories AbstractCommonFilesMetadataBuilder.buildCategorySelectionString.doc=Documents AbstractCommonFilesMetadataBuilder.buildCategorySelectionString.media=Media +# {0} - threshold percent AbstractCommonFilesMetadataBuilder.getPercentFilter.thresholdPercent=, Threshold {0}% +# {0} - attr type +# {1} - threshold string AllInterCaseCommonAttributeSearcher.buildTabTitle.titleInterAll=Common Properties (All Central Repository Cases, {0}{1}) +# {0} - build category +# {1} - threshold string AllIntraCaseCommonAttributeSearcher.buildTabTitle.titleIntraAll=Common Properties (All Data Sources, {0}{1}) # {0} - number of datasources CommonAttributePanel.dataSourcesLabel.text=The current Central Repository contains {0} data source(s). @@ -98,7 +103,13 @@ CommonAttributePanel.organizeByCountRadio.text=Number of occurrences CommonAttributePanel.caseResultsRadioButton.text=Case CommonAttributePanel.countResultsRadioButton.text=Number of data sources CommonAttributePanel.displayResultsLabel.text_2=Display results organized by: +# {0} - case name +# {1} - attr type +# {2} - threshold string SingleInterCaseCommonAttributeSearcher.buildTabTitle.titleInterSingle=Common Properties (Central Repository Case: {0}, {1}{2}) +# {0} - data source name +# {1} - build category +# {2} - threshold string SingleIntraCaseCommonAttributeSearcher.buildTabTitle.titleIntraSingle=Common Properties (Data Source: {0}, {1}{2}) UserInputErrorManager.categories=No file categories are included in the search. UserInputErrorManager.frequency=Invalid Frequency Percentage: 0 < % < 100. diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/datamodel/Bundle.properties-MERGED index f1507f0380..9ac85bd1e7 100755 --- a/Core/src/org/sleuthkit/autopsy/datamodel/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/datamodel/Bundle.properties-MERGED @@ -47,6 +47,7 @@ AttachmentNode.getActions.openInExtViewer.text=Open in External Viewer Ctrl+E AttachmentNode.getActions.searchFilesSameMD5.text=Search for files with the same MD5 hash AttachmentNode.getActions.viewFileInDir.text=View File in Directory AttachmentNode.getActions.viewInNewWin.text=View in New Window +# {0} - node name BaseChildFactory.NoSuchEventBusException.message=No event bus for node: {0} BlackboardArtifactNode.createSheet.artifactDetails.displayName=Result Details BlackboardArtifactNode.createSheet.artifactDetails.name=Result Details @@ -267,10 +268,10 @@ ImageNode.getActions.viewInNewWin.text=View in New Window ImageNode.createSheet.name.name=Name ImageNode.createSheet.name.displayName=Name ImageNode.createSheet.name.desc=no description -Installer.exception.tskVerStringNull.msg=Sleuth Kit JNI test call returned without error, but version string was null! -Installer.exception.taskVerStringBang.msg=Sleuth Kit JNI test call returned without error, but version string was ""! -Installer.tskLibErr.msg=Problem with Sleuth Kit JNI. Test call failed!\n\nDetails: {0} -Installer.tskLibErr.err=Fatal Error! +Installer.exception.tskVerStringNull.msg=Sleuth Kit JNI test call returned without error, but version string was null\! +Installer.exception.taskVerStringBang.msg=Sleuth Kit JNI test call returned without error, but version string was ""\! +Installer.tskLibErr.msg=Problem with Sleuth Kit JNI. Test call failed\!\n\nDetails: {0} +Installer.tskLibErr.err=Fatal Error\! InterestingHits.interestingItems.text=INTERESTING ITEMS InterestingHits.displayName.text=Interesting Items InterestingHits.createSheet.name.name=Name 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 5c0cdd1277..4729293fb9 100755 --- a/Core/src/org/sleuthkit/autopsy/modules/embeddedfileextractor/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/modules/embeddedfileextractor/Bundle.properties-MERGED @@ -23,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/interestingitems/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties-MERGED index e63c1878ac..31a0690b82 100755 --- a/Core/src/org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties-MERGED @@ -2,6 +2,7 @@ FilesIdentifierIngestJobSettingsPanel.getError=Error getting interesting files s FilesIdentifierIngestJobSettingsPanel.updateError=Error updating interesting files sets settings file. FilesIdentifierIngestModule.getFilesError=Error getting interesting files sets from file. FilesIdentifierIngestModule.indexError.message=Failed to index interesting file hit artifact for keyword search. +# {0} - daysIncluded FilesSet.rule.dateRule.toString=(modified within {0} day(s)) FilesSetDefsPanel.bytes=Bytes FilesSetDefsPanel.cancelImportMsg=Cancel import 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 02435933ad..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 -#Wed, 04 Mar 2020 11:04:14 -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 b538422219..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 -#Wed, 04 Mar 2020 11:04:14 -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 e6c3fda9c56da371ec8d83f9e9ee5279814cb0a0 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Wed, 4 Mar 2020 12:43:12 -0500 Subject: [PATCH 24/97] updates to fix bundle issues --- .../autopsy/contentviewers/Bundle.properties | 1 + .../contentviewers/Bundle.properties-MERGED | 1 + .../contentviewers/Bundle_ja.properties | 1 + .../contentviewers/MessageContentViewer.java | 92 -------------- .../TextTranslatableComponent.java | 117 ++++++++++++++++++ .../contentviewers/TranslatablePanel.form | 12 -- .../contentviewers/TranslatablePanel.java | 8 -- 7 files changed, 120 insertions(+), 112 deletions(-) create mode 100644 Core/src/org/sleuthkit/autopsy/contentviewers/TextTranslatableComponent.java diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/Bundle.properties b/Core/src/org/sleuthkit/autopsy/contentviewers/Bundle.properties index 5eaf823310..cf07682e5d 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/Bundle.properties @@ -49,6 +49,7 @@ Metadata.nodeText.text=From The Sleuth Kit istat Tool: Metadata.nodeText.exceptionNotice.text=Error getting file metadata: MessageContentViewer.rtfbodyScrollPane.TabConstraints.tabTitle=RTF MessageContentViewer.headersScrollPane.TabConstraints.tabTitle=Headers +MessageContentViewer.textbodyScrollPane.TabConstraints.tabTitle=Text MessageContentViewer.htmlPane.TabConstraints.tabTitle=HTML MessageContentViewer.fromText.text=from address goes here MessageContentViewer.fromLabel.text=From: diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/contentviewers/Bundle.properties-MERGED index bf230f3c10..737b6900d4 100755 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/Bundle.properties-MERGED @@ -95,6 +95,7 @@ Metadata.nodeText.text=From The Sleuth Kit istat Tool: Metadata.nodeText.exceptionNotice.text=Error getting file metadata: MessageContentViewer.rtfbodyScrollPane.TabConstraints.tabTitle=RTF MessageContentViewer.headersScrollPane.TabConstraints.tabTitle=Headers +MessageContentViewer.textbodyScrollPane.TabConstraints.tabTitle=Text MessageContentViewer.htmlPane.TabConstraints.tabTitle=HTML MessageContentViewer.fromText.text=from address goes here MessageContentViewer.fromLabel.text=From: diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/Bundle_ja.properties b/Core/src/org/sleuthkit/autopsy/contentviewers/Bundle_ja.properties index 5f15b483c3..f7b7844e60 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/Bundle_ja.properties +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/Bundle_ja.properties @@ -94,6 +94,7 @@ Metadata.nodeText.text=\u9001\u4fe1\u5143\u306eSleuth Kit\u306eistat\u30c4\u30fc Metadata.nodeText.exceptionNotice.text=\u30d5\u30a1\u30a4\u30eb\u306e\u30e1\u30bf\u30c7\u30fc\u30bf\u3092\u53d6\u5f97\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f: MessageContentViewer.rtfbodyScrollPane.TabConstraints.tabTitle=RTF MessageContentViewer.headersScrollPane.TabConstraints.tabTitle=\u30d8\u30c3\u30c0\u30fc +MessageContentViewer.textbodyScrollPane.TabConstraints.tabTitle=\u30c6\u30ad\u30b9\u30c8 MessageContentViewer.htmlPane.TabConstraints.tabTitle=HTML MessageContentViewer.fromText.text=\u9001\u4fe1\u5143\u30a2\u30c9\u30ec\u30b9\u3092\u3053\u3053\u306b\u8868\u793a MessageContentViewer.fromLabel.text=\u5dee\u51fa\u4eba: diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java b/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java index 0f92181d69..6e1d718324 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java @@ -29,8 +29,6 @@ import java.util.List; import java.util.Optional; import java.util.Set; import java.util.logging.Level; -import javax.swing.JScrollPane; -import javax.swing.JTextArea; import javax.swing.text.JTextComponent; import org.apache.commons.lang3.StringUtils; import org.jsoup.Jsoup; @@ -43,16 +41,12 @@ 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.contentviewers.TranslatablePanel.TranslatableComponent; import org.sleuthkit.autopsy.corecomponentinterfaces.DataContentViewer; import org.sleuthkit.autopsy.corecomponents.DataResultPanel; import org.sleuthkit.autopsy.corecomponents.TableFilterNode; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.directorytree.DataResultFilterNode; import org.sleuthkit.autopsy.directorytree.NewWindowViewAction; -import org.sleuthkit.autopsy.texttranslation.NoServiceProviderException; -import org.sleuthkit.autopsy.texttranslation.TextTranslationService; -import org.sleuthkit.autopsy.texttranslation.TranslationException; import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.BlackboardArtifact; import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_ASSOCIATED_OBJECT; @@ -101,92 +95,6 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont return true; } - /** - * provides the interface to be injected into the TranslatablePanel and displays text - */ - static class TextTranslatableComponent implements TranslatableComponent { - private final Component parentComponent; - private final JTextArea textComponent; - private final TextTranslationService translationService; - - private boolean translate = false; - private String translated = null; - private String origContent = ""; - - - TextTranslatableComponent() { - JTextArea textComponent = new JTextArea(); - textComponent.setEditable(false); - textComponent.setLineWrap(true); - textComponent.setRows(5); - textComponent.setWrapStyleWord(true); - - JScrollPane parentComponent = new JScrollPane(); - parentComponent.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); - parentComponent.setVerticalScrollBarPolicy(javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS); - parentComponent.setViewportView(textComponent); - - this.parentComponent = parentComponent; - this.textComponent = textComponent; - this.translationService = TextTranslationService.getInstance(); - } - - TextTranslatableComponent(Component parentComponent, JTextArea textComponent, TextTranslationService translationService) { - this.parentComponent = parentComponent; - this.textComponent = textComponent; - this.translationService = translationService; - } - - public Component getComponent() { - return parentComponent; - } - - public String getContent() { - return origContent; - } - - public boolean isTranslated() { - return translate; - } - - private boolean setPanelContent(String content) { - return tryHandle(() -> { - textComponent.setText(content == null ? "" : content); - }, "There was an error in setting up the text for MessageContentViewer text panel"); - - } - - @NbBundle.Messages("TextTranslatableComponent.setPanelContent.onSetContentError=Unable to display text at this time.") - private String onErr(boolean success) { - return (success) ? null : Bundle.TextTranslatableComponent_setPanelContent_onSetContentError(); - } - - public String setContent(String content) { - this.origContent = content; - this.translated = null; - this.translate = false; - return onErr(setPanelContent(content)); - } - - @NbBundle.Messages("TextTranslatableComponent.setTranslated.onTranslateError=Unable to translate text at this time.") - public String setTranslated(boolean translate) { - this.translate = translate; - if (this.translate) { - if (this.translated == null) { - try { - this.translated = this.translationService.translate(this.origContent); - } catch (NoServiceProviderException | TranslationException ex) { - LOGGER.log(Level.WARNING, "Unable to translate text with translation service", ex); - return Bundle.TextTranslatableComponent_setTranslated_onTranslateError(); - } - } - return onErr(setPanelContent(this.translated == null ? "" : this.translated)); - } - else { - return onErr(setPanelContent(this.origContent)); - } - } - } private static final long serialVersionUID = 1L; diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/TextTranslatableComponent.java b/Core/src/org/sleuthkit/autopsy/contentviewers/TextTranslatableComponent.java new file mode 100644 index 0000000000..d188720a49 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/TextTranslatableComponent.java @@ -0,0 +1,117 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2017-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; + +import java.awt.Component; +import java.util.logging.Level; +import javax.swing.JScrollPane; +import javax.swing.JTextArea; +import org.openide.util.NbBundle; +import org.sleuthkit.autopsy.coreutils.Logger; +import org.sleuthkit.autopsy.texttranslation.NoServiceProviderException; +import org.sleuthkit.autopsy.texttranslation.TextTranslationService; +import org.sleuthkit.autopsy.texttranslation.TranslationException; + +/** + * provides the interface to be injected into the TranslatablePanel and displays text + */ +final class TextTranslatableComponent implements TranslatablePanel.TranslatableComponent { + + private static final Logger LOGGER = Logger.getLogger(TextTranslatableComponent.class.getName()); + private final Component parentComponent; + private final JTextArea textComponent; + private final TextTranslationService translationService; + private boolean translate = false; + private String translated = null; + private String origContent = ""; + + TextTranslatableComponent() { + JTextArea textComponent = new JTextArea(); + textComponent.setEditable(false); + textComponent.setLineWrap(true); + textComponent.setRows(5); + textComponent.setWrapStyleWord(true); + JScrollPane parentComponent = new JScrollPane(); + parentComponent.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); + parentComponent.setVerticalScrollBarPolicy(javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS); + parentComponent.setViewportView(textComponent); + this.parentComponent = parentComponent; + this.textComponent = textComponent; + this.translationService = TextTranslationService.getInstance(); + } + + TextTranslatableComponent(Component parentComponent, JTextArea textComponent, TextTranslationService translationService) { + this.parentComponent = parentComponent; + this.textComponent = textComponent; + this.translationService = translationService; + } + + public Component getComponent() { + return parentComponent; + } + + public String getContent() { + return origContent; + } + + public boolean isTranslated() { + return translate; + } + + private boolean setPanelContent(String content) { + try { + textComponent.setText(content == null ? "" : content); + return true; + } catch (Exception e) { + LOGGER.log(Level.WARNING, "There was an error in setting up the text for MessageContentViewer text panel", e); + return false; + } + } + + @NbBundle.Messages(value = "TextTranslatableComponent.setPanelContent.onSetContentError=Unable to display text at this time.") + private String onErr(boolean success) { + return (success) ? null : Bundle.TextTranslatableComponent_setPanelContent_onSetContentError(); + } + + public String setContent(String content) { + this.origContent = content; + this.translated = null; + this.translate = false; + return onErr(setPanelContent(content)); + } + + @NbBundle.Messages(value = "TextTranslatableComponent.setTranslated.onTranslateError=Unable to translate text at this time.") + public String setTranslated(boolean translate) { + this.translate = translate; + if (this.translate) { + if (this.translated == null) { + try { + this.translated = this.translationService.translate(this.origContent); + } catch (NoServiceProviderException | TranslationException ex) { + LOGGER.log(Level.WARNING, "Unable to translate text with translation service", ex); + return Bundle.TextTranslatableComponent_setTranslated_onTranslateError(); + } + } + return onErr(setPanelContent(this.translated == null ? "" : this.translated)); + } else { + return onErr(setPanelContent(this.origContent)); + } + } + +} diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/TranslatablePanel.form b/Core/src/org/sleuthkit/autopsy/contentviewers/TranslatablePanel.form index 2ac835e4e3..384414b26e 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/TranslatablePanel.form +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/TranslatablePanel.form @@ -87,18 +87,6 @@ - - - - - - - - - - - - diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/TranslatablePanel.java b/Core/src/org/sleuthkit/autopsy/contentviewers/TranslatablePanel.java index 9d3ef27a4e..53d6d25941 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/TranslatablePanel.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/TranslatablePanel.java @@ -165,7 +165,6 @@ final class TranslatablePanel extends JPanel { jPanel1 = new javax.swing.JPanel(); translateComboBox = new javax.swing.JComboBox<>(); warningLabel = new javax.swing.JLabel(); - showLabel = new javax.swing.JLabel(); setMaximumSize(new java.awt.Dimension(2000, 2000)); setMinimumSize(new java.awt.Dimension(2, 2)); @@ -204,12 +203,6 @@ final class TranslatablePanel extends JPanel { gridBagConstraints.weightx = 0.25; jPanel1.add(warningLabel, gridBagConstraints); - org.openide.awt.Mnemonics.setLocalizedText(showLabel, org.openide.util.NbBundle.getMessage(TranslatablePanel.class, "TranslatablePanel.showLabel.text")); // NOI18N - gridBagConstraints = new java.awt.GridBagConstraints(); - gridBagConstraints.gridx = 2; - gridBagConstraints.gridy = 0; - jPanel1.add(showLabel, gridBagConstraints); - add(jPanel1, java.awt.BorderLayout.NORTH); }// //GEN-END:initComponents @@ -219,7 +212,6 @@ final class TranslatablePanel extends JPanel { // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JPanel jPanel1; - private javax.swing.JLabel showLabel; private javax.swing.JComboBox translateComboBox; private javax.swing.JLabel warningLabel; // End of variables declaration//GEN-END:variables From 294aa6c7730e8ca32fac93119127377f0841f376 Mon Sep 17 00:00:00 2001 From: Raman Arora Date: Wed, 4 Mar 2020 14:44:55 -0500 Subject: [PATCH 25/97] Ensure default content gets populated in Accounts related tables. --- .../datamodel/RdbmsCentralRepoFactory.java | 50 +++++++++++++++---- 1 file changed, 39 insertions(+), 11 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/RdbmsCentralRepoFactory.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/RdbmsCentralRepoFactory.java index db7343ad50..09f103a038 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/RdbmsCentralRepoFactory.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/RdbmsCentralRepoFactory.java @@ -192,7 +192,8 @@ public class RdbmsCentralRepoFactory { } result = CentralRepoDbUtil.insertDefaultCorrelationTypes(conn) - && CentralRepoDbUtil.insertDefaultOrganization(conn); + && CentralRepoDbUtil.insertDefaultOrganization(conn) && + insertDefaultAccountsTablesContent(conn); // @TODO: uncomment when ready to create/populate persona tables // && insertDefaultPersonaTablesContent(conn); @@ -765,6 +766,43 @@ 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) { + Statement stmt = null; + try { + 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; + } finally { + if (stmt != null) { + try { + stmt.close(); + } catch (SQLException ex2) { + LOGGER.log(Level.SEVERE, "Error closing statement.", ex2); + } + } + } + + return true; + } + /** * Inserts the default content in persona related tables. * @@ -792,16 +830,6 @@ public class RdbmsCentralRepoFactory { stmt.execute(sqlString); } - // 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; From db90af5d5a2cc93fc343218fcc2d04bba1b43fd3 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Wed, 4 Mar 2020 14:53:31 -0500 Subject: [PATCH 26/97] updates to fix translation panel gui rough edges --- .../contentviewers/MessageContentViewer.java | 2 + .../TextTranslatableComponent.java | 3 + .../contentviewers/TranslatablePanel.form | 26 ++++--- .../contentviewers/TranslatablePanel.java | 71 ++++++++++--------- 4 files changed, 57 insertions(+), 45 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java b/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java index 6e1d718324..ae26576c35 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java @@ -20,6 +20,7 @@ package org.sleuthkit.autopsy.contentviewers; import org.sleuthkit.autopsy.datamodel.AttachmentNode; import com.google.gson.Gson; +import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; import java.util.Arrays; @@ -131,6 +132,7 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont drp = DataResultPanel.createInstanceUninitialized(Bundle.MessageContentViewer_AtrachmentsPanel_title(), "", new TableFilterNode(Node.EMPTY, false), 0, null); attachmentsScrollPane.setViewportView(drp); + //textPanel.setLayout(new BorderLayout()); msgbodyTabbedPane.insertTab( NbBundle.getMessage(MessageContentViewer.class, "MessageContentViewer.textbodyScrollPane.TabConstraints.tabTitle"), null, diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/TextTranslatableComponent.java b/Core/src/org/sleuthkit/autopsy/contentviewers/TextTranslatableComponent.java index d188720a49..653efba23a 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/TextTranslatableComponent.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/TextTranslatableComponent.java @@ -47,9 +47,11 @@ final class TextTranslatableComponent implements TranslatablePanel.TranslatableC textComponent.setLineWrap(true); textComponent.setRows(5); textComponent.setWrapStyleWord(true); + JScrollPane parentComponent = new JScrollPane(); parentComponent.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); parentComponent.setVerticalScrollBarPolicy(javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS); + //parentComponent.setVerticalScrollBarPolicy(javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED); parentComponent.setViewportView(textComponent); this.parentComponent = parentComponent; this.textComponent = textComponent; @@ -77,6 +79,7 @@ final class TextTranslatableComponent implements TranslatablePanel.TranslatableC private boolean setPanelContent(String content) { try { textComponent.setText(content == null ? "" : content); + textComponent.setCaretPosition(0); return true; } catch (Exception e) { LOGGER.log(Level.WARNING, "There was an error in setting up the text for MessageContentViewer text panel", e); diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/TranslatablePanel.form b/Core/src/org/sleuthkit/autopsy/contentviewers/TranslatablePanel.form index 384414b26e..45eb156e87 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/TranslatablePanel.form +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/TranslatablePanel.form @@ -29,7 +29,7 @@ - + @@ -49,18 +49,22 @@ - + - - + + + + + + - + @@ -70,20 +74,20 @@ - - + + - - + + - - + + diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/TranslatablePanel.java b/Core/src/org/sleuthkit/autopsy/contentviewers/TranslatablePanel.java index 53d6d25941..107dae8cb1 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/TranslatablePanel.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/TranslatablePanel.java @@ -19,15 +19,19 @@ package org.sleuthkit.autopsy.contentviewers; import java.awt.Component; +import javax.swing.ImageIcon; import org.apache.commons.lang.StringUtils; import javax.swing.JPanel; import javax.swing.SwingUtilities; import org.openide.util.NbBundle.Messages; +import org.sleuthkit.autopsy.texttranslation.TextTranslationService; /** * A panel for translation with a subcomponent that allows for translation */ final class TranslatablePanel extends JPanel { + + /** * an option in drop down of whether or not to translate */ @@ -86,11 +90,12 @@ final class TranslatablePanel extends JPanel { private static final long serialVersionUID = 1L; + private final ImageIcon warningIcon = new ImageIcon(TranslatablePanel.class.getResource("/org/sleuthkit/autopsy/images/warning16.png")); private final TranslatableComponent subcomponent; private final String origOptionText; private final String translatedOptionText; - + private final TextTranslationService translationService; @Messages({"TranslatablePanel.comboBoxOption.originalText=Original Text", "TranslatablePanel.comboBoxOption.translatedText=Translated Text"}) @@ -99,29 +104,40 @@ final class TranslatablePanel extends JPanel { subcomponent, Bundle.TranslatablePanel_comboBoxOption_originalText(), Bundle.TranslatablePanel_comboBoxOption_translatedText(), - null); + null, + TextTranslationService.getInstance()); } /** * Creates new form TranslatedContentPanel */ - TranslatablePanel(TranslatableComponent subcomponent, String origOptionText, String translatedOptionText, String origContent) { + TranslatablePanel(TranslatableComponent subcomponent, String origOptionText, String translatedOptionText, String origContent, + TextTranslationService translationService) { this.subcomponent = subcomponent; this.origOptionText = origOptionText; this.translatedOptionText = translatedOptionText; + this.translationService = translationService; initComponents(); - additionalInit(origContent); + additionalInit(); + setTranslationBarVisible(); + setContent(origContent); } private void setWarningLabelMsg(String msg) { - warningLabel.setText(msg); - warningLabel.setVisible(StringUtils.isEmpty(msg)); + boolean hasWarning = !StringUtils.isEmpty(msg); + warningLabel.setText(hasWarning ? msg : ""); + warningLabel.setIcon(hasWarning ? warningIcon : null); } + private void setTranslationBarVisible() { + translationBar.setVisible(this.translationService.hasProvider()); + } + void reset() { + setTranslationBarVisible(); setContent(null); } @@ -135,13 +151,12 @@ final class TranslatablePanel extends JPanel { - private void additionalInit(String origContent) { + private void additionalInit() { add(this.subcomponent.getComponent(), java.awt.BorderLayout.CENTER); setWarningLabelMsg(null); translateComboBox.removeAllItems(); translateComboBox.addItem(new TranslateOption(this.origOptionText, false)); translateComboBox.addItem(new TranslateOption(this.translatedOptionText, true)); - this.subcomponent.setContent(origContent); } private void handleComboBoxChange(TranslateOption translateOption) { @@ -160,9 +175,8 @@ final class TranslatablePanel extends JPanel { @SuppressWarnings("unchecked") // //GEN-BEGIN:initComponents private void initComponents() { - java.awt.GridBagConstraints gridBagConstraints; - jPanel1 = new javax.swing.JPanel(); + translationBar = new javax.swing.JPanel(); translateComboBox = new javax.swing.JComboBox<>(); warningLabel = new javax.swing.JLabel(); @@ -173,37 +187,26 @@ final class TranslatablePanel extends JPanel { setVerifyInputWhenFocusTarget(false); setLayout(new java.awt.BorderLayout()); - jPanel1.setBorder(javax.swing.BorderFactory.createEtchedBorder()); - jPanel1.setMaximumSize(new java.awt.Dimension(182, 24)); - jPanel1.setPreferredSize(new java.awt.Dimension(182, 24)); - jPanel1.setLayout(new java.awt.GridBagLayout()); + translationBar.setBorder(javax.swing.BorderFactory.createEtchedBorder()); + translationBar.setMaximumSize(new java.awt.Dimension(182, 24)); + translationBar.setPreferredSize(new java.awt.Dimension(182, 24)); + translationBar.setLayout(new java.awt.BorderLayout()); - translateComboBox.setMinimumSize(new java.awt.Dimension(43, 20)); - translateComboBox.setPreferredSize(new java.awt.Dimension(43, 20)); + translateComboBox.setMaximumSize(new java.awt.Dimension(200, 20)); + translateComboBox.setMinimumSize(new java.awt.Dimension(200, 20)); + translateComboBox.setName(""); // NOI18N + translateComboBox.setPreferredSize(new java.awt.Dimension(200, 20)); translateComboBox.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { translateComboBoxActionPerformed(evt); } }); - gridBagConstraints = new java.awt.GridBagConstraints(); - gridBagConstraints.gridx = 3; - gridBagConstraints.gridy = 0; - gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; - gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST; - gridBagConstraints.weightx = 0.1; - gridBagConstraints.insets = new java.awt.Insets(0, 5, 0, 0); - jPanel1.add(translateComboBox, gridBagConstraints); + translationBar.add(translateComboBox, java.awt.BorderLayout.LINE_END); - warningLabel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/images/warning16.png"))); // NOI18N - gridBagConstraints = new java.awt.GridBagConstraints(); - gridBagConstraints.gridx = 0; - gridBagConstraints.gridy = 0; - gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; - gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST; - gridBagConstraints.weightx = 0.25; - jPanel1.add(warningLabel, gridBagConstraints); + warningLabel.setMaximumSize(new java.awt.Dimension(32767, 32767)); + translationBar.add(warningLabel, java.awt.BorderLayout.CENTER); - add(jPanel1, java.awt.BorderLayout.NORTH); + add(translationBar, java.awt.BorderLayout.NORTH); }// //GEN-END:initComponents private void translateComboBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_translateComboBoxActionPerformed @@ -211,8 +214,8 @@ final class TranslatablePanel extends JPanel { }//GEN-LAST:event_translateComboBoxActionPerformed // Variables declaration - do not modify//GEN-BEGIN:variables - private javax.swing.JPanel jPanel1; private javax.swing.JComboBox translateComboBox; + private javax.swing.JPanel translationBar; private javax.swing.JLabel warningLabel; // End of variables declaration//GEN-END:variables } \ No newline at end of file From dc53c93eec39fdd63ba83454f5f3054e4a3da699 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Wed, 4 Mar 2020 15:43:49 -0500 Subject: [PATCH 27/97] updates for scrollbar visibility --- .../autopsy/contentviewers/TextTranslatableComponent.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/TextTranslatableComponent.java b/Core/src/org/sleuthkit/autopsy/contentviewers/TextTranslatableComponent.java index 653efba23a..801647e679 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/TextTranslatableComponent.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/TextTranslatableComponent.java @@ -50,8 +50,7 @@ final class TextTranslatableComponent implements TranslatablePanel.TranslatableC JScrollPane parentComponent = new JScrollPane(); parentComponent.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); - parentComponent.setVerticalScrollBarPolicy(javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS); - //parentComponent.setVerticalScrollBarPolicy(javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED); + parentComponent.setVerticalScrollBarPolicy(javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED); parentComponent.setViewportView(textComponent); this.parentComponent = parentComponent; this.textComponent = textComponent; From 1f7ab40a4dcfbd4670f08eb59d93e4f547ce45ea Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Thu, 5 Mar 2020 07:37:51 -0500 Subject: [PATCH 28/97] updates for async behavior --- .../TextTranslatableComponent.java | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/TextTranslatableComponent.java b/Core/src/org/sleuthkit/autopsy/contentviewers/TextTranslatableComponent.java index 801647e679..74f2fddf03 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/TextTranslatableComponent.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/TextTranslatableComponent.java @@ -22,6 +22,7 @@ import java.awt.Component; import java.util.logging.Level; import javax.swing.JScrollPane; import javax.swing.JTextArea; +import javax.swing.SwingUtilities; import org.openide.util.NbBundle; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.texttranslation.NoServiceProviderException; @@ -103,12 +104,15 @@ final class TextTranslatableComponent implements TranslatablePanel.TranslatableC this.translate = translate; if (this.translate) { if (this.translated == null) { - try { - this.translated = this.translationService.translate(this.origContent); - } catch (NoServiceProviderException | TranslationException ex) { - LOGGER.log(Level.WARNING, "Unable to translate text with translation service", ex); - return Bundle.TextTranslatableComponent_setTranslated_onTranslateError(); - } + final String originalContent = this.origContent; + SwingUtilities.invokeLater(() -> { + try { + this.translated = this.translationService.translate(originalContent); + } catch (NoServiceProviderException | TranslationException ex) { + LOGGER.log(Level.WARNING, "Unable to translate text with translation service", ex); + return Bundle.TextTranslatableComponent_setTranslated_onTranslateError(); + } + }); } return onErr(setPanelContent(this.translated == null ? "" : this.translated)); } else { From b3347aa58a0617183a17f8cf626ed22b4a29d3cc Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Thu, 5 Mar 2020 07:42:28 -0500 Subject: [PATCH 29/97] 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 30/97] 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 31/97] 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 fe86d86dd2ec6c1fee5f8a0407570f46bde4b8f7 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Thu, 5 Mar 2020 09:10:05 -0500 Subject: [PATCH 32/97] abstracted TranslateTextTask --- .../TextTranslatableComponent.java | 2 +- .../contentviewers/TranslatablePanel.java | 4 +- .../texttranslation/ui/TranslateTextTask.java | 160 ++++++++++++++++++ .../ui/TranslatedTextViewer.java | 118 ++----------- 4 files changed, 175 insertions(+), 109 deletions(-) create mode 100644 Core/src/org/sleuthkit/autopsy/texttranslation/ui/TranslateTextTask.java diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/TextTranslatableComponent.java b/Core/src/org/sleuthkit/autopsy/contentviewers/TextTranslatableComponent.java index 74f2fddf03..ea456cd5eb 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/TextTranslatableComponent.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/TextTranslatableComponent.java @@ -110,7 +110,7 @@ final class TextTranslatableComponent implements TranslatablePanel.TranslatableC this.translated = this.translationService.translate(originalContent); } catch (NoServiceProviderException | TranslationException ex) { LOGGER.log(Level.WARNING, "Unable to translate text with translation service", ex); - return Bundle.TextTranslatableComponent_setTranslated_onTranslateError(); + //return Bundle.TextTranslatableComponent_setTranslated_onTranslateError(); } }); } diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/TranslatablePanel.java b/Core/src/org/sleuthkit/autopsy/contentviewers/TranslatablePanel.java index 107dae8cb1..48c4006785 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/TranslatablePanel.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/TranslatablePanel.java @@ -30,7 +30,9 @@ import org.sleuthkit.autopsy.texttranslation.TextTranslationService; * A panel for translation with a subcomponent that allows for translation */ final class TranslatablePanel extends JPanel { - + interface ContentSetter { + void set(String content) throws Exception; + } /** * an option in drop down of whether or not to translate diff --git a/Core/src/org/sleuthkit/autopsy/texttranslation/ui/TranslateTextTask.java b/Core/src/org/sleuthkit/autopsy/texttranslation/ui/TranslateTextTask.java new file mode 100644 index 0000000000..ddfcc5b155 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/texttranslation/ui/TranslateTextTask.java @@ -0,0 +1,160 @@ +/* + * 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.texttranslation.ui; + +import java.awt.ComponentOrientation; +import java.awt.Font; +import java.util.concurrent.CancellationException; +import java.util.concurrent.ExecutionException; +import java.util.logging.Level; +import javax.swing.SwingUtilities; +import javax.swing.SwingWorker; +import org.openide.util.NbBundle; +import org.sleuthkit.autopsy.coreutils.Logger; +import org.sleuthkit.autopsy.coreutils.TextUtil; +import org.sleuthkit.autopsy.texttranslation.NoServiceProviderException; +import org.sleuthkit.autopsy.texttranslation.TextTranslationService; +import org.sleuthkit.autopsy.texttranslation.TranslationException; + +/** +* abstract class for translating text and displaying to the user +*/ +public abstract class TranslateTextTask extends SwingWorker { + private static final Logger logger = Logger.getLogger(TranslatedTextViewer.class.getName()); + + private final boolean translateText; + private final String contentDescriptor; + + + /** + * + * @param translateText whether or not to translate text + * @param contentDescriptor the content descriptor for the item being translated (used for logging errors) + */ + public TranslateTextTask(boolean translateText, String fileDescriptor) { + this.translateText = translateText; + this.contentDescriptor = fileDescriptor; + } + + + protected abstract String retrieveText() throws Exception; + + protected abstract void onTextDisplay(String text, ComponentOrientation orientation, int font); + + @NbBundle.Messages({ + "TranslatedContentViewer.extractingText=Extracting text, please wait...", + "TranslatedContentViewer.translatingText=Translating text, please wait...", + "# {0} - exception message", "TranslatedContentViewer.errorExtractingText=An error occurred while extracting the text ({0}).", + "TranslatedContentViewer.fileHasNoText=File has no text.", + "TranslatedContentViewer.noServiceProvider=The machine translation software was not found.", + "# {0} - exception message", "TranslatedContentViewer.translationException=An error occurred while translating the text ({0})." + }) + @Override + public String doInBackground() throws InterruptedException { + if (this.isCancelled()) { + throw new InterruptedException(); + } + + SwingUtilities.invokeLater(() -> { + onTextDisplay(Bundle.TranslatedContentViewer_extractingText(), ComponentOrientation.LEFT_TO_RIGHT, Font.ITALIC); + }); + String fileText; + try { + fileText = retrieveText(); + } catch (InterruptedException | CancellationException e) { + // bubble up cancellation instead of continuing + throw e; + } catch (Exception ex) { + logger.log(Level.WARNING, "Error extracting text for file " + this.contentDescriptor, ex); + return Bundle.TranslatedContentViewer_errorExtractingText(ex.getMessage()); + } + + if (this.isCancelled()) { + throw new InterruptedException(); + } + + if (fileText == null || fileText.isEmpty()) { + return Bundle.TranslatedContentViewer_fileHasNoText(); + } + + if (!this.translateText) { + return fileText; + } + + SwingUtilities.invokeLater(() -> { + onTextDisplay(Bundle.TranslatedContentViewer_translatingText(), ComponentOrientation.LEFT_TO_RIGHT, Font.ITALIC); + }); + String translation; + try { + translation = translate(fileText); + } catch (NoServiceProviderException ex) { + logger.log(Level.WARNING, "Error translating text for file " + this.contentDescriptor, ex); + translation = Bundle.TranslatedContentViewer_noServiceProvider(); + } catch (TranslationException ex) { + logger.log(Level.WARNING, "Error translating text for file " + this.contentDescriptor, ex); + translation = Bundle.TranslatedContentViewer_translationException(ex.getMessage()); + } + + if (this.isCancelled()) { + throw new InterruptedException(); + } + + return translation; + } + + @Override + public void done() { + try { + String result = get(); + if (this.isCancelled()) { + throw new InterruptedException(); + } + int len = result.length(); + int maxOrientChars = Math.min(len, 1024); + String orientDetectSubstring = result.substring(0, maxOrientChars); + ComponentOrientation orientation = TextUtil.getTextDirection(orientDetectSubstring); + onTextDisplay(result, orientation, Font.PLAIN); + + } catch (InterruptedException | CancellationException ignored) { + // Task cancelled, no error. + } catch (ExecutionException ex) { + logger.log(Level.WARNING, "Error occurred during background task execution for file " + this.contentDescriptor, ex); + onTextDisplay(Bundle.TranslatedContentViewer_translationException(ex.getMessage()), ComponentOrientation.LEFT_TO_RIGHT, Font.ITALIC); + } + } + + /** + * Pass the translation off to the Translation service provider. + * + * @param input Text to be translated + * + * @return Translated text or error message + */ + @NbBundle.Messages({ + "TranslatedContentViewer.emptyTranslation=The machine translation software did not return any text." + }) + private String translate(String input) throws NoServiceProviderException, TranslationException { + TextTranslationService translatorInstance = TextTranslationService.getInstance(); + String translatedResult = translatorInstance.translate(input); + if (translatedResult.isEmpty()) { + return Bundle.TranslatedContentViewer_emptyTranslation(); + } + return translatedResult; + } +} diff --git a/Core/src/org/sleuthkit/autopsy/texttranslation/ui/TranslatedTextViewer.java b/Core/src/org/sleuthkit/autopsy/texttranslation/ui/TranslatedTextViewer.java index 7e07545b49..ecae3645c3 100644 --- a/Core/src/org/sleuthkit/autopsy/texttranslation/ui/TranslatedTextViewer.java +++ b/Core/src/org/sleuthkit/autopsy/texttranslation/ui/TranslatedTextViewer.java @@ -160,112 +160,13 @@ public final class TranslatedTextViewer implements TextViewer { /** * Extracts text from a file and optionally translates it. */ - private class ExtractAndTranslateTextTask extends SwingWorker { + private class ExtractAndTranslateTextTask extends TranslateTextTask { private final AbstractFile file; - private final boolean translateText; private ExtractAndTranslateTextTask(AbstractFile file, boolean translateText) { + super(translateText, String.format("%s (objId=%d)", file.getName(), file.getId())); this.file = file; - this.translateText = translateText; - } - - @NbBundle.Messages({ - "TranslatedContentViewer.extractingText=Extracting text, please wait...", - "TranslatedContentViewer.translatingText=Translating text, please wait...", - "# {0} - exception message", "TranslatedContentViewer.errorExtractingText=An error occurred while extracting the text ({0}).", - "TranslatedContentViewer.fileHasNoText=File has no text.", - "TranslatedContentViewer.noServiceProvider=The machine translation software was not found.", - "# {0} - exception message", "TranslatedContentViewer.translationException=An error occurred while translating the text ({0})." - }) - @Override - public String doInBackground() throws InterruptedException { - if (this.isCancelled()) { - throw new InterruptedException(); - } - - SwingUtilities.invokeLater(() -> { - panel.display(Bundle.TranslatedContentViewer_extractingText(), ComponentOrientation.LEFT_TO_RIGHT, Font.ITALIC); - }); - String fileText; - try { - fileText = getFileText(file); - } catch (IOException | TextExtractor.InitReaderException ex) { - logger.log(Level.WARNING, String.format("Error extracting text for file %s (objId=%d)", file.getName(), file.getId()), ex); - return Bundle.TranslatedContentViewer_errorExtractingText(ex.getMessage()); - } - - if (this.isCancelled()) { - throw new InterruptedException(); - } - - if (fileText == null || fileText.isEmpty()) { - return Bundle.TranslatedContentViewer_fileHasNoText(); - } - - if (!this.translateText) { - return fileText; - } - - SwingUtilities.invokeLater(() -> { - panel.display(Bundle.TranslatedContentViewer_translatingText(), ComponentOrientation.LEFT_TO_RIGHT, Font.ITALIC); - }); - String translation; - try { - translation = translate(fileText); - } catch (NoServiceProviderException ex) { - logger.log(Level.WARNING, String.format("Error translating text for file %s (objId=%d)", file.getName(), file.getId()), ex); - translation = Bundle.TranslatedContentViewer_noServiceProvider(); - } catch (TranslationException ex) { - logger.log(Level.WARNING, String.format("Error translating text for file %s (objId=%d)", file.getName(), file.getId()), ex); - translation = Bundle.TranslatedContentViewer_translationException(ex.getMessage()); - } - - if (this.isCancelled()) { - throw new InterruptedException(); - } - - return translation; - } - - @Override - public void done() { - try { - String result = get(); - if (this.isCancelled()) { - throw new InterruptedException(); - } - int len = result.length(); - int maxOrientChars = Math.min(len, 1024); - String orientDetectSubstring = result.substring(0, maxOrientChars); - ComponentOrientation orientation = TextUtil.getTextDirection(orientDetectSubstring); - panel.display(result, orientation, Font.PLAIN); - - } catch (InterruptedException | CancellationException ignored) { - // Task cancelled, no error. - } catch (ExecutionException ex) { - logger.log(Level.WARNING, String.format("Error occurred during background task execution for file %s (objId=%d)", file.getName(), file.getId()), ex); - panel.display(Bundle.TranslatedContentViewer_translationException(ex.getMessage()), ComponentOrientation.LEFT_TO_RIGHT, Font.ITALIC); - } - } - - /** - * Pass the translation off to the Translation service provider. - * - * @param input Text to be translated - * - * @return Translated text or error message - */ - @NbBundle.Messages({ - "TranslatedContentViewer.emptyTranslation=The machine translation software did not return any text." - }) - private String translate(String input) throws NoServiceProviderException, TranslationException { - TextTranslationService translatorInstance = TextTranslationService.getInstance(); - String translatedResult = translatorInstance.translate(input); - if (translatedResult.isEmpty()) { - return Bundle.TranslatedContentViewer_emptyTranslation(); - } - return translatedResult; } /** @@ -275,13 +176,9 @@ public final class TranslatedTextViewer implements TextViewer { * * @return Extracted text * - * @throws IOException - * @throws InterruptedException - * @throws - * org.sleuthkit.autopsy.textextractors.TextExtractor.InitReaderException + * @throws Exception */ - private String getFileText(AbstractFile file) throws IOException, - InterruptedException, TextExtractor.InitReaderException { + protected String retrieveText() throws Exception { final boolean isImage = file.getMIMEType().toLowerCase().startsWith("image/"); // NON-NLS String result; @@ -382,8 +279,15 @@ public final class TranslatedTextViewer implements TextViewer { return TextExtractorFactory.getStringsExtractor(file, context).getReader(); } } + + + @Override + protected void onTextDisplay(String text, ComponentOrientation orientation, int font) { + panel.display(text, orientation, font); + } } + /** * Listens for drop-down selection changes and pushes processing off of the * EDT and into a SwingWorker. From d3089f7bf3c56d66edf4cd41ddb757f730153157 Mon Sep 17 00:00:00 2001 From: Mark McKinnon Date: Thu, 5 Mar 2020 09:59:21 -0500 Subject: [PATCH 33/97] Update contextviewer for source and usage Add both source and usage to contextviewer at same time. --- .../contextviewer/Bundle.properties-MERGED | 8 +- .../contextviewer/ContextViewer.form | 72 ++++++++++-- .../contextviewer/ContextViewer.java | 110 ++++++++++++++++-- 3 files changed, 169 insertions(+), 21 deletions(-) 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 b29e7190fd..aafa549431 100755 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/Bundle.properties-MERGED @@ -3,16 +3,20 @@ 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 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 ContextViewer.messageTo=To -ContextViewer.on=On +ContextViewer.on=Opened on ContextViewer.recentDocs=Recent Documents: ContextViewer.title=Context ContextViewer.toolTip=Displays context for selected file. +ContextViewer.unknown=Opened on unknown time diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextViewer.form b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextViewer.form index f7e70919c0..ab4771fc71 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextViewer.form +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextViewer.form @@ -27,17 +27,30 @@ - - - - - + + + + + + + + + + + + + + + - - + + + + + @@ -56,7 +69,16 @@ - + + + + + + + + + +
@@ -96,5 +118,39 @@
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextViewer.java b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextViewer.java index 1baa412495..0e8e03f5b1 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextViewer.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextViewer.java @@ -83,6 +83,10 @@ public final class ContextViewer extends javax.swing.JPanel implements DataConte 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(); setBackground(new java.awt.Color(255, 255, 255)); @@ -100,6 +104,20 @@ public final class ContextViewer extends javax.swing.JPanel implements DataConte 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 + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); layout.setHorizontalGroup( @@ -110,14 +128,23 @@ public final class ContextViewer extends javax.swing.JPanel implements DataConte .addGroup(layout.createSequentialGroup() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(jSourceLabel) + .addComponent(jUsageLabel) .addGroup(layout.createSequentialGroup() .addGap(6, 6, 6) - .addComponent(jSourceNameLabel) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(jSourceTextLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 192, Short.MAX_VALUE))) + .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() - .addComponent(jSourceGoToResultButton) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jSourceGoToResultButton) + .addComponent(jUsageGoToResultButton)) .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))) ); layout.setVerticalGroup( @@ -131,7 +158,15 @@ public final class ContextViewer extends javax.swing.JPanel implements DataConte .addComponent(jSourceTextLabel)) .addGap(18, 18, 18) .addComponent(jSourceGoToResultButton) - .addGap(0, 203, Short.MAX_VALUE)) + .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)) + .addGap(18, 18, 18) + .addComponent(jUsageGoToResultButton) + .addGap(0, 60, Short.MAX_VALUE)) ); }// //GEN-END:initComponents @@ -146,6 +181,15 @@ public final class ContextViewer extends javax.swing.JPanel implements DataConte }//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))) { @@ -246,9 +290,12 @@ public final class ContextViewer extends javax.swing.JPanel implements DataConte } } jSourceGoToResultButton.setVisible(true); + jUsageGoToResultButton.setVisible(true); if (foundASource == false) { setSourceName("Unknown"); showSourceText(false); + setUsageName("Unknown"); + showUsageText(false); } } @@ -263,6 +310,11 @@ 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)); if (associatedArtifactAttribute != null) { @@ -303,8 +355,8 @@ public final class ContextViewer extends javax.swing.JPanel implements DataConte setSourceName(Bundle.ContextViewer_downloadSource()); setSourceText(webDownloadArtifactToString(associatedArtifact)); } else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_RECENT_OBJECT.getTypeID() == associatedArtifact.getArtifactTypeID()) { - setSourceName(Bundle.ContextViewer_recentDocs()); - setSourceText(recentDocArtifactToString(associatedArtifact)); + setUsageName(Bundle.ContextViewer_recentDocs()); + setUsageText(recentDocArtifactToString(associatedArtifact)); } } @@ -318,6 +370,15 @@ public final class ContextViewer extends javax.swing.JPanel implements DataConte 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. * @@ -332,6 +393,24 @@ public final class ContextViewer extends javax.swing.JPanel implements DataConte 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); } /** @@ -371,16 +450,21 @@ public final class ContextViewer extends javax.swing.JPanel implements DataConte * @throws TskCoreException */ @NbBundle.Messages({ - "ContextViewer.file=File", - "ContextViewer.on=On" + "ContextViewer.on=Opened on", + "ContextViewer.unknown=Opened on unknown time" }) private String recentDocArtifactToString(BlackboardArtifact artifact) throws TskCoreException { StringBuilder sb = new StringBuilder(ARTIFACT_STR_MAX_LEN); Map attributesMap = getAttributesMap(artifact); + BlackboardAttribute attribute = attributesMap.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME); + if (BlackboardArtifact.ARTIFACT_TYPE.TSK_RECENT_OBJECT.getTypeID() == artifact.getArtifactTypeID()) { - appendAttributeString(sb, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PATH, attributesMap, Bundle.ContextViewer_file()); - appendAttributeString(sb, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME, attributesMap, Bundle.ContextViewer_on()); + if (attribute.getValueLong() > 0) { + appendAttributeString(sb, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME, attributesMap, Bundle.ContextViewer_on()); + } else { + sb.append(Bundle.ContextViewer_unknown()); + } } return sb.toString(); } @@ -472,5 +556,9 @@ public final class ContextViewer extends javax.swing.JPanel implements DataConte 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; // End of variables declaration//GEN-END:variables } From 2b10038796be37c9b920dd8e049538afc7164f3b Mon Sep 17 00:00:00 2001 From: Mark McKinnon Date: Thu, 5 Mar 2020 10:11:30 -0500 Subject: [PATCH 34/97] Update Bundle.properties Missed file in commit --- .../autopsy/contentviewers/contextviewer/Bundle.properties | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/Bundle.properties b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/Bundle.properties index efe92bd0f6..6a74bbcb06 100755 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/Bundle.properties @@ -2,3 +2,7 @@ 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 From 1641af93ed82643bf4d6c65ee58ac330a395565f Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Thu, 5 Mar 2020 10:23:19 -0500 Subject: [PATCH 35/97] fix of TranslateTextTask --- .../contentviewers/TranslatablePanel.java | 46 ++------- .../texttranslation/ui/TranslateTextTask.java | 97 ++++++++++++------- .../ui/TranslatedTextViewer.java | 32 +++++- 3 files changed, 102 insertions(+), 73 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/TranslatablePanel.java b/Core/src/org/sleuthkit/autopsy/contentviewers/TranslatablePanel.java index 48c4006785..9a6860eabd 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/TranslatablePanel.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/TranslatablePanel.java @@ -61,49 +61,22 @@ final class TranslatablePanel extends JPanel { } - /** - * describes a component that will allow for translation that has String-based content - */ - interface TranslatableComponent { - /** - * @return the underlying component to be added to TranslatablePanel as a parent - */ - Component getComponent(); - - - /** - * set the content for this subcomponent - * @param content the original content for the component; when this is reset, there is no translation initially - * @return if non-null string, this string will appear as error message - */ - String setContent(String content); - String getContent(); - - - /** - * sets the state of this component to translated - * @param translate whether or not to translate this component - * @return if non-null string, this string will appear as error message - */ - String setTranslated(boolean translate); - boolean isTranslated(); - } - - private static final long serialVersionUID = 1L; private final ImageIcon warningIcon = new ImageIcon(TranslatablePanel.class.getResource("/org/sleuthkit/autopsy/images/warning16.png")); - private final TranslatableComponent subcomponent; + private final ContentSetter onContent; + private final Component subcomponent; private final String origOptionText; private final String translatedOptionText; private final TextTranslationService translationService; @Messages({"TranslatablePanel.comboBoxOption.originalText=Original Text", "TranslatablePanel.comboBoxOption.translatedText=Translated Text"}) - TranslatablePanel(TranslatableComponent subcomponent) { + TranslatablePanel(Component subcomponent, ContentSetter onContent) { this( - subcomponent, + subcomponent, + onContent, Bundle.TranslatablePanel_comboBoxOption_originalText(), Bundle.TranslatablePanel_comboBoxOption_translatedText(), null, @@ -113,9 +86,10 @@ final class TranslatablePanel extends JPanel { /** * Creates new form TranslatedContentPanel */ - TranslatablePanel(TranslatableComponent subcomponent, String origOptionText, String translatedOptionText, String origContent, + TranslatablePanel(Component subcomponent, ContentSetter onContent, String origOptionText, String translatedOptionText, String origContent, TextTranslationService translationService) { this.subcomponent = subcomponent; + this.onContent = onContent; this.origOptionText = origOptionText; this.translatedOptionText = translatedOptionText; this.translationService = translationService; @@ -146,7 +120,7 @@ final class TranslatablePanel extends JPanel { void setContent(String content) { this.translateComboBox.setSelectedIndex(0); SwingUtilities.invokeLater(() -> { - String errMess = this.subcomponent.setContent(content); + String errMess = this.onContent.set(content); setWarningLabelMsg(errMess); }); } @@ -154,7 +128,7 @@ final class TranslatablePanel extends JPanel { private void additionalInit() { - add(this.subcomponent.getComponent(), java.awt.BorderLayout.CENTER); + add(this.subcomponent, java.awt.BorderLayout.CENTER); setWarningLabelMsg(null); translateComboBox.removeAllItems(); translateComboBox.addItem(new TranslateOption(this.origOptionText, false)); @@ -163,7 +137,7 @@ final class TranslatablePanel extends JPanel { private void handleComboBoxChange(TranslateOption translateOption) { SwingUtilities.invokeLater(() -> { - String errMess = this.subcomponent.setTranslated(translateOption.shouldTranslate()); + String errMess = this.onContent.set(translateOption.shouldTranslate()); setWarningLabelMsg(errMess); }); } diff --git a/Core/src/org/sleuthkit/autopsy/texttranslation/ui/TranslateTextTask.java b/Core/src/org/sleuthkit/autopsy/texttranslation/ui/TranslateTextTask.java index ddfcc5b155..a912b0e346 100644 --- a/Core/src/org/sleuthkit/autopsy/texttranslation/ui/TranslateTextTask.java +++ b/Core/src/org/sleuthkit/autopsy/texttranslation/ui/TranslateTextTask.java @@ -20,11 +20,13 @@ package org.sleuthkit.autopsy.texttranslation.ui; import java.awt.ComponentOrientation; import java.awt.Font; +import java.io.IOException; import java.util.concurrent.CancellationException; import java.util.concurrent.ExecutionException; import java.util.logging.Level; import javax.swing.SwingUtilities; import javax.swing.SwingWorker; +import org.openide.util.Exceptions; import org.openide.util.NbBundle; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.TextUtil; @@ -35,17 +37,39 @@ import org.sleuthkit.autopsy.texttranslation.TranslationException; /** * abstract class for translating text and displaying to the user */ -public abstract class TranslateTextTask extends SwingWorker { +public abstract class TranslateTextTask extends SwingWorker { private static final Logger logger = Logger.getLogger(TranslatedTextViewer.class.getName()); private final boolean translateText; private final String contentDescriptor; + /** + * as a result of running and processing the translation + */ + static class Result { + public final String errorMessage; + public final String result; + public final boolean successful; + + public static Result error(String message) { + return new Result(null, message, false); + } + + public static Result success(String content) { + return new Result(content, null, true); + } + + private Result(String result, String errorMessage, boolean successful) { + this.successful = successful; + this.errorMessage = errorMessage; + this.result = result; + } + } /** * * @param translateText whether or not to translate text - * @param contentDescriptor the content descriptor for the item being translated (used for logging errors) + * @param contentDescriptor the content descriptor for the item being translated (used for logging errors) */ public TranslateTextTask(boolean translateText, String fileDescriptor) { this.translateText = translateText; @@ -53,36 +77,31 @@ public abstract class TranslateTextTask extends SwingWorker { } - protected abstract String retrieveText() throws Exception; + protected abstract String retrieveText() throws IOException, InterruptedException, IllegalStateException; protected abstract void onTextDisplay(String text, ComponentOrientation orientation, int font); + protected void onErrorDisplay(String text, ComponentOrientation orientation, int font) { + onTextDisplay(text, orientation, font); + } + @NbBundle.Messages({ - "TranslatedContentViewer.extractingText=Extracting text, please wait...", "TranslatedContentViewer.translatingText=Translating text, please wait...", - "# {0} - exception message", "TranslatedContentViewer.errorExtractingText=An error occurred while extracting the text ({0}).", "TranslatedContentViewer.fileHasNoText=File has no text.", "TranslatedContentViewer.noServiceProvider=The machine translation software was not found.", "# {0} - exception message", "TranslatedContentViewer.translationException=An error occurred while translating the text ({0})." }) @Override - public String doInBackground() throws InterruptedException { - if (this.isCancelled()) { + public Result doInBackground() throws InterruptedException { + if (this.isCancelled()) { throw new InterruptedException(); } - - SwingUtilities.invokeLater(() -> { - onTextDisplay(Bundle.TranslatedContentViewer_extractingText(), ComponentOrientation.LEFT_TO_RIGHT, Font.ITALIC); - }); - String fileText; + + String fileText; try { fileText = retrieveText(); - } catch (InterruptedException | CancellationException e) { - // bubble up cancellation instead of continuing - throw e; - } catch (Exception ex) { - logger.log(Level.WARNING, "Error extracting text for file " + this.contentDescriptor, ex); - return Bundle.TranslatedContentViewer_errorExtractingText(ex.getMessage()); + } catch (IOException | IllegalStateException ex) { + return Result.error(ex.getMessage()); } if (this.isCancelled()) { @@ -90,52 +109,58 @@ public abstract class TranslateTextTask extends SwingWorker { } if (fileText == null || fileText.isEmpty()) { - return Bundle.TranslatedContentViewer_fileHasNoText(); + return Result.error(Bundle.TranslatedContentViewer_fileHasNoText()); } if (!this.translateText) { - return fileText; + return Result.success(fileText); } SwingUtilities.invokeLater(() -> { onTextDisplay(Bundle.TranslatedContentViewer_translatingText(), ComponentOrientation.LEFT_TO_RIGHT, Font.ITALIC); }); - String translation; + Result translationResult; try { - translation = translate(fileText); + translationResult = translate(fileText); } catch (NoServiceProviderException ex) { logger.log(Level.WARNING, "Error translating text for file " + this.contentDescriptor, ex); - translation = Bundle.TranslatedContentViewer_noServiceProvider(); + translationResult = Result.error(Bundle.TranslatedContentViewer_noServiceProvider()); } catch (TranslationException ex) { logger.log(Level.WARNING, "Error translating text for file " + this.contentDescriptor, ex); - translation = Bundle.TranslatedContentViewer_translationException(ex.getMessage()); + translationResult = Result.error(Bundle.TranslatedContentViewer_translationException(ex.getMessage())); } if (this.isCancelled()) { throw new InterruptedException(); } - return translation; + return translationResult; } @Override public void done() { try { - String result = get(); + Result executionResult = get(); if (this.isCancelled()) { throw new InterruptedException(); } - int len = result.length(); - int maxOrientChars = Math.min(len, 1024); - String orientDetectSubstring = result.substring(0, maxOrientChars); - ComponentOrientation orientation = TextUtil.getTextDirection(orientDetectSubstring); - onTextDisplay(result, orientation, Font.PLAIN); - + + if (executionResult.successful) { + String result = executionResult.result; + int len = result.length(); + int maxOrientChars = Math.min(len, 1024); + String orientDetectSubstring = result.substring(0, maxOrientChars); + ComponentOrientation orientation = TextUtil.getTextDirection(orientDetectSubstring); + onTextDisplay(result, orientation, Font.PLAIN); + } + else { + onErrorDisplay(executionResult.errorMessage, ComponentOrientation.LEFT_TO_RIGHT, Font.ITALIC); + } } catch (InterruptedException | CancellationException ignored) { // Task cancelled, no error. } catch (ExecutionException ex) { logger.log(Level.WARNING, "Error occurred during background task execution for file " + this.contentDescriptor, ex); - onTextDisplay(Bundle.TranslatedContentViewer_translationException(ex.getMessage()), ComponentOrientation.LEFT_TO_RIGHT, Font.ITALIC); + onErrorDisplay(Bundle.TranslatedContentViewer_translationException(ex.getMessage()), ComponentOrientation.LEFT_TO_RIGHT, Font.ITALIC); } } @@ -149,12 +174,12 @@ public abstract class TranslateTextTask extends SwingWorker { @NbBundle.Messages({ "TranslatedContentViewer.emptyTranslation=The machine translation software did not return any text." }) - private String translate(String input) throws NoServiceProviderException, TranslationException { + private Result translate(String input) throws NoServiceProviderException, TranslationException { TextTranslationService translatorInstance = TextTranslationService.getInstance(); String translatedResult = translatorInstance.translate(input); if (translatedResult.isEmpty()) { - return Bundle.TranslatedContentViewer_emptyTranslation(); + return Result.error(Bundle.TranslatedContentViewer_emptyTranslation()); } - return translatedResult; + return Result.success(translatedResult); } } diff --git a/Core/src/org/sleuthkit/autopsy/texttranslation/ui/TranslatedTextViewer.java b/Core/src/org/sleuthkit/autopsy/texttranslation/ui/TranslatedTextViewer.java index ecae3645c3..864a2ed860 100644 --- a/Core/src/org/sleuthkit/autopsy/texttranslation/ui/TranslatedTextViewer.java +++ b/Core/src/org/sleuthkit/autopsy/texttranslation/ui/TranslatedTextViewer.java @@ -178,8 +178,38 @@ public final class TranslatedTextViewer implements TextViewer { * * @throws Exception */ - protected String retrieveText() throws Exception { + @NbBundle.Messages({ + "TranslatedContentViewer.extractingText=Extracting text, please wait...", + "# {0} - exception message", "TranslatedContentViewer.errorExtractingText=An error occurred while extracting the text ({0}).", + }) + protected String retrieveText() throws IOException, InterruptedException, IllegalStateException { + SwingUtilities.invokeLater(() -> { + onTextDisplay(Bundle.TranslatedContentViewer_extractingText(), ComponentOrientation.LEFT_TO_RIGHT, Font.ITALIC); + }); + try { + return getFileText(file); + } catch (IOException | TextExtractor.InitReaderException ex) { + logger.log(Level.WARNING, String.format("Error extracting text for file %s (objId=%d)", file.getName(), file.getId()), ex); + // throw new exception with message to be displayed to user + throw new IllegalStateException(Bundle.TranslatedContentViewer_errorExtractingText(ex.getMessage()), ex); + } + } + + + /** + * Extracts text from the given node + * + * @param file Selected node in UI + * + * @return Extracted text + * + * @throws IOException + * @throws InterruptedException + * @throws + * org.sleuthkit.autopsy.textextractors.TextExtractor.InitReaderException + */ + private String getFileText(AbstractFile file) throws IOException, InterruptedException, TextExtractor.InitReaderException { final boolean isImage = file.getMIMEType().toLowerCase().startsWith("image/"); // NON-NLS String result; if (isImage) { From 34f49c9840af3cf0731dc931ecf1887c9b34b026 Mon Sep 17 00:00:00 2001 From: Mark McKinnon Date: Thu, 5 Mar 2020 11:29:42 -0500 Subject: [PATCH 36/97] Indent goto button and change on to at indented goto button more and change text from on to at --- .../contextviewer/Bundle.properties-MERGED | 4 +- .../contextviewer/ContextViewer.form | 54 ++++++++++--------- .../contextviewer/ContextViewer.java | 44 +++++++-------- 3 files changed, 53 insertions(+), 49 deletions(-) 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 aafa549431..76df8c7b3c 100755 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/Bundle.properties-MERGED @@ -15,8 +15,8 @@ ContextViewer.message=Message ContextViewer.messageFrom=From ContextViewer.messageOn=On ContextViewer.messageTo=To -ContextViewer.on=Opened on +ContextViewer.on=Opened at ContextViewer.recentDocs=Recent Documents: ContextViewer.title=Context ContextViewer.toolTip=Displays context for selected file. -ContextViewer.unknown=Opened on unknown time +ContextViewer.unknown=Opened at unknown time diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextViewer.form b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextViewer.form index ab4771fc71..020705e938 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextViewer.form +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextViewer.form @@ -24,36 +24,38 @@ - + + + + - - + + + + + - - - - - - - - - - - - - + + + - - - - - - - - + + + + + + + + + + + + + + @@ -76,9 +78,9 @@
- + - +
diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextViewer.java b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextViewer.java index 0e8e03f5b1..0c457be704 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextViewer.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/ContextViewer.java @@ -125,27 +125,29 @@ public final class ContextViewer extends javax.swing.JPanel implements DataConte .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) - .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)) + .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() - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(jSourceGoToResultButton) - .addComponent(jUsageGoToResultButton)) - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))) + .addGap(45, 45, 45) + .addComponent(jUsageGoToResultButton)) + .addGroup(layout.createSequentialGroup() + .addGap(46, 46, 46) + .addComponent(jSourceGoToResultButton))) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) @@ -164,9 +166,9 @@ public final class ContextViewer extends javax.swing.JPanel implements DataConte .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(jUsageNameLabel) .addComponent(jUsageTextLabel)) - .addGap(18, 18, 18) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jUsageGoToResultButton) - .addGap(0, 60, Short.MAX_VALUE)) + .addGap(0, 62, Short.MAX_VALUE)) ); }// //GEN-END:initComponents @@ -450,8 +452,8 @@ public final class ContextViewer extends javax.swing.JPanel implements DataConte * @throws TskCoreException */ @NbBundle.Messages({ - "ContextViewer.on=Opened on", - "ContextViewer.unknown=Opened on unknown time" + "ContextViewer.on=Opened at", + "ContextViewer.unknown=Opened at unknown time" }) private String recentDocArtifactToString(BlackboardArtifact artifact) throws TskCoreException { StringBuilder sb = new StringBuilder(ARTIFACT_STR_MAX_LEN); From 1989451aa0914776f9c9f6d46ecc22d4838c527d Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Thu, 5 Mar 2020 12:53:07 -0500 Subject: [PATCH 37/97] working through translatable panel and extracting translate text task --- .../contentviewers/TranslatablePanel.form | 2 +- .../contentviewers/TranslatablePanel.java | 192 ++++++++++++-- .../texttranslation/ui/TranslateTextTask.java | 247 ++++++++++-------- .../ui/TranslatedTextViewer.java | 2 +- 4 files changed, 303 insertions(+), 140 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/TranslatablePanel.form b/Core/src/org/sleuthkit/autopsy/contentviewers/TranslatablePanel.form index 45eb156e87..cd272658bf 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/TranslatablePanel.form +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/TranslatablePanel.form @@ -79,7 +79,7 @@ - + diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/TranslatablePanel.java b/Core/src/org/sleuthkit/autopsy/contentviewers/TranslatablePanel.java index 9a6860eabd..b6a3a7d78b 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/TranslatablePanel.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/TranslatablePanel.java @@ -18,26 +18,37 @@ */ package org.sleuthkit.autopsy.contentviewers; +import com.google.common.util.concurrent.ThreadFactoryBuilder; import java.awt.Component; +import java.awt.ComponentOrientation; +import java.awt.Font; +import java.io.IOException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.ThreadFactory; import javax.swing.ImageIcon; -import org.apache.commons.lang.StringUtils; import javax.swing.JPanel; import javax.swing.SwingUtilities; import org.openide.util.NbBundle.Messages; +import org.sleuthkit.autopsy.texttranslation.NoServiceProviderException; import org.sleuthkit.autopsy.texttranslation.TextTranslationService; +import org.sleuthkit.autopsy.texttranslation.TranslationException; +import org.sleuthkit.autopsy.texttranslation.ui.TranslateTextTask; /** * A panel for translation with a subcomponent that allows for translation */ final class TranslatablePanel extends JPanel { + + interface ContentSetter { - void set(String content) throws Exception; + void set(String content, ComponentOrientation orientation, int font) throws Exception; } /** * an option in drop down of whether or not to translate */ - private class TranslateOption { + private static class TranslateOption { private final String text; private final boolean translate; @@ -60,9 +71,65 @@ final class TranslatablePanel extends JPanel { } } + private static class TranslatedText { + private final String text; + private final ComponentOrientation orientation; + + public TranslatedText(String text, ComponentOrientation orientation) { + this.text = text; + this.orientation = orientation; + } + + public String getText() { + return text; + } + + public ComponentOrientation getOrientation() { + return orientation; + } + } + + private class OnTranslation extends TranslateTextTask { + public OnTranslation() { + super(true, contentDescriptor == null ? "" : contentDescriptor); + } + + @Override + protected String translate(String input) throws NoServiceProviderException, TranslationException { + // defer to outer class method so that it can be overridden for items like html, rtf, etc. + return retrieveTranslation(input); + } + + @Override + protected void onProgressDisplay(String text, ComponentOrientation orientation, int font) { + setStatus(text, false); + } + + @Override + protected void onErrorDisplay(String text, ComponentOrientation orientation, int font) { + setStatus(text, true); + } + + @Override + protected String retrieveText() throws IOException, InterruptedException, IllegalStateException { + return content == null ? "" : content; + } + + @Override + protected void onTextDisplay(String text, ComponentOrientation orientation, int font) { + // on successful acquire cache the result and set the text + setCachedTranslated(new TranslatedText(text, orientation)); + setSubcomponentContent(text, orientation, font); + } + } + private static final long serialVersionUID = 1L; + private static final ComponentOrientation DEFAULT_ORIENTATION = ComponentOrientation.LEFT_TO_RIGHT; + private static final int DEFAULT_FONT = Font.PLAIN; + + private final ImageIcon warningIcon = new ImageIcon(TranslatablePanel.class.getResource("/org/sleuthkit/autopsy/images/warning16.png")); private final ContentSetter onContent; @@ -70,6 +137,16 @@ final class TranslatablePanel extends JPanel { private final String origOptionText; private final String translatedOptionText; private final TextTranslationService translationService; + private final ThreadFactory translationThreadFactory = new ThreadFactoryBuilder().setNameFormat("translatable-panel-%d").build(); + private final ExecutorService executorService = Executors.newSingleThreadExecutor(translationThreadFactory); + + + private String content; + private String contentDescriptor; + private volatile TranslatedText cachedTranslated; + private volatile OnTranslation backgroundTask = null; + + @Messages({"TranslatablePanel.comboBoxOption.originalText=Original Text", "TranslatablePanel.comboBoxOption.translatedText=Translated Text"}) @@ -97,48 +174,115 @@ final class TranslatablePanel extends JPanel { initComponents(); additionalInit(); setTranslationBarVisible(); - setContent(origContent); + reset(); } + private TranslatedText getCachedTranslated() { + synchronized(cachedTranslated) { + return cachedTranslated; + } + } + + private void setCachedTranslated(TranslatedText translated) { + synchronized(cachedTranslated) { + this.cachedTranslated = translated; + } + } + + private synchronized void cancelPendingTranslation() { + if (backgroundTask != null && !backgroundTask.isDone()) { + backgroundTask.cancel(true); + } + backgroundTask = null; + } + + private synchronized void runTranslationTask() { + cancelPendingTranslation(); + backgroundTask = new OnTranslation(); + + //Pass the background task to a single threaded pool to keep + //the number of jobs running to one. + executorService.execute(backgroundTask); + } + + + void reset() { + setTranslationBarVisible(); + setContent(null, null); + } + + void setContent(String content, String contentDescriptor) { + cancelPendingTranslation(); + this.translateComboBox.setSelectedIndex(0); + this.content = content; + this.contentDescriptor = contentDescriptor; + setStatus(null, false); + setCachedTranslated(null); + setSubcomponentContent(content); + } - private void setWarningLabelMsg(String msg) { - boolean hasWarning = !StringUtils.isEmpty(msg); - warningLabel.setText(hasWarning ? msg : ""); - warningLabel.setIcon(hasWarning ? warningIcon : null); + /** + * where actual translation takes place + * allowed to be overridden for the sake of varying translatable content (i.e. html, rtf, etc) + * @param input the input content + * @return the result of translation + * @throws TranslationException + * @throws NoServiceProviderException + */ + protected String retrieveTranslation(String input) throws TranslationException, NoServiceProviderException { + return translationService.translate(input); + } + + + + private void setStatus(String msg, boolean showWarningIcon) { + statusLabel.setText(msg); + statusLabel.setIcon(showWarningIcon ? warningIcon : null); } private void setTranslationBarVisible() { translationBar.setVisible(this.translationService.hasProvider()); } - void reset() { - setTranslationBarVisible(); - setContent(null); + private void setSubcomponentContent(String content) { + setSubcomponentContent(content, DEFAULT_ORIENTATION, DEFAULT_FONT); } - void setContent(String content) { - this.translateComboBox.setSelectedIndex(0); + @Messages({"# {0} - exception message", "TranslatablePanel.onSetContentError.text=There was an error displaying the text: {0}"}) + private void setSubcomponentContent(String content, ComponentOrientation orientation, int font) { SwingUtilities.invokeLater(() -> { - String errMess = this.onContent.set(content); - setWarningLabelMsg(errMess); + try { + this.onContent.set(content, orientation, font); + } catch (Exception ex) { + setStatus(Bundle.TranslatablePanel_onSetContentError_text(ex.getMessage()), true); + } }); } - - private void additionalInit() { add(this.subcomponent, java.awt.BorderLayout.CENTER); - setWarningLabelMsg(null); + setStatus(null, false); translateComboBox.removeAllItems(); translateComboBox.addItem(new TranslateOption(this.origOptionText, false)); translateComboBox.addItem(new TranslateOption(this.translatedOptionText, true)); } private void handleComboBoxChange(TranslateOption translateOption) { + cancelPendingTranslation(); SwingUtilities.invokeLater(() -> { - String errMess = this.onContent.set(translateOption.shouldTranslate()); - setWarningLabelMsg(errMess); + if (translateOption.shouldTranslate()) { + TranslatedText translated = getCachedTranslated(); + if (translated != null) { + setSubcomponentContent(translated.getText(), translated.getOrientation(), DEFAULT_FONT); + } + else { + runTranslationTask(); + } + } + else { + setSubcomponentContent(content); + } }); } @@ -154,7 +298,7 @@ final class TranslatablePanel extends JPanel { translationBar = new javax.swing.JPanel(); translateComboBox = new javax.swing.JComboBox<>(); - warningLabel = new javax.swing.JLabel(); + statusLabel = new javax.swing.JLabel(); setMaximumSize(new java.awt.Dimension(2000, 2000)); setMinimumSize(new java.awt.Dimension(2, 2)); @@ -179,8 +323,8 @@ final class TranslatablePanel extends JPanel { }); translationBar.add(translateComboBox, java.awt.BorderLayout.LINE_END); - warningLabel.setMaximumSize(new java.awt.Dimension(32767, 32767)); - translationBar.add(warningLabel, java.awt.BorderLayout.CENTER); + statusLabel.setMaximumSize(new java.awt.Dimension(32767, 32767)); + translationBar.add(statusLabel, java.awt.BorderLayout.CENTER); add(translationBar, java.awt.BorderLayout.NORTH); }// //GEN-END:initComponents @@ -190,8 +334,8 @@ final class TranslatablePanel extends JPanel { }//GEN-LAST:event_translateComboBoxActionPerformed // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JLabel statusLabel; private javax.swing.JComboBox translateComboBox; private javax.swing.JPanel translationBar; - private javax.swing.JLabel warningLabel; // End of variables declaration//GEN-END:variables } \ No newline at end of file diff --git a/Core/src/org/sleuthkit/autopsy/texttranslation/ui/TranslateTextTask.java b/Core/src/org/sleuthkit/autopsy/texttranslation/ui/TranslateTextTask.java index a912b0e346..f5056196e1 100644 --- a/Core/src/org/sleuthkit/autopsy/texttranslation/ui/TranslateTextTask.java +++ b/Core/src/org/sleuthkit/autopsy/texttranslation/ui/TranslateTextTask.java @@ -26,7 +26,6 @@ import java.util.concurrent.ExecutionException; import java.util.logging.Level; import javax.swing.SwingUtilities; import javax.swing.SwingWorker; -import org.openide.util.Exceptions; import org.openide.util.NbBundle; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.TextUtil; @@ -35,151 +34,171 @@ import org.sleuthkit.autopsy.texttranslation.TextTranslationService; import org.sleuthkit.autopsy.texttranslation.TranslationException; /** -* abstract class for translating text and displaying to the user -*/ + * abstract class for translating text and displaying to the user + */ public abstract class TranslateTextTask extends SwingWorker { - private static final Logger logger = Logger.getLogger(TranslatedTextViewer.class.getName()); - private final boolean translateText; - private final String contentDescriptor; - - /** - * as a result of running and processing the translation - */ - static class Result { - public final String errorMessage; - public final String result; - public final boolean successful; - - public static Result error(String message) { - return new Result(null, message, false); - } - - public static Result success(String content) { - return new Result(content, null, true); - } - + private static final Logger logger = Logger.getLogger(TranslatedTextViewer.class.getName()); + + private final boolean translateText; + private final String contentDescriptor; + + /** + * as a result of running and processing the translation + */ + public static class Result { + + private final String errorMessage; + private final String result; + private final boolean successful; + + public static Result error(String message) { + return new Result(null, message, false); + } + + public static Result success(String content) { + return new Result(content, null, true); + } + private Result(String result, String errorMessage, boolean successful) { this.successful = successful; this.errorMessage = errorMessage; this.result = result; } - } - /** - * - * @param translateText whether or not to translate text - * @param contentDescriptor the content descriptor for the item being translated (used for logging errors) - */ + public String getErrorMessage() { + return errorMessage; + } + + public String getResult() { + return result; + } + + public boolean isSuccessful() { + return successful; + } + + } + + /** + * + * @param translateText whether or not to translate text + * @param contentDescriptor the content descriptor for the item being + * translated (used for logging errors) + */ public TranslateTextTask(boolean translateText, String fileDescriptor) { this.translateText = translateText; this.contentDescriptor = fileDescriptor; } - protected abstract String retrieveText() throws IOException, InterruptedException, IllegalStateException; - + protected abstract void onTextDisplay(String text, ComponentOrientation orientation, int font); - protected void onErrorDisplay(String text, ComponentOrientation orientation, int font) { + protected void onProgressDisplay(String text, ComponentOrientation orientation, int font) { + // default to normal display unless overridden onTextDisplay(text, orientation, font); } - @NbBundle.Messages({ - "TranslatedContentViewer.translatingText=Translating text, please wait...", - "TranslatedContentViewer.fileHasNoText=File has no text.", - "TranslatedContentViewer.noServiceProvider=The machine translation software was not found.", - "# {0} - exception message", "TranslatedContentViewer.translationException=An error occurred while translating the text ({0})." - }) - @Override - public Result doInBackground() throws InterruptedException { + protected void onErrorDisplay(String text, ComponentOrientation orientation, int font) { + // default to normal display unless overridden + onTextDisplay(text, orientation, font); + } + + @NbBundle.Messages({ + "TranslatedContentViewer.translatingText=Translating text, please wait...", + "TranslatedContentViewer.fileHasNoText=File has no text.", + "TranslatedContentViewer.noServiceProvider=The machine translation software was not found.", + "# {0} - exception message", "TranslatedContentViewer.translationException=An error occurred while translating the text ({0})." + }) + @Override + public Result doInBackground() throws InterruptedException { if (this.isCancelled()) { - throw new InterruptedException(); - } - + throw new InterruptedException(); + } + String fileText; - try { - fileText = retrieveText(); - } catch (IOException | IllegalStateException ex) { - return Result.error(ex.getMessage()); - } + try { + fileText = retrieveText(); + } catch (IOException | IllegalStateException ex) { + return Result.error(ex.getMessage()); + } - if (this.isCancelled()) { - throw new InterruptedException(); - } + if (this.isCancelled()) { + throw new InterruptedException(); + } - if (fileText == null || fileText.isEmpty()) { - return Result.error(Bundle.TranslatedContentViewer_fileHasNoText()); - } + if (fileText == null || fileText.isEmpty()) { + return Result.error(Bundle.TranslatedContentViewer_fileHasNoText()); + } - if (!this.translateText) { - return Result.success(fileText); - } + if (!this.translateText) { + return Result.success(fileText); + } - SwingUtilities.invokeLater(() -> { - onTextDisplay(Bundle.TranslatedContentViewer_translatingText(), ComponentOrientation.LEFT_TO_RIGHT, Font.ITALIC); - }); - Result translationResult; - try { - translationResult = translate(fileText); - } catch (NoServiceProviderException ex) { - logger.log(Level.WARNING, "Error translating text for file " + this.contentDescriptor, ex); - translationResult = Result.error(Bundle.TranslatedContentViewer_noServiceProvider()); - } catch (TranslationException ex) { - logger.log(Level.WARNING, "Error translating text for file " + this.contentDescriptor, ex); - translationResult = Result.error(Bundle.TranslatedContentViewer_translationException(ex.getMessage())); - } + SwingUtilities.invokeLater(() -> { + onProgressDisplay(Bundle.TranslatedContentViewer_translatingText(), ComponentOrientation.LEFT_TO_RIGHT, Font.ITALIC); + }); - if (this.isCancelled()) { - throw new InterruptedException(); - } + try { + String translation = translate(fileText); + if (this.isCancelled()) { + throw new InterruptedException(); + } - return translationResult; - } + if (translation == null || translation.isEmpty()) { + return Result.error(Bundle.TranslatedContentViewer_emptyTranslation()); + } else { + return Result.success(translation); + } - @Override - public void done() { - try { - Result executionResult = get(); - if (this.isCancelled()) { - throw new InterruptedException(); - } - - if (executionResult.successful) { - String result = executionResult.result; + } catch (NoServiceProviderException ex) { + logger.log(Level.WARNING, "Error translating text for file " + this.contentDescriptor, ex); + return Result.error(Bundle.TranslatedContentViewer_noServiceProvider()); + } catch (TranslationException ex) { + logger.log(Level.WARNING, "Error translating text for file " + this.contentDescriptor, ex); + return Result.error(Bundle.TranslatedContentViewer_translationException(ex.getMessage())); + } + } + + @Override + public void done() { + try { + Result executionResult = get(); + if (this.isCancelled()) { + throw new InterruptedException(); + } + + if (executionResult.isSuccessful()) { + String result = executionResult.getResult(); int len = result.length(); int maxOrientChars = Math.min(len, 1024); String orientDetectSubstring = result.substring(0, maxOrientChars); ComponentOrientation orientation = TextUtil.getTextDirection(orientDetectSubstring); onTextDisplay(result, orientation, Font.PLAIN); - } - else { - onErrorDisplay(executionResult.errorMessage, ComponentOrientation.LEFT_TO_RIGHT, Font.ITALIC); - } - } catch (InterruptedException | CancellationException ignored) { - // Task cancelled, no error. - } catch (ExecutionException ex) { - logger.log(Level.WARNING, "Error occurred during background task execution for file " + this.contentDescriptor, ex); - onErrorDisplay(Bundle.TranslatedContentViewer_translationException(ex.getMessage()), ComponentOrientation.LEFT_TO_RIGHT, Font.ITALIC); - } - } + } else { + onErrorDisplay(executionResult.getErrorMessage(), ComponentOrientation.LEFT_TO_RIGHT, Font.ITALIC); + } + } catch (InterruptedException | CancellationException ignored) { + // Task cancelled, no error. + } catch (ExecutionException ex) { + logger.log(Level.WARNING, "Error occurred during background task execution for file " + this.contentDescriptor, ex); + onErrorDisplay(Bundle.TranslatedContentViewer_translationException(ex.getMessage()), ComponentOrientation.LEFT_TO_RIGHT, Font.ITALIC); + } + } - /** - * Pass the translation off to the Translation service provider. - * - * @param input Text to be translated - * - * @return Translated text or error message - */ - @NbBundle.Messages({ - "TranslatedContentViewer.emptyTranslation=The machine translation software did not return any text." - }) - private Result translate(String input) throws NoServiceProviderException, TranslationException { - TextTranslationService translatorInstance = TextTranslationService.getInstance(); - String translatedResult = translatorInstance.translate(input); - if (translatedResult.isEmpty()) { - return Result.error(Bundle.TranslatedContentViewer_emptyTranslation()); - } - return Result.success(translatedResult); - } + /** + * Pass the translation off to the Translation service provider. + * + * @param input Text to be translated + * + * @return Translated text or error message + */ + @NbBundle.Messages({ + "TranslatedContentViewer.emptyTranslation=The machine translation software did not return any text." + }) + protected String translate(String input) throws NoServiceProviderException, TranslationException { + TextTranslationService translatorInstance = TextTranslationService.getInstance(); + return translatorInstance.translate(input); + } } diff --git a/Core/src/org/sleuthkit/autopsy/texttranslation/ui/TranslatedTextViewer.java b/Core/src/org/sleuthkit/autopsy/texttranslation/ui/TranslatedTextViewer.java index 864a2ed860..a913cacf38 100644 --- a/Core/src/org/sleuthkit/autopsy/texttranslation/ui/TranslatedTextViewer.java +++ b/Core/src/org/sleuthkit/autopsy/texttranslation/ui/TranslatedTextViewer.java @@ -184,7 +184,7 @@ public final class TranslatedTextViewer implements TextViewer { }) protected String retrieveText() throws IOException, InterruptedException, IllegalStateException { SwingUtilities.invokeLater(() -> { - onTextDisplay(Bundle.TranslatedContentViewer_extractingText(), ComponentOrientation.LEFT_TO_RIGHT, Font.ITALIC); + onProgressDisplay(Bundle.TranslatedContentViewer_extractingText(), ComponentOrientation.LEFT_TO_RIGHT, Font.ITALIC); }); try { From 98941ab783b7043bc57328f94e1758fe2f056b80 Mon Sep 17 00:00:00 2001 From: Raman Arora Date: Thu, 5 Mar 2020 13:21:52 -0500 Subject: [PATCH 38/97] Use try-with-resources for resource management. --- .../datamodel/RdbmsCentralRepoFactory.java | 35 ++++--------------- 1 file changed, 7 insertions(+), 28 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/RdbmsCentralRepoFactory.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/RdbmsCentralRepoFactory.java index 09f103a038..66227ea366 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/RdbmsCentralRepoFactory.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/RdbmsCentralRepoFactory.java @@ -774,10 +774,8 @@ public class RdbmsCentralRepoFactory { * @return True if success, false otherwise. */ private boolean insertDefaultAccountsTablesContent(Connection conn) { - Statement stmt = null; - try { - stmt = conn.createStatement(); - + + try (Statement stmt = conn.createStatement()) { // Populate the account_types table for (Account.Type type : Account.Type.PREDEFINED_ACCOUNT_TYPES) { int correlationTypeId = getCorrelationTypeIdForAccountType(conn, type); @@ -790,16 +788,8 @@ public class RdbmsCentralRepoFactory { } catch (SQLException ex) { LOGGER.log(Level.SEVERE, String.format("Failed to populate default data in Accounts tables."), ex); return false; - } finally { - if (stmt != null) { - try { - stmt.close(); - } catch (SQLException ex2) { - LOGGER.log(Level.SEVERE, "Error closing statement.", ex2); - } - } - } - + } + return true; } @@ -812,10 +802,7 @@ public class RdbmsCentralRepoFactory { */ private boolean insertDefaultPersonaTablesContent(Connection conn) { - Statement stmt = null; - try { - stmt = conn.createStatement(); - + try (Statement stmt = conn.createStatement()) { // populate the confidence table for (Confidence confidence : Persona.Confidence.values()) { String sqlString = "INSERT INTO confidence (confidence_id, description) VALUES ( " + confidence.getLevel() + ", '" + confidence.toString() + "')" //NON-NLS @@ -833,16 +820,8 @@ public class RdbmsCentralRepoFactory { } catch (SQLException ex) { LOGGER.log(Level.SEVERE, String.format("Failed to populate default data in Persona tables."), ex); return false; - } finally { - if (stmt != null) { - try { - stmt.close(); - } catch (SQLException ex2) { - LOGGER.log(Level.SEVERE, "Error closing statement.", ex2); - } - } - } - + } + return true; } From 93f003522f3c70e77ca27f510fa8a05be4bd0e83 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Thu, 5 Mar 2020 16:05:58 -0500 Subject: [PATCH 39/97] reworked panel --- .../contentviewers/MessageContentViewer.form | 5 - .../contentviewers/MessageContentViewer.java | 110 +++++----- .../TextTranslatableComponent.java | 123 ----------- .../contentviewers/TranslatablePanel.java | 204 ++++++++++-------- .../ui/TranslatedTextViewer.java | 6 - 5 files changed, 172 insertions(+), 276 deletions(-) delete mode 100644 Core/src/org/sleuthkit/autopsy/contentviewers/TextTranslatableComponent.java diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.form b/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.form index f0a971c143..c8ff9674c7 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.form +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.form @@ -202,11 +202,6 @@ - - - - - diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java b/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java index ae26576c35..e1190aaefd 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java @@ -20,9 +20,9 @@ package org.sleuthkit.autopsy.contentviewers; import org.sleuthkit.autopsy.datamodel.AttachmentNode; import com.google.gson.Gson; -import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; +import java.awt.ComponentOrientation; import java.util.Arrays; import java.util.Collection; import java.util.HashSet; @@ -30,6 +30,7 @@ import java.util.List; import java.util.Optional; import java.util.Set; import java.util.logging.Level; +import javax.swing.JScrollPane; import javax.swing.text.JTextComponent; import org.apache.commons.lang3.StringUtils; import org.jsoup.Jsoup; @@ -39,10 +40,12 @@ import org.openide.nodes.AbstractNode; import org.openide.nodes.Children; import org.openide.nodes.Node; import org.openide.util.NbBundle; +import org.openide.util.NbBundle.Messages; 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.corecomponents.AutoWrappingJTextPane; import org.sleuthkit.autopsy.corecomponents.DataResultPanel; import org.sleuthkit.autopsy.corecomponents.TableFilterNode; import org.sleuthkit.autopsy.coreutils.Logger; @@ -84,20 +87,36 @@ import org.sleuthkit.datamodel.blackboardutils.attributes.MessageAttachments.URL @ServiceProvider(service = DataContentViewer.class, position = 5) @SuppressWarnings("PMD.SingularField") // UI widgets cause lots of false positives public class MessageContentViewer extends javax.swing.JPanel implements DataContentViewer { - private static boolean tryHandle(Runnable runnable, String logErrorMessage) { - try { - runnable.run(); + + class TextComponent implements TranslatablePanel.ContentComponent { + + private final Component rootComponent; + private final AutoWrappingJTextPane textComponent; + + TextComponent() { + textComponent = new AutoWrappingJTextPane(); + textComponent.setEditable(false); + + JScrollPane parentComponent = new JScrollPane(); + parentComponent.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); + parentComponent.setVerticalScrollBarPolicy(javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED); + parentComponent.setViewportView(textComponent); + rootComponent = parentComponent; } - catch (Exception e) { - LOGGER.log(Level.WARNING, logErrorMessage, e); - return false; + + @Override + public Component getRootComponent() { + return rootComponent; + } + + @Override + public void setContent(String content, ComponentOrientation orientation) throws Exception { + textComponent.setText(content == null ? "" : content); + textComponent.setComponentOrientation(orientation); + textComponent.setCaretPosition(0); } - - return true; } - - - + private static final long serialVersionUID = 1L; private static final Logger LOGGER = Logger.getLogger(MessageContentViewer.class.getName()); private static final BlackboardAttribute.Type TSK_ASSOCIATED_TYPE = new BlackboardAttribute.Type(TSK_ASSOCIATED_ARTIFACT); @@ -108,12 +127,9 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont private static final int RTF_TAB_INDEX = 3; private static final int ATTM_TAB_INDEX = 4; - - - private final List textAreas; private final org.sleuthkit.autopsy.contentviewers.HtmlPanel htmlPanel = new org.sleuthkit.autopsy.contentviewers.HtmlPanel(); - private final TranslatablePanel textPanel = new TranslatablePanel(new TextTranslatableComponent()); + private final TranslatablePanel textPanel = new TranslatablePanel(new TextComponent()); /** * Artifact currently being displayed */ @@ -131,15 +147,15 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont envelopePanel.setBackground(new Color(0, 0, 0, 38)); drp = DataResultPanel.createInstanceUninitialized(Bundle.MessageContentViewer_AtrachmentsPanel_title(), "", new TableFilterNode(Node.EMPTY, false), 0, null); attachmentsScrollPane.setViewportView(drp); - + //textPanel.setLayout(new BorderLayout()); msgbodyTabbedPane.insertTab( - NbBundle.getMessage(MessageContentViewer.class, "MessageContentViewer.textbodyScrollPane.TabConstraints.tabTitle"), - null, - textPanel, - null, - TEXT_TAB_INDEX); - + NbBundle.getMessage(MessageContentViewer.class, "MessageContentViewer.textbodyScrollPane.TabConstraints.tabTitle"), + null, + textPanel, + null, + TEXT_TAB_INDEX); + msgbodyTabbedPane.setEnabledAt(ATTM_TAB_INDEX, true); /* @@ -163,7 +179,6 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont -> viewInNewWindowButton.setEnabled(drpExplorerManager.getSelectedNodes().length == 1)); } - /** * 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 @@ -422,11 +437,11 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont * Get the artifact associated with the given artifact, if there is one. * * @param artifact The artifact to get the associated artifact from. Must - * not be null + * not be null * * @throws TskCoreException If there is a critical error querying the DB. * @return An optional containing the artifact associated with the given - * artifact, if there is one. + * artifact, if there is one. */ private static Optional getAssociatedArtifact(final BlackboardArtifact artifact) throws TskCoreException { BlackboardAttribute attribute = artifact.getAttribute(TSK_ASSOCIATED_TYPE); @@ -506,10 +521,10 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont * Is the given artifact one that can be shown in this viewer? * * @param nodeArtifact An artifact that might be a message. Must not be - * null. + * null. * * @return True if the given artifact can be shown as a message in this - * viewer. + * viewer. */ private static boolean isMessageArtifact(BlackboardArtifact nodeArtifact) { final int artifactTypeID = nodeArtifact.getArtifactTypeID(); @@ -555,14 +570,14 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont return nodeArtifact; } - + @Override public int isPreferred(Node node) { // For message artifacts this is a high priority viewer, // but for attachment files, this a lower priority vewer. if (isSupported(node)) { BlackboardArtifact nodeArtifact = node.getLookup().lookup(BlackboardArtifact.class); - if (nodeArtifact != null) { + if (nodeArtifact != null) { return 7; } else { return 1; @@ -575,7 +590,7 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont * Configure the text area at the given index to show the content of the * given type. * - * @param type The ATTRIBUT_TYPE to show in the indexed tab. + * @param type The ATTRIBUT_TYPE to show in the indexed tab. * @param index The index of the text area to configure. * * @throws TskCoreException @@ -586,7 +601,7 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont if (index == HTML_TAB_INDEX && StringUtils.isNotBlank(attributeText)) { htmlPanel.setHtmlText(attributeText); } else if (index == TEXT_TAB_INDEX && StringUtils.isNotBlank(attributeText)) { - textPanel.setContent(attributeText); + textPanel.setContent(attributeText, artifact.toString()); } else { JTextComponent textComponent = textAreas.get(index); if (textComponent != null) { @@ -612,34 +627,34 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont } private void configureAttachments() throws TskCoreException { - + final Set attachments; - + // Attachments are specified in an attribute TSK_ATTACHMENTS as JSON attribute BlackboardAttribute attachmentsAttr = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ATTACHMENTS)); - if(attachmentsAttr != null) { - + if (attachmentsAttr != null) { + attachments = new HashSet<>(); - String jsonVal = attachmentsAttr.getValueString(); + String jsonVal = attachmentsAttr.getValueString(); MessageAttachments msgAttachments = new Gson().fromJson(jsonVal, MessageAttachments.class); - + Collection fileAttachments = msgAttachments.getFileAttachments(); - for (FileAttachment fileAttachment: fileAttachments) { + for (FileAttachment fileAttachment : fileAttachments) { attachments.add(fileAttachment); } Collection urlAttachments = msgAttachments.getUrlAttachments(); - for (URLAttachment urlAttachment: urlAttachments) { + for (URLAttachment urlAttachment : urlAttachments) { attachments.add(urlAttachment); } } else { // For backward compatibility - email attachements are derived files and children of the email message artifact - attachments = new HashSet<>(); - for (Content child: artifact.getChildren()) { - if (child instanceof AbstractFile) { - attachments.add(new FileAttachment((AbstractFile)child)); - } + attachments = new HashSet<>(); + for (Content child : artifact.getChildren()) { + if (child instanceof AbstractFile) { + attachments.add(new FileAttachment((AbstractFile) child)); } + } } - + final int numberOfAttachments = attachments.size(); msgbodyTabbedPane.setEnabledAt(ATTM_TAB_INDEX, numberOfAttachments > 0); @@ -727,9 +742,8 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont return doc.html(); } - /** - * Creates child nodes for message attachments. + * Creates child nodes for message attachments. */ private static class AttachmentsChildren extends Children.Keys { diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/TextTranslatableComponent.java b/Core/src/org/sleuthkit/autopsy/contentviewers/TextTranslatableComponent.java deleted file mode 100644 index ea456cd5eb..0000000000 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/TextTranslatableComponent.java +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Autopsy Forensic Browser - * - * Copyright 2017-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; - -import java.awt.Component; -import java.util.logging.Level; -import javax.swing.JScrollPane; -import javax.swing.JTextArea; -import javax.swing.SwingUtilities; -import org.openide.util.NbBundle; -import org.sleuthkit.autopsy.coreutils.Logger; -import org.sleuthkit.autopsy.texttranslation.NoServiceProviderException; -import org.sleuthkit.autopsy.texttranslation.TextTranslationService; -import org.sleuthkit.autopsy.texttranslation.TranslationException; - -/** - * provides the interface to be injected into the TranslatablePanel and displays text - */ -final class TextTranslatableComponent implements TranslatablePanel.TranslatableComponent { - - private static final Logger LOGGER = Logger.getLogger(TextTranslatableComponent.class.getName()); - private final Component parentComponent; - private final JTextArea textComponent; - private final TextTranslationService translationService; - private boolean translate = false; - private String translated = null; - private String origContent = ""; - - TextTranslatableComponent() { - JTextArea textComponent = new JTextArea(); - textComponent.setEditable(false); - textComponent.setLineWrap(true); - textComponent.setRows(5); - textComponent.setWrapStyleWord(true); - - JScrollPane parentComponent = new JScrollPane(); - parentComponent.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); - parentComponent.setVerticalScrollBarPolicy(javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED); - parentComponent.setViewportView(textComponent); - this.parentComponent = parentComponent; - this.textComponent = textComponent; - this.translationService = TextTranslationService.getInstance(); - } - - TextTranslatableComponent(Component parentComponent, JTextArea textComponent, TextTranslationService translationService) { - this.parentComponent = parentComponent; - this.textComponent = textComponent; - this.translationService = translationService; - } - - public Component getComponent() { - return parentComponent; - } - - public String getContent() { - return origContent; - } - - public boolean isTranslated() { - return translate; - } - - private boolean setPanelContent(String content) { - try { - textComponent.setText(content == null ? "" : content); - textComponent.setCaretPosition(0); - return true; - } catch (Exception e) { - LOGGER.log(Level.WARNING, "There was an error in setting up the text for MessageContentViewer text panel", e); - return false; - } - } - - @NbBundle.Messages(value = "TextTranslatableComponent.setPanelContent.onSetContentError=Unable to display text at this time.") - private String onErr(boolean success) { - return (success) ? null : Bundle.TextTranslatableComponent_setPanelContent_onSetContentError(); - } - - public String setContent(String content) { - this.origContent = content; - this.translated = null; - this.translate = false; - return onErr(setPanelContent(content)); - } - - @NbBundle.Messages(value = "TextTranslatableComponent.setTranslated.onTranslateError=Unable to translate text at this time.") - public String setTranslated(boolean translate) { - this.translate = translate; - if (this.translate) { - if (this.translated == null) { - final String originalContent = this.origContent; - SwingUtilities.invokeLater(() -> { - try { - this.translated = this.translationService.translate(originalContent); - } catch (NoServiceProviderException | TranslationException ex) { - LOGGER.log(Level.WARNING, "Unable to translate text with translation service", ex); - //return Bundle.TextTranslatableComponent_setTranslated_onTranslateError(); - } - }); - } - return onErr(setPanelContent(this.translated == null ? "" : this.translated)); - } else { - return onErr(setPanelContent(this.origContent)); - } - } - -} diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/TranslatablePanel.java b/Core/src/org/sleuthkit/autopsy/contentviewers/TranslatablePanel.java index b6a3a7d78b..ba92c38872 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/TranslatablePanel.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/TranslatablePanel.java @@ -21,7 +21,6 @@ package org.sleuthkit.autopsy.contentviewers; import com.google.common.util.concurrent.ThreadFactoryBuilder; import java.awt.Component; import java.awt.ComponentOrientation; -import java.awt.Font; import java.io.IOException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @@ -38,17 +37,30 @@ import org.sleuthkit.autopsy.texttranslation.ui.TranslateTextTask; /** * A panel for translation with a subcomponent that allows for translation */ -final class TranslatablePanel extends JPanel { +class TranslatablePanel extends JPanel { - - interface ContentSetter { - void set(String content, ComponentOrientation orientation, int font) throws Exception; + static interface ContentComponent { + /** + * gets root component of the translation panel + * @return the root component to insert into the translatable panel + */ + Component getRootComponent(); + + /** + * sets the content of the component to the provided content + * @param content the content to be displayed + * @param orientation how it should be displayed + * @throws Exception if there is an error in rendering the content + */ + void setContent(String content, ComponentOrientation orientation) throws Exception; } - + + /** * an option in drop down of whether or not to translate */ private static class TranslateOption { + private final String text; private final boolean translate; @@ -60,7 +72,7 @@ final class TranslatablePanel extends JPanel { public String getText() { return text; } - + @Override public String toString() { return text; @@ -70,8 +82,9 @@ final class TranslatablePanel extends JPanel { return translate; } } - + private static class TranslatedText { + private final String text; private final ComponentOrientation orientation; @@ -88,12 +101,13 @@ final class TranslatablePanel extends JPanel { return orientation; } } - + private class OnTranslation extends TranslateTextTask { + public OnTranslation() { super(true, contentDescriptor == null ? "" : contentDescriptor); } - + @Override protected String translate(String input) throws NoServiceProviderException, TranslationException { // defer to outer class method so that it can be overridden for items like html, rtf, etc. @@ -119,123 +133,129 @@ final class TranslatablePanel extends JPanel { protected void onTextDisplay(String text, ComponentOrientation orientation, int font) { // on successful acquire cache the result and set the text setCachedTranslated(new TranslatedText(text, orientation)); - setSubcomponentContent(text, orientation, font); - } + setChildComponentContent(text, orientation); + + // clear any status + clearStatus(); + } } - - - + private static final long serialVersionUID = 1L; private static final ComponentOrientation DEFAULT_ORIENTATION = ComponentOrientation.LEFT_TO_RIGHT; - private static final int DEFAULT_FONT = Font.PLAIN; - - + private final ImageIcon warningIcon = new ImageIcon(TranslatablePanel.class.getResource("/org/sleuthkit/autopsy/images/warning16.png")); - - private final ContentSetter onContent; - private final Component subcomponent; + + private final ContentComponent contentComponent; + private final Component rootComponent; private final String origOptionText; private final String translatedOptionText; private final TextTranslationService translationService; private final ThreadFactory translationThreadFactory = new ThreadFactoryBuilder().setNameFormat("translatable-panel-%d").build(); private final ExecutorService executorService = Executors.newSingleThreadExecutor(translationThreadFactory); - - + + private final Object cachedTranslatedLock = new Object(); + private final Object backgroundTaskLock = new Object(); + private String content; private String contentDescriptor; + private volatile TranslatedText cachedTranslated; private volatile OnTranslation backgroundTask = null; - - @Messages({"TranslatablePanel.comboBoxOption.originalText=Original Text", - "TranslatablePanel.comboBoxOption.translatedText=Translated Text"}) - TranslatablePanel(Component subcomponent, ContentSetter onContent) { + "TranslatablePanel.comboBoxOption.translatedText=Translated Text"}) + TranslatablePanel(ContentComponent contentComponent) { this( - subcomponent, - onContent, - Bundle.TranslatablePanel_comboBoxOption_originalText(), - Bundle.TranslatablePanel_comboBoxOption_translatedText(), + contentComponent, + Bundle.TranslatablePanel_comboBoxOption_originalText(), + Bundle.TranslatablePanel_comboBoxOption_translatedText(), null, TextTranslationService.getInstance()); } - + /** * Creates new form TranslatedContentPanel */ - TranslatablePanel(Component subcomponent, ContentSetter onContent, String origOptionText, String translatedOptionText, String origContent, + TranslatablePanel(ContentComponent contentComponent, String origOptionText, String translatedOptionText, String origContent, TextTranslationService translationService) { - this.subcomponent = subcomponent; - this.onContent = onContent; + this.contentComponent = contentComponent; + this.rootComponent = contentComponent.getRootComponent(); this.origOptionText = origOptionText; this.translatedOptionText = translatedOptionText; this.translationService = translationService; - + initComponents(); additionalInit(); setTranslationBarVisible(); reset(); } + + private TranslatedText getCachedTranslated() { - synchronized(cachedTranslated) { - return cachedTranslated; + synchronized (cachedTranslatedLock) { + return cachedTranslated; } } private void setCachedTranslated(TranslatedText translated) { - synchronized(cachedTranslated) { + synchronized (cachedTranslatedLock) { this.cachedTranslated = translated; - } - } - - private synchronized void cancelPendingTranslation() { - if (backgroundTask != null && !backgroundTask.isDone()) { - backgroundTask.cancel(true); } - backgroundTask = null; } - - private synchronized void runTranslationTask() { - cancelPendingTranslation(); - backgroundTask = new OnTranslation(); - //Pass the background task to a single threaded pool to keep - //the number of jobs running to one. - executorService.execute(backgroundTask); + private void cancelPendingTranslation() { + synchronized (backgroundTaskLock) { + if (backgroundTask != null && !backgroundTask.isDone()) { + backgroundTask.cancel(true); + } + backgroundTask = null; + } } - - + + private void runTranslationTask() { + synchronized (backgroundTaskLock) { + cancelPendingTranslation(); + backgroundTask = new OnTranslation(); + + //Pass the background task to a single threaded pool to keep + //the number of jobs running to one. + executorService.execute(backgroundTask); + } + } + void reset() { setTranslationBarVisible(); setContent(null, null); } - + void setContent(String content, String contentDescriptor) { cancelPendingTranslation(); this.translateComboBox.setSelectedIndex(0); this.content = content; this.contentDescriptor = contentDescriptor; - setStatus(null, false); + clearStatus(); setCachedTranslated(null); - setSubcomponentContent(content); + setChildComponentContent(content); } - - + /** - * where actual translation takes place - * allowed to be overridden for the sake of varying translatable content (i.e. html, rtf, etc) - * @param input the input content - * @return the result of translation + * where actual translation takes place allowed to be overridden for the + * sake of varying translatable content (i.e. html, rtf, etc) + * + * @param input the input content + * @return the result of translation * @throws TranslationException - * @throws NoServiceProviderException + * @throws NoServiceProviderException */ - protected String retrieveTranslation(String input) throws TranslationException, NoServiceProviderException { + protected String retrieveTranslation(String input) throws TranslationException, NoServiceProviderException { return translationService.translate(input); } - - - + + private void clearStatus() { + setStatus(null, false); + } + private void setStatus(String msg, boolean showWarningIcon) { statusLabel.setText(msg); statusLabel.setIcon(showWarningIcon ? warningIcon : null); @@ -244,16 +264,16 @@ final class TranslatablePanel extends JPanel { private void setTranslationBarVisible() { translationBar.setVisible(this.translationService.hasProvider()); } - - private void setSubcomponentContent(String content) { - setSubcomponentContent(content, DEFAULT_ORIENTATION, DEFAULT_FONT); + + private void setChildComponentContent(String content) { + setChildComponentContent(content, DEFAULT_ORIENTATION); } - - @Messages({"# {0} - exception message", "TranslatablePanel.onSetContentError.text=There was an error displaying the text: {0}"}) - private void setSubcomponentContent(String content, ComponentOrientation orientation, int font) { + + @Messages({"# {0} - exception message", "TranslatablePanel.onSetContentError.text=There was an error displaying the text: {0}"}) + private void setChildComponentContent(String content, ComponentOrientation orientation) { SwingUtilities.invokeLater(() -> { try { - this.onContent.set(content, orientation, font); + contentComponent.setContent(content, orientation); } catch (Exception ex) { setStatus(Bundle.TranslatablePanel_onSetContentError_text(ex.getMessage()), true); } @@ -261,31 +281,27 @@ final class TranslatablePanel extends JPanel { } private void additionalInit() { - add(this.subcomponent, java.awt.BorderLayout.CENTER); - setStatus(null, false); + add(this.rootComponent, java.awt.BorderLayout.CENTER); translateComboBox.removeAllItems(); translateComboBox.addItem(new TranslateOption(this.origOptionText, false)); translateComboBox.addItem(new TranslateOption(this.translatedOptionText, true)); } - + private void handleComboBoxChange(TranslateOption translateOption) { cancelPendingTranslation(); - SwingUtilities.invokeLater(() -> { - if (translateOption.shouldTranslate()) { - TranslatedText translated = getCachedTranslated(); - if (translated != null) { - setSubcomponentContent(translated.getText(), translated.getOrientation(), DEFAULT_FONT); - } - else { - runTranslationTask(); - } + clearStatus(); + + if (translateOption.shouldTranslate()) { + TranslatedText translated = getCachedTranslated(); + if (translated != null) { + setChildComponentContent(translated.getText(), translated.getOrientation()); + } else { + runTranslationTask(); } - else { - setSubcomponentContent(content); - } - }); + } else { + setChildComponentContent(content); + } } - /** * This method is called from within the constructor to initialize the form. @@ -338,4 +354,4 @@ final class TranslatablePanel extends JPanel { private javax.swing.JComboBox translateComboBox; private javax.swing.JPanel translationBar; // End of variables declaration//GEN-END:variables -} \ No newline at end of file +} diff --git a/Core/src/org/sleuthkit/autopsy/texttranslation/ui/TranslatedTextViewer.java b/Core/src/org/sleuthkit/autopsy/texttranslation/ui/TranslatedTextViewer.java index a913cacf38..a18e8b9c70 100644 --- a/Core/src/org/sleuthkit/autopsy/texttranslation/ui/TranslatedTextViewer.java +++ b/Core/src/org/sleuthkit/autopsy/texttranslation/ui/TranslatedTextViewer.java @@ -28,8 +28,6 @@ import java.awt.event.ActionListener; import java.io.IOException; import java.io.Reader; import java.util.Arrays; -import java.util.concurrent.CancellationException; -import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.ThreadFactory; @@ -37,19 +35,15 @@ import org.openide.nodes.Node; import org.openide.util.lookup.ServiceProvider; import org.sleuthkit.autopsy.corecomponentinterfaces.TextViewer; import org.sleuthkit.datamodel.AbstractFile; -import javax.swing.SwingWorker; import org.openide.util.Lookup; import org.openide.util.NbBundle; import org.openide.util.lookup.Lookups; import org.sleuthkit.autopsy.corecomponents.DataContentViewerUtility; import org.sleuthkit.autopsy.coreutils.ExecUtil.ProcessTerminator; -import org.sleuthkit.autopsy.coreutils.TextUtil; import org.sleuthkit.autopsy.textextractors.TextExtractor; import org.sleuthkit.autopsy.textextractors.TextExtractorFactory; import org.sleuthkit.autopsy.textextractors.configs.ImageConfig; import org.sleuthkit.autopsy.texttranslation.TextTranslationService; -import org.sleuthkit.autopsy.texttranslation.NoServiceProviderException; -import org.sleuthkit.autopsy.texttranslation.TranslationException; import org.sleuthkit.datamodel.Content; import java.util.List; import java.util.logging.Level; From ad873dbd2d585ae52b6c019927e8776c1a65166f Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Thu, 5 Mar 2020 20:17:47 -0500 Subject: [PATCH 40/97] 6105 Clean up and bug fixes for GPX Parser --- .../GPX_Module/GPX_Parser_Module.py | 210 +++++++----------- 1 file changed, 82 insertions(+), 128 deletions(-) diff --git a/InternalPythonModules/GPX_Module/GPX_Parser_Module.py b/InternalPythonModules/GPX_Module/GPX_Parser_Module.py index d33084ccac..0769408f2a 100644 --- a/InternalPythonModules/GPX_Module/GPX_Parser_Module.py +++ b/InternalPythonModules/GPX_Module/GPX_Parser_Module.py @@ -37,8 +37,12 @@ from org.sleuthkit.datamodel import BlackboardArtifact from org.sleuthkit.datamodel import BlackboardAttribute from org.sleuthkit.datamodel import TskCoreException from org.sleuthkit.datamodel.blackboardutils import GeoArtifactsHelper -from org.sleuthkit.datamodel.blackboardutils.attributes import GeoWaypoint -from org.sleuthkit.datamodel.blackboardutils.attributes import GeoTrackPoints +from org.sleuthkit.datamodel.blackboardutils.attributes import TskGeoWaypointsUtil +from org.sleuthkit.datamodel.blackboardutils.attributes.TskGeoWaypointsUtil import GeoWaypointList +from org.sleuthkit.datamodel.blackboardutils.attributes.TskGeoWaypointsUtil.GeoWaypointList import GeoWaypoint +from org.sleuthkit.datamodel.blackboardutils.attributes import TskGeoTrackpointsUtil +from org.sleuthkit.datamodel.blackboardutils.attributes.TskGeoTrackpointsUtil import GeoTrackPointList +from org.sleuthkit.datamodel.blackboardutils.attributes.TskGeoTrackpointsUtil.GeoTrackPointList import GeoTrackPoint from org.sleuthkit.autopsy.datamodel import ContentUtils from org.sleuthkit.autopsy.ingest import IngestModule from org.sleuthkit.autopsy.ingest.IngestModule import IngestModuleException @@ -63,20 +67,15 @@ import gpxpy.parser class GPXParserDataSourceIngestModuleFactory(IngestModuleFactoryAdapter): moduleName = "GPX Parser" - - # True - Verbose debugging messages sent to log file. - # False - Verbose debugging turned off. - debuglevel = False def getModuleDisplayName(self): return self.moduleName - # TODO: Give it a description def getModuleDescription(self): return "Module that extracts GEO data from GPX files." def getModuleVersionNumber(self): - return "1.1" + return "1.2" def isDataSourceIngestModuleFactory(self): return True @@ -88,10 +87,14 @@ class GPXParserDataSourceIngestModuleFactory(IngestModuleFactoryAdapter): # Data Source-level ingest module. One gets created per data source. class GPXParserDataSourceIngestModule(DataSourceIngestModule): - _logger = Logger.getLogger(GPXParserDataSourceIngestModuleFactory.moduleName) + # True - Verbose debugging messages sent to log file. + # False - Verbose debugging turned off. + writeDebugMsgs = True + + logger = Logger.getLogger(GPXParserDataSourceIngestModuleFactory.moduleName) def log(self, level, msg): - self._logger.logp(level, self.__class__.__name__, inspect.stack()[1][3], msg) + self.logger.logp(level, self.__class__.__name__, inspect.stack()[1][3], msg) def __init__(self): self.context = None @@ -105,179 +108,130 @@ class GPXParserDataSourceIngestModule(DataSourceIngestModule): # We don't know how much work there is yet. progressBar.switchToIndeterminate() - - # This will work in 4.0.1 and beyond. - # Use blackboard class to index blackboard artifacts for keyword search. - blackboard = Case.getCurrentCase().getServices().getBlackboard() - # Get the sleuthkitcase + # Get the case database and its blackboard. skCase = Case.getCurrentCase().getSleuthkitCase() + blackboard = skCase.getBlackboard() - # In the name and then count and read them. - fileManager = Case.getCurrentCase().getServices().getFileManager() - + # Get any files with a .gpx extension. + # It would perhaps be better to get these files by MIME type instead. + # RC: It would also be better if this were a file level ingest module so it could process files extracted from archives. + fileManager = Case.getCurrentCase().getServices().getFileManager() files = fileManager.findFiles(dataSource, "%.gpx") - # TODO: Would like to change this to find files based on mimetype rather than extension. - #files = findFiles(dataSource, "text/xml") - #if (file.isMimeType('text/xml') == False): + # Update the progress bar now that we know how much work there is to do. numFiles = len(files) - if GPXParserDataSourceIngestModuleFactory.debuglevel: self.log(Level.INFO, "found " + str(numFiles) + " files") + if self.writeDebugMsgs: self.log(Level.INFO, "Found " + str(numFiles) + " GPX files") progressBar.switchToDeterminate(numFiles) - fileCount = 0; - # Get module name for adding attributes + # Get the module name, it will be needed for adding attributes moduleName = GPXParserDataSourceIngestModuleFactory.moduleName + + # Check if a folder for this is present in the case Temp directory. + # If not, create it. + dirName = os.path.join(Case.getCurrentCase().getTempDirectory(), "GPX_Parser_Module") + try: + os.stat(dirName) + except: + os.mkdir(dirName) + + # Create a temp file name. It appears that we cannot close and delete + # this file, but we can overwrite it for each file we need to process. + fileName = os.path.join(dirName, "tmp.gpx") + fileCount = 0; for file in files: - # Get the GeoArtifactsHelper - geoArtifactHelper = GeoArtifactsHelper(skCase, moduleName, file) + # Create a GeoArtifactsHelper for this file. + geoArtifactHelper = GeoArtifactsHelper(skCase, moduleName, None, file) # Check if the user pressed cancel while we were busy. if self.context.isJobCancelled(): return IngestModule.ProcessResult.OK - #self.log(Level.INFO, "GPX: Processing file: " + file.getName()) + if self.writeDebugMsgs: self.log(Level.INFO, "Processing " + file.getUniquePath() + " (objID = " + str(file.getId()) + ")") fileCount += 1 - # Check if module folder is present. If not, create it. - dirName = os.path.join(Case.getCurrentCase().getTempDirectory(), "GPX_Parser_Module") - try: - os.stat(dirName) - except: - os.mkdir(dirName) - fileName = os.path.join(dirName, "tmp.gpx") - - # Check to see if temporary file exists. If it does, remove it. - if os.path.exists(fileName): - try: - os.remove(fileName) - if GPXParserDataSourceIngestModuleFactory.debuglevel: self.log(Level.INFO, "GPX:\t" + "FILE DELETED " + fileName ) - except: - if GPXParserDataSourceIngestModuleFactory.debuglevel: self.log(Level.INFO, "GPX:\t" + "FILE NOT DELETED " + fileName) - - # This writes the file to the local file system. + # Write the file so that it can be parsed by gpxpy. localFile = File(fileName) ContentUtils.writeToFile(file, localFile) - # Send to gpxpy for parsing. + # Send the file to gpxpy for parsing. gpxfile = open(fileName) try: gpx = gpxpy.parse(gpxfile) - if GPXParserDataSourceIngestModuleFactory.debuglevel: self.log(Level.INFO, "GPX:\t" + "FILE PARSED") - except: - if GPXParserDataSourceIngestModuleFactory.debuglevel: self.log(Level.SEVERE, "GPX:\t" + file.getName() + " - FILE NOT PARSED") + if self.writeDebugMsgs: self.log(Level.INFO, "Parsed " + file.getUniquePath() + " (objID = " + str(file.getId()) + ")") + except Exception as e: + self.log(Level.WARNING, "Error parsing file " + file.getUniquePath() + " (objID = " + str(file.getId()) + "):" + str(e)) continue if gpx: - if GPXParserDataSourceIngestModuleFactory.debuglevel: self.log(Level.INFO, "GPX: TRACKS") + if self.writeDebugMsgs: self.log(Level.INFO, "Processing tracks from " + file.getUniquePath() + " (objID = " + str(file.getId()) + ")") for track in gpx.tracks: for segment in track.segments: - geoPointList = ArrayList() + geoPointList = TskGeoTrackpointsUtil.GeoTrackPointList() for point in segment.points: - + elevation = 0 if point.elevation != None: elevation = point.elevation - dateTime = 0 + timeStamp = 0 try: if (point.time != None): - datetime = long(time.mktime(point.time.timetuple())) - except: - pass + timeStamp = long(time.mktime(point.time.timetuple())) + except Exception as e: + self.log(Level.WARNING, "Error getting track timestamp from " + file.getUniquePath() + " (objID = " + str(file.getId()) + "):" + e) - geoPointList.add(GeoWaypoint.GeoTrackPoint(point.latitude, point.longitude, elevation, 0, 0, 0, dateTime)) + geoPointList.addPoint(GeoTrackPoint(point.latitude, point.longitude, elevation, None, 0, 0, 0, timeStamp)) try: - # Add the trackpoint using the helper class - geoartifact = geoArtifactHelper.addTrack("Trackpoint", geoPointList) + geoArtifactHelper.addTrack("Track", geoPointList, None) except Blackboard.BlackboardException as e: - if GPXParserDataSourceIngestModuleFactory.debuglevel: self.log(Level.SEVERE, "GPX: Error using geo artifact helper with blackboard " ) + self.log(Level.SEVERE, "Error posting GPS track artifact for " + file.getUniquePath() + " (objID = " + str(file.getId()) + "):" + e.getMessage()) except TskCoreException as e: - if GPXParserDataSourceIngestModuleFactory.debuglevel: self.log(Level.SEVERE, "GPX: Error using geo artifact helper tskcoreexception" ) + self.log(Level.SEVERE, "Error creating GPS track artifact for " + file.getUniquePath() + " (objID = " + str(file.getId()) + "):" + e.getMessage()) - if GPXParserDataSourceIngestModuleFactory.debuglevel: self.log(Level.INFO, "GPX: WAYPOINTS") + if self.writeDebugMsgs: self.log(Level.INFO, "Processing waypoints from " + file.getUniquePath() + " (objID = " + str(file.getId()) + ")") for waypoint in gpx.waypoints: - attributes = ArrayList() - art = file.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_BOOKMARK) - - attributes.add(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LATITUDE.getTypeID(), moduleName, waypoint.latitude)) - attributes.add(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LONGITUDE.getTypeID(), moduleName, waypoint.longitude)) - attributes.add(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_FLAG.getTypeID(), moduleName, "Waypoint")) - attributes.add(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_NAME.getTypeID(), moduleName, waypoint.name)) - attributes.add(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID(), moduleName, "GPXParser")) - - art.addAttributes(attributes) try: - # Post the artifact to blackboard - skCase.getBlackboard().postArtifact(art, moduleName) + art = file.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_BOOKMARK) + + attributes = ArrayList() + attributes.add(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LATITUDE.getTypeID(), moduleName, waypoint.latitude)) + attributes.add(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LONGITUDE.getTypeID(), moduleName, waypoint.longitude)) + attributes.add(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_FLAG.getTypeID(), moduleName, "Waypoint")) + attributes.add(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_NAME.getTypeID(), moduleName, waypoint.name)) + attributes.add(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID(), moduleName, "GPXParser")) + art.addAttributes(attributes) + + blackboard.postArtifact(art, moduleName) + except Blackboard.BlackboardException as e: - if GPXParserDataSourceIngestModuleFactory.debuglevel: self.log(Level.SEVERE, "GPX: Error using geo artifact helper with blackboard for waypoints" ) + self.log(Level.SEVERE, "Error posting GPS bookmark artifact for " + file.getUniquePath() + " (objID = " + str(file.getId()) + "):" + e.getMessage()) + except TskCoreException as e: + self.log(Level.SEVERE, "Error creating GPS bookmark artifact for " + file.getUniquePath() + " (objID = " + str(file.getId()) + "):" + e.getMessage()) - if GPXParserDataSourceIngestModuleFactory.debuglevel: self.log(Level.INFO, "GPX: ROUTES") + if self.writeDebugMsgs: self.log(Level.INFO, "Processing routes from " + file.getUniquePath() + " (objID = " + str(file.getId()) + ")") for route in gpx.routes: - firstTimeThru = 0 - startingPoint = list() - endingPoint = list() + + geoWaypointList = TskGeoWaypointsUtil.GeoWaypointList() + for point in route.points: - # If first time in loop only populate starting point - if (firstTimeThru == 0): - startingPoint.append((point.latitude, point.longitude)) - firstTimeThru = 1 - else: - startingPoint.append((point.latitude, point.longitude)) - endingPoint.append((point.latitude, point.longitude)) + geoWaypointList.addPoint(point.latitude, point.longitude, elevation, point.name) - if (len(endingPoint) > 0): - # get length of ending point as this ensures that we have equal points to process. - for i in range(0,len(endingPoint) -1): - attributes = ArrayList() - art = file.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_ROUTE) - - attributes.add(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LATITUDE_START.getTypeID(), moduleName, startingPoint[i][0])) - attributes.add(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LONGITUDE_START.getTypeID(), moduleName, startingPoint[i][1])) - attributes.add(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LATITUDE_END.getTypeID(), moduleName, endingPoint[i][0])) - attributes.add(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LONGITUDE_END.getTypeID(), moduleName, endingPoint[i][1])) - - art.addAttributes(attributes) - - try: - # Post the artifact to blackboard - skCase.getBlackboard().postArtifact(art, moduleName) - except Blackboard.BlackboardException as e: - if GPXParserDataSourceIngestModuleFactory.debuglevel: self.log(Level.SEVERE, "GPX: Error using geo artifact helper with blackboard for waypoints" ) - else: - if (len(startingPoint) > 0): - attributes = ArrayList() - art = file.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_ROUTE) - - attributes.add(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LATITUDE_START.getTypeID(), moduleName, startingPoint[0][0])) - attributes.add(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LONGITUDE_START.getTypeID(), moduleName, startingPoint[0][1])) - attributes.add(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LATITUDE_END.getTypeID(), moduleName, startingPoint[0][0])) - attributes.add(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LONGITUDE_END.getTypeID(), moduleName, startingPoint[0][1])) - - art.addAttributes(attributes) - - try: - # Post the artifact to blackboard - skCase.getBlackboard().postArtifact(art, moduleName) - except Blackboard.BlackboardException as e: - if GPXParserDataSourceIngestModuleFactory.debuglevel: self.log(Level.SEVERE, "GPX: Error using geo artifact helper with blackboard for waypoints" ) - + try: + geoArtifactHelper.addRoute(None, None, geoWaypointList, None) + except Blackboard.BlackboardException as e: + self.log("Error posting GPS route artifact for " + file.getUniquePath() + " (objID = " + str(file.getId()) + "):" + e.getMessage()) + except TskCoreException as e: + self.log(Level.SEVERE, "Error creating GPS route artifact for " + file.getUniquePath() + " (objID = " + str(file.getId()) + "):" + e.getMessage()) # Update the progress bar. progressBar.progress(fileCount) - if os.path.exists(fileName): - try: - os.remove(fileName) - if GPXParserDataSourceIngestModuleFactory.debuglevel: self.log(Level.INFO, "GPX:\t" + "FILE DELETED") - except: - self.log(Level.SEVERE, "GPX:\t" + "FILE NOT DELETED") # Post a message to the ingest messages inbox. - message = IngestMessage.createMessage(IngestMessage.MessageType.DATA, "GPX Parser Data Source Ingest Module", "Found %d files" % fileCount) + message = IngestMessage.createMessage(IngestMessage.MessageType.DATA, moduleName, "Processed %d files" % fileCount) IngestServices.getInstance().postMessage(message) return IngestModule.ProcessResult.OK; From a5a532dc9eae2fb9fcd61595a8c01c72be405472 Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Thu, 5 Mar 2020 20:20:24 -0500 Subject: [PATCH 41/97] 6105 Clean up and bug fixes for GPX Parser --- InternalPythonModules/GPX_Module/GPX_Parser_Module.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/InternalPythonModules/GPX_Module/GPX_Parser_Module.py b/InternalPythonModules/GPX_Module/GPX_Parser_Module.py index 0769408f2a..7800b5f849 100644 --- a/InternalPythonModules/GPX_Module/GPX_Parser_Module.py +++ b/InternalPythonModules/GPX_Module/GPX_Parser_Module.py @@ -87,11 +87,8 @@ class GPXParserDataSourceIngestModuleFactory(IngestModuleFactoryAdapter): # Data Source-level ingest module. One gets created per data source. class GPXParserDataSourceIngestModule(DataSourceIngestModule): - # True - Verbose debugging messages sent to log file. - # False - Verbose debugging turned off. - writeDebugMsgs = True - logger = Logger.getLogger(GPXParserDataSourceIngestModuleFactory.moduleName) + writeDebugMsgs = True def log(self, level, msg): self.logger.logp(level, self.__class__.__name__, inspect.stack()[1][3], msg) From 174644f13fb2af036eddb325f1f5bb928c618837 Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Thu, 5 Mar 2020 20:22:55 -0500 Subject: [PATCH 42/97] 6105 Clean up and bug fixes for GPX Parser --- InternalPythonModules/GPX_Module/GPX_Parser_Module.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/InternalPythonModules/GPX_Module/GPX_Parser_Module.py b/InternalPythonModules/GPX_Module/GPX_Parser_Module.py index 7800b5f849..6b61e28fc8 100644 --- a/InternalPythonModules/GPX_Module/GPX_Parser_Module.py +++ b/InternalPythonModules/GPX_Module/GPX_Parser_Module.py @@ -124,7 +124,7 @@ class GPXParserDataSourceIngestModule(DataSourceIngestModule): # Get the module name, it will be needed for adding attributes moduleName = GPXParserDataSourceIngestModuleFactory.moduleName - # Check if a folder for this is present in the case Temp directory. + # Check if a folder for this module is present in the case Temp directory. # If not, create it. dirName = os.path.join(Case.getCurrentCase().getTempDirectory(), "GPX_Parser_Module") try: From f2e8e01a0c7769893296e7365b4c9681519dffb2 Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Thu, 5 Mar 2020 20:25:28 -0500 Subject: [PATCH 43/97] 6105 Clean up and bug fixes for GPX Parser --- InternalPythonModules/GPX_Module/GPX_Parser_Module.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/InternalPythonModules/GPX_Module/GPX_Parser_Module.py b/InternalPythonModules/GPX_Module/GPX_Parser_Module.py index 6b61e28fc8..933505e243 100644 --- a/InternalPythonModules/GPX_Module/GPX_Parser_Module.py +++ b/InternalPythonModules/GPX_Module/GPX_Parser_Module.py @@ -178,7 +178,7 @@ class GPXParserDataSourceIngestModule(DataSourceIngestModule): if (point.time != None): timeStamp = long(time.mktime(point.time.timetuple())) except Exception as e: - self.log(Level.WARNING, "Error getting track timestamp from " + file.getUniquePath() + " (objID = " + str(file.getId()) + "):" + e) + self.log(Level.WARNING, "Error getting track timestamp from " + file.getUniquePath() + " (objID = " + str(file.getId()) + "):" + str(e)) geoPointList.addPoint(GeoTrackPoint(point.latitude, point.longitude, elevation, None, 0, 0, 0, timeStamp)) From 167c12f00c8b54c2525a0b73bd14fd7aa6b6252e Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Fri, 6 Mar 2020 08:36:42 -0500 Subject: [PATCH 44/97] 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 45/97] 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 46/97] 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 950ce12ac081c00af7600ba61cfcf82081ddb308 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Fri, 6 Mar 2020 10:20:36 -0500 Subject: [PATCH 47/97] synchronized for concurrency when setting messages --- .../sleuthkit/autopsy/contentviewers/TranslatablePanel.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/TranslatablePanel.java b/Core/src/org/sleuthkit/autopsy/contentviewers/TranslatablePanel.java index ba92c38872..d5c9d2f0f6 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/TranslatablePanel.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/TranslatablePanel.java @@ -256,7 +256,7 @@ class TranslatablePanel extends JPanel { setStatus(null, false); } - private void setStatus(String msg, boolean showWarningIcon) { + private synchronized void setStatus(String msg, boolean showWarningIcon) { statusLabel.setText(msg); statusLabel.setIcon(showWarningIcon ? warningIcon : null); } @@ -270,7 +270,7 @@ class TranslatablePanel extends JPanel { } @Messages({"# {0} - exception message", "TranslatablePanel.onSetContentError.text=There was an error displaying the text: {0}"}) - private void setChildComponentContent(String content, ComponentOrientation orientation) { + private synchronized void setChildComponentContent(String content, ComponentOrientation orientation) { SwingUtilities.invokeLater(() -> { try { contentComponent.setContent(content, orientation); From 118d02b1a0e9394da939b4560ae9d1f5c4a4f499 Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Fri, 6 Mar 2020 11:19:36 -0500 Subject: [PATCH 48/97] 6105 Clean up and bug fixes for GPX Parser --- InternalPythonModules/GPX_Module/GPX_Parser_Module.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/InternalPythonModules/GPX_Module/GPX_Parser_Module.py b/InternalPythonModules/GPX_Module/GPX_Parser_Module.py index 933505e243..44e9217f4d 100644 --- a/InternalPythonModules/GPX_Module/GPX_Parser_Module.py +++ b/InternalPythonModules/GPX_Module/GPX_Parser_Module.py @@ -88,7 +88,7 @@ class GPXParserDataSourceIngestModuleFactory(IngestModuleFactoryAdapter): class GPXParserDataSourceIngestModule(DataSourceIngestModule): logger = Logger.getLogger(GPXParserDataSourceIngestModuleFactory.moduleName) - writeDebugMsgs = True + writeDebugMsgs = False def log(self, level, msg): self.logger.logp(level, self.__class__.__name__, inspect.stack()[1][3], msg) From 4bf94826bbaa865fe3fd687538c0932d1a5610df Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Fri, 6 Mar 2020 11:28:09 -0500 Subject: [PATCH 49/97] changed default preference --- Core/src/org/sleuthkit/autopsy/core/UserPreferences.java | 3 ++- .../sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) 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 e3b69b6a6ff052866a83f997474e46a2d774f0e0 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Fri, 6 Mar 2020 13:40:26 -0500 Subject: [PATCH 50/97] updates for codacy items --- .../contentviewers/MessageContentViewer.java | 21 +++++---- .../contentviewers/TranslatablePanel.java | 44 ++++++++++++++----- .../texttranslation/ui/TranslateTextTask.java | 5 +++ 3 files changed, 50 insertions(+), 20 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java b/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java index e1190aaefd..9f6062a4bb 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java @@ -40,10 +40,10 @@ import org.openide.nodes.AbstractNode; import org.openide.nodes.Children; import org.openide.nodes.Node; import org.openide.util.NbBundle; -import org.openide.util.NbBundle.Messages; import org.openide.util.lookup.ServiceProvider; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; +import org.sleuthkit.autopsy.contentviewers.TranslatablePanel.TranslatablePanelException; import org.sleuthkit.autopsy.corecomponentinterfaces.DataContentViewer; import org.sleuthkit.autopsy.corecomponents.AutoWrappingJTextPane; import org.sleuthkit.autopsy.corecomponents.DataResultPanel; @@ -88,19 +88,22 @@ import org.sleuthkit.datamodel.blackboardutils.attributes.MessageAttachments.URL @SuppressWarnings("PMD.SingularField") // UI widgets cause lots of false positives public class MessageContentViewer extends javax.swing.JPanel implements DataContentViewer { + /** + * a text component viewer to be a child component to be placed in a translatablepanel. + */ class TextComponent implements TranslatablePanel.ContentComponent { private final Component rootComponent; - private final AutoWrappingJTextPane textComponent; + private final AutoWrappingJTextPane childTextComponent; TextComponent() { - textComponent = new AutoWrappingJTextPane(); - textComponent.setEditable(false); + childTextComponent = new AutoWrappingJTextPane(); + childTextComponent.setEditable(false); JScrollPane parentComponent = new JScrollPane(); parentComponent.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); parentComponent.setVerticalScrollBarPolicy(javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED); - parentComponent.setViewportView(textComponent); + parentComponent.setViewportView(childTextComponent); rootComponent = parentComponent; } @@ -110,10 +113,10 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont } @Override - public void setContent(String content, ComponentOrientation orientation) throws Exception { - textComponent.setText(content == null ? "" : content); - textComponent.setComponentOrientation(orientation); - textComponent.setCaretPosition(0); + public void setContent(String content, ComponentOrientation orientation) throws TranslatablePanelException { + childTextComponent.setText(content == null ? "" : content); + childTextComponent.setComponentOrientation(orientation); + childTextComponent.setCaretPosition(0); } } diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/TranslatablePanel.java b/Core/src/org/sleuthkit/autopsy/contentviewers/TranslatablePanel.java index d5c9d2f0f6..d1aa1e57af 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/TranslatablePanel.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/TranslatablePanel.java @@ -38,8 +38,24 @@ import org.sleuthkit.autopsy.texttranslation.ui.TranslateTextTask; * A panel for translation with a subcomponent that allows for translation */ class TranslatablePanel extends JPanel { + + class TranslatablePanelException extends Exception { - static interface ContentComponent { + TranslatablePanelException(String message) { + super(message); + } + + TranslatablePanelException(String message, Throwable cause) { + super(message, cause); + } + } + + + /** + * describes a child component to be placed as a child of this panel. the child received + * from getRootComponent() will listen for content updates from setContent() + */ + interface ContentComponent { /** * gets root component of the translation panel * @return the root component to insert into the translatable panel @@ -52,7 +68,7 @@ class TranslatablePanel extends JPanel { * @param orientation how it should be displayed * @throws Exception if there is an error in rendering the content */ - void setContent(String content, ComponentOrientation orientation) throws Exception; + void setContent(String content, ComponentOrientation orientation) throws TranslatablePanelException; } @@ -64,12 +80,12 @@ class TranslatablePanel extends JPanel { private final String text; private final boolean translate; - public TranslateOption(String text, boolean translate) { + TranslateOption(String text, boolean translate) { this.text = text; this.translate = translate; } - public String getText() { + String getText() { return text; } @@ -78,33 +94,39 @@ class TranslatablePanel extends JPanel { return text; } - public boolean shouldTranslate() { + boolean shouldTranslate() { return translate; } } + /** + * the cached result of translating the current content + */ private static class TranslatedText { private final String text; private final ComponentOrientation orientation; - public TranslatedText(String text, ComponentOrientation orientation) { + TranslatedText(String text, ComponentOrientation orientation) { this.text = text; this.orientation = orientation; } - public String getText() { + String getText() { return text; } - public ComponentOrientation getOrientation() { + ComponentOrientation getOrientation() { return orientation; } } + /** + * connects the swing worker specified by TranslateTextTask to this component + */ private class OnTranslation extends TranslateTextTask { - public OnTranslation() { + OnTranslation() { super(true, contentDescriptor == null ? "" : contentDescriptor); } @@ -224,7 +246,7 @@ class TranslatablePanel extends JPanel { } } - void reset() { + final void reset() { setTranslationBarVisible(); setContent(null, null); } @@ -274,7 +296,7 @@ class TranslatablePanel extends JPanel { SwingUtilities.invokeLater(() -> { try { contentComponent.setContent(content, orientation); - } catch (Exception ex) { + } catch (TranslatablePanelException ex) { setStatus(Bundle.TranslatablePanel_onSetContentError_text(ex.getMessage()), true); } }); diff --git a/Core/src/org/sleuthkit/autopsy/texttranslation/ui/TranslateTextTask.java b/Core/src/org/sleuthkit/autopsy/texttranslation/ui/TranslateTextTask.java index f5056196e1..70fe09f4cf 100644 --- a/Core/src/org/sleuthkit/autopsy/texttranslation/ui/TranslateTextTask.java +++ b/Core/src/org/sleuthkit/autopsy/texttranslation/ui/TranslateTextTask.java @@ -136,6 +136,10 @@ public abstract class TranslateTextTask extends SwingWorker { onProgressDisplay(Bundle.TranslatedContentViewer_translatingText(), ComponentOrientation.LEFT_TO_RIGHT, Font.ITALIC); }); @@ -160,6 +164,7 @@ public abstract class TranslateTextTask extends SwingWorker Date: Fri, 6 Mar 2020 15:42:23 -0500 Subject: [PATCH 51/97] updated comments --- .../contentviewers/TranslatablePanel.java | 97 +++++++++++++++---- .../texttranslation/ui/TranslateTextTask.java | 67 +++++++++---- 2 files changed, 126 insertions(+), 38 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/TranslatablePanel.java b/Core/src/org/sleuthkit/autopsy/contentviewers/TranslatablePanel.java index d1aa1e57af..e20b7e063e 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/TranslatablePanel.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/TranslatablePanel.java @@ -39,7 +39,13 @@ import org.sleuthkit.autopsy.texttranslation.ui.TranslateTextTask; */ class TranslatablePanel extends JPanel { + /** + * an exception that can occur during the normal operation of the translatable panel + * for instance, this exception can be thrown if it is not possible to set the child + * content to the provided content string + */ class TranslatablePanelException extends Exception { + public static final long serialVersionUID = 1L; TranslatablePanelException(String message) { super(message); @@ -168,9 +174,6 @@ class TranslatablePanel extends JPanel { private final ImageIcon warningIcon = new ImageIcon(TranslatablePanel.class.getResource("/org/sleuthkit/autopsy/images/warning16.png")); private final ContentComponent contentComponent; - private final Component rootComponent; - private final String origOptionText; - private final String translatedOptionText; private final TextTranslationService translationService; private final ThreadFactory translationThreadFactory = new ThreadFactoryBuilder().setNameFormat("translatable-panel-%d").build(); private final ExecutorService executorService = Executors.newSingleThreadExecutor(translationThreadFactory); @@ -180,6 +183,7 @@ class TranslatablePanel extends JPanel { private String content; private String contentDescriptor; + private boolean prevTranslateSelection; private volatile TranslatedText cachedTranslated; private volatile OnTranslation backgroundTask = null; @@ -201,31 +205,37 @@ class TranslatablePanel extends JPanel { TranslatablePanel(ContentComponent contentComponent, String origOptionText, String translatedOptionText, String origContent, TextTranslationService translationService) { this.contentComponent = contentComponent; - this.rootComponent = contentComponent.getRootComponent(); - this.origOptionText = origOptionText; - this.translatedOptionText = translatedOptionText; this.translationService = translationService; initComponents(); - additionalInit(); + additionalInit(contentComponent.getRootComponent(), origOptionText, translatedOptionText); setTranslationBarVisible(); reset(); } + /** + * @return the cached translated text or returns null + */ private TranslatedText getCachedTranslated() { synchronized (cachedTranslatedLock) { return cachedTranslated; } } + /** + * @param translated the translated text to be cached + */ private void setCachedTranslated(TranslatedText translated) { synchronized (cachedTranslatedLock) { this.cachedTranslated = translated; } } + /** + * if a translation worker is running, this is called to cancel the worker + */ private void cancelPendingTranslation() { synchronized (backgroundTaskLock) { if (backgroundTask != null && !backgroundTask.isDone()) { @@ -235,6 +245,9 @@ class TranslatablePanel extends JPanel { } } + /** + * runs a translation worker to translate the text + */ private void runTranslationTask() { synchronized (backgroundTaskLock) { cancelPendingTranslation(); @@ -246,14 +259,24 @@ class TranslatablePanel extends JPanel { } } + /** + * resets the component to an empty state and sets the translation bar visibility + * based on whether there is a provider + */ final void reset() { setTranslationBarVisible(); setContent(null, null); } + /** + * sets the content for the component; this also clears the status + * @param content the content for the panel + * @param contentDescriptor the content descriptor to be used in error messages + */ void setContent(String content, String contentDescriptor) { cancelPendingTranslation(); this.translateComboBox.setSelectedIndex(0); + this.prevTranslateSelection = false; this.content = content; this.contentDescriptor = contentDescriptor; clearStatus(); @@ -274,23 +297,43 @@ class TranslatablePanel extends JPanel { return translationService.translate(input); } + /** + * clears the status bar + */ private void clearStatus() { setStatus(null, false); } + /** + * sets the status bar message + * @param msg the status bar message to show + * @param showWarningIcon whether that status is a warning + */ private synchronized void setStatus(String msg, boolean showWarningIcon) { statusLabel.setText(msg); statusLabel.setIcon(showWarningIcon ? warningIcon : null); } + /** + * sets the translation bar visibility based on whether or not there is a provided + */ private void setTranslationBarVisible() { translationBar.setVisible(this.translationService.hasProvider()); } + /** + * the child component provided in the constructor will have its content set to the string provided + * @param content the content to display in the child component + */ private void setChildComponentContent(String content) { setChildComponentContent(content, DEFAULT_ORIENTATION); } + /** + * the child component provided in the constructor will have its content set to the string provided + * @param content the content to display in the child component + * @param orientation the orientation for the text + */ @Messages({"# {0} - exception message", "TranslatablePanel.onSetContentError.text=There was an error displaying the text: {0}"}) private synchronized void setChildComponentContent(String content, ComponentOrientation orientation) { SwingUtilities.invokeLater(() -> { @@ -302,26 +345,38 @@ class TranslatablePanel extends JPanel { }); } - private void additionalInit() { - add(this.rootComponent, java.awt.BorderLayout.CENTER); + /** + * items that are programmatically initialized + */ + private void additionalInit(Component rootComponent, String origOptionText, String translatedOptionText) { + add(rootComponent, java.awt.BorderLayout.CENTER); translateComboBox.removeAllItems(); - translateComboBox.addItem(new TranslateOption(this.origOptionText, false)); - translateComboBox.addItem(new TranslateOption(this.translatedOptionText, true)); + translateComboBox.addItem(new TranslateOption(origOptionText, false)); + translateComboBox.addItem(new TranslateOption(translatedOptionText, true)); } + /** + * when the combo box choice is selected, this method is fired + * @param translateOption the current translate option + */ private void handleComboBoxChange(TranslateOption translateOption) { - cancelPendingTranslation(); - clearStatus(); + boolean curTranslateSelection = translateOption.shouldTranslate(); + if (curTranslateSelection != this.prevTranslateSelection) { + this.prevTranslateSelection = curTranslateSelection; + + cancelPendingTranslation(); + clearStatus(); - if (translateOption.shouldTranslate()) { - TranslatedText translated = getCachedTranslated(); - if (translated != null) { - setChildComponentContent(translated.getText(), translated.getOrientation()); + if (curTranslateSelection) { + TranslatedText translated = getCachedTranslated(); + if (translated != null) { + setChildComponentContent(translated.getText(), translated.getOrientation()); + } else { + runTranslationTask(); + } } else { - runTranslationTask(); - } - } else { - setChildComponentContent(content); + setChildComponentContent(content); + } } } diff --git a/Core/src/org/sleuthkit/autopsy/texttranslation/ui/TranslateTextTask.java b/Core/src/org/sleuthkit/autopsy/texttranslation/ui/TranslateTextTask.java index 70fe09f4cf..2932cf5d19 100644 --- a/Core/src/org/sleuthkit/autopsy/texttranslation/ui/TranslateTextTask.java +++ b/Core/src/org/sleuthkit/autopsy/texttranslation/ui/TranslateTextTask.java @@ -36,7 +36,7 @@ import org.sleuthkit.autopsy.texttranslation.TranslationException; /** * abstract class for translating text and displaying to the user */ -public abstract class TranslateTextTask extends SwingWorker { +public abstract class TranslateTextTask extends SwingWorker { private static final Logger logger = Logger.getLogger(TranslatedTextViewer.class.getName()); @@ -46,21 +46,21 @@ public abstract class TranslateTextTask extends SwingWorker { onProgressDisplay(Bundle.TranslatedContentViewer_translatingText(), ComponentOrientation.LEFT_TO_RIGHT, Font.ITALIC); }); @@ -151,17 +184,17 @@ public abstract class TranslateTextTask extends SwingWorker Date: Fri, 6 Mar 2020 16:27:11 -0500 Subject: [PATCH 52/97] 6107 prompt user to use CR only in release mode --- .../eventlisteners/Installer.java | 64 +++++++++++-------- 1 file changed, 36 insertions(+), 28 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/Installer.java b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/Installer.java index 208f201a30..b9e5cd2d40 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/Installer.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/Installer.java @@ -32,6 +32,7 @@ import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoException; import org.sleuthkit.autopsy.core.RuntimeProperties; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.ModuleSettings; +import org.sleuthkit.autopsy.coreutils.Version; /** * Install event listeners during module initialization @@ -59,21 +60,38 @@ public class Installer extends ModuleInstall { @NbBundle.Messages({ "Installer.initialCreateSqlite.title=Enable Central Repository?", "Installer.initialCreateSqlite.messageHeader=The Central Repository is not enabled. Would you like to enable it?", - "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.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." }) @Override public void restored() { Case.addPropertyChangeListener(pcl); ieListener.installListeners(); + if (Version.getBuildType() == Version.Type.RELEASE) { + centralRepoCheckAndSetup(); + } + // now run regular module startup code + try { + CentralRepoDbManager.upgradeDatabase(); + } catch (CentralRepoException ex) { + LOGGER.log(Level.SEVERE, "There was an error while upgrading the central repository database", ex); + if (RuntimeProperties.runningWithGUI()) { + reportUpgradeError(ex); + } + } + } - + /** + * Check if CR has been previously configured or initialized and if not + * prompt user to set up. + */ + private void centralRepoCheckAndSetup() { Map centralRepoSettings = ModuleSettings.getConfigSettings("CentralRepository"); String initializedStr = centralRepoSettings.get("initialized"); - + // check to see if the repo has been initialized asking to setup cr boolean initialized = Boolean.parseBoolean(initializedStr); - + // if it hasn't received that flag, check for a previous install where cr is already setup if (!initialized) { boolean prevRepo = Boolean.parseBoolean(centralRepoSettings.get("db.useCentralRepo")); @@ -91,13 +109,13 @@ public class Installer extends ModuleInstall { try { SwingUtilities.invokeAndWait(() -> { try { - String dialogText = - "" + - "
" + - "

" + NbBundle.getMessage(this.getClass(), "Installer.initialCreateSqlite.messageHeader") + "

" + - "

" + NbBundle.getMessage(this.getClass(), "Installer.initialCreateSqlite.messageDesc") + "

" + - "
" + - ""; + String dialogText + = "" + + "
" + + "

" + NbBundle.getMessage(this.getClass(), "Installer.initialCreateSqlite.messageHeader") + "

" + + "

" + NbBundle.getMessage(this.getClass(), "Installer.initialCreateSqlite.messageDesc") + "

" + + "
" + + ""; if (JOptionPane.YES_OPTION == JOptionPane.showConfirmDialog(WindowManager.getDefault().getMainWindow(), dialogText, @@ -120,23 +138,13 @@ public class Installer extends ModuleInstall { try { setupDefaultSqlite(); } catch (CentralRepoException ex) { - LOGGER.log(Level.SEVERE, "There was an error while initializing the central repository database", ex); + LOGGER.log(Level.SEVERE, "There was an error while initializing the central repository database", ex); reportUpgradeError(ex); } } ModuleSettings.setConfigSetting("CentralRepository", "initialized", "true"); - } - - // now run regular module startup code - try { - CentralRepoDbManager.upgradeDatabase(); - } catch (CentralRepoException ex) { - LOGGER.log(Level.SEVERE, "There was an error while upgrading the central repository database", ex); - if (RuntimeProperties.runningWithGUI()) { - reportUpgradeError(ex); - } } } @@ -145,15 +153,15 @@ public class Installer extends ModuleInstall { manager.setupDefaultSqliteDb(); } - @NbBundle.Messages({ "Installer.centralRepoUpgradeFailed.title=Central repository disabled" }) + @NbBundle.Messages({"Installer.centralRepoUpgradeFailed.title=Central repository disabled"}) private void reportUpgradeError(CentralRepoException ex) { try { SwingUtilities.invokeAndWait(() -> { JOptionPane.showMessageDialog(null, - ex.getUserMessage(), - NbBundle.getMessage(this.getClass(), - "Installer.centralRepoUpgradeFailed.title"), - JOptionPane.ERROR_MESSAGE); + ex.getUserMessage(), + NbBundle.getMessage(this.getClass(), + "Installer.centralRepoUpgradeFailed.title"), + JOptionPane.ERROR_MESSAGE); }); } catch (InterruptedException | InvocationTargetException e) { LOGGER.log(Level.WARNING, e.getMessage(), e); From 9329b1244c84ed67950065be7820590b6c514a30 Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Fri, 6 Mar 2020 17:06:13 -0500 Subject: [PATCH 53/97] Update for geoartifact helpers API change --- InternalPythonModules/GPX_Module/GPX_Parser_Module.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/InternalPythonModules/GPX_Module/GPX_Parser_Module.py b/InternalPythonModules/GPX_Module/GPX_Parser_Module.py index 44e9217f4d..84a768b71e 100644 --- a/InternalPythonModules/GPX_Module/GPX_Parser_Module.py +++ b/InternalPythonModules/GPX_Module/GPX_Parser_Module.py @@ -216,7 +216,7 @@ class GPXParserDataSourceIngestModule(DataSourceIngestModule): geoWaypointList = TskGeoWaypointsUtil.GeoWaypointList() for point in route.points: - geoWaypointList.addPoint(point.latitude, point.longitude, elevation, point.name) + geoWaypointList.addPoint(GeoWaypoint(point.latitude, point.longitude, point.name)) try: geoArtifactHelper.addRoute(None, None, geoWaypointList, None) From ce49d54ca0fa87e84bb98d55c2ed88e43d3d0544 Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Fri, 6 Mar 2020 20:10:39 -0500 Subject: [PATCH 54/97] Make sure package installer for CR does no popup --- .../eventlisteners/Bundle.properties-MERGED | 2 +- .../eventlisteners/Installer.java | 181 ++++++++++++------ 2 files changed, 127 insertions(+), 56 deletions(-) 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..e3c99ded13 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/Bundle.properties-MERGED @@ -8,5 +8,5 @@ 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.messageHeader=The Central Repository is not enabled. Would you like to enable it? Installer.initialCreateSqlite.title=Enable Central Repository? diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/Installer.java b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/Installer.java index b9e5cd2d40..9f888e43f2 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/Installer.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/Installer.java @@ -1,7 +1,7 @@ /* - * Central Repository + * Autopsy Forensic Browser * - * Copyright 2015-2017 Basis Technology Corp. + * Copyright 2017-2020 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -35,17 +35,37 @@ import org.sleuthkit.autopsy.coreutils.ModuleSettings; import org.sleuthkit.autopsy.coreutils.Version; /** - * Install event listeners during module initialization + * Adds/removes application event listeners responsible for adding data to the + * central repository, sets up a default, single-user SQLite central repository + * if no central repository is configured, and updates the central repository + * schema as required. + * + * TODO (Jira-6108): At first glance, this package seems to have become a rather + * strange package for the "package installer" for the CR to reside in. The + * org.sleuthkit.autopsy.centralrepository package would seem to be more + * appropriate with so much going on. However, having a central repository + * schema update occur in a "package installer" with no user feedback is not + * optimal. Furthermore, for a multi-user (collaborative) installation, a schema + * update should be done in a more controlled way by acquiring an exclusive + * coordination service lock and requiring shared locks to be acquired by nodes + * with open cases. */ public class Installer extends ModuleInstall { - private static final Logger LOGGER = Logger.getLogger(Installer.class.getName()); + private static final Logger logger = Logger.getLogger(Installer.class.getName()); private static final long serialVersionUID = 1L; - private final CaseEventListener pcl = new CaseEventListener(); - private final IngestEventsListener ieListener = new IngestEventsListener(); - private static Installer instance; + private final CaseEventListener caseEventListener = new CaseEventListener(); + private final IngestEventsListener ingestEventListener = new IngestEventsListener(); + /** + * Gets the singleton "package installer" used by the registered Installer + * for the Autopsy-Core module located in the org.sleuthkit.autopsy.core + * package. + * + * @return The "package installer" singleton for the + * org.sleuthkit.autopsy.centralrepository.eventlisteners package. + */ public synchronized static Installer getDefault() { if (instance == null) { instance = new Installer(); @@ -53,10 +73,25 @@ public class Installer extends ModuleInstall { return instance; } + /** + * Constructs the singleton "package installer" used by the registered + * Installer for the Autopsy-Core module located in the + * org.sleuthkit.autopsy.core package. + */ private Installer() { super(); } + /* + * Adds/removes application event listeners responsible for adding data to + * the central repository, sets up a default, single-user SQLite central + * repository if no central repository is configured, and updates the + * central repository schema as required. + * + * Called by the registered Installer for the Autopsy-Core module located in + * the org.sleuthkit.autopsy.core package when the already installed + * Autopsy-Core module is restored (during application startup). + */ @NbBundle.Messages({ "Installer.initialCreateSqlite.title=Enable Central Repository?", "Installer.initialCreateSqlite.messageHeader=The Central Repository is not enabled. Would you like to enable it?", @@ -65,27 +100,31 @@ public class Installer extends ModuleInstall { }) @Override public void restored() { - Case.addPropertyChangeListener(pcl); - ieListener.installListeners(); + addApplicationEventListeners(); + if (Version.getBuildType() == Version.Type.RELEASE) { - centralRepoCheckAndSetup(); - } - // now run regular module startup code - try { - CentralRepoDbManager.upgradeDatabase(); - } catch (CentralRepoException ex) { - LOGGER.log(Level.SEVERE, "There was an error while upgrading the central repository database", ex); - if (RuntimeProperties.runningWithGUI()) { - reportUpgradeError(ex); - } + setupDefaultCentralRepository(); } + + updateCentralRepoSchema(); } /** - * Check if CR has been previously configured or initialized and if not - * prompt user to set up. + * Adds the application event listeners responsible for adding data to the + * central repository. */ - private void centralRepoCheckAndSetup() { + private void addApplicationEventListeners() { + Case.addPropertyChangeListener(caseEventListener); + ingestEventListener.installListeners(); + } + + /** + * Checks if the central repository has been set up and configured. If not, + * either offers to perform set up (running with a GUI) or does the set up + * unconditionally (not running with a GUI, e.g., in an automated ingest + * node). + */ + private void setupDefaultCentralRepository() { Map centralRepoSettings = ModuleSettings.getConfigSettings("CentralRepository"); String initializedStr = centralRepoSettings.get("initialized"); @@ -122,25 +161,25 @@ public class Installer extends ModuleInstall { NbBundle.getMessage(this.getClass(), "Installer.initialCreateSqlite.title"), JOptionPane.YES_NO_OPTION)) { - setupDefaultSqlite(); + setupDefaultSqliteCentralRepo(); } } catch (CentralRepoException ex) { - LOGGER.log(Level.SEVERE, "There was an error while initializing the central repository database", ex); + logger.log(Level.SEVERE, "There was an error while initializing the central repository database", ex); - reportUpgradeError(ex); + doMessageBoxIfRunningInGUI(ex); } }); } catch (InterruptedException | InvocationTargetException ex) { - LOGGER.log(Level.SEVERE, "There was an error while running the swing utility invoke later while creating the central repository database", ex); + logger.log(Level.SEVERE, "There was an error while running the swing utility invoke later while creating the central repository database", ex); } } // if no GUI, just initialize else { try { - setupDefaultSqlite(); + setupDefaultSqliteCentralRepo(); } catch (CentralRepoException ex) { - LOGGER.log(Level.SEVERE, "There was an error while initializing the central repository database", ex); + logger.log(Level.SEVERE, "There was an error while initializing the central repository database", ex); - reportUpgradeError(ex); + doMessageBoxIfRunningInGUI(ex); } } @@ -148,43 +187,75 @@ public class Installer extends ModuleInstall { } } - private void setupDefaultSqlite() throws CentralRepoException { + /** + * Sets up a default single-user SQLite central repository. + * + * @throws CentralRepoException If there is an error setting up teh central + * repository. + */ + private void setupDefaultSqliteCentralRepo() throws CentralRepoException { CentralRepoDbManager manager = new CentralRepoDbManager(); manager.setupDefaultSqliteDb(); } - @NbBundle.Messages({"Installer.centralRepoUpgradeFailed.title=Central repository disabled"}) - private void reportUpgradeError(CentralRepoException ex) { + /** + * Update the central repository schema. + */ + private void updateCentralRepoSchema() { try { - SwingUtilities.invokeAndWait(() -> { - JOptionPane.showMessageDialog(null, - ex.getUserMessage(), - NbBundle.getMessage(this.getClass(), - "Installer.centralRepoUpgradeFailed.title"), - JOptionPane.ERROR_MESSAGE); - }); - } catch (InterruptedException | InvocationTargetException e) { - LOGGER.log(Level.WARNING, e.getMessage(), e); + CentralRepoDbManager.upgradeDatabase(); + } catch (CentralRepoException ex) { + logger.log(Level.SEVERE, "An error occurred updating the central repository schema", ex); + if (RuntimeProperties.runningWithGUI()) { + doMessageBoxIfRunningInGUI(ex); + } } - } - @Override - public boolean closing() { - //platform about to close - - return true; + /** + * Display a central repository exception in a message box if running with a + * GUI. + * + * @param ex The exception. + */ + @NbBundle.Messages({"Installer.centralRepoUpgradeFailed.title=Central repository disabled"}) + private void doMessageBoxIfRunningInGUI(CentralRepoException ex) { + if (RuntimeProperties.runningWithGUI()) { + try { + SwingUtilities.invokeAndWait(() -> { + JOptionPane.showMessageDialog(null, + ex.getUserMessage(), + NbBundle.getMessage(this.getClass(), "Installer.centralRepoUpgradeFailed.title"), + JOptionPane.ERROR_MESSAGE); + }); + } catch (InterruptedException | InvocationTargetException e) { + logger.log(Level.WARNING, e.getMessage(), e); + } + } } @Override public void uninstalled() { - //module is being unloaded - - Case.removePropertyChangeListener(pcl); - pcl.shutdown(); - ieListener.shutdown(); - ieListener.uninstallListeners(); - - // TODO: remove thread pool + /* + * TODO (Jira-6108): This code is erronoeous. As documented at + * http://bits.netbeans.org/dev/javadoc/org-openide-modules/org/openide/modules/ModuleInstall.html#uninstalled-- + * + * "Called when the module is disabled while the application is still + * running. Should remove whatever functionality that it had registered + * in ModuleInstall.restored(). + * + * Beware: in practice there is no way to + * ensure that this method will really be called. The module might + * simply be deleted or disabled while the application is not running. + * In fact this is always the case in NetBeans 6.0; the Plugin Manager + * only uninstalls or disables modules between restarts. This method + * will still be called if you reload a module during development." + * + * THIS CODE IS NEVER EXECUTED. + */ + Case.removePropertyChangeListener(caseEventListener); + caseEventListener.shutdown(); + ingestEventListener.shutdown(); + ingestEventListener.uninstallListeners(); } } From 1d58cdcccbf94bf9ab8d24185ef23e9c73aa52ab Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Mon, 9 Mar 2020 08:11:28 -0400 Subject: [PATCH 55/97] 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 56/97] 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 57/97] 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 58/97] 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 e81fc04495bbfae0f5d2ede0353acafeedb5171a Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Mon, 9 Mar 2020 11:42:05 -0400 Subject: [PATCH 59/97] Update GPX parser for geo helper API changes --- InternalPythonModules/GPX_Module/GPX_Parser_Module.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/InternalPythonModules/GPX_Module/GPX_Parser_Module.py b/InternalPythonModules/GPX_Module/GPX_Parser_Module.py index 84a768b71e..6aeb84d5be 100644 --- a/InternalPythonModules/GPX_Module/GPX_Parser_Module.py +++ b/InternalPythonModules/GPX_Module/GPX_Parser_Module.py @@ -216,7 +216,7 @@ class GPXParserDataSourceIngestModule(DataSourceIngestModule): geoWaypointList = TskGeoWaypointsUtil.GeoWaypointList() for point in route.points: - geoWaypointList.addPoint(GeoWaypoint(point.latitude, point.longitude, point.name)) + geoWaypointList.addPoint(GeoWaypoint(point.latitude, point.longitude, point.elevation, point.name)) try: geoArtifactHelper.addRoute(None, None, geoWaypointList, None) From e842893a322a960bfc751423a8963cf6c4fa3c18 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Mon, 9 Mar 2020 13:20:01 -0400 Subject: [PATCH 60/97] 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 61/97] 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 468e0b95e9ee8c16e727ba751128d6afb43b88e6 Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Mon, 9 Mar 2020 17:51:39 -0400 Subject: [PATCH 62/97] 5052 utility class for AbstractNode backforund tasks --- .../datamodel/utils/BackgroundTaskRunner.java | 163 ++++++++++++++++++ 1 file changed, 163 insertions(+) create mode 100755 Core/src/org/sleuthkit/autopsy/datamodel/utils/BackgroundTaskRunner.java diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/utils/BackgroundTaskRunner.java b/Core/src/org/sleuthkit/autopsy/datamodel/utils/BackgroundTaskRunner.java new file mode 100755 index 0000000000..e6170b9500 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/datamodel/utils/BackgroundTaskRunner.java @@ -0,0 +1,163 @@ +/* + * 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 com.google.common.util.concurrent.ThreadFactoryBuilder; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.lang.ref.WeakReference; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.logging.Level; +import org.openide.nodes.AbstractNode; +import org.openide.util.WeakListeners; +import org.sleuthkit.autopsy.coreutils.Logger; +import org.sleuthkit.autopsy.datamodel.AbstractContentNode; + +/** + * A utility that allows AbstractNode subclasses to execute background tasks in + * threads in a thread pool. An AbstractNode subclass client needs to provide an + * implementation of the NodeTask interface that does the background task and + * returns the task result in the form of a PropertyChangeEvent. It also needs + * to provide an implementation of a PropertyChangeListener to handle the + * PropertyChangeEvent returned by the NodeTask. The utility uses weak + * references to the AbstractNode and the PropertyChangeListener to safely + * return results to the node, if it has not been destroyed by the NetBeans + * framework at the time the task is completed. + */ +public final class BackgroundTaskRunner { + + private static final Logger logger = Logger.getLogger(AbstractContentNode.class.getName()); + private static final Integer THREAD_POOL_SIZE = 10; + private static final ExecutorService executor = Executors.newFixedThreadPool(THREAD_POOL_SIZE, new ThreadFactoryBuilder().setNameFormat("node-background-task-%d").build()); + + /** + * Implementations of this interface do a task in a background thread + * supplied by this utility. + */ + @FunctionalInterface + public interface NodeTask { + + /** + * Performs a task in a thread supplied by this utility. + * + * @param future The future of the actual background task executing this + * method, may be checked for task cancellation. + * + * @return A PropertyChangeEvent holding the result of the task. + * + * @throws Exception If there is an error performing the task. + */ + PropertyChangeEvent run(Future future) throws Exception; + } + + /** + * Submits a background task for an AbstractNode to a dedicated thread pool. + * + * @param node The AbstractNode. + * @param task The task to be done in the background. + * @param listener A PropertyChangeListener for the AbstractNode to handle + * the PropertyChangeEvent produced by the task. + * + * @return The Future for the Runnable used to run the task. + */ + public static Future submitTask(AbstractNode node, NodeTask task, PropertyChangeListener listener) { + NodeBackgroundTask backgroundTask = new NodeBackgroundTask(node, task, listener); + Future future = executor.submit(backgroundTask); + backgroundTask.setFuture(future); + return future; + } + + /** + * A Runnable that uses weak references to an AbstractNode and the + * PropertyChangeListener for the node to safely return results to the node, + * if it has not been destroyed by the NetBeans framework at the time the + * task is completed. + */ + private static class NodeBackgroundTask implements Runnable { + + private final WeakReference weakNodeRef; + private final NodeTask task; + private final PropertyChangeListener weakListenerRef; + private Future future; + + /** + * Constructs a Runnable that uses weak references to an AbstractNode + * and the PropertyChangeListener for the node to safely return results + * to the node, if it still exists at the time the task is completed. + * + * @param node The AbstractNode. + * @param task The task to be done in the background. + * @param listener A PropertyChangeListener for the AbstractNode to + * handle the PropertyChangeEvent produced by the task. + */ + private NodeBackgroundTask(AbstractNode node, NodeTask task, PropertyChangeListener listener) { + this.weakNodeRef = new WeakReference<>(node); + this.task = task; + this.weakListenerRef = WeakListeners.propertyChange(listener, null); + } + + @Override + public void run() { + AbstractNode node = weakNodeRef.get(); + if (node == null) { + return; + } + + if (future.isCancelled()) { + return; + } + + PropertyChangeEvent changeEvent = null; + try { + changeEvent = task.run(future); + } catch (Exception ex) { + logger.log(Level.WARNING, "Error executing AbstractNode background task", ex); + } + + if (future.isCancelled()) { + return; + } + + if (changeEvent != null && weakListenerRef != null) { + weakListenerRef.propertyChange(changeEvent); + } + + } + + /** + * Provides this Runnable with access to its Future when it has been + * submitted to an ExecutrService. + * + * @param future The Future. + */ + private void setFuture(Future future) { + this.future = future; + } + + } + + /** + * A private constructor to prevent instatiation of this utility class. + */ + private BackgroundTaskRunner() { + } + +} From bd42ee66a937adcab5735afd78f19e6c9efe15a6 Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Mon, 9 Mar 2020 17:56:15 -0400 Subject: [PATCH 63/97] 5052 utility class for AbstractNode backforund tasks --- .../sleuthkit/autopsy/datamodel/utils/BackgroundTaskRunner.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/utils/BackgroundTaskRunner.java b/Core/src/org/sleuthkit/autopsy/datamodel/utils/BackgroundTaskRunner.java index e6170b9500..f06d02a07e 100755 --- a/Core/src/org/sleuthkit/autopsy/datamodel/utils/BackgroundTaskRunner.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/utils/BackgroundTaskRunner.java @@ -144,7 +144,7 @@ public final class BackgroundTaskRunner { /** * Provides this Runnable with access to its Future when it has been - * submitted to an ExecutrService. + * submitted to an ExecutorService. * * @param future The Future. */ From e93ff5e39f9b8e70479e3f7b2d8deba9af36d1c5 Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Tue, 10 Mar 2020 14:05:58 -0400 Subject: [PATCH 64/97] NodeBackgroundTaskRunner to AbstractNodePropertySheetTask --- .../utils/AbstractNodePropertySheetTask.java | 136 +++++++++++++++ .../datamodel/utils/BackgroundTaskRunner.java | 163 ------------------ 2 files changed, 136 insertions(+), 163 deletions(-) create mode 100755 Core/src/org/sleuthkit/autopsy/datamodel/utils/AbstractNodePropertySheetTask.java delete mode 100755 Core/src/org/sleuthkit/autopsy/datamodel/utils/BackgroundTaskRunner.java diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/utils/AbstractNodePropertySheetTask.java b/Core/src/org/sleuthkit/autopsy/datamodel/utils/AbstractNodePropertySheetTask.java new file mode 100755 index 0000000000..a96f705ee0 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/datamodel/utils/AbstractNodePropertySheetTask.java @@ -0,0 +1,136 @@ +/* + * 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 com.google.common.util.concurrent.ThreadFactoryBuilder; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.lang.ref.WeakReference; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.logging.Level; +import org.openide.nodes.AbstractNode; +import org.sleuthkit.autopsy.coreutils.Logger; +import org.sleuthkit.autopsy.datamodel.AbstractContentNode; + +/** + * An abstract base class for background tasks needed to compute values for the + * property sheet of an AbstractNode. + * + * The results of the computation are returned by firing a PropertyChangeEvent + * and the run method has an exception firewall with logging. These features + * relieve the AbstractNode from having to create a thread to block on the get() + * method of the task Future. + * + * Only weak references to the AbstractNode and its ProeprtyChangeListener are + * held prior to task execution so that a queued task does not interfere with + * garbage collection if the node has been destroyed by the NetBeans framework. + * + * A thread pool with descriptively named threads (node-background-task-N) is + * provided for executing instances of the tasks. + */ +public abstract class AbstractNodePropertySheetTask implements Runnable { + + private static final Logger LOGGER = Logger.getLogger(AbstractContentNode.class.getName()); + private static final Integer THREAD_POOL_SIZE = 10; + private static final ExecutorService executor = Executors.newFixedThreadPool(THREAD_POOL_SIZE, new ThreadFactoryBuilder().setNameFormat("node-background-task-%d").build()); + private final WeakReference weakNodeRef; + private final WeakReference weakListenerRef; + + /** + * Submits a task to compute values for the property sheet of an + * AbstractNode to a thread pool dedicated to such tasks with descriptively + * named threads (node-background-task-N). + * + * @param task The task. + * + * @return The Future of the task, may be used for task cancellation by + * calling Future.cancel(true). + */ + public static Future submitTask(AbstractNodePropertySheetTask task) { + return executor.submit(task); + } + + /** + * Constructs an abstract base class for background tasks needed to compute + * values for the property sheet of an AbstractNode. + * + * The results of the computation are returned by firing a + * PropertyChangeEvent and the run method has an exception firewall with + * logging. These features relieve the AbstractNode from having to create a + * thread to block on the get() method of the task Future. + * + * Only weak references to the AbstractNode and its ProeprtyChangeListener + * are held prior to task execution so that a queued task does not interfere + * with garbage collection if the node has been destroyed by the NetBeans + * framework. + * + * A thread pool with descriptively named threads (node-background-task-N) + * is provided for executing instances of the tasks. + * + * @param node The node. + * @param listener A property change listener for the node. + */ + protected AbstractNodePropertySheetTask(AbstractNode node, PropertyChangeListener listener) { + this.weakNodeRef = new WeakReference<>(node); + this.weakListenerRef = new WeakReference<>(listener); + } + + /** + * Computes the values for the property sheet of an AbstractNode. The + * results of the computation are returned as a PropertyChangeEvent which is + * fired to the PropertyChangeEventListener of the node. + * + * @param node The ABstractNode. + * + * @return The result of the computation as a PropertyChangeEvent. + */ + protected abstract PropertyChangeEvent computePropertyValue(AbstractNode node) throws Exception; + + @Override + final public void run() { + try { + AbstractNode node = this.weakNodeRef.get(); + PropertyChangeListener listener = this.weakListenerRef.get(); + if (node == null || listener== null) { + return; + } + + if (Thread.currentThread().isInterrupted()) { + return; + } + + PropertyChangeEvent changeEvent = computePropertyValue(node); + + if (Thread.currentThread().isInterrupted()) { + return; + } + + if (changeEvent != null) { + listener.propertyChange(changeEvent); + } + + } catch (Exception ex) { + LOGGER.log(Level.WARNING, "Error executing property sheet values computation background task", ex); + } + + } + +} diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/utils/BackgroundTaskRunner.java b/Core/src/org/sleuthkit/autopsy/datamodel/utils/BackgroundTaskRunner.java deleted file mode 100755 index f06d02a07e..0000000000 --- a/Core/src/org/sleuthkit/autopsy/datamodel/utils/BackgroundTaskRunner.java +++ /dev/null @@ -1,163 +0,0 @@ -/* - * 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 com.google.common.util.concurrent.ThreadFactoryBuilder; -import java.beans.PropertyChangeEvent; -import java.beans.PropertyChangeListener; -import java.lang.ref.WeakReference; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; -import java.util.logging.Level; -import org.openide.nodes.AbstractNode; -import org.openide.util.WeakListeners; -import org.sleuthkit.autopsy.coreutils.Logger; -import org.sleuthkit.autopsy.datamodel.AbstractContentNode; - -/** - * A utility that allows AbstractNode subclasses to execute background tasks in - * threads in a thread pool. An AbstractNode subclass client needs to provide an - * implementation of the NodeTask interface that does the background task and - * returns the task result in the form of a PropertyChangeEvent. It also needs - * to provide an implementation of a PropertyChangeListener to handle the - * PropertyChangeEvent returned by the NodeTask. The utility uses weak - * references to the AbstractNode and the PropertyChangeListener to safely - * return results to the node, if it has not been destroyed by the NetBeans - * framework at the time the task is completed. - */ -public final class BackgroundTaskRunner { - - private static final Logger logger = Logger.getLogger(AbstractContentNode.class.getName()); - private static final Integer THREAD_POOL_SIZE = 10; - private static final ExecutorService executor = Executors.newFixedThreadPool(THREAD_POOL_SIZE, new ThreadFactoryBuilder().setNameFormat("node-background-task-%d").build()); - - /** - * Implementations of this interface do a task in a background thread - * supplied by this utility. - */ - @FunctionalInterface - public interface NodeTask { - - /** - * Performs a task in a thread supplied by this utility. - * - * @param future The future of the actual background task executing this - * method, may be checked for task cancellation. - * - * @return A PropertyChangeEvent holding the result of the task. - * - * @throws Exception If there is an error performing the task. - */ - PropertyChangeEvent run(Future future) throws Exception; - } - - /** - * Submits a background task for an AbstractNode to a dedicated thread pool. - * - * @param node The AbstractNode. - * @param task The task to be done in the background. - * @param listener A PropertyChangeListener for the AbstractNode to handle - * the PropertyChangeEvent produced by the task. - * - * @return The Future for the Runnable used to run the task. - */ - public static Future submitTask(AbstractNode node, NodeTask task, PropertyChangeListener listener) { - NodeBackgroundTask backgroundTask = new NodeBackgroundTask(node, task, listener); - Future future = executor.submit(backgroundTask); - backgroundTask.setFuture(future); - return future; - } - - /** - * A Runnable that uses weak references to an AbstractNode and the - * PropertyChangeListener for the node to safely return results to the node, - * if it has not been destroyed by the NetBeans framework at the time the - * task is completed. - */ - private static class NodeBackgroundTask implements Runnable { - - private final WeakReference weakNodeRef; - private final NodeTask task; - private final PropertyChangeListener weakListenerRef; - private Future future; - - /** - * Constructs a Runnable that uses weak references to an AbstractNode - * and the PropertyChangeListener for the node to safely return results - * to the node, if it still exists at the time the task is completed. - * - * @param node The AbstractNode. - * @param task The task to be done in the background. - * @param listener A PropertyChangeListener for the AbstractNode to - * handle the PropertyChangeEvent produced by the task. - */ - private NodeBackgroundTask(AbstractNode node, NodeTask task, PropertyChangeListener listener) { - this.weakNodeRef = new WeakReference<>(node); - this.task = task; - this.weakListenerRef = WeakListeners.propertyChange(listener, null); - } - - @Override - public void run() { - AbstractNode node = weakNodeRef.get(); - if (node == null) { - return; - } - - if (future.isCancelled()) { - return; - } - - PropertyChangeEvent changeEvent = null; - try { - changeEvent = task.run(future); - } catch (Exception ex) { - logger.log(Level.WARNING, "Error executing AbstractNode background task", ex); - } - - if (future.isCancelled()) { - return; - } - - if (changeEvent != null && weakListenerRef != null) { - weakListenerRef.propertyChange(changeEvent); - } - - } - - /** - * Provides this Runnable with access to its Future when it has been - * submitted to an ExecutorService. - * - * @param future The Future. - */ - private void setFuture(Future future) { - this.future = future; - } - - } - - /** - * A private constructor to prevent instatiation of this utility class. - */ - private BackgroundTaskRunner() { - } - -} From e8fe6ec1e57be944070c456c1fe767945d9b6c17 Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Tue, 10 Mar 2020 14:09:14 -0400 Subject: [PATCH 65/97] NodeBackgroundTaskRunner to AbstractNodePropertySheetTask --- .../datamodel/utils/AbstractNodePropertySheetTask.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/utils/AbstractNodePropertySheetTask.java b/Core/src/org/sleuthkit/autopsy/datamodel/utils/AbstractNodePropertySheetTask.java index a96f705ee0..ea7aca6ab4 100755 --- a/Core/src/org/sleuthkit/autopsy/datamodel/utils/AbstractNodePropertySheetTask.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/utils/AbstractNodePropertySheetTask.java @@ -98,7 +98,11 @@ public abstract class AbstractNodePropertySheetTask implements Runnable { * results of the computation are returned as a PropertyChangeEvent which is * fired to the PropertyChangeEventListener of the node. * - * @param node The ABstractNode. + * IMPORTANT: Implementations of this method should check for cancellation + * by calling Thread.currentThread().isInterrupted() at approoraite + * intervals. + * + * @param node The AbstractNode. * * @return The result of the computation as a PropertyChangeEvent. */ @@ -109,7 +113,7 @@ public abstract class AbstractNodePropertySheetTask implements Runnable { try { AbstractNode node = this.weakNodeRef.get(); PropertyChangeListener listener = this.weakListenerRef.get(); - if (node == null || listener== null) { + if (node == null || listener == null) { return; } @@ -118,7 +122,7 @@ public abstract class AbstractNodePropertySheetTask implements Runnable { } PropertyChangeEvent changeEvent = computePropertyValue(node); - + if (Thread.currentThread().isInterrupted()) { return; } From e5d36505514a9ae2e6a1c57ed49eabaacd3896a2 Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Tue, 10 Mar 2020 14:11:27 -0400 Subject: [PATCH 66/97] NodeBackgroundTaskRunner to AbstractNodePropertySheetTask --- .../datamodel/utils/AbstractNodePropertySheetTask.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/utils/AbstractNodePropertySheetTask.java b/Core/src/org/sleuthkit/autopsy/datamodel/utils/AbstractNodePropertySheetTask.java index ea7aca6ab4..b05118bda4 100755 --- a/Core/src/org/sleuthkit/autopsy/datamodel/utils/AbstractNodePropertySheetTask.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/utils/AbstractNodePropertySheetTask.java @@ -39,7 +39,7 @@ import org.sleuthkit.autopsy.datamodel.AbstractContentNode; * relieve the AbstractNode from having to create a thread to block on the get() * method of the task Future. * - * Only weak references to the AbstractNode and its ProeprtyChangeListener are + * Only weak references to the AbstractNode and its PropertyChangeListener are * held prior to task execution so that a queued task does not interfere with * garbage collection if the node has been destroyed by the NetBeans framework. * @@ -77,7 +77,7 @@ public abstract class AbstractNodePropertySheetTask implements Runnable { * logging. These features relieve the AbstractNode from having to create a * thread to block on the get() method of the task Future. * - * Only weak references to the AbstractNode and its ProeprtyChangeListener + * Only weak references to the AbstractNode and its PropertyChangeListener * are held prior to task execution so that a queued task does not interfere * with garbage collection if the node has been destroyed by the NetBeans * framework. From 3038a9b869c26cb4a960cc6a633478caf75fb8b5 Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Tue, 10 Mar 2020 14:36:47 -0400 Subject: [PATCH 67/97] NodeBackgroundTaskRunner to AbstractNodePropertySheetTask --- .../utils/AbstractNodePropertySheetTask.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/utils/AbstractNodePropertySheetTask.java b/Core/src/org/sleuthkit/autopsy/datamodel/utils/AbstractNodePropertySheetTask.java index b05118bda4..368b09b142 100755 --- a/Core/src/org/sleuthkit/autopsy/datamodel/utils/AbstractNodePropertySheetTask.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/utils/AbstractNodePropertySheetTask.java @@ -46,12 +46,12 @@ import org.sleuthkit.autopsy.datamodel.AbstractContentNode; * A thread pool with descriptively named threads (node-background-task-N) is * provided for executing instances of the tasks. */ -public abstract class AbstractNodePropertySheetTask implements Runnable { +public abstract class AbstractNodePropertySheetTask implements Runnable { private static final Logger LOGGER = Logger.getLogger(AbstractContentNode.class.getName()); private static final Integer THREAD_POOL_SIZE = 10; private static final ExecutorService executor = Executors.newFixedThreadPool(THREAD_POOL_SIZE, new ThreadFactoryBuilder().setNameFormat("node-background-task-%d").build()); - private final WeakReference weakNodeRef; + private final WeakReference weakNodeRef; private final WeakReference weakListenerRef; /** @@ -64,7 +64,7 @@ public abstract class AbstractNodePropertySheetTask implements Runnable { * @return The Future of the task, may be used for task cancellation by * calling Future.cancel(true). */ - public static Future submitTask(AbstractNodePropertySheetTask task) { + public static Future submitTask(AbstractNodePropertySheetTask task) { return executor.submit(task); } @@ -88,7 +88,7 @@ public abstract class AbstractNodePropertySheetTask implements Runnable { * @param node The node. * @param listener A property change listener for the node. */ - protected AbstractNodePropertySheetTask(AbstractNode node, PropertyChangeListener listener) { + protected AbstractNodePropertySheetTask(T node, PropertyChangeListener listener) { this.weakNodeRef = new WeakReference<>(node); this.weakListenerRef = new WeakReference<>(listener); } @@ -99,19 +99,19 @@ public abstract class AbstractNodePropertySheetTask implements Runnable { * fired to the PropertyChangeEventListener of the node. * * IMPORTANT: Implementations of this method should check for cancellation - * by calling Thread.currentThread().isInterrupted() at approoraite + * by calling Thread.currentThread().isInterrupted() at appropriate * intervals. * * @param node The AbstractNode. * * @return The result of the computation as a PropertyChangeEvent. */ - protected abstract PropertyChangeEvent computePropertyValue(AbstractNode node) throws Exception; + protected abstract PropertyChangeEvent computePropertyValue(T node) throws Exception; @Override final public void run() { try { - AbstractNode node = this.weakNodeRef.get(); + T node = this.weakNodeRef.get(); PropertyChangeListener listener = this.weakListenerRef.get(); if (node == null || listener == null) { return; From dc048fc03400731d49c478c652994e1b80e6f5ea Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Tue, 10 Mar 2020 15:11:00 -0400 Subject: [PATCH 68/97] 6075 Remove popup from TimelineController event handler --- .../org/sleuthkit/autopsy/timeline/TimeLineController.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/timeline/TimeLineController.java b/Core/src/org/sleuthkit/autopsy/timeline/TimeLineController.java index adf4509e76..cf8e9c46f7 100755 --- a/Core/src/org/sleuthkit/autopsy/timeline/TimeLineController.java +++ b/Core/src/org/sleuthkit/autopsy/timeline/TimeLineController.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2014-2019 Basis Technology Corp. + * Copyright 2014-2020 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -72,7 +72,6 @@ import org.sleuthkit.autopsy.casemodule.events.ContentTagDeletedEvent; import org.sleuthkit.autopsy.coreutils.History; import org.sleuthkit.autopsy.coreutils.LoggedTask; import org.sleuthkit.autopsy.coreutils.Logger; -import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil; import org.sleuthkit.autopsy.coreutils.ThreadConfined; import org.sleuthkit.autopsy.events.AutopsyEvent; import org.sleuthkit.autopsy.ingest.IngestManager; @@ -806,7 +805,6 @@ public class TimeLineController { future.get(); } catch (InterruptedException | ExecutionException ex) { logger.log(Level.SEVERE, errorLogMessage, ex); - MessageNotifyUtil.Message.error(errorUserMessage); } }, MoreExecutors.directExecutor()); } From 7a2c1319dad002486431a39a4ba61bf47a698463 Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Tue, 10 Mar 2020 16:08:43 -0400 Subject: [PATCH 69/97] 5790 multi-user case deletion control --- .../org/sleuthkit/autopsy/casemodule/Case.java | 2 +- .../autopsy/casemodule/CaseDeleteAction.java | 5 +++-- .../autopsy/featureaccess/FeatureAccessUtils.java | 15 ++++++++++++--- 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/Case.java b/Core/src/org/sleuthkit/autopsy/casemodule/Case.java index e684b4af4b..a031c9b5ed 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/Case.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/Case.java @@ -1114,7 +1114,7 @@ public class Case { CallableSystemAction.get(CaseCloseAction.class).setEnabled(true); CallableSystemAction.get(CaseDetailsAction.class).setEnabled(true); CallableSystemAction.get(DataSourceSummaryAction.class).setEnabled(true); - CallableSystemAction.get(CaseDeleteAction.class).setEnabled(true); + CallableSystemAction.get(CaseDeleteAction.class).setEnabled(FeatureAccessUtils.canDeleteCases()); CallableSystemAction.get(OpenTimelineAction.class).setEnabled(true); CallableSystemAction.get(OpenCommVisualizationToolAction.class).setEnabled(true); CallableSystemAction.get(CommonAttributeSearchAction.class).setEnabled(true); diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/CaseDeleteAction.java b/Core/src/org/sleuthkit/autopsy/casemodule/CaseDeleteAction.java index a389aca979..f7bb3d6a62 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/CaseDeleteAction.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/CaseDeleteAction.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2011-2018 Basis Technology Corp. + * Copyright 2011-2020 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -35,6 +35,7 @@ import org.openide.util.NbBundle.Messages; import org.openide.util.actions.CallableSystemAction; import org.openide.windows.WindowManager; import org.sleuthkit.autopsy.coreutils.Logger; +import org.sleuthkit.autopsy.featureaccess.FeatureAccessUtils; /** * The action associated with the Delete button of the Case Properties panel. It @@ -54,7 +55,7 @@ final class CaseDeleteAction extends CallableSystemAction { /* * A value of 'null' signifies that there is no case open. */ - setEnabled(null != evt.getNewValue()); + setEnabled(null != evt.getNewValue() && FeatureAccessUtils.canDeleteCases()); }); } diff --git a/Core/src/org/sleuthkit/autopsy/featureaccess/FeatureAccessUtils.java b/Core/src/org/sleuthkit/autopsy/featureaccess/FeatureAccessUtils.java index 87b4fed4f7..738aedf331 100644 --- a/Core/src/org/sleuthkit/autopsy/featureaccess/FeatureAccessUtils.java +++ b/Core/src/org/sleuthkit/autopsy/featureaccess/FeatureAccessUtils.java @@ -73,6 +73,15 @@ final public class FeatureAccessUtils { return dataSourceDeletionAllowed; } + /** + * Indicates whether or not a user can delete the current case. + * + * @return True or false. + */ + public static boolean canDeleteCases() { + return currentCaseIsSingleUserCase() || multiUserCaseRestrictionsFileAbsent(); + } + /** * Indicates whether or not the current case is a single-user case. * @@ -83,12 +92,12 @@ final public class FeatureAccessUtils { } /** - * Indicates whether or not the current user is allowed to create or modify - * (add or delete data sources) multi-user cases. + * Indicates whether or not the multi-user case privileges restriction file + * is absent. * * @return True or false. */ - public static boolean multiUserCaseRestrictionsFileAbsent() { + private static boolean multiUserCaseRestrictionsFileAbsent() { File accessLimitingFile = new File(MULTIUSER_CASE_RESTRICTED_FILE_PATH); return !accessLimitingFile.exists(); } From 45cd32b997bc20d20dbf5ccca944e5bd2bc7ca7b Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Tue, 10 Mar 2020 16:09:41 -0400 Subject: [PATCH 70/97] 5790 multi-user case deletion control --- Core/src/org/sleuthkit/autopsy/casemodule/Case.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/Case.java b/Core/src/org/sleuthkit/autopsy/casemodule/Case.java index a031c9b5ed..39a13dcfab 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/Case.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/Case.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2012-2019 Basis Technology Corp. + * Copyright 2012-2020 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); From 8353d8436b6279ee97e409f27a0f89023b20e6b6 Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Tue, 10 Mar 2020 16:11:41 -0400 Subject: [PATCH 71/97] 5790 multi-user case deletion control --- Core/src/org/sleuthkit/autopsy/casemodule/Case.java | 2 +- Core/src/org/sleuthkit/autopsy/casemodule/CaseDeleteAction.java | 2 +- .../org/sleuthkit/autopsy/featureaccess/FeatureAccessUtils.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/Case.java b/Core/src/org/sleuthkit/autopsy/casemodule/Case.java index 39a13dcfab..b70845e3df 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/Case.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/Case.java @@ -1114,7 +1114,7 @@ public class Case { CallableSystemAction.get(CaseCloseAction.class).setEnabled(true); CallableSystemAction.get(CaseDetailsAction.class).setEnabled(true); CallableSystemAction.get(DataSourceSummaryAction.class).setEnabled(true); - CallableSystemAction.get(CaseDeleteAction.class).setEnabled(FeatureAccessUtils.canDeleteCases()); + CallableSystemAction.get(CaseDeleteAction.class).setEnabled(FeatureAccessUtils.canDeleteCurrentCase()); CallableSystemAction.get(OpenTimelineAction.class).setEnabled(true); CallableSystemAction.get(OpenCommVisualizationToolAction.class).setEnabled(true); CallableSystemAction.get(CommonAttributeSearchAction.class).setEnabled(true); diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/CaseDeleteAction.java b/Core/src/org/sleuthkit/autopsy/casemodule/CaseDeleteAction.java index f7bb3d6a62..6bd0231405 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/CaseDeleteAction.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/CaseDeleteAction.java @@ -55,7 +55,7 @@ final class CaseDeleteAction extends CallableSystemAction { /* * A value of 'null' signifies that there is no case open. */ - setEnabled(null != evt.getNewValue() && FeatureAccessUtils.canDeleteCases()); + setEnabled(null != evt.getNewValue() && FeatureAccessUtils.canDeleteCurrentCase()); }); } diff --git a/Core/src/org/sleuthkit/autopsy/featureaccess/FeatureAccessUtils.java b/Core/src/org/sleuthkit/autopsy/featureaccess/FeatureAccessUtils.java index 738aedf331..fdc5d8b222 100644 --- a/Core/src/org/sleuthkit/autopsy/featureaccess/FeatureAccessUtils.java +++ b/Core/src/org/sleuthkit/autopsy/featureaccess/FeatureAccessUtils.java @@ -78,7 +78,7 @@ final public class FeatureAccessUtils { * * @return True or false. */ - public static boolean canDeleteCases() { + public static boolean canDeleteCurrentCase() { return currentCaseIsSingleUserCase() || multiUserCaseRestrictionsFileAbsent(); } From 9163097d3cf42a7df39e33989fb363b0d7c7048a Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Tue, 10 Mar 2020 16:33:29 -0400 Subject: [PATCH 72/97] 6028 Restrict ability to add hash sets to CR --- .../autopsy/featureaccess/FeatureAccessUtils.java | 12 +++++++++++- .../hashdatabase/HashDbImportDatabaseDialog.java | 6 +++--- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/featureaccess/FeatureAccessUtils.java b/Core/src/org/sleuthkit/autopsy/featureaccess/FeatureAccessUtils.java index 87b4fed4f7..780ceb054e 100644 --- a/Core/src/org/sleuthkit/autopsy/featureaccess/FeatureAccessUtils.java +++ b/Core/src/org/sleuthkit/autopsy/featureaccess/FeatureAccessUtils.java @@ -73,6 +73,16 @@ final public class FeatureAccessUtils { return dataSourceDeletionAllowed; } + /** + * Indicates whether or not a user can add hash sets to the central + * repository. + * + * @return True or false. + */ + public static boolean canAddHashSetsToCentralRepo() { + return multiUserCaseRestrictionsFileAbsent(); + } + /** * Indicates whether or not the current case is a single-user case. * @@ -88,7 +98,7 @@ final public class FeatureAccessUtils { * * @return True or false. */ - public static boolean multiUserCaseRestrictionsFileAbsent() { + private static boolean multiUserCaseRestrictionsFileAbsent() { File accessLimitingFile = new File(MULTIUSER_CASE_RESTRICTED_FILE_PATH); return !accessLimitingFile.exists(); } diff --git a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbImportDatabaseDialog.java b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbImportDatabaseDialog.java index 1e34c9bbda..f3bd39148f 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbImportDatabaseDialog.java +++ b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbImportDatabaseDialog.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2011-2018 Basis Technology Corp. + * Copyright 2014-2020 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -42,6 +42,7 @@ import org.sleuthkit.autopsy.modules.hashdatabase.HashDbManager.HashDb.KnownFile import org.sleuthkit.autopsy.modules.hashdatabase.HashDbManager.HashDbManagerException; import org.sleuthkit.autopsy.modules.hashdatabase.HashDbManager.HashDb; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository; +import org.sleuthkit.autopsy.featureaccess.FeatureAccessUtils; /** * Instances of this class allow a user to select an existing hash database and @@ -108,8 +109,7 @@ final class HashDbImportDatabaseDialog extends javax.swing.JDialog { private void enableComponents(){ - - if(! CentralRepository.isEnabled()){ + if(!CentralRepository.isEnabled() || !FeatureAccessUtils.canAddHashSetsToCentralRepo()){ centralRepoRadioButton.setEnabled(false); fileTypeRadioButton.setSelected(true); } else { From 760f88658c024ffc5e34f7d40fad396e48823751 Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Tue, 10 Mar 2020 17:06:15 -0400 Subject: [PATCH 73/97] 6039 ELiminate popups from ingest module factory --- .../ingest/IngestModuleFactoryLoader.java | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/ingest/IngestModuleFactoryLoader.java b/Core/src/org/sleuthkit/autopsy/ingest/IngestModuleFactoryLoader.java index 672ffd6807..3e3e006dd3 100644 --- a/Core/src/org/sleuthkit/autopsy/ingest/IngestModuleFactoryLoader.java +++ b/Core/src/org/sleuthkit/autopsy/ingest/IngestModuleFactoryLoader.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2014-2018 Basis Technology Corp. + * Copyright 2014-2020 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -51,6 +51,7 @@ final class IngestModuleFactoryLoader { private static final Logger logger = Logger.getLogger(IngestModuleFactoryLoader.class.getName()); private static final String SAMPLE_MODULE_FACTORY_CLASS_NAME = SampleIngestModuleFactory.class.getCanonicalName(); private static final ArrayList coreModuleOrdering = new ArrayList() { + private static final long serialVersionUID = 1L; { // The ordering of the core ingest module factories implemented // using Java is hard-coded. @@ -79,7 +80,7 @@ final class IngestModuleFactoryLoader { * removed between invocations. * * @return A list of objects that implement the IngestModuleFactory - * interface. + * interface. */ static List getIngestModuleFactories() { // A hash set of display names and a hash map of class names to @@ -132,7 +133,7 @@ final class IngestModuleFactoryLoader { factories.add(factory); logger.log(Level.INFO, "Found ingest module factory: name = {0}, version = {1}", new Object[]{factory.getModuleDisplayName(), factory.getModuleVersionNumber()}); //NON-NLS } else { - logger.log(Level.SEVERE, "Found duplicate ingest module display name (name = {0})", factory.getModuleDisplayName()); //NON-NLS + logger.log(Level.WARNING, "Found duplicate ingest module display name (name = {0})", factory.getModuleDisplayName()); //NON-NLS DialogDisplayer.getDefault().notify(new NotifyDescriptor.Message( NbBundle.getMessage(IngestModuleFactoryLoader.class, "IngestModuleFactoryLoader.errorMessages.duplicateDisplayName", factory.getModuleDisplayName()), NotifyDescriptor.ERROR_MESSAGE)); @@ -154,11 +155,14 @@ final class IngestModuleFactoryLoader { javaFactoriesByClass.put(factory.getClass().getCanonicalName(), factory); logger.log(Level.INFO, "Found ingest module factory: name = {0}, version = {1}", new Object[]{factory.getModuleDisplayName(), factory.getModuleVersionNumber()}); //NON-NLS } else { - logger.log(Level.SEVERE, "Found duplicate ingest module display name (name = {0})", factory.getModuleDisplayName()); //NON-NLS - DialogDisplayer.getDefault().notify(new NotifyDescriptor.Message( - NbBundle.getMessage(IngestModuleFactoryLoader.class, "IngestModuleFactoryLoader.errorMessages.duplicateDisplayName", factory.getModuleDisplayName()), - NotifyDescriptor.ERROR_MESSAGE)); + logger.log(Level.WARNING, "Found duplicate ingest module display name (name = {0})", factory.getModuleDisplayName()); //NON-NLS } } + /** + * Private constructor to prevent instantiation of this utility class. + */ + private IngestModuleFactoryLoader() { + } + } From b6957fe2bcb1ac3736bc1823a6624c0e42829125 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Tue, 10 Mar 2020 17:25:21 -0400 Subject: [PATCH 74/97] 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 75/97] 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 5b5a2fe204ccd1faac1bb7091eeb649538a79f72 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Wed, 11 Mar 2020 10:14:59 -0400 Subject: [PATCH 76/97] update for disabled --- .../contentviewers/MessageContentViewer.java | 3 +- .../contentviewers/TranslatablePanel.java | 66 +++++++++---------- .../texttranslation/ui/TranslateTextTask.java | 30 ++++----- 3 files changed, 49 insertions(+), 50 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java b/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java index 9f6062a4bb..8ea3867470 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java @@ -89,7 +89,7 @@ import org.sleuthkit.datamodel.blackboardutils.attributes.MessageAttachments.URL public class MessageContentViewer extends javax.swing.JPanel implements DataContentViewer { /** - * a text component viewer to be a child component to be placed in a translatablepanel. + * This is a text component viewer to be a child component to be placed in a {@link TranslatablePanel TranslatablePanel}. */ class TextComponent implements TranslatablePanel.ContentComponent { @@ -151,7 +151,6 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont drp = DataResultPanel.createInstanceUninitialized(Bundle.MessageContentViewer_AtrachmentsPanel_title(), "", new TableFilterNode(Node.EMPTY, false), 0, null); attachmentsScrollPane.setViewportView(drp); - //textPanel.setLayout(new BorderLayout()); msgbodyTabbedPane.insertTab( NbBundle.getMessage(MessageContentViewer.class, "MessageContentViewer.textbodyScrollPane.TabConstraints.tabTitle"), null, diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/TranslatablePanel.java b/Core/src/org/sleuthkit/autopsy/contentviewers/TranslatablePanel.java index e20b7e063e..1e3c5514bd 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/TranslatablePanel.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/TranslatablePanel.java @@ -35,14 +35,14 @@ import org.sleuthkit.autopsy.texttranslation.TranslationException; import org.sleuthkit.autopsy.texttranslation.ui.TranslateTextTask; /** - * A panel for translation with a subcomponent that allows for translation + * This is a panel for translation with a subcomponent that allows for translation. */ class TranslatablePanel extends JPanel { /** - * an exception that can occur during the normal operation of the translatable panel - * for instance, this exception can be thrown if it is not possible to set the child - * content to the provided content string + * This is an exception that can occur during the normal operation of the translatable + * panel. For instance, this exception can be thrown if it is not possible to set the child + * content to the provided content string. */ class TranslatablePanelException extends Exception { public static final long serialVersionUID = 1L; @@ -58,18 +58,18 @@ class TranslatablePanel extends JPanel { /** - * describes a child component to be placed as a child of this panel. the child received - * from getRootComponent() will listen for content updates from setContent() + * This describes a child component to be placed as a child of this panel. The child received + * from {@link #getRootComponent() getRootComponent() } will listen for content updates from setContent(). */ interface ContentComponent { /** - * gets root component of the translation panel + * This method gets root component of the translation panel. * @return the root component to insert into the translatable panel */ Component getRootComponent(); /** - * sets the content of the component to the provided content + * This method sets the content of the component to the provided content. * @param content the content to be displayed * @param orientation how it should be displayed * @throws Exception if there is an error in rendering the content @@ -79,7 +79,7 @@ class TranslatablePanel extends JPanel { /** - * an option in drop down of whether or not to translate + * This is an option in drop down of whether or not to translate. */ private static class TranslateOption { @@ -106,7 +106,7 @@ class TranslatablePanel extends JPanel { } /** - * the cached result of translating the current content + * This represents the cached result of translating the current content. */ private static class TranslatedText { @@ -128,7 +128,8 @@ class TranslatablePanel extends JPanel { } /** - * connects the swing worker specified by TranslateTextTask to this component + * This connects the swing worker specified by + * {@link org.sleuthkit.autopsy.texttranslation.ui.TranslateTextTask TranslateTextTask} to this component. */ private class OnTranslation extends TranslateTextTask { @@ -138,7 +139,7 @@ class TranslatablePanel extends JPanel { @Override protected String translate(String input) throws NoServiceProviderException, TranslationException { - // defer to outer class method so that it can be overridden for items like html, rtf, etc. + // This defers to the outer class method so that it can be overridden for items like html, rtf, etc. return retrieveTranslation(input); } @@ -159,11 +160,11 @@ class TranslatablePanel extends JPanel { @Override protected void onTextDisplay(String text, ComponentOrientation orientation, int font) { - // on successful acquire cache the result and set the text + // On successful acquire, this caches the result and set the text. setCachedTranslated(new TranslatedText(text, orientation)); setChildComponentContent(text, orientation); - // clear any status + // This clears any status that may be present. clearStatus(); } } @@ -200,7 +201,7 @@ class TranslatablePanel extends JPanel { } /** - * Creates new form TranslatedContentPanel + * This creates a new panel using @{link ContentPanel ContentPanel} as a child. */ TranslatablePanel(ContentComponent contentComponent, String origOptionText, String translatedOptionText, String origContent, TextTranslationService translationService) { @@ -209,7 +210,6 @@ class TranslatablePanel extends JPanel { initComponents(); additionalInit(contentComponent.getRootComponent(), origOptionText, translatedOptionText); - setTranslationBarVisible(); reset(); } @@ -234,7 +234,7 @@ class TranslatablePanel extends JPanel { } /** - * if a translation worker is running, this is called to cancel the worker + * If a translation worker is running, this is called to cancel the worker. */ private void cancelPendingTranslation() { synchronized (backgroundTaskLock) { @@ -246,7 +246,7 @@ class TranslatablePanel extends JPanel { } /** - * runs a translation worker to translate the text + * This runs a translation worker to translate the text. */ private void runTranslationTask() { synchronized (backgroundTaskLock) { @@ -260,16 +260,16 @@ class TranslatablePanel extends JPanel { } /** - * resets the component to an empty state and sets the translation bar visibility - * based on whether there is a provider + * This resets the component to an empty state and sets the translation bar visibility + * based on whether there is a provider. */ final void reset() { - setTranslationBarVisible(); + setTranslationEnabled(); setContent(null, null); } /** - * sets the content for the component; this also clears the status + * This method sets the content for the component; this also clears the status. * @param content the content for the panel * @param contentDescriptor the content descriptor to be used in error messages */ @@ -285,8 +285,8 @@ class TranslatablePanel extends JPanel { } /** - * where actual translation takes place allowed to be overridden for the - * sake of varying translatable content (i.e. html, rtf, etc) + * This is where actual translation takes place allowed to be overridden for the + * sake of varying translatable content (i.e. html, rtf, etc). * * @param input the input content * @return the result of translation @@ -298,14 +298,14 @@ class TranslatablePanel extends JPanel { } /** - * clears the status bar + * This method clears the status bar. */ private void clearStatus() { setStatus(null, false); } /** - * sets the status bar message + * This sets the status bar message. * @param msg the status bar message to show * @param showWarningIcon whether that status is a warning */ @@ -315,14 +315,14 @@ class TranslatablePanel extends JPanel { } /** - * sets the translation bar visibility based on whether or not there is a provided + * This method sets the translation bar visibility based on whether or not there is a provided. */ - private void setTranslationBarVisible() { - translationBar.setVisible(this.translationService.hasProvider()); + private void setTranslationEnabled() { + translateComboBox.setEnabled(this.translationService.hasProvider()); } /** - * the child component provided in the constructor will have its content set to the string provided + * The child component provided in the constructor will have its content set to the string provided. * @param content the content to display in the child component */ private void setChildComponentContent(String content) { @@ -330,7 +330,7 @@ class TranslatablePanel extends JPanel { } /** - * the child component provided in the constructor will have its content set to the string provided + * The child component provided in the constructor will have its content set to the string provided. * @param content the content to display in the child component * @param orientation the orientation for the text */ @@ -346,7 +346,7 @@ class TranslatablePanel extends JPanel { } /** - * items that are programmatically initialized + * This method is for items that are programmatically initialized. */ private void additionalInit(Component rootComponent, String origOptionText, String translatedOptionText) { add(rootComponent, java.awt.BorderLayout.CENTER); @@ -356,7 +356,7 @@ class TranslatablePanel extends JPanel { } /** - * when the combo box choice is selected, this method is fired + * When the combo box choice is selected, this method is fired. * @param translateOption the current translate option */ private void handleComboBoxChange(TranslateOption translateOption) { diff --git a/Core/src/org/sleuthkit/autopsy/texttranslation/ui/TranslateTextTask.java b/Core/src/org/sleuthkit/autopsy/texttranslation/ui/TranslateTextTask.java index 2932cf5d19..9fe93b21ab 100644 --- a/Core/src/org/sleuthkit/autopsy/texttranslation/ui/TranslateTextTask.java +++ b/Core/src/org/sleuthkit/autopsy/texttranslation/ui/TranslateTextTask.java @@ -34,7 +34,7 @@ import org.sleuthkit.autopsy.texttranslation.TextTranslationService; import org.sleuthkit.autopsy.texttranslation.TranslationException; /** - * abstract class for translating text and displaying to the user + * This is an abstract class for translating text and displaying to the user. */ public abstract class TranslateTextTask extends SwingWorker { @@ -44,7 +44,7 @@ public abstract class TranslateTextTask extends SwingWorker Date: Wed, 11 Mar 2020 10:29:00 -0400 Subject: [PATCH 77/97] update for disabled --- .../org/sleuthkit/autopsy/contentviewers/TranslatablePanel.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/TranslatablePanel.java b/Core/src/org/sleuthkit/autopsy/contentviewers/TranslatablePanel.java index 1e3c5514bd..4f2508be28 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/TranslatablePanel.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/TranslatablePanel.java @@ -264,7 +264,6 @@ class TranslatablePanel extends JPanel { * based on whether there is a provider. */ final void reset() { - setTranslationEnabled(); setContent(null, null); } @@ -275,6 +274,7 @@ class TranslatablePanel extends JPanel { */ void setContent(String content, String contentDescriptor) { cancelPendingTranslation(); + setTranslationEnabled(); this.translateComboBox.setSelectedIndex(0); this.prevTranslateSelection = false; this.content = content; From 487d680d4174e7b0f7a7fd14ec676a71494225da Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Wed, 11 Mar 2020 10:53:28 -0400 Subject: [PATCH 78/97] 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 a1315898eac252ccd3b942b88ef077c8b279c96d Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Wed, 11 Mar 2020 11:31:04 -0400 Subject: [PATCH 79/97] 5999 improve comment --- Core/src/org/sleuthkit/autopsy/filequery/FileSearch.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/filequery/FileSearch.java b/Core/src/org/sleuthkit/autopsy/filequery/FileSearch.java index 56a6754e3f..daa4124e8d 100644 --- a/Core/src/org/sleuthkit/autopsy/filequery/FileSearch.java +++ b/Core/src/org/sleuthkit/autopsy/filequery/FileSearch.java @@ -644,7 +644,7 @@ class FileSearch { return; } BufferedImage thumbnail = ScalrWrapper.resize(bufferedImage, Scalr.Method.SPEED, Scalr.Mode.FIT_TO_HEIGHT, ImageUtils.ICON_SIZE_LARGE, ImageUtils.ICON_SIZE_MEDIUM, Scalr.OP_ANTIALIAS); - //we are height limited here so it can be wider than it can be tall, scalr maintains aspect ratio + //We are height limited here so it can be wider than it can be tall.Scalr maintains the aspect ratio. videoThumbnails.add(thumbnail); if (cacheDirectory != null) { try { From 41981a722ed4f34a44b57d3aa71ed91baae6daf2 Mon Sep 17 00:00:00 2001 From: Mark McKinnon Date: Wed, 11 Mar 2020 15:41:51 -0400 Subject: [PATCH 80/97] 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 81/97] 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 43e44ff3ded355cc3ba5c86107b3a0a76f8cff9d Mon Sep 17 00:00:00 2001 From: Mark McKinnon Date: Wed, 11 Mar 2020 17:17:50 -0400 Subject: [PATCH 82/97] 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 83/97] 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 2f1da70aef7034f31f84999beac90d36269c9ca8 Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Wed, 11 Mar 2020 18:46:55 -0400 Subject: [PATCH 84/97] Fix varargs syntax error in ScalrWrapper.java --- CoreLibs/src/org/sleuthkit/autopsy/corelibs/ScalrWrapper.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CoreLibs/src/org/sleuthkit/autopsy/corelibs/ScalrWrapper.java b/CoreLibs/src/org/sleuthkit/autopsy/corelibs/ScalrWrapper.java index f101a0b875..ad9522fb37 100644 --- a/CoreLibs/src/org/sleuthkit/autopsy/corelibs/ScalrWrapper.java +++ b/CoreLibs/src/org/sleuthkit/autopsy/corelibs/ScalrWrapper.java @@ -37,7 +37,7 @@ public class ScalrWrapper { return Scalr.resize(input, size, Scalr.OP_ANTIALIAS); } - public static synchronized BufferedImage resize(BufferedImage bufferedImage, Method method, Scalr.Mode mode, int width, int height, BufferedImageOp... ops) { + public static synchronized BufferedImage resize(BufferedImage bufferedImage, Method method, Scalr.Mode mode, int width, int height, BufferedImageOp ...ops) { return Scalr.resize(bufferedImage, method, mode, width, height, ops); } From 20ba2b77c5a05db5f23ad5dd3d41352387345f1b Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Wed, 11 Mar 2020 19:02:03 -0400 Subject: [PATCH 85/97] 6028 Restrict ability to add hash sets to CR --- .../HashDbCreateDatabaseDialog.java | 85 ++++++++++--------- 1 file changed, 44 insertions(+), 41 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbCreateDatabaseDialog.java b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbCreateDatabaseDialog.java index 6f68a3defc..5470b385fb 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbCreateDatabaseDialog.java +++ b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbCreateDatabaseDialog.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"); @@ -44,6 +44,7 @@ import org.sleuthkit.autopsy.modules.hashdatabase.HashDbManager.HashDbManagerExc import org.sleuthkit.datamodel.TskData; import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository; +import org.sleuthkit.autopsy.featureaccess.FeatureAccessUtils; /** * Instances of this class allow a user to create a new hash database and add it @@ -124,29 +125,29 @@ final class HashDbCreateDatabaseDialog extends javax.swing.JDialog { setLocationRelativeTo(getOwner()); setVisible(true); } - - private void enableComponents(){ - - if(! CentralRepository.isEnabled()){ + + private void enableComponents() { + + if (!CentralRepository.isEnabled() || !FeatureAccessUtils.canAddHashSetsToCentralRepo()) { centralRepoRadioButton.setEnabled(false); fileTypeRadioButton.setSelected(true); } else { populateCombobox(); } - + boolean isFileType = fileTypeRadioButton.isSelected(); // Type type only databasePathLabel.setEnabled(isFileType); databasePathTextField.setEnabled(isFileType); saveAsButton.setEnabled(isFileType); - + // Central repo only - lbOrg.setEnabled(! isFileType); - orgButton.setEnabled(! isFileType); - orgComboBox.setEnabled(! isFileType); + lbOrg.setEnabled(!isFileType); + orgButton.setEnabled(!isFileType); + orgComboBox.setEnabled(!isFileType); } - + @NbBundle.Messages({"HashDbCreateDatabaseDialog.populateOrgsError.message=Failure loading organizations."}) private void populateCombobox() { orgComboBox.removeAllItems(); @@ -155,7 +156,7 @@ final class HashDbCreateDatabaseDialog extends javax.swing.JDialog { orgs = dbManager.getOrganizations(); orgs.forEach((org) -> { orgComboBox.addItem(org.getName()); - if(CentralRepoDbUtil.isDefaultOrg(org)){ + if (CentralRepoDbUtil.isDefaultOrg(org)) { orgComboBox.setSelectedItem(org.getName()); selectedOrg = org; } @@ -167,7 +168,7 @@ final class HashDbCreateDatabaseDialog extends javax.swing.JDialog { JOptionPane.showMessageDialog(this, Bundle.HashDbCreateDatabaseDialog_populateOrgsError_message()); Logger.getLogger(ImportCentralRepoDbProgressDialog.class.getName()).log(Level.SEVERE, "Failure loading organizations", ex); } - } + } /** * This method is called from within the constructor to initialize the form. @@ -413,7 +414,7 @@ final class HashDbCreateDatabaseDialog extends javax.swing.JDialog { path.append(lastBaseDirectory); File hashDbFolder = new File(path.toString()); // create the folder if it doesn't exist - if (!hashDbFolder.exists()){ + if (!hashDbFolder.exists()) { hashDbFolder.mkdir(); } if (!hashSetNameTextField.getText().isEmpty()) { @@ -452,7 +453,7 @@ final class HashDbCreateDatabaseDialog extends javax.swing.JDialog { return; } - if(fileTypeRadioButton.isSelected()){ + if (fileTypeRadioButton.isSelected()) { if (databasePathTextField.getText().isEmpty()) { JOptionPane.showMessageDialog(this, NbBundle.getMessage(this.getClass(), @@ -463,13 +464,13 @@ final class HashDbCreateDatabaseDialog extends javax.swing.JDialog { return; } } else { - if(selectedOrg == null){ + if (selectedOrg == null) { JOptionPane.showMessageDialog(this, - NbBundle.getMessage(this.getClass(), - "HashDbCreateDatabaseDialog.missingOrg"), - NbBundle.getMessage(this.getClass(), - "HashDbCreateDatabaseDialog.createHashDbErr"), - JOptionPane.ERROR_MESSAGE); + NbBundle.getMessage(this.getClass(), + "HashDbCreateDatabaseDialog.missingOrg"), + NbBundle.getMessage(this.getClass(), + "HashDbCreateDatabaseDialog.createHashDbErr"), + JOptionPane.ERROR_MESSAGE); return; } } @@ -487,7 +488,7 @@ final class HashDbCreateDatabaseDialog extends javax.swing.JDialog { String errorMessage = NbBundle .getMessage(this.getClass(), "HashDbCreateDatabaseDialog.errMsg.hashDbCreationErr"); - if(fileTypeRadioButton.isSelected()){ + if (fileTypeRadioButton.isSelected()) { try { newHashDb = HashDbManager.getInstance().addNewHashDatabaseNoSave(hashSetNameTextField.getText(), fileChooser.getSelectedFile().getCanonicalPath(), true, sendIngestMessagesCheckbox.isSelected(), type); } catch (IOException ex) { @@ -510,17 +511,17 @@ final class HashDbCreateDatabaseDialog extends javax.swing.JDialog { } } else { // Check if a hash set with the same name/version already exists - try{ - if(CentralRepository.getInstance().referenceSetExists(hashSetNameTextField.getText(), "")){ + try { + if (CentralRepository.getInstance().referenceSetExists(hashSetNameTextField.getText(), "")) { JOptionPane.showMessageDialog(this, - NbBundle.getMessage(this.getClass(), - "HashDbCreateDatabaseDialog.duplicateName"), - NbBundle.getMessage(this.getClass(), - "HashDbCreateDatabaseDialog.createHashDbErr"), - JOptionPane.ERROR_MESSAGE); + NbBundle.getMessage(this.getClass(), + "HashDbCreateDatabaseDialog.duplicateName"), + NbBundle.getMessage(this.getClass(), + "HashDbCreateDatabaseDialog.createHashDbErr"), + JOptionPane.ERROR_MESSAGE); return; } - } catch (CentralRepoException ex){ + } catch (CentralRepoException ex) { Logger.getLogger(HashDbImportDatabaseDialog.class.getName()).log(Level.SEVERE, "Error looking up reference set", ex); JOptionPane.showMessageDialog(this, NbBundle.getMessage(this.getClass(), @@ -528,16 +529,16 @@ final class HashDbCreateDatabaseDialog extends javax.swing.JDialog { NbBundle.getMessage(this.getClass(), "HashDbCreateDatabaseDialog.createHashDbErr"), JOptionPane.ERROR_MESSAGE); - return; + return; } - - try{ - int referenceSetID = CentralRepository.getInstance().newReferenceSet(new CentralRepoFileSet(selectedOrg.getOrgID(), hashSetNameTextField.getText(), + + try { + int referenceSetID = CentralRepository.getInstance().newReferenceSet(new CentralRepoFileSet(selectedOrg.getOrgID(), hashSetNameTextField.getText(), "", fileKnown, false, CentralRepository.getInstance().getCorrelationTypeById(CorrelationAttributeInstance.FILES_TYPE_ID))); - newHashDb = HashDbManager.getInstance().addExistingCentralRepoHashSet(hashSetNameTextField.getText(), - "", referenceSetID, + newHashDb = HashDbManager.getInstance().addExistingCentralRepoHashSet(hashSetNameTextField.getText(), + "", referenceSetID, true, sendIngestMessagesCheckbox.isSelected(), type, false); - } catch (CentralRepoException | TskCoreException ex){ + } catch (CentralRepoException | TskCoreException ex) { Logger.getLogger(HashDbImportDatabaseDialog.class.getName()).log(Level.SEVERE, "Error creating new reference set", ex); JOptionPane.showMessageDialog(this, NbBundle.getMessage(this.getClass(), @@ -545,8 +546,8 @@ final class HashDbCreateDatabaseDialog extends javax.swing.JDialog { NbBundle.getMessage(this.getClass(), "HashDbCreateDatabaseDialog.createHashDbErr"), JOptionPane.ERROR_MESSAGE); - return; - } + return; + } } dispose(); @@ -561,11 +562,13 @@ final class HashDbCreateDatabaseDialog extends javax.swing.JDialog { // update the combobox options if (dialog.isChanged()) { populateCombobox(); - } + } }//GEN-LAST:event_orgButtonActionPerformed private void orgComboBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_orgComboBoxActionPerformed - if (null == orgComboBox.getSelectedItem()) return; + if (null == orgComboBox.getSelectedItem()) { + return; + } String orgName = this.orgComboBox.getSelectedItem().toString(); for (CentralRepoOrganization org : orgs) { if (org.getName().equals(orgName)) { From c9982d4440f272a957032eab0c22fabe12edd594 Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Wed, 11 Mar 2020 19:03:58 -0400 Subject: [PATCH 86/97] 6028 Restrict ability to add hash sets to CR --- .../HashDbImportDatabaseDialog.java | 112 +++++++++--------- 1 file changed, 57 insertions(+), 55 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbImportDatabaseDialog.java b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbImportDatabaseDialog.java index f3bd39148f..a08f324a44 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbImportDatabaseDialog.java +++ b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbImportDatabaseDialog.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2014-2020 Basis Technology Corp. + * Copyright 2013-2020 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -90,7 +90,7 @@ final class HashDbImportDatabaseDialog extends javax.swing.JDialog { String[] EXTENSION = new String[]{"txt", "kdb", "idx", "hash", "Hash", "hsh"}; //NON-NLS FileNameExtensionFilter filter = new FileNameExtensionFilter( NbBundle.getMessage(this.getClass(), "HashDbImportDatabaseDialog.fileNameExtFilter.text"), EXTENSION); - fileChooser.setFileFilter(filter); + fileChooser.setFileFilter(filter); fileChooser.setMultiSelectionEnabled(false); } @@ -106,28 +106,28 @@ final class HashDbImportDatabaseDialog extends javax.swing.JDialog { } return shortenedPath; } - - private void enableComponents(){ - - if(!CentralRepository.isEnabled() || !FeatureAccessUtils.canAddHashSetsToCentralRepo()){ + + private void enableComponents() { + + if (!CentralRepository.isEnabled() || !FeatureAccessUtils.canAddHashSetsToCentralRepo()) { centralRepoRadioButton.setEnabled(false); fileTypeRadioButton.setSelected(true); } else { populateCombobox(); } - + boolean isFileType = fileTypeRadioButton.isSelected(); // Central repo only - lbVersion.setEnabled((! isFileType) && (readOnlyCheckbox.isSelected())); - versionTextField.setEnabled((! isFileType) && (readOnlyCheckbox.isSelected())); - - lbOrg.setEnabled(! isFileType); - orgButton.setEnabled(! isFileType); - orgComboBox.setEnabled(! isFileType); - readOnlyCheckbox.setEnabled(! isFileType); + lbVersion.setEnabled((!isFileType) && (readOnlyCheckbox.isSelected())); + versionTextField.setEnabled((!isFileType) && (readOnlyCheckbox.isSelected())); + + lbOrg.setEnabled(!isFileType); + orgButton.setEnabled(!isFileType); + orgComboBox.setEnabled(!isFileType); + readOnlyCheckbox.setEnabled(!isFileType); } - + @NbBundle.Messages({"HashDbImportDatabaseDialog.populateOrgsError.message=Failure loading organizations."}) private void populateCombobox() { orgComboBox.removeAllItems(); @@ -136,7 +136,7 @@ final class HashDbImportDatabaseDialog extends javax.swing.JDialog { orgs = dbManager.getOrganizations(); orgs.forEach((org) -> { orgComboBox.addItem(org.getName()); - if(CentralRepoDbUtil.isDefaultOrg(org)){ + if (CentralRepoDbUtil.isDefaultOrg(org)) { orgComboBox.setSelectedItem(org.getName()); selectedOrg = org; } @@ -468,28 +468,28 @@ final class HashDbImportDatabaseDialog extends javax.swing.JDialog { JOptionPane.ERROR_MESSAGE); return; } - - if(centralRepoRadioButton.isSelected()){ - if(readOnlyCheckbox.isSelected() && versionTextField.getText().isEmpty()){ + + if (centralRepoRadioButton.isSelected()) { + if (readOnlyCheckbox.isSelected() && versionTextField.getText().isEmpty()) { JOptionPane.showMessageDialog(this, - NbBundle.getMessage(this.getClass(), - "HashDbImportDatabaseDialog.missingVersion"), - NbBundle.getMessage(this.getClass(), - "HashDbImportDatabaseDialog.importHashDbErr"), - JOptionPane.ERROR_MESSAGE); + NbBundle.getMessage(this.getClass(), + "HashDbImportDatabaseDialog.missingVersion"), + NbBundle.getMessage(this.getClass(), + "HashDbImportDatabaseDialog.importHashDbErr"), + JOptionPane.ERROR_MESSAGE); return; } - - if(selectedOrg == null){ + + if (selectedOrg == null) { JOptionPane.showMessageDialog(this, - NbBundle.getMessage(this.getClass(), - "HashDbImportDatabaseDialog.missingOrg"), - NbBundle.getMessage(this.getClass(), - "HashDbImportDatabaseDialog.importHashDbErr"), - JOptionPane.ERROR_MESSAGE); + NbBundle.getMessage(this.getClass(), + "HashDbImportDatabaseDialog.missingOrg"), + NbBundle.getMessage(this.getClass(), + "HashDbImportDatabaseDialog.importHashDbErr"), + JOptionPane.ERROR_MESSAGE); return; } - } + } if (selectedFilePath.isEmpty()) { JOptionPane.showMessageDialog(this, @@ -500,7 +500,7 @@ final class HashDbImportDatabaseDialog extends javax.swing.JDialog { JOptionPane.ERROR_MESSAGE); return; } - + File file = new File(selectedFilePath); if (!file.exists()) { JOptionPane.showMessageDialog(this, @@ -523,11 +523,11 @@ final class HashDbImportDatabaseDialog extends javax.swing.JDialog { String errorMessage = NbBundle.getMessage(this.getClass(), "HashDbImportDatabaseDialog.unableToCopyToUserDirMsg", locationInUserConfigDir); Logger.getLogger(HashDbImportDatabaseDialog.class.getName()).log(Level.SEVERE, errorMessage, ex); JOptionPane.showMessageDialog(this, errorMessage, NbBundle.getMessage(this.getClass(), "HashDbImportDatabaseDialog.importHashDbErr"), - JOptionPane.ERROR_MESSAGE); + JOptionPane.ERROR_MESSAGE); return; } } - + KnownFilesType type; if (knownRadioButton.isSelected()) { type = KnownFilesType.KNOWN; @@ -536,9 +536,9 @@ final class HashDbImportDatabaseDialog extends javax.swing.JDialog { } String errorMessage = NbBundle.getMessage(this.getClass(), - "HashDbImportDatabaseDialog.errorMessage.failedToOpenHashDbMsg", - selectedFilePath); - if(fileTypeRadioButton.isSelected()){ + "HashDbImportDatabaseDialog.errorMessage.failedToOpenHashDbMsg", + selectedFilePath); + if (fileTypeRadioButton.isSelected()) { try { selectedHashDb = HashDbManager.getInstance().addExistingHashDatabaseNoSave(hashSetNameTextField.getText(), selectedFilePath, true, sendIngestMessagesCheckbox.isSelected(), type); @@ -552,19 +552,19 @@ final class HashDbImportDatabaseDialog extends javax.swing.JDialog { return; } } else { - + // Check if a hash set with the same name/version already exists - try{ - if(CentralRepository.getInstance().referenceSetExists(hashSetNameTextField.getText(), versionTextField.getText())){ + try { + if (CentralRepository.getInstance().referenceSetExists(hashSetNameTextField.getText(), versionTextField.getText())) { JOptionPane.showMessageDialog(this, - NbBundle.getMessage(this.getClass(), - "HashDbImportDatabaseDialog.duplicateName"), - NbBundle.getMessage(this.getClass(), - "HashDbImportDatabaseDialog.importHashDbErr"), - JOptionPane.ERROR_MESSAGE); + NbBundle.getMessage(this.getClass(), + "HashDbImportDatabaseDialog.duplicateName"), + NbBundle.getMessage(this.getClass(), + "HashDbImportDatabaseDialog.importHashDbErr"), + JOptionPane.ERROR_MESSAGE); return; } - } catch (CentralRepoException ex){ + } catch (CentralRepoException ex) { Logger.getLogger(HashDbImportDatabaseDialog.class.getName()).log(Level.SEVERE, "Error looking up reference set", ex); JOptionPane.showMessageDialog(this, NbBundle.getMessage(this.getClass(), @@ -572,20 +572,20 @@ final class HashDbImportDatabaseDialog extends javax.swing.JDialog { NbBundle.getMessage(this.getClass(), "HashDbImportDatabaseDialog.importHashDbErr"), JOptionPane.ERROR_MESSAGE); - return; + return; } - + String version; - if(readOnlyCheckbox.isSelected()){ + if (readOnlyCheckbox.isSelected()) { version = versionTextField.getText(); } else { // Editable databases don't have a version version = ""; } ImportCentralRepoDbProgressDialog progressDialog = new ImportCentralRepoDbProgressDialog(); - progressDialog.importFile(hashSetNameTextField.getText(), version, - selectedOrg.getOrgID(), true, sendIngestMessagesCheckbox.isSelected(), type, - readOnlyCheckbox.isSelected(), selectedFilePath); + progressDialog.importFile(hashSetNameTextField.getText(), version, + selectedOrg.getOrgID(), true, sendIngestMessagesCheckbox.isSelected(), type, + readOnlyCheckbox.isSelected(), selectedFilePath); selectedHashDb = progressDialog.getDatabase(); } @@ -609,11 +609,13 @@ final class HashDbImportDatabaseDialog extends javax.swing.JDialog { // update the combobox options if (dialog.isChanged()) { populateCombobox(); - } + } }//GEN-LAST:event_orgButtonActionPerformed private void orgComboBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_orgComboBoxActionPerformed - if (null == orgComboBox.getSelectedItem()) return; + if (null == orgComboBox.getSelectedItem()) { + return; + } String orgName = this.orgComboBox.getSelectedItem().toString(); for (CentralRepoOrganization org : orgs) { if (org.getName().equals(orgName)) { From af551fbed0f1276a354c94e47a9d5e21452f4374 Mon Sep 17 00:00:00 2001 From: Raman Arora Date: Thu, 12 Mar 2020 11:45:55 -0400 Subject: [PATCH 87/97] 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 88/97] 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 89/97] 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 90/97] 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 91/97] 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 92/97] 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 93/97] 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 94/97] 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 e3e86dd20f736e9c5efaaf4094328939d7b986fd Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Fri, 13 Mar 2020 10:14:23 -0400 Subject: [PATCH 95/97] 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 96/97] 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 1fc3bd524a4e6b8bc092160c521210d2ac4f4212 Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Fri, 13 Mar 2020 15:35:55 -0400 Subject: [PATCH 97/97] 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