postgresql settings UI is implemented. now to do cleanup/testing.

This commit is contained in:
Nick Davis 2017-06-20 15:09:55 -04:00
parent f044aea5aa
commit fcd6b2ce08
17 changed files with 404 additions and 329 deletions

View File

@ -524,7 +524,7 @@ public class EamCaseEditDetailsDialog extends JDialog {
private void updateDb() { private void updateDb() {
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
if (!dbManager.isEnabled()) { if (!EamDb.isEnabled()) {
LOGGER.log(Level.SEVERE, "Enteprise artifacts manager database not enabled"); // NON-NLS LOGGER.log(Level.SEVERE, "Enteprise artifacts manager database not enabled"); // NON-NLS
return; return;
} }

View File

@ -504,8 +504,7 @@ public class DataContentViewerOtherCases extends javax.swing.JPanel implements D
@Override @Override
public boolean isSupported(Node node) { public boolean isSupported(Node node) {
EamDb dbManager = EamDb.getInstance(); if (!EamDb.isEnabled()) {
if (!dbManager.isEnabled()) {
return false; return false;
} }
@ -516,8 +515,7 @@ public class DataContentViewerOtherCases extends javax.swing.JPanel implements D
@Override @Override
@Messages({"DataContentViewerOtherCases.table.nodbconnection=Cannot connect to enterprise artifacts manager database."}) @Messages({"DataContentViewerOtherCases.table.nodbconnection=Cannot connect to enterprise artifacts manager database."})
public void setNode(Node node) { public void setNode(Node node) {
EamDb dbManager = EamDb.getInstance(); if (!EamDb.isEnabled()) {
if (!dbManager.isEnabled()) {
return; return;
} }

View File

@ -450,7 +450,7 @@ public abstract class AbstractSqlEamDb implements EamDb {
PreparedStatement preparedStatement = null; PreparedStatement preparedStatement = null;
ResultSet resultSet = null; ResultSet resultSet = null;
String sql = "SELECT * FROM data_sources WHERE device_id=?"; String sql = "SELECT * FROM data_sources WHERE device_id=?"; // NON-NLS
try { try {
preparedStatement = conn.prepareStatement(sql); preparedStatement = conn.prepareStatement(sql);

View File

@ -27,9 +27,9 @@ public interface EamDb {
public static final int SCHEMA_VERSION = 1; public static final int SCHEMA_VERSION = 1;
/** /**
* Get the instance; default to SQLITE. * Get the instance
* *
* @return The EamDb instance * @return The EamDb instance or null if one is not configured.
* *
* @throws EamDbException * @throws EamDbException
*/ */
@ -41,8 +41,9 @@ public interface EamDb {
return PostgresEamDb.getInstance(); return PostgresEamDb.getInstance();
case SQLITE: case SQLITE:
default:
return SqliteEamDb.getInstance(); return SqliteEamDb.getInstance();
default:
return null;
} }
} }
@ -66,7 +67,9 @@ public interface EamDb {
* *
* @return Is the database enabled * @return Is the database enabled
*/ */
boolean isEnabled(); static boolean isEnabled() {
return EamDbPlatformEnum.getSelectedPlatform() != EamDbPlatformEnum.DISABLED;
}
/** /**
* Get the list of tags recognized as "Bad" * Get the list of tags recognized as "Bad"

View File

@ -7,18 +7,22 @@
package org.sleuthkit.autopsy.experimental.enterpriseartifactsmanager.datamodel; package org.sleuthkit.autopsy.experimental.enterpriseartifactsmanager.datamodel;
import java.sql.Connection; import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.sql.Statement; import java.sql.Statement;
import java.util.List; import java.util.List;
import java.util.logging.Level; import java.util.logging.Level;
import org.sleuthkit.autopsy.coreutils.Logger;
import static org.sleuthkit.autopsy.experimental.enterpriseartifactsmanager.datamodel.EamDb.SCHEMA_VERSION; import static org.sleuthkit.autopsy.experimental.enterpriseartifactsmanager.datamodel.EamDb.SCHEMA_VERSION;
/** /**
* *
*/ */
public class EamDbUtil { public class EamDbUtil {
private final static Logger LOGGER = Logger.getLogger(EamDbUtil.class.getName());
/** /**
* Close the prepared statement. * Close the prepared statement.
* *
@ -26,12 +30,12 @@ public class EamDbUtil {
* *
* @throws EamDbException * @throws EamDbException
*/ */
public static void closePreparedStatement(PreparedStatement preparedStatement) throws EamDbException { public static void closePreparedStatement(PreparedStatement preparedStatement) {
if (null != preparedStatement) { if (null != preparedStatement) {
try { try {
preparedStatement.close(); preparedStatement.close();
} catch (SQLException ex) { } catch (SQLException ex) {
throw new EamDbException("Error closing PreparedStatement.", ex); LOGGER.log(Level.SEVERE, "Error closing PreparedStatement.", ex);
} }
} }
} }
@ -43,12 +47,12 @@ public class EamDbUtil {
* *
* @throws EamDbException * @throws EamDbException
*/ */
public static void closeResultSet(ResultSet resultSet) throws EamDbException { public static void closeResultSet(ResultSet resultSet) {
if (null != resultSet) { if (null != resultSet) {
try { try {
resultSet.close(); resultSet.close();
} catch (SQLException ex) { } catch (SQLException ex) {
throw new EamDbException("Error closing ResultSet.", ex); LOGGER.log(Level.SEVERE, "Error closing ResultSet.", ex);
} }
} }
} }
@ -60,24 +64,23 @@ public class EamDbUtil {
* *
* @throws EamDbException * @throws EamDbException
*/ */
public static void closeConnection(Connection conn) throws EamDbException { public static void closeConnection(Connection conn) {
if (null != conn) { if (null != conn) {
try { try {
conn.close(); conn.close();
} catch (SQLException ex) { } catch (SQLException ex) {
throw new EamDbException("Error closing Connection.", ex); LOGGER.log(Level.SEVERE, "Error closing Connection.", ex);
} }
} }
} }
/** /**
* Insert the default artifact types into the database. * Insert the default artifact types into the database.
* *
* @param conn An open database connection. * @param conn Open connection to use.
* * @return true on success, else false
* @throws EamDbException
*/ */
public static void insertDefaultArtifactTypes(Connection conn) throws EamDbException { public static boolean insertDefaultArtifactTypes(Connection conn) {
PreparedStatement preparedStatement = null; PreparedStatement preparedStatement = null;
List<EamArtifact.Type> DEFAULT_ARTIFACT_TYPES = EamArtifact.getDefaultArtifactTypes(); List<EamArtifact.Type> DEFAULT_ARTIFACT_TYPES = EamArtifact.getDefaultArtifactTypes();
String sql = "INSERT INTO artifact_types(name, supported, enabled) VALUES (?, ?, ?)"; String sql = "INSERT INTO artifact_types(name, supported, enabled) VALUES (?, ?, ?)";
@ -92,10 +95,12 @@ public class EamDbUtil {
} }
preparedStatement.executeBatch(); preparedStatement.executeBatch();
} catch (SQLException ex) { } catch (SQLException ex) {
throw new EamDbException("Error inserting default correlation artifact types.", ex); // NON-NLS LOGGER.log(Level.SEVERE, "Error inserting default correlation artifact types.", ex); // NON-NLS
return false;
} finally { } finally {
EamDbUtil.closePreparedStatement(preparedStatement); EamDbUtil.closePreparedStatement(preparedStatement);
} }
return true;
} }
/** /**
@ -104,9 +109,10 @@ public class EamDbUtil {
* This should be called immediately following the database schema being * This should be called immediately following the database schema being
* loaded. * loaded.
* *
* @throws EamDbException * @param conn Open connection to use.
* @return true on success, else false
*/ */
public static void insertSchemaVersion(Connection conn) throws EamDbException { public static boolean insertSchemaVersion(Connection conn) {
PreparedStatement preparedStatement = null; PreparedStatement preparedStatement = null;
String sql = "INSERT INTO db_info (name, value) VALUES (?, ?)"; String sql = "INSERT INTO db_info (name, value) VALUES (?, ?)";
try { try {
@ -115,10 +121,12 @@ public class EamDbUtil {
preparedStatement.setString(2, String.valueOf(SCHEMA_VERSION)); preparedStatement.setString(2, String.valueOf(SCHEMA_VERSION));
preparedStatement.executeUpdate(); preparedStatement.executeUpdate();
} catch (SQLException ex) { } catch (SQLException ex) {
throw new EamDbException("Error adding schema version to db_info.", ex); LOGGER.log(Level.SEVERE, "Error adding schema version to db_info.", ex);
return false;
} finally { } finally {
EamDbUtil.closePreparedStatement(preparedStatement); EamDbUtil.closePreparedStatement(preparedStatement);
} }
return true;
} }
/** /**
@ -142,10 +150,7 @@ public class EamDbUtil {
} catch (SQLException ex) { } catch (SQLException ex) {
return false; return false;
} finally { } finally {
try { EamDbUtil.closeResultSet(resultSet);
EamDbUtil.closeResultSet(resultSet);
} catch (EamDbException ex) {
}
} }
return true; return true;
} }
@ -171,10 +176,7 @@ public class EamDbUtil {
} catch (SQLException ex) { } catch (SQLException ex) {
return false; return false;
} finally { } finally {
try { EamDbUtil.closeResultSet(resultSet);
EamDbUtil.closeResultSet(resultSet);
} catch (EamDbException ex) {
}
} }
return false; return false;

View File

@ -126,174 +126,6 @@ public class PostgresEamDb extends AbstractSqlEamDb {
connectionPool.setValidationQuery(dbSettings.getValidationQuery()); connectionPool.setValidationQuery(dbSettings.getValidationQuery());
} }
/**
* Initialize the database schema.
*
* Requires valid connectionPool.
*
* This method is called from within connect(), so we cannot call connect()
* to get a connection. This method is called after setupConnectionPool(),
* so it is safe to assume that a valid connectionPool exists. The
* implementation of connect() is synchronized, so we can safely use the
* connectionPool object directly.
*/
private void initializeDatabaseSchema() throws EamDbException {
// The "id" column is an alias for the built-in 64-bit int "rowid" column.
// It is autoincrementing by default and must be of type "integer primary key".
// We've omitted the autoincrement argument because we are not currently
// using the id value to search for specific rows, so we do not care
// if a rowid is re-used after an existing rows was previously deleted.
StringBuilder createOrganizationsTable = new StringBuilder();
createOrganizationsTable.append("CREATE TABLE IF NOT EXISTS organizations (");
createOrganizationsTable.append("id SERIAL PRIMARY KEY,");
createOrganizationsTable.append("org_name text NOT NULL,");
createOrganizationsTable.append("poc_name text NOT NULL,");
createOrganizationsTable.append("poc_email text NOT NULL,");
createOrganizationsTable.append("poc_phone text NOT NULL");
createOrganizationsTable.append(")");
// NOTE: The organizations will only have a small number of rows, so
// an index is probably not worthwhile.
StringBuilder createCasesTable = new StringBuilder();
createCasesTable.append("CREATE TABLE IF NOT EXISTS cases (");
createCasesTable.append("id SERIAL PRIMARY KEY,");
createCasesTable.append("case_uid text NOT NULL,");
createCasesTable.append("org_id integer,");
createCasesTable.append("case_name text NOT NULL,");
createCasesTable.append("creation_date text NOT NULL,");
createCasesTable.append("case_number text NOT NULL,");
createCasesTable.append("examiner_name text NOT NULL,");
createCasesTable.append("examiner_email text NOT NULL,");
createCasesTable.append("examiner_phone text NOT NULL,");
createCasesTable.append("notes text NOT NULL,");
createCasesTable.append("foreign key (org_id) references organizations(id) on update set null on delete set null");
createCasesTable.append(")");
// NOTE: when there are few cases in the cases table, these indices may not be worthwhile
String casesIdx1 = "CREATE INDEX IF NOT EXISTS cases_org_id ON cases (org_id)";
String casesIdx2 = "CREATE INDEX IF NOT EXISTS cases_case_uid ON cases (case_uid)";
StringBuilder createDataSourcesTable = new StringBuilder();
createDataSourcesTable.append("CREATE TABLE IF NOT EXISTS data_sources (");
createDataSourcesTable.append("id SERIAL PRIMARY KEY,");
createDataSourcesTable.append("device_id text NOT NULL,");
createDataSourcesTable.append("name text NOT NULL,");
createDataSourcesTable.append("CONSTRAINT device_id_unique UNIQUE (device_id)");
createDataSourcesTable.append(")");
String dataSourceIdx1 = "CREATE INDEX IF NOT EXISTS data_sources_name ON data_sources (name)";
StringBuilder createGlobalReferenceSetsTable = new StringBuilder();
createGlobalReferenceSetsTable.append("CREATE TABLE IF NOT EXISTS global_reference_sets (");
createGlobalReferenceSetsTable.append("id SERIAL PRIMARY KEY,");
createGlobalReferenceSetsTable.append("org_id integer,");
createGlobalReferenceSetsTable.append("set_name text NOT NULL,");
createGlobalReferenceSetsTable.append("version text NOT NULL,");
createGlobalReferenceSetsTable.append("import_date text NOT NULL,");
createGlobalReferenceSetsTable.append("foreign key (org_id) references organizations(id) on update set null on delete set null");
createGlobalReferenceSetsTable.append(")");
String globalReferenceSetsIdx1 = "CREATE INDEX IF NOT EXISTS global_reference_sets_org_id ON global_reference_sets (org_id)";
StringBuilder createGlobalFilesTable = new StringBuilder();
createGlobalFilesTable.append("CREATE TABLE IF NOT EXISTS global_files (");
createGlobalFilesTable.append("id SERIAL PRIMARY KEY,");
createGlobalFilesTable.append("global_reference_set_id integer,");
createGlobalFilesTable.append("value text NOT NULL,");
createGlobalFilesTable.append("known_status text NOT NULL,");
createGlobalFilesTable.append("comment text NOT NULL,");
createGlobalFilesTable.append("CONSTRAINT global_files_multi_unique UNIQUE (global_reference_set_id,value),");
createGlobalFilesTable.append("foreign key (global_reference_set_id) references global_reference_sets(id) on update set null on delete set null");
createGlobalFilesTable.append(")");
String globalFilesIdx1 = "CREATE INDEX IF NOT EXISTS global_files_value ON global_files (value)";
String globalFilesIdx2 = "CREATE INDEX IF NOT EXISTS global_files_value_known_status ON global_files (value, known_status)";
StringBuilder createArtifactTypesTable = new StringBuilder();
createArtifactTypesTable.append("CREATE TABLE IF NOT EXISTS artifact_types (");
createArtifactTypesTable.append("id SERIAL PRIMARY KEY,");
createArtifactTypesTable.append("name text NOT NULL,");
createArtifactTypesTable.append("supported integer NOT NULL,");
createArtifactTypesTable.append("enabled integer NOT NULL,");
createArtifactTypesTable.append("CONSTRAINT artifact_type_name_unique UNIQUE (name)");
createArtifactTypesTable.append(")");
// NOTE: there are API methods that query by one of: name, supported, or enabled.
// Only name is currently implemented, but, there will only be a small number
// of artifact_types, so there is no benefit to having any indices.
StringBuilder createArtifactInstancesTableTemplate = new StringBuilder();
createArtifactInstancesTableTemplate.append("CREATE TABLE IF NOT EXISTS %s_instances (");
createArtifactInstancesTableTemplate.append("id SERIAL PRIMARY KEY,");
createArtifactInstancesTableTemplate.append("case_id integer,");
createArtifactInstancesTableTemplate.append("data_source_id integer,");
createArtifactInstancesTableTemplate.append("value text NOT NULL,");
createArtifactInstancesTableTemplate.append("file_path text NOT NULL,");
createArtifactInstancesTableTemplate.append("known_status text NOT NULL,");
createArtifactInstancesTableTemplate.append("comment text NOT NULL,");
createArtifactInstancesTableTemplate.append("CONSTRAINT %s_instances_multi_unique_ UNIQUE (case_id, data_source_id, value, file_path),");
createArtifactInstancesTableTemplate.append("foreign key (case_id) references cases(id) on update set null on delete set null,");
createArtifactInstancesTableTemplate.append("foreign key (data_source_id) references data_sources(id) on update set null on delete set null");
createArtifactInstancesTableTemplate.append(")");
// TODO: do we need any more indices?
String instancesIdx1 = "CREATE INDEX IF NOT EXISTS %s_instances_case_id ON %s_instances (case_id)";
String instancesIdx2 = "CREATE INDEX IF NOT EXISTS %s_instances_data_source_id ON %s_instances (data_source_id)";
String instancesIdx3 = "CREATE INDEX IF NOT EXISTS %s_instances_value ON %s_instances (value)";
String instancesIdx4 = "CREATE INDEX IF NOT EXISTS %s_instances_value_known_status ON %s_instances (value, known_status)";
StringBuilder createDbInfoTable = new StringBuilder();
createDbInfoTable.append("CREATE TABLE IF NOT EXISTS db_info (");
createDbInfoTable.append("id SERIAL PRIMARY KEY NOT NULL,");
createDbInfoTable.append("name text NOT NULL,");
createDbInfoTable.append("value text NOT NULL");
createDbInfoTable.append(")");
// NOTE: the db_info table currenly only has 1 row, so having an index
// provides no benefit.
Connection conn = null;
try {
conn = connectionPool.getConnection();
Statement stmt = conn.createStatement();
stmt.execute(createOrganizationsTable.toString());
stmt.execute(createCasesTable.toString());
stmt.execute(casesIdx1);
stmt.execute(casesIdx2);
stmt.execute(createDataSourcesTable.toString());
stmt.execute(dataSourceIdx1);
stmt.execute(createGlobalReferenceSetsTable.toString());
stmt.execute(globalReferenceSetsIdx1);
stmt.execute(createGlobalFilesTable.toString());
stmt.execute(globalFilesIdx1);
stmt.execute(globalFilesIdx2);
stmt.execute(createArtifactTypesTable.toString());
stmt.execute(createDbInfoTable.toString());
// Create a separate table for each artifact type
String type_name;
for (EamArtifact.Type type : DEFAULT_ARTIFACT_TYPES) {
type_name = type.getName();
stmt.execute(String.format(createArtifactInstancesTableTemplate.toString(), type_name, type_name));
stmt.execute(String.format(instancesIdx1, type_name, type_name));
stmt.execute(String.format(instancesIdx2, type_name, type_name));
stmt.execute(String.format(instancesIdx3, type_name, type_name));
stmt.execute(String.format(instancesIdx4, type_name, type_name));
}
} catch (SQLException ex) {
throw new EamDbException("Error initializing db schema.", ex); // NON-NLS
} finally {
EamDbUtil.closeConnection(conn);
}
}
/** /**
* Lazily setup Singleton connection on first request. * Lazily setup Singleton connection on first request.
* *
@ -321,11 +153,6 @@ public class PostgresEamDb extends AbstractSqlEamDb {
} }
} }
@Override
public boolean isEnabled() {
return dbSettings.isEnabled();
}
@Override @Override
public List<String> getBadTags() { public List<String> getBadTags() {
return dbSettings.getBadTags(); return dbSettings.getBadTags();

View File

@ -20,6 +20,7 @@ package org.sleuthkit.autopsy.experimental.enterpriseartifactsmanager.datamodel;
import java.sql.Connection; import java.sql.Connection;
import java.sql.DriverManager; import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.sql.Statement; import java.sql.Statement;
@ -27,6 +28,7 @@ import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.logging.Level; import java.util.logging.Level;
import org.openide.util.Exceptions;
import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.coreutils.ModuleSettings; import org.sleuthkit.autopsy.coreutils.ModuleSettings;
@ -39,7 +41,7 @@ public final class PostgresEamDbSettings {
private final static Logger LOGGER = Logger.getLogger(PostgresEamDbSettings.class.getName()); private final static Logger LOGGER = Logger.getLogger(PostgresEamDbSettings.class.getName());
private final String DEFAULT_HOST = "localhost"; // NON-NLS private final String DEFAULT_HOST = "localhost"; // NON-NLS
private final int DEFAULT_PORT = 5432; private final int DEFAULT_PORT = 5432;
private final String DEFAULT_DBNAME = "enterpriseartifactmanagerdb"; // NON-NLS private final String DEFAULT_DBNAME = "EnterpriseArtifacts"; // NON-NLS
private final int DEFAULT_BULK_THRESHHOLD = 1000; private final int DEFAULT_BULK_THRESHHOLD = 1000;
private final String DEFAULT_USERNAME = ""; private final String DEFAULT_USERNAME = "";
private final String DEFAULT_PASSWORD = ""; private final String DEFAULT_PASSWORD = "";
@ -120,7 +122,6 @@ public final class PostgresEamDbSettings {
} }
public void saveSettings() { public void saveSettings() {
ModuleSettings.setConfigSetting("EnterpriseArtifactsManager", "db.enabled", Boolean.toString(isEnabled())); // NON-NLS
ModuleSettings.setConfigSetting("EnterpriseArtifactsManager", "db.postgresql.host", getHost()); // NON-NLS ModuleSettings.setConfigSetting("EnterpriseArtifactsManager", "db.postgresql.host", getHost()); // NON-NLS
ModuleSettings.setConfigSetting("EnterpriseArtifactsManager", "db.postgresql.port", Integer.toString(port)); // NON-NLS ModuleSettings.setConfigSetting("EnterpriseArtifactsManager", "db.postgresql.port", Integer.toString(port)); // NON-NLS
ModuleSettings.setConfigSetting("EnterpriseArtifactsManager", "db.postgresql.dbName", getDbName()); // NON-NLS ModuleSettings.setConfigSetting("EnterpriseArtifactsManager", "db.postgresql.dbName", getDbName()); // NON-NLS
@ -133,14 +134,21 @@ public final class PostgresEamDbSettings {
/** /**
* Get the full connection URL as a String * Get the full connection URL as a String
* *
* @param usePostgresDb Connect to the 'postgres' database when testing
* connectivity and creating the main database.
*
* @return * @return
*/ */
public String getConnectionURL() { public String getConnectionURL(boolean usePostgresDb) {
StringBuilder url = new StringBuilder(); StringBuilder url = new StringBuilder();
url.append(getJDBCBaseURI()); url.append(getJDBCBaseURI());
url.append(getHost()); url.append(getHost());
url.append("/"); // NON-NLS url.append("/"); // NON-NLS
url.append(getDbName()); if (usePostgresDb) {
url.append("postgres"); // NON-NLS
} else {
url.append(getDbName());
}
url.append("?user="); // NON-NLS url.append("?user="); // NON-NLS
url.append(getUserName()); url.append(getUserName());
url.append("&password="); // NON-NLS url.append("&password="); // NON-NLS
@ -150,50 +158,299 @@ public final class PostgresEamDbSettings {
} }
/** /**
* Using the current settings, test the connection to the database. * Use the current settings to get an ephemeral client connection for testing.
*
* @return Connection or null.
*/
private Connection getEphemeralConnection(boolean usePostgresDb) {
Connection conn;
try {
String url = getConnectionURL(usePostgresDb);
Class.forName(getDriver());
conn = DriverManager.getConnection(url);
} catch (ClassNotFoundException | SQLException ex) {
// TODO: Determine why a connection failure (ConnectionException) re-throws
// the SQLException and does not print this log message?
LOGGER.log(Level.SEVERE, "Failed to acquire ephemeral connection to postgresql."); // NON-NLS
conn = null;
}
return conn;
}
/**
* Use 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.
*/ */
public boolean testConnectionSettings() { public boolean verifyConnection() {
// Open a new ephemeral client here to test that we can connect Connection conn = getEphemeralConnection(true);
ResultSet resultSet = null; if (null == conn) {
Connection conn = null; return false;
try { }
String url = getConnectionURL();
Class.forName(getDriver()); boolean result = EamDbUtil.executeValidationQuery(conn, VALIDATION_QUERY);
conn = DriverManager.getConnection(url); EamDbUtil.closeConnection(conn);
Statement tester = conn.createStatement(); return result;
resultSet = tester.executeQuery(getValidationQuery()); }
if (resultSet.next()) {
LOGGER.log(Level.INFO, "Testing connection to postgresql success."); // NON-NLS /**
} * Check to see if the database exists.
} catch (ClassNotFoundException | SQLException ex) { *
LOGGER.log(Level.INFO, "Testing connection to postgresql failed.", ex); // NON-NLS * @return true if exists, else false
*/
public boolean verifyDatabaseExists() {
Connection conn = getEphemeralConnection(true);
if (null == conn) {
return false; return false;
} finally {
if (null != resultSet) {
try {
resultSet.close();
} catch (SQLException ex) {
LOGGER.log(Level.SEVERE, "Error closing ResultSet.", ex); // NON-NLS
}
}
if (null != conn) {
try {
conn.close();
} catch (SQLException ex) {
LOGGER.log(Level.SEVERE, "Error closing test connection.", ex); // NON-NLS
}
}
} }
return true; String sql = "SELECT datname FROM pg_catalog.pg_database WHERE lower(datname) = lower(?) LIMIT 1"; // NON-NLS
PreparedStatement ps = null;
ResultSet rs = null;
try {
ps = conn.prepareStatement(sql);
ps.setString(1, getDbName());
rs = ps.executeQuery();
if (rs.next()) {
return true;
}
} catch (SQLException ex) {
LOGGER.log(Level.SEVERE, "Failed to execute database existance query.", ex); // NON-NLS
return false;
} finally {
EamDbUtil.closePreparedStatement(ps);
EamDbUtil.closeResultSet(rs);
EamDbUtil.closeConnection(conn);
}
return false;
} }
/**
* Use the current settings and the schema version query
* to test the database schema.
*
* @return true if successfull connection, else false.
*/
public boolean verifyDatabaseSchema() {
Connection conn = getEphemeralConnection(false);
if (null == conn) {
return false;
}
boolean result = EamDbUtil.schemaVersionIsSet(conn);
EamDbUtil.closeConnection(conn);
return result;
}
public boolean createDatabase() {
Connection conn = getEphemeralConnection(true);
if (null == conn) {
return false;
}
String sql = "CREATE DATABASE %s OWNER %s"; // NON-NLS
try {
Statement stmt;
stmt = conn.createStatement();
stmt.execute(String.format(sql, getDbName(), getUserName()));
} catch (SQLException ex) {
LOGGER.log(Level.SEVERE, "Failed to execute create database statement.", ex); // NON-NLS
return false;
} finally {
EamDbUtil.closeConnection(conn);
}
return true;
}
/**
* Initialize the database schema.
*
* Requires valid connectionPool.
*
* This method is called from within connect(), so we cannot call connect()
* to get a connection. This method is called after setupConnectionPool(),
* so it is safe to assume that a valid connectionPool exists. The
* implementation of connect() is synchronized, so we can safely use the
* connectionPool object directly.
*/
public boolean initializeDatabaseSchema() {
// The "id" column is an alias for the built-in 64-bit int "rowid" column.
// It is autoincrementing by default and must be of type "integer primary key".
// We've omitted the autoincrement argument because we are not currently
// using the id value to search for specific rows, so we do not care
// if a rowid is re-used after an existing rows was previously deleted.
StringBuilder createOrganizationsTable = new StringBuilder();
createOrganizationsTable.append("CREATE TABLE IF NOT EXISTS organizations (");
createOrganizationsTable.append("id SERIAL PRIMARY KEY,");
createOrganizationsTable.append("org_name text NOT NULL,");
createOrganizationsTable.append("poc_name text NOT NULL,");
createOrganizationsTable.append("poc_email text NOT NULL,");
createOrganizationsTable.append("poc_phone text NOT NULL");
createOrganizationsTable.append(")");
// NOTE: The organizations will only have a small number of rows, so
// an index is probably not worthwhile.
StringBuilder createCasesTable = new StringBuilder();
createCasesTable.append("CREATE TABLE IF NOT EXISTS cases (");
createCasesTable.append("id SERIAL PRIMARY KEY,");
createCasesTable.append("case_uid text NOT NULL,");
createCasesTable.append("org_id integer,");
createCasesTable.append("case_name text NOT NULL,");
createCasesTable.append("creation_date text NOT NULL,");
createCasesTable.append("case_number text NOT NULL,");
createCasesTable.append("examiner_name text NOT NULL,");
createCasesTable.append("examiner_email text NOT NULL,");
createCasesTable.append("examiner_phone text NOT NULL,");
createCasesTable.append("notes text NOT NULL,");
createCasesTable.append("foreign key (org_id) references organizations(id) on update set null on delete set null");
createCasesTable.append(")");
// NOTE: when there are few cases in the cases table, these indices may not be worthwhile
String casesIdx1 = "CREATE INDEX IF NOT EXISTS cases_org_id ON cases (org_id)";
String casesIdx2 = "CREATE INDEX IF NOT EXISTS cases_case_uid ON cases (case_uid)";
StringBuilder createDataSourcesTable = new StringBuilder();
createDataSourcesTable.append("CREATE TABLE IF NOT EXISTS data_sources (");
createDataSourcesTable.append("id SERIAL PRIMARY KEY,");
createDataSourcesTable.append("device_id text NOT NULL,");
createDataSourcesTable.append("name text NOT NULL,");
createDataSourcesTable.append("CONSTRAINT device_id_unique UNIQUE (device_id)");
createDataSourcesTable.append(")");
String dataSourceIdx1 = "CREATE INDEX IF NOT EXISTS data_sources_name ON data_sources (name)";
StringBuilder createGlobalReferenceSetsTable = new StringBuilder();
createGlobalReferenceSetsTable.append("CREATE TABLE IF NOT EXISTS global_reference_sets (");
createGlobalReferenceSetsTable.append("id SERIAL PRIMARY KEY,");
createGlobalReferenceSetsTable.append("org_id integer,");
createGlobalReferenceSetsTable.append("set_name text NOT NULL,");
createGlobalReferenceSetsTable.append("version text NOT NULL,");
createGlobalReferenceSetsTable.append("import_date text NOT NULL,");
createGlobalReferenceSetsTable.append("foreign key (org_id) references organizations(id) on update set null on delete set null");
createGlobalReferenceSetsTable.append(")");
String globalReferenceSetsIdx1 = "CREATE INDEX IF NOT EXISTS global_reference_sets_org_id ON global_reference_sets (org_id)";
StringBuilder createGlobalFilesTable = new StringBuilder();
createGlobalFilesTable.append("CREATE TABLE IF NOT EXISTS global_files (");
createGlobalFilesTable.append("id SERIAL PRIMARY KEY,");
createGlobalFilesTable.append("global_reference_set_id integer,");
createGlobalFilesTable.append("value text NOT NULL,");
createGlobalFilesTable.append("known_status text NOT NULL,");
createGlobalFilesTable.append("comment text NOT NULL,");
createGlobalFilesTable.append("CONSTRAINT global_files_multi_unique UNIQUE (global_reference_set_id,value),");
createGlobalFilesTable.append("foreign key (global_reference_set_id) references global_reference_sets(id) on update set null on delete set null");
createGlobalFilesTable.append(")");
String globalFilesIdx1 = "CREATE INDEX IF NOT EXISTS global_files_value ON global_files (value)";
String globalFilesIdx2 = "CREATE INDEX IF NOT EXISTS global_files_value_known_status ON global_files (value, known_status)";
StringBuilder createArtifactTypesTable = new StringBuilder();
createArtifactTypesTable.append("CREATE TABLE IF NOT EXISTS artifact_types (");
createArtifactTypesTable.append("id SERIAL PRIMARY KEY,");
createArtifactTypesTable.append("name text NOT NULL,");
createArtifactTypesTable.append("supported integer NOT NULL,");
createArtifactTypesTable.append("enabled integer NOT NULL,");
createArtifactTypesTable.append("CONSTRAINT artifact_type_name_unique UNIQUE (name)");
createArtifactTypesTable.append(")");
// NOTE: there are API methods that query by one of: name, supported, or enabled.
// Only name is currently implemented, but, there will only be a small number
// of artifact_types, so there is no benefit to having any indices.
StringBuilder createArtifactInstancesTableTemplate = new StringBuilder();
createArtifactInstancesTableTemplate.append("CREATE TABLE IF NOT EXISTS %s_instances (");
createArtifactInstancesTableTemplate.append("id SERIAL PRIMARY KEY,");
createArtifactInstancesTableTemplate.append("case_id integer,");
createArtifactInstancesTableTemplate.append("data_source_id integer,");
createArtifactInstancesTableTemplate.append("value text NOT NULL,");
createArtifactInstancesTableTemplate.append("file_path text NOT NULL,");
createArtifactInstancesTableTemplate.append("known_status text NOT NULL,");
createArtifactInstancesTableTemplate.append("comment text NOT NULL,");
createArtifactInstancesTableTemplate.append("CONSTRAINT %s_instances_multi_unique_ UNIQUE (case_id, data_source_id, value, file_path),");
createArtifactInstancesTableTemplate.append("foreign key (case_id) references cases(id) on update set null on delete set null,");
createArtifactInstancesTableTemplate.append("foreign key (data_source_id) references data_sources(id) on update set null on delete set null");
createArtifactInstancesTableTemplate.append(")");
// TODO: do we need any more indices?
String instancesIdx1 = "CREATE INDEX IF NOT EXISTS %s_instances_case_id ON %s_instances (case_id)";
String instancesIdx2 = "CREATE INDEX IF NOT EXISTS %s_instances_data_source_id ON %s_instances (data_source_id)";
String instancesIdx3 = "CREATE INDEX IF NOT EXISTS %s_instances_value ON %s_instances (value)";
String instancesIdx4 = "CREATE INDEX IF NOT EXISTS %s_instances_value_known_status ON %s_instances (value, known_status)";
StringBuilder createDbInfoTable = new StringBuilder();
createDbInfoTable.append("CREATE TABLE IF NOT EXISTS db_info (");
createDbInfoTable.append("id SERIAL PRIMARY KEY NOT NULL,");
createDbInfoTable.append("name text NOT NULL,");
createDbInfoTable.append("value text NOT NULL");
createDbInfoTable.append(")");
// NOTE: the db_info table currenly only has 1 row, so having an index
// provides no benefit.
Connection conn = null;
try {
conn = getEphemeralConnection(false);
if (null == conn) {
return false;
}
Statement stmt = conn.createStatement();
stmt.execute(createOrganizationsTable.toString());
stmt.execute(createCasesTable.toString());
stmt.execute(casesIdx1);
stmt.execute(casesIdx2);
stmt.execute(createDataSourcesTable.toString());
stmt.execute(dataSourceIdx1);
stmt.execute(createGlobalReferenceSetsTable.toString());
stmt.execute(globalReferenceSetsIdx1);
stmt.execute(createGlobalFilesTable.toString());
stmt.execute(globalFilesIdx1);
stmt.execute(globalFilesIdx2);
stmt.execute(createArtifactTypesTable.toString());
stmt.execute(createDbInfoTable.toString());
// Create a separate table for each artifact type
List<EamArtifact.Type> DEFAULT_ARTIFACT_TYPES = EamArtifact.getDefaultArtifactTypes();
String type_name;
for (EamArtifact.Type type : DEFAULT_ARTIFACT_TYPES) {
type_name = type.getName();
stmt.execute(String.format(createArtifactInstancesTableTemplate.toString(), type_name, type_name));
stmt.execute(String.format(instancesIdx1, type_name, type_name));
stmt.execute(String.format(instancesIdx2, type_name, type_name));
stmt.execute(String.format(instancesIdx3, type_name, type_name));
stmt.execute(String.format(instancesIdx4, type_name, type_name));
}
} catch (SQLException ex) {
LOGGER.log(Level.SEVERE, "Error initializing db schema.", ex); // NON-NLS
return false;
} finally {
EamDbUtil.closeConnection(conn);
}
return true;
}
public boolean insertDefaultDatabaseContent() { public boolean insertDefaultDatabaseContent() {
return true; Connection conn = getEphemeralConnection(false);
if (null == conn) {
return false;
}
boolean result = EamDbUtil.insertDefaultArtifactTypes(conn)
&& EamDbUtil.insertSchemaVersion(conn);
EamDbUtil.closeConnection(conn);
return result;
} }
public boolean isChanged() { public boolean isChanged() {
String hostString = ModuleSettings.getConfigSetting("EnterpriseArtifactsManager", "db.postgresql.host"); // NON-NLS String hostString = ModuleSettings.getConfigSetting("EnterpriseArtifactsManager", "db.postgresql.host"); // NON-NLS
String portString = ModuleSettings.getConfigSetting("EnterpriseArtifactsManager", "db.postgresql.port"); // NON-NLS String portString = ModuleSettings.getConfigSetting("EnterpriseArtifactsManager", "db.postgresql.port"); // NON-NLS

View File

@ -133,7 +133,7 @@ public class SqliteEamDb extends AbstractSqlEamDb {
@Override @Override
protected Connection connect() throws EamDbException { protected Connection connect() throws EamDbException {
synchronized (this) { synchronized (this) {
if (!dbSettings.isEnabled()) { if (!EamDb.isEnabled()) {
throw new EamDbException("Enterprise artifacts manager is not enabled"); // NON-NLS throw new EamDbException("Enterprise artifacts manager is not enabled"); // NON-NLS
} }
@ -151,11 +151,6 @@ public class SqliteEamDb extends AbstractSqlEamDb {
} }
} }
@Override
public boolean isEnabled() {
return dbSettings.isEnabled();
}
@Override @Override
public List<String> getBadTags() { public List<String> getBadTags() {
return dbSettings.getBadTags(); return dbSettings.getBadTags();

View File

@ -104,7 +104,6 @@ public final class SqliteEamDbSettings {
public void saveSettings() { public void saveSettings() {
createDbDirectory(); createDbDirectory();
ModuleSettings.setConfigSetting("EnterpriseArtifactsManager", "db.enabled", Boolean.toString(isEnabled())); // NON-NLS
ModuleSettings.setConfigSetting("EnterpriseArtifactsManager", "db.sqlite.dbName", getDbName()); // NON-NLS ModuleSettings.setConfigSetting("EnterpriseArtifactsManager", "db.sqlite.dbName", getDbName()); // NON-NLS
ModuleSettings.setConfigSetting("EnterpriseArtifactsManager", "db.sqlite.dbDirectory", getDbDirectory()); // NON-NLS ModuleSettings.setConfigSetting("EnterpriseArtifactsManager", "db.sqlite.dbDirectory", getDbDirectory()); // NON-NLS
ModuleSettings.setConfigSetting("EnterpriseArtifactsManager", "db.sqlite.bulkThreshold", Integer.toString(getBulkThreshold())); // NON-NLS ModuleSettings.setConfigSetting("EnterpriseArtifactsManager", "db.sqlite.bulkThreshold", Integer.toString(getBulkThreshold())); // NON-NLS
@ -175,14 +174,14 @@ public final class SqliteEamDbSettings {
return null; return null;
} }
Connection conn = null; Connection conn;
try { try {
String url = getConnectionURL(); String url = getConnectionURL();
Class.forName(getDriver()); Class.forName(getDriver());
conn = DriverManager.getConnection(url); conn = DriverManager.getConnection(url);
} catch (ClassNotFoundException | SQLException ex) { } catch (ClassNotFoundException | SQLException ex) {
LOGGER.log(Level.SEVERE, "Failed to acquire ephemeral connection to sqlite.", ex); // NON-NLS LOGGER.log(Level.SEVERE, "Failed to acquire ephemeral connection to sqlite.", ex); // NON-NLS
return null; conn = null;
} }
return conn; return conn;
} }
@ -200,11 +199,7 @@ public final class SqliteEamDbSettings {
} }
boolean result = EamDbUtil.executeValidationQuery(conn, VALIDATION_QUERY); boolean result = EamDbUtil.executeValidationQuery(conn, VALIDATION_QUERY);
try { EamDbUtil.closeConnection(conn);
EamDbUtil.closeConnection(conn);
} catch (EamDbException ex) {
LOGGER.log(Level.SEVERE, "verifyConnection failed to close resources.", ex);
}
return result; return result;
} }
@ -221,11 +216,7 @@ public final class SqliteEamDbSettings {
} }
boolean result = EamDbUtil.schemaVersionIsSet(conn); boolean result = EamDbUtil.schemaVersionIsSet(conn);
try { EamDbUtil.closeConnection(conn);
EamDbUtil.closeConnection(conn);
} catch (EamDbException ex) {
LOGGER.log(Level.SEVERE, "verifyDatabaseSchema failed to close resources.", ex);
}
return result; return result;
} }
@ -359,6 +350,9 @@ public final class SqliteEamDbSettings {
Connection conn = null; Connection conn = null;
try { try {
conn = getEphemeralConnection(); conn = getEphemeralConnection();
if (null == conn) {
return false;
}
Statement stmt = conn.createStatement(); Statement stmt = conn.createStatement();
stmt.execute(PRAGMA_JOURNAL_WAL); stmt.execute(PRAGMA_JOURNAL_WAL);
stmt.execute(PRAGMA_SYNC_OFF); stmt.execute(PRAGMA_SYNC_OFF);
@ -403,11 +397,7 @@ public final class SqliteEamDbSettings {
LOGGER.log(Level.SEVERE, "Error initializing db schema.", ex); // NON-NLS LOGGER.log(Level.SEVERE, "Error initializing db schema.", ex); // NON-NLS
return false; return false;
} finally { } finally {
try { EamDbUtil.closeConnection(conn);
EamDbUtil.closeConnection(conn);
} catch (EamDbException ex) {
LOGGER.log(Level.SEVERE, "initializeDatabaseSchema failed to close resources.", ex);
}
} }
return true; return true;
} }
@ -418,19 +408,10 @@ public final class SqliteEamDbSettings {
return false; return false;
} }
try { boolean result = EamDbUtil.insertDefaultArtifactTypes(conn)
EamDbUtil.insertDefaultArtifactTypes(conn); && EamDbUtil.insertSchemaVersion(conn);
EamDbUtil.insertSchemaVersion(conn); EamDbUtil.closeConnection(conn);
} catch (EamDbException ex) { return result;
return false;
} finally {
try {
EamDbUtil.closeConnection(conn);
} catch (EamDbException ex) {
LOGGER.log(Level.SEVERE, "insertDefaultDatabaseContent failed to close resources.", ex);
}
}
return true;
} }
public boolean isChanged() { public boolean isChanged() {
@ -443,20 +424,6 @@ public final class SqliteEamDbSettings {
|| !Integer.toString(bulkThreshold).equals(bulkThresholdString); || !Integer.toString(bulkThreshold).equals(bulkThresholdString);
} }
/**
* @return the enabled
*/
public boolean isEnabled() {
return enabled;
}
/**
* @param enabled the enabled to set
*/
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
/** /**
* @return the dbName * @return the dbName
*/ */

View File

@ -42,7 +42,7 @@ public class BadFileTagRunner implements Runnable {
@Override @Override
public void run() { public void run() {
if (!dbManager.isEnabled()) { if (!EamDb.isEnabled()) {
LOGGER.log(Level.WARNING, "Enterprise artifacts manager database not configured"); // NON-NLS LOGGER.log(Level.WARNING, "Enterprise artifacts manager database not configured"); // NON-NLS
return; return;
} }

View File

@ -61,7 +61,7 @@ public class CaseEventListener implements PropertyChangeListener {
EamDb dbManager = EamDb.getInstance(); EamDb dbManager = EamDb.getInstance();
switch (Case.Events.valueOf(evt.getPropertyName())) { switch (Case.Events.valueOf(evt.getPropertyName())) {
case CONTENT_TAG_ADDED: { case CONTENT_TAG_ADDED: {
if (!dbManager.isEnabled()) { if (!EamDb.isEnabled()) {
return; return;
} }
@ -125,7 +125,7 @@ public class CaseEventListener implements PropertyChangeListener {
break; break;
case BLACKBOARD_ARTIFACT_TAG_ADDED: { case BLACKBOARD_ARTIFACT_TAG_ADDED: {
if (!dbManager.isEnabled()) { if (!EamDb.isEnabled()) {
return; return;
} }
@ -157,7 +157,7 @@ public class CaseEventListener implements PropertyChangeListener {
break; break;
case DATA_SOURCE_ADDED: { case DATA_SOURCE_ADDED: {
if (!dbManager.isEnabled()) { if (!EamDb.isEnabled()) {
break; break;
} }
@ -214,7 +214,7 @@ public class CaseEventListener implements PropertyChangeListener {
"", "",
""); "");
if (!dbManager.isEnabled()) { if (!EamDb.isEnabled()) {
break; break;
} }

View File

@ -78,7 +78,7 @@ public class IngestEventsListener {
EamDb dbManager = EamDb.getInstance(); EamDb dbManager = EamDb.getInstance();
switch (IngestManager.IngestModuleEvent.valueOf(evt.getPropertyName())) { switch (IngestManager.IngestModuleEvent.valueOf(evt.getPropertyName())) {
case DATA_ADDED: { case DATA_ADDED: {
if (!dbManager.isEnabled()) { if (!EamDb.isEnabled()) {
return; return;
} }

View File

@ -45,7 +45,7 @@ public class NewArtifactsRunner implements Runnable {
@Override @Override
public void run() { public void run() {
if (!dbManager.isEnabled()) { if (!EamDb.isEnabled()) {
LOGGER.log(Level.WARNING, "Enterprise artifacts manager database not configured"); // NON-NLS LOGGER.log(Level.WARNING, "Enterprise artifacts manager database not configured"); // NON-NLS
return; return;
} }

View File

@ -70,7 +70,7 @@ class IngestModule implements FileIngestModule {
@Override @Override
public ProcessResult process(AbstractFile af) { public ProcessResult process(AbstractFile af) {
if (Boolean.parseBoolean(ModuleSettings.getConfigSetting("EnterpriseArtifactsManager", "db.enabled")) == false if (Boolean.parseBoolean(ModuleSettings.getConfigSetting("EnterpriseArtifactsManager", "db.enabled")) == false
|| EamDb.getInstance().isEnabled() == false) { || EamDb.isEnabled() == false) {
/* /*
* Not signaling an error for now. This is a workaround for the way * Not signaling an error for now. This is a workaround for the way
* all newly didscovered ingest modules are automatically anabled. * all newly didscovered ingest modules are automatically anabled.
@ -153,7 +153,7 @@ class IngestModule implements FileIngestModule {
@Override @Override
public void shutDown() { public void shutDown() {
if (Boolean.parseBoolean(ModuleSettings.getConfigSetting("EnterpriseArtifactsManager", "db.enabled")) == false if (Boolean.parseBoolean(ModuleSettings.getConfigSetting("EnterpriseArtifactsManager", "db.enabled")) == false
|| EamDb.getInstance().isEnabled() == false) { || EamDb.isEnabled() == false) {
/* /*
* Not signaling an error for now. This is a workaround for the way * Not signaling an error for now. This is a workaround for the way
* all newly didscovered ingest modules are automatically anabled. * all newly didscovered ingest modules are automatically anabled.
@ -188,7 +188,7 @@ class IngestModule implements FileIngestModule {
@Override @Override
public void startUp(IngestJobContext context) throws IngestModuleException { public void startUp(IngestJobContext context) throws IngestModuleException {
if (Boolean.parseBoolean(ModuleSettings.getConfigSetting("EnterpriseArtifactsManager", "db.enabled")) == false if (Boolean.parseBoolean(ModuleSettings.getConfigSetting("EnterpriseArtifactsManager", "db.enabled")) == false
|| EamDb.getInstance().isEnabled() == false) { || EamDb.isEnabled() == false) {
/* /*
* Not throwing the customary exception for now. This is a * Not throwing the customary exception for now. This is a
* workaround for the way all newly didscovered ingest modules are * workaround for the way all newly didscovered ingest modules are

View File

@ -200,11 +200,11 @@
</Group> </Group>
<EmptySpace type="separate" max="-2" attributes="0"/> <EmptySpace type="separate" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" max="-2" attributes="0"> <Group type="103" groupAlignment="0" max="-2" attributes="0">
<Component id="tbDbPassword" alignment="0" pref="439" max="32767" attributes="0"/> <Component id="tbDbUsername" alignment="0" pref="439" max="32767" attributes="0"/>
<Component id="tbDbUsername" alignment="0" max="32767" attributes="0"/>
<Component id="tbDbName" alignment="0" max="32767" attributes="0"/> <Component id="tbDbName" alignment="0" max="32767" attributes="0"/>
<Component id="tbDbPort" alignment="0" max="32767" attributes="0"/> <Component id="tbDbPort" alignment="0" max="32767" attributes="0"/>
<Component id="tbDbHostname" max="32767" attributes="0"/> <Component id="tbDbHostname" max="32767" attributes="0"/>
<Component id="jpDbPassword" max="32767" attributes="0"/>
</Group> </Group>
<EmptySpace max="32767" attributes="0"/> <EmptySpace max="32767" attributes="0"/>
</Group> </Group>
@ -236,7 +236,7 @@
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0"> <Group type="103" groupAlignment="3" attributes="0">
<Component id="lbUserPassword" alignment="3" min="-2" pref="20" max="-2" attributes="0"/> <Component id="lbUserPassword" alignment="3" min="-2" pref="20" max="-2" attributes="0"/>
<Component id="tbDbPassword" alignment="3" min="-2" max="-2" attributes="0"/> <Component id="jpDbPassword" alignment="3" min="-2" max="-2" attributes="0"/>
</Group> </Group>
<EmptySpace pref="19" max="32767" attributes="0"/> <EmptySpace pref="19" max="32767" attributes="0"/>
</Group> </Group>
@ -287,7 +287,7 @@
</Component> </Component>
<Component class="javax.swing.JTextField" name="tbDbUsername"> <Component class="javax.swing.JTextField" name="tbDbUsername">
</Component> </Component>
<Component class="javax.swing.JTextField" name="tbDbPassword"> <Component class="javax.swing.JPasswordField" name="jpDbPassword">
</Component> </Component>
</SubComponents> </SubComponents>
</Container> </Container>

View File

@ -28,6 +28,7 @@ import org.openide.util.NbBundle.Messages;
import org.openide.windows.WindowManager; import org.openide.windows.WindowManager;
import org.sleuthkit.autopsy.corecomponents.TextPrompt; import org.sleuthkit.autopsy.corecomponents.TextPrompt;
import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.experimental.enterpriseartifactsmanager.datamodel.EamDb;
import org.sleuthkit.autopsy.experimental.enterpriseartifactsmanager.datamodel.EamDbException; import org.sleuthkit.autopsy.experimental.enterpriseartifactsmanager.datamodel.EamDbException;
import org.sleuthkit.autopsy.experimental.enterpriseartifactsmanager.datamodel.EamDbPlatformEnum; import org.sleuthkit.autopsy.experimental.enterpriseartifactsmanager.datamodel.EamDbPlatformEnum;
import org.sleuthkit.autopsy.experimental.enterpriseartifactsmanager.datamodel.PostgresEamDbSettings; import org.sleuthkit.autopsy.experimental.enterpriseartifactsmanager.datamodel.PostgresEamDbSettings;
@ -98,7 +99,7 @@ public class EamDbSettingsDialog extends JDialog {
tbDbPort = new javax.swing.JTextField(); tbDbPort = new javax.swing.JTextField();
tbDbName = new javax.swing.JTextField(); tbDbName = new javax.swing.JTextField();
tbDbUsername = new javax.swing.JTextField(); tbDbUsername = new javax.swing.JTextField();
tbDbPassword = new javax.swing.JTextField(); jpDbPassword = new javax.swing.JPasswordField();
rdioBnSQLite = new javax.swing.JRadioButton(); rdioBnSQLite = new javax.swing.JRadioButton();
rdioBnPostgreSQL = new javax.swing.JRadioButton(); rdioBnPostgreSQL = new javax.swing.JRadioButton();
rdioBnDisabled = new javax.swing.JRadioButton(); rdioBnDisabled = new javax.swing.JRadioButton();
@ -179,11 +180,11 @@ public class EamDbSettingsDialog extends JDialog {
.addComponent(lbUserPassword)) .addComponent(lbUserPassword))
.addGap(18, 18, 18) .addGap(18, 18, 18)
.addGroup(pnPostgreSQLSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) .addGroup(pnPostgreSQLSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
.addComponent(tbDbPassword, javax.swing.GroupLayout.DEFAULT_SIZE, 439, Short.MAX_VALUE) .addComponent(tbDbUsername, javax.swing.GroupLayout.DEFAULT_SIZE, 439, Short.MAX_VALUE)
.addComponent(tbDbUsername)
.addComponent(tbDbName) .addComponent(tbDbName)
.addComponent(tbDbPort) .addComponent(tbDbPort)
.addComponent(tbDbHostname)) .addComponent(tbDbHostname)
.addComponent(jpDbPassword))
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
); );
pnPostgreSQLSettingsLayout.setVerticalGroup( pnPostgreSQLSettingsLayout.setVerticalGroup(
@ -208,7 +209,7 @@ public class EamDbSettingsDialog extends JDialog {
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(pnPostgreSQLSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addGroup(pnPostgreSQLSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(lbUserPassword, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(lbUserPassword, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(tbDbPassword, 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))
.addContainerGap(19, Short.MAX_VALUE)) .addContainerGap(19, Short.MAX_VALUE))
); );
@ -439,14 +440,21 @@ public class EamDbSettingsDialog extends JDialog {
private void bnTestActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnTestActionPerformed private void bnTestActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnTestActionPerformed
// lbTestDatabase.setIcon(null); // lbTestDatabase.setIcon(null);
// lbTestDatabase.setText(""); // lbTestDatabase.setText("");
boolean connectionOk;
boolean schemaOk;
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
EamDbPlatformEnum selectedPlatform = EamDbPlatformEnum.getSelectedPlatform(); EamDbPlatformEnum selectedPlatform = EamDbPlatformEnum.getSelectedPlatform();
switch (selectedPlatform) { switch (selectedPlatform) {
case POSTGRESQL: case POSTGRESQL:
connectionOk = dbSettingsPostgres.testConnectionSettings(); if (dbSettingsPostgres.verifyConnection()) {
if (dbSettingsPostgres.verifyDatabaseExists()
&& dbSettingsPostgres.verifyDatabaseSchema()) {
testingStatus = DatabaseTestResult.TESTEDOK;
} else {
testingStatus = DatabaseTestResult.SCHEMA_INVALID;
}
} else {
testingStatus = DatabaseTestResult.CONNECTION_FAILED;
}
break; break;
case SQLITE: case SQLITE:
if (dbSettingsSqlite.dbDirectoryExists() if (dbSettingsSqlite.dbDirectoryExists()
@ -474,6 +482,12 @@ public class EamDbSettingsDialog extends JDialog {
boolean result = false; boolean result = false;
switch (selectedPlatform) { switch (selectedPlatform) {
case POSTGRESQL: case POSTGRESQL:
if (!dbSettingsPostgres.verifyDatabaseExists()) {
dbSettingsPostgres.createDatabase();
}
result = dbSettingsPostgres.initializeDatabaseSchema()
&& dbSettingsPostgres.insertDefaultDatabaseContent();
break; break;
case SQLITE: case SQLITE:
if (!dbSettingsSqlite.dbDirectoryExists()) { if (!dbSettingsSqlite.dbDirectoryExists()) {
@ -487,14 +501,27 @@ public class EamDbSettingsDialog extends JDialog {
if (false == result) { if (false == result) {
taSetupGuidance.setText(Bundle.EamDbSettingsDialog_creation_failed()); taSetupGuidance.setText(Bundle.EamDbSettingsDialog_creation_failed());
} else { } else {
testingStatus = DatabaseTestResult.TESTEDOK;
valid(); valid();
} }
}//GEN-LAST:event_bnCreateDbActionPerformed }//GEN-LAST:event_bnCreateDbActionPerformed
private void bnOkActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnOkActionPerformed private void bnOkActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnOkActionPerformed
// hasChanged = true; EamDbPlatformEnum selectedPlatform = EamDbPlatformEnum.getSelectedPlatform();
// dbSettings.setEnabled(true); EamDbPlatformEnum.saveSelectedPlatform();
// dbSettings.saveSettings(); switch (selectedPlatform) {
case POSTGRESQL:
dbSettingsPostgres.saveSettings();
EamDb.getInstance().updateSettings();
break;
case SQLITE:
dbSettingsSqlite.saveSettings();
EamDb.getInstance().updateSettings();
break;
case DISABLED:
break;
}
dispose(); dispose();
}//GEN-LAST:event_bnOkActionPerformed }//GEN-LAST:event_bnOkActionPerformed
@ -543,8 +570,8 @@ public class EamDbSettingsDialog extends JDialog {
tbDbName.setEnabled(enabled); tbDbName.setEnabled(enabled);
tbDbUsername.setText(enabled ? dbSettingsPostgres.getUserName() : ""); tbDbUsername.setText(enabled ? dbSettingsPostgres.getUserName() : "");
tbDbUsername.setEnabled(enabled); tbDbUsername.setEnabled(enabled);
tbDbPassword.setText(enabled ? dbSettingsPostgres.getPassword() : ""); jpDbPassword.setText(enabled ? dbSettingsPostgres.getPassword() : "");
tbDbPassword.setEnabled(enabled); jpDbPassword.setEnabled(enabled);
} }
/** /**
@ -573,7 +600,6 @@ public class EamDbSettingsDialog extends JDialog {
textPrompts.add(new TextPrompt(Bundle.EamDbSettingsDialog_textPrompt_port(), tbDbPort)); textPrompts.add(new TextPrompt(Bundle.EamDbSettingsDialog_textPrompt_port(), tbDbPort));
textPrompts.add(new TextPrompt(Bundle.EamDbSettingsDialog_textPrompt_dbName(), tbDbName)); textPrompts.add(new TextPrompt(Bundle.EamDbSettingsDialog_textPrompt_dbName(), tbDbName));
textPrompts.add(new TextPrompt(Bundle.EamDbSettingsDialog_textPrompt_user(), tbDbUsername)); textPrompts.add(new TextPrompt(Bundle.EamDbSettingsDialog_textPrompt_user(), tbDbUsername));
textPrompts.add(new TextPrompt(Bundle.EamDbSettingsDialog_textPrompt_password(), tbDbPassword));
configureTextPrompts(textPrompts); configureTextPrompts(textPrompts);
} }
@ -598,7 +624,7 @@ public class EamDbSettingsDialog extends JDialog {
textBoxes.add(tbDbPort); textBoxes.add(tbDbPort);
textBoxes.add(tbDbName); textBoxes.add(tbDbName);
textBoxes.add(tbDbUsername); textBoxes.add(tbDbUsername);
textBoxes.add(tbDbPassword); textBoxes.add(jpDbPassword);
addDocumentListeners(textBoxes, textBoxChangedListener); addDocumentListeners(textBoxes, textBoxChangedListener);
} }
@ -643,7 +669,7 @@ public class EamDbSettingsDialog extends JDialog {
&& !tbDbPort.getText().trim().isEmpty() && !tbDbPort.getText().trim().isEmpty()
&& !tbDbName.getText().trim().isEmpty() && !tbDbName.getText().trim().isEmpty()
&& !tbDbUsername.getText().trim().isEmpty() && !tbDbUsername.getText().trim().isEmpty()
&& !tbDbPassword.getText().trim().isEmpty(); && 0 < jpDbPassword.getPassword().length;
break; break;
@ -727,7 +753,7 @@ public class EamDbSettingsDialog extends JDialog {
} }
try { try {
dbSettingsPostgres.setPassword(tbDbPassword.getText().trim()); dbSettingsPostgres.setPassword(jpDbPassword.getPassword().toString());
} catch (EamDbException ex) { } catch (EamDbException ex) {
if (!guidanceText.toString().isEmpty()) { if (!guidanceText.toString().isEmpty()) {
guidanceText.append(", "); guidanceText.append(", ");
@ -874,6 +900,7 @@ public class EamDbSettingsDialog extends JDialog {
private javax.swing.JButton bnOk; private javax.swing.JButton bnOk;
private javax.swing.JButton bnTest; private javax.swing.JButton bnTest;
private javax.swing.JFileChooser fcDatabasePath; private javax.swing.JFileChooser fcDatabasePath;
private javax.swing.JPasswordField jpDbPassword;
private javax.swing.JLabel lbDatabaseName; private javax.swing.JLabel lbDatabaseName;
private javax.swing.JLabel lbDatabasePath; private javax.swing.JLabel lbDatabasePath;
private javax.swing.JLabel lbHostName; private javax.swing.JLabel lbHostName;
@ -891,7 +918,6 @@ public class EamDbSettingsDialog extends JDialog {
private javax.swing.JTextArea taSetupGuidance; private javax.swing.JTextArea taSetupGuidance;
private javax.swing.JTextField tbDbHostname; private javax.swing.JTextField tbDbHostname;
private javax.swing.JTextField tbDbName; private javax.swing.JTextField tbDbName;
private javax.swing.JTextField tbDbPassword;
private javax.swing.JTextField tbDbPort; private javax.swing.JTextField tbDbPort;
private javax.swing.JTextField tbDbUsername; private javax.swing.JTextField tbDbUsername;
private javax.swing.JTextField tfDatabasePath; private javax.swing.JTextField tfDatabasePath;

View File

@ -178,7 +178,7 @@ final class ImportHashDatabaseDialog extends javax.swing.JDialog {
public boolean valid() { public boolean valid() {
lbWarningMsg.setText(""); lbWarningMsg.setText("");
EamDb dbManager = EamDb.getInstance(); EamDb dbManager = EamDb.getInstance();
if (!dbManager.isEnabled()) { if (!EamDb.isEnabled()) {
lbWarningMsg.setText(Bundle.ImportHashDatabaseDialog_validation_notEnabled()); lbWarningMsg.setText(Bundle.ImportHashDatabaseDialog_validation_notEnabled());
return false; return false;
} }
@ -561,7 +561,7 @@ final class ImportHashDatabaseDialog extends javax.swing.JDialog {
this.knownStatus = knownStatus; this.knownStatus = knownStatus;
this.globalSetID = globalSetID; this.globalSetID = globalSetID;
if (!dbManager.isEnabled()) { if (!EamDb.isEnabled()) {
throw new EamDbException("Enterprise artifacts manager database settings were not properly initialized"); // NON-NLS throw new EamDbException("Enterprise artifacts manager database settings were not properly initialized"); // NON-NLS
} }
} }