Make sure package installer for CR does no popup

This commit is contained in:
Richard Cordovano 2020-03-06 20:10:39 -05:00
parent ba48d51836
commit ce49d54ca0
2 changed files with 127 additions and 56 deletions

View File

@ -8,5 +8,5 @@ IngestEventsListener.prevExists.text=Previously Seen Devices (Central Repository
IngestEventsListener.prevTaggedSet.text=Previously Tagged As Notable (Central Repository) IngestEventsListener.prevTaggedSet.text=Previously Tagged As Notable (Central Repository)
Installer.centralRepoUpgradeFailed.title=Central repository disabled 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.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? 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 * Contact: carrier <at> sleuthkit <dot> org
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * 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; 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 { 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 static final long serialVersionUID = 1L;
private final CaseEventListener pcl = new CaseEventListener();
private final IngestEventsListener ieListener = new IngestEventsListener();
private static Installer instance; 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() { public synchronized static Installer getDefault() {
if (instance == null) { if (instance == null) {
instance = new Installer(); instance = new Installer();
@ -53,10 +73,25 @@ public class Installer extends ModuleInstall {
return instance; 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() { private Installer() {
super(); 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({ @NbBundle.Messages({
"Installer.initialCreateSqlite.title=Enable Central Repository?", "Installer.initialCreateSqlite.title=Enable Central Repository?",
"Installer.initialCreateSqlite.messageHeader=The Central Repository is not enabled. Would you like to enable it?", "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 @Override
public void restored() { public void restored() {
Case.addPropertyChangeListener(pcl); addApplicationEventListeners();
ieListener.installListeners();
if (Version.getBuildType() == Version.Type.RELEASE) { if (Version.getBuildType() == Version.Type.RELEASE) {
centralRepoCheckAndSetup(); setupDefaultCentralRepository();
}
// 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);
}
} }
updateCentralRepoSchema();
} }
/** /**
* Check if CR has been previously configured or initialized and if not * Adds the application event listeners responsible for adding data to the
* prompt user to set up. * 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<String, String> centralRepoSettings = ModuleSettings.getConfigSettings("CentralRepository"); Map<String, String> centralRepoSettings = ModuleSettings.getConfigSettings("CentralRepository");
String initializedStr = centralRepoSettings.get("initialized"); String initializedStr = centralRepoSettings.get("initialized");
@ -122,25 +161,25 @@ public class Installer extends ModuleInstall {
NbBundle.getMessage(this.getClass(), "Installer.initialCreateSqlite.title"), NbBundle.getMessage(this.getClass(), "Installer.initialCreateSqlite.title"),
JOptionPane.YES_NO_OPTION)) { JOptionPane.YES_NO_OPTION)) {
setupDefaultSqlite(); setupDefaultSqliteCentralRepo();
} }
} catch (CentralRepoException ex) { } 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) { } 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 } // if no GUI, just initialize
else { else {
try { try {
setupDefaultSqlite(); setupDefaultSqliteCentralRepo();
} catch (CentralRepoException ex) { } 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(); CentralRepoDbManager manager = new CentralRepoDbManager();
manager.setupDefaultSqliteDb(); manager.setupDefaultSqliteDb();
} }
@NbBundle.Messages({"Installer.centralRepoUpgradeFailed.title=Central repository disabled"}) /**
private void reportUpgradeError(CentralRepoException ex) { * Update the central repository schema.
*/
private void updateCentralRepoSchema() {
try { try {
SwingUtilities.invokeAndWait(() -> { CentralRepoDbManager.upgradeDatabase();
JOptionPane.showMessageDialog(null, } catch (CentralRepoException ex) {
ex.getUserMessage(), logger.log(Level.SEVERE, "An error occurred updating the central repository schema", ex);
NbBundle.getMessage(this.getClass(), if (RuntimeProperties.runningWithGUI()) {
"Installer.centralRepoUpgradeFailed.title"), doMessageBoxIfRunningInGUI(ex);
JOptionPane.ERROR_MESSAGE); }
});
} catch (InterruptedException | InvocationTargetException e) {
LOGGER.log(Level.WARNING, e.getMessage(), e);
} }
} }
@Override /**
public boolean closing() { * Display a central repository exception in a message box if running with a
//platform about to close * GUI.
*
return true; * @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 @Override
public void uninstalled() { public void uninstalled() {
//module is being unloaded /*
* TODO (Jira-6108): This code is erronoeous. As documented at
Case.removePropertyChangeListener(pcl); * http://bits.netbeans.org/dev/javadoc/org-openide-modules/org/openide/modules/ModuleInstall.html#uninstalled--
pcl.shutdown(); *
ieListener.shutdown(); * "Called when the module is disabled while the application is still
ieListener.uninstallListeners(); * running. Should remove whatever functionality that it had registered
* in ModuleInstall.restored().
// TODO: remove thread pool *
* 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();
} }
} }