From cf3230b246618b55b5292b882faa459eb04033a8 Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Thu, 15 Jun 2017 14:56:30 -0400 Subject: [PATCH 01/20] 2745 replace fixed indexs to table with loop --- .../DataContentViewerArtifact.form | 384 +++++++++--------- .../DataContentViewerArtifact.java | 77 ++-- 2 files changed, 225 insertions(+), 236 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/DataContentViewerArtifact.form b/Core/src/org/sleuthkit/autopsy/corecomponents/DataContentViewerArtifact.form index 8957d55bb1..8e379954e9 100644 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/DataContentViewerArtifact.form +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/DataContentViewerArtifact.form @@ -45,222 +45,212 @@ - + - + - + - - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/DataContentViewerArtifact.java b/Core/src/org/sleuthkit/autopsy/corecomponents/DataContentViewerArtifact.java index 5b7cf32634..c1d2bfc4c9 100644 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/DataContentViewerArtifact.java +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/DataContentViewerArtifact.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2011-2017 Basis Technology Corp. + * Copyright 2011-2013 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -26,12 +26,14 @@ import java.awt.event.ActionListener; import java.awt.datatransfer.StringSelection; import java.text.SimpleDateFormat; import java.util.ArrayList; +import java.util.Enumeration; import java.util.List; import java.util.concurrent.ExecutionException; import java.util.logging.Level; import javax.swing.JMenuItem; import javax.swing.SwingWorker; import javax.swing.table.DefaultTableModel; +import javax.swing.table.TableColumn; import org.apache.commons.lang.StringUtils; import org.openide.nodes.Node; import org.openide.util.Lookup; @@ -75,6 +77,7 @@ public class DataContentViewerArtifact extends javax.swing.JPanel implements Dat Bundle.DataContentViewerArtifact_attrsTableHeader_type(), Bundle.DataContentViewerArtifact_attrsTableHeader_value(), Bundle.DataContentViewerArtifact_attrsTableHeader_sources()}; + private static final int[] COLUMN_WIDTHS = {100, 800, 100}; public DataContentViewerArtifact() { initResultsTable(); @@ -86,30 +89,31 @@ public class DataContentViewerArtifact extends javax.swing.JPanel implements Dat private void initResultsTable() { resultsTable = new ETable(); - resultsTable.setModel(new javax.swing.table.DefaultTableModel() { private static final long serialVersionUID = 1L; - @Override public boolean isCellEditable(int rowIndex, int columnIndex) { return false; } - }); resultsTable.setCellSelectionEnabled(true); - resultsTable.getColumnModel().getSelectionModel().setSelectionMode(javax.swing.ListSelectionModel.SINGLE_INTERVAL_SELECTION); - resultsTable.setColumnHidingAllowed(false); resultsTable.getTableHeader().setReorderingAllowed(false); - resultsTable.setRowSorter(null); //null sorter turns off sorting + resultsTable.getColumnModel().getSelectionModel().setSelectionMode(javax.swing.ListSelectionModel.SINGLE_INTERVAL_SELECTION); updateColumnSizes(); } private void updateColumnSizes() { resultsTable.setAutoResizeMode(javax.swing.JTable.AUTO_RESIZE_NEXT_COLUMN); - if (resultsTable.getColumnModel().getColumnCount() > 0) { - resultsTable.getColumnModel().getColumn(0).setPreferredWidth(100); - resultsTable.getColumnModel().getColumn(1).setPreferredWidth(800); - resultsTable.getColumnModel().getColumn(2).setPreferredWidth(100); + Enumeration columns = resultsTable.getColumnModel().getColumns(); + while (columns.hasMoreElements()) { + TableColumn col = columns.nextElement(); + if (col.getHeaderValue().equals(COLUMN_HEADERS[0])) { + col.setPreferredWidth(COLUMN_WIDTHS[0]); + } else if (col.getHeaderValue().equals(COLUMN_HEADERS[1])) { + col.setPreferredWidth(COLUMN_WIDTHS[1]); + } else if (col.getHeaderValue().equals(COLUMN_HEADERS[2])) { + col.setPreferredWidth(COLUMN_WIDTHS[2]); + } } } @@ -119,13 +123,12 @@ public class DataContentViewerArtifact extends javax.swing.JPanel implements Dat * regenerated by the Form Editor. */ @SuppressWarnings("unchecked") - // + // //GEN-BEGIN:initComponents private void initComponents() { rightClickMenu = new javax.swing.JPopupMenu(); copyMenuItem = new javax.swing.JMenuItem(); selectAllMenuItem = new javax.swing.JMenuItem(); - jScrollPane1 = new javax.swing.JScrollPane(); jPanel1 = new javax.swing.JPanel(); totalPageLabel = new javax.swing.JLabel(); ofLabel = new javax.swing.JLabel(); @@ -145,9 +148,6 @@ public class DataContentViewerArtifact extends javax.swing.JPanel implements Dat setPreferredSize(new java.awt.Dimension(622, 58)); - jScrollPane1.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); - jScrollPane1.setPreferredSize(new java.awt.Dimension(622, 58)); - jPanel1.setPreferredSize(new java.awt.Dimension(620, 58)); totalPageLabel.setText(org.openide.util.NbBundle.getMessage(DataContentViewerArtifact.class, "DataContentViewerArtifact.totalPageLabel.text")); // NOI18N @@ -197,7 +197,8 @@ public class DataContentViewerArtifact extends javax.swing.JPanel implements Dat } }); - resultsTableScrollPane.setPreferredSize(new java.awt.Dimension(620, 271)); + resultsTableScrollPane.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); + resultsTableScrollPane.setPreferredSize(new java.awt.Dimension(620, 34)); javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1); jPanel1.setLayout(jPanel1Layout); @@ -218,13 +219,13 @@ public class DataContentViewerArtifact extends javax.swing.JPanel implements Dat .addComponent(prevPageButton, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE) .addGap(0, 0, 0) .addComponent(nextPageButton, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE) - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addContainerGap(366, Short.MAX_VALUE)) .addComponent(resultsTableScrollPane, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup() - .addContainerGap(277, Short.MAX_VALUE) + .addContainerGap(280, Short.MAX_VALUE) .addComponent(artifactLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 258, javax.swing.GroupLayout.PREFERRED_SIZE) - .addContainerGap(85, Short.MAX_VALUE))) + .addContainerGap(84, Short.MAX_VALUE))) ); jPanel1Layout.setVerticalGroup( jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) @@ -239,47 +240,45 @@ public class DataContentViewerArtifact extends javax.swing.JPanel implements Dat .addComponent(prevPageButton, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(pageLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(resultsTableScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 34, Short.MAX_VALUE)) + .addComponent(resultsTableScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 29, Short.MAX_VALUE) + .addGap(0, 0, 0)) .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel1Layout.createSequentialGroup() .addComponent(artifactLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGap(0, 40, Short.MAX_VALUE))) + .addGap(0, 401, Short.MAX_VALUE))) ); - jScrollPane1.setViewportView(jPanel1); - 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.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, 622, Short.MAX_VALUE) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(jScrollPane1, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) ); - }// + }// //GEN-END:initComponents - private void prevPageButtonActionPerformed(java.awt.event.ActionEvent evt) { - currentPage = currentPage - 1; - currentPageLabel.setText(Integer.toString(currentPage)); - artifactLabel.setText(artifactTableContents.get(currentPage - 1).getArtifactDisplayName()); - startNewTask(new SelectedArtifactChangedTask(currentPage)); - } - - private void nextPageButtonActionPerformed(java.awt.event.ActionEvent evt) { + private void nextPageButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_nextPageButtonActionPerformed currentPage = currentPage + 1; currentPageLabel.setText(Integer.toString(currentPage)); artifactLabel.setText(artifactTableContents.get(currentPage - 1).getArtifactDisplayName()); startNewTask(new SelectedArtifactChangedTask(currentPage)); - } + }//GEN-LAST:event_nextPageButtonActionPerformed - // Variables declaration - do not modify + private void prevPageButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_prevPageButtonActionPerformed + currentPage = currentPage - 1; + currentPageLabel.setText(Integer.toString(currentPage)); + artifactLabel.setText(artifactTableContents.get(currentPage - 1).getArtifactDisplayName()); + startNewTask(new SelectedArtifactChangedTask(currentPage)); + }//GEN-LAST:event_prevPageButtonActionPerformed + + // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JLabel artifactLabel; private javax.swing.JMenuItem copyMenuItem; private javax.swing.JLabel currentPageLabel; private javax.swing.JPanel jPanel1; - private javax.swing.JScrollPane jScrollPane1; private javax.swing.JButton nextPageButton; private javax.swing.JLabel ofLabel; private javax.swing.JLabel pageLabel; @@ -289,7 +288,7 @@ public class DataContentViewerArtifact extends javax.swing.JPanel implements Dat private javax.swing.JPopupMenu rightClickMenu; private javax.swing.JMenuItem selectAllMenuItem; private javax.swing.JLabel totalPageLabel; - // End of variables declaration + // End of variables declaration//GEN-END:variables private ETable resultsTable; private void customizeComponents() { From 545a149dbee8423d57a1eba36bcf57c7fb06c2be Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Thu, 15 Jun 2017 16:03:06 -0400 Subject: [PATCH 02/20] 2745 disable column hiding leaving sorting enabled for content viewer ETable --- .../autopsy/corecomponents/DataContentViewerArtifact.java | 1 + 1 file changed, 1 insertion(+) diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/DataContentViewerArtifact.java b/Core/src/org/sleuthkit/autopsy/corecomponents/DataContentViewerArtifact.java index c1d2bfc4c9..de23bd88e1 100644 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/DataContentViewerArtifact.java +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/DataContentViewerArtifact.java @@ -98,6 +98,7 @@ public class DataContentViewerArtifact extends javax.swing.JPanel implements Dat }); resultsTable.setCellSelectionEnabled(true); resultsTable.getTableHeader().setReorderingAllowed(false); + resultsTable.setColumnHidingAllowed(false); resultsTable.getColumnModel().getSelectionModel().setSelectionMode(javax.swing.ListSelectionModel.SINGLE_INTERVAL_SELECTION); updateColumnSizes(); } From cc3d21c3ca26e65b07e863db62a6171e5ca8dd4b Mon Sep 17 00:00:00 2001 From: Nick Davis Date: Thu, 15 Jun 2017 18:03:52 -0400 Subject: [PATCH 03/20] started on issue #174. Changed Save button to OK button. Updated default db path. Use default db path in file chooser. Use default db dir in file chooser. --- .../datamodel/SqliteEamDbSettings.java | 2 +- .../optionspanel/Bundle.properties | 2 +- .../optionspanel/EamSqliteSettingsDialog.form | 10 +++---- .../optionspanel/EamSqliteSettingsDialog.java | 29 +++++++++++-------- 4 files changed, 24 insertions(+), 19 deletions(-) diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/SqliteEamDbSettings.java b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/SqliteEamDbSettings.java index ede8e04d51..787de9c4f0 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/SqliteEamDbSettings.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/SqliteEamDbSettings.java @@ -41,7 +41,7 @@ public final class SqliteEamDbSettings { private final static Logger LOGGER = Logger.getLogger(SqliteEamDbSettings.class.getName()); private final String DEFAULT_DBNAME = "EnterpriseArtifacts.db"; // NON-NLS - private final String DEFAULT_DBDIRECTORY = PlatformUtil.getUserDirectory() + File.separator + "Autopsy" + File.separator + "eamdb"; // NON-NLS + private final String DEFAULT_DBDIRECTORY = PlatformUtil.getUserDirectory() + File.separator + "enterprise_artifacts_manager"; // NON-NLS private final int DEFAULT_BULK_THRESHHOLD = 1000; private final String DEFAULT_BAD_TAGS = "Evidence"; // NON-NLS private final String JDBC_DRIVER = "org.sqlite.JDBC"; // NON-NLS diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/Bundle.properties b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/Bundle.properties index ccb83b2e46..1b1cb090cf 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/Bundle.properties +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/Bundle.properties @@ -17,7 +17,6 @@ EamPostgresSettingsDialog.bnSave.text=Save EamPostgresSettingsDialog.lbHostName.text=Host Name / IP : EamPostgresSettingsDialog.bnTestConnection.text=Test Connection EamPostgresSettingsDialog.lbDatabaseName.text=Database name : -EamSqliteSettingsDialog.bnSave.text=Save EamSqliteSettingsDialog.bnCancel.text=Cancel EamSqliteSettingsDialog.lbTestDatabase.text= EamSqliteSettingsDialog.bnTestDatabase.text=Test Connection @@ -68,3 +67,4 @@ ManageArtifactTypesDialog.cancelButton.text=Cancel ManageArtifactTypesDialog.okButton.text=OK ManageArtifactTypesDialog.lbWarningMsg.text=Warning Message ManageArtifactTypesDialog.taInstructionsMsg.text=Select one or more artifact types to store in the database and use for correlation during Ingest. +EamSqliteSettingsDialog.bnOk.text=OK diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/EamSqliteSettingsDialog.form b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/EamSqliteSettingsDialog.form index 9ab466696d..de9cad5ca8 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/EamSqliteSettingsDialog.form +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/EamSqliteSettingsDialog.form @@ -91,7 +91,7 @@ - + @@ -116,7 +116,7 @@ - + @@ -198,14 +198,14 @@ - + - + - + diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/EamSqliteSettingsDialog.java b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/EamSqliteSettingsDialog.java index e46288dd21..60ff1f8f81 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/EamSqliteSettingsDialog.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/EamSqliteSettingsDialog.java @@ -87,7 +87,7 @@ public class EamSqliteSettingsDialog extends javax.swing.JDialog { lbTestDatabaseWarning.setText(""); hasChanged = false; tfDatabasePath.getDocument().addDocumentListener(textBoxChangedListener); - bnSave.setEnabled(false); + bnOk.setEnabled(false); bnTestDatabase.setEnabled(false); } @@ -135,11 +135,11 @@ public class EamSqliteSettingsDialog extends javax.swing.JDialog { private boolean valid() { boolean result = false; if (tfDatabasePath.getText().trim().isEmpty()) { - bnSave.setEnabled(false); + bnOk.setEnabled(false); bnTestDatabase.setEnabled(false); } else { storeDbNameAndDirectory(); - bnSave.setEnabled(true); + bnOk.setEnabled(true); bnTestDatabase.setEnabled(true); result = true; } @@ -182,7 +182,7 @@ public class EamSqliteSettingsDialog extends javax.swing.JDialog { bnTestDatabase = new javax.swing.JButton(); lbTestDatabase = new javax.swing.JLabel(); bnCancel = new javax.swing.JButton(); - bnSave = new javax.swing.JButton(); + bnOk = new javax.swing.JButton(); setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); @@ -218,10 +218,10 @@ public class EamSqliteSettingsDialog extends javax.swing.JDialog { } }); - org.openide.awt.Mnemonics.setLocalizedText(bnSave, org.openide.util.NbBundle.getMessage(EamSqliteSettingsDialog.class, "EamSqliteSettingsDialog.bnSave.text")); // NOI18N - bnSave.addActionListener(new java.awt.event.ActionListener() { + org.openide.awt.Mnemonics.setLocalizedText(bnOk, org.openide.util.NbBundle.getMessage(EamSqliteSettingsDialog.class, "EamSqliteSettingsDialog.bnOk.text")); // NOI18N + bnOk.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { - bnSaveActionPerformed(evt); + bnOkActionPerformed(evt); } }); @@ -247,7 +247,7 @@ public class EamSqliteSettingsDialog extends javax.swing.JDialog { .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(lbTestDatabase, javax.swing.GroupLayout.PREFERRED_SIZE, 30, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(bnSave) + .addComponent(bnOk) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(bnCancel) .addContainerGap()))) @@ -267,7 +267,7 @@ public class EamSqliteSettingsDialog extends javax.swing.JDialog { .addGap(19, 19, 19) .addGroup(pnContentLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(bnCancel) - .addComponent(bnSave))) + .addComponent(bnOk))) .addGroup(pnContentLayout.createSequentialGroup() .addGap(18, 18, 18) .addGroup(pnContentLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) @@ -311,11 +311,15 @@ public class EamSqliteSettingsDialog extends javax.swing.JDialog { @Messages({"EnterpriseArtifactsManagerSQLiteSettingsDialog.chooserPath.failedToGetDbPathMsg=Selected database path is invalid. Try again."}) private void bnDatabasePathFileOpenActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnDatabasePathFileOpenActionPerformed + fcDatabasePath.setCurrentDirectory(new File(dbSettings.getDbDirectory())); + fcDatabasePath.setSelectedFile(new File(dbSettings.getFileNameWithPath())); if (fcDatabasePath.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) { File databaseFile = fcDatabasePath.getSelectedFile(); try { tfDatabasePath.setText(databaseFile.getCanonicalPath()); valid(); + // TODO: create the db/schema if it doesn't exist. + // TODO: set variable noting that we created a new db, so it can be removed if Cancel button is clicked. } catch (IOException ex) { LOGGER.log(Level.SEVERE, "Failed to get path of selected database file", ex); // NON-NLS @@ -339,20 +343,21 @@ public class EamSqliteSettingsDialog extends javax.swing.JDialog { }//GEN-LAST:event_bnTestDatabaseActionPerformed private void bnCancelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnCancelActionPerformed + // TODO: if a new db was created, then delete it. update settings to disable this platform dispose(); }//GEN-LAST:event_bnCancelActionPerformed - private void bnSaveActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnSaveActionPerformed + private void bnOkActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnOkActionPerformed hasChanged = true; dbSettings.setEnabled(true); dbSettings.saveSettings(); dispose(); - }//GEN-LAST:event_bnSaveActionPerformed + }//GEN-LAST:event_bnOkActionPerformed // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JButton bnCancel; private javax.swing.JButton bnDatabasePathFileOpen; - private javax.swing.JButton bnSave; + private javax.swing.JButton bnOk; private javax.swing.JButton bnTestDatabase; private javax.swing.JFileChooser fcDatabasePath; private javax.swing.JScrollPane jScrollPane; From 1b431362449c19bdfe007fbbd2ab5428cd7e083b Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Fri, 16 Jun 2017 11:18:44 -0400 Subject: [PATCH 04/20] 2745 change out of date comments in DataContentViewerArtifact --- .../corecomponents/DataContentViewerArtifact.java | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/DataContentViewerArtifact.java b/Core/src/org/sleuthkit/autopsy/corecomponents/DataContentViewerArtifact.java index de23bd88e1..8ad63473d4 100644 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/DataContentViewerArtifact.java +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/DataContentViewerArtifact.java @@ -52,7 +52,7 @@ import org.netbeans.swing.etable.ETable; /** * Instances of this class display the BlackboardArtifacts associated with the - * Content represented by a Node. Each BlackboardArtifact is rendered as an HTML + * Content represented by a Node. Each BlackboardArtifact is rendered displayed in a JTable * representation of its BlackboardAttributes. */ @ServiceProvider(service = DataContentViewer.class, position = 3) @@ -548,10 +548,6 @@ public class DataContentViewerArtifact extends javax.swing.JPanel implements Dat totalPageLabel.setText(Integer.toString(viewUpdate.numberOfPages)); currentPageLabel.setText(Integer.toString(currentPage)); artifactLabel.setText(viewUpdate.tableContents.getArtifactDisplayName()); - // @@@ This can take a long time. Perhaps a faster HTML renderer can be found. - // Note that the rendering appears to be done on a background thread, since the - // wait cursor reset below happens before the new text hits the JTextPane. On the - // other hand, the UI is unresponsive... DefaultTableModel tModel = ((DefaultTableModel) resultsTable.getModel()); tModel.setDataVector(viewUpdate.tableContents.getRows(), COLUMN_HEADERS); updateColumnSizes(); @@ -740,8 +736,7 @@ public class DataContentViewerArtifact extends javax.swing.JPanel implements Dat List artifactContents = getArtifactContents(); ResultsTableArtifact artifactContent = artifactContents.get(pageIndex - 1); - // It may take a considerable amount of time to fetch the attributes of the selected artifact and render them - // as HTML, so check for cancellation. + // It may take a considerable amount of time to fetch the attributes of the selected artifact so check for cancellation. if (isCancelled()) { return null; } From 4adda2a630deac45b1a2b00d1d8b179c3fbd4c3b Mon Sep 17 00:00:00 2001 From: Nick Davis Date: Fri, 16 Jun 2017 18:59:10 -0400 Subject: [PATCH 05/20] converting to new db config UI; layout complete. --- .../datamodel/EamDbPlatformEnum.java | 17 +- .../optionspanel/Bundle.properties | 28 +- .../optionspanel/EamDbSettingsDialog.form | 463 +++++++++++ .../optionspanel/EamDbSettingsDialog.java | 716 ++++++++++++++++++ .../optionspanel/GlobalSettingsPanel.form | 466 ++++++------ .../optionspanel/GlobalSettingsPanel.java | 487 ++++-------- 6 files changed, 1607 insertions(+), 570 deletions(-) create mode 100644 Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/EamDbSettingsDialog.form create mode 100644 Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/EamDbSettingsDialog.java diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/EamDbPlatformEnum.java b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/EamDbPlatformEnum.java index bc02377430..1f2362d25f 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/EamDbPlatformEnum.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/EamDbPlatformEnum.java @@ -24,7 +24,8 @@ import org.sleuthkit.autopsy.coreutils.ModuleSettings; * */ public enum EamDbPlatformEnum { - SQLITE("SQLite", true), + DISABLED("", true), + SQLITE("SQLite", false), POSTGRESQL("PostgreSQL", false); private final String platformName; @@ -44,6 +45,8 @@ public enum EamDbPlatformEnum { if (null != selectedPlatformString) { selected = this.toString().equalsIgnoreCase(selectedPlatformString); + } else if (this == DISABLED) { + selected = true; } } @@ -56,13 +59,13 @@ public enum EamDbPlatformEnum { this.selected = selected; } - private Boolean isSelected() { + public Boolean isSelected() { return selected; } public static EamDbPlatformEnum fromString(String pName) { if (null == pName) { - return SQLITE; + return DISABLED; } for (EamDbPlatformEnum p : EamDbPlatformEnum.values()) { @@ -70,14 +73,14 @@ public enum EamDbPlatformEnum { return p; } } - return SQLITE; + return DISABLED; } /** * Save the selected platform to the config file. */ public static void saveSelectedPlatform() { - EamDbPlatformEnum selectedPlatform = SQLITE; + EamDbPlatformEnum selectedPlatform = DISABLED; for (EamDbPlatformEnum p : EamDbPlatformEnum.values()) { if (p.isSelected()) { selectedPlatform = p; @@ -103,7 +106,7 @@ public enum EamDbPlatformEnum { * Get the selected platform. * * @return The selected platform, or if not platform is selected, default to - * SQLITE. + * DISABLED. */ public static EamDbPlatformEnum getSelectedPlatform() { for (EamDbPlatformEnum p : EamDbPlatformEnum.values()) { @@ -111,6 +114,6 @@ public enum EamDbPlatformEnum { return p; } } - return SQLITE; + return DISABLED; } } diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/Bundle.properties b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/Bundle.properties index 1b1cb090cf..8811aa8c49 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/Bundle.properties +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/Bundle.properties @@ -13,7 +13,6 @@ EamPostgresSettingsDialog.lbUserPassword.text=User Password : EamPostgresSettingsDialog.lbUserName.text=User Name : EamPostgresSettingsDialog.bnCancel.text=Cancel EamPostgresSettingsDialog.lbPort.text=Port : -EamPostgresSettingsDialog.bnSave.text=Save EamPostgresSettingsDialog.lbHostName.text=Host Name / IP : EamPostgresSettingsDialog.bnTestConnection.text=Test Connection EamPostgresSettingsDialog.lbDatabaseName.text=Database name : @@ -43,14 +42,11 @@ ImportHashDatabaseDialog.bnNewOrganization.text=Add New Organization ImportHashDatabaseDialog.tfDatabaseName.tooltip=Name for this database ImportHashDatabaseDialog.tfDatabaseVersion.tooltip.text=Database Version Number GlobalSettingsPanel.bnImportDatabase.actionCommand= -GlobalSettingsPanel.cbEnableEnterpriseArtifactsManager.text=Enable Enterprise Artifacts Manager GlobalSettingsPanel.bnManageTypes.text=Manage Artifact Types GlobalSettingsPanel.bnManageTags.actionCommand= GlobalSettingsPanel.bnManageTags.toolTipText= GlobalSettingsPanel.bnManageTags.text=Manage Tags GlobalSettingsPanel.tbOops.text= -GlobalSettingsPanel.bnConfigureDatabaseSettings.text=Configure -GlobalSettingsPanel.lbDatabasePlatform.text=Enable Database Platform : GlobalSettingsPanel.lbDatabaseSettings.text=Database Settings GlobalSettingsPanel.bnImportDatabase.label=Import Hash Database AddNewOrganizationDialog.lbPocPhone.text=Phone: @@ -68,3 +64,27 @@ ManageArtifactTypesDialog.okButton.text=OK ManageArtifactTypesDialog.lbWarningMsg.text=Warning Message ManageArtifactTypesDialog.taInstructionsMsg.text=Select one or more artifact types to store in the database and use for correlation during Ingest. EamSqliteSettingsDialog.bnOk.text=OK +EamPostgresSettingsDialog.bnSave.text=Save +EamDbSettingsDialog.pnDatabaseConnectionSettings.border.title=Database Settings +EamDbSettingsDialog.rdioBnPostgreSQL.text=PostgreSQL +EamDbSettingsDialog.rdioBnSQLite.text=SQLite +EamDbSettingsDialog.bnDatabasePathFileOpen.text=Open... +EamDbSettingsDialog.tfDatabasePath.toolTipText=Filename and path to store SQLite db file +EamDbSettingsDialog.tfDatabasePath.text= +EamDbSettingsDialog.lbDatabasePath.text=Database Path : +EamDbSettingsDialog.rdioBnDisabled.text=Disabled +EamDbSettingsDialog.bnCancel.text=Cancel +EamDbSettingsDialog.bnOk.text=OK +EamDbSettingsDialog.bnTest.text=Test +EamDbSettingsDialog.lbHostName.text=Host Name / IP : +EamDbSettingsDialog.lbDatabaseName.text=Database name : +EamDbSettingsDialog.lbUserPassword.text=User Password : +EamDbSettingsDialog.lbUserName.text=User Name : +EamDbSettingsDialog.lbPort.text=Port : +EamDbSettingsDialog.bnCreateDb.text=Create +EamDbSettingsDialog.pnSetupGuidance.border.title=Setup Guidance +GlobalSettingsPanel.pnDatabaseConfiguration.title=Database Configuration +GlobalSettingsPanel.lbDbPlatformTypeLabel.text=Type: +GlobalSettingsPanel.lbDbNameLabel.text=Name: +GlobalSettingsPanel.bnDbConfigure.text=Configure +GlobalSettingsPanel.lbDbLocationLabel.text=Location: diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/EamDbSettingsDialog.form b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/EamDbSettingsDialog.form new file mode 100644 index 0000000000..881f93eac4 --- /dev/null +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/EamDbSettingsDialog.form @@ -0,0 +1,463 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/EamDbSettingsDialog.java b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/EamDbSettingsDialog.java new file mode 100644 index 0000000000..785c1110b6 --- /dev/null +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/EamDbSettingsDialog.java @@ -0,0 +1,716 @@ +/* + * 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.experimental.enterpriseartifactsmanager.optionspanel; + +import java.awt.Color; +import java.awt.Cursor; +import java.awt.Dimension; +import java.awt.Toolkit; +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.logging.Level; +import javax.swing.ImageIcon; +import javax.swing.JDialog; +import javax.swing.JFileChooser; +import javax.swing.JFrame; +import javax.swing.JOptionPane; +import javax.swing.JTextField; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; +import org.netbeans.spi.options.OptionsPanelController; +import org.openide.util.ImageUtilities; +import org.openide.util.NbBundle.Messages; +import org.openide.windows.WindowManager; +import org.sleuthkit.autopsy.corecomponents.TextPrompt; +import org.sleuthkit.autopsy.coreutils.Logger; +import org.sleuthkit.autopsy.experimental.enterpriseartifactsmanager.datamodel.EamDbException; +import org.sleuthkit.autopsy.experimental.enterpriseartifactsmanager.datamodel.EamDbPlatformEnum; +import org.sleuthkit.autopsy.experimental.enterpriseartifactsmanager.datamodel.PostgresEamDbSettings; +import org.sleuthkit.autopsy.experimental.enterpriseartifactsmanager.datamodel.SqliteEamDbSettings; + +/** + * + * @author nick + */ +public class EamDbSettingsDialog extends JDialog { + private static final Logger LOGGER = Logger.getLogger(EamDbSettingsDialog.class.getName()); + private final Collection textBoxes; + private final TextBoxChangedListener textBoxChangedListener; + private final ImageIcon goodIcon; + private final ImageIcon badIcon; + + private PostgresEamDbSettings dbSettingsPostgres; + private SqliteEamDbSettings dbSettingsSqlite; + private Boolean hasChanged; + + /** + * Creates new form EamDbSettingsDialog + */ + @Messages({"EamDbSettingsDialog.title.text=Enterprise Artifacts Manager Settings"}) + public EamDbSettingsDialog() { + super((JFrame) WindowManager.getDefault().getMainWindow(), + Bundle.EamDbSettingsDialog_title_text(), + true); // NON-NLS + + textBoxes = new ArrayList<>(); + textBoxChangedListener = new TextBoxChangedListener(); + goodIcon = new ImageIcon(ImageUtilities.loadImage("org/sleuthkit/autopsy/images/good.png", false)); // NON-NLS + badIcon = new ImageIcon(ImageUtilities.loadImage("org/sleuthkit/autopsy/images/bad.png", false)); // NON-NLS + + initComponents(); + customizeComponents(); + display(); + } + + /** + * 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() { + + bnGrpDatabasePlatforms = new javax.swing.ButtonGroup(); + fcDatabasePath = new javax.swing.JFileChooser(); + pnDatabaseConnectionSettings = new javax.swing.JPanel(); + pnSQLiteSettings = new javax.swing.JPanel(); + lbDatabasePath = new javax.swing.JLabel(); + tfDatabasePath = new javax.swing.JTextField(); + bnDatabasePathFileOpen = new javax.swing.JButton(); + pnPostgreSQLSettings = new javax.swing.JPanel(); + lbHostName = new javax.swing.JLabel(); + lbPort = new javax.swing.JLabel(); + lbUserName = new javax.swing.JLabel(); + lbUserPassword = new javax.swing.JLabel(); + lbDatabaseName = new javax.swing.JLabel(); + tbDbHostname = new javax.swing.JTextField(); + tbDbPort = new javax.swing.JTextField(); + tbDbName = new javax.swing.JTextField(); + tbDbUsername = new javax.swing.JTextField(); + tbDbPassword = new javax.swing.JTextField(); + rdioBnSQLite = new javax.swing.JRadioButton(); + rdioBnPostgreSQL = new javax.swing.JRadioButton(); + rdioBnDisabled = new javax.swing.JRadioButton(); + pnButtons = new javax.swing.JPanel(); + bnCancel = new javax.swing.JButton(); + bnOk = new javax.swing.JButton(); + bnTest = new javax.swing.JButton(); + bnCreateDb = new javax.swing.JButton(); + pnSetupGuidance = new javax.swing.JPanel(); + taSetupGuidance = new javax.swing.JTextArea(); + + setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + + pnDatabaseConnectionSettings.setBorder(javax.swing.BorderFactory.createTitledBorder(null, org.openide.util.NbBundle.getMessage(EamDbSettingsDialog.class, "EamDbSettingsDialog.pnDatabaseConnectionSettings.border.title"), javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("Tahoma", 0, 12))); // NOI18N + pnDatabaseConnectionSettings.setName(""); // NOI18N + + pnSQLiteSettings.setBorder(javax.swing.BorderFactory.createEtchedBorder()); + + org.openide.awt.Mnemonics.setLocalizedText(lbDatabasePath, org.openide.util.NbBundle.getMessage(EamDbSettingsDialog.class, "EamDbSettingsDialog.lbDatabasePath.text")); // NOI18N + + tfDatabasePath.setText(org.openide.util.NbBundle.getMessage(EamDbSettingsDialog.class, "EamDbSettingsDialog.tfDatabasePath.text")); // NOI18N + tfDatabasePath.setToolTipText(org.openide.util.NbBundle.getMessage(EamDbSettingsDialog.class, "EamDbSettingsDialog.tfDatabasePath.toolTipText")); // NOI18N + + org.openide.awt.Mnemonics.setLocalizedText(bnDatabasePathFileOpen, org.openide.util.NbBundle.getMessage(EamDbSettingsDialog.class, "EamDbSettingsDialog.bnDatabasePathFileOpen.text")); // NOI18N + bnDatabasePathFileOpen.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + bnDatabasePathFileOpenActionPerformed(evt); + } + }); + + javax.swing.GroupLayout pnSQLiteSettingsLayout = new javax.swing.GroupLayout(pnSQLiteSettings); + pnSQLiteSettings.setLayout(pnSQLiteSettingsLayout); + pnSQLiteSettingsLayout.setHorizontalGroup( + pnSQLiteSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(pnSQLiteSettingsLayout.createSequentialGroup() + .addContainerGap() + .addComponent(lbDatabasePath) + .addGap(18, 18, 18) + .addComponent(tfDatabasePath, javax.swing.GroupLayout.PREFERRED_SIZE, 343, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(bnDatabasePathFileOpen) + .addContainerGap()) + ); + pnSQLiteSettingsLayout.setVerticalGroup( + pnSQLiteSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(pnSQLiteSettingsLayout.createSequentialGroup() + .addContainerGap() + .addGroup(pnSQLiteSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(lbDatabasePath, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(tfDatabasePath, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(bnDatabasePathFileOpen)) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + + pnPostgreSQLSettings.setBorder(javax.swing.BorderFactory.createEtchedBorder()); + + org.openide.awt.Mnemonics.setLocalizedText(lbHostName, org.openide.util.NbBundle.getMessage(EamDbSettingsDialog.class, "EamDbSettingsDialog.lbHostName.text")); // NOI18N + + org.openide.awt.Mnemonics.setLocalizedText(lbPort, org.openide.util.NbBundle.getMessage(EamDbSettingsDialog.class, "EamDbSettingsDialog.lbPort.text")); // NOI18N + + org.openide.awt.Mnemonics.setLocalizedText(lbUserName, org.openide.util.NbBundle.getMessage(EamDbSettingsDialog.class, "EamDbSettingsDialog.lbUserName.text")); // NOI18N + + org.openide.awt.Mnemonics.setLocalizedText(lbUserPassword, org.openide.util.NbBundle.getMessage(EamDbSettingsDialog.class, "EamDbSettingsDialog.lbUserPassword.text")); // NOI18N + + org.openide.awt.Mnemonics.setLocalizedText(lbDatabaseName, org.openide.util.NbBundle.getMessage(EamDbSettingsDialog.class, "EamDbSettingsDialog.lbDatabaseName.text")); // NOI18N + + javax.swing.GroupLayout pnPostgreSQLSettingsLayout = new javax.swing.GroupLayout(pnPostgreSQLSettings); + pnPostgreSQLSettings.setLayout(pnPostgreSQLSettingsLayout); + pnPostgreSQLSettingsLayout.setHorizontalGroup( + pnPostgreSQLSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(pnPostgreSQLSettingsLayout.createSequentialGroup() + .addContainerGap() + .addGroup(pnPostgreSQLSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(lbHostName) + .addComponent(lbPort) + .addComponent(lbDatabaseName) + .addComponent(lbUserName) + .addComponent(lbUserPassword)) + .addGap(18, 18, 18) + .addGroup(pnPostgreSQLSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addComponent(tbDbPassword, javax.swing.GroupLayout.DEFAULT_SIZE, 439, Short.MAX_VALUE) + .addComponent(tbDbUsername) + .addComponent(tbDbName) + .addComponent(tbDbPort) + .addComponent(tbDbHostname)) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + pnPostgreSQLSettingsLayout.setVerticalGroup( + pnPostgreSQLSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(pnPostgreSQLSettingsLayout.createSequentialGroup() + .addContainerGap() + .addGroup(pnPostgreSQLSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(tbDbHostname, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(lbHostName, javax.swing.GroupLayout.PREFERRED_SIZE, 22, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(pnPostgreSQLSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addComponent(tbDbPort) + .addComponent(lbPort, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(pnPostgreSQLSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addComponent(tbDbName) + .addComponent(lbDatabaseName, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(pnPostgreSQLSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addComponent(tbDbUsername) + .addComponent(lbUserName, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(pnPostgreSQLSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .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)) + .addContainerGap(19, Short.MAX_VALUE)) + ); + + org.openide.awt.Mnemonics.setLocalizedText(rdioBnSQLite, org.openide.util.NbBundle.getMessage(EamDbSettingsDialog.class, "EamDbSettingsDialog.rdioBnSQLite.text")); // NOI18N + rdioBnSQLite.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + rdioBnSQLiteActionPerformed(evt); + } + }); + + org.openide.awt.Mnemonics.setLocalizedText(rdioBnPostgreSQL, org.openide.util.NbBundle.getMessage(EamDbSettingsDialog.class, "EamDbSettingsDialog.rdioBnPostgreSQL.text")); // NOI18N + rdioBnPostgreSQL.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + rdioBnPostgreSQLActionPerformed(evt); + } + }); + + org.openide.awt.Mnemonics.setLocalizedText(rdioBnDisabled, org.openide.util.NbBundle.getMessage(EamDbSettingsDialog.class, "EamDbSettingsDialog.rdioBnDisabled.text")); // NOI18N + rdioBnDisabled.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + rdioBnDisabledActionPerformed(evt); + } + }); + + javax.swing.GroupLayout pnDatabaseConnectionSettingsLayout = new javax.swing.GroupLayout(pnDatabaseConnectionSettings); + pnDatabaseConnectionSettings.setLayout(pnDatabaseConnectionSettingsLayout); + pnDatabaseConnectionSettingsLayout.setHorizontalGroup( + pnDatabaseConnectionSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(pnDatabaseConnectionSettingsLayout.createSequentialGroup() + .addComponent(rdioBnPostgreSQL) + .addGap(0, 0, Short.MAX_VALUE)) + .addGroup(pnDatabaseConnectionSettingsLayout.createSequentialGroup() + .addGroup(pnDatabaseConnectionSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(rdioBnSQLite) + .addComponent(rdioBnDisabled)) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addGroup(pnDatabaseConnectionSettingsLayout.createSequentialGroup() + .addContainerGap() + .addGroup(pnDatabaseConnectionSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(pnSQLiteSettings, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(pnPostgreSQLSettings, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))) + ); + pnDatabaseConnectionSettingsLayout.setVerticalGroup( + pnDatabaseConnectionSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, pnDatabaseConnectionSettingsLayout.createSequentialGroup() + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(rdioBnDisabled) + .addGap(13, 13, 13) + .addComponent(rdioBnSQLite) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(pnSQLiteSettings, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(12, 12, 12) + .addComponent(rdioBnPostgreSQL) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(pnPostgreSQLSettings, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(329, 329, 329)) + ); + + org.openide.awt.Mnemonics.setLocalizedText(bnCancel, org.openide.util.NbBundle.getMessage(EamDbSettingsDialog.class, "EamDbSettingsDialog.bnCancel.text")); // NOI18N + bnCancel.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + bnCancelActionPerformed(evt); + } + }); + + org.openide.awt.Mnemonics.setLocalizedText(bnOk, org.openide.util.NbBundle.getMessage(EamDbSettingsDialog.class, "EamDbSettingsDialog.bnOk.text")); // NOI18N + bnOk.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + bnOkActionPerformed(evt); + } + }); + + org.openide.awt.Mnemonics.setLocalizedText(bnTest, org.openide.util.NbBundle.getMessage(EamDbSettingsDialog.class, "EamDbSettingsDialog.bnTest.text")); // NOI18N + bnTest.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + bnTestActionPerformed(evt); + } + }); + + org.openide.awt.Mnemonics.setLocalizedText(bnCreateDb, org.openide.util.NbBundle.getMessage(EamDbSettingsDialog.class, "EamDbSettingsDialog.bnCreateDb.text")); // NOI18N + bnCreateDb.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + bnCreateDbActionPerformed(evt); + } + }); + + javax.swing.GroupLayout pnButtonsLayout = new javax.swing.GroupLayout(pnButtons); + pnButtons.setLayout(pnButtonsLayout); + pnButtonsLayout.setHorizontalGroup( + pnButtonsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(pnButtonsLayout.createSequentialGroup() + .addContainerGap() + .addComponent(bnTest) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(bnCreateDb) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(bnOk) + .addGap(11, 11, 11) + .addComponent(bnCancel) + .addContainerGap()) + ); + pnButtonsLayout.setVerticalGroup( + pnButtonsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(pnButtonsLayout.createSequentialGroup() + .addGap(0, 0, 0) + .addGroup(pnButtonsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(bnOk) + .addComponent(bnCancel) + .addComponent(bnTest) + .addComponent(bnCreateDb)) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + + pnSetupGuidance.setBorder(javax.swing.BorderFactory.createTitledBorder(null, org.openide.util.NbBundle.getMessage(EamDbSettingsDialog.class, "EamDbSettingsDialog.pnSetupGuidance.border.title"), javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("Tahoma", 0, 12))); // NOI18N + + taSetupGuidance.setEditable(false); + taSetupGuidance.setBackground(new java.awt.Color(240, 240, 240)); + taSetupGuidance.setColumns(20); + taSetupGuidance.setFont(new java.awt.Font("Monospaced", 0, 12)); // NOI18N + taSetupGuidance.setForeground(new java.awt.Color(255, 102, 102)); + taSetupGuidance.setLineWrap(true); + taSetupGuidance.setRows(3); + taSetupGuidance.setTabSize(4); + taSetupGuidance.setWrapStyleWord(true); + taSetupGuidance.setAutoscrolls(false); + taSetupGuidance.setBorder(null); + taSetupGuidance.setRequestFocusEnabled(false); + taSetupGuidance.setVerifyInputWhenFocusTarget(false); + + javax.swing.GroupLayout pnSetupGuidanceLayout = new javax.swing.GroupLayout(pnSetupGuidance); + pnSetupGuidance.setLayout(pnSetupGuidanceLayout); + pnSetupGuidanceLayout.setHorizontalGroup( + pnSetupGuidanceLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(pnSetupGuidanceLayout.createSequentialGroup() + .addContainerGap() + .addComponent(taSetupGuidance) + .addContainerGap()) + ); + pnSetupGuidanceLayout.setVerticalGroup( + pnSetupGuidanceLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, pnSetupGuidanceLayout.createSequentialGroup() + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(taSetupGuidance, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); + getContentPane().setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(pnSetupGuidance, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(pnDatabaseConnectionSettings, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(pnButtons, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addContainerGap()) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addComponent(pnSetupGuidance, 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) + .addComponent(pnDatabaseConnectionSettings, javax.swing.GroupLayout.PREFERRED_SIZE, 348, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(pnButtons, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(0, 0, 0)) + ); + + pack(); + }// //GEN-END:initComponents + + private void customizeComponents() { + setTextPrompts(); + setTextBoxListeners(); + + bnGrpDatabasePlatforms.add(rdioBnDisabled); + bnGrpDatabasePlatforms.add(rdioBnPostgreSQL); + bnGrpDatabasePlatforms.add(rdioBnSQLite); + + EamDbPlatformEnum selectedPlatform = EamDbPlatformEnum.getSelectedPlatform(); + switch (selectedPlatform) { + case POSTGRESQL: + rdioBnPostgreSQL.setSelected(true); + break; + case SQLITE: + rdioBnSQLite.setSelected(true); + break; + default: + rdioBnDisabled.setSelected(true); + } + + } + + private void display() { + Dimension screenDimension = Toolkit.getDefaultToolkit().getScreenSize(); + setLocation((screenDimension.width - getSize().width) / 2, (screenDimension.height - getSize().height) / 2); + setVisible(true); + } + + private void bnDatabasePathFileOpenActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnDatabasePathFileOpenActionPerformed +// fcDatabasePath.setCurrentDirectory(new File(dbSettings.getDbDirectory())); +// fcDatabasePath.setSelectedFile(new File(dbSettings.getFileNameWithPath())); + if (fcDatabasePath.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) { + File databaseFile = fcDatabasePath.getSelectedFile(); + try { + tfDatabasePath.setText(databaseFile.getCanonicalPath()); + valid(); + // TODO: create the db/schema if it doesn't exist. + // TODO: set variable noting that we created a new db, so it can be removed if Cancel button is clicked. + + } catch (IOException ex) { + LOGGER.log(Level.SEVERE, "Failed to get path of selected database file", ex); // NON-NLS + JOptionPane.showMessageDialog(this, Bundle.EnterpriseArtifactsManagerSQLiteSettingsDialog_chooserPath_failedToGetDbPathMsg()); + } + } + }//GEN-LAST:event_bnDatabasePathFileOpenActionPerformed + + private void bnTestActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnTestActionPerformed +// lbTestDatabase.setIcon(null); +// lbTestDatabase.setText(""); +// setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); +// +// if (dbSettings.testSettings()) { +// lbTestDatabase.setIcon(goodIcon); +// } else { +// lbTestDatabase.setIcon(badIcon); +// } + +// setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); + }//GEN-LAST:event_bnTestActionPerformed + + private void bnCreateDbActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnCreateDbActionPerformed + // TODO add your handling code here: + }//GEN-LAST:event_bnCreateDbActionPerformed + + private void bnOkActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnOkActionPerformed + hasChanged = true; +// dbSettings.setEnabled(true); +// dbSettings.saveSettings(); + dispose(); + }//GEN-LAST:event_bnOkActionPerformed + + private void bnCancelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnCancelActionPerformed + dispose(); + }//GEN-LAST:event_bnCancelActionPerformed + + private void rdioBnDisabledActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_rdioBnDisabledActionPerformed + String text = taSetupGuidance.getText(); + if (rdioBnDisabled.isSelected()) { + taSetupGuidance.setText((text + ",selected Disabled")); + } else { + taSetupGuidance.setText((text + ",de-selected Disabled")); + } + }//GEN-LAST:event_rdioBnDisabledActionPerformed + + private void rdioBnSQLiteActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_rdioBnSQLiteActionPerformed + String text = taSetupGuidance.getText(); + if (rdioBnSQLite.isSelected()) { + taSetupGuidance.setText((text + ",selected SQLite")); + } else { + taSetupGuidance.setText((text + ",de-selected SQLite")); + } + }//GEN-LAST:event_rdioBnSQLiteActionPerformed + + private void rdioBnPostgreSQLActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_rdioBnPostgreSQLActionPerformed + String text = taSetupGuidance.getText(); + if (rdioBnPostgreSQL.isSelected()) { + taSetupGuidance.setText((text + ",selected PostgreSQL")); + } else { + taSetupGuidance.setText((text + ",de-selected PostgreSQL")); + } + }//GEN-LAST:event_rdioBnPostgreSQLActionPerformed + + /** + * Add text prompts to all of the text fields. + */ + @Messages({"EamDbSettingsDialog.textPrompt.hostnameOrIP=Hostname or IP Address", + "EamDbSettingsDialog.textPrompt.port=Port Number", + "EamDbSettingsDialog.textPrompt.dbName=Database Name", + "EamDbSettingsDialog.textPrompt.user=Database User", + "EamDbSettingsDialog.textPrompt.password=Database User's Password"}) + private void setTextPrompts() { + Collection textPrompts = new ArrayList<>(); + textPrompts.add(new TextPrompt(Bundle.EamDbSettingsDialog_textPrompt_hostnameOrIP(), tbDbHostname)); + 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_user(), tbDbUsername)); + textPrompts.add(new TextPrompt(Bundle.EamDbSettingsDialog_textPrompt_password(), tbDbPassword)); + configureTextPrompts(textPrompts); + } + + /** + * Set each textbox with a "statusIcon" property enabling the + * DocumentListeners to know which icon to erase when changes are made + */ +// private void setTextBoxStatusIcons() { +// tbDbHostname.getDocument().putProperty("statusIcon", lbTestDatabase); // NON-NLS +// tbDbPort.getDocument().putProperty("statusIcon", lbTestDatabase); // NON-NLS +// tbDbName.getDocument().putProperty("statusIcon", lbTestDatabase); // NON-NLS +// tbDbUsername.getDocument().putProperty("statusIcon", lbTestDatabase); // NON-NLS +// tbDbPassword.getDocument().putProperty("statusIcon", lbTestDatabase); // NON-NLS +// } +// + /** + * Register for notifications when the text boxes get updated. + */ + private void setTextBoxListeners() { + textBoxes.add(tfDatabasePath); + textBoxes.add(tbDbHostname); + textBoxes.add(tbDbPort); + textBoxes.add(tbDbName); + textBoxes.add(tbDbUsername); + textBoxes.add(tbDbPassword); + addDocumentListeners(textBoxes, textBoxChangedListener); + } + + /** + * Sets the foreground color and transparency of a collection of text + * prompts. + * + * @param textPrompts The text prompts to configure. + */ + private static void configureTextPrompts(Collection textPrompts) { + float alpha = 0.9f; // Mostly opaque + for (TextPrompt textPrompt : textPrompts) { + textPrompt.setForeground(Color.LIGHT_GRAY); + textPrompt.changeAlpha(alpha); + } + } + + /** + * Adds a change listener to a collection of text fields. + * + * @param textFields The text fields. + * @param listener The change listener. + */ + private static void addDocumentListeners(Collection textFields, TextBoxChangedListener listener) { + textFields.forEach((textField) -> { + textField.getDocument().addDocumentListener(listener); + }); + } + + /** + * Tests whether or not values have been entered in all of the database + * settings text fields. + * + * @return True or false. + */ + private boolean databaseFieldsArePopulated() { + return !tbDbHostname.getText().trim().isEmpty() + && !tbDbPort.getText().trim().isEmpty() + && !tbDbName.getText().trim().isEmpty() + && !tbDbUsername.getText().trim().isEmpty() + && !tbDbPassword.getText().trim().isEmpty(); + } + + /** + * Tests whether or not all of the settings components are populated. + * + * @return True or false. + */ + @Messages({"EamDbSettingsDialog.validation.incompleteFields=Fill in all values"}) + private boolean checkFields() { + boolean result = true; + + boolean dbPopulated = databaseFieldsArePopulated(); + + if (!dbPopulated) { + // We don't even have everything filled out + result = false; + taSetupGuidance.setText(Bundle.EamDbSettingsDialog_validation_incompleteFields()); + } + return result; + } + + /** + * Tests whether or not the database settings are valid. + * + * @return True or false. + */ + @Messages({"EamDbSettingsDialog.validation.invalidHost=Invalid database hostname.", + "EamDbSettingsDialog.validation.invalidPort=Invalid database port number.", + "EamDbSettingsDialog.validation.invalidDbName=Invalid database name.", + "EamDbSettingsDialog.validation.invalidDbUser=Invalid database username.", + "EamDbSettingsDialog.validation.invalidDbPassword=Invalid database password.",}) + private boolean databaseSettingsAreValid() { +/* + try { + dbSettings.setHost(tbDbHostname.getText().trim()); + } catch (EamDbException ex) { + taSetupGuidance.setText(Bundle.EamDbSettingsDialog_validation_invalidHost()); + return false; + } + + try { + dbSettings.setPort(Integer.valueOf(tbDbPort.getText().trim())); + } catch (NumberFormatException | EamDbException ex) { + taSetupGuidance.setText(Bundle.EamDbSettingsDialog_validation_invalidPort()); + return false; + } + + try { + dbSettings.setDbName(tbDbName.getText().trim()); + } catch (EamDbException ex) { + taSetupGuidance.setText(Bundle.EamDbSettingsDialog_validation_invalidDbName()); + return false; + } + + try { + dbSettings.setUserName(tbDbUsername.getText().trim()); + } catch (EamDbException ex) { + taSetupGuidance.setText(Bundle.EamDbSettingsDialog_validation_invalidDbUser()); + return false; + } + + try { + dbSettings.setPassword(tbDbPassword.getText().trim()); + } catch (EamDbException ex) { + taSetupGuidance.setText(Bundle.EamDbSettingsDialog_validation_invalidDbPassword()); + return false; + } +*/ + return true; + } + + /** + * Validates that the form is filled out correctly for our usage. + * + * @return true if it's okay, false otherwise. + */ + public boolean valid() { +// taSetupGuidance.setText(""); +/* + return checkFields() + && enableTestDatabaseButton(databaseSettingsAreValid()) + && enableSaveButton(databaseSettingsAreValid()); +*/ + return true; + } + + /** + * Used to listen for changes in text boxes. It lets the panel know things + * have been updated and that validation needs to happen. + */ + private class TextBoxChangedListener implements DocumentListener { + + @Override + public void changedUpdate(DocumentEvent e) { + Object statusIcon = e.getDocument().getProperty("statusIcon"); // NON-NLS + if (statusIcon != null) { + ((javax.swing.JLabel) statusIcon).setIcon(null); + } + firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); + valid(); + } + + @Override + public void insertUpdate(DocumentEvent e) { + Object statusIcon = e.getDocument().getProperty("statusIcon"); // NON-NLS + if (statusIcon != null) { + ((javax.swing.JLabel) statusIcon).setIcon(null); + } + firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); + valid(); + } + + @Override + public void removeUpdate(DocumentEvent e) { + Object statusIcon = e.getDocument().getProperty("statusIcon"); // NON-NLS + if (statusIcon != null) { + ((javax.swing.JLabel) statusIcon).setIcon(null); + } + firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); + valid(); + } + } + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton bnCancel; + private javax.swing.JButton bnCreateDb; + private javax.swing.JButton bnDatabasePathFileOpen; + private javax.swing.ButtonGroup bnGrpDatabasePlatforms; + private javax.swing.JButton bnOk; + private javax.swing.JButton bnTest; + private javax.swing.JFileChooser fcDatabasePath; + private javax.swing.JLabel lbDatabaseName; + private javax.swing.JLabel lbDatabasePath; + private javax.swing.JLabel lbHostName; + private javax.swing.JLabel lbPort; + private javax.swing.JLabel lbUserName; + private javax.swing.JLabel lbUserPassword; + private javax.swing.JPanel pnButtons; + private javax.swing.JPanel pnDatabaseConnectionSettings; + private javax.swing.JPanel pnPostgreSQLSettings; + private javax.swing.JPanel pnSQLiteSettings; + private javax.swing.JPanel pnSetupGuidance; + private javax.swing.JRadioButton rdioBnDisabled; + private javax.swing.JRadioButton rdioBnPostgreSQL; + private javax.swing.JRadioButton rdioBnSQLite; + private javax.swing.JTextArea taSetupGuidance; + private javax.swing.JTextField tbDbHostname; + private javax.swing.JTextField tbDbName; + private javax.swing.JTextField tbDbPassword; + private javax.swing.JTextField tbDbPort; + private javax.swing.JTextField tbDbUsername; + private javax.swing.JTextField tfDatabasePath; + // End of variables declaration//GEN-END:variables +} diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/GlobalSettingsPanel.form b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/GlobalSettingsPanel.form index 29154fc5ea..f90b07be51 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/GlobalSettingsPanel.form +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/GlobalSettingsPanel.form @@ -19,259 +19,245 @@ - + + + + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/GlobalSettingsPanel.java b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/GlobalSettingsPanel.java index b0a2624224..092bc9966b 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/GlobalSettingsPanel.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/GlobalSettingsPanel.java @@ -21,8 +21,6 @@ package org.sleuthkit.autopsy.experimental.enterpriseartifactsmanager.optionspan import org.sleuthkit.autopsy.coreutils.Logger; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; -import javax.swing.JComboBox; -import javax.swing.JOptionPane; import javax.swing.SwingUtilities; import org.netbeans.spi.options.OptionsPanelController; import org.openide.util.NbBundle.Messages; @@ -32,7 +30,8 @@ import org.sleuthkit.autopsy.events.AutopsyEvent; import org.sleuthkit.autopsy.ingest.IngestManager; import org.sleuthkit.autopsy.ingest.IngestModuleGlobalSettingsPanel; import org.sleuthkit.autopsy.experimental.enterpriseartifactsmanager.datamodel.EamDbPlatformEnum; -import org.sleuthkit.autopsy.experimental.enterpriseartifactsmanager.datamodel.EamDb; +import org.sleuthkit.autopsy.experimental.enterpriseartifactsmanager.datamodel.PostgresEamDbSettings; +import org.sleuthkit.autopsy.experimental.enterpriseartifactsmanager.datamodel.SqliteEamDbSettings; /** * Main settings panel for the enterprise artifacts manager @@ -44,10 +43,6 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i private final IngestJobEventPropertyChangeListener ingestJobEventListener; - private boolean dbConfigured; - private boolean initiallyEnabled; - private boolean comboboxSelectDatabaseTypeActionListenerActive; - /** * Creates new form EnterpriseArtifactsManagerOptionsPanel */ @@ -62,12 +57,6 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i @Messages({"GlobalSettingsPanel.title=Global Enterprise Artifacts Manager Settings"}) private void customizeComponents() { setName(Bundle.GlobalSettingsPanel_title()); - comboboxSelectDatabaseTypeActionListenerActive = false; // don't fire action listener while loading combobox content - comboboxSelectDatabaseType.removeAllItems(); - for (EamDbPlatformEnum p : EamDbPlatformEnum.values()) { - comboboxSelectDatabaseType.addItem(p.toString()); - } - comboboxSelectDatabaseTypeActionListenerActive = true; } private void addIngestJobEventsListener() { @@ -84,22 +73,77 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i // //GEN-BEGIN:initComponents private void initComponents() { - jScrollPane = new javax.swing.JScrollPane(); - pnOverallPanel = new javax.swing.JPanel(); - pnSettings = new javax.swing.JPanel(); + pnDatabaseConfiguration = new javax.swing.JPanel(); + lbDbPlatformTypeLabel = new javax.swing.JLabel(); + lbDbNameLabel = new javax.swing.JLabel(); + lbDbLocationLabel = new javax.swing.JLabel(); + bnDbConfigure = new javax.swing.JButton(); + lbDbPlatformValue = new javax.swing.JLabel(); + lbDbNameValue = new javax.swing.JLabel(); + lbDbLocationValue = new javax.swing.JLabel(); + pnDatabaseContentButtons = new javax.swing.JPanel(); bnImportDatabase = new javax.swing.JButton(); - pnDatabaseConnectionSettings = new javax.swing.JPanel(); - comboboxSelectDatabaseType = new javax.swing.JComboBox<>(); - lbDatabasePlatform = new javax.swing.JLabel(); - bnConfigureDatabaseSettings = new javax.swing.JButton(); - tbOops = new javax.swing.JTextField(); bnManageTags = new javax.swing.JButton(); bnManageTypes = new javax.swing.JButton(); - cbEnableEnterpriseArtifactsManager = new javax.swing.JCheckBox(); + tbOops = new javax.swing.JTextField(); setName(""); // NOI18N - jScrollPane.setBorder(null); + pnDatabaseConfiguration.setBorder(javax.swing.BorderFactory.createTitledBorder(null, org.openide.util.NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.pnDatabaseConfiguration.title"), javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("Tahoma", 0, 12))); // NOI18N + + org.openide.awt.Mnemonics.setLocalizedText(lbDbPlatformTypeLabel, org.openide.util.NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.lbDbPlatformTypeLabel.text")); // NOI18N + + org.openide.awt.Mnemonics.setLocalizedText(lbDbNameLabel, org.openide.util.NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.lbDbNameLabel.text")); // NOI18N + + org.openide.awt.Mnemonics.setLocalizedText(lbDbLocationLabel, org.openide.util.NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.lbDbLocationLabel.text")); // NOI18N + + org.openide.awt.Mnemonics.setLocalizedText(bnDbConfigure, org.openide.util.NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.bnDbConfigure.text")); // NOI18N + bnDbConfigure.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + bnDbConfigureActionPerformed(evt); + } + }); + + javax.swing.GroupLayout pnDatabaseConfigurationLayout = new javax.swing.GroupLayout(pnDatabaseConfiguration); + pnDatabaseConfiguration.setLayout(pnDatabaseConfigurationLayout); + pnDatabaseConfigurationLayout.setHorizontalGroup( + pnDatabaseConfigurationLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(pnDatabaseConfigurationLayout.createSequentialGroup() + .addContainerGap() + .addGroup(pnDatabaseConfigurationLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(pnDatabaseConfigurationLayout.createSequentialGroup() + .addGroup(pnDatabaseConfigurationLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addComponent(lbDbPlatformTypeLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(lbDbNameLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(lbDbLocationLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 57, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(pnDatabaseConfigurationLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(pnDatabaseConfigurationLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(lbDbPlatformValue, javax.swing.GroupLayout.PREFERRED_SIZE, 711, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(lbDbNameValue, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, 711, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(lbDbLocationValue, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, 711, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addComponent(bnDbConfigure)) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + pnDatabaseConfigurationLayout.setVerticalGroup( + pnDatabaseConfigurationLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(pnDatabaseConfigurationLayout.createSequentialGroup() + .addGap(7, 7, 7) + .addGroup(pnDatabaseConfigurationLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addComponent(lbDbPlatformTypeLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(lbDbPlatformValue, javax.swing.GroupLayout.PREFERRED_SIZE, 14, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(pnDatabaseConfigurationLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addComponent(lbDbNameLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(lbDbNameValue, javax.swing.GroupLayout.PREFERRED_SIZE, 14, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(pnDatabaseConfigurationLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addComponent(lbDbLocationLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(lbDbLocationValue, javax.swing.GroupLayout.PREFERRED_SIZE, 14, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 11, Short.MAX_VALUE) + .addComponent(bnDbConfigure) + .addContainerGap()) + ); bnImportDatabase.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/experimental/images/import16.png"))); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(bnImportDatabase, org.openide.util.NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.bnImportDatabase.label")); // NOI18N @@ -110,54 +154,6 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i } }); - pnDatabaseConnectionSettings.setBorder(javax.swing.BorderFactory.createTitledBorder(null, org.openide.util.NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.lbDatabaseSettings.text"), javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("Tahoma", 0, 12))); // NOI18N - pnDatabaseConnectionSettings.setName(""); // NOI18N - - comboboxSelectDatabaseType.setModel(new javax.swing.DefaultComboBoxModel<>(new String[] { "test 1", "test 2" })); - comboboxSelectDatabaseType.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - comboboxSelectDatabaseTypeActionPerformed(evt); - } - }); - - org.openide.awt.Mnemonics.setLocalizedText(lbDatabasePlatform, org.openide.util.NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.lbDatabasePlatform.text")); // NOI18N - - org.openide.awt.Mnemonics.setLocalizedText(bnConfigureDatabaseSettings, org.openide.util.NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.bnConfigureDatabaseSettings.text")); // NOI18N - bnConfigureDatabaseSettings.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - bnConfigureDatabaseSettingsActionPerformed(evt); - } - }); - - javax.swing.GroupLayout pnDatabaseConnectionSettingsLayout = new javax.swing.GroupLayout(pnDatabaseConnectionSettings); - pnDatabaseConnectionSettings.setLayout(pnDatabaseConnectionSettingsLayout); - pnDatabaseConnectionSettingsLayout.setHorizontalGroup( - pnDatabaseConnectionSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, pnDatabaseConnectionSettingsLayout.createSequentialGroup() - .addContainerGap() - .addComponent(lbDatabasePlatform) - .addGap(18, 18, 18) - .addComponent(comboboxSelectDatabaseType, javax.swing.GroupLayout.PREFERRED_SIZE, 79, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(bnConfigureDatabaseSettings) - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - ); - pnDatabaseConnectionSettingsLayout.setVerticalGroup( - pnDatabaseConnectionSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(pnDatabaseConnectionSettingsLayout.createSequentialGroup() - .addGap(3, 3, 3) - .addGroup(pnDatabaseConnectionSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(lbDatabasePlatform, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(comboboxSelectDatabaseType, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(bnConfigureDatabaseSettings))) - ); - - tbOops.setEditable(false); - tbOops.setFont(tbOops.getFont().deriveFont(tbOops.getFont().getStyle() | java.awt.Font.BOLD, 12)); - tbOops.setForeground(new java.awt.Color(255, 0, 0)); - tbOops.setText(org.openide.util.NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.tbOops.text")); // NOI18N - tbOops.setBorder(null); - org.openide.awt.Mnemonics.setLocalizedText(bnManageTags, org.openide.util.NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.bnManageTags.text")); // NOI18N bnManageTags.setToolTipText(org.openide.util.NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.bnManageTags.toolTipText")); // NOI18N bnManageTags.setActionCommand(org.openide.util.NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.bnManageTags.actionCommand")); // NOI18N @@ -174,229 +170,139 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i } }); - javax.swing.GroupLayout pnSettingsLayout = new javax.swing.GroupLayout(pnSettings); - pnSettings.setLayout(pnSettingsLayout); - pnSettingsLayout.setHorizontalGroup( - pnSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(pnSettingsLayout.createSequentialGroup() + javax.swing.GroupLayout pnDatabaseContentButtonsLayout = new javax.swing.GroupLayout(pnDatabaseContentButtons); + pnDatabaseContentButtons.setLayout(pnDatabaseContentButtonsLayout); + pnDatabaseContentButtonsLayout.setHorizontalGroup( + pnDatabaseContentButtonsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, pnDatabaseContentButtonsLayout.createSequentialGroup() .addContainerGap() - .addGroup(pnSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(tbOops) - .addGroup(pnSettingsLayout.createSequentialGroup() - .addGroup(pnSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(pnDatabaseConnectionSettings, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGroup(pnSettingsLayout.createSequentialGroup() - .addComponent(bnImportDatabase) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(bnManageTags) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(bnManageTypes))) - .addGap(0, 188, Short.MAX_VALUE))) - .addContainerGap()) - ); - pnSettingsLayout.setVerticalGroup( - pnSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, pnSettingsLayout.createSequentialGroup() - .addGap(8, 8, 8) - .addComponent(tbOops, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(bnImportDatabase) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(pnDatabaseConnectionSettings, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 33, Short.MAX_VALUE) - .addGroup(pnSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(bnManageTags) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(bnManageTypes) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + pnDatabaseContentButtonsLayout.setVerticalGroup( + pnDatabaseContentButtonsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, pnDatabaseContentButtonsLayout.createSequentialGroup() + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGroup(pnDatabaseContentButtonsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(bnImportDatabase) .addComponent(bnManageTags, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(bnManageTypes, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE)) .addGap(34, 34, 34)) ); - cbEnableEnterpriseArtifactsManager.setFont(cbEnableEnterpriseArtifactsManager.getFont().deriveFont(cbEnableEnterpriseArtifactsManager.getFont().getStyle() & ~java.awt.Font.BOLD, 11)); - org.openide.awt.Mnemonics.setLocalizedText(cbEnableEnterpriseArtifactsManager, org.openide.util.NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.cbEnableEnterpriseArtifactsManager.text")); // NOI18N - cbEnableEnterpriseArtifactsManager.addItemListener(new java.awt.event.ItemListener() { - public void itemStateChanged(java.awt.event.ItemEvent evt) { - cbEnableEnterpriseArtifactsManagerItemStateChanged(evt); - } - }); - - javax.swing.GroupLayout pnOverallPanelLayout = new javax.swing.GroupLayout(pnOverallPanel); - pnOverallPanel.setLayout(pnOverallPanelLayout); - pnOverallPanelLayout.setHorizontalGroup( - pnOverallPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(pnOverallPanelLayout.createSequentialGroup() - .addContainerGap() - .addGroup(pnOverallPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(pnOverallPanelLayout.createSequentialGroup() - .addComponent(cbEnableEnterpriseArtifactsManager, javax.swing.GroupLayout.PREFERRED_SIZE, 215, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGap(0, 0, Short.MAX_VALUE)) - .addComponent(pnSettings, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))) - ); - pnOverallPanelLayout.setVerticalGroup( - pnOverallPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, pnOverallPanelLayout.createSequentialGroup() - .addComponent(cbEnableEnterpriseArtifactsManager) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(pnSettings, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - ); - - jScrollPane.setViewportView(pnOverallPanel); + tbOops.setEditable(false); + tbOops.setFont(tbOops.getFont().deriveFont(tbOops.getFont().getStyle() | java.awt.Font.BOLD, 12)); + tbOops.setForeground(new java.awt.Color(255, 0, 0)); + tbOops.setText(org.openide.util.NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.tbOops.text")); // NOI18N + tbOops.setBorder(null); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(jScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGroup(layout.createSequentialGroup() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addComponent(pnDatabaseConfiguration, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addGroup(layout.createSequentialGroup() + .addGap(20, 20, 20) + .addComponent(pnDatabaseContentButtons, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))) + .addContainerGap()) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addGap(15, 15, 15) + .addComponent(tbOops, javax.swing.GroupLayout.DEFAULT_SIZE, 805, Short.MAX_VALUE) + .addContainerGap())) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addComponent(jScrollPane) - .addGap(2, 2, 2)) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addContainerGap() + .addComponent(pnDatabaseConfiguration, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 178, Short.MAX_VALUE) + .addComponent(pnDatabaseContentButtons, javax.swing.GroupLayout.PREFERRED_SIZE, 50, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(22, 22, 22)) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addGap(287, 287, 287) + .addComponent(tbOops, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap(89, Short.MAX_VALUE))) ); }// //GEN-END:initComponents - private void cbEnableEnterpriseArtifactsManagerItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_cbEnableEnterpriseArtifactsManagerItemStateChanged - tbOops.setText(""); - if (!cbEnableEnterpriseArtifactsManager.isSelected()) { - enableAllSubComponents(false); - firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); - } else { - enableDatabaseSubComponents(true); - validateDatabaseSettings(); - } - }//GEN-LAST:event_cbEnableEnterpriseArtifactsManagerItemStateChanged - private void bnImportDatabaseActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnImportDatabaseActionPerformed ImportHashDatabaseDialog dialog = new ImportHashDatabaseDialog(); firePropertyChange(OptionsPanelController.PROP_VALID, null, null); }//GEN-LAST:event_bnImportDatabaseActionPerformed - /** - * When the "Configure" button is clicked, open the proper dialog. - * - * @param evt Button event - */ - @Messages({"GlobalSettingsPanel.configureButton.errorLabel=You must select a valid platform in the drop down box.", - "GlobalSettingsPanel.configureButton.errorTitle=Invalid platform selection."}) - private void bnConfigureDatabaseSettingsActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnConfigureDatabaseSettingsActionPerformed - EamDbPlatformEnum selectedPlatform = EamDbPlatformEnum.getSelectedPlatform(); - Boolean dbConfigChanged = false; - - switch (selectedPlatform) { - case SQLITE: - EamSqliteSettingsDialog dialogS = new EamSqliteSettingsDialog(); - dbConfigChanged = dialogS.isChanged(); - break; - - case POSTGRESQL: - EamPostgresSettingsDialog dialogP = new EamPostgresSettingsDialog(); - dbConfigChanged = dialogP.isChanged(); - break; - - default: - JOptionPane.showMessageDialog(null, Bundle.GlobalSettingsPanel_configureButton_errorLabel(), - Bundle.GlobalSettingsPanel_configureButton_errorTitle(), - JOptionPane.ERROR_MESSAGE); - break; - } - - if (dbConfigChanged) { - if (initiallyEnabled || dbConfigured) { - enableButtonSubComponents(false); - } - dbConfigured = true; - firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); - } - }//GEN-LAST:event_bnConfigureDatabaseSettingsActionPerformed - - /** - * When there is a change to the combobox, update the selectedPlatform. - * - * @param evt - */ - @SuppressWarnings({"unchecked cast", "unchecked"}) - private void comboboxSelectDatabaseTypeActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_comboboxSelectDatabaseTypeActionPerformed - if (comboboxSelectDatabaseTypeActionListenerActive) { - JComboBox cb = (JComboBox) evt.getSource(); - String platformName = (String) cb.getSelectedItem(); - EamDbPlatformEnum.setSelectedPlatform(platformName); - } - }//GEN-LAST:event_comboboxSelectDatabaseTypeActionPerformed - private void bnManageTagsActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnManageTagsActionPerformed ManageTagsDialog dialog = new ManageTagsDialog(); firePropertyChange(OptionsPanelController.PROP_VALID, null, null); }//GEN-LAST:event_bnManageTagsActionPerformed private void bnManageTypesActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnManageTypesActionPerformed - ManageArtifactTypesDialog dialogT = new ManageArtifactTypesDialog(); + ManageArtifactTypesDialog dialog = new ManageArtifactTypesDialog(); firePropertyChange(OptionsPanelController.PROP_VALID, null, null); }//GEN-LAST:event_bnManageTypesActionPerformed + private void bnDbConfigureActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnDbConfigureActionPerformed + EamDbSettingsDialog dialog = new EamDbSettingsDialog(); + firePropertyChange(OptionsPanelController.PROP_VALID, null, null); + }//GEN-LAST:event_bnDbConfigureActionPerformed + @Override public void load() { tbOops.setText(""); enableAllSubComponents(false); - - initiallyEnabled = Boolean.valueOf(ModuleSettings.getConfigSetting("EnterpriseArtifactsManager", "db.enabled")); // NON-NLS - cbEnableEnterpriseArtifactsManager.setSelected(initiallyEnabled); // NON-NLS - String selectedPlatformString = ModuleSettings.getConfigSetting("EnterpriseArtifactsManager", "db.selectedPlatform"); // NON-NLS - dbConfigured = selectedPlatformString != null; - - if (dbConfigured) { - comboboxSelectDatabaseTypeActionListenerActive = false; // don't fire action listener while configuring combobox content - comboboxSelectDatabaseType.setSelectedIndex(EamDbPlatformEnum.getSelectedPlatform().ordinal()); - comboboxSelectDatabaseTypeActionListenerActive = true; // don't fire action listener while loading combobox content - } - if (this.valid() && initiallyEnabled) { - enableButtonSubComponents(true); + EamDbPlatformEnum selectedPlatform = EamDbPlatformEnum.getSelectedPlatform(); + + switch (selectedPlatform) { + case POSTGRESQL: + PostgresEamDbSettings dbSettingsPg = new PostgresEamDbSettings(); + lbDbPlatformValue.setText(EamDbPlatformEnum.POSTGRESQL.toString()); + lbDbNameValue.setText(dbSettingsPg.getDbName()); + lbDbLocationValue.setText(dbSettingsPg.getHost()); + break; + case SQLITE: + SqliteEamDbSettings dbSettingsSqlite = new SqliteEamDbSettings(); + lbDbPlatformValue.setText(EamDbPlatformEnum.SQLITE.toString()); + lbDbNameValue.setText(dbSettingsSqlite.getDbName()); + lbDbLocationValue.setText(dbSettingsSqlite.getDbDirectory()); + break; + default: + lbDbPlatformValue.setText(""); + lbDbNameValue.setText(""); + lbDbLocationValue.setText(""); + break; } + this.ingestStateUpdated(); } @Override public void store() { // Click OK or Apply on Options Panel - saveSettings(); } /** - * Validates that the form is filled out correctly for our usage. + * Validates that the dialog/panel is filled out correctly for our usage. * * @return true if it's okay, false otherwise. */ - boolean valid() { + public boolean valid() { tbOops.setText(""); + Boolean enabled = Boolean.valueOf(ModuleSettings.getConfigSetting("EnterpriseArtifactsManager", "db.enabled")); // NON-NLS - if (cbEnableEnterpriseArtifactsManager.isSelected()) { - return validateDatabaseSettings(); - } else { - return true; - } - } - - /** - * Validate the Database Settings panel - * - * @return true or false - */ - @Messages({"GlobalSettingsPanel.validate.mustConfigureDb.text=You must configure the database."}) - private boolean validateDatabaseSettings() { - if (!dbConfigured) { - tbOops.setText(Bundle.GlobalSettingsPanel_validate_mustConfigureDb_text()); - return false; - } - - return true; + return enabled && EamDbPlatformEnum.getSelectedPlatform() != EamDbPlatformEnum.DISABLED; } @Override public void saveSettings() { // Click OK on Global Settings Panel - ModuleSettings.setConfigSetting("EnterpriseArtifactsManager", "db.enabled", Boolean.toString(cbEnableEnterpriseArtifactsManager.isSelected())); // NON-NLS - if (cbEnableEnterpriseArtifactsManager.isSelected()) { - EamDbPlatformEnum.saveSelectedPlatform(); - EamDb dbManager = EamDb.getInstance(); - dbManager.updateSettings(); - enableButtonSubComponents(true); - } } @Override @@ -426,7 +332,8 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i } }; - @Messages({"GlobalSettingsPanel.validationErrMsg.ingestRunning=Cannot change settings while ingest is running."}) + @Messages({"GlobalSettingsPanel.validationErrMsg.ingestRunning=Cannot change settings while ingest is running.", + "GlobalSettingsPanel.validationerrMsg.mustConfigure=You must configure the database."}) private void ingestStateUpdated() { if (!SwingUtilities.isEventDispatchThread()) { SwingUtilities.invokeLater(() -> { @@ -437,13 +344,16 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i } if (IngestManager.getInstance().isIngestRunning()) { - cbEnableEnterpriseArtifactsManager.setEnabled(false); tbOops.setText(Bundle.GlobalSettingsPanel_validationErrMsg_ingestRunning()); enableAllSubComponents(false); } else { - cbEnableEnterpriseArtifactsManager.setEnabled(true); tbOops.setText(""); - enableAllSubComponents(cbEnableEnterpriseArtifactsManager.isSelected()); + if (valid()) { + enableAllSubComponents(true); + } else { + enableDatabaseConfigureButton(true); + tbOops.setText(Bundle.GlobalSettingsPanel_validationerrMsg_mustConfigure()); + } } } @@ -456,22 +366,20 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i * @return True */ private boolean enableAllSubComponents(Boolean enable) { - enableDatabaseSubComponents(enable); + enableDatabaseConfigureButton(enable); enableButtonSubComponents(enable); return true; } /** - * Wrapper around each of the enableXYZ methods that configure the database - * to enable/disable them all at the same time. + * Enable the Configure button * * @param enable * * @return True */ - private boolean enableDatabaseSubComponents(Boolean enable) { - enableDatabasePlatformComboBox(enable); - enableConfigureDatabasePlatformButton(enable); + private boolean enableDatabaseConfigureButton(Boolean enable) { + bnDbConfigure.setEnabled(enable); return true; } @@ -484,84 +392,25 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i * @return True */ private boolean enableButtonSubComponents(Boolean enable) { - enableManageCorrelationTypesButton(enable); - enableImportGloballyKnownArtifactsButton(enable); - enableManageTagsButton(enable); + bnManageTypes.setEnabled(enable); + bnImportDatabase.setEnabled(enable); + bnManageTags.setEnabled(enable); return true; } - /** - * Enables the ComboBox used to select the database platform. - * - * @param enable - * - * @return True or False - */ - private boolean enableDatabasePlatformComboBox(Boolean enable) { - comboboxSelectDatabaseType.setEnabled(enable); - return enable; - } - - /** - * Enables the "Configure" button used to configure the database platform. - * - * @param enable - * - * @return True or False - */ - private boolean enableConfigureDatabasePlatformButton(Boolean enable) { - bnConfigureDatabaseSettings.setEnabled(enable); - return enable; - } - - /** - * Enables the "Import Globally Known Artifacts" button. - * - * @param enable - * - * @return True or False - */ - private boolean enableImportGloballyKnownArtifactsButton(Boolean enable) { - bnImportDatabase.setEnabled(enable); - return enable; - } - - /** - * Enables the "Manage Artifact Types" button. - * - * @param enable - * - * @return True or False - */ - private boolean enableManageCorrelationTypesButton(Boolean enable) { - bnManageTypes.setEnabled(enable); - return enable; - } - - /** - * Enables the "Manage Tags" button. - * - * @param enable - * - * @return True or False - */ - private boolean enableManageTagsButton(Boolean enable) { - bnManageTags.setEnabled(enable); - return enable; - } - // Variables declaration - do not modify//GEN-BEGIN:variables - private javax.swing.JButton bnConfigureDatabaseSettings; + private javax.swing.JButton bnDbConfigure; private javax.swing.JButton bnImportDatabase; private javax.swing.JButton bnManageTags; private javax.swing.JButton bnManageTypes; - private javax.swing.JCheckBox cbEnableEnterpriseArtifactsManager; - private javax.swing.JComboBox comboboxSelectDatabaseType; - private javax.swing.JScrollPane jScrollPane; - private javax.swing.JLabel lbDatabasePlatform; - private javax.swing.JPanel pnDatabaseConnectionSettings; - private javax.swing.JPanel pnOverallPanel; - private javax.swing.JPanel pnSettings; + private javax.swing.JLabel lbDbLocationLabel; + private javax.swing.JLabel lbDbLocationValue; + private javax.swing.JLabel lbDbNameLabel; + private javax.swing.JLabel lbDbNameValue; + private javax.swing.JLabel lbDbPlatformTypeLabel; + private javax.swing.JLabel lbDbPlatformValue; + private javax.swing.JPanel pnDatabaseConfiguration; + private javax.swing.JPanel pnDatabaseContentButtons; private javax.swing.JTextField tbOops; // End of variables declaration//GEN-END:variables } From e741d0169a4726ba619bf5e06c0e0ba14d204351 Mon Sep 17 00:00:00 2001 From: millmanorama Date: Sat, 17 Jun 2017 10:43:15 +0200 Subject: [PATCH 06/20] format and obvious cleanup --- .../autopsy/datamodel/KeywordHits.java | 179 ++++++++++-------- 1 file changed, 101 insertions(+), 78 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/KeywordHits.java b/Core/src/org/sleuthkit/autopsy/datamodel/KeywordHits.java index 0d34d62fdd..d3585e9c7f 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/KeywordHits.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/KeywordHits.java @@ -1,15 +1,15 @@ /* * Autopsy Forensic Browser - * - * Copyright 2011-2016 Basis Technology Corp. + * + * Copyright 2011-2017 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. @@ -33,6 +33,7 @@ import java.util.Observable; import java.util.Observer; import java.util.Set; import java.util.logging.Level; +import org.apache.commons.lang3.StringUtils; import org.openide.nodes.ChildFactory; import org.openide.nodes.Children; import org.openide.nodes.Node; @@ -68,18 +69,18 @@ public class KeywordHits implements AutopsyVisitableItem { // String used in the instance MAP so that exact matches and substring can fit into the same // data structure as regexps, even though they don't use instances. private final String DEFAULT_INSTANCE_NAME = "DEFAULT_INSTANCE_NAME"; - + public KeywordHits(SleuthkitCase skCase) { this.skCase = skCase; keywordResults = new KeywordResults(); } - - /* All of these maps and code assume the following: - * Regexps will have an 'instance' layer that shows the specific words that matched the regexp - * Exact match and substring will not have the instance layer and instead will have the specific hits - * below their term. - */ + /* + * All of these maps and code assume the following: Regexps will have an + * 'instance' layer that shows the specific words that matched the regexp + * Exact match and substring will not have the instance layer and instead + * will have the specific hits below their term. + */ private final class KeywordResults extends Observable { // Map from listName/Type to Map of keywords/regexp to Map of instance terms to Set of artifact Ids @@ -104,11 +105,12 @@ public class KeywordHits implements AutopsyVisitableItem { } /** - * Get keywords used in a given list. Will be regexp patterns for regexps - * and search term for non-regexps. - * + * Get keywords used in a given list. Will be regexp patterns for + * regexps and search term for non-regexps. + * * @param listName Keyword list name - * @return + * + * @return */ List getKeywords(String listName) { List keywords; @@ -118,15 +120,16 @@ public class KeywordHits implements AutopsyVisitableItem { Collections.sort(keywords); return keywords; } - + /** - * Get specific keyword terms that were found for a given list - * and keyword combination. For example, a specific phone number for a - * phone number regexp. Will be the default instance for non-regexp searches. - * + * Get specific keyword terms that were found for a given list and + * keyword combination. For example, a specific phone number for a phone + * number regexp. Will be the default instance for non-regexp searches. + * * @param listName Keyword list name - * @param keyword search term (regexp pattern or exact match term) - * @return + * @param keyword search term (regexp pattern or exact match term) + * + * @return */ List getKeywordInstances(String listName, String keyword) { List instances; @@ -139,10 +142,14 @@ public class KeywordHits implements AutopsyVisitableItem { /** * Get artifact ids for a given list, keyword, and instance triple - * @param listName Keyword list name - * @param keyword search term (regexp pattern or exact match term) - * @param keywordInstance specific term that matched (or default instance name) - * @return + * + * @param listName Keyword list name + * @param keyword search term (regexp pattern or exact match + * term) + * @param keywordInstance specific term that matched (or default + * instance name) + * + * @return */ Set getArtifactIds(String listName, String keyword, String keywordInstance) { synchronized (topLevelMap) { @@ -151,11 +158,13 @@ public class KeywordHits implements AutopsyVisitableItem { } /** - * Add a hit for a regexp to the internal data structure. - * @param listMap Maps keywords/regexp to instances to artifact IDs - * @param regExp Regular expression that was used in search + * Add a hit for a regexp to the internal data structure. + * + * @param listMap Maps keywords/regexp to instances to artifact + * IDs + * @param regExp Regular expression that was used in search * @param keywordInstance Specific term that matched regexp - * @param artifactId Artifact id of file that had hit + * @param artifactId Artifact id of file that had hit */ void addRegExpToList(Map>> listMap, String regExp, String keywordInstance, Long artifactId) { if (listMap.containsKey(regExp) == false) { @@ -171,12 +180,13 @@ public class KeywordHits implements AutopsyVisitableItem { // add this ID to the instance instanceMap.get(keywordInstance).add(artifactId); } - - + /** - * Add a hit for a exactmatch (or substring) to the internal data structure. - * @param listMap Maps keywords/regexp to instances to artifact IDs - * @param keyWord Term that was hit + * Add a hit for a exactmatch (or substring) to the internal data + * structure. + * + * @param listMap Maps keywords/regexp to instances to artifact IDs + * @param keyWord Term that was hit * @param artifactId Artifact id of file that had hit */ void addNonRegExpMatchToList(Map>> listMap, String keyWord, Long artifactId) { @@ -191,10 +201,13 @@ public class KeywordHits implements AutopsyVisitableItem { } instanceMap.get(DEFAULT_INSTANCE_NAME).add(artifactId); } - + /** - * Populate data structure for the tree based on the keyword hit artifacts - * @param artifactIds Maps Artifact ID to map of attribute types to attribute values + * Populate data structure for the tree based on the keyword hit + * artifacts + * + * @param artifactIds Maps Artifact ID to map of attribute types to + * attribute values */ void populateTreeMaps(Map> artifactIds) { synchronized (topLevelMap) { @@ -223,7 +236,7 @@ public class KeywordHits implements AutopsyVisitableItem { String reg = attributes.get(Long.valueOf(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD_REGEXP.getTypeID())); // new in 4.4 String kwType = attributes.get(Long.valueOf(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD_SEARCH_TYPE.getTypeID())); - + // part of a list if (listName != null) { // get or create list entry @@ -231,7 +244,7 @@ public class KeywordHits implements AutopsyVisitableItem { listsMap.put(listName, new LinkedHashMap<>()); } Map>> listMap = listsMap.get(listName); - + // substring, treated same as exact match // Enum for "1" is defined in KeywordSearch.java if ((kwType != null) && (kwType.equals("1"))) { @@ -241,8 +254,7 @@ public class KeywordHits implements AutopsyVisitableItem { } else { addNonRegExpMatchToList(listMap, word, id); } - } - else if (reg != null) { + } else if (reg != null) { addRegExpToList(listMap, reg, word, id); } else { addNonRegExpMatchToList(listMap, word, id); @@ -259,11 +271,11 @@ public class KeywordHits implements AutopsyVisitableItem { } // literal, single term else { addNonRegExpMatchToList(literalMap, word, id); - } + } } topLevelMap.putAll(listsMap); } - + setChanged(); notifyObservers(); } @@ -299,9 +311,9 @@ public class KeywordHits implements AutopsyVisitableItem { long artifactId = resultSet.getLong("artifact_id"); //NON-NLS long typeId = resultSet.getLong("attribute_type_id"); //NON-NLS if (!artifactIds.containsKey(artifactId)) { - artifactIds.put(artifactId, new LinkedHashMap()); + artifactIds.put(artifactId, new LinkedHashMap<>()); } - if (valueStr != null && !valueStr.equals("")) { + if (StringUtils.isNotEmpty(valueStr)) { artifactIds.get(artifactId).put(typeId, valueStr); } else { // Keyword Search Type is an int @@ -366,7 +378,7 @@ public class KeywordHits implements AutopsyVisitableItem { } /** - * Creates the list nodes + * Creates the list nodes */ private class ListFactory extends ChildFactory.Detachable implements Observer { @@ -458,8 +470,9 @@ public class KeywordHits implements AutopsyVisitableItem { } } - /** - * Represents the keyword search lists (or default groupings if list was not given) + /** + * Represents the keyword search lists (or default groupings if list was not + * given) */ public class ListNode extends DisplayableItemNode implements Observer { @@ -587,12 +600,12 @@ public class KeywordHits implements AutopsyVisitableItem { private void updateDisplayName() { int totalDescendants = 0; - + for (String instance : keywordResults.getKeywordInstances(setName, keyword)) { Set ids = keywordResults.getArtifactIds(setName, keyword, instance); totalDescendants += ids.size(); } - + super.setDisplayName(keyword + " (" + totalDescendants + ")"); } @@ -607,8 +620,7 @@ public class KeywordHits implements AutopsyVisitableItem { // is this an exact/substring match (i.e. did we use the DEFAULT name)? if (instances.size() == 1 && instances.get(0).equals(DEFAULT_INSTANCE_NAME)) { return true; - } - else { + } else { return false; } } @@ -645,42 +657,50 @@ public class KeywordHits implements AutopsyVisitableItem { return getClass().getName(); } } - + // Allows us to pass in either longs or strings // as they keys for different types of nodes at the // same level. Probably a better way to do this, but // it works. - class RegExpInstanceKey { + private class RegExpInstanceKey { + private final boolean isRegExp; private String strKey; private Long longKey; - public RegExpInstanceKey(String key) { + + RegExpInstanceKey(String key) { isRegExp = true; strKey = key; } - public RegExpInstanceKey(Long key) { + + RegExpInstanceKey(Long key) { isRegExp = false; longKey = key; } + boolean isRegExp() { return isRegExp; } + Long getIdKey() { return longKey; } + String getRegExpKey() { return strKey; } } /** - * Creates the nodes for a given regexp that represent the specific terms that were found + * Creates the nodes for a given regexp that represent the specific terms + * that were found */ public class RegExpInstancesFactory extends ChildFactory.Detachable implements Observer { + private final String keyword; private final String setName; - - private Map nodesMap = new HashMap<>(); + + private final Map nodesMap = new HashMap<>(); public RegExpInstancesFactory(String setName, String keyword) { super(); @@ -700,15 +720,15 @@ public class KeywordHits implements AutopsyVisitableItem { @Override protected boolean createKeys(List list) { - List instances = keywordResults.getKeywordInstances(setName, keyword); + List instances = keywordResults.getKeywordInstances(setName, keyword); // The keys are different depending on what we are displaying. // regexp get another layer to show instances. // Exact/substring matches don't. if ((instances.size() == 1) && (instances.get(0).equals(DEFAULT_INSTANCE_NAME))) { - for (Long id : keywordResults.getArtifactIds(setName, keyword, DEFAULT_INSTANCE_NAME) ) { + for (Long id : keywordResults.getArtifactIds(setName, keyword, DEFAULT_INSTANCE_NAME)) { RegExpInstanceKey key = new RegExpInstanceKey(id); if (!nodesMap.containsKey(key)) { - nodesMap.put(key, createNode(key)); + nodesMap.put(key, createNode(key)); } list.add(key); } @@ -720,7 +740,7 @@ public class KeywordHits implements AutopsyVisitableItem { } list.add(key); } - + } return true; } @@ -731,23 +751,24 @@ public class KeywordHits implements AutopsyVisitableItem { } private DisplayableItemNode createNode(RegExpInstanceKey key) { - // if it isn't a regexp, then skip the 'instance' layer of the tree + // if it isn't a regexp, then skip the 'instance' layer of the tree if (key.isRegExp() == false) { return createBlackboardArtifactNode(key.getIdKey()); } else { return new RegExpInstanceNode(setName, keyword, key.getRegExpKey()); } - + } + @Override public void update(Observable o, Object arg) { refresh(true); } - + } - + /** - * Represents a specific term that was found from a regexp + * Represents a specific term that was found from a regexp */ public class RegExpInstanceNode extends DisplayableItemNode implements Observer { @@ -814,12 +835,14 @@ public class KeywordHits implements AutopsyVisitableItem { } } - /** + /** * Create a blackboard node for the given Keyword Hit artifact + * * @param artifactId + * * @return Node or null on error */ - private BlackboardArtifactNode createBlackboardArtifactNode (Long artifactId) { + private BlackboardArtifactNode createBlackboardArtifactNode(Long artifactId) { if (skCase == null) { return null; } @@ -869,7 +892,7 @@ public class KeywordHits implements AutopsyVisitableItem { } return null; } - + /** * Creates nodes for individual files that had hits */ @@ -878,8 +901,8 @@ public class KeywordHits implements AutopsyVisitableItem { private final String keyword; private final String setName; private final String instance; - - private Map nodesMap = new HashMap<>(); + + private final Map nodesMap = new HashMap<>(); public HitsFactory(String setName, String keyword, String instance) { super(); @@ -900,11 +923,11 @@ public class KeywordHits implements AutopsyVisitableItem { @Override protected boolean createKeys(List list) { - for (Long id : keywordResults.getArtifactIds(setName, keyword, instance) ) { + for (Long id : keywordResults.getArtifactIds(setName, keyword, instance)) { if (!nodesMap.containsKey(id)) { - nodesMap.put(id, createBlackboardArtifactNode(id)); + nodesMap.put(id, createBlackboardArtifactNode(id)); } - list.add(id); + list.add(id); } return true; } From 8bf884b3a7645e9448d4af21797935e3464ba2e1 Mon Sep 17 00:00:00 2001 From: millmanorama Date: Mon, 19 Jun 2017 14:29:47 +0200 Subject: [PATCH 07/20] show "correct" counts in table --- .../autopsy/datamodel/KeywordHits.java | 25 ++++++++----------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/KeywordHits.java b/Core/src/org/sleuthkit/autopsy/datamodel/KeywordHits.java index d3585e9c7f..cde13121b7 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/KeywordHits.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/KeywordHits.java @@ -33,6 +33,7 @@ import java.util.Observable; import java.util.Observer; import java.util.Set; import java.util.logging.Level; +import java.util.stream.Collectors; import org.apache.commons.lang3.StringUtils; import org.openide.nodes.ChildFactory; import org.openide.nodes.Children; @@ -596,17 +597,17 @@ public class KeywordHits implements AutopsyVisitableItem { this.setIconBaseWithExtension("org/sleuthkit/autopsy/images/keyword_hits.png"); //NON-NLS updateDisplayName(); keywordResults.addObserver(this); + } private void updateDisplayName() { - int totalDescendants = 0; + super.setDisplayName(keyword + " (" + countTotalDescendants() + ")"); + } - for (String instance : keywordResults.getKeywordInstances(setName, keyword)) { - Set ids = keywordResults.getArtifactIds(setName, keyword, instance); - totalDescendants += ids.size(); - } - - super.setDisplayName(keyword + " (" + totalDescendants + ")"); + private int countTotalDescendants() { + return keywordResults.getKeywordInstances(setName, keyword).stream() + .mapToInt(instance -> keywordResults.getArtifactIds(setName, keyword, instance).size()) + .sum(); } @Override @@ -618,11 +619,7 @@ public class KeywordHits implements AutopsyVisitableItem { public boolean isLeafTypeNode() { List instances = keywordResults.getKeywordInstances(setName, keyword); // is this an exact/substring match (i.e. did we use the DEFAULT name)? - if (instances.size() == 1 && instances.get(0).equals(DEFAULT_INSTANCE_NAME)) { - return true; - } else { - return false; - } + return instances.size() == 1 && instances.get(0).equals(DEFAULT_INSTANCE_NAME); } @Override @@ -647,7 +644,7 @@ public class KeywordHits implements AutopsyVisitableItem { ss.put(new NodeProperty<>(NbBundle.getMessage(this.getClass(), "KeywordHits.createSheet.filesWithHits.name"), NbBundle.getMessage(this.getClass(), "KeywordHits.createSheet.filesWithHits.displayName"), NbBundle.getMessage(this.getClass(), "KeywordHits.createSheet.filesWithHits.desc"), - keywordResults.getKeywordInstances(setName, keyword).size())); + countTotalDescendants())); return s; } @@ -824,7 +821,7 @@ public class KeywordHits implements AutopsyVisitableItem { ss.put(new NodeProperty<>(NbBundle.getMessage(this.getClass(), "KeywordHits.createSheet.filesWithHits.name"), NbBundle.getMessage(this.getClass(), "KeywordHits.createSheet.filesWithHits.displayName"), NbBundle.getMessage(this.getClass(), "KeywordHits.createSheet.filesWithHits.desc"), - keywordResults.getKeywordInstances(setName, keyword).size())); + keywordResults.getArtifactIds(setName, keyword, instance).size())); return s; } From f044aea5aaf2d8ead8642d7dce79416e2ce74111 Mon Sep 17 00:00:00 2001 From: Nick Davis Date: Mon, 19 Jun 2017 19:52:19 -0400 Subject: [PATCH 08/20] refactored some common code into EamDbUtil. finished settings dialog impl for SQLite. --- .../datamodel/AbstractSqlEamDb.java | 357 ++++-------- .../datamodel/EamArtifact.java | 13 + .../datamodel/EamDb.java | 1 + .../datamodel/EamDbPlatformEnum.java | 2 +- .../datamodel/EamDbUtil.java | 182 ++++++ .../datamodel/PostgresEamDb.java | 11 +- .../datamodel/PostgresEamDbSettings.java | 13 +- .../datamodel/SqliteEamDb.java | 211 +------ .../datamodel/SqliteEamDbSettings.java | 325 +++++++++-- .../optionspanel/EamDbSettingsDialog.java | 395 +++++++++---- .../EamPostgresSettingsDialog.form | 246 -------- .../EamPostgresSettingsDialog.java | 545 ------------------ .../optionspanel/EamSqliteSettingsDialog.form | 218 ------- .../optionspanel/EamSqliteSettingsDialog.java | 371 ------------ .../optionspanel/GlobalSettingsPanel.java | 2 +- 15 files changed, 924 insertions(+), 1968 deletions(-) create mode 100644 Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/EamDbUtil.java delete mode 100644 Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/EamPostgresSettingsDialog.form delete mode 100644 Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/EamPostgresSettingsDialog.java delete mode 100644 Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/EamSqliteSettingsDialog.form delete mode 100644 Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/EamSqliteSettingsDialog.java diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/AbstractSqlEamDb.java b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/AbstractSqlEamDb.java index 0610efe438..64c13420c1 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/AbstractSqlEamDb.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/AbstractSqlEamDb.java @@ -45,8 +45,7 @@ public abstract class AbstractSqlEamDb implements EamDb { private final static Logger LOGGER = Logger.getLogger(AbstractSqlEamDb.class.getName()); - protected static final int SCHEMA_VERSION = 1; - protected final List DEFAULT_ARTIFACT_TYPES = new ArrayList<>(); + protected final List DEFAULT_ARTIFACT_TYPES; private int bulkArtifactsCount; private int bulkGlobalArtifactsCount; @@ -67,7 +66,7 @@ public abstract class AbstractSqlEamDb implements EamDb { bulkArtifacts = new HashMap<>(); bulkGlobalArtifacts = new HashMap<>(); - loadDefaultArtifactTypes(); + DEFAULT_ARTIFACT_TYPES = EamArtifact.getDefaultArtifactTypes(); for (EamArtifact.Type type : DEFAULT_ARTIFACT_TYPES) { bulkArtifacts.put(type.getName(), new ArrayList<>()); @@ -75,56 +74,6 @@ public abstract class AbstractSqlEamDb implements EamDb { } } - /** - * Load the default correlation artifact types - */ - private void loadDefaultArtifactTypes() { - DEFAULT_ARTIFACT_TYPES.add(new EamArtifact.Type("FILES", true, true)); // NON-NLS - DEFAULT_ARTIFACT_TYPES.add(new EamArtifact.Type("DOMAIN", true, false)); // NON-NLS - DEFAULT_ARTIFACT_TYPES.add(new EamArtifact.Type("EMAIL", true, false)); // NON-NLS - DEFAULT_ARTIFACT_TYPES.add(new EamArtifact.Type("PHONE", true, false)); // NON-NLS - DEFAULT_ARTIFACT_TYPES.add(new EamArtifact.Type("USBID", true, false)); // NON-NLS - } - - /** - * Store the default Correlation Artifact Types in the db. - * - * This should be called immediately following the database schema being - * loaded. - * - * @throws EamDbException - */ - private void storeDefaultArtifactTypes() throws EamDbException { - for (EamArtifact.Type defType : DEFAULT_ARTIFACT_TYPES) { - newCorrelationArtifactType(defType); - } - } - - /** - * Store the schema version into the db_info table. - * - * This should be called immediately following the database schema being - * loaded. - * - * @throws EamDbException - */ - private void storeSchemaVersion() throws EamDbException { - newDbInfo("SCHEMA_VERSION", String.valueOf(SCHEMA_VERSION)); - } - - /** - * Insert all default content into a freshly initialized/reset database. - * - * This should be called immediately following the database schema being - * reset or initialized. - * - * @throws EamDbException - */ - protected void insertDefaultContent() throws EamDbException { - storeDefaultArtifactTypes(); - storeSchemaVersion(); - } - /** * Check to see if the database schema exists and is the current version. - * If it doesn't exist, initialize it and load default content. - If it is @@ -133,86 +82,30 @@ public abstract class AbstractSqlEamDb implements EamDb { * * Note: this should be call after the connectionPool is initialized. */ - protected void confirmDatabaseSchema() throws EamDbException { - int schema_version; - try { - schema_version = Integer.parseInt(getDbInfo("SCHEMA_VERSION")); - } catch (EamDbException | NumberFormatException ex) { - // error likely means we have not initialized the schema - schema_version = 0; - LOGGER.log(Level.WARNING, "Could not find SCHEMA_VERSION in db_info table, assuming database is not initialized.", ex); // NON-NLS - } - - if (0 == schema_version) { - initializeDatabaseSchema(); - insertDefaultContent(); - } else if (SCHEMA_VERSION > schema_version) { - // FUTURE: upgrade schema - } - // else, schema is current - } - - /** - * Create the schema for the selected database implementation - */ - protected abstract void initializeDatabaseSchema() throws EamDbException; +// protected void confirmDatabaseSchema() throws EamDbException { +// int schema_version; +// try { +// schema_version = Integer.parseInt(getDbInfo("SCHEMA_VERSION")); +// } catch (EamDbException | NumberFormatException ex) { +// // error likely means we have not initialized the schema +// schema_version = 0; +// LOGGER.log(Level.WARNING, "Could not find SCHEMA_VERSION in db_info table, assuming database is not initialized.", ex); // NON-NLS +// } +// +// if (0 == schema_version) { +//// initializeDatabaseSchema(); +// insertDefaultContent(); +// } else if (SCHEMA_VERSION > schema_version) { +// // FUTURE: upgrade schema +// } +// // else, schema is current +// } /** * Setup and create a connection to the selected database implementation */ protected abstract Connection connect() throws EamDbException; - /** - * Close the in-use connection and return it to the pool. - * - * @param conn An open connection - * - * @throws EamDbException - */ - protected void closeConnection(Connection conn) throws EamDbException { - if (null != conn) { - try { - conn.close(); - } catch (SQLException ex) { - throw new EamDbException("Error closing Connection.", ex); - } - } - } - - /** - * Close the prepared statement. - * - * @param preparedStatement - * - * @throws EamDbException - */ - protected void closePreparedStatement(PreparedStatement preparedStatement) throws EamDbException { - if (null != preparedStatement) { - try { - preparedStatement.close(); - } catch (SQLException ex) { - throw new EamDbException("Error closing PreparedStatement.", ex); - } - } - } - - /** - * Close the resultSet. - * - * @param resultSet - * - * @throws EamDbException - */ - protected void closeResultSet(ResultSet resultSet) throws EamDbException { - if (null != resultSet) { - try { - resultSet.close(); - } catch (SQLException ex) { - throw new EamDbException("Error closing ResultSet.", ex); - } - } - } - /** * Get the list of tags recognized as "Bad" * @@ -260,8 +153,8 @@ public abstract class AbstractSqlEamDb implements EamDb { } catch (SQLException ex) { throw new EamDbException("Error adding new name/value pair to db_info.", ex); } finally { - closePreparedStatement(preparedStatement); - closeConnection(conn); + EamDbUtil.closePreparedStatement(preparedStatement); + EamDbUtil.closeConnection(conn); } } @@ -293,9 +186,9 @@ public abstract class AbstractSqlEamDb implements EamDb { } catch (SQLException ex) { throw new EamDbException("Error getting value for name.", ex); } finally { - closePreparedStatement(preparedStatement); - closeResultSet(resultSet); - closeConnection(conn); + EamDbUtil.closePreparedStatement(preparedStatement); + EamDbUtil.closeResultSet(resultSet); + EamDbUtil.closeConnection(conn); } return value; @@ -323,8 +216,8 @@ public abstract class AbstractSqlEamDb implements EamDb { } catch (SQLException ex) { throw new EamDbException("Error updating value for name.", ex); } finally { - closePreparedStatement(preparedStatement); - closeConnection(conn); + EamDbUtil.closePreparedStatement(preparedStatement); + EamDbUtil.closeConnection(conn); } } @@ -366,8 +259,8 @@ public abstract class AbstractSqlEamDb implements EamDb { } catch (SQLException ex) { throw new EamDbException("Error inserting new case.", ex); // NON-NLS } finally { - closePreparedStatement(preparedStatement); - closeConnection(conn); + EamDbUtil.closePreparedStatement(preparedStatement); + EamDbUtil.closeConnection(conn); } } @@ -406,8 +299,8 @@ public abstract class AbstractSqlEamDb implements EamDb { } catch (SQLException ex) { throw new EamDbException("Error updating case.", ex); // NON-NLS } finally { - closePreparedStatement(preparedStatement); - closeConnection(conn); + EamDbUtil.closePreparedStatement(preparedStatement); + EamDbUtil.closeConnection(conn); } } @@ -442,9 +335,9 @@ public abstract class AbstractSqlEamDb implements EamDb { } catch (SQLException ex) { throw new EamDbException("Error getting case details.", ex); // NON-NLS } finally { - closePreparedStatement(preparedStatement); - closeResultSet(resultSet); - closeConnection(conn); + EamDbUtil.closePreparedStatement(preparedStatement); + EamDbUtil.closeResultSet(resultSet); + EamDbUtil.closeConnection(conn); } return eamCaseResult; @@ -479,9 +372,9 @@ public abstract class AbstractSqlEamDb implements EamDb { } catch (SQLException ex) { throw new EamDbException("Error getting all cases.", ex); // NON-NLS } finally { - closePreparedStatement(preparedStatement); - closeResultSet(resultSet); - closeConnection(conn); + EamDbUtil.closePreparedStatement(preparedStatement); + EamDbUtil.closeResultSet(resultSet); + EamDbUtil.closeConnection(conn); } return cases; @@ -510,8 +403,8 @@ public abstract class AbstractSqlEamDb implements EamDb { } catch (SQLException ex) { throw new EamDbException("Error inserting new data source.", ex); // NON-NLS } finally { - closePreparedStatement(preparedStatement); - closeConnection(conn); + EamDbUtil.closePreparedStatement(preparedStatement); + EamDbUtil.closeConnection(conn); } } @@ -537,8 +430,8 @@ public abstract class AbstractSqlEamDb implements EamDb { } catch (SQLException ex) { throw new EamDbException("Error updating case.", ex); // NON-NLS } finally { - closePreparedStatement(preparedStatement); - closeConnection(conn); + EamDbUtil.closePreparedStatement(preparedStatement); + EamDbUtil.closeConnection(conn); } } @@ -569,9 +462,9 @@ public abstract class AbstractSqlEamDb implements EamDb { } catch (SQLException ex) { throw new EamDbException("Error getting case details.", ex); // NON-NLS } finally { - closePreparedStatement(preparedStatement); - closeResultSet(resultSet); - closeConnection(conn); + EamDbUtil.closePreparedStatement(preparedStatement); + EamDbUtil.closeResultSet(resultSet); + EamDbUtil.closeConnection(conn); } return eamDataSourceResult; @@ -603,9 +496,9 @@ public abstract class AbstractSqlEamDb implements EamDb { } catch (SQLException ex) { throw new EamDbException("Error getting all data sources.", ex); // NON-NLS } finally { - closePreparedStatement(preparedStatement); - closeResultSet(resultSet); - closeConnection(conn); + EamDbUtil.closePreparedStatement(preparedStatement); + EamDbUtil.closeResultSet(resultSet); + EamDbUtil.closeConnection(conn); } return dataSources; @@ -651,8 +544,8 @@ public abstract class AbstractSqlEamDb implements EamDb { } catch (SQLException ex) { throw new EamDbException("Error inserting new artifact into artifacts table.", ex); // NON-NLS } finally { - closePreparedStatement(preparedStatement); - closeConnection(conn); + EamDbUtil.closePreparedStatement(preparedStatement); + EamDbUtil.closeConnection(conn); } } @@ -697,9 +590,9 @@ public abstract class AbstractSqlEamDb implements EamDb { } catch (SQLException ex) { throw new EamDbException("Error getting artifact instances by artifactType and artifactValue.", ex); // NON-NLS } finally { - closePreparedStatement(preparedStatement); - closeResultSet(resultSet); - closeConnection(conn); + EamDbUtil.closePreparedStatement(preparedStatement); + EamDbUtil.closeResultSet(resultSet); + EamDbUtil.closeConnection(conn); } return artifactInstances; @@ -749,9 +642,9 @@ public abstract class AbstractSqlEamDb implements EamDb { } catch (SQLException ex) { throw new EamDbException("Error getting artifact instances by artifactType and artifactValue.", ex); // NON-NLS } finally { - closePreparedStatement(preparedStatement); - closeResultSet(resultSet); - closeConnection(conn); + EamDbUtil.closePreparedStatement(preparedStatement); + EamDbUtil.closeResultSet(resultSet); + EamDbUtil.closeConnection(conn); } return artifactInstances; @@ -790,9 +683,9 @@ public abstract class AbstractSqlEamDb implements EamDb { } catch (SQLException ex) { throw new EamDbException("Error getting count of artifact instances by artifactType and artifactValue.", ex); // NON-NLS } finally { - closePreparedStatement(preparedStatement); - closeResultSet(resultSet); - closeConnection(conn); + EamDbUtil.closePreparedStatement(preparedStatement); + EamDbUtil.closeResultSet(resultSet); + EamDbUtil.closeConnection(conn); } return instanceCount; @@ -852,9 +745,9 @@ public abstract class AbstractSqlEamDb implements EamDb { } catch (SQLException ex) { throw new EamDbException("Error counting unique caseDisplayName/dataSource tuples having artifactType and artifactValue.", ex); // NON-NLS } finally { - closePreparedStatement(preparedStatement); - closeResultSet(resultSet); - closeConnection(conn); + EamDbUtil.closePreparedStatement(preparedStatement); + EamDbUtil.closeResultSet(resultSet); + EamDbUtil.closeConnection(conn); } return instanceCount; @@ -897,9 +790,9 @@ public abstract class AbstractSqlEamDb implements EamDb { } catch (SQLException ex) { throw new EamDbException("Error counting unique caseDisplayName/dataSource tuples.", ex); // NON-NLS } finally { - closePreparedStatement(preparedStatement); - closeResultSet(resultSet); - closeConnection(conn); + EamDbUtil.closePreparedStatement(preparedStatement); + EamDbUtil.closeResultSet(resultSet); + EamDbUtil.closeConnection(conn); } return instanceCount; @@ -952,9 +845,9 @@ public abstract class AbstractSqlEamDb implements EamDb { } catch (SQLException ex) { throw new EamDbException("Error counting artifact instances by caseName/dataSource.", ex); // NON-NLS } finally { - closePreparedStatement(preparedStatement); - closeResultSet(resultSet); - closeConnection(conn); + EamDbUtil.closePreparedStatement(preparedStatement); + EamDbUtil.closeResultSet(resultSet); + EamDbUtil.closeConnection(conn); } return instanceCount; @@ -1034,8 +927,8 @@ public abstract class AbstractSqlEamDb implements EamDb { } catch (SQLException ex) { throw new EamDbException("Error inserting bulk artifacts.", ex); // NON-NLS } finally { - closePreparedStatement(bulkPs); - closeConnection(conn); + EamDbUtil.closePreparedStatement(bulkPs); + EamDbUtil.closeConnection(conn); } } @@ -1087,8 +980,8 @@ public abstract class AbstractSqlEamDb implements EamDb { } catch (SQLException ex) { throw new EamDbException("Error inserting bulk cases.", ex); // NON-NLS } finally { - closePreparedStatement(bulkPs); - closeConnection(conn); + EamDbUtil.closePreparedStatement(bulkPs); + EamDbUtil.closeConnection(conn); } } @@ -1153,10 +1046,10 @@ public abstract class AbstractSqlEamDb implements EamDb { } catch (SQLException ex) { throw new EamDbException("Error getting/setting artifact instance knownStatus=Bad.", ex); // NON-NLS } finally { - closePreparedStatement(preparedUpdate); - closePreparedStatement(preparedQuery); - closeResultSet(resultSet); - closeConnection(conn); + EamDbUtil.closePreparedStatement(preparedUpdate); + EamDbUtil.closePreparedStatement(preparedQuery); + EamDbUtil.closeResultSet(resultSet); + EamDbUtil.closeConnection(conn); } } @@ -1201,9 +1094,9 @@ public abstract class AbstractSqlEamDb implements EamDb { } catch (SQLException ex) { throw new EamDbException("Error getting known bad artifact instances.", ex); // NON-NLS } finally { - closePreparedStatement(preparedStatement); - closeResultSet(resultSet); - closeConnection(conn); + EamDbUtil.closePreparedStatement(preparedStatement); + EamDbUtil.closeResultSet(resultSet); + EamDbUtil.closeConnection(conn); } return artifactInstances; @@ -1240,9 +1133,9 @@ public abstract class AbstractSqlEamDb implements EamDb { } catch (SQLException ex) { throw new EamDbException("Error getting count of known bad artifact instances.", ex); // NON-NLS } finally { - closePreparedStatement(preparedStatement); - closeResultSet(resultSet); - closeConnection(conn); + EamDbUtil.closePreparedStatement(preparedStatement); + EamDbUtil.closeResultSet(resultSet); + EamDbUtil.closeConnection(conn); } return badInstances; @@ -1291,9 +1184,9 @@ public abstract class AbstractSqlEamDb implements EamDb { } catch (SQLException ex) { throw new EamDbException("Error getting known bad artifact instances.", ex); // NON-NLS } finally { - closePreparedStatement(preparedStatement); - closeResultSet(resultSet); - closeConnection(conn); + EamDbUtil.closePreparedStatement(preparedStatement); + EamDbUtil.closeResultSet(resultSet); + EamDbUtil.closeConnection(conn); } return caseNames.stream().collect(Collectors.toList()); @@ -1331,9 +1224,9 @@ public abstract class AbstractSqlEamDb implements EamDb { } catch (SQLException ex) { throw new EamDbException("Error determining if artifact is globally known bad.", ex); // NON-NLS } finally { - closePreparedStatement(preparedStatement); - closeResultSet(resultSet); - closeConnection(conn); + EamDbUtil.closePreparedStatement(preparedStatement); + EamDbUtil.closeResultSet(resultSet); + EamDbUtil.closeConnection(conn); } return 0 < badInstances; @@ -1364,8 +1257,8 @@ public abstract class AbstractSqlEamDb implements EamDb { } catch (SQLException ex) { throw new EamDbException("Error inserting new organization.", ex); // NON-NLS } finally { - closePreparedStatement(preparedStatement); - closeConnection(conn); + EamDbUtil.closePreparedStatement(preparedStatement); + EamDbUtil.closeConnection(conn); } } @@ -1396,9 +1289,9 @@ public abstract class AbstractSqlEamDb implements EamDb { } catch (SQLException ex) { throw new EamDbException("Error getting all organizations.", ex); // NON-NLS } finally { - closePreparedStatement(preparedStatement); - closeResultSet(resultSet); - closeConnection(conn); + EamDbUtil.closePreparedStatement(preparedStatement); + EamDbUtil.closeResultSet(resultSet); + EamDbUtil.closeConnection(conn); } } @@ -1429,9 +1322,9 @@ public abstract class AbstractSqlEamDb implements EamDb { } catch (SQLException ex) { throw new EamDbException("Error getting organization by id.", ex); // NON-NLS } finally { - closePreparedStatement(preparedStatement); - closeResultSet(resultSet); - closeConnection(conn); + EamDbUtil.closePreparedStatement(preparedStatement); + EamDbUtil.closeResultSet(resultSet); + EamDbUtil.closeConnection(conn); } } @@ -1476,10 +1369,10 @@ public abstract class AbstractSqlEamDb implements EamDb { } catch (SQLException ex) { throw new EamDbException("Error inserting new global set.", ex); // NON-NLS } finally { - closePreparedStatement(preparedStatement1); - closePreparedStatement(preparedStatement2); - closeResultSet(resultSet); - closeConnection(conn); + EamDbUtil.closePreparedStatement(preparedStatement1); + EamDbUtil.closePreparedStatement(preparedStatement2); + EamDbUtil.closeResultSet(resultSet); + EamDbUtil.closeConnection(conn); } } @@ -1510,9 +1403,9 @@ public abstract class AbstractSqlEamDb implements EamDb { } catch (SQLException ex) { throw new EamDbException("Error getting global set by id.", ex); // NON-NLS } finally { - closePreparedStatement(preparedStatement1); - closeResultSet(resultSet); - closeConnection(conn); + EamDbUtil.closePreparedStatement(preparedStatement1); + EamDbUtil.closeResultSet(resultSet); + EamDbUtil.closeConnection(conn); } } @@ -1541,8 +1434,8 @@ public abstract class AbstractSqlEamDb implements EamDb { } catch (SQLException ex) { throw new EamDbException("Error inserting new global file instance into global_files table.", ex); // NON-NLS } finally { - closePreparedStatement(preparedStatement); - closeConnection(conn); + EamDbUtil.closePreparedStatement(preparedStatement); + EamDbUtil.closeConnection(conn); } } @@ -1605,8 +1498,8 @@ public abstract class AbstractSqlEamDb implements EamDb { } catch (SQLException ex) { throw new EamDbException("Error inserting bulk artifacts.", ex); // NON-NLS } finally { - closePreparedStatement(bulkPs); - closeConnection(conn); + EamDbUtil.closePreparedStatement(bulkPs); + EamDbUtil.closeConnection(conn); } } } @@ -1639,9 +1532,9 @@ public abstract class AbstractSqlEamDb implements EamDb { } catch (SQLException ex) { throw new EamDbException("Error getting global set by id.", ex); // NON-NLS } finally { - closePreparedStatement(preparedStatement1); - closeResultSet(resultSet); - closeConnection(conn); + EamDbUtil.closePreparedStatement(preparedStatement1); + EamDbUtil.closeResultSet(resultSet); + EamDbUtil.closeConnection(conn); } } @@ -1670,8 +1563,8 @@ public abstract class AbstractSqlEamDb implements EamDb { } catch (SQLException ex) { throw new EamDbException("Error inserting new correlation artifact type.", ex); // NON-NLS } finally { - closePreparedStatement(preparedStatement); - closeConnection(conn); + EamDbUtil.closePreparedStatement(preparedStatement); + EamDbUtil.closeConnection(conn); } } @@ -1703,9 +1596,9 @@ public abstract class AbstractSqlEamDb implements EamDb { } catch (SQLException ex) { throw new EamDbException("Error getting all correlation artifact types.", ex); // NON-NLS } finally { - closePreparedStatement(preparedStatement); - closeResultSet(resultSet); - closeConnection(conn); + EamDbUtil.closePreparedStatement(preparedStatement); + EamDbUtil.closeResultSet(resultSet); + EamDbUtil.closeConnection(conn); } } @@ -1737,9 +1630,9 @@ public abstract class AbstractSqlEamDb implements EamDb { } catch (SQLException ex) { throw new EamDbException("Error getting enabled correlation artifact types.", ex); // NON-NLS } finally { - closePreparedStatement(preparedStatement); - closeResultSet(resultSet); - closeConnection(conn); + EamDbUtil.closePreparedStatement(preparedStatement); + EamDbUtil.closeResultSet(resultSet); + EamDbUtil.closeConnection(conn); } } @@ -1771,9 +1664,9 @@ public abstract class AbstractSqlEamDb implements EamDb { } catch (SQLException ex) { throw new EamDbException("Error getting supported correlation artifact types.", ex); // NON-NLS } finally { - closePreparedStatement(preparedStatement); - closeResultSet(resultSet); - closeConnection(conn); + EamDbUtil.closePreparedStatement(preparedStatement); + EamDbUtil.closeResultSet(resultSet); + EamDbUtil.closeConnection(conn); } } @@ -1801,8 +1694,8 @@ public abstract class AbstractSqlEamDb implements EamDb { } catch (SQLException ex) { throw new EamDbException("Error getting correlation artifact type by name.", ex); // NON-NLS } finally { - closePreparedStatement(preparedStatement); - closeConnection(conn); + EamDbUtil.closePreparedStatement(preparedStatement); + EamDbUtil.closeConnection(conn); } } @@ -1835,9 +1728,9 @@ public abstract class AbstractSqlEamDb implements EamDb { } catch (SQLException ex) { throw new EamDbException("Error getting correlation artifact type by name.", ex); // NON-NLS } finally { - closePreparedStatement(preparedStatement); - closeResultSet(resultSet); - closeConnection(conn); + EamDbUtil.closePreparedStatement(preparedStatement); + EamDbUtil.closeResultSet(resultSet); + EamDbUtil.closeConnection(conn); } } diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/EamArtifact.java b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/EamArtifact.java index 090341023c..dd33b5e0e9 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/EamArtifact.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/EamArtifact.java @@ -36,6 +36,19 @@ public class EamArtifact implements Serializable { private Type artifactType; private final List artifactInstances; + /** + * Load the default correlation artifact types + */ + public static List getDefaultArtifactTypes() { + List DEFAULT_ARTIFACT_TYPES = new ArrayList<>(); + DEFAULT_ARTIFACT_TYPES.add(new EamArtifact.Type("FILES", true, true)); // NON-NLS + DEFAULT_ARTIFACT_TYPES.add(new EamArtifact.Type("DOMAIN", true, false)); // NON-NLS + DEFAULT_ARTIFACT_TYPES.add(new EamArtifact.Type("EMAIL", true, false)); // NON-NLS + DEFAULT_ARTIFACT_TYPES.add(new EamArtifact.Type("PHONE", true, false)); // NON-NLS + DEFAULT_ARTIFACT_TYPES.add(new EamArtifact.Type("USBID", true, false)); // NON-NLS + return DEFAULT_ARTIFACT_TYPES; + } + public EamArtifact(Type artifactType, String artifactValue) { this.ID = ""; this.artifactType = artifactType; diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/EamDb.java b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/EamDb.java index a5b71de42a..aaa688a783 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/EamDb.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/EamDb.java @@ -24,6 +24,7 @@ import java.util.List; * Main interface for interacting with the database */ public interface EamDb { + public static final int SCHEMA_VERSION = 1; /** * Get the instance; default to SQLITE. diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/EamDbPlatformEnum.java b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/EamDbPlatformEnum.java index 1f2362d25f..2b117d326d 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/EamDbPlatformEnum.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/EamDbPlatformEnum.java @@ -24,7 +24,7 @@ import org.sleuthkit.autopsy.coreutils.ModuleSettings; * */ public enum EamDbPlatformEnum { - DISABLED("", true), + DISABLED("Disabled", true), SQLITE("SQLite", false), POSTGRESQL("PostgreSQL", false); diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/EamDbUtil.java b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/EamDbUtil.java new file mode 100644 index 0000000000..1a19b3e27d --- /dev/null +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/EamDbUtil.java @@ -0,0 +1,182 @@ +/* + * 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.experimental.enterpriseartifactsmanager.datamodel; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.List; +import java.util.logging.Level; +import static org.sleuthkit.autopsy.experimental.enterpriseartifactsmanager.datamodel.EamDb.SCHEMA_VERSION; + +/** + * + */ +public class EamDbUtil { + /** + * Close the prepared statement. + * + * @param preparedStatement + * + * @throws EamDbException + */ + public static void closePreparedStatement(PreparedStatement preparedStatement) throws EamDbException { + if (null != preparedStatement) { + try { + preparedStatement.close(); + } catch (SQLException ex) { + throw new EamDbException("Error closing PreparedStatement.", ex); + } + } + } + + /** + * Close the resultSet. + * + * @param resultSet + * + * @throws EamDbException + */ + public static void closeResultSet(ResultSet resultSet) throws EamDbException { + if (null != resultSet) { + try { + resultSet.close(); + } catch (SQLException ex) { + throw new EamDbException("Error closing ResultSet.", ex); + } + } + } + + /** + * Close the in-use connection and return it to the pool. + * + * @param conn An open connection + * + * @throws EamDbException + */ + public static void closeConnection(Connection conn) throws EamDbException { + if (null != conn) { + try { + conn.close(); + } catch (SQLException ex) { + throw new EamDbException("Error closing Connection.", ex); + } + } + } + + /** + * Insert the default artifact types into the database. + * + * @param conn An open database connection. + * + * @throws EamDbException + */ + public static void insertDefaultArtifactTypes(Connection conn) throws EamDbException { + PreparedStatement preparedStatement = null; + List DEFAULT_ARTIFACT_TYPES = EamArtifact.getDefaultArtifactTypes(); + String sql = "INSERT INTO artifact_types(name, supported, enabled) VALUES (?, ?, ?)"; + + try { + preparedStatement = conn.prepareStatement(sql); + for (EamArtifact.Type newType : DEFAULT_ARTIFACT_TYPES) { + preparedStatement.setString(1, newType.getName()); + preparedStatement.setInt(2, newType.isSupported() ? 1 : 0); + preparedStatement.setInt(3, newType.isEnabled() ? 1 : 0); + preparedStatement.addBatch(); + } + preparedStatement.executeBatch(); + } catch (SQLException ex) { + throw new EamDbException("Error inserting default correlation artifact types.", ex); // NON-NLS + } finally { + EamDbUtil.closePreparedStatement(preparedStatement); + } + } + + /** + * Store the schema version into the db_info table. + * + * This should be called immediately following the database schema being + * loaded. + * + * @throws EamDbException + */ + public static void insertSchemaVersion(Connection conn) throws EamDbException { + PreparedStatement preparedStatement = null; + String sql = "INSERT INTO db_info (name, value) VALUES (?, ?)"; + try { + preparedStatement = conn.prepareStatement(sql); + preparedStatement.setString(1, "SCHEMA_VERSION"); + preparedStatement.setString(2, String.valueOf(SCHEMA_VERSION)); + preparedStatement.executeUpdate(); + } catch (SQLException ex) { + throw new EamDbException("Error adding schema version to db_info.", ex); + } finally { + EamDbUtil.closePreparedStatement(preparedStatement); + } + } + + /** + * Query to see if the SCHEMA_VERSION is set in the db. + * + * @return true if set, else false. + */ + public static boolean schemaVersionIsSet(Connection conn) { + if (null == conn) { + return false; + } + + ResultSet resultSet = null; + try { + Statement tester = conn.createStatement(); + String sql = "SELECT value FROM db_info WHERE name='SCHEMA_VERSION'"; + resultSet = tester.executeQuery(sql); + if (resultSet.next()) { + String value = resultSet.getString("value"); + } + } catch (SQLException ex) { + return false; + } finally { + try { + EamDbUtil.closeResultSet(resultSet); + } catch (EamDbException ex) { + } + } + return true; + } + + /** + * Use the current settings and the validation query + * to test the connection to the database. + * + * @return true if successfull query execution, else false. + */ + public static boolean executeValidationQuery(Connection conn, String validationQuery) { + if (null == conn) { + return false; + } + + ResultSet resultSet = null; + try { + Statement tester = conn.createStatement(); + resultSet = tester.executeQuery(validationQuery); + if (resultSet.next()) { + return true; + } + } catch (SQLException ex) { + return false; + } finally { + try { + EamDbUtil.closeResultSet(resultSet); + } catch (EamDbException ex) { + } + } + + return false; + } +} diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/PostgresEamDb.java b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/PostgresEamDb.java index 52f60b1950..1c889cd3c3 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/PostgresEamDb.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/PostgresEamDb.java @@ -90,10 +90,10 @@ public class PostgresEamDb extends AbstractSqlEamDb { } catch (SQLException ex) { //LOGGER.log(Level.WARNING, "Failed to reset database.", ex); } finally { - closeConnection(conn); + EamDbUtil.closeConnection(conn); } - insertDefaultContent(); + dbSettings.insertDefaultDatabaseContent(); } /** @@ -137,8 +137,7 @@ public class PostgresEamDb extends AbstractSqlEamDb { * implementation of connect() is synchronized, so we can safely use the * connectionPool object directly. */ - @Override - protected void initializeDatabaseSchema() throws EamDbException { + 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 @@ -291,7 +290,7 @@ public class PostgresEamDb extends AbstractSqlEamDb { } catch (SQLException ex) { throw new EamDbException("Error initializing db schema.", ex); // NON-NLS } finally { - closeConnection(conn); + EamDbUtil.closeConnection(conn); } } @@ -311,7 +310,7 @@ public class PostgresEamDb extends AbstractSqlEamDb { if (connectionPool == null) { setupConnectionPool(); - confirmDatabaseSchema(); +// confirmDatabaseSchema(); } } diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/PostgresEamDbSettings.java b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/PostgresEamDbSettings.java index 7b08740354..3c0a64ae46 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/PostgresEamDbSettings.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/PostgresEamDbSettings.java @@ -149,7 +149,12 @@ public final class PostgresEamDbSettings { return url.toString(); } - public boolean testSettings() { + /** + * Using the current settings, test the connection to the database. + * + * @return true if successfull connection, else false. + */ + public boolean testConnectionSettings() { // Open a new ephemeral client here to test that we can connect ResultSet resultSet = null; Connection conn = null; @@ -184,7 +189,11 @@ public final class PostgresEamDbSettings { return true; } - + + public boolean insertDefaultDatabaseContent() { + return true; + } + public boolean isChanged() { String hostString = ModuleSettings.getConfigSetting("EnterpriseArtifactsManager", "db.postgresql.host"); // NON-NLS String portString = ModuleSettings.getConfigSetting("EnterpriseArtifactsManager", "db.postgresql.port"); // NON-NLS diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/SqliteEamDb.java b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/SqliteEamDb.java index 3e43ca97c1..a5d4111b3c 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/SqliteEamDb.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/SqliteEamDb.java @@ -38,13 +38,6 @@ public class SqliteEamDb extends AbstractSqlEamDb { private static SqliteEamDb instance; - protected static final String PRAGMA_SYNC_OFF = "PRAGMA synchronous = OFF"; - protected static final String PRAGMA_SYNC_NORMAL = "PRAGMA synchronous = NORMAL"; - private static final String PRAGMA_JOURNAL_WAL = "PRAGMA journal_mode = WAL"; - private static final String PRAGMA_READ_UNCOMMITTED_TRUE = "PRAGMA read_uncommitted = True"; - private static final String PRAGMA_ENCODING_UTF8 = "PRAGMA encoding = 'UTF-8'"; - private static final String PRAGMA_PAGE_SIZE_4096 = "PRAGMA page_size = 4096"; - private static final String PRAGMA_FOREIGN_KEYS_ON = "PRAGMA foreign_keys = ON"; private BasicDataSource connectionPool = null; private final SqliteEamDbSettings dbSettings; @@ -97,12 +90,12 @@ public class SqliteEamDb extends AbstractSqlEamDb { } dropContent.executeUpdate("VACUUM"); - insertDefaultContent(); + dbSettings.insertDefaultDatabaseContent(); } catch (SQLException ex) { LOGGER.log(Level.WARNING, "Failed to reset database.", ex); } finally { - closeConnection(conn); + EamDbUtil.closeConnection(conn); } } @@ -130,202 +123,6 @@ public class SqliteEamDb extends AbstractSqlEamDb { connectionPool.setValidationQuery(dbSettings.getValidationQuery()); } - /** - * Verify the EAM db directory exists. If it doesn't, then create it. - * - * @throws EamDbException - */ - private void verifyDBDirectory() throws EamDbException { - File dbDir = new File(dbSettings.getDbDirectory()); - if (!dbDir.exists()) { - LOGGER.log(Level.INFO, "sqlite directory does not exist, creating it at {0}.", dbSettings.getDbDirectory()); // NON-NLS - try { - Files.createDirectories(dbDir.toPath()); - } catch (IOException ex) { - throw new EamDbException("Failed to create sqlite database directory. ", ex); // NON-NLS - } - } else if (dbDir.exists() && !dbDir.isDirectory()) { - LOGGER.log(Level.INFO, "Failed to create sqlite database directory. Path already exists and is not a directory: {0}", dbSettings.getDbDirectory()); // NON-NLS - } - - } - - /** - * 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. - */ - @Override - protected 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 integer primary key autoincrement NOT NULL,"); - 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 integer primary key autoincrement NOT NULL,"); - 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("CONSTRAINT case_uid_unique UNIQUE(case_uid)"); - 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 integer primary key autoincrement NOT NULL,"); - 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 integer primary key autoincrement NOT NULL,"); - 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 integer primary key autoincrement NOT NULL,"); - 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 integer primary key autoincrement NOT NULL,"); - 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 integer primary key autoincrement NOT NULL,"); - 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 integer 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(PRAGMA_JOURNAL_WAL); - stmt.execute(PRAGMA_SYNC_OFF); - stmt.execute(PRAGMA_READ_UNCOMMITTED_TRUE); - stmt.execute(PRAGMA_ENCODING_UTF8); - stmt.execute(PRAGMA_PAGE_SIZE_4096); - stmt.execute(PRAGMA_FOREIGN_KEYS_ON); - - 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 { - closeConnection(conn); - } - } - /** * Lazily setup Singleton connection on first request. * @@ -341,9 +138,9 @@ public class SqliteEamDb extends AbstractSqlEamDb { } if (connectionPool == null) { - verifyDBDirectory(); +// verifyDBDirectory(); setupConnectionPool(); - confirmDatabaseSchema(); +// confirmDatabaseSchema(); } try { diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/SqliteEamDbSettings.java b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/SqliteEamDbSettings.java index 787de9c4f0..5ac7da6834 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/SqliteEamDbSettings.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/SqliteEamDbSettings.java @@ -23,6 +23,7 @@ import java.io.IOException; import java.nio.file.Files; import java.sql.Connection; import java.sql.DriverManager; +import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; @@ -30,6 +31,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.logging.Level; +import org.openide.util.Exceptions; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.ModuleSettings; import org.sleuthkit.autopsy.coreutils.PlatformUtil; @@ -47,6 +49,13 @@ public final class SqliteEamDbSettings { private final String JDBC_DRIVER = "org.sqlite.JDBC"; // NON-NLS private final String JDBC_BASE_URI = "jdbc:sqlite:"; // NON-NLS private final String VALIDATION_QUERY = "SELECT count(*) from sqlite_master"; // NON-NLS + private static final String PRAGMA_SYNC_OFF = "PRAGMA synchronous = OFF"; + private static final String PRAGMA_SYNC_NORMAL = "PRAGMA synchronous = NORMAL"; + private static final String PRAGMA_JOURNAL_WAL = "PRAGMA journal_mode = WAL"; + private static final String PRAGMA_READ_UNCOMMITTED_TRUE = "PRAGMA read_uncommitted = True"; + private static final String PRAGMA_ENCODING_UTF8 = "PRAGMA encoding = 'UTF-8'"; + private static final String PRAGMA_PAGE_SIZE_4096 = "PRAGMA page_size = 4096"; + private static final String PRAGMA_FOREIGN_KEYS_ON = "PRAGMA foreign_keys = ON"; private boolean enabled; private String dbName; @@ -93,7 +102,7 @@ public final class SqliteEamDbSettings { } public void saveSettings() { - createAndVerifyDirectory(); + createDbDirectory(); ModuleSettings.setConfigSetting("EnterpriseArtifactsManager", "db.enabled", Boolean.toString(isEnabled())); // NON-NLS ModuleSettings.setConfigSetting("EnterpriseArtifactsManager", "db.sqlite.dbName", getDbName()); // NON-NLS @@ -102,20 +111,40 @@ public final class SqliteEamDbSettings { ModuleSettings.setConfigSetting("EnterpriseArtifactsManager", "db.badTags", String.join(",", badTags)); // NON-NLS } - public boolean createAndVerifyDirectory() { + /** + * Verify that the db directory path exists. + * + * @return true if exists, else false + */ + public boolean dbDirectoryExists() { // Ensure dbDirectory is a valid directory File dbDir = new File(getDbDirectory()); + if (!dbDir.exists()) { - LOGGER.log(Level.INFO, "sqlite directory does not exist, creating it at {0}.", getDbDirectory()); // NON-NLS + return false; + } else if (!dbDir.isDirectory()) { + return false; + } + + return true; + + } + + /** + * Create the db directory if it does not exist. + * + * @return true is successfully created or already exists, else false + */ + public boolean createDbDirectory() { + if (!dbDirectoryExists()) { try { + File dbDir = new File(getDbDirectory()); Files.createDirectories(dbDir.toPath()); + LOGGER.log(Level.INFO, "sqlite directory did not exist, created it at {0}.", getDbDirectory()); // NON-NLS } catch (IOException ex) { - LOGGER.log(Level.INFO, "Failed to create sqlite database directory.", ex); // NON-NLS + LOGGER.log(Level.SEVERE, "Failed to create sqlite database directory.", ex); // NON-NLS return false; } - } else if (dbDir.exists() && !dbDir.isDirectory()) { - LOGGER.log(Level.INFO, "Failed to create sqlite database directory. Path already exists and is not a directory."); // NON-NLS - return false; } return true; @@ -134,46 +163,276 @@ public final class SqliteEamDbSettings { return url.toString(); } - public boolean testSettings() { - if (!createAndVerifyDirectory()) { - return false; + /** + * Use the current settings to get an ephemeral client connection for testing. + * + * If the directory path does not exist, it will return null. + * + * @return Connection or null. + */ + private Connection getEphemeralConnection() { + if (!dbDirectoryExists()) { + return null; } - // Open a new ephemeral client here to test that we can connect - ResultSet resultSet = null; Connection conn = null; try { String url = getConnectionURL(); Class.forName(getDriver()); conn = DriverManager.getConnection(url); - Statement tester = conn.createStatement(); - resultSet = tester.executeQuery(getValidationQuery()); - if (resultSet.next()) { - LOGGER.log(Level.INFO, "Testing connection to sqlite success."); // NON-NLS - } } catch (ClassNotFoundException | SQLException ex) { - LOGGER.log(Level.INFO, "Testing connection to sqlite failed.", ex); // NON-NLS + LOGGER.log(Level.SEVERE, "Failed to acquire ephemeral connection to sqlite.", ex); // NON-NLS + return 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. + */ + public boolean verifyConnection() { + Connection conn = getEphemeralConnection(); + if (null == conn) { + return false; + } + + boolean result = EamDbUtil.executeValidationQuery(conn, VALIDATION_QUERY); + try { + EamDbUtil.closeConnection(conn); + } catch (EamDbException ex) { + LOGGER.log(Level.SEVERE, "verifyConnection failed to close resources.", ex); + } + return result; + } + + /** + * 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(); + if (null == conn) { 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 - } - } } + boolean result = EamDbUtil.schemaVersionIsSet(conn); + try { + EamDbUtil.closeConnection(conn); + } catch (EamDbException ex) { + LOGGER.log(Level.SEVERE, "verifyDatabaseSchema failed to close resources.", ex); + } + return result; + } + + /** + * 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 integer primary key autoincrement NOT NULL,"); + 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 integer primary key autoincrement NOT NULL,"); + 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("CONSTRAINT case_uid_unique UNIQUE(case_uid)"); + 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 integer primary key autoincrement NOT NULL,"); + 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 integer primary key autoincrement NOT NULL,"); + 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 integer primary key autoincrement NOT NULL,"); + 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 integer primary key autoincrement NOT NULL,"); + 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 integer primary key autoincrement NOT NULL,"); + 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 integer 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(); + Statement stmt = conn.createStatement(); + stmt.execute(PRAGMA_JOURNAL_WAL); + stmt.execute(PRAGMA_SYNC_OFF); + stmt.execute(PRAGMA_READ_UNCOMMITTED_TRUE); + stmt.execute(PRAGMA_ENCODING_UTF8); + stmt.execute(PRAGMA_PAGE_SIZE_4096); + stmt.execute(PRAGMA_FOREIGN_KEYS_ON); + + 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 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 { + try { + EamDbUtil.closeConnection(conn); + } catch (EamDbException ex) { + LOGGER.log(Level.SEVERE, "initializeDatabaseSchema failed to close resources.", ex); + } + } return true; } + public boolean insertDefaultDatabaseContent() { + Connection conn = getEphemeralConnection(); + if (null == conn) { + return false; + } + + try { + EamDbUtil.insertDefaultArtifactTypes(conn); + EamDbUtil.insertSchemaVersion(conn); + } catch (EamDbException ex) { + 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() { String dbNameString = ModuleSettings.getConfigSetting("EnterpriseArtifactsManager", "db.sqlite.dbName"); // NON-NLS String dbDirectoryString = ModuleSettings.getConfigSetting("EnterpriseArtifactsManager", "db.sqlite.dbDirectory"); // NON-NLS diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/EamDbSettingsDialog.java b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/EamDbSettingsDialog.java index 785c1110b6..9d11ff16c7 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/EamDbSettingsDialog.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/EamDbSettingsDialog.java @@ -44,9 +44,10 @@ public class EamDbSettingsDialog extends JDialog { private final ImageIcon goodIcon; private final ImageIcon badIcon; - private PostgresEamDbSettings dbSettingsPostgres; - private SqliteEamDbSettings dbSettingsSqlite; - private Boolean hasChanged; + private final PostgresEamDbSettings dbSettingsPostgres; + private final SqliteEamDbSettings dbSettingsSqlite; + private DatabaseTestResult testingStatus; + private Boolean isCreated; /** * Creates new form EamDbSettingsDialog @@ -62,8 +63,12 @@ public class EamDbSettingsDialog extends JDialog { goodIcon = new ImageIcon(ImageUtilities.loadImage("org/sleuthkit/autopsy/images/good.png", false)); // NON-NLS badIcon = new ImageIcon(ImageUtilities.loadImage("org/sleuthkit/autopsy/images/bad.png", false)); // NON-NLS + dbSettingsPostgres = new PostgresEamDbSettings(); + dbSettingsSqlite = new SqliteEamDbSettings(); + initComponents(); customizeComponents(); + valid(); display(); } @@ -378,9 +383,6 @@ public class EamDbSettingsDialog extends JDialog { }// //GEN-END:initComponents private void customizeComponents() { - setTextPrompts(); - setTextBoxListeners(); - bnGrpDatabasePlatforms.add(rdioBnDisabled); bnGrpDatabasePlatforms.add(rdioBnPostgreSQL); bnGrpDatabasePlatforms.add(rdioBnSQLite); @@ -389,14 +391,27 @@ public class EamDbSettingsDialog extends JDialog { switch (selectedPlatform) { case POSTGRESQL: rdioBnPostgreSQL.setSelected(true); + testingStatus = DatabaseTestResult.UNTESTED; + updatePostgresFields(true); + updateSqliteFields(false); break; case SQLITE: rdioBnSQLite.setSelected(true); + testingStatus = DatabaseTestResult.UNTESTED; + updatePostgresFields(false); + updateSqliteFields(true); break; default: rdioBnDisabled.setSelected(true); + testingStatus = DatabaseTestResult.TESTEDOK; + updatePostgresFields(false); + updateSqliteFields(false); + break; } + setTextPrompts(); + setTextBoxListeners(); + } private void display() { @@ -405,20 +420,18 @@ public class EamDbSettingsDialog extends JDialog { setVisible(true); } + @Messages({"EamDbSettingsDialog.chooserPath.failedToGetDbPathMsg=Selected database path is invalid. Try again."}) private void bnDatabasePathFileOpenActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnDatabasePathFileOpenActionPerformed -// fcDatabasePath.setCurrentDirectory(new File(dbSettings.getDbDirectory())); -// fcDatabasePath.setSelectedFile(new File(dbSettings.getFileNameWithPath())); + fcDatabasePath.setCurrentDirectory(new File(dbSettingsSqlite.getDbDirectory())); + fcDatabasePath.setSelectedFile(new File(dbSettingsSqlite.getFileNameWithPath())); if (fcDatabasePath.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) { File databaseFile = fcDatabasePath.getSelectedFile(); try { tfDatabasePath.setText(databaseFile.getCanonicalPath()); valid(); - // TODO: create the db/schema if it doesn't exist. - // TODO: set variable noting that we created a new db, so it can be removed if Cancel button is clicked. - } catch (IOException ex) { LOGGER.log(Level.SEVERE, "Failed to get path of selected database file", ex); // NON-NLS - JOptionPane.showMessageDialog(this, Bundle.EnterpriseArtifactsManagerSQLiteSettingsDialog_chooserPath_failedToGetDbPathMsg()); + JOptionPane.showMessageDialog(this, Bundle.EamDbSettingsDialog_chooserPath_failedToGetDbPathMsg()); } } }//GEN-LAST:event_bnDatabasePathFileOpenActionPerformed @@ -426,23 +439,60 @@ public class EamDbSettingsDialog extends JDialog { private void bnTestActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnTestActionPerformed // lbTestDatabase.setIcon(null); // lbTestDatabase.setText(""); -// setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); -// -// if (dbSettings.testSettings()) { -// lbTestDatabase.setIcon(goodIcon); -// } else { -// lbTestDatabase.setIcon(badIcon); -// } + boolean connectionOk; + boolean schemaOk; + setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); + + EamDbPlatformEnum selectedPlatform = EamDbPlatformEnum.getSelectedPlatform(); + switch (selectedPlatform) { + case POSTGRESQL: + connectionOk = dbSettingsPostgres.testConnectionSettings(); + break; + case SQLITE: + if (dbSettingsSqlite.dbDirectoryExists() + && dbSettingsSqlite.verifyConnection()) { + if (dbSettingsSqlite.verifyDatabaseSchema()) { + testingStatus = DatabaseTestResult.TESTEDOK; + } else { + testingStatus = DatabaseTestResult.SCHEMA_INVALID; + } + } else { + testingStatus = DatabaseTestResult.SCHEMA_INVALID; + } + break; + } -// setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); + setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); + valid(); }//GEN-LAST:event_bnTestActionPerformed + @Messages({"EamDbSettingsDialog.creation.failed=Database initialization failed."}) private void bnCreateDbActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnCreateDbActionPerformed - // TODO add your handling code here: + + setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); + EamDbPlatformEnum selectedPlatform = EamDbPlatformEnum.getSelectedPlatform(); + boolean result = false; + switch (selectedPlatform) { + case POSTGRESQL: + break; + case SQLITE: + if (!dbSettingsSqlite.dbDirectoryExists()) { + dbSettingsSqlite.createDbDirectory(); + } + result = dbSettingsSqlite.initializeDatabaseSchema() + && dbSettingsSqlite.insertDefaultDatabaseContent(); + break; + } + setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); + if (false == result) { + taSetupGuidance.setText(Bundle.EamDbSettingsDialog_creation_failed()); + } else { + valid(); + } }//GEN-LAST:event_bnCreateDbActionPerformed private void bnOkActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnOkActionPerformed - hasChanged = true; +// hasChanged = true; // dbSettings.setEnabled(true); // dbSettings.saveSettings(); dispose(); @@ -453,32 +503,62 @@ public class EamDbSettingsDialog extends JDialog { }//GEN-LAST:event_bnCancelActionPerformed private void rdioBnDisabledActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_rdioBnDisabledActionPerformed - String text = taSetupGuidance.getText(); - if (rdioBnDisabled.isSelected()) { - taSetupGuidance.setText((text + ",selected Disabled")); - } else { - taSetupGuidance.setText((text + ",de-selected Disabled")); - } + EamDbPlatformEnum.setSelectedPlatform(EamDbPlatformEnum.DISABLED.toString()); + testingStatus = DatabaseTestResult.TESTEDOK; + + updateSqliteFields(false); + updatePostgresFields(false); }//GEN-LAST:event_rdioBnDisabledActionPerformed - private void rdioBnSQLiteActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_rdioBnSQLiteActionPerformed - String text = taSetupGuidance.getText(); - if (rdioBnSQLite.isSelected()) { - taSetupGuidance.setText((text + ",selected SQLite")); - } else { - taSetupGuidance.setText((text + ",de-selected SQLite")); - } - }//GEN-LAST:event_rdioBnSQLiteActionPerformed private void rdioBnPostgreSQLActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_rdioBnPostgreSQLActionPerformed - String text = taSetupGuidance.getText(); - if (rdioBnPostgreSQL.isSelected()) { - taSetupGuidance.setText((text + ",selected PostgreSQL")); - } else { - taSetupGuidance.setText((text + ",de-selected PostgreSQL")); - } + EamDbPlatformEnum.setSelectedPlatform(EamDbPlatformEnum.POSTGRESQL.toString()); + testingStatus = DatabaseTestResult.UNTESTED; + + updateSqliteFields(false); + updatePostgresFields(true); }//GEN-LAST:event_rdioBnPostgreSQLActionPerformed + private void rdioBnSQLiteActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_rdioBnSQLiteActionPerformed + EamDbPlatformEnum.setSelectedPlatform(EamDbPlatformEnum.SQLITE.toString()); + testingStatus = DatabaseTestResult.UNTESTED; + + updateSqliteFields(true); + updatePostgresFields(false); + + }//GEN-LAST:event_rdioBnSQLiteActionPerformed + + /** + * Update the fields for the Postgres platform depending on whether the + * Postgres radioButton is enabled. + * + * @param enabled + */ + private void updatePostgresFields(boolean enabled) { + tbDbHostname.setText(enabled ? dbSettingsPostgres.getHost() : ""); + tbDbHostname.setEnabled(enabled); + tbDbPort.setText(enabled ? Integer.toString(dbSettingsPostgres.getPort()) : ""); + tbDbPort.setEnabled(enabled); + tbDbName.setText(enabled ? dbSettingsPostgres.getDbName() : ""); + tbDbName.setEnabled(enabled); + tbDbUsername.setText(enabled ? dbSettingsPostgres.getUserName() : ""); + tbDbUsername.setEnabled(enabled); + tbDbPassword.setText(enabled ? dbSettingsPostgres.getPassword() : ""); + tbDbPassword.setEnabled(enabled); + } + + /** + * Update the fields for the SQLite platform depending on whether the + * SQLite radioButton is enabled. + * + * @param enabled + */ + private void updateSqliteFields(boolean enabled) { + tfDatabasePath.setText(enabled ? dbSettingsSqlite.getFileNameWithPath() : ""); + tfDatabasePath.setEnabled(enabled); + bnDatabasePathFileOpen.setEnabled(enabled); + } + /** * Add text prompts to all of the text fields. */ @@ -508,7 +588,7 @@ public class EamDbSettingsDialog extends JDialog { // tbDbUsername.getDocument().putProperty("statusIcon", lbTestDatabase); // NON-NLS // tbDbPassword.getDocument().putProperty("statusIcon", lbTestDatabase); // NON-NLS // } -// +// /** * Register for notifications when the text boxes get updated. */ @@ -554,12 +634,29 @@ public class EamDbSettingsDialog extends JDialog { * * @return True or false. */ - private boolean databaseFieldsArePopulated() { - return !tbDbHostname.getText().trim().isEmpty() - && !tbDbPort.getText().trim().isEmpty() - && !tbDbName.getText().trim().isEmpty() - && !tbDbUsername.getText().trim().isEmpty() - && !tbDbPassword.getText().trim().isEmpty(); + @Messages({"EamDbSettingsDialog.validation.incompleteFields=Fill in all values for the selected database."}) + private boolean databaseFieldsArePopulated(EamDbPlatformEnum selectedPlatform) { + boolean result = true; + switch (selectedPlatform) { + case POSTGRESQL: + result = !tbDbHostname.getText().trim().isEmpty() + && !tbDbPort.getText().trim().isEmpty() + && !tbDbName.getText().trim().isEmpty() + && !tbDbUsername.getText().trim().isEmpty() + && !tbDbPassword.getText().trim().isEmpty(); + + break; + + case SQLITE: + result = !tfDatabasePath.getText().trim().isEmpty(); + break; + } + + if (!result) { + taSetupGuidance.setText(Bundle.EamDbSettingsDialog_validation_incompleteFields()); + } + + return result; } /** @@ -567,18 +664,9 @@ public class EamDbSettingsDialog extends JDialog { * * @return True or false. */ - @Messages({"EamDbSettingsDialog.validation.incompleteFields=Fill in all values"}) - private boolean checkFields() { - boolean result = true; - - boolean dbPopulated = databaseFieldsArePopulated(); - - if (!dbPopulated) { - // We don't even have everything filled out - result = false; - taSetupGuidance.setText(Bundle.EamDbSettingsDialog_validation_incompleteFields()); - } - return result; + private boolean checkFields(EamDbPlatformEnum selectedPlatform) { + return databaseFieldsArePopulated(selectedPlatform) + && databaseSettingsAreValid(selectedPlatform); } /** @@ -590,45 +678,81 @@ public class EamDbSettingsDialog extends JDialog { "EamDbSettingsDialog.validation.invalidPort=Invalid database port number.", "EamDbSettingsDialog.validation.invalidDbName=Invalid database name.", "EamDbSettingsDialog.validation.invalidDbUser=Invalid database username.", - "EamDbSettingsDialog.validation.invalidDbPassword=Invalid database password.",}) - private boolean databaseSettingsAreValid() { -/* - try { - dbSettings.setHost(tbDbHostname.getText().trim()); - } catch (EamDbException ex) { - taSetupGuidance.setText(Bundle.EamDbSettingsDialog_validation_invalidHost()); - return false; + "EamDbSettingsDialog.validation.invalidDbPassword=Invalid database password.", + "EamDbSettingsDialog.validation.invalidDbPath=Invalid database path."}) + private boolean databaseSettingsAreValid(EamDbPlatformEnum selectedPlatform) { + boolean result = true; + StringBuilder guidanceText = new StringBuilder(); + + switch (selectedPlatform) { + case POSTGRESQL: + try { + dbSettingsPostgres.setHost(tbDbHostname.getText().trim()); + } catch (EamDbException ex) { + if (!guidanceText.toString().isEmpty()) { + guidanceText.append(", "); + } + guidanceText.append(Bundle.EamDbSettingsDialog_validation_invalidHost()); + result = false; + } + + try { + dbSettingsPostgres.setPort(Integer.valueOf(tbDbPort.getText().trim())); + } catch (NumberFormatException | EamDbException ex) { + if (!guidanceText.toString().isEmpty()) { + guidanceText.append(", "); + } + guidanceText.append(Bundle.EamDbSettingsDialog_validation_invalidPort()); + result = false; + } + + try { + dbSettingsPostgres.setDbName(tbDbName.getText().trim()); + } catch (EamDbException ex) { + if (!guidanceText.toString().isEmpty()) { + guidanceText.append(", "); + } + guidanceText.append(Bundle.EamDbSettingsDialog_validation_invalidDbName()); + result = false; + } + + try { + dbSettingsPostgres.setUserName(tbDbUsername.getText().trim()); + } catch (EamDbException ex) { + if (!guidanceText.toString().isEmpty()) { + guidanceText.append(", "); + } + guidanceText.append(Bundle.EamDbSettingsDialog_validation_invalidDbUser()); + result = false; + } + + try { + dbSettingsPostgres.setPassword(tbDbPassword.getText().trim()); + } catch (EamDbException ex) { + if (!guidanceText.toString().isEmpty()) { + guidanceText.append(", "); + } + guidanceText.append(Bundle.EamDbSettingsDialog_validation_invalidDbPassword()); + result = false; + } + break; + case SQLITE: + try { + File databasePath = new File(tfDatabasePath.getText()); + dbSettingsSqlite.setDbName(databasePath.getName()); + dbSettingsSqlite.setDbDirectory(databasePath.getParent()); + } catch (EamDbException ex) { + if (!guidanceText.toString().isEmpty()) { + guidanceText.append(", "); + } + guidanceText.append(Bundle.EamDbSettingsDialog_validation_invalidDbPath()); + result = false; + } + break; } - try { - dbSettings.setPort(Integer.valueOf(tbDbPort.getText().trim())); - } catch (NumberFormatException | EamDbException ex) { - taSetupGuidance.setText(Bundle.EamDbSettingsDialog_validation_invalidPort()); - return false; - } - - try { - dbSettings.setDbName(tbDbName.getText().trim()); - } catch (EamDbException ex) { - taSetupGuidance.setText(Bundle.EamDbSettingsDialog_validation_invalidDbName()); - return false; - } - - try { - dbSettings.setUserName(tbDbUsername.getText().trim()); - } catch (EamDbException ex) { - taSetupGuidance.setText(Bundle.EamDbSettingsDialog_validation_invalidDbUser()); - return false; - } - - try { - dbSettings.setPassword(tbDbPassword.getText().trim()); - } catch (EamDbException ex) { - taSetupGuidance.setText(Bundle.EamDbSettingsDialog_validation_invalidDbPassword()); - return false; - } -*/ - return true; + taSetupGuidance.setText(guidanceText.toString()); + return result; } /** @@ -636,16 +760,68 @@ public class EamDbSettingsDialog extends JDialog { * * @return true if it's okay, false otherwise. */ - public boolean valid() { -// taSetupGuidance.setText(""); -/* - return checkFields() - && enableTestDatabaseButton(databaseSettingsAreValid()) - && enableSaveButton(databaseSettingsAreValid()); -*/ - return true; + private boolean valid() { + taSetupGuidance.setText(""); + EamDbPlatformEnum selectedPlatform = EamDbPlatformEnum.getSelectedPlatform(); + return checkFields(selectedPlatform) + && enableTestButton(selectedPlatform) + && enableCreateButton() + && enableOkButton(); } + /** + * Enable the "Test" button once all fields are valid. + * + * @return true + */ + @Messages({"EamDbSettingsDialog.validation.mustTest=Once you are statisfied with the database settings, click the Test button to test the database connection, settings, and schema.", + "EamDbSettingsDialog.validation.failedConnection=The connection to the database failed. Update the settings and try the Test again."}) + private boolean enableTestButton(EamDbPlatformEnum selectedPlatform) { + if (selectedPlatform != EamDbPlatformEnum.DISABLED) { + bnTest.setEnabled(true); + if (testingStatus == DatabaseTestResult.UNTESTED) { + taSetupGuidance.setText(Bundle.EamDbSettingsDialog_validation_mustTest()); + } else if (testingStatus == DatabaseTestResult.CONNECTION_FAILED) { + taSetupGuidance.setText(Bundle.EamDbSettingsDialog_validation_failedConnection()); + } + } else { + bnTest.setEnabled(false); + } + return true; + } + + /** + * Enable the "Create" button if the db is not created. + * + * @return true if db is created, else false + */ + @Messages({"EamDbSettingsDialog.validation.dbNotCreated=The database does not exist. Click the Create button to create and initialize the database."}) + private boolean enableCreateButton() { + if (testingStatus == DatabaseTestResult.SCHEMA_INVALID) { + bnCreateDb.setEnabled(true); + taSetupGuidance.setText(Bundle.EamDbSettingsDialog_validation_dbNotCreated()); + } else { + bnCreateDb.setEnabled(false); + } + return true; + } + + /** + * Enable the "OK" button if the db test passed. Disabled defaults to db test passed. + * + * @return true + */ + @Messages({"EamDbSettingsDialog.validation.finished=Click OK to save your database settings and return to the Options."}) + private boolean enableOkButton() { + if (testingStatus == DatabaseTestResult.TESTEDOK) { + bnOk.setEnabled(true); + taSetupGuidance.setText(Bundle.EamDbSettingsDialog_validation_finished()); + } else { + bnOk.setEnabled(false); + } + return true; + } + /** * Used to listen for changes in text boxes. It lets the panel know things * have been updated and that validation needs to happen. @@ -682,6 +858,13 @@ public class EamDbSettingsDialog extends JDialog { valid(); } } + + private enum DatabaseTestResult { + UNTESTED, + CONNECTION_FAILED, + SCHEMA_INVALID, + TESTEDOK; + } // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JButton bnCancel; diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/EamPostgresSettingsDialog.form b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/EamPostgresSettingsDialog.form deleted file mode 100644 index 31db936608..0000000000 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/EamPostgresSettingsDialog.form +++ /dev/null @@ -1,246 +0,0 @@ - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/EamPostgresSettingsDialog.java b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/EamPostgresSettingsDialog.java deleted file mode 100644 index 148551ffce..0000000000 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/EamPostgresSettingsDialog.java +++ /dev/null @@ -1,545 +0,0 @@ -/* - * Enterprise Artifacts Manager - * - * Copyright 2015-2017 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.experimental.enterpriseartifactsmanager.optionspanel; - -import java.awt.Color; -import java.awt.Cursor; -import java.awt.Dimension; -import java.awt.Toolkit; -import java.util.ArrayList; -import java.util.Collection; -import javax.swing.ImageIcon; -import javax.swing.JFrame; -import javax.swing.JTextField; -import javax.swing.event.DocumentEvent; -import javax.swing.event.DocumentListener; -import org.netbeans.spi.options.OptionsPanelController; -import org.openide.util.ImageUtilities; -import org.openide.util.NbBundle; -import org.openide.util.NbBundle.Messages; -import org.openide.windows.WindowManager; -import org.sleuthkit.autopsy.corecomponents.TextPrompt; -import org.sleuthkit.autopsy.coreutils.Logger; -import org.sleuthkit.autopsy.experimental.enterpriseartifactsmanager.datamodel.EamDbException; -import org.sleuthkit.autopsy.experimental.enterpriseartifactsmanager.datamodel.PostgresEamDbSettings; - -/** - * Settings panel for the postgres-specific options - */ -public class EamPostgresSettingsDialog extends javax.swing.JDialog { - - private static final Logger LOGGER = Logger.getLogger(EamSqliteSettingsDialog.class.getName()); - private final ImageIcon goodIcon; - private final ImageIcon badIcon; - private final Collection textBoxes; - private final TextBoxChangedListener textBoxChangedListener; - - private final PostgresEamDbSettings dbSettings; - private Boolean hasChanged; - - /** - * Creates new form EnterpriseArtifactsManagerPostgresSettingsDialog - */ - @NbBundle.Messages({"EnterpriseArtifactsManagerPostgresSettingsDialog.postgresSettingsMessage.text=PostgreSQL Database Settings"}) - public EamPostgresSettingsDialog() { - super((JFrame) WindowManager.getDefault().getMainWindow(), - Bundle.EnterpriseArtifactsManagerPostgresSettingsDialog_postgresSettingsMessage_text(), - true); // NON-NLS - - textBoxes = new ArrayList<>(); - textBoxChangedListener = new TextBoxChangedListener(); - this.dbSettings = new PostgresEamDbSettings(); - goodIcon = new ImageIcon(ImageUtilities.loadImage("org/sleuthkit/autopsy/images/good.png", false)); // NON-NLS - badIcon = new ImageIcon(ImageUtilities.loadImage("org/sleuthkit/autopsy/images/bad.png", false)); // NON-NLS - - initComponents(); - customizeComponents(); - display(); - } - - /** - * Let calling object determine if this dialog made any changes. - * - * @return true or false - */ - public Boolean isChanged() { - return hasChanged; - } - - private void customizeComponents() { - hasChanged = false; - lbTestDatabaseWarning.setText(""); - setTextPrompts(); - setTextBoxStatusIcons(); - setTextBoxListeners(); - tbDbHostname.setText(dbSettings.getHost()); - tbDbPort.setText(Integer.toString(dbSettings.getPort())); - tbDbName.setText(dbSettings.getDbName()); - tbDbUsername.setText(dbSettings.getUserName()); - tbDbPassword.setText(dbSettings.getPassword()); - - enableTestDatabaseButton(false); - enableSaveButton(false); - this.valid(); - } - - private void display() { - Dimension screenDimension = Toolkit.getDefaultToolkit().getScreenSize(); - setLocation((screenDimension.width - getSize().width) / 2, (screenDimension.height - getSize().height) / 2); - setVisible(true); - } - - /** - * Add text prompts to all of the text fields. - */ - @Messages({"EnterpriseArtifactsManagerPostgresSettingsDialog.textPrompt.hostnameOrIP=Hostname or IP Address", - "EnterpriseArtifactsManagerPostgresSettingsDialog.textPrompt.port=Port Number", - "EnterpriseArtifactsManagerPostgresSettingsDialog.textPrompt.dbName=Database Name", - "EnterpriseArtifactsManagerPostgresSettingsDialog.textPrompt.user=Database User", - "EnterpriseArtifactsManagerPostgresSettingsDialog.textPrompt.password=Database User's Password"}) - private void setTextPrompts() { - Collection textPrompts = new ArrayList<>(); - textPrompts.add(new TextPrompt(Bundle.EnterpriseArtifactsManagerPostgresSettingsDialog_textPrompt_hostnameOrIP(), tbDbHostname)); - textPrompts.add(new TextPrompt(Bundle.EnterpriseArtifactsManagerPostgresSettingsDialog_textPrompt_port(), tbDbPort)); - textPrompts.add(new TextPrompt(Bundle.EnterpriseArtifactsManagerPostgresSettingsDialog_textPrompt_dbName(), tbDbName)); - textPrompts.add(new TextPrompt(Bundle.EnterpriseArtifactsManagerPostgresSettingsDialog_textPrompt_user(), tbDbUsername)); - textPrompts.add(new TextPrompt(Bundle.EnterpriseArtifactsManagerPostgresSettingsDialog_textPrompt_password(), tbDbPassword)); - configureTextPrompts(textPrompts); - } - - /** - * Set each textbox with a "statusIcon" property enabling the - * DocumentListeners to know which icon to erase when changes are made - */ - private void setTextBoxStatusIcons() { - tbDbHostname.getDocument().putProperty("statusIcon", lbTestDatabase); // NON-NLS - tbDbPort.getDocument().putProperty("statusIcon", lbTestDatabase); // NON-NLS - tbDbName.getDocument().putProperty("statusIcon", lbTestDatabase); // NON-NLS - tbDbUsername.getDocument().putProperty("statusIcon", lbTestDatabase); // NON-NLS - tbDbPassword.getDocument().putProperty("statusIcon", lbTestDatabase); // NON-NLS - } - - /** - * Register for notifications when the text boxes get updated. - */ - private void setTextBoxListeners() { - textBoxes.add(tbDbHostname); - textBoxes.add(tbDbPort); - textBoxes.add(tbDbName); - textBoxes.add(tbDbUsername); - textBoxes.add(tbDbPassword); - addDocumentListeners(textBoxes, textBoxChangedListener); - } - - /** - * Sets the foreground color and transparency of a collection of text - * prompts. - * - * @param textPrompts The text prompts to configure. - */ - private static void configureTextPrompts(Collection textPrompts) { - float alpha = 0.9f; // Mostly opaque - for (TextPrompt textPrompt : textPrompts) { - textPrompt.setForeground(Color.LIGHT_GRAY); - textPrompt.changeAlpha(alpha); - } - } - - /** - * Adds a change listener to a collection of text fields. - * - * @param textFields The text fields. - * @param listener The change listener. - */ - private static void addDocumentListeners(Collection textFields, TextBoxChangedListener listener) { - textFields.forEach((textField) -> { - textField.getDocument().addDocumentListener(listener); - }); - } - - /** - * Tests whether or not values have been entered in all of the database - * settings text fields. - * - * @return True or false. - */ - private boolean databaseFieldsArePopulated() { - return !tbDbHostname.getText().trim().isEmpty() - && !tbDbPort.getText().trim().isEmpty() - && !tbDbName.getText().trim().isEmpty() - && !tbDbUsername.getText().trim().isEmpty() - && !tbDbPassword.getText().trim().isEmpty(); - } - - /** - * Tests whether or not all of the settings components are populated. - * - * @return True or false. - */ - @Messages({"EnterpriseArtifactsManagerPostgresSettingsDialog.validation.incompleteFields=Fill in all values"}) - private boolean checkFields() { - boolean result = true; - - boolean dbPopulated = databaseFieldsArePopulated(); - - if (!dbPopulated) { - // We don't even have everything filled out - result = false; - lbTestDatabaseWarning.setText(Bundle.EnterpriseArtifactsManagerPostgresSettingsDialog_validation_incompleteFields()); - } - return result; - } - - /** - * Tests whether or not the database settings are valid. - * - * @return True or false. - */ - @Messages({"EnterpriseArtifactsManagerPostgresSettingsDialog.validation.invalidHost=Invalid database hostname.", - "EnterpriseArtifactsManagerPostgresSettingsDialog.validation.invalidPort=Invalid database port number.", - "EnterpriseArtifactsManagerPostgresSettingsDialog.validation.invalidDbName=Invalid database name.", - "EnterpriseArtifactsManagerPostgresSettingsDialog.validation.invalidDbUser=Invalid database username.", - "EnterpriseArtifactsManagerPostgresSettingsDialog.validation.invalidDbPassword=Invalid database password.",}) - private boolean databaseSettingsAreValid() { - - try { - dbSettings.setHost(tbDbHostname.getText().trim()); - } catch (EamDbException ex) { - lbTestDatabaseWarning.setText(Bundle.EnterpriseArtifactsManagerPostgresSettingsDialog_validation_invalidHost()); - return false; - } - - try { - dbSettings.setPort(Integer.valueOf(tbDbPort.getText().trim())); - } catch (NumberFormatException | EamDbException ex) { - lbTestDatabaseWarning.setText(Bundle.EnterpriseArtifactsManagerPostgresSettingsDialog_validation_invalidPort()); - return false; - } - - try { - dbSettings.setDbName(tbDbName.getText().trim()); - } catch (EamDbException ex) { - lbTestDatabaseWarning.setText(Bundle.EnterpriseArtifactsManagerPostgresSettingsDialog_validation_invalidDbName()); - return false; - } - - try { - dbSettings.setUserName(tbDbUsername.getText().trim()); - } catch (EamDbException ex) { - lbTestDatabaseWarning.setText(Bundle.EnterpriseArtifactsManagerPostgresSettingsDialog_validation_invalidDbUser()); - return false; - } - - try { - dbSettings.setPassword(tbDbPassword.getText().trim()); - } catch (EamDbException ex) { - lbTestDatabaseWarning.setText(Bundle.EnterpriseArtifactsManagerPostgresSettingsDialog_validation_invalidDbPassword()); - return false; - } - - return true; - } - - /** - * Validates that the form is filled out correctly for our usage. - * - * @return true if it's okay, false otherwise. - */ - public boolean valid() { - lbTestDatabaseWarning.setText(""); - - return checkFields() - && enableTestDatabaseButton(databaseSettingsAreValid()) - && enableSaveButton(databaseSettingsAreValid()); - } - - /** - * Enables the "Test Connection" button to test the database settings. - * - * @param enable - * - * @return True or False - */ - private boolean enableTestDatabaseButton(Boolean enable) { - bnTestConnection.setEnabled(enable); - return enable; - } - - /** - * Enables the "Save" button to save the database settings. - * - * @param enable - * - * @return True or False - */ - private boolean enableSaveButton(Boolean enable) { - bnSave.setEnabled(enable); - return enable; - } - - /** - * Used to listen for changes in text boxes. It lets the panel know things - * have been updated and that validation needs to happen. - */ - private class TextBoxChangedListener implements DocumentListener { - - @Override - public void changedUpdate(DocumentEvent e) { - Object statusIcon = e.getDocument().getProperty("statusIcon"); // NON-NLS - if (statusIcon != null) { - ((javax.swing.JLabel) statusIcon).setIcon(null); - } - firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); - valid(); - } - - @Override - public void insertUpdate(DocumentEvent e) { - Object statusIcon = e.getDocument().getProperty("statusIcon"); // NON-NLS - if (statusIcon != null) { - ((javax.swing.JLabel) statusIcon).setIcon(null); - } - firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); - valid(); - } - - @Override - public void removeUpdate(DocumentEvent e) { - Object statusIcon = e.getDocument().getProperty("statusIcon"); // NON-NLS - if (statusIcon != null) { - ((javax.swing.JLabel) statusIcon).setIcon(null); - } - firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); - valid(); - } - } - - /** - * 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() { - - pnOuter = new javax.swing.JPanel(); - jScrollPane = new javax.swing.JScrollPane(); - pnContent = new javax.swing.JPanel(); - lbHostName = new javax.swing.JLabel(); - lbPort = new javax.swing.JLabel(); - lbUserName = new javax.swing.JLabel(); - lbUserPassword = new javax.swing.JLabel(); - lbDatabaseName = new javax.swing.JLabel(); - tbDbHostname = new javax.swing.JTextField(); - tbDbPort = new javax.swing.JTextField(); - tbDbName = new javax.swing.JTextField(); - tbDbUsername = new javax.swing.JTextField(); - tbDbPassword = new javax.swing.JTextField(); - bnTestConnection = new javax.swing.JButton(); - bnSave = new javax.swing.JButton(); - bnCancel = new javax.swing.JButton(); - lbTestDatabaseWarning = new javax.swing.JLabel(); - lbTestDatabase = new javax.swing.JLabel(); - - setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); - - org.openide.awt.Mnemonics.setLocalizedText(lbHostName, org.openide.util.NbBundle.getMessage(EamPostgresSettingsDialog.class, "EamPostgresSettingsDialog.lbHostName.text")); // NOI18N - - org.openide.awt.Mnemonics.setLocalizedText(lbPort, org.openide.util.NbBundle.getMessage(EamPostgresSettingsDialog.class, "EamPostgresSettingsDialog.lbPort.text")); // NOI18N - - org.openide.awt.Mnemonics.setLocalizedText(lbUserName, org.openide.util.NbBundle.getMessage(EamPostgresSettingsDialog.class, "EamPostgresSettingsDialog.lbUserName.text")); // NOI18N - - org.openide.awt.Mnemonics.setLocalizedText(lbUserPassword, org.openide.util.NbBundle.getMessage(EamPostgresSettingsDialog.class, "EamPostgresSettingsDialog.lbUserPassword.text")); // NOI18N - - org.openide.awt.Mnemonics.setLocalizedText(lbDatabaseName, org.openide.util.NbBundle.getMessage(EamPostgresSettingsDialog.class, "EamPostgresSettingsDialog.lbDatabaseName.text")); // NOI18N - - org.openide.awt.Mnemonics.setLocalizedText(bnTestConnection, org.openide.util.NbBundle.getMessage(EamPostgresSettingsDialog.class, "EamPostgresSettingsDialog.bnTestConnection.text")); // NOI18N - bnTestConnection.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - bnTestConnectionActionPerformed(evt); - } - }); - - org.openide.awt.Mnemonics.setLocalizedText(bnSave, org.openide.util.NbBundle.getMessage(EamPostgresSettingsDialog.class, "EamPostgresSettingsDialog.bnSave.text")); // NOI18N - bnSave.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - bnSaveActionPerformed(evt); - } - }); - - org.openide.awt.Mnemonics.setLocalizedText(bnCancel, org.openide.util.NbBundle.getMessage(EamPostgresSettingsDialog.class, "EamPostgresSettingsDialog.bnCancel.text")); // NOI18N - bnCancel.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - bnCancelActionPerformed(evt); - } - }); - - lbTestDatabaseWarning.setFont(new java.awt.Font("Tahoma", 1, 12)); // NOI18N - lbTestDatabaseWarning.setForeground(new java.awt.Color(255, 0, 0)); - - javax.swing.GroupLayout pnContentLayout = new javax.swing.GroupLayout(pnContent); - pnContent.setLayout(pnContentLayout); - pnContentLayout.setHorizontalGroup( - pnContentLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(pnContentLayout.createSequentialGroup() - .addContainerGap() - .addGroup(pnContentLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(pnContentLayout.createSequentialGroup() - .addComponent(bnTestConnection) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(lbTestDatabase, javax.swing.GroupLayout.PREFERRED_SIZE, 19, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGap(153, 153, 153) - .addComponent(bnSave) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(bnCancel)) - .addGroup(pnContentLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false) - .addComponent(lbTestDatabaseWarning, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addGroup(javax.swing.GroupLayout.Alignment.LEADING, pnContentLayout.createSequentialGroup() - .addGroup(pnContentLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(lbHostName) - .addComponent(lbPort) - .addComponent(lbDatabaseName) - .addComponent(lbUserName) - .addComponent(lbUserPassword)) - .addGap(18, 18, 18) - .addGroup(pnContentLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) - .addComponent(tbDbPassword, javax.swing.GroupLayout.DEFAULT_SIZE, 322, Short.MAX_VALUE) - .addComponent(tbDbUsername) - .addComponent(tbDbName) - .addComponent(tbDbHostname) - .addComponent(tbDbPort, javax.swing.GroupLayout.PREFERRED_SIZE, 67, javax.swing.GroupLayout.PREFERRED_SIZE))))) - .addGap(0, 11, Short.MAX_VALUE)) - ); - pnContentLayout.setVerticalGroup( - pnContentLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(pnContentLayout.createSequentialGroup() - .addContainerGap() - .addGroup(pnContentLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) - .addComponent(tbDbHostname, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(lbHostName, javax.swing.GroupLayout.PREFERRED_SIZE, 22, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(pnContentLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) - .addComponent(tbDbPort) - .addComponent(lbPort, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(pnContentLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) - .addComponent(tbDbName) - .addComponent(lbDatabaseName, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(pnContentLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) - .addComponent(tbDbUsername) - .addComponent(lbUserName, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(pnContentLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .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)) - .addGap(37, 37, 37) - .addComponent(lbTestDatabaseWarning, javax.swing.GroupLayout.PREFERRED_SIZE, 21, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addGroup(pnContentLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(bnTestConnection) - .addComponent(bnSave) - .addComponent(bnCancel) - .addComponent(lbTestDatabase, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addGap(0, 0, Short.MAX_VALUE)) - ); - - jScrollPane.setViewportView(pnContent); - - javax.swing.GroupLayout pnOuterLayout = new javax.swing.GroupLayout(pnOuter); - pnOuter.setLayout(pnOuterLayout); - pnOuterLayout.setHorizontalGroup( - pnOuterLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGap(0, 448, Short.MAX_VALUE) - .addGroup(pnOuterLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(pnOuterLayout.createSequentialGroup() - .addComponent(jScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 448, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGap(0, 0, Short.MAX_VALUE))) - ); - pnOuterLayout.setVerticalGroup( - pnOuterLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGap(0, 249, Short.MAX_VALUE) - .addGroup(pnOuterLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(pnOuterLayout.createSequentialGroup() - .addComponent(jScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 249, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGap(0, 0, Short.MAX_VALUE))) - ); - - javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); - getContentPane().setLayout(layout); - layout.setHorizontalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(pnOuter, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - ); - layout.setVerticalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(pnOuter, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - ); - - pack(); - }// //GEN-END:initComponents - - private void bnTestConnectionActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnTestConnectionActionPerformed - lbTestDatabase.setIcon(null); - lbTestDatabase.setText(""); - setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); - - if (dbSettings.testSettings()) { - lbTestDatabase.setIcon(goodIcon); - } else { - lbTestDatabase.setIcon(badIcon); - } - - setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); - - }//GEN-LAST:event_bnTestConnectionActionPerformed - - private void bnSaveActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnSaveActionPerformed - hasChanged = true; - dbSettings.setEnabled(true); - dbSettings.saveSettings(); - dispose(); - }//GEN-LAST:event_bnSaveActionPerformed - - private void bnCancelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnCancelActionPerformed - dispose(); - }//GEN-LAST:event_bnCancelActionPerformed - - // Variables declaration - do not modify//GEN-BEGIN:variables - private javax.swing.JButton bnCancel; - private javax.swing.JButton bnSave; - private javax.swing.JButton bnTestConnection; - private javax.swing.JScrollPane jScrollPane; - private javax.swing.JLabel lbDatabaseName; - private javax.swing.JLabel lbHostName; - private javax.swing.JLabel lbPort; - private javax.swing.JLabel lbTestDatabase; - private javax.swing.JLabel lbTestDatabaseWarning; - private javax.swing.JLabel lbUserName; - private javax.swing.JLabel lbUserPassword; - private javax.swing.JPanel pnContent; - private javax.swing.JPanel pnOuter; - private javax.swing.JTextField tbDbHostname; - private javax.swing.JTextField tbDbName; - private javax.swing.JTextField tbDbPassword; - private javax.swing.JTextField tbDbPort; - private javax.swing.JTextField tbDbUsername; - // End of variables declaration//GEN-END:variables -} diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/EamSqliteSettingsDialog.form b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/EamSqliteSettingsDialog.form deleted file mode 100644 index de9cad5ca8..0000000000 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/EamSqliteSettingsDialog.form +++ /dev/null @@ -1,218 +0,0 @@ - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/EamSqliteSettingsDialog.java b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/EamSqliteSettingsDialog.java deleted file mode 100644 index 60ff1f8f81..0000000000 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/EamSqliteSettingsDialog.java +++ /dev/null @@ -1,371 +0,0 @@ -/* - * Enterprise Artifacts Manager - * - * Copyright 2015-2017 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.experimental.enterpriseartifactsmanager.optionspanel; - -import java.awt.Cursor; -import java.awt.Dimension; -import java.awt.Toolkit; -import java.io.File; -import java.io.IOException; -import java.util.logging.Level; -import javax.swing.ImageIcon; -import javax.swing.JFileChooser; -import javax.swing.JFrame; -import javax.swing.JOptionPane; -import javax.swing.event.DocumentEvent; -import javax.swing.event.DocumentListener; -import javax.swing.filechooser.FileNameExtensionFilter; -import org.netbeans.spi.options.OptionsPanelController; -import org.openide.util.ImageUtilities; -import org.openide.util.NbBundle.Messages; -import org.openide.windows.WindowManager; -import org.sleuthkit.autopsy.coreutils.Logger; -import org.sleuthkit.autopsy.experimental.enterpriseartifactsmanager.datamodel.EamDbException; -import org.sleuthkit.autopsy.experimental.enterpriseartifactsmanager.datamodel.SqliteEamDbSettings; - -/** - * Settings panel for the sqlite-specific options - */ -public class EamSqliteSettingsDialog extends javax.swing.JDialog { - - private static final Logger LOGGER = Logger.getLogger(EamSqliteSettingsDialog.class.getName()); - private final ImageIcon goodIcon; - private final ImageIcon badIcon; - private final TextBoxChangedListener textBoxChangedListener; - - private final SqliteEamDbSettings dbSettings; - private Boolean hasChanged; - - /** - * Creates new form EnterpriseArtifactsManagerSQLiteSettingsDialog - */ - @Messages({"EnterpriseArtifactsManagerSQLiteSettingsDialog.sqliteSettingsMessage.text=SQLite Database Settings"}) - public EamSqliteSettingsDialog() { - super((JFrame) WindowManager.getDefault().getMainWindow(), - Bundle.EnterpriseArtifactsManagerSQLiteSettingsDialog_sqliteSettingsMessage_text(), - true); // NON-NLS - - this.dbSettings = new SqliteEamDbSettings(); - goodIcon = new ImageIcon(ImageUtilities.loadImage("org/sleuthkit/autopsy/images/good.png", false)); // NON-NLS - badIcon = new ImageIcon(ImageUtilities.loadImage("org/sleuthkit/autopsy/images/bad.png", false)); // NON-NLS - textBoxChangedListener = new TextBoxChangedListener(); - - initComponents(); - customizeComponents(); - valid(); - display(); - } - - /** - * Let calling object determine if this dialog made any changes. - * - * @return true or false - */ - public Boolean isChanged() { - return hasChanged; - } - - private void customizeComponents() { - customizeFileChooser(); - tfDatabasePath.setText(dbSettings.getFileNameWithPath()); - lbTestDatabaseWarning.setText(""); - hasChanged = false; - tfDatabasePath.getDocument().addDocumentListener(textBoxChangedListener); - bnOk.setEnabled(false); - bnTestDatabase.setEnabled(false); - } - - @Messages({"EnterpriseArtifactsManagerSQLiteSettingsDialog.fileNameExtFilter.text=SQLite Database File"}) - private void customizeFileChooser() { - fcDatabasePath.setDragEnabled(false); - fcDatabasePath.setFileSelectionMode(JFileChooser.FILES_ONLY); - String[] EXTENSION = new String[]{"db"}; //NON-NLS - FileNameExtensionFilter filter = new FileNameExtensionFilter(Bundle.EnterpriseArtifactsManagerSQLiteSettingsDialog_fileNameExtFilter_text(), EXTENSION); // NON-NLS - fcDatabasePath.setFileFilter(filter); - fcDatabasePath.setMultiSelectionEnabled(false); - } - - private void display() { - Dimension screenDimension = Toolkit.getDefaultToolkit().getScreenSize(); - setLocation((screenDimension.width - getSize().width) / 2, (screenDimension.height - getSize().height) / 2); - setVisible(true); - } - - /** - * Used to listen for changes in text boxes. It lets the panel know things - * have been updated and that validation needs to happen. - */ - private class TextBoxChangedListener implements DocumentListener { - - @Override - public void changedUpdate(DocumentEvent e) { - firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); - valid(); - } - - @Override - public void insertUpdate(DocumentEvent e) { - firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); - valid(); - } - - @Override - public void removeUpdate(DocumentEvent e) { - firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); - valid(); - } - } - - private boolean valid() { - boolean result = false; - if (tfDatabasePath.getText().trim().isEmpty()) { - bnOk.setEnabled(false); - bnTestDatabase.setEnabled(false); - } else { - storeDbNameAndDirectory(); - bnOk.setEnabled(true); - bnTestDatabase.setEnabled(true); - result = true; - } - return result; - } - - /** - * Get the db file name and directory path from the file chooser and store - * in dbSettings. - */ - @Messages({"EnterpriseArtifactsManagerSQLiteSettingsDialog.storeDbNameAndDirectory.failedToSetDbNamePathMsg=Database filename or directory path is missing. Try again."}) - private void storeDbNameAndDirectory() { - File databasePath = new File(tfDatabasePath.getText()); - try { - dbSettings.setDbName(databasePath.getName()); - dbSettings.setDbDirectory(databasePath.getParent()); - } catch (EamDbException ex) { - LOGGER.log(Level.SEVERE, "Failed to set database name or directory path.", ex); // NON-NLS - JOptionPane.showMessageDialog(this, Bundle.EnterpriseArtifactsManagerSQLiteSettingsDialog_storeDbNameAndDirectory_failedToSetDbNamePathMsg()); - } - } - - /** - * 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() { - - fcDatabasePath = new javax.swing.JFileChooser(); - pnOuter = new javax.swing.JPanel(); - jScrollPane = new javax.swing.JScrollPane(); - pnContent = new javax.swing.JPanel(); - lbDatabasePath = new javax.swing.JLabel(); - tfDatabasePath = new javax.swing.JTextField(); - bnDatabasePathFileOpen = new javax.swing.JButton(); - lbTestDatabaseWarning = new javax.swing.JLabel(); - bnTestDatabase = new javax.swing.JButton(); - lbTestDatabase = new javax.swing.JLabel(); - bnCancel = new javax.swing.JButton(); - bnOk = new javax.swing.JButton(); - - setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); - - org.openide.awt.Mnemonics.setLocalizedText(lbDatabasePath, org.openide.util.NbBundle.getMessage(EamSqliteSettingsDialog.class, "EamSqliteSettingsDialog.lbDatabasePath.text")); // NOI18N - - tfDatabasePath.setText(org.openide.util.NbBundle.getMessage(EamSqliteSettingsDialog.class, "EamSqliteSettingsDialog.tfDatabasePath.text")); // NOI18N - tfDatabasePath.setToolTipText(org.openide.util.NbBundle.getMessage(EamSqliteSettingsDialog.class, "EamSqliteSettingsDialog.tfDatabasePath.toolTipText")); // NOI18N - - org.openide.awt.Mnemonics.setLocalizedText(bnDatabasePathFileOpen, org.openide.util.NbBundle.getMessage(EamSqliteSettingsDialog.class, "EamSqliteSettingsDialog.bnDatabasePathFileOpen.text")); // NOI18N - bnDatabasePathFileOpen.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - bnDatabasePathFileOpenActionPerformed(evt); - } - }); - - lbTestDatabaseWarning.setForeground(new java.awt.Color(255, 51, 51)); - org.openide.awt.Mnemonics.setLocalizedText(lbTestDatabaseWarning, org.openide.util.NbBundle.getMessage(EamSqliteSettingsDialog.class, "EamSqliteSettingsDialog.lbTestDatabaseWarning.text")); // NOI18N - - org.openide.awt.Mnemonics.setLocalizedText(bnTestDatabase, org.openide.util.NbBundle.getMessage(EamSqliteSettingsDialog.class, "EamSqliteSettingsDialog.bnTestDatabase.text")); // NOI18N - bnTestDatabase.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - bnTestDatabaseActionPerformed(evt); - } - }); - - org.openide.awt.Mnemonics.setLocalizedText(lbTestDatabase, org.openide.util.NbBundle.getMessage(EamSqliteSettingsDialog.class, "EamSqliteSettingsDialog.lbTestDatabase.text")); // NOI18N - lbTestDatabase.setName(""); // NOI18N - - org.openide.awt.Mnemonics.setLocalizedText(bnCancel, org.openide.util.NbBundle.getMessage(EamSqliteSettingsDialog.class, "EamSqliteSettingsDialog.bnCancel.text")); // NOI18N - bnCancel.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - bnCancelActionPerformed(evt); - } - }); - - org.openide.awt.Mnemonics.setLocalizedText(bnOk, org.openide.util.NbBundle.getMessage(EamSqliteSettingsDialog.class, "EamSqliteSettingsDialog.bnOk.text")); // NOI18N - bnOk.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - bnOkActionPerformed(evt); - } - }); - - javax.swing.GroupLayout pnContentLayout = new javax.swing.GroupLayout(pnContent); - pnContent.setLayout(pnContentLayout); - pnContentLayout.setHorizontalGroup( - pnContentLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(pnContentLayout.createSequentialGroup() - .addContainerGap() - .addGroup(pnContentLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(pnContentLayout.createSequentialGroup() - .addGroup(pnContentLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false) - .addComponent(lbTestDatabaseWarning, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addGroup(pnContentLayout.createSequentialGroup() - .addComponent(lbDatabasePath) - .addGap(18, 18, 18) - .addComponent(tfDatabasePath, javax.swing.GroupLayout.PREFERRED_SIZE, 343, javax.swing.GroupLayout.PREFERRED_SIZE))) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 57, Short.MAX_VALUE) - .addComponent(bnDatabasePathFileOpen) - .addGap(24, 24, 24)) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, pnContentLayout.createSequentialGroup() - .addComponent(bnTestDatabase) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(lbTestDatabase, javax.swing.GroupLayout.PREFERRED_SIZE, 30, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(bnOk) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(bnCancel) - .addContainerGap()))) - ); - pnContentLayout.setVerticalGroup( - pnContentLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(pnContentLayout.createSequentialGroup() - .addContainerGap() - .addGroup(pnContentLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(lbDatabasePath, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(tfDatabasePath, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(bnDatabasePathFileOpen)) - .addGap(18, 18, 18) - .addComponent(lbTestDatabaseWarning, javax.swing.GroupLayout.PREFERRED_SIZE, 22, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGroup(pnContentLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(pnContentLayout.createSequentialGroup() - .addGap(19, 19, 19) - .addGroup(pnContentLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(bnCancel) - .addComponent(bnOk))) - .addGroup(pnContentLayout.createSequentialGroup() - .addGap(18, 18, 18) - .addGroup(pnContentLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(lbTestDatabase, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(bnTestDatabase)))) - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - ); - - jScrollPane.setViewportView(pnContent); - - javax.swing.GroupLayout pnOuterLayout = new javax.swing.GroupLayout(pnOuter); - pnOuter.setLayout(pnOuterLayout); - pnOuterLayout.setHorizontalGroup( - pnOuterLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(jScrollPane) - ); - pnOuterLayout.setVerticalGroup( - pnOuterLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(jScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - ); - - javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); - getContentPane().setLayout(layout); - layout.setHorizontalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGap(0, 603, Short.MAX_VALUE) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(pnOuter, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - ); - layout.setVerticalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGap(0, 129, Short.MAX_VALUE) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addComponent(pnOuter, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGap(0, 0, Short.MAX_VALUE))) - ); - - pack(); - }// //GEN-END:initComponents - - @Messages({"EnterpriseArtifactsManagerSQLiteSettingsDialog.chooserPath.failedToGetDbPathMsg=Selected database path is invalid. Try again."}) - private void bnDatabasePathFileOpenActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnDatabasePathFileOpenActionPerformed - fcDatabasePath.setCurrentDirectory(new File(dbSettings.getDbDirectory())); - fcDatabasePath.setSelectedFile(new File(dbSettings.getFileNameWithPath())); - if (fcDatabasePath.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) { - File databaseFile = fcDatabasePath.getSelectedFile(); - try { - tfDatabasePath.setText(databaseFile.getCanonicalPath()); - valid(); - // TODO: create the db/schema if it doesn't exist. - // TODO: set variable noting that we created a new db, so it can be removed if Cancel button is clicked. - - } catch (IOException ex) { - LOGGER.log(Level.SEVERE, "Failed to get path of selected database file", ex); // NON-NLS - JOptionPane.showMessageDialog(this, Bundle.EnterpriseArtifactsManagerSQLiteSettingsDialog_chooserPath_failedToGetDbPathMsg()); - } - } - }//GEN-LAST:event_bnDatabasePathFileOpenActionPerformed - - private void bnTestDatabaseActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnTestDatabaseActionPerformed - lbTestDatabase.setIcon(null); - lbTestDatabaseWarning.setText(""); - setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); - - if (dbSettings.testSettings()) { - lbTestDatabase.setIcon(goodIcon); - } else { - lbTestDatabase.setIcon(badIcon); - } - - setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); - }//GEN-LAST:event_bnTestDatabaseActionPerformed - - private void bnCancelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnCancelActionPerformed - // TODO: if a new db was created, then delete it. update settings to disable this platform - dispose(); - }//GEN-LAST:event_bnCancelActionPerformed - - private void bnOkActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnOkActionPerformed - hasChanged = true; - dbSettings.setEnabled(true); - dbSettings.saveSettings(); - dispose(); - }//GEN-LAST:event_bnOkActionPerformed - - // Variables declaration - do not modify//GEN-BEGIN:variables - private javax.swing.JButton bnCancel; - private javax.swing.JButton bnDatabasePathFileOpen; - private javax.swing.JButton bnOk; - private javax.swing.JButton bnTestDatabase; - private javax.swing.JFileChooser fcDatabasePath; - private javax.swing.JScrollPane jScrollPane; - private javax.swing.JLabel lbDatabasePath; - private javax.swing.JLabel lbTestDatabase; - private javax.swing.JLabel lbTestDatabaseWarning; - private javax.swing.JPanel pnContent; - private javax.swing.JPanel pnOuter; - private javax.swing.JTextField tfDatabasePath; - // End of variables declaration//GEN-END:variables -} diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/GlobalSettingsPanel.java b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/GlobalSettingsPanel.java index 092bc9966b..7935354071 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/GlobalSettingsPanel.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/GlobalSettingsPanel.java @@ -276,7 +276,7 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i lbDbLocationValue.setText(dbSettingsSqlite.getDbDirectory()); break; default: - lbDbPlatformValue.setText(""); + lbDbPlatformValue.setText(EamDbPlatformEnum.DISABLED.toString()); lbDbNameValue.setText(""); lbDbLocationValue.setText(""); break; From fcd6b2ce08036ad0244e9551a8d980f9aa72c64a Mon Sep 17 00:00:00 2001 From: Nick Davis Date: Tue, 20 Jun 2017 15:09:55 -0400 Subject: [PATCH 09/20] postgresql settings UI is implemented. now to do cleanup/testing. --- .../actions/EamCaseEditDetailsDialog.java | 2 +- .../DataContentViewerOtherCases.java | 6 +- .../datamodel/AbstractSqlEamDb.java | 2 +- .../datamodel/EamDb.java | 11 +- .../datamodel/EamDbUtil.java | 48 +-- .../datamodel/PostgresEamDb.java | 173 --------- .../datamodel/PostgresEamDbSettings.java | 333 ++++++++++++++++-- .../datamodel/SqliteEamDb.java | 7 +- .../datamodel/SqliteEamDbSettings.java | 57 +-- .../eventlisteners/BadFileTagRunner.java | 2 +- .../eventlisteners/CaseEventListener.java | 8 +- .../eventlisteners/IngestEventsListener.java | 2 +- .../eventlisteners/NewArtifactsRunner.java | 2 +- .../ingestmodule/IngestModule.java | 6 +- .../optionspanel/EamDbSettingsDialog.form | 8 +- .../optionspanel/EamDbSettingsDialog.java | 62 +++- .../ImportHashDatabaseDialog.java | 4 +- 17 files changed, 404 insertions(+), 329 deletions(-) diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/actions/EamCaseEditDetailsDialog.java b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/actions/EamCaseEditDetailsDialog.java index d2f147419d..d8c24d1a58 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/actions/EamCaseEditDetailsDialog.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/actions/EamCaseEditDetailsDialog.java @@ -524,7 +524,7 @@ public class EamCaseEditDetailsDialog extends JDialog { private void updateDb() { setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); - if (!dbManager.isEnabled()) { + if (!EamDb.isEnabled()) { LOGGER.log(Level.SEVERE, "Enteprise artifacts manager database not enabled"); // NON-NLS return; } diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/contentviewer/DataContentViewerOtherCases.java b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/contentviewer/DataContentViewerOtherCases.java index e0ad406386..f4679d52a6 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/contentviewer/DataContentViewerOtherCases.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/contentviewer/DataContentViewerOtherCases.java @@ -504,8 +504,7 @@ public class DataContentViewerOtherCases extends javax.swing.JPanel implements D @Override public boolean isSupported(Node node) { - EamDb dbManager = EamDb.getInstance(); - if (!dbManager.isEnabled()) { + if (!EamDb.isEnabled()) { return false; } @@ -516,8 +515,7 @@ public class DataContentViewerOtherCases extends javax.swing.JPanel implements D @Override @Messages({"DataContentViewerOtherCases.table.nodbconnection=Cannot connect to enterprise artifacts manager database."}) public void setNode(Node node) { - EamDb dbManager = EamDb.getInstance(); - if (!dbManager.isEnabled()) { + if (!EamDb.isEnabled()) { return; } diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/AbstractSqlEamDb.java b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/AbstractSqlEamDb.java index 64c13420c1..5b0af7c6e6 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/AbstractSqlEamDb.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/AbstractSqlEamDb.java @@ -450,7 +450,7 @@ public abstract class AbstractSqlEamDb implements EamDb { PreparedStatement preparedStatement = 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 { preparedStatement = conn.prepareStatement(sql); diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/EamDb.java b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/EamDb.java index aaa688a783..0f7a1839cc 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/EamDb.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/EamDb.java @@ -27,9 +27,9 @@ public interface EamDb { 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 */ @@ -41,8 +41,9 @@ public interface EamDb { return PostgresEamDb.getInstance(); case SQLITE: - default: return SqliteEamDb.getInstance(); + default: + return null; } } @@ -66,7 +67,9 @@ public interface EamDb { * * @return Is the database enabled */ - boolean isEnabled(); + static boolean isEnabled() { + return EamDbPlatformEnum.getSelectedPlatform() != EamDbPlatformEnum.DISABLED; + } /** * Get the list of tags recognized as "Bad" diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/EamDbUtil.java b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/EamDbUtil.java index 1a19b3e27d..3d5dbe3d5c 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/EamDbUtil.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/EamDbUtil.java @@ -7,18 +7,22 @@ package org.sleuthkit.autopsy.experimental.enterpriseartifactsmanager.datamodel; import java.sql.Connection; +import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.List; import java.util.logging.Level; +import org.sleuthkit.autopsy.coreutils.Logger; import static org.sleuthkit.autopsy.experimental.enterpriseartifactsmanager.datamodel.EamDb.SCHEMA_VERSION; /** * */ public class EamDbUtil { + private final static Logger LOGGER = Logger.getLogger(EamDbUtil.class.getName()); + /** * Close the prepared statement. * @@ -26,12 +30,12 @@ public class EamDbUtil { * * @throws EamDbException */ - public static void closePreparedStatement(PreparedStatement preparedStatement) throws EamDbException { + public static void closePreparedStatement(PreparedStatement preparedStatement) { if (null != preparedStatement) { try { preparedStatement.close(); } 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 */ - public static void closeResultSet(ResultSet resultSet) throws EamDbException { + public static void closeResultSet(ResultSet resultSet) { if (null != resultSet) { try { resultSet.close(); } 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 */ - public static void closeConnection(Connection conn) throws EamDbException { + public static void closeConnection(Connection conn) { if (null != conn) { try { conn.close(); } 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. * - * @param conn An open database connection. - * - * @throws EamDbException + * @param conn Open connection to use. + * @return true on success, else false */ - public static void insertDefaultArtifactTypes(Connection conn) throws EamDbException { + public static boolean insertDefaultArtifactTypes(Connection conn) { PreparedStatement preparedStatement = null; List DEFAULT_ARTIFACT_TYPES = EamArtifact.getDefaultArtifactTypes(); String sql = "INSERT INTO artifact_types(name, supported, enabled) VALUES (?, ?, ?)"; @@ -92,10 +95,12 @@ public class EamDbUtil { } preparedStatement.executeBatch(); } 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 { EamDbUtil.closePreparedStatement(preparedStatement); } + return true; } /** @@ -104,9 +109,10 @@ public class EamDbUtil { * This should be called immediately following the database schema being * 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; String sql = "INSERT INTO db_info (name, value) VALUES (?, ?)"; try { @@ -115,10 +121,12 @@ public class EamDbUtil { preparedStatement.setString(2, String.valueOf(SCHEMA_VERSION)); preparedStatement.executeUpdate(); } 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 { EamDbUtil.closePreparedStatement(preparedStatement); } + return true; } /** @@ -142,10 +150,7 @@ public class EamDbUtil { } catch (SQLException ex) { return false; } finally { - try { - EamDbUtil.closeResultSet(resultSet); - } catch (EamDbException ex) { - } + EamDbUtil.closeResultSet(resultSet); } return true; } @@ -171,10 +176,7 @@ public class EamDbUtil { } catch (SQLException ex) { return false; } finally { - try { - EamDbUtil.closeResultSet(resultSet); - } catch (EamDbException ex) { - } + EamDbUtil.closeResultSet(resultSet); } return false; diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/PostgresEamDb.java b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/PostgresEamDb.java index 1c889cd3c3..83fafdf7db 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/PostgresEamDb.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/PostgresEamDb.java @@ -126,174 +126,6 @@ public class PostgresEamDb extends AbstractSqlEamDb { 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. * @@ -321,11 +153,6 @@ public class PostgresEamDb extends AbstractSqlEamDb { } } - @Override - public boolean isEnabled() { - return dbSettings.isEnabled(); - } - @Override public List getBadTags() { return dbSettings.getBadTags(); diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/PostgresEamDbSettings.java b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/PostgresEamDbSettings.java index 3c0a64ae46..e59af50013 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/PostgresEamDbSettings.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/PostgresEamDbSettings.java @@ -20,6 +20,7 @@ package org.sleuthkit.autopsy.experimental.enterpriseartifactsmanager.datamodel; import java.sql.Connection; import java.sql.DriverManager; +import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; @@ -27,6 +28,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.logging.Level; +import org.openide.util.Exceptions; import org.sleuthkit.autopsy.coreutils.Logger; 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 String DEFAULT_HOST = "localhost"; // NON-NLS 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 String DEFAULT_USERNAME = ""; private final String DEFAULT_PASSWORD = ""; @@ -120,7 +122,6 @@ public final class PostgresEamDbSettings { } 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.port", Integer.toString(port)); // 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 * + * @param usePostgresDb Connect to the 'postgres' database when testing + * connectivity and creating the main database. + * * @return */ - public String getConnectionURL() { + public String getConnectionURL(boolean usePostgresDb) { StringBuilder url = new StringBuilder(); url.append(getJDBCBaseURI()); url.append(getHost()); 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(getUserName()); 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. */ - public boolean testConnectionSettings() { - // Open a new ephemeral client here to test that we can connect - ResultSet resultSet = null; - Connection conn = null; - try { - String url = getConnectionURL(); - Class.forName(getDriver()); - conn = DriverManager.getConnection(url); - Statement tester = conn.createStatement(); - resultSet = tester.executeQuery(getValidationQuery()); - if (resultSet.next()) { - LOGGER.log(Level.INFO, "Testing connection to postgresql success."); // NON-NLS - } - } catch (ClassNotFoundException | SQLException ex) { - LOGGER.log(Level.INFO, "Testing connection to postgresql failed.", ex); // NON-NLS + public boolean verifyConnection() { + Connection conn = getEphemeralConnection(true); + if (null == conn) { + return false; + } + + boolean result = EamDbUtil.executeValidationQuery(conn, VALIDATION_QUERY); + EamDbUtil.closeConnection(conn); + return result; + } + + /** + * Check to see if the database exists. + * + * @return true if exists, else false + */ + public boolean verifyDatabaseExists() { + Connection conn = getEphemeralConnection(true); + if (null == conn) { 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 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() { - 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() { String hostString = ModuleSettings.getConfigSetting("EnterpriseArtifactsManager", "db.postgresql.host"); // NON-NLS String portString = ModuleSettings.getConfigSetting("EnterpriseArtifactsManager", "db.postgresql.port"); // NON-NLS diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/SqliteEamDb.java b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/SqliteEamDb.java index a5d4111b3c..0b41f2d7d9 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/SqliteEamDb.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/SqliteEamDb.java @@ -133,7 +133,7 @@ public class SqliteEamDb extends AbstractSqlEamDb { @Override protected Connection connect() throws EamDbException { synchronized (this) { - if (!dbSettings.isEnabled()) { + if (!EamDb.isEnabled()) { 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 public List getBadTags() { return dbSettings.getBadTags(); diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/SqliteEamDbSettings.java b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/SqliteEamDbSettings.java index 5ac7da6834..b4a891a57b 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/SqliteEamDbSettings.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/SqliteEamDbSettings.java @@ -104,7 +104,6 @@ public final class SqliteEamDbSettings { public void saveSettings() { 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.dbDirectory", getDbDirectory()); // NON-NLS ModuleSettings.setConfigSetting("EnterpriseArtifactsManager", "db.sqlite.bulkThreshold", Integer.toString(getBulkThreshold())); // NON-NLS @@ -175,14 +174,14 @@ public final class SqliteEamDbSettings { return null; } - Connection conn = null; + Connection conn; try { String url = getConnectionURL(); Class.forName(getDriver()); conn = DriverManager.getConnection(url); } catch (ClassNotFoundException | SQLException ex) { LOGGER.log(Level.SEVERE, "Failed to acquire ephemeral connection to sqlite.", ex); // NON-NLS - return null; + conn = null; } return conn; } @@ -200,11 +199,7 @@ public final class SqliteEamDbSettings { } boolean result = EamDbUtil.executeValidationQuery(conn, VALIDATION_QUERY); - try { - EamDbUtil.closeConnection(conn); - } catch (EamDbException ex) { - LOGGER.log(Level.SEVERE, "verifyConnection failed to close resources.", ex); - } + EamDbUtil.closeConnection(conn); return result; } @@ -221,11 +216,7 @@ public final class SqliteEamDbSettings { } boolean result = EamDbUtil.schemaVersionIsSet(conn); - try { - EamDbUtil.closeConnection(conn); - } catch (EamDbException ex) { - LOGGER.log(Level.SEVERE, "verifyDatabaseSchema failed to close resources.", ex); - } + EamDbUtil.closeConnection(conn); return result; } @@ -359,6 +350,9 @@ public final class SqliteEamDbSettings { Connection conn = null; try { conn = getEphemeralConnection(); + if (null == conn) { + return false; + } Statement stmt = conn.createStatement(); stmt.execute(PRAGMA_JOURNAL_WAL); stmt.execute(PRAGMA_SYNC_OFF); @@ -403,11 +397,7 @@ public final class SqliteEamDbSettings { LOGGER.log(Level.SEVERE, "Error initializing db schema.", ex); // NON-NLS return false; } finally { - try { - EamDbUtil.closeConnection(conn); - } catch (EamDbException ex) { - LOGGER.log(Level.SEVERE, "initializeDatabaseSchema failed to close resources.", ex); - } + EamDbUtil.closeConnection(conn); } return true; } @@ -418,19 +408,10 @@ public final class SqliteEamDbSettings { return false; } - try { - EamDbUtil.insertDefaultArtifactTypes(conn); - EamDbUtil.insertSchemaVersion(conn); - } catch (EamDbException ex) { - return false; - } finally { - try { - EamDbUtil.closeConnection(conn); - } catch (EamDbException ex) { - LOGGER.log(Level.SEVERE, "insertDefaultDatabaseContent failed to close resources.", ex); - } - } - return true; + boolean result = EamDbUtil.insertDefaultArtifactTypes(conn) + && EamDbUtil.insertSchemaVersion(conn); + EamDbUtil.closeConnection(conn); + return result; } public boolean isChanged() { @@ -443,20 +424,6 @@ public final class SqliteEamDbSettings { || !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 */ diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/eventlisteners/BadFileTagRunner.java b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/eventlisteners/BadFileTagRunner.java index 3bbbb1aebf..1355bbef7e 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/eventlisteners/BadFileTagRunner.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/eventlisteners/BadFileTagRunner.java @@ -42,7 +42,7 @@ public class BadFileTagRunner implements Runnable { @Override public void run() { - if (!dbManager.isEnabled()) { + if (!EamDb.isEnabled()) { LOGGER.log(Level.WARNING, "Enterprise artifacts manager database not configured"); // NON-NLS return; } diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/eventlisteners/CaseEventListener.java b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/eventlisteners/CaseEventListener.java index 053eeebbc3..039e9a8867 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/eventlisteners/CaseEventListener.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/eventlisteners/CaseEventListener.java @@ -61,7 +61,7 @@ public class CaseEventListener implements PropertyChangeListener { EamDb dbManager = EamDb.getInstance(); switch (Case.Events.valueOf(evt.getPropertyName())) { case CONTENT_TAG_ADDED: { - if (!dbManager.isEnabled()) { + if (!EamDb.isEnabled()) { return; } @@ -125,7 +125,7 @@ public class CaseEventListener implements PropertyChangeListener { break; case BLACKBOARD_ARTIFACT_TAG_ADDED: { - if (!dbManager.isEnabled()) { + if (!EamDb.isEnabled()) { return; } @@ -157,7 +157,7 @@ public class CaseEventListener implements PropertyChangeListener { break; case DATA_SOURCE_ADDED: { - if (!dbManager.isEnabled()) { + if (!EamDb.isEnabled()) { break; } @@ -214,7 +214,7 @@ public class CaseEventListener implements PropertyChangeListener { "", ""); - if (!dbManager.isEnabled()) { + if (!EamDb.isEnabled()) { break; } diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/eventlisteners/IngestEventsListener.java b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/eventlisteners/IngestEventsListener.java index bcd1f3abeb..9066d960d5 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/eventlisteners/IngestEventsListener.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/eventlisteners/IngestEventsListener.java @@ -78,7 +78,7 @@ public class IngestEventsListener { EamDb dbManager = EamDb.getInstance(); switch (IngestManager.IngestModuleEvent.valueOf(evt.getPropertyName())) { case DATA_ADDED: { - if (!dbManager.isEnabled()) { + if (!EamDb.isEnabled()) { return; } diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/eventlisteners/NewArtifactsRunner.java b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/eventlisteners/NewArtifactsRunner.java index 79762b75a6..a8eaa8fd3d 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/eventlisteners/NewArtifactsRunner.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/eventlisteners/NewArtifactsRunner.java @@ -45,7 +45,7 @@ public class NewArtifactsRunner implements Runnable { @Override public void run() { - if (!dbManager.isEnabled()) { + if (!EamDb.isEnabled()) { LOGGER.log(Level.WARNING, "Enterprise artifacts manager database not configured"); // NON-NLS return; } diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/ingestmodule/IngestModule.java b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/ingestmodule/IngestModule.java index 72fdf1762b..3742ba564d 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/ingestmodule/IngestModule.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/ingestmodule/IngestModule.java @@ -70,7 +70,7 @@ class IngestModule implements FileIngestModule { @Override public ProcessResult process(AbstractFile af) { 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 * all newly didscovered ingest modules are automatically anabled. @@ -153,7 +153,7 @@ class IngestModule implements FileIngestModule { @Override public void shutDown() { 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 * all newly didscovered ingest modules are automatically anabled. @@ -188,7 +188,7 @@ class IngestModule implements FileIngestModule { @Override public void startUp(IngestJobContext context) throws IngestModuleException { 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 * workaround for the way all newly didscovered ingest modules are diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/EamDbSettingsDialog.form b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/EamDbSettingsDialog.form index 881f93eac4..e9e3f2aaab 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/EamDbSettingsDialog.form +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/EamDbSettingsDialog.form @@ -200,11 +200,11 @@ - - + + @@ -236,7 +236,7 @@ - + @@ -287,7 +287,7 @@
- + diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/EamDbSettingsDialog.java b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/EamDbSettingsDialog.java index 9d11ff16c7..3fcfda51c0 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/EamDbSettingsDialog.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/EamDbSettingsDialog.java @@ -28,6 +28,7 @@ import org.openide.util.NbBundle.Messages; import org.openide.windows.WindowManager; import org.sleuthkit.autopsy.corecomponents.TextPrompt; 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.EamDbPlatformEnum; import org.sleuthkit.autopsy.experimental.enterpriseartifactsmanager.datamodel.PostgresEamDbSettings; @@ -98,7 +99,7 @@ public class EamDbSettingsDialog extends JDialog { tbDbPort = new javax.swing.JTextField(); tbDbName = new javax.swing.JTextField(); tbDbUsername = new javax.swing.JTextField(); - tbDbPassword = new javax.swing.JTextField(); + jpDbPassword = new javax.swing.JPasswordField(); rdioBnSQLite = new javax.swing.JRadioButton(); rdioBnPostgreSQL = new javax.swing.JRadioButton(); rdioBnDisabled = new javax.swing.JRadioButton(); @@ -179,11 +180,11 @@ public class EamDbSettingsDialog extends JDialog { .addComponent(lbUserPassword)) .addGap(18, 18, 18) .addGroup(pnPostgreSQLSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) - .addComponent(tbDbPassword, javax.swing.GroupLayout.DEFAULT_SIZE, 439, Short.MAX_VALUE) - .addComponent(tbDbUsername) + .addComponent(tbDbUsername, javax.swing.GroupLayout.DEFAULT_SIZE, 439, Short.MAX_VALUE) .addComponent(tbDbName) .addComponent(tbDbPort) - .addComponent(tbDbHostname)) + .addComponent(tbDbHostname) + .addComponent(jpDbPassword)) .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); pnPostgreSQLSettingsLayout.setVerticalGroup( @@ -208,7 +209,7 @@ public class EamDbSettingsDialog extends JDialog { .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(pnPostgreSQLSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .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)) ); @@ -439,14 +440,21 @@ public class EamDbSettingsDialog extends JDialog { private void bnTestActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnTestActionPerformed // lbTestDatabase.setIcon(null); // lbTestDatabase.setText(""); - boolean connectionOk; - boolean schemaOk; setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); EamDbPlatformEnum selectedPlatform = EamDbPlatformEnum.getSelectedPlatform(); switch (selectedPlatform) { 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; case SQLITE: if (dbSettingsSqlite.dbDirectoryExists() @@ -474,6 +482,12 @@ public class EamDbSettingsDialog extends JDialog { boolean result = false; switch (selectedPlatform) { case POSTGRESQL: + if (!dbSettingsPostgres.verifyDatabaseExists()) { + dbSettingsPostgres.createDatabase(); + } + result = dbSettingsPostgres.initializeDatabaseSchema() + && dbSettingsPostgres.insertDefaultDatabaseContent(); + break; case SQLITE: if (!dbSettingsSqlite.dbDirectoryExists()) { @@ -487,14 +501,27 @@ public class EamDbSettingsDialog extends JDialog { if (false == result) { taSetupGuidance.setText(Bundle.EamDbSettingsDialog_creation_failed()); } else { + testingStatus = DatabaseTestResult.TESTEDOK; valid(); } }//GEN-LAST:event_bnCreateDbActionPerformed private void bnOkActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnOkActionPerformed -// hasChanged = true; -// dbSettings.setEnabled(true); -// dbSettings.saveSettings(); + EamDbPlatformEnum selectedPlatform = EamDbPlatformEnum.getSelectedPlatform(); + EamDbPlatformEnum.saveSelectedPlatform(); + switch (selectedPlatform) { + case POSTGRESQL: + dbSettingsPostgres.saveSettings(); + EamDb.getInstance().updateSettings(); + break; + case SQLITE: + dbSettingsSqlite.saveSettings(); + EamDb.getInstance().updateSettings(); + break; + case DISABLED: + break; + } + dispose(); }//GEN-LAST:event_bnOkActionPerformed @@ -543,8 +570,8 @@ public class EamDbSettingsDialog extends JDialog { tbDbName.setEnabled(enabled); tbDbUsername.setText(enabled ? dbSettingsPostgres.getUserName() : ""); tbDbUsername.setEnabled(enabled); - tbDbPassword.setText(enabled ? dbSettingsPostgres.getPassword() : ""); - tbDbPassword.setEnabled(enabled); + jpDbPassword.setText(enabled ? dbSettingsPostgres.getPassword() : ""); + 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_dbName(), tbDbName)); textPrompts.add(new TextPrompt(Bundle.EamDbSettingsDialog_textPrompt_user(), tbDbUsername)); - textPrompts.add(new TextPrompt(Bundle.EamDbSettingsDialog_textPrompt_password(), tbDbPassword)); configureTextPrompts(textPrompts); } @@ -598,7 +624,7 @@ public class EamDbSettingsDialog extends JDialog { textBoxes.add(tbDbPort); textBoxes.add(tbDbName); textBoxes.add(tbDbUsername); - textBoxes.add(tbDbPassword); + textBoxes.add(jpDbPassword); addDocumentListeners(textBoxes, textBoxChangedListener); } @@ -643,7 +669,7 @@ public class EamDbSettingsDialog extends JDialog { && !tbDbPort.getText().trim().isEmpty() && !tbDbName.getText().trim().isEmpty() && !tbDbUsername.getText().trim().isEmpty() - && !tbDbPassword.getText().trim().isEmpty(); + && 0 < jpDbPassword.getPassword().length; break; @@ -727,7 +753,7 @@ public class EamDbSettingsDialog extends JDialog { } try { - dbSettingsPostgres.setPassword(tbDbPassword.getText().trim()); + dbSettingsPostgres.setPassword(jpDbPassword.getPassword().toString()); } catch (EamDbException ex) { if (!guidanceText.toString().isEmpty()) { guidanceText.append(", "); @@ -874,6 +900,7 @@ public class EamDbSettingsDialog extends JDialog { private javax.swing.JButton bnOk; private javax.swing.JButton bnTest; private javax.swing.JFileChooser fcDatabasePath; + private javax.swing.JPasswordField jpDbPassword; private javax.swing.JLabel lbDatabaseName; private javax.swing.JLabel lbDatabasePath; private javax.swing.JLabel lbHostName; @@ -891,7 +918,6 @@ public class EamDbSettingsDialog extends JDialog { private javax.swing.JTextArea taSetupGuidance; private javax.swing.JTextField tbDbHostname; private javax.swing.JTextField tbDbName; - private javax.swing.JTextField tbDbPassword; private javax.swing.JTextField tbDbPort; private javax.swing.JTextField tbDbUsername; private javax.swing.JTextField tfDatabasePath; diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/ImportHashDatabaseDialog.java b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/ImportHashDatabaseDialog.java index e1927401cd..3b1d392943 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/ImportHashDatabaseDialog.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/ImportHashDatabaseDialog.java @@ -178,7 +178,7 @@ final class ImportHashDatabaseDialog extends javax.swing.JDialog { public boolean valid() { lbWarningMsg.setText(""); EamDb dbManager = EamDb.getInstance(); - if (!dbManager.isEnabled()) { + if (!EamDb.isEnabled()) { lbWarningMsg.setText(Bundle.ImportHashDatabaseDialog_validation_notEnabled()); return false; } @@ -561,7 +561,7 @@ final class ImportHashDatabaseDialog extends javax.swing.JDialog { this.knownStatus = knownStatus; this.globalSetID = globalSetID; - if (!dbManager.isEnabled()) { + if (!EamDb.isEnabled()) { throw new EamDbException("Enterprise artifacts manager database settings were not properly initialized"); // NON-NLS } } From bb914eb1a7d709a23aaacdd4f063b2e115013ebe Mon Sep 17 00:00:00 2001 From: Nick Davis Date: Tue, 20 Jun 2017 17:35:39 -0400 Subject: [PATCH 10/20] extracted TextConverter class from UserPreferences and made it public. Created an Exception class for it. --- .../sleuthkit/autopsy/core/Bundle.properties | 2 - .../autopsy/core/UserPreferences.java | 114 +++++------------- .../autopsy/coreutils/TextConverter.java | 88 ++++++++++++++ .../coreutils/TextConverterException.java | 30 +++++ 4 files changed, 150 insertions(+), 84 deletions(-) create mode 100644 Core/src/org/sleuthkit/autopsy/coreutils/TextConverter.java create mode 100644 Core/src/org/sleuthkit/autopsy/coreutils/TextConverterException.java diff --git a/Core/src/org/sleuthkit/autopsy/core/Bundle.properties b/Core/src/org/sleuthkit/autopsy/core/Bundle.properties index 8ba6b8f14e..db8e9e9808 100644 --- a/Core/src/org/sleuthkit/autopsy/core/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/core/Bundle.properties @@ -20,8 +20,6 @@ ServicesMonitor.statusChange.notify.title=Service Status Update ServicesMonitor.statusChange.notify.msg=Status for {0} is {1} ServicesMonitor.nullServiceName.excepton.txt=Requested service name is null ServicesMonitor.unknownServiceName.excepton.txt=Requested service name {0} is unknown -TextConverter.convert.exception.txt=Unable to convert text {0} to hex text -TextConverter.convertFromHex.exception.txt=Unable to convert hex text to text ServicesMonitor.KeywordSearchNull=Cannot find Keyword Search service ServicesMonitor.InvalidPortNumber=Invalid port number. ServicesMonitor.remoteCaseDatabase.displayName.text=Multi-user case database service diff --git a/Core/src/org/sleuthkit/autopsy/core/UserPreferences.java b/Core/src/org/sleuthkit/autopsy/core/UserPreferences.java index 9ca9a4ac02..df63b0fa1f 100755 --- a/Core/src/org/sleuthkit/autopsy/core/UserPreferences.java +++ b/Core/src/org/sleuthkit/autopsy/core/UserPreferences.java @@ -18,20 +18,16 @@ */ package org.sleuthkit.autopsy.core; -import java.util.Base64; +import org.sleuthkit.autopsy.coreutils.TextConverter; import java.util.prefs.BackingStoreException; import org.sleuthkit.autopsy.events.MessageServiceConnectionInfo; import java.util.prefs.PreferenceChangeListener; import java.util.prefs.Preferences; -import javax.crypto.Cipher; -import javax.crypto.SecretKey; -import javax.crypto.SecretKeyFactory; -import javax.crypto.spec.PBEKeySpec; -import javax.crypto.spec.PBEParameterSpec; -import org.openide.util.NbBundle; +import org.openide.util.Exceptions; import org.openide.util.NbPreferences; import org.sleuthkit.autopsy.coreutils.ModuleSettings; import org.sleuthkit.autopsy.coreutils.PlatformUtil; +import org.sleuthkit.autopsy.coreutils.TextConverterException; import org.sleuthkit.autopsy.coreutils.Version; import org.sleuthkit.datamodel.CaseDbConnectionInfo; import org.sleuthkit.datamodel.TskData.DbType; @@ -205,12 +201,16 @@ public final class UserPreferences { } catch (Exception ex) { dbType = DbType.SQLITE; } - return new CaseDbConnectionInfo( - preferences.get(EXTERNAL_DATABASE_HOSTNAME_OR_IP, ""), - preferences.get(EXTERNAL_DATABASE_PORTNUMBER, "5432"), - preferences.get(EXTERNAL_DATABASE_USER, ""), - TextConverter.convertHexTextToText(preferences.get(EXTERNAL_DATABASE_PASSWORD, "")), - dbType); + try { + return new CaseDbConnectionInfo( + preferences.get(EXTERNAL_DATABASE_HOSTNAME_OR_IP, ""), + preferences.get(EXTERNAL_DATABASE_PORTNUMBER, "5432"), + preferences.get(EXTERNAL_DATABASE_USER, ""), + TextConverter.convertHexTextToText(preferences.get(EXTERNAL_DATABASE_PASSWORD, "")), + dbType); + } catch (TextConverterException ex) { + throw new UserPreferencesException("Failure converting password hex text to text.", ex); // NON-NLS + } } /** @@ -225,7 +225,11 @@ public final class UserPreferences { preferences.put(EXTERNAL_DATABASE_HOSTNAME_OR_IP, connectionInfo.getHost()); preferences.put(EXTERNAL_DATABASE_PORTNUMBER, connectionInfo.getPort()); preferences.put(EXTERNAL_DATABASE_USER, connectionInfo.getUserName()); - preferences.put(EXTERNAL_DATABASE_PASSWORD, TextConverter.convertTextToHexText(connectionInfo.getPassword())); + try { + preferences.put(EXTERNAL_DATABASE_PASSWORD, TextConverter.convertTextToHexText(connectionInfo.getPassword())); + } catch (TextConverterException ex) { + throw new UserPreferencesException("Failure converting text to password hext text", ex); // NON-NLS + } preferences.put(EXTERNAL_DATABASE_TYPE, connectionInfo.getDbType().toString()); } @@ -267,7 +271,11 @@ public final class UserPreferences { preferences.put(MESSAGE_SERVICE_HOST, info.getHost()); preferences.put(MESSAGE_SERVICE_PORT, Integer.toString(info.getPort())); preferences.put(MESSAGE_SERVICE_USER, info.getUserName()); - preferences.put(MESSAGE_SERVICE_PASSWORD, TextConverter.convertTextToHexText(info.getPassword())); + try { + preferences.put(MESSAGE_SERVICE_PASSWORD, TextConverter.convertTextToHexText(info.getPassword())); + } catch (TextConverterException ex) { + throw new UserPreferencesException("Failed to convert password text to hex text.", ex); + } } /** @@ -286,11 +294,15 @@ public final class UserPreferences { port = DEFAULT_PORT_INT; } - return new MessageServiceConnectionInfo( - preferences.get(MESSAGE_SERVICE_HOST, ""), - port, - preferences.get(MESSAGE_SERVICE_USER, ""), - TextConverter.convertHexTextToText(preferences.get(MESSAGE_SERVICE_PASSWORD, ""))); + try { + return new MessageServiceConnectionInfo( + preferences.get(MESSAGE_SERVICE_HOST, ""), + port, + preferences.get(MESSAGE_SERVICE_USER, ""), + TextConverter.convertHexTextToText(preferences.get(MESSAGE_SERVICE_PASSWORD, ""))); + } catch (TextConverterException ex) { + throw new UserPreferencesException("Failed to convert password hex text to text.", ex); + } } /** @@ -359,66 +371,4 @@ public final class UserPreferences { preferences.put(APP_NAME, name); } - /** - * Provides ability to convert text to hex text. - */ - static final class TextConverter { - - private static final char[] TMP = "hgleri21auty84fwe".toCharArray(); //NON-NLS - private static final byte[] SALT = { - (byte) 0xde, (byte) 0x33, (byte) 0x10, (byte) 0x12, - (byte) 0xde, (byte) 0x33, (byte) 0x10, (byte) 0x12,}; - - /** - * Convert text to hex text. - * - * @param property Input text string. - * - * @return Converted hex string. - * - * @throws org.sleuthkit.autopsy.core.UserPreferencesException - */ - static String convertTextToHexText(String property) throws UserPreferencesException { - try { - SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBEWithMD5AndDES"); //NON-NLS - SecretKey key = keyFactory.generateSecret(new PBEKeySpec(TMP)); - Cipher pbeCipher = Cipher.getInstance("PBEWithMD5AndDES"); //NON-NLS - pbeCipher.init(Cipher.ENCRYPT_MODE, key, new PBEParameterSpec(SALT, 20)); - return base64Encode(pbeCipher.doFinal(property.getBytes("UTF-8"))); - } catch (Exception ex) { - throw new UserPreferencesException( - NbBundle.getMessage(TextConverter.class, "TextConverter.convert.exception.txt")); - } - } - - private static String base64Encode(byte[] bytes) { - return Base64.getEncoder().encodeToString(bytes); - } - - /** - * Convert hex text back to text. - * - * @param property Input hex text string. - * - * @return Converted text string. - * - * @throws org.sleuthkit.autopsy.core.UserPreferencesException - */ - static String convertHexTextToText(String property) throws UserPreferencesException { - try { - SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBEWithMD5AndDES"); //NON-NLS - SecretKey key = keyFactory.generateSecret(new PBEKeySpec(TMP)); - Cipher pbeCipher = Cipher.getInstance("PBEWithMD5AndDES"); //NON-NLS - pbeCipher.init(Cipher.DECRYPT_MODE, key, new PBEParameterSpec(SALT, 20)); - return new String(pbeCipher.doFinal(base64Decode(property)), "UTF-8"); - } catch (Exception ex) { - throw new UserPreferencesException( - NbBundle.getMessage(TextConverter.class, "TextConverter.convertFromHex.exception.txt")); - } - } - - private static byte[] base64Decode(String property) { - return Base64.getDecoder().decode(property); - } - } } diff --git a/Core/src/org/sleuthkit/autopsy/coreutils/TextConverter.java b/Core/src/org/sleuthkit/autopsy/coreutils/TextConverter.java new file mode 100644 index 0000000000..b69a411a96 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/coreutils/TextConverter.java @@ -0,0 +1,88 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2011-2017 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.coreutils; + +import java.util.Base64; +import javax.crypto.Cipher; +import javax.crypto.SecretKey; +import javax.crypto.SecretKeyFactory; +import javax.crypto.spec.PBEKeySpec; +import javax.crypto.spec.PBEParameterSpec; +import org.openide.util.NbBundle; + +/** + * Provides ability to convert text to hex text. + */ +public final class TextConverter { + + private static final char[] TMP = "hgleri21auty84fwe".toCharArray(); //NON-NLS + private static final byte[] SALT = {(byte) 0xde, (byte) 0x33, (byte) 0x10, (byte) 0x12, (byte) 0xde, (byte) 0x33, (byte) 0x10, (byte) 0x12}; + + /** + * Convert text to hex text. + * + * @param property Input text string. + * + * @return Converted hex string. + * + * @throws org.sleuthkit.autopsy.coreutils.TextConverterException + */ + public static String convertTextToHexText(String property) throws TextConverterException { + try { + SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBEWithMD5AndDES"); //NON-NLS + SecretKey key = keyFactory.generateSecret(new PBEKeySpec(TMP)); + Cipher pbeCipher = Cipher.getInstance("PBEWithMD5AndDES"); //NON-NLS + pbeCipher.init(Cipher.ENCRYPT_MODE, key, new PBEParameterSpec(SALT, 20)); + return base64Encode(pbeCipher.doFinal(property.getBytes("UTF-8"))); + } catch (Exception ex) { + throw new TextConverterException(NbBundle.getMessage(TextConverter.class, "TextConverter.convert.exception.txt")); + } + } + + public static String base64Encode(byte[] bytes) { + return Base64.getEncoder().encodeToString(bytes); + } + + /** + * Convert hex text back to text. + * + * @param property Input hex text string. + * + * @return Converted text string. + * + * @throws org.sleuthkit.autopsy.coreutils.TextConverterException + */ + public static String convertHexTextToText(String property) throws TextConverterException { + try { + SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBEWithMD5AndDES"); //NON-NLS + SecretKey key = keyFactory.generateSecret(new PBEKeySpec(TMP)); + Cipher pbeCipher = Cipher.getInstance("PBEWithMD5AndDES"); //NON-NLS + pbeCipher.init(Cipher.DECRYPT_MODE, key, new PBEParameterSpec(SALT, 20)); + return new String(pbeCipher.doFinal(base64Decode(property)), "UTF-8"); + } catch (Exception ex) { + throw new TextConverterException(NbBundle.getMessage(TextConverter.class, "TextConverter.convertFromHex.exception.txt")); + } + } + + public static byte[] base64Decode(String property) { + return Base64.getDecoder().decode(property); + } + +} diff --git a/Core/src/org/sleuthkit/autopsy/coreutils/TextConverterException.java b/Core/src/org/sleuthkit/autopsy/coreutils/TextConverterException.java new file mode 100644 index 0000000000..3634d021e2 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/coreutils/TextConverterException.java @@ -0,0 +1,30 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2011-2017 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.coreutils; + +/** + * + */ +public class TextConverterException extends Exception { + + public TextConverterException(String message) { + super(message); + } +} \ No newline at end of file From beba50c23105d81153cc6260d5bb323f219ff809 Mon Sep 17 00:00:00 2001 From: Nick Davis Date: Tue, 20 Jun 2017 17:36:23 -0400 Subject: [PATCH 11/20] bundle changes associated with TextConverter changes. --- Core/src/org/sleuthkit/autopsy/coreutils/Bundle.properties | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/coreutils/Bundle.properties b/Core/src/org/sleuthkit/autopsy/coreutils/Bundle.properties index f633003d1d..e16d1e4fbd 100644 --- a/Core/src/org/sleuthkit/autopsy/coreutils/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/coreutils/Bundle.properties @@ -20,4 +20,6 @@ PlatformUtil.getPhysicalMemInfo.usageText=Physical memory usage (max, total, fre PlatformUtil.getAllMemUsageInfo.usageText={0}\n\ {1}\n\ Process Virtual Memory\: {2} -StringExtract.illegalStateException.cannotInit.msg=Unicode table not properly initialized, cannot instantiate StringExtract \ No newline at end of file +StringExtract.illegalStateException.cannotInit.msg=Unicode table not properly initialized, cannot instantiate StringExtract +TextConverter.convert.exception.txt=Unable to convert text {0} to hex text +TextConverter.convertFromHex.exception.txt=Unable to convert hex text to text From fc20b7ea19e446619d514263062e5bc64909c7f8 Mon Sep 17 00:00:00 2001 From: Nick Davis Date: Tue, 20 Jun 2017 17:37:42 -0400 Subject: [PATCH 12/20] changed password field into a proper JPassword box. now using TextConverter to store encrypted password in properties file. --- .../datamodel/PostgresEamDb.java | 3 +- .../datamodel/PostgresEamDbSettings.java | 33 +++++++------- .../datamodel/SqliteEamDb.java | 4 -- .../datamodel/SqliteEamDbSettings.java | 6 --- .../optionspanel/EamDbSettingsDialog.form | 25 ++++++++--- .../optionspanel/EamDbSettingsDialog.java | 43 ++++++++++--------- 6 files changed, 58 insertions(+), 56 deletions(-) diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/PostgresEamDb.java b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/PostgresEamDb.java index 83fafdf7db..97b3a99a0f 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/PostgresEamDb.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/PostgresEamDb.java @@ -136,13 +136,12 @@ public class PostgresEamDb extends AbstractSqlEamDb { @Override protected Connection connect() throws EamDbException { synchronized (this) { - if (!dbSettings.isEnabled()) { + if (!EamDb.isEnabled()) { throw new EamDbException("Enterprise artifacts manager is not enabled"); // NON-NLS } if (connectionPool == null) { setupConnectionPool(); -// confirmDatabaseSchema(); } } diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/PostgresEamDbSettings.java b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/PostgresEamDbSettings.java index e59af50013..cde5f412e2 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/PostgresEamDbSettings.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/PostgresEamDbSettings.java @@ -31,6 +31,8 @@ import java.util.logging.Level; import org.openide.util.Exceptions; 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 enterprise artifacts manager @@ -50,7 +52,6 @@ public final class PostgresEamDbSettings { private final String JDBC_BASE_URI = "jdbc:postgresql://"; // NON-NLS private final String JDBC_DRIVER = "org.postgresql.Driver"; // NON-NLS - private boolean enabled; private String host; private int port; private String dbName; @@ -64,8 +65,6 @@ public final class PostgresEamDbSettings { } public void loadSettings() { - enabled = Boolean.valueOf(ModuleSettings.getConfigSetting("EnterpriseArtifactsManager", "db.enabled")); // NON-NLS - host = ModuleSettings.getConfigSetting("EnterpriseArtifactsManager", "db.postgresql.host"); // NON-NLS if (host == null || host.isEmpty()) { host = DEFAULT_HOST; @@ -112,6 +111,13 @@ public final class PostgresEamDbSettings { password = ModuleSettings.getConfigSetting("EnterpriseArtifactsManager", "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; + } } String badTagsStr = ModuleSettings.getConfigSetting("EnterpriseArtifactsManager", "db.badTags"); // NON-NLS @@ -127,7 +133,12 @@ public final class PostgresEamDbSettings { ModuleSettings.setConfigSetting("EnterpriseArtifactsManager", "db.postgresql.dbName", getDbName()); // NON-NLS ModuleSettings.setConfigSetting("EnterpriseArtifactsManager", "db.postgresql.bulkThreshold", Integer.toString(getBulkThreshold())); // NON-NLS ModuleSettings.setConfigSetting("EnterpriseArtifactsManager", "db.postgresql.user", getUserName()); // NON-NLS - ModuleSettings.setConfigSetting("EnterpriseArtifactsManager", "db.postgresql.password", getPassword()); // NON-NLS + try { + ModuleSettings.setConfigSetting("EnterpriseArtifactsManager", "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); + } + ModuleSettings.setConfigSetting("EnterpriseArtifactsManager", "db.badTags", String.join(",", badTags)); // NON-NLS } @@ -464,20 +475,6 @@ public final class PostgresEamDbSettings { || !userName.equals(userNameString) || !password.equals(userPasswordString); } - /** - * @return the enabled - */ - public boolean isEnabled() { - return enabled; - } - - /** - * @param enabled the enabled to set - */ - public void setEnabled(boolean enabled) { - this.enabled = enabled; - } - /** * @return the host */ diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/SqliteEamDb.java b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/SqliteEamDb.java index 0b41f2d7d9..e720955308 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/SqliteEamDb.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/SqliteEamDb.java @@ -19,8 +19,6 @@ package org.sleuthkit.autopsy.experimental.enterpriseartifactsmanager.datamodel; import java.io.File; -import java.io.IOException; -import java.nio.file.Files; import java.sql.Connection; import java.sql.SQLException; import java.sql.Statement; @@ -138,9 +136,7 @@ public class SqliteEamDb extends AbstractSqlEamDb { } if (connectionPool == null) { -// verifyDBDirectory(); setupConnectionPool(); -// confirmDatabaseSchema(); } try { diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/SqliteEamDbSettings.java b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/SqliteEamDbSettings.java index b4a891a57b..896fad4f9e 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/SqliteEamDbSettings.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/SqliteEamDbSettings.java @@ -23,15 +23,12 @@ import java.io.IOException; import java.nio.file.Files; import java.sql.Connection; import java.sql.DriverManager; -import java.sql.PreparedStatement; -import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.logging.Level; -import org.openide.util.Exceptions; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.ModuleSettings; import org.sleuthkit.autopsy.coreutils.PlatformUtil; @@ -57,7 +54,6 @@ public final class SqliteEamDbSettings { private static final String PRAGMA_PAGE_SIZE_4096 = "PRAGMA page_size = 4096"; private static final String PRAGMA_FOREIGN_KEYS_ON = "PRAGMA foreign_keys = ON"; - private boolean enabled; private String dbName; private String dbDirectory; private int bulkThreshold; @@ -68,8 +64,6 @@ public final class SqliteEamDbSettings { } public void loadSettings() { - enabled = Boolean.valueOf(ModuleSettings.getConfigSetting("EnterpriseArtifactsManager", "db.enabled")); // NON-NLS - dbName = ModuleSettings.getConfigSetting("EnterpriseArtifactsManager", "db.sqlite.dbName"); // NON-NLS if (dbName == null || dbName.isEmpty()) { dbName = DEFAULT_DBNAME; diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/EamDbSettingsDialog.form b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/EamDbSettingsDialog.form index e9e3f2aaab..719c2083ab 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/EamDbSettingsDialog.form +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/EamDbSettingsDialog.form @@ -332,6 +332,8 @@ + + @@ -345,13 +347,22 @@ - - - - - + + + + + + + + + + + + + + - + @@ -397,6 +408,8 @@ + + diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/EamDbSettingsDialog.java b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/EamDbSettingsDialog.java index 3fcfda51c0..66f2cdefa1 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/EamDbSettingsDialog.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/EamDbSettingsDialog.java @@ -108,6 +108,7 @@ public class EamDbSettingsDialog extends JDialog { bnOk = new javax.swing.JButton(); bnTest = new javax.swing.JButton(); bnCreateDb = new javax.swing.JButton(); + lbTestIcon = new javax.swing.JLabel(); pnSetupGuidance = new javax.swing.JPanel(); taSetupGuidance = new javax.swing.JTextArea(); @@ -304,6 +305,8 @@ public class EamDbSettingsDialog extends JDialog { .addContainerGap() .addComponent(bnTest) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(lbTestIcon, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(18, 18, 18) .addComponent(bnCreateDb) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(bnOk) @@ -315,12 +318,18 @@ public class EamDbSettingsDialog extends JDialog { pnButtonsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(pnButtonsLayout.createSequentialGroup() .addGap(0, 0, 0) - .addGroup(pnButtonsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(bnOk) - .addComponent(bnCancel) - .addComponent(bnTest) - .addComponent(bnCreateDb)) - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addGroup(pnButtonsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(pnButtonsLayout.createSequentialGroup() + .addGap(4, 4, 4) + .addComponent(lbTestIcon, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addGroup(pnButtonsLayout.createSequentialGroup() + .addGroup(pnButtonsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(bnOk) + .addComponent(bnCancel) + .addComponent(bnTest) + .addComponent(bnCreateDb)) + .addGap(0, 0, Short.MAX_VALUE))) + .addContainerGap()) ); pnSetupGuidance.setBorder(javax.swing.BorderFactory.createTitledBorder(null, org.openide.util.NbBundle.getMessage(EamDbSettingsDialog.class, "EamDbSettingsDialog.pnSetupGuidance.border.title"), javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("Tahoma", 0, 12))); // NOI18N @@ -412,7 +421,7 @@ public class EamDbSettingsDialog extends JDialog { setTextPrompts(); setTextBoxListeners(); - + lbTestIcon.setIcon(null); } private void display() { @@ -471,6 +480,11 @@ public class EamDbSettingsDialog extends JDialog { } setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); + if (testingStatus == DatabaseTestResult.TESTEDOK) { + lbTestIcon.setIcon(goodIcon); + } else { + lbTestIcon.setIcon(badIcon); + } valid(); }//GEN-LAST:event_bnTestActionPerformed @@ -753,7 +767,7 @@ public class EamDbSettingsDialog extends JDialog { } try { - dbSettingsPostgres.setPassword(jpDbPassword.getPassword().toString()); + dbSettingsPostgres.setPassword(new String(jpDbPassword.getPassword())); } catch (EamDbException ex) { if (!guidanceText.toString().isEmpty()) { guidanceText.append(", "); @@ -856,30 +870,18 @@ public class EamDbSettingsDialog extends JDialog { @Override public void changedUpdate(DocumentEvent e) { - Object statusIcon = e.getDocument().getProperty("statusIcon"); // NON-NLS - if (statusIcon != null) { - ((javax.swing.JLabel) statusIcon).setIcon(null); - } firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); valid(); } @Override public void insertUpdate(DocumentEvent e) { - Object statusIcon = e.getDocument().getProperty("statusIcon"); // NON-NLS - if (statusIcon != null) { - ((javax.swing.JLabel) statusIcon).setIcon(null); - } firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); valid(); } @Override public void removeUpdate(DocumentEvent e) { - Object statusIcon = e.getDocument().getProperty("statusIcon"); // NON-NLS - if (statusIcon != null) { - ((javax.swing.JLabel) statusIcon).setIcon(null); - } firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); valid(); } @@ -905,6 +907,7 @@ public class EamDbSettingsDialog extends JDialog { private javax.swing.JLabel lbDatabasePath; private javax.swing.JLabel lbHostName; private javax.swing.JLabel lbPort; + private javax.swing.JLabel lbTestIcon; private javax.swing.JLabel lbUserName; private javax.swing.JLabel lbUserPassword; private javax.swing.JPanel pnButtons; From a40984ea1528b120f9759e2a7ee181e53c822339 Mon Sep 17 00:00:00 2001 From: Nick Davis Date: Tue, 20 Jun 2017 18:59:14 -0400 Subject: [PATCH 13/20] add .db to sqlite dbfile name if it does not have that extension. some cleanup --- .../datamodel/PostgresEamDbSettings.java | 6 ++- .../optionspanel/EamDbSettingsDialog.form | 3 ++ .../optionspanel/EamDbSettingsDialog.java | 41 +++++++++++-------- .../optionspanel/GlobalSettingsPanel.java | 19 +++------ 4 files changed, 37 insertions(+), 32 deletions(-) diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/PostgresEamDbSettings.java b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/PostgresEamDbSettings.java index cde5f412e2..5d7ca067b8 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/PostgresEamDbSettings.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/PostgresEamDbSettings.java @@ -28,7 +28,6 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.logging.Level; -import org.openide.util.Exceptions; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.ModuleSettings; import org.sleuthkit.autopsy.coreutils.TextConverter; @@ -512,10 +511,13 @@ public final class PostgresEamDbSettings { } /** + * To prevent issues where one command can honor case and another cannot, + * we will force the dbname to lower case. + * * @return the dbName */ public String getDbName() { - return dbName; + return dbName.toLowerCase(); } /** diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/EamDbSettingsDialog.form b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/EamDbSettingsDialog.form index 719c2083ab..915d26febd 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/EamDbSettingsDialog.form +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/EamDbSettingsDialog.form @@ -164,6 +164,9 @@ + + + diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/EamDbSettingsDialog.java b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/EamDbSettingsDialog.java index 66f2cdefa1..b0c8f51e22 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/EamDbSettingsDialog.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/EamDbSettingsDialog.java @@ -48,7 +48,7 @@ public class EamDbSettingsDialog extends JDialog { private final PostgresEamDbSettings dbSettingsPostgres; private final SqliteEamDbSettings dbSettingsSqlite; private DatabaseTestResult testingStatus; - private Boolean isCreated; + private final EamDbPlatformEnum initialSelectedPlatform; /** * Creates new form EamDbSettingsDialog @@ -66,6 +66,7 @@ public class EamDbSettingsDialog extends JDialog { dbSettingsPostgres = new PostgresEamDbSettings(); dbSettingsSqlite = new SqliteEamDbSettings(); + initialSelectedPlatform = EamDbPlatformEnum.getSelectedPlatform(); initComponents(); customizeComponents(); @@ -123,6 +124,11 @@ public class EamDbSettingsDialog extends JDialog { tfDatabasePath.setText(org.openide.util.NbBundle.getMessage(EamDbSettingsDialog.class, "EamDbSettingsDialog.tfDatabasePath.text")); // NOI18N tfDatabasePath.setToolTipText(org.openide.util.NbBundle.getMessage(EamDbSettingsDialog.class, "EamDbSettingsDialog.tfDatabasePath.toolTipText")); // NOI18N + tfDatabasePath.addFocusListener(new java.awt.event.FocusAdapter() { + public void focusLost(java.awt.event.FocusEvent evt) { + tfDatabasePathFocusLost(evt); + } + }); org.openide.awt.Mnemonics.setLocalizedText(bnDatabasePathFileOpen, org.openide.util.NbBundle.getMessage(EamDbSettingsDialog.class, "EamDbSettingsDialog.bnDatabasePathFileOpen.text")); // NOI18N bnDatabasePathFileOpen.addActionListener(new java.awt.event.ActionListener() { @@ -437,7 +443,11 @@ public class EamDbSettingsDialog extends JDialog { if (fcDatabasePath.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) { File databaseFile = fcDatabasePath.getSelectedFile(); try { - tfDatabasePath.setText(databaseFile.getCanonicalPath()); + String fullPath = databaseFile.getCanonicalPath(); + if (!fullPath.endsWith(".db")) { + fullPath = fullPath + ".db"; // NON-NLS + } + tfDatabasePath.setText(fullPath); valid(); } catch (IOException ex) { LOGGER.log(Level.SEVERE, "Failed to get path of selected database file", ex); // NON-NLS @@ -447,8 +457,6 @@ public class EamDbSettingsDialog extends JDialog { }//GEN-LAST:event_bnDatabasePathFileOpenActionPerformed private void bnTestActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnTestActionPerformed -// lbTestDatabase.setIcon(null); -// lbTestDatabase.setText(""); setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); EamDbPlatformEnum selectedPlatform = EamDbPlatformEnum.getSelectedPlatform(); @@ -492,6 +500,7 @@ public class EamDbSettingsDialog extends JDialog { private void bnCreateDbActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnCreateDbActionPerformed setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); + lbTestIcon.setIcon(null); EamDbPlatformEnum selectedPlatform = EamDbPlatformEnum.getSelectedPlatform(); boolean result = false; switch (selectedPlatform) { @@ -540,6 +549,8 @@ public class EamDbSettingsDialog extends JDialog { }//GEN-LAST:event_bnOkActionPerformed private void bnCancelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnCancelActionPerformed + EamDbPlatformEnum.setSelectedPlatform(initialSelectedPlatform.name()); + dispose(); }//GEN-LAST:event_bnCancelActionPerformed @@ -569,6 +580,14 @@ public class EamDbSettingsDialog extends JDialog { }//GEN-LAST:event_rdioBnSQLiteActionPerformed + private void tfDatabasePathFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_tfDatabasePathFocusLost + String fullPath = tfDatabasePath.getText(); + if (!fullPath.endsWith(".db")) { + fullPath = fullPath + ".db"; // NON-NLS + } + tfDatabasePath.setText(fullPath); + }//GEN-LAST:event_tfDatabasePathFocusLost + /** * Update the fields for the Postgres platform depending on whether the * Postgres radioButton is enabled. @@ -616,19 +635,7 @@ public class EamDbSettingsDialog extends JDialog { textPrompts.add(new TextPrompt(Bundle.EamDbSettingsDialog_textPrompt_user(), tbDbUsername)); configureTextPrompts(textPrompts); } - - /** - * Set each textbox with a "statusIcon" property enabling the - * DocumentListeners to know which icon to erase when changes are made - */ -// private void setTextBoxStatusIcons() { -// tbDbHostname.getDocument().putProperty("statusIcon", lbTestDatabase); // NON-NLS -// tbDbPort.getDocument().putProperty("statusIcon", lbTestDatabase); // NON-NLS -// tbDbName.getDocument().putProperty("statusIcon", lbTestDatabase); // NON-NLS -// tbDbUsername.getDocument().putProperty("statusIcon", lbTestDatabase); // NON-NLS -// tbDbPassword.getDocument().putProperty("statusIcon", lbTestDatabase); // NON-NLS -// } -// + /** * Register for notifications when the text boxes get updated. */ diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/GlobalSettingsPanel.java b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/GlobalSettingsPanel.java index 7935354071..119cc74ef8 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/GlobalSettingsPanel.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/GlobalSettingsPanel.java @@ -252,7 +252,7 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i private void bnDbConfigureActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnDbConfigureActionPerformed EamDbSettingsDialog dialog = new EamDbSettingsDialog(); - firePropertyChange(OptionsPanelController.PROP_VALID, null, null); + load(); // reload db settings content and update buttons }//GEN-LAST:event_bnDbConfigureActionPerformed @Override @@ -268,17 +268,21 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i lbDbPlatformValue.setText(EamDbPlatformEnum.POSTGRESQL.toString()); lbDbNameValue.setText(dbSettingsPg.getDbName()); lbDbLocationValue.setText(dbSettingsPg.getHost()); + enableAllSubComponents(true); break; case SQLITE: SqliteEamDbSettings dbSettingsSqlite = new SqliteEamDbSettings(); lbDbPlatformValue.setText(EamDbPlatformEnum.SQLITE.toString()); lbDbNameValue.setText(dbSettingsSqlite.getDbName()); lbDbLocationValue.setText(dbSettingsSqlite.getDbDirectory()); + enableAllSubComponents(true); break; default: lbDbPlatformValue.setText(EamDbPlatformEnum.DISABLED.toString()); lbDbNameValue.setText(""); lbDbLocationValue.setText(""); + enableDatabaseConfigureButton(true); + tbOops.setText(Bundle.GlobalSettingsPanel_validationerrMsg_mustConfigure()); break; } @@ -295,10 +299,7 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i * @return true if it's okay, false otherwise. */ public boolean valid() { - tbOops.setText(""); - Boolean enabled = Boolean.valueOf(ModuleSettings.getConfigSetting("EnterpriseArtifactsManager", "db.enabled")); // NON-NLS - - return enabled && EamDbPlatformEnum.getSelectedPlatform() != EamDbPlatformEnum.DISABLED; + return true; } @Override @@ -346,14 +347,6 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i if (IngestManager.getInstance().isIngestRunning()) { tbOops.setText(Bundle.GlobalSettingsPanel_validationErrMsg_ingestRunning()); enableAllSubComponents(false); - } else { - tbOops.setText(""); - if (valid()) { - enableAllSubComponents(true); - } else { - enableDatabaseConfigureButton(true); - tbOops.setText(Bundle.GlobalSettingsPanel_validationerrMsg_mustConfigure()); - } } } From 91ed88195521b5970670bebf25b59b151c79d559 Mon Sep 17 00:00:00 2001 From: Nick Davis Date: Tue, 20 Jun 2017 19:45:31 -0400 Subject: [PATCH 14/20] now require a Organization to be selected in the ComboBox before enabling the Ok button. Also adding an Organization will re-run validation. --- .../optionspanel/ImportHashDatabaseDialog.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/ImportHashDatabaseDialog.java b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/ImportHashDatabaseDialog.java index e1927401cd..68fbc74fa5 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/ImportHashDatabaseDialog.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/ImportHashDatabaseDialog.java @@ -119,8 +119,11 @@ final class ImportHashDatabaseDialog extends javax.swing.JDialog { orgs = dbManager.getOrganizations(); orgs.forEach((org) -> { comboboxSourceOrganization.addItem(org.getName()); - selectedOrg = orgs.get(0); }); + if (!orgs.isEmpty()) { + selectedOrg = orgs.get(0); + } + valid(); } catch (EamDbException ex) { LOGGER.log(Level.SEVERE, "Failure populating combobox with organizations.", ex); } @@ -183,7 +186,7 @@ final class ImportHashDatabaseDialog extends javax.swing.JDialog { return false; } - return enableOkButton(checkFields()); + return enableOkButton(checkFields() && null != selectedOrg); } /** @@ -545,6 +548,7 @@ final class ImportHashDatabaseDialog extends javax.swing.JDialog { return; } } + valid(); }//GEN-LAST:event_comboboxSourceOrganizationActionPerformed @NbBundle.Messages({"ImportHashDatabaseDialog.ImportHashDatabaseWorker.displayName=Importing Hash Database"}) From fe7aabb9930ea3970da6a12db6c832e333065a6a Mon Sep 17 00:00:00 2001 From: Nick Davis Date: Wed, 21 Jun 2017 16:14:24 -0400 Subject: [PATCH 15/20] added input validation to db settings. changed red text to a mix of red or black depending on if it's an error. changed postgres connection to use a properties object to store the user/pass. reduced the large area between the db config button and the lower buttons on the main options panel. --- .../datamodel/PostgresEamDb.java | 8 ++-- .../datamodel/PostgresEamDbSettings.java | 36 ++++++++++-------- .../datamodel/SqliteEamDbSettings.java | 11 ++++-- .../optionspanel/EamDbSettingsDialog.form | 3 -- .../optionspanel/EamDbSettingsDialog.java | 28 +++++++++----- .../optionspanel/GlobalSettingsPanel.form | 37 +++++-------------- .../optionspanel/GlobalSettingsPanel.java | 31 +++++----------- 7 files changed, 67 insertions(+), 87 deletions(-) diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/PostgresEamDb.java b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/PostgresEamDb.java index 97b3a99a0f..0815d9997b 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/PostgresEamDb.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/PostgresEamDb.java @@ -113,12 +113,10 @@ public class PostgresEamDb extends AbstractSqlEamDb { connectionURL.append(dbSettings.getPort()); connectionURL.append("/"); connectionURL.append(dbSettings.getDbName()); - connectionURL.append("?user="); - connectionURL.append(dbSettings.getUserName()); - connectionURL.append("&password="); - connectionURL.append(dbSettings.getPassword()); - + connectionPool.setUrl(connectionURL.toString()); + connectionPool.setUsername(dbSettings.getUserName()); + connectionPool.setPassword(dbSettings.getPassword()); // tweak pool configuration connectionPool.setInitialSize(5); // start with 5 connections diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/PostgresEamDbSettings.java b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/PostgresEamDbSettings.java index 5d7ca067b8..5611842c1f 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/PostgresEamDbSettings.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/PostgresEamDbSettings.java @@ -27,7 +27,9 @@ import java.sql.Statement; import java.util.ArrayList; import java.util.Arrays; import java.util.List; +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; @@ -50,7 +52,8 @@ public final class PostgresEamDbSettings { private final String VALIDATION_QUERY = "SELECT version()"; // NON-NLS private final String JDBC_BASE_URI = "jdbc:postgresql://"; // NON-NLS private final String JDBC_DRIVER = "org.postgresql.Driver"; // NON-NLS - + private final String DB_NAMES_REGEX = "[a-z][a-z0-9_]*"; // only lower case + private final String DB_USER_NAMES_REGEX = "[a-zA-Z]\\w*"; private String host; private int port; private String dbName; @@ -159,10 +162,6 @@ public final class PostgresEamDbSettings { } else { url.append(getDbName()); } - url.append("?user="); // NON-NLS - url.append(getUserName()); - url.append("&password="); // NON-NLS - url.append(getPassword()); return url.toString(); } @@ -176,8 +175,12 @@ public final class PostgresEamDbSettings { Connection conn; try { String url = getConnectionURL(usePostgresDb); + Properties props = new Properties(); + props.setProperty("user", getUserName()); + props.setProperty("password", getPassword()); + Class.forName(getDriver()); - conn = DriverManager.getConnection(url); + conn = DriverManager.getConnection(url, props); } catch (ClassNotFoundException | SQLException ex) { // TODO: Determine why a connection failure (ConnectionException) re-throws // the SQLException and does not print this log message? @@ -524,12 +527,13 @@ public final class PostgresEamDbSettings { * @param dbName the dbName to set */ public void setDbName(String dbName) throws EamDbException { - if (dbName != null && !dbName.isEmpty()) { - this.dbName = dbName; - } else { + if (dbName == null || dbName.isEmpty()) { throw new EamDbException("Error invalid name for database connection. Cannot be null or empty."); // NON-NLS - + } else if (!Pattern.matches(DB_NAMES_REGEX, dbName)) { + throw new EamDbException("Error invalid name for database connection. Name can only contain letters, numbers, and '_', and must start with a letter."); // NON-NLS } + + this.dbName = dbName.toLowerCase(); } /** @@ -561,11 +565,12 @@ public final class PostgresEamDbSettings { * @param userName the userName to set */ public void setUserName(String userName) throws EamDbException { - if (userName != null && !userName.isEmpty()) { - this.userName = userName; - } else { + if (userName == null || userName.isEmpty()) { throw new EamDbException("Error invalid user name for database connection. Cannot be null or empty."); // NON-NLS + } else if (!Pattern.matches(DB_USER_NAMES_REGEX, userName)) { + throw new EamDbException("Error invalid user name for database connection. Name can only contain letters, numbers, and '_', and must start with a letter."); // NON-NLS } + this.userName = userName; } /** @@ -579,11 +584,10 @@ public final class PostgresEamDbSettings { * @param password the password to set */ public void setPassword(String password) throws EamDbException { - if (password != null && !password.isEmpty()) { - this.password = password; - } else { + if (password == null || password.isEmpty()) { throw new EamDbException("Error invalid user password for database connection. Cannot be null or empty."); // NON-NLS } + this.password = password; } /** diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/SqliteEamDbSettings.java b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/SqliteEamDbSettings.java index 896fad4f9e..db1f6aa083 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/SqliteEamDbSettings.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/SqliteEamDbSettings.java @@ -29,6 +29,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; 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.PlatformUtil; @@ -53,7 +54,7 @@ public final class SqliteEamDbSettings { private static final String PRAGMA_ENCODING_UTF8 = "PRAGMA encoding = 'UTF-8'"; private static final String PRAGMA_PAGE_SIZE_4096 = "PRAGMA page_size = 4096"; private static final String PRAGMA_FOREIGN_KEYS_ON = "PRAGMA foreign_keys = ON"; - + private final String DB_NAMES_REGEX = "[a-zA-Z]\\w*(\\.db)?"; private String dbName; private String dbDirectory; private int bulkThreshold; @@ -431,11 +432,13 @@ public final class SqliteEamDbSettings { * @param dbName the dbName to set */ public void setDbName(String dbName) throws EamDbException { - if (dbName != null && !dbName.isEmpty()) { - this.dbName = dbName; - } else { + if (dbName == null || dbName.isEmpty()) { throw new EamDbException("Error invalid file name for database. Cannot be null or empty."); // NON-NLS + } else if (!Pattern.matches(DB_NAMES_REGEX, dbName)) { + throw new EamDbException("Error invalid name for database connection. Name can only contain letters, numbers, and '_', must start with a letter."); // NON-NLS } + + this.dbName = dbName; } /** diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/EamDbSettingsDialog.form b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/EamDbSettingsDialog.form index 915d26febd..cd6e8a7ea6 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/EamDbSettingsDialog.form +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/EamDbSettingsDialog.form @@ -458,9 +458,6 @@ - - - diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/EamDbSettingsDialog.java b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/EamDbSettingsDialog.java index b0c8f51e22..971cb78887 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/EamDbSettingsDialog.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/EamDbSettingsDialog.java @@ -344,7 +344,6 @@ public class EamDbSettingsDialog extends JDialog { taSetupGuidance.setBackground(new java.awt.Color(240, 240, 240)); taSetupGuidance.setColumns(20); taSetupGuidance.setFont(new java.awt.Font("Monospaced", 0, 12)); // NOI18N - taSetupGuidance.setForeground(new java.awt.Color(255, 102, 102)); taSetupGuidance.setLineWrap(true); taSetupGuidance.setRows(3); taSetupGuidance.setTabSize(4); @@ -435,7 +434,15 @@ public class EamDbSettingsDialog extends JDialog { setLocation((screenDimension.width - getSize().width) / 2, (screenDimension.height - getSize().height) / 2); setVisible(true); } - + private void setGuidanceMessage(String message, boolean isError) { + taSetupGuidance.setText(message); + if (isError) { + taSetupGuidance.setForeground(new Color(255, 102, 102)); // light red color + } else { + taSetupGuidance.setForeground(new Color(0, 0, 0)); // black color + } + } + @Messages({"EamDbSettingsDialog.chooserPath.failedToGetDbPathMsg=Selected database path is invalid. Try again."}) private void bnDatabasePathFileOpenActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnDatabasePathFileOpenActionPerformed fcDatabasePath.setCurrentDirectory(new File(dbSettingsSqlite.getDbDirectory())); @@ -451,7 +458,7 @@ public class EamDbSettingsDialog extends JDialog { valid(); } catch (IOException ex) { LOGGER.log(Level.SEVERE, "Failed to get path of selected database file", ex); // NON-NLS - JOptionPane.showMessageDialog(this, Bundle.EamDbSettingsDialog_chooserPath_failedToGetDbPathMsg()); + setGuidanceMessage(Bundle.EamDbSettingsDialog_chooserPath_failedToGetDbPathMsg(), true); } } }//GEN-LAST:event_bnDatabasePathFileOpenActionPerformed @@ -522,7 +529,7 @@ public class EamDbSettingsDialog extends JDialog { } setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); if (false == result) { - taSetupGuidance.setText(Bundle.EamDbSettingsDialog_creation_failed()); + setGuidanceMessage(Bundle.EamDbSettingsDialog_creation_failed(), true); } else { testingStatus = DatabaseTestResult.TESTEDOK; valid(); @@ -700,7 +707,7 @@ public class EamDbSettingsDialog extends JDialog { } if (!result) { - taSetupGuidance.setText(Bundle.EamDbSettingsDialog_validation_incompleteFields()); + setGuidanceMessage(Bundle.EamDbSettingsDialog_validation_incompleteFields(), true); } return result; @@ -798,7 +805,8 @@ public class EamDbSettingsDialog extends JDialog { break; } - taSetupGuidance.setText(guidanceText.toString()); + setGuidanceMessage(guidanceText.toString(), true); + bnTest.setEnabled(result); return result; } @@ -827,9 +835,9 @@ public class EamDbSettingsDialog extends JDialog { if (selectedPlatform != EamDbPlatformEnum.DISABLED) { bnTest.setEnabled(true); if (testingStatus == DatabaseTestResult.UNTESTED) { - taSetupGuidance.setText(Bundle.EamDbSettingsDialog_validation_mustTest()); + setGuidanceMessage(Bundle.EamDbSettingsDialog_validation_mustTest(), false); } else if (testingStatus == DatabaseTestResult.CONNECTION_FAILED) { - taSetupGuidance.setText(Bundle.EamDbSettingsDialog_validation_failedConnection()); + setGuidanceMessage(Bundle.EamDbSettingsDialog_validation_failedConnection(), true); } } else { bnTest.setEnabled(false); @@ -846,7 +854,7 @@ public class EamDbSettingsDialog extends JDialog { private boolean enableCreateButton() { if (testingStatus == DatabaseTestResult.SCHEMA_INVALID) { bnCreateDb.setEnabled(true); - taSetupGuidance.setText(Bundle.EamDbSettingsDialog_validation_dbNotCreated()); + setGuidanceMessage(Bundle.EamDbSettingsDialog_validation_dbNotCreated(), false); } else { bnCreateDb.setEnabled(false); } @@ -862,7 +870,7 @@ public class EamDbSettingsDialog extends JDialog { private boolean enableOkButton() { if (testingStatus == DatabaseTestResult.TESTEDOK) { bnOk.setEnabled(true); - taSetupGuidance.setText(Bundle.EamDbSettingsDialog_validation_finished()); + setGuidanceMessage(Bundle.EamDbSettingsDialog_validation_finished(), false); } else { bnOk.setEnabled(false); } diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/GlobalSettingsPanel.form b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/GlobalSettingsPanel.form index f90b07be51..02edd5748e 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/GlobalSettingsPanel.form +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/GlobalSettingsPanel.form @@ -19,26 +19,15 @@ - + + - - - - - - - - + + + - - - - - - - @@ -46,16 +35,11 @@ - + + + - - - - - - - - + @@ -248,9 +232,6 @@ - - - diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/GlobalSettingsPanel.java b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/GlobalSettingsPanel.java index 119cc74ef8..ca37fc5f03 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/GlobalSettingsPanel.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/GlobalSettingsPanel.java @@ -196,7 +196,6 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i tbOops.setEditable(false); tbOops.setFont(tbOops.getFont().deriveFont(tbOops.getFont().getStyle() | java.awt.Font.BOLD, 12)); - tbOops.setForeground(new java.awt.Color(255, 0, 0)); tbOops.setText(org.openide.util.NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.tbOops.text")); // NOI18N tbOops.setBorder(null); @@ -205,33 +204,23 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() + .addContainerGap() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addContainerGap() - .addComponent(pnDatabaseConfiguration, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - .addGroup(layout.createSequentialGroup() - .addGap(20, 20, 20) - .addComponent(pnDatabaseContentButtons, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))) + .addComponent(pnDatabaseContentButtons, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(tbOops, javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(pnDatabaseConfiguration, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addContainerGap()) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addGap(15, 15, 15) - .addComponent(tbOops, javax.swing.GroupLayout.DEFAULT_SIZE, 805, Short.MAX_VALUE) - .addContainerGap())) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() .addContainerGap() .addComponent(pnDatabaseConfiguration, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 178, Short.MAX_VALUE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(tbOops, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(pnDatabaseContentButtons, javax.swing.GroupLayout.PREFERRED_SIZE, 50, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGap(22, 22, 22)) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addGap(287, 287, 287) - .addComponent(tbOops, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addContainerGap(89, Short.MAX_VALUE))) + .addGap(0, 18, Short.MAX_VALUE)) ); }// //GEN-END:initComponents @@ -256,6 +245,7 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i }//GEN-LAST:event_bnDbConfigureActionPerformed @Override + @Messages({"GlobalSettingsPanel.validationerrMsg.mustConfigure=Configure the database to enable this module."}) public void load() { tbOops.setText(""); @@ -333,8 +323,7 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i } }; - @Messages({"GlobalSettingsPanel.validationErrMsg.ingestRunning=Cannot change settings while ingest is running.", - "GlobalSettingsPanel.validationerrMsg.mustConfigure=You must configure the database."}) + @Messages({"GlobalSettingsPanel.validationErrMsg.ingestRunning=You cannot change settings while ingest is running."}) private void ingestStateUpdated() { if (!SwingUtilities.isEventDispatchThread()) { SwingUtilities.invokeLater(() -> { From 701ef5ff2d1c904e93b037d87b90dc3c2dca7c82 Mon Sep 17 00:00:00 2001 From: Nick Davis Date: Wed, 21 Jun 2017 19:31:32 -0400 Subject: [PATCH 16/20] send database settings exception messages back to config window and display them in red. surround guidance message panel with a scrollpane. added red/green check boxes to the Create button. correctly clear the red/green check boxes by the Test and Create buttons when a change is made. Do not save state until OK button is clicked, so either the X or the Cancel button will cause no change (ignoreing the creation of a db). --- .../datamodel/PostgresEamDbSettings.java | 18 +-- .../datamodel/SqliteEamDbSettings.java | 6 +- .../optionspanel/EamDbSettingsDialog.form | 65 ++++++---- .../optionspanel/EamDbSettingsDialog.java | 111 ++++++++---------- 4 files changed, 101 insertions(+), 99 deletions(-) diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/PostgresEamDbSettings.java b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/PostgresEamDbSettings.java index 5611842c1f..58d99981a6 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/PostgresEamDbSettings.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/PostgresEamDbSettings.java @@ -44,7 +44,7 @@ public final class PostgresEamDbSettings { private final static Logger LOGGER = Logger.getLogger(PostgresEamDbSettings.class.getName()); private final String DEFAULT_HOST = "localhost"; // NON-NLS private final int DEFAULT_PORT = 5432; - private final String DEFAULT_DBNAME = "EnterpriseArtifacts"; // NON-NLS + private final String DEFAULT_DBNAME = "enterpriseartifacts"; // NON-NLS private final int DEFAULT_BULK_THRESHHOLD = 1000; private final String DEFAULT_USERNAME = ""; private final String DEFAULT_PASSWORD = ""; @@ -491,7 +491,7 @@ public final class PostgresEamDbSettings { if (null != host && !host.isEmpty()) { this.host = host; } else { - throw new EamDbException("Error invalid host for database connection. Cannot be null or empty."); // NON-NLS + throw new EamDbException("Invalid host name. Cannot be empty."); // NON-NLS } } @@ -509,7 +509,7 @@ public final class PostgresEamDbSettings { if (port > 0 && port < 65535) { this.port = port; } else { - throw new EamDbException("Error invalid port for database connection."); // NON-NLS + throw new EamDbException("Invalid port. Must be a number greater than 0."); // NON-NLS } } @@ -528,9 +528,9 @@ public final class PostgresEamDbSettings { */ public void setDbName(String dbName) throws EamDbException { if (dbName == null || dbName.isEmpty()) { - throw new EamDbException("Error invalid name for database connection. Cannot be null or empty."); // NON-NLS + throw new EamDbException("Invalid database name. Cannot be empty."); // NON-NLS } else if (!Pattern.matches(DB_NAMES_REGEX, dbName)) { - throw new EamDbException("Error invalid name for database connection. Name can only contain letters, numbers, and '_', and must start with a letter."); // NON-NLS + throw new EamDbException("Invalid database name. Name must start with a letter and can only contain letters, numbers, and '_'."); // NON-NLS } this.dbName = dbName.toLowerCase(); @@ -550,7 +550,7 @@ public final class PostgresEamDbSettings { if (bulkThreshold > 0) { this.bulkThreshold = bulkThreshold; } else { - throw new EamDbException("Error invalid bulk threshold for database connection."); // NON-NLS + throw new EamDbException("Invalid bulk threshold for database connection."); // NON-NLS } } @@ -566,9 +566,9 @@ public final class PostgresEamDbSettings { */ public void setUserName(String userName) throws EamDbException { if (userName == null || userName.isEmpty()) { - throw new EamDbException("Error invalid user name for database connection. Cannot be null or empty."); // NON-NLS + throw new EamDbException("Invalid user name. Cannot be empty."); // NON-NLS } else if (!Pattern.matches(DB_USER_NAMES_REGEX, userName)) { - throw new EamDbException("Error invalid user name for database connection. Name can only contain letters, numbers, and '_', and must start with a letter."); // NON-NLS + throw new EamDbException("Invalid user name. Name must start with a letter and can only contain letters, numbers, and '_'."); // NON-NLS } this.userName = userName; } @@ -585,7 +585,7 @@ public final class PostgresEamDbSettings { */ public void setPassword(String password) throws EamDbException { if (password == null || password.isEmpty()) { - throw new EamDbException("Error invalid user password for database connection. Cannot be null or empty."); // NON-NLS + throw new EamDbException("Invalid user password. Cannot be empty."); // NON-NLS } this.password = password; } diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/SqliteEamDbSettings.java b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/SqliteEamDbSettings.java index db1f6aa083..742863ab33 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/SqliteEamDbSettings.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/SqliteEamDbSettings.java @@ -433,9 +433,9 @@ public final class SqliteEamDbSettings { */ public void setDbName(String dbName) throws EamDbException { if (dbName == null || dbName.isEmpty()) { - throw new EamDbException("Error invalid file name for database. Cannot be null or empty."); // NON-NLS + throw new EamDbException("Invalid database file name. Cannot be null or empty."); // NON-NLS } else if (!Pattern.matches(DB_NAMES_REGEX, dbName)) { - throw new EamDbException("Error invalid name for database connection. Name can only contain letters, numbers, and '_', must start with a letter."); // NON-NLS + throw new EamDbException("Invalid database file name. Name must start with a letter and can only contain letters, numbers, and '_'."); // NON-NLS } this.dbName = dbName; @@ -455,7 +455,7 @@ public final class SqliteEamDbSettings { if (bulkThreshold > 0) { this.bulkThreshold = bulkThreshold; } else { - throw new EamDbException("Error invalid bulk threshold for database connection."); // NON-NLS + throw new EamDbException("Invalid bulk threshold for database connection."); // NON-NLS } } diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/EamDbSettingsDialog.form b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/EamDbSettingsDialog.form index cd6e8a7ea6..3a43033eca 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/EamDbSettingsDialog.form +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/EamDbSettingsDialog.form @@ -338,6 +338,8 @@ + + @@ -351,11 +353,9 @@ - - - - - + + + @@ -413,6 +413,8 @@ + + @@ -432,44 +434,55 @@ - + - - - + + + - + - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/EamDbSettingsDialog.java b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/EamDbSettingsDialog.java index 971cb78887..c95c6f6bfb 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/EamDbSettingsDialog.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/EamDbSettingsDialog.java @@ -48,7 +48,7 @@ public class EamDbSettingsDialog extends JDialog { private final PostgresEamDbSettings dbSettingsPostgres; private final SqliteEamDbSettings dbSettingsSqlite; private DatabaseTestResult testingStatus; - private final EamDbPlatformEnum initialSelectedPlatform; + private EamDbPlatformEnum selectedPlatform; /** * Creates new form EamDbSettingsDialog @@ -66,7 +66,7 @@ public class EamDbSettingsDialog extends JDialog { dbSettingsPostgres = new PostgresEamDbSettings(); dbSettingsSqlite = new SqliteEamDbSettings(); - initialSelectedPlatform = EamDbPlatformEnum.getSelectedPlatform(); + selectedPlatform = EamDbPlatformEnum.getSelectedPlatform(); initComponents(); customizeComponents(); @@ -110,7 +110,9 @@ public class EamDbSettingsDialog extends JDialog { bnTest = new javax.swing.JButton(); bnCreateDb = new javax.swing.JButton(); lbTestIcon = new javax.swing.JLabel(); + lbCreateIcon = new javax.swing.JLabel(); pnSetupGuidance = new javax.swing.JPanel(); + jScrollPane1 = new javax.swing.JScrollPane(); taSetupGuidance = new javax.swing.JTextArea(); setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); @@ -314,6 +316,8 @@ public class EamDbSettingsDialog extends JDialog { .addComponent(lbTestIcon, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE) .addGap(18, 18, 18) .addComponent(bnCreateDb) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(lbCreateIcon, javax.swing.GroupLayout.PREFERRED_SIZE, 21, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(bnOk) .addGap(11, 11, 11) @@ -325,9 +329,8 @@ public class EamDbSettingsDialog extends JDialog { .addGroup(pnButtonsLayout.createSequentialGroup() .addGap(0, 0, 0) .addGroup(pnButtonsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(pnButtonsLayout.createSequentialGroup() - .addGap(4, 4, 4) - .addComponent(lbTestIcon, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addComponent(lbCreateIcon, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(lbTestIcon, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addGroup(pnButtonsLayout.createSequentialGroup() .addGroup(pnButtonsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(bnOk) @@ -340,6 +343,8 @@ public class EamDbSettingsDialog extends JDialog { pnSetupGuidance.setBorder(javax.swing.BorderFactory.createTitledBorder(null, org.openide.util.NbBundle.getMessage(EamDbSettingsDialog.class, "EamDbSettingsDialog.pnSetupGuidance.border.title"), javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("Tahoma", 0, 12))); // NOI18N + jScrollPane1.setBorder(null); + taSetupGuidance.setEditable(false); taSetupGuidance.setBackground(new java.awt.Color(240, 240, 240)); taSetupGuidance.setColumns(20); @@ -352,6 +357,7 @@ public class EamDbSettingsDialog extends JDialog { taSetupGuidance.setBorder(null); taSetupGuidance.setRequestFocusEnabled(false); taSetupGuidance.setVerifyInputWhenFocusTarget(false); + jScrollPane1.setViewportView(taSetupGuidance); javax.swing.GroupLayout pnSetupGuidanceLayout = new javax.swing.GroupLayout(pnSetupGuidance); pnSetupGuidance.setLayout(pnSetupGuidanceLayout); @@ -359,14 +365,14 @@ public class EamDbSettingsDialog extends JDialog { pnSetupGuidanceLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(pnSetupGuidanceLayout.createSequentialGroup() .addContainerGap() - .addComponent(taSetupGuidance) + .addComponent(jScrollPane1) .addContainerGap()) ); pnSetupGuidanceLayout.setVerticalGroup( pnSetupGuidanceLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, pnSetupGuidanceLayout.createSequentialGroup() - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(taSetupGuidance, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGroup(pnSetupGuidanceLayout.createSequentialGroup() + .addContainerGap() + .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); @@ -402,7 +408,6 @@ public class EamDbSettingsDialog extends JDialog { bnGrpDatabasePlatforms.add(rdioBnPostgreSQL); bnGrpDatabasePlatforms.add(rdioBnSQLite); - EamDbPlatformEnum selectedPlatform = EamDbPlatformEnum.getSelectedPlatform(); switch (selectedPlatform) { case POSTGRESQL: rdioBnPostgreSQL.setSelected(true); @@ -443,6 +448,11 @@ public class EamDbSettingsDialog extends JDialog { } } + private void clearIcons() { + lbTestIcon.setIcon(null); + lbCreateIcon.setIcon(null); + } + @Messages({"EamDbSettingsDialog.chooserPath.failedToGetDbPathMsg=Selected database path is invalid. Try again."}) private void bnDatabasePathFileOpenActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnDatabasePathFileOpenActionPerformed fcDatabasePath.setCurrentDirectory(new File(dbSettingsSqlite.getDbDirectory())); @@ -466,7 +476,6 @@ public class EamDbSettingsDialog extends JDialog { private void bnTestActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnTestActionPerformed setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); - EamDbPlatformEnum selectedPlatform = EamDbPlatformEnum.getSelectedPlatform(); switch (selectedPlatform) { case POSTGRESQL: if (dbSettingsPostgres.verifyConnection()) { @@ -507,8 +516,7 @@ public class EamDbSettingsDialog extends JDialog { private void bnCreateDbActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnCreateDbActionPerformed setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); - lbTestIcon.setIcon(null); - EamDbPlatformEnum selectedPlatform = EamDbPlatformEnum.getSelectedPlatform(); + clearIcons(); boolean result = false; switch (selectedPlatform) { case POSTGRESQL: @@ -530,14 +538,16 @@ public class EamDbSettingsDialog extends JDialog { setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); if (false == result) { setGuidanceMessage(Bundle.EamDbSettingsDialog_creation_failed(), true); + lbCreateIcon.setIcon(badIcon); } else { testingStatus = DatabaseTestResult.TESTEDOK; + lbCreateIcon.setIcon(goodIcon); valid(); } }//GEN-LAST:event_bnCreateDbActionPerformed private void bnOkActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnOkActionPerformed - EamDbPlatformEnum selectedPlatform = EamDbPlatformEnum.getSelectedPlatform(); + EamDbPlatformEnum.setSelectedPlatform(selectedPlatform.name()); EamDbPlatformEnum.saveSelectedPlatform(); switch (selectedPlatform) { case POSTGRESQL: @@ -556,13 +566,11 @@ public class EamDbSettingsDialog extends JDialog { }//GEN-LAST:event_bnOkActionPerformed private void bnCancelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnCancelActionPerformed - EamDbPlatformEnum.setSelectedPlatform(initialSelectedPlatform.name()); - dispose(); }//GEN-LAST:event_bnCancelActionPerformed private void rdioBnDisabledActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_rdioBnDisabledActionPerformed - EamDbPlatformEnum.setSelectedPlatform(EamDbPlatformEnum.DISABLED.toString()); + selectedPlatform = EamDbPlatformEnum.DISABLED; testingStatus = DatabaseTestResult.TESTEDOK; updateSqliteFields(false); @@ -571,7 +579,7 @@ public class EamDbSettingsDialog extends JDialog { private void rdioBnPostgreSQLActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_rdioBnPostgreSQLActionPerformed - EamDbPlatformEnum.setSelectedPlatform(EamDbPlatformEnum.POSTGRESQL.toString()); + selectedPlatform = EamDbPlatformEnum.POSTGRESQL; testingStatus = DatabaseTestResult.UNTESTED; updateSqliteFields(false); @@ -579,7 +587,7 @@ public class EamDbSettingsDialog extends JDialog { }//GEN-LAST:event_rdioBnPostgreSQLActionPerformed private void rdioBnSQLiteActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_rdioBnSQLiteActionPerformed - EamDbPlatformEnum.setSelectedPlatform(EamDbPlatformEnum.SQLITE.toString()); + selectedPlatform = EamDbPlatformEnum.SQLITE; testingStatus = DatabaseTestResult.UNTESTED; updateSqliteFields(true); @@ -689,7 +697,7 @@ public class EamDbSettingsDialog extends JDialog { * @return True or false. */ @Messages({"EamDbSettingsDialog.validation.incompleteFields=Fill in all values for the selected database."}) - private boolean databaseFieldsArePopulated(EamDbPlatformEnum selectedPlatform) { + private boolean databaseFieldsArePopulated() { boolean result = true; switch (selectedPlatform) { case POSTGRESQL: @@ -718,9 +726,9 @@ public class EamDbSettingsDialog extends JDialog { * * @return True or false. */ - private boolean checkFields(EamDbPlatformEnum selectedPlatform) { - return databaseFieldsArePopulated(selectedPlatform) - && databaseSettingsAreValid(selectedPlatform); + private boolean checkFields() { + return databaseFieldsArePopulated() + && databaseSettingsAreValid(); } /** @@ -728,13 +736,7 @@ public class EamDbSettingsDialog extends JDialog { * * @return True or false. */ - @Messages({"EamDbSettingsDialog.validation.invalidHost=Invalid database hostname.", - "EamDbSettingsDialog.validation.invalidPort=Invalid database port number.", - "EamDbSettingsDialog.validation.invalidDbName=Invalid database name.", - "EamDbSettingsDialog.validation.invalidDbUser=Invalid database username.", - "EamDbSettingsDialog.validation.invalidDbPassword=Invalid database password.", - "EamDbSettingsDialog.validation.invalidDbPath=Invalid database path."}) - private boolean databaseSettingsAreValid(EamDbPlatformEnum selectedPlatform) { + private boolean databaseSettingsAreValid() { boolean result = true; StringBuilder guidanceText = new StringBuilder(); @@ -743,50 +745,35 @@ public class EamDbSettingsDialog extends JDialog { try { dbSettingsPostgres.setHost(tbDbHostname.getText().trim()); } catch (EamDbException ex) { - if (!guidanceText.toString().isEmpty()) { - guidanceText.append(", "); - } - guidanceText.append(Bundle.EamDbSettingsDialog_validation_invalidHost()); + guidanceText.append(ex.getMessage()); result = false; } try { dbSettingsPostgres.setPort(Integer.valueOf(tbDbPort.getText().trim())); } catch (NumberFormatException | EamDbException ex) { - if (!guidanceText.toString().isEmpty()) { - guidanceText.append(", "); - } - guidanceText.append(Bundle.EamDbSettingsDialog_validation_invalidPort()); + guidanceText.append(ex.getMessage()); result = false; } try { dbSettingsPostgres.setDbName(tbDbName.getText().trim()); } catch (EamDbException ex) { - if (!guidanceText.toString().isEmpty()) { - guidanceText.append(", "); - } - guidanceText.append(Bundle.EamDbSettingsDialog_validation_invalidDbName()); + guidanceText.append(ex.getMessage()); result = false; } try { dbSettingsPostgres.setUserName(tbDbUsername.getText().trim()); } catch (EamDbException ex) { - if (!guidanceText.toString().isEmpty()) { - guidanceText.append(", "); - } - guidanceText.append(Bundle.EamDbSettingsDialog_validation_invalidDbUser()); + guidanceText.append(ex.getMessage()); result = false; } try { dbSettingsPostgres.setPassword(new String(jpDbPassword.getPassword())); } catch (EamDbException ex) { - if (!guidanceText.toString().isEmpty()) { - guidanceText.append(", "); - } - guidanceText.append(Bundle.EamDbSettingsDialog_validation_invalidDbPassword()); + guidanceText.append(ex.getMessage()); result = false; } break; @@ -796,17 +783,13 @@ public class EamDbSettingsDialog extends JDialog { dbSettingsSqlite.setDbName(databasePath.getName()); dbSettingsSqlite.setDbDirectory(databasePath.getParent()); } catch (EamDbException ex) { - if (!guidanceText.toString().isEmpty()) { - guidanceText.append(", "); - } - guidanceText.append(Bundle.EamDbSettingsDialog_validation_invalidDbPath()); + guidanceText.append(ex.getMessage()); result = false; } break; } setGuidanceMessage(guidanceText.toString(), true); - bnTest.setEnabled(result); return result; } @@ -817,9 +800,7 @@ public class EamDbSettingsDialog extends JDialog { */ private boolean valid() { taSetupGuidance.setText(""); - EamDbPlatformEnum selectedPlatform = EamDbPlatformEnum.getSelectedPlatform(); - return checkFields(selectedPlatform) - && enableTestButton(selectedPlatform) + return enableTestButton(checkFields()) && enableCreateButton() && enableOkButton(); } @@ -831,8 +812,8 @@ public class EamDbSettingsDialog extends JDialog { */ @Messages({"EamDbSettingsDialog.validation.mustTest=Once you are statisfied with the database settings, click the Test button to test the database connection, settings, and schema.", "EamDbSettingsDialog.validation.failedConnection=The connection to the database failed. Update the settings and try the Test again."}) - private boolean enableTestButton(EamDbPlatformEnum selectedPlatform) { - if (selectedPlatform != EamDbPlatformEnum.DISABLED) { + private boolean enableTestButton(boolean isValidInput) { + if (selectedPlatform != EamDbPlatformEnum.DISABLED && isValidInput) { bnTest.setEnabled(true); if (testingStatus == DatabaseTestResult.UNTESTED) { setGuidanceMessage(Bundle.EamDbSettingsDialog_validation_mustTest(), false); @@ -866,7 +847,7 @@ public class EamDbSettingsDialog extends JDialog { * * @return true */ - @Messages({"EamDbSettingsDialog.validation.finished=Click OK to save your database settings and return to the Options."}) + @Messages({"EamDbSettingsDialog.validation.finished=Click OK to save your database settings and return to the Options. Or select a differnt database type."}) private boolean enableOkButton() { if (testingStatus == DatabaseTestResult.TESTEDOK) { bnOk.setEnabled(true); @@ -886,18 +867,24 @@ public class EamDbSettingsDialog extends JDialog { @Override public void changedUpdate(DocumentEvent e) { firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); + clearIcons(); + testingStatus = DatabaseTestResult.UNTESTED; valid(); } @Override public void insertUpdate(DocumentEvent e) { firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); + clearIcons(); + testingStatus = DatabaseTestResult.UNTESTED; valid(); } @Override public void removeUpdate(DocumentEvent e) { firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); + clearIcons(); + testingStatus = DatabaseTestResult.UNTESTED; valid(); } } @@ -917,7 +904,9 @@ public class EamDbSettingsDialog extends JDialog { private javax.swing.JButton bnOk; private javax.swing.JButton bnTest; private javax.swing.JFileChooser fcDatabasePath; + private javax.swing.JScrollPane jScrollPane1; private javax.swing.JPasswordField jpDbPassword; + private javax.swing.JLabel lbCreateIcon; private javax.swing.JLabel lbDatabaseName; private javax.swing.JLabel lbDatabasePath; private javax.swing.JLabel lbHostName; From 8166bd22723600515c69a4e51144b7943d9a762a Mon Sep 17 00:00:00 2001 From: millmanorama Date: Thu, 22 Jun 2017 11:47:24 +0200 Subject: [PATCH 17/20] put the correct node name in the lookup --- Core/src/org/sleuthkit/autopsy/datamodel/KeywordHits.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/KeywordHits.java b/Core/src/org/sleuthkit/autopsy/datamodel/KeywordHits.java index cde13121b7..c25e4c52b0 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/KeywordHits.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/KeywordHits.java @@ -774,7 +774,7 @@ public class KeywordHits implements AutopsyVisitableItem { private final String instance; public RegExpInstanceNode(String setName, String keyword, String instance) { - super(Children.create(new HitsFactory(setName, keyword, instance), true), Lookups.singleton(keyword)); + super(Children.create(new HitsFactory(setName, keyword, instance), true), Lookups.singleton(instance)); super.setName(instance); //the instance represents the name of the keyword hit at this point as the keyword is the regex this.setName = setName; this.keyword = keyword; From a961d2f6153bf65887a9d0739d047f192f4ad8b6 Mon Sep 17 00:00:00 2001 From: Nick Davis Date: Thu, 22 Jun 2017 10:41:04 -0400 Subject: [PATCH 18/20] can now disable the EAM. --- .../optionspanel/EamDbSettingsDialog.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/EamDbSettingsDialog.java b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/EamDbSettingsDialog.java index c95c6f6bfb..4f95216843 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/EamDbSettingsDialog.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/EamDbSettingsDialog.java @@ -849,7 +849,7 @@ public class EamDbSettingsDialog extends JDialog { */ @Messages({"EamDbSettingsDialog.validation.finished=Click OK to save your database settings and return to the Options. Or select a differnt database type."}) private boolean enableOkButton() { - if (testingStatus == DatabaseTestResult.TESTEDOK) { + if (testingStatus == DatabaseTestResult.TESTEDOK || selectedPlatform == EamDbPlatformEnum.DISABLED) { bnOk.setEnabled(true); setGuidanceMessage(Bundle.EamDbSettingsDialog_validation_finished(), false); } else { From 4d304c65a3b252347625fdd98938c7cce2087f56 Mon Sep 17 00:00:00 2001 From: Nick Davis Date: Thu, 22 Jun 2017 10:52:58 -0400 Subject: [PATCH 19/20] removed usage of 'db.enabled' property, since it is no longer used by the config panel. Now we just check EamDb.isEnbled(). --- .../actions/EamEditCaseInfoAction.java | 6 ++---- .../ingestmodule/IngestModule.java | 10 +++------- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/actions/EamEditCaseInfoAction.java b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/actions/EamEditCaseInfoAction.java index 7b7f2db346..7c13f22530 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/actions/EamEditCaseInfoAction.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/actions/EamEditCaseInfoAction.java @@ -20,7 +20,6 @@ package org.sleuthkit.autopsy.experimental.enterpriseartifactsmanager.actions; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; -import org.sleuthkit.autopsy.coreutils.Logger; import javax.swing.Action; import org.openide.awt.ActionID; import org.openide.awt.ActionReference; @@ -29,7 +28,7 @@ import org.openide.util.HelpCtx; import org.openide.util.NbBundle.Messages; import org.openide.util.actions.CallableSystemAction; import org.sleuthkit.autopsy.casemodule.Case; -import org.sleuthkit.autopsy.coreutils.ModuleSettings; +import org.sleuthkit.autopsy.experimental.enterpriseartifactsmanager.datamodel.EamDb; /** * Action to update case details in enterprise artifacts manager database @@ -53,8 +52,7 @@ public final class EamEditCaseInfoAction extends CallableSystemAction implements @Override public boolean isEnabled() { - boolean enabled = Boolean.valueOf(ModuleSettings.getConfigSetting("EnterpriseArtifactsManager", "db.enabled")); // NON-NLS - return enabled && Case.isCaseOpen(); + return EamDb.isEnabled() && Case.isCaseOpen(); } @Override diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/ingestmodule/IngestModule.java b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/ingestmodule/IngestModule.java index 3742ba564d..6937f5aca1 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/ingestmodule/IngestModule.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/ingestmodule/IngestModule.java @@ -29,7 +29,6 @@ import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.services.Blackboard; import org.sleuthkit.autopsy.core.RuntimeProperties; import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil; -import org.sleuthkit.autopsy.coreutils.ModuleSettings; import org.sleuthkit.autopsy.ingest.FileIngestModule; import org.sleuthkit.autopsy.ingest.IngestJobContext; import org.sleuthkit.autopsy.ingest.IngestMessage; @@ -69,8 +68,7 @@ class IngestModule implements FileIngestModule { @Override public ProcessResult process(AbstractFile af) { - if (Boolean.parseBoolean(ModuleSettings.getConfigSetting("EnterpriseArtifactsManager", "db.enabled")) == false - || EamDb.isEnabled() == false) { + if (EamDb.isEnabled() == false) { /* * Not signaling an error for now. This is a workaround for the way * all newly didscovered ingest modules are automatically anabled. @@ -152,8 +150,7 @@ class IngestModule implements FileIngestModule { @Override public void shutDown() { - if (Boolean.parseBoolean(ModuleSettings.getConfigSetting("EnterpriseArtifactsManager", "db.enabled")) == false - || EamDb.isEnabled() == false) { + if (EamDb.isEnabled() == false) { /* * Not signaling an error for now. This is a workaround for the way * all newly didscovered ingest modules are automatically anabled. @@ -187,8 +184,7 @@ class IngestModule implements FileIngestModule { }) @Override public void startUp(IngestJobContext context) throws IngestModuleException { - if (Boolean.parseBoolean(ModuleSettings.getConfigSetting("EnterpriseArtifactsManager", "db.enabled")) == false - || EamDb.isEnabled() == false) { + if (EamDb.isEnabled() == false) { /* * Not throwing the customary exception for now. This is a * workaround for the way all newly didscovered ingest modules are From a617d552c094707e2259c0121d04a188a240b982 Mon Sep 17 00:00:00 2001 From: Ann Priestman Date: Thu, 22 Jun 2017 12:21:19 -0400 Subject: [PATCH 20/20] Convert sql statements referring to device name to use device id --- .../datamodel/AbstractSqlEamDb.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/AbstractSqlEamDb.java b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/AbstractSqlEamDb.java index 5b0af7c6e6..4c7c0e09a4 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/AbstractSqlEamDb.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/AbstractSqlEamDb.java @@ -829,14 +829,15 @@ public abstract class AbstractSqlEamDb implements EamDb { sql.append("+ (SELECT count(*) FROM "); sql.append(table_name); - sql.append(" WHERE case_id=(SELECT id FROM cases WHERE case_uid=?))");// and data_source_id=(SELECT id FROM data_sources WHERE name=?))"); + sql.append(" WHERE case_id=(SELECT id FROM cases WHERE case_uid=?) and data_source_id=(SELECT id FROM data_sources WHERE device_id=?))"); } try { preparedStatement = conn.prepareStatement(sql.toString()); for (int i = 0; i < artifactTypes.size(); ++i) { - preparedStatement.setString(i + 1, eamInstance.getEamCase().getCaseUUID()); + preparedStatement.setString(2 * i + 1, eamInstance.getEamCase().getCaseUUID()); + preparedStatement.setString(2 * i + 2, eamInstance.getEamDataSource().getDeviceID()); } resultSet = preparedStatement.executeQuery();