Merge remote-tracking branch 'upstream/develop' into update-geolocation-attribute-helper-docs

This commit is contained in:
Richard Cordovano 2020-03-09 10:03:18 -04:00
commit 751abdfc4a
2 changed files with 144 additions and 65 deletions

View File

@ -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?

View File

@ -1,7 +1,7 @@
/*
* Central Repository
* Autopsy Forensic Browser
*
* Copyright 2015-2017 Basis Technology Corp.
* Copyright 2017-2020 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -32,19 +32,40 @@ 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
* 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();
@ -52,28 +73,64 @@ 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?",
"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();
addApplicationEventListeners();
if (Version.getBuildType() == Version.Type.RELEASE) {
setupDefaultCentralRepository();
}
updateCentralRepoSchema();
}
/**
* Adds the application event listeners responsible for adding data to the
* central repository.
*/
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<String, String> 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,92 +148,114 @@ public class Installer extends ModuleInstall {
try {
SwingUtilities.invokeAndWait(() -> {
try {
String dialogText =
"<html><body>" +
"<div style='width: 400px;'>" +
"<p>" + NbBundle.getMessage(this.getClass(), "Installer.initialCreateSqlite.messageHeader") + "</p>" +
"<p style='margin-top: 10px'>" + NbBundle.getMessage(this.getClass(), "Installer.initialCreateSqlite.messageDesc") + "</p>" +
"</div>" +
"</body></html>";
String dialogText
= "<html><body>"
+ "<div style='width: 400px;'>"
+ "<p>" + NbBundle.getMessage(this.getClass(), "Installer.initialCreateSqlite.messageHeader") + "</p>"
+ "<p style='margin-top: 10px'>" + NbBundle.getMessage(this.getClass(), "Installer.initialCreateSqlite.messageDesc") + "</p>"
+ "</div>"
+ "</body></html>";
if (JOptionPane.YES_OPTION == JOptionPane.showConfirmDialog(WindowManager.getDefault().getMainWindow(),
dialogText,
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);
}
}
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);
}
}
}
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();
}
}